raylib-cpp
raylib-cpp copied to clipboard
Wrapper is no longer recognizing set() and IsReady() functions for some reasons
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.
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.
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.
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);
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.
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 ?
Yes, it worked.
Missed click.
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:
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.
I really would like to get some help if you didn't give up heh
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.
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.
I believe it could be because of the static usage. Maybe use a static object pointer instead?
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.
Hmm, interesting. Thanks for sharing the debug log. Is it segfaulting on load? I do know that LoadTexture only works after InitWindow...
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.
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.
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.
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: