Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Problem with the assetmanager from the book SFML essentials  (Read 2197 times)

0 Members and 1 Guest are viewing this topic.

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Problem with the assetmanager from the book SFML essentials
« on: December 26, 2017, 07:59:41 pm »
I'm having trouble using the AssetManager class from the book SFML Essentials.

The class is a singleton meant to hold sf::Texture. I slightly modified it to store sf::Image instead.

It's causing a strange problem: The code compiles successfully in visual studio 2015 community debug mode, the console window launches, but the sfml window never does. It's stuck in the console window indefinitely, meaning I can't debug it.

Relevant code:

AssetManager.h
public:

AssetManager();
static sf::Image& get_image(std::string const& filename);
static void erase_image(std::string const& filename);

private:

std::map<std::string, sf::Image> m_Images;
static AssetManager* sInstance;
 
AssetManager.cpp
AssetManager* AssetManager::sInstance = nullptr;

AssetManager::AssetManager()
{
        assert(sInstance == nullptr);
        sInstance = this;
}

sf::Image& AssetManager::get_image(std::string const& filename)
{
        auto& iMap = sInstance->m_Images;

        //See if the texture is already loaded
        auto pairFound = iMap.find(filename);
        //If yes, return the texture
        if (pairFound != iMap.end())
        {
                return pairFound->second;
        }
        else //Else, load the texture and return it
        {
                //Create an element in the texture map
                auto& image = iMap[filename];
                image.loadFromFile(filename);
                return image;
        }
}

void AssetManager::erase_image(std::string const& filename)
{
        auto& iMap = sInstance->m_Images;

        iMap.erase(filename);
}
 

Enemy.h
Enemy();
~Enemy();

std::map<std::string, sf::Image> Images;
 
Enemy.cpp
Enemy::Enemy()
{
        Images["Spawn"] = AssetManager::get_image("Spawn.png");
}

Enemy::~Enemy()
{
        AssetManager::erase_image("Spawn.png");
}
 


Here's the really strange part, broken into (steps):

(1) If I remove Enemy's destructor, it still doesn't run.

(2) If I then also remove / comment out the get_image line in Enemy constructor, then it runs but obviously I don't have the image in-game.

(3) If I THEN re-add / uncomment that same line (in the constructor), THEN IT RUNS AND I GET THE IMAGE IN-GAME

(4) If I then re-add the destructor it stops running.

(5) If I then remove the destructor again, it doesn't run! EVEN THOUGH THE EXACT SAME CODE RAN SUCCESSFULLY 2 STEPS AGO! (in step 3)

Does anybody have a clue why this is happening?

I also welcome any opinions on whether this is a good/bad resource manager and if I should switch to some other resource manager.

fallahn

  • Hero Member
  • *****
  • Posts: 502
  • Buns.
    • View Profile
    • Trederia
Re: Problem with the assetmanager from the book SFML essentials
« Reply #1 on: December 26, 2017, 11:19:39 pm »
Currently I prefer the resource manager outlined in SFML Game Development. It's not a singleton, so it relies on scope to help better manage resources: for example you might have an instance of the resource manager in your menu state, and another in the game state. When you load your menu all the resources are held by its own resource manager - and unloaded again as the menu is destroyed and game state loaded. If this were a singleton you'd either have to specifiy resources to unload when switching from your menu to your game state, or live with having all your menu resources loaded even when you're not in a menu, which seems a bit counter-intuitive (to my mind) for a resource manager. If there are resources which do need to be shared between states then passing a reference to the resource manager to each state is easy. Secondly it uses unique_ptr for underlying storage - not only does this help prevent memory leaks and negate the need for manual memory management, it has the advantage of being templated, making it easier to template the resource manager itself. This way switching the resource types from sf::Texture to sf::Image (or even other types such as sf::SoundBuffer) is as simple as supplying a different template parameter. EG:

ResourceManager<sf::Texture> textureResource;
ResourceManager<sf::Image> imageResource;
 

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10924
    • View Profile
    • development blog
    • Email
Re: Problem with the assetmanager from the book SFML essentials
« Reply #2 on: December 26, 2017, 11:52:50 pm »
In my experience, odd behavior most of time originates from corrupted (heap) memory.

If the window doesn't show up it means that you never reach the window creation method. You claim that something can't be debugged because of that, how so?
Set a breakpoint right after int main() and then step through and step into every function to find out what's going on.

And I agree with fallahn the resource manager from the SFML Game Development book is very nice.
You can find the code for it here: https://github.com/SFML/SFML-Game-Development-Book/tree/master/02_Resources
An alternative implementation can be found in Thor's resource holder: http://www.bromeon.ch/libraries/thor/tutorials/v2.0/resources.html
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Re: Problem with the assetmanager from the book SFML essentials
« Reply #3 on: December 27, 2017, 08:30:20 am »
Thank you both for the answers. I'm looking into the managers you guys suggested right now. It's gonna be some work switch from the comfort of the global access singleton, but after reading more about how singletons work I'm convinced that switching is for the better.