raylib-cpp icon indicating copy to clipboard operation
raylib-cpp copied to clipboard

Wrapper is no longer recognizing set() and IsReady() functions for some reasons

Open byjove01 opened this issue 2 years ago • 18 comments

Hey. I'm trying to make a resource manager with raylib-cpp (nice wrapper btw) but I'm meeting a problematic issue : it seems like when I launch my program, no window appears, because the render loop doesn't launch. I just get the console telling me it "successfully" loaded the first sprite it found in the "assets" folder, then it stops. I launch the GDB debugger and I get directly a segmentation fault, not really from my resource manager code, but from the "Texture.hpp" header file, at the 144th line with the error Use of undeclared identifier "set".. I also get the same error with the below line, with the IsReady() function.

I definitely don't understand what the hell is happening, it feels so frustrating... I don't think I forgot any necessary header files, or making really beginner-level mistakes - I could still be wrong, but it seems like it definitely come from the wrapper files. I am on Arch btw. If needed, here is the original code. Thanks in advance for the help.

code.txt

byjove01 avatar Apr 12 '22 21:04 byjove01

Certainly is strange. Here is the Load() function you're hitting...

    /**
     * Load texture from file into GPU memory (VRAM)
     */
    bool Load(const std::string& fileName) {
        set(::LoadTexture(fileName.c_str()));
        return IsReady();
    }

Since it's loading into VRAM, you will want to make sure the Window is loaded first. Use of undeclared identifier "set" is more curious though, since the set function definitely is part of Texture.

RobLoach avatar Apr 22 '22 04:04 RobLoach

The Window is definitely loaded in my engine's constructor function so I don't think it's related to this. However, I just realized I'm using C++11 properties like smart pointers to create my resource manager.

template<typename T>
using ptr = std::unique_ptr<T>;

std::map<std::string, ptr<raylib::Texture>> ResManager::m_Textures { std::map<std::string, ptr<raylib::Texture>>() };
std::map<std::string, ptr<raylib::Music>> ResManager::m_Musics { std::map<std::string, ptr<raylib::Music>>() };
std::map<std::string, ptr<raylib::Sound>> ResManager::m_Sounds { std::map<std::string, ptr<raylib::Sound>>() };

Could the main issue be the interaction of these modern C++ concepts and the fact Raylib being a C-based library ? I don't know how compatible the C standard used by Raylib and C++11 are, so I feel forced to not neglect any potential hint.

byjove01 avatar Apr 25 '22 18:04 byjove01

This works... Make sure to set C++14 in your compiler tho.

// Init
std::map<std::string, ptr<raylib::Texture>> textures {std::map<std::string, ptr<raylib::Texture>>()};

// Load
textures.emplace("ps3", std::make_unique<raylib::Texture>("resources/ps3.png"));

// Draw
textures["ps3"]->Draw(10, 10);

RobLoach avatar May 02 '22 05:05 RobLoach

I'm on C++17 and it just doesn't work. The IDE has nothing to say when I browse the wrapper files by myself, but start to go nuts when I am trying to debug my program. I noticed I didn't say to you my resource manager is supposed to be static... if that can help. I also tried your example, the same problem happens, it doesn't look to be related to the unique_ptr object or the <map> container but really with this set() weird problem.

Also, I asked CMake to only search and include the raylib library. Did I do well? Because I saw a Cmake template in the main README with a find_package(raylib_cpp) before including that library to the project. I don't know the hell how library linking works (and I am not sure I want to) but my problem could be related to a missing link. I tried to do the same on my side, but CMake couldn't find any library as the one in the example.

byjove01 avatar May 02 '22 07:05 byjove01

Are you able to compile one of the basic examples? Like https://github.com/RobLoach/raylib-cpp/blob/master/examples/core/core_basic_window.cpp ?

RobLoach avatar May 02 '22 07:05 RobLoach

Yes, it worked.

byjove01 avatar May 02 '22 19:05 byjove01

Missed click.

byjove01 avatar May 02 '22 19:05 byjove01

I noticed I didn't say to you my resource manager is supposed to be static

Another note...static variables will be destroyed when the program terminates, so may want to be careful with that :wink:

RobLoach avatar May 02 '22 20:05 RobLoach

That's intended, I anyways don't want to stock my resources for a longer time than the program lifetime itself :) Just in case, compiling your example worked, but I still got this weird set() problem... heh.

byjove01 avatar May 03 '22 05:05 byjove01

I really would like to get some help if you didn't give up heh

byjove01 avatar Jun 15 '22 12:06 byjove01

Could you send a larger snippet of your code? It's difficult to understand what's happening without a use case. Or try to put together an example of it.

RobLoach avatar Jun 15 '22 14:06 RobLoach

Could you send a larger snippet of your code? It's difficult to understand what's happening without a use case. Or try to put together an example of it.

After some readings of my own code, I realized I don't even need to give you my own code : the code example you gave days ago just does the exact same result. With no additions on my side. As my object is using static containers and functions, I thought it could be related but apparently it's not, because the segfault issue happens without this object being even declared.

byjove01 avatar Jun 25 '22 16:06 byjove01

I believe it could be because of the static usage. Maybe use a static object pointer instead?

RobLoach avatar Jun 25 '22 17:06 RobLoach

I really don't want to look tough, but you should read my posts entirely xD Without my static class' header being included in the main.cpp file - implying it's not working by any way - I still get the segfault error. The only code left in my main.cpp is the code sample you gave me higher in the thread:

// Init std::map<std::string, ptrraylib::Texture> textures {std::map<std::string, ptrraylib::Texture>()};

// Load textures.emplace("ps3", std::make_uniqueraylib::Texture("resources/ps3.png"));

// Draw textures["ps3"]->Draw(10, 10);

Here's the debug callstack I got after the error got noticed.

5 raylib::Texture::Load Texture.hpp 144 0x562447d56aa1 6 raylib::Texture::Texture Texture.hpp 66 0x562447d56967 7 std::make_unique<raylib::Texture, char const (&) [88]> unique_ptr.h 1065 0x562447d56d71 8 main main.cpp 17 0x562447d566ce

It's really as much weird as it's frustrating... I've looked several times through my CMakeLists.txt but everything seems to be well installed, and in other ways, raylib and the wrapper are both perfectly working.

byjove01 avatar Jun 25 '22 19:06 byjove01

Hmm, interesting. Thanks for sharing the debug log. Is it segfaulting on load? I do know that LoadTexture only works after InitWindow...

RobLoach avatar Jun 26 '22 05:06 RobLoach

Yes, directly on Load(). I'd like to give you more info but sadly the debugger won't give me more. The only think I can remind you is that the compiler literally denies the existence of set() and IsReady() functions in raylib-cpp files.

byjove01 avatar Jun 26 '22 06:06 byjove01

These... should likely be part of the constructor...

auto& m = m_Musics[entryName] = std::make_unique<raylib::Music>();
m->Load(filePath);

auto& s = m_Sounds[entryName] = std::make_unique<raylib::Sound>();
s->Load(filePath);

// Use constructor?
m_Musics[entryName] = std::make_unique<raylib::Music>(filePath);

m_Sounds[entryName] = std::make_unique<raylib::Sound>(filePath);

Throwing some TraceLog()s in there could help you decipher where it fails exactly too.

RobLoach avatar Jun 30 '22 03:06 RobLoach

TraceLog() doesn't give more info, sadly. But strangely, I maybe did succeed to solve the problem. You see, in my main.cpp file, I was asking my static ResManager to load game resources BEFORE my Engine class (that implements the audio initialization, but also the window creation) was running. Suddenly, when I did put my loadResources() invokation between my Engine class declaration, and the use of its run() function, everything started to work.

I don't really know to what it's relatedmaybe some internal Raylib mechanics, but at least, the program is working now.

byjove01 avatar Jun 30 '22 08:06 byjove01

Glad you got it to work! On construction, objects need to understand how to construct its children, and if a Texture tries to load before InitWindow(), things will break :wink:

RobLoach avatar Sep 28 '22 18:09 RobLoach