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

Author Topic: ImageManager  (Read 4072 times)

0 Members and 1 Guest are viewing this topic.

Olof Larsson

  • Newbie
  • *
  • Posts: 4
    • View Profile
ImageManager
« on: May 08, 2010, 10:16:36 pm »
http://www.sfml-dev.org/tutorials/1.6/graphics-sprite.php
At the end of that tutorial it's written:

Quote
In a more complex engine, images would be automatically handled by a manager. This is a more generic and easy way of handling resources. The idea is to make the manager store the images, associated to their filename (or whatever unique identifier), so that if the same image is requested several times, the same instance will actually always be returned by the manager.
Code: [Select]
sf::Sprite Sprite;

// GetImage will always return the same image for the same filename
Sprite.SetImage(ImageManager.GetImage("data/missile.png"));



However there is no ImageManager class bundled with SFML currently right?  :(

So i tried to write one:  :D
Code: [Select]

class Image_manager
{
private:
map<string, sf::Image> image_map;

public:
const sf::Image& GetImage(string image_path) // The filename is used as a key
{
// Is this image is not loaded - load it
if(image_map.find(image_path) == image_map.end())
{
sf::Image tmp;
if(!tmp.LoadFromFile(image_path))
{
exit(EXIT_FAILURE);
}

image_map.insert( pair<string,sf::Image>(image_path,tmp) );
}

return image_map[image_path];
}

void InformUs() const
{
cout << "These are the images we have loaded:" << endl;
for(map<string, sf::Image>::const_iterator it = image_map.begin(); it != image_map.end(); ++it)
{
   cout << it->first << endl;
}
}
};


How can the class above be improved?
Is an ImageManager bundled with SFML2?

panithadrum

  • Sr. Member
  • ****
  • Posts: 304
    • View Profile
    • Skyrpex@Github
    • Email
ImageManager
« Reply #1 on: May 08, 2010, 11:11:40 pm »
I would work with pointers: copying images is a high cost function.

You could insert an empty image and then loading, instead.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
ImageManager
« Reply #2 on: May 08, 2010, 11:30:51 pm »
Check wiki for alternatives.
SFML / OS X developer

Olof Larsson

  • Newbie
  • *
  • Posts: 4
    • View Profile
ImageManager
« Reply #3 on: May 09, 2010, 01:14:45 am »
Quote from: "panithadrum"
I would work with pointers: copying images is a high cost function.

You could insert an empty image and then loading, instead.


Where am I copying the image?  :shock:
Im new to this const & ** *& *& * &*&*  stuff  :lol:

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
ImageManager
« Reply #4 on: May 09, 2010, 01:18:08 am »
here :
Code: [Select]
image_map.insert( pair<string,sf::Image>(image_path,tmp) );
SFML / OS X developer

nulloid

  • Full Member
  • ***
  • Posts: 134
    • View Profile
ImageManager
« Reply #5 on: May 09, 2010, 01:20:30 am »
Well.. in C++, arguments in a function are passed by value. So if you have a class "BigObject", and you call doSomethingWith(BigObject), than a copy of BigObject will be passed to the function. So here you copy the object. If you want to avoid this, you have to use references (&) or pointers (*). I suggest you to read about the at http://cplusplus.com or http://cppreference.com.
(I'm not sure if you did know that, but just to be sure :D)

Olof Larsson

  • Newbie
  • *
  • Posts: 4
    • View Profile
ImageManager
« Reply #6 on: May 09, 2010, 01:52:07 am »
Ok, thank's! I saw in the wiki that there are allready neat implementations for resource managers :)
For example: http://www.sfml-dev.org/wiki/en/sources/resource_manager
Thank you.

But anyways - would this solve the copy problem?
Are there any copy situations left?
Code: [Select]

class Image_manager
{
private:
map<string, sf::Image> image_map;

public:
const sf::Image& GetImage(string image_path) // The filename is used as a key
{
// Is this image is not loaded - load it
if(image_map.find(image_path) == image_map.end())
{
pair<string, sf::Image> path_image_pair;
path_image_pair.first = image_path;
if(!path_image_pair.second.LoadFromFile(image_path))
{
exit(EXIT_FAILURE);
}

image_map.insert( path_image_pair );
}

return image_map[image_path];
}
};

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
ImageManager
« Reply #7 on: May 09, 2010, 11:51:11 am »
When you insert an object into your map the object is copied. Ths your image too.

To avoid copy use sf::Image* or a smart pointer.
SFML / OS X developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
ImageManager
« Reply #8 on: May 09, 2010, 11:57:24 am »
Or insert an empty image then load it (instead of inserting an already loaded image). Copying an empty image doesn't cost much.
Laurent Gomila - SFML developer

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
ImageManager
« Reply #9 on: May 09, 2010, 11:59:52 am »
You're always smarter ^^
SFML / OS X developer