Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - texus

#1
Yes, that would be the solution.
You would indeed need a second function with tgui::Container::Ptr, unless you make the first parameter a template as well (but then you will need to pass "&gui" as argument when calling the function).
#2
I've given it some more thought and asked for some extra opinions about this issue on discord yesterday, and my decision is that I'm not going to change the API for this. I don't really want to add another function and extra code just to provide slightly better debug information in the case where the "get" function is used without proper error checking (i.e. testing if returned value is nullptr or not).

QuoteI can also do this in case of an exception being thrown, can't I?
Yes, you could catch the exception to find out that that the widget didn't exist. So no functionality would be lost. The code wouldn't look as clean as a simple if check though.
#3
The issue is that calling the get function with an incorrect name isn't technically an error, it could be intentional. Otherwise it would be simple: I would just add an assert in the get function, that would immediately alert the developer that he's doing something invalid.

Maybe I could consider some global flag that you could set to cause a get() function to crash when used with an invalid name, but I would first need to verify that TGUI isn't relying on a nullptr being returned internally.

In TGUI 0.6 I had my own smart pointer type instead of using std::shared_ptr. That actually had one big advantage: I could control what happened when attempting to dereference a nullptr. I don't think it's worth going back to something like that, but it would allow better debug information as well. This is however something that I feel the debugger should catch for you. Similar to how "operator[]" asserts in debug mode but not in release mode, I feel like a nullptr dereference should be something that the debugger very clearly tells you about when running the code in debug mode. Some debuggers do a better job than others at showing where the real issue lies in these cases.
#4
The thing that I'm a bit worried about is that it might not always be as useful to throw there. If you have a try-catch in your main function to print the exception and then return from main (which I sometimes even recommend that people do), then the debugger won't tell you where the exception occurred. Although if I include the widget name in the exception error then you would probably still be able to locate the faulty "get" call.

The usability of detecting an issue by throwing an exception really depends on the platform. On my linux system, any assertion or uncaught exceptions will be printed out in the terminal with the error message, even without a debugger attached. On other platforms, it just crashes without printing a message. I've had multiple people ask me in the past why there code was crashing where it turned out to be an uncaught exception, which is the reason why I often recommend the try-catch in the main function: so that these people would be able to see what is going wrong. The exact same advice is however bad for people who do use a debugger properly, as they get a better output without catching the exception.

The "get" function isn't going to change for backwards compatibility and because I'm not convinced that it should throw (because I try to only throw things that might be called during initialization). So the only thing that I can do is add a new "tryGet" function. The problem with that is that you need to change your code to always use the new function everywhere, and I'm not sure if it really helps much. The debugger will stop inside the "tryGet" function on failure, so you would still need to get a call stack to figure out where the function was called. The exact same "bt" command in gdb would probably also tell you that there is a nullptr in "pic->getRenderer()->setTexture(texture);" though. Although I admit that the call stack with the exception would be slightly more useful if you don't know what to look for.
#5
The "get" function isn't guaranteed to succeed, the documentation states that it will return a "nullptr" if it can't find the widget.

The only thing that I could do to improve this situation is to create an alternative getter that would throw an exception instead of returning a nullptr.

Does the debugger give you an address when the segmentation fault occurs? It should, and the address should be very close to 0 for this crash. If you see this, then the first thing to check is if you are calling a function on a nullptr. This can be helpful to more easily find what is causing the crash.

Another useful thing to look at if you get a crash is the call stack. If you have the debug symbols for TGUI then it might even literally contain that the this pointer is 0x0 inside the Picture function.
#6
TGUI doesn't just support SFML, it can also be used with e.g. SDL or GLFW. I designed the library so that it could be built with multiple of these backends simultaneously and that the backend would be selectable at runtime. The downside of that is that until the backend code is loaded, TGUI has no idea which implementation of tgui::Texture it should use (loading the image is completely different in SFML vs SDL).

So somewhere at the beginning of your code you need to initialize the SFML_GRAPHICS backend after which you can actually use TGUI (as loading the backend initializes the internals of the library). While you can manually create the backend object, for simplicity it is tied to the Gui object by default. If you create the Gui object, it will automatically initialize the backend if no backend was loaded yet. This however means that unless you manually initialize the backend, you must load the Gui object before you do anything else with the TGUI library.

Essentially creating and destroying the Gui object acts like global TGUI_Init() and TGUI_Destroy() functions.

One extra detail to note: if the Gui object is created WITHOUT a window, then the backend still won't be initialized until the gui is given a window, so a window needs to be attached to the gui before you can load the texture (because only then does TGUI have access to the OpenGL context from the SFML window).
#7
That assertion means you are trying to create the Texture before the Gui has been constructed.
#8
You can temporarily disable the onValueChange signal:
Code (cpp) Select
SpindleControl2->onValueChange.setEnabled(false);
SpindleControl2->setValue(BalancedValue);
SpindleControl2->onValueChange.setEnabled(true);
#9
The most efficient way is to calculate it yourself on a resize event, but you can actually let TGUI do this automatically.

If you know the ratio is 4/3, you can use this code:
pic->setPosition("(&.size - size) / 2");
pic->setSize({"min(&.w, &.h * 4/3)", "min(&.h, &.w * 3/4)"});

Or if you don't know the ratio you can calculate it on runtime and change the above setSize call to the following (this code assumes the picture is added to the gui directly, but just replace "gui" with the parent of the picture if not):
pic->setSize({bindMin(bindWidth(gui), bindHeight(gui) * (pic->getSize().x / pic->getSize().y)),
              bindMin(bindHeight(gui), bindWidth(gui) * (pic->getSize().y / pic->getSize().x))});
#10
Installation help / Re: CMake cannot find SFML
31 March 2024, 16:02:24
Quotebut I couldn't find anything. Is it possible that the file is not in the folder and CMake creates it?
The file has to be created by CMake somewhere in your build directory. Deleting the entire build directory should cause it to be recreated from scratch instead of from cached files.

The most important thing is that you got it working now though.
#11
Installation help / Re: CMake cannot find SFML
30 March 2024, 08:59:34
I have no idea how it's even possible, but something looks wrong with that TGUI dll. The size of your dll is smaller than the ones I have. Even the 32bit dlls that I have are still larger than the tgui-d.dll that was generated on your pc.

I've downloaded the "MinGW-w64 13.1.0 - x86_64‑posix‑seh (64bit)" version of TGUI 1.2.0 from https://tgui.eu/download/ and copied the tgui-d.dll from the bin folder of the zip file into your build_directory and afterwards I could run your exe just fine (after also copying xubuntu_bg_aluminium.jpg into the build_directory).

EDIT: Your dll file isn't even recognized as a valid DLL by the tools that I have to dump dll information.
EDIT 2: The first 1536 bytes (= exactly 3 * 512 bytes) in your DLL are all 0-bytes, so the file looks corrupted. Have you tried deleting the file and letting your cmake project generate it again?
#12
Installation help / Re: CMake cannot find SFML
29 March 2024, 08:29:09
I'm not sure how much I can help with this issue.

One thing you could still try is to use the precompiled TGUI libraries for MinGW 64bit instead of building them yourself, although I doubt that it will solve anything.

Have you tried reinstalling the latest Microsoft Visual C++ Redistributable version just to be sure?

Could you create a zip file with the exe, SFML dlls, TGUI dll and the 3 gcc dlls that I mentioned in my previous post and send those to me? Then I can try testing if I find anything weird with it.
Could you also post the current CMake script that you are using? Maybe I can try building the same way here and see if I can reproduce it or not.
#13
Installation help / Re: CMake cannot find SFML
28 March 2024, 19:28:05
0xc000012f seems to mean that the "Microsoft Visual C++ Redistributable" isn't installed, which is a bit weird in this case. To run any software that was build with Visual Studio, you need to have the redistributable installed for that Visual Studio version. It raises a question though: what code is built with Visual C++? You are building with MinGW, the precompiled SFML libraries were build with MinGW, and TGUI is being build together with your project and also with the MinGW compiler.

Is the bin directory of your MinGW compiler in your PATH environment variable?
Just to be safe, can you copy libgcc_s_seh-1.dll, libstdc++-6.dll and libwinpthread-1.dll from "C:\mingw64\bin\" and place them next to your exe?
#14
Installation help / Re: CMake cannot find SFML
28 March 2024, 18:32:01
Somewhere inside your "c:/Users/luka-/OneDrive/Desktop/AutoBackupScript2/build" folder. Probably inside the "TGUI/lib/Debug" subdirectory.

There is a way to let CMake automatically copy the dll when building. Try adding the following to your cmake script: (I didn't test this so it might not work as-is)
Code (cmake) Select
add_custom_command(
    TARGET AutoBackupScript POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:tgui>" "."
    VERBATIM)
#15
Installation help / Re: CMake cannot find SFML
28 March 2024, 08:39:33
QuoteCould I be overlooking something, such as copying .dll files or a similar requirement?
It's possible, but it's hard to say if you don't actually get an error message. Are the sfml and dll files placed next to the exe?

I don't really know VS Code. Do you have some process output somewhere? If the program crashes then it usually sets a return value other than 0. If you find some output with something similar to "program exited with code ..." then you can usually search online for that code to determine whether it ended due to a missing dll, an access violation or an uncaught exception.

There are 2 things you can test:
1) Run the exe from file explorer instead of from the IDE. If it won't run due to a missing dll, you will get an error when attempting to run the exe like that.
2) If something goes wrong in TGUI (e.g. a file can't be loaded), then it will throw an exception. If you don't catch this exception then the program terminates.

Do something like this in the main function to print something to the command line when an exception occurs, so that you can see what went wrong. I'm not sure if you will be able to see the text printed somewhere, but you might also be able to e.g. put a breakpoint in the catch code to test if it passes there. The "e.what()" value is a string that contains the TGUI error message.
Code (cpp) Select
int main()
{
    try
    {
        // <Put your existing code here>
        return 0;
    }
    catch (const tgui::Exception& e)
    {
        std::cerr << "TGUI exception: " << e.what() << std::endl;
        return 1;
    }
}