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

Author Topic: Creating std::vector of sf::Image/Sound  (Read 11330 times)

0 Members and 3 Guests are viewing this topic.

RetroX

  • Newbie
  • *
  • Posts: 13
    • View Profile
Creating std::vector of sf::Image/Sound
« on: March 07, 2010, 03:36:22 am »
This is probably a frowned-upon method of doing things.

Would it be considered "safe" to create an std::vector of sf::Image, to act as an array?  I use it as a way to store dynamically-sized arrays of loaded images, but after reading the tutorial, it warns on Image-loading and the like, and I'd like to just ask for a general opinion.  It hasn't caused any problems on my new box (3.4GHz x4, 4GB, Arch Linux/Win7) or my old box (1.2GHz x1, 512MB, Arch Linux/Win2k).

For example, the following code:
Code: [Select]
std::vector<sf::Image> array;
array.resize(2);
if (!array[0].LoadFromFile("image.png") || !array[1].LoadFromFile("image2.png"))
 {
 exit(EXIT_FAILURE);
 }

(obviously, in this case, you'd just use sf::Image array[2], but as a concept)

I have no idea how std::vector or sf::Image work, so, I figured that I'd ask this.

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
Creating std::vector of sf::Image/Sound
« Reply #1 on: March 07, 2010, 05:24:48 am »
For your question about std::vector vs. array, vectors are usually preferred, because they can do anything an array can do, and more.
Once you get into vectors, you are going to love them! :)

Actually, I can't even remember the last time I used an array. I simply just can't find a good reason to use them.

Also, when you have learned about vectors, you will want to look into iterators, too, and then later, the other STL containers. A whole world of possibilities will open up for you.

Happy learning! :)

Walker

  • Full Member
  • ***
  • Posts: 181
    • View Profile
Creating std::vector of sf::Image/Sound
« Reply #2 on: March 07, 2010, 05:38:12 am »
I don't think there is any issue with your example. I think the problems the tutorial mentions come when you copy images.

I just had a skim through the image/sprite tutorial and it even mentions (at the end) that you can use an "image manager", which sounds similar to what you are doing.

Vectors are pretty awesome :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Creating std::vector of sf::Image/Sound
« Reply #3 on: March 07, 2010, 09:56:53 am »
Quote
Would it be considered "safe" to create an std::vector of sf::Image, to act as an array?

Absolutely. The only thing that you must keep in mind is that some operations (such as adding an element) may move all the vector elements elsewhere in memory, invalidating all the sprites that previously pointed to them.

Quote
Actually, I can't even remember the last time I used an array. I simply just can't find a good reason to use them.

Using a vector everywhere is a mistake, if your array is not dynamic then just use a raw array (or boost.array) ;)
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Creating std::vector of sf::Image/Sound
« Reply #4 on: March 07, 2010, 12:45:22 pm »
Probably, std::list is the better choice here. It has two big advantages: Adding an element always takes constant time, while vectors might reallocate their whole sequence, unnecessarily copying thousands of pixels. The second pro is that iterators, references and pointers to the elements of std::list remain valid. You probably don't need random access, and the small node overhead of the doubly linked list is negligible compared to the memory required by sf::Image.

However, if your container has a constant size which is known at compile time, then I'll recommend std::tr1::array. This class behaves like a raw array, except that it's more comfortable and secure in debug-mode.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

RetroX

  • Newbie
  • *
  • Posts: 13
    • View Profile
Creating std::vector of sf::Image/Sound
« Reply #5 on: March 07, 2010, 06:59:56 pm »
The main reason that I asked was because of std::vector's capacity allocation; I wasn't sure if in doing that, it would create tons of unused images, taking up a load of memory.

Anyways, thanks for the help.  I'll look into seeing if std::list is a better solution, as well.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Creating std::vector of sf::Image/Sound
« Reply #6 on: March 07, 2010, 07:11:45 pm »
Quote
The main reason that I asked was because of std::vector's capacity allocation; I wasn't sure if in doing that, it would create tons of unused images, taking up a load of memory.

std::vector allocates more memory than what is necessary to store the elements, but it's unused memory, no dummy instance is created.
Laurent Gomila - SFML developer

OniLinkPlus

  • Hero Member
  • *****
  • Posts: 500
    • View Profile
Creating std::vector of sf::Image/Sound
« Reply #7 on: March 07, 2010, 07:25:52 pm »
Another way you could go about doing this is use a std::map where the key is the filename, in order to write an efficient image manager, but I am not sure if it pulls a std::vector and moves the entire array occasionally on the addition of a new element, or if it goes the double-linked list route.
I use the latest build of SFML2

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Creating std::vector of sf::Image/Sound
« Reply #8 on: March 07, 2010, 10:39:50 pm »
Quote from: "OniLink10"
I am not sure if it pulls a std::vector and moves the entire array occasionally on the addition of a new element, or if it goes the double-linked list route.
Neither of them. std::map arranges its elements in a tree structure. Like at std::list, Iterators remain valid and the single elements are not copied when the map grows. In contrast, access, insertions and removals have a complexity of O(log(n)).
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
Creating std::vector of sf::Image/Sound
« Reply #9 on: March 07, 2010, 10:52:54 pm »
Quote from: "Laurent"
Quote
Would it be considered "safe" to create an std::vector of sf::Image, to act as an array?

Absolutely. The only thing that you must keep in mind is that some operations (such as adding an element) may move all the vector elements elsewhere in memory, invalidating all the sprites that previously pointed to them.
That certainly is an important point, that I had not thought about... Thanks for making it clear!

Quote from: "Laurent"
Quote
Actually, I can't even remember the last time I used an array. I simply just can't find a good reason to use them.

Using a vector everywhere is a mistake, if your array is not dynamic then just use a raw array (or boost.array) ;)
Why is that a mistake? Vectors make iterating over the entire array much simpler, for instance, as it knows about its size. Is it wrong to use a vector as a safer array, with more features?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Creating std::vector of sf::Image/Sound
« Reply #10 on: March 07, 2010, 11:12:41 pm »
Quote
Why is that a mistake? Vectors make iterating over the entire array much simpler, for instance, as it knows about its size. Is it wrong to use a vector as a safer array, with more features?

I'm not talking about raw dynamic arrays, which should indeed never be used, I'm talking about static arrays. If you want 10 ints then use a int[10] (or a boost::array<int, 10>), not a std::vector<int>.
Laurent Gomila - SFML developer

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
Creating std::vector of sf::Image/Sound
« Reply #11 on: March 07, 2010, 11:16:40 pm »
Quote from: "Laurent"
Quote
Why is that a mistake? Vectors make iterating over the entire array much simpler, for instance, as it knows about its size. Is it wrong to use a vector as a safer array, with more features?

I'm not talking about raw dynamic arrays, which should indeed never be used, I'm talking about static arrays. If you want 10 ints then use a int[10] (or a boost::array<int, 10>), not a std::vector<int>.
Sure, I understand that, but why is vector not good for that? I am just trying to get smarter :)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Creating std::vector of sf::Image/Sound
« Reply #12 on: March 07, 2010, 11:18:34 pm »
Quote from: "model76"
Why is that a mistake? Vectors make iterating over the entire array much simpler, for instance, as it knows about its size. Is it wrong to use a vector as a safer array, with more features?
It's always wrong to use something everywhere just because it has some advantages. Never stop thinking. ;)

An array with automatic storage (such as T[size] or std::tr1::array<T, size>) fits better when 1. the size is constant and known at compile time and 2. you need a very fast memory allocation. In contrast, the std::vector<T> comes with overhead you don't need.

However, I would still prefer std::tr1::array over raw arrays because this class has a STL-compatible interface with methods such as begin(), end() or size(). Additionally, a useful implementation places assertions in debug-mode so that errors like out-of-ranges are caught. And on modern compilers, there's no reason why the class should be slower.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Creating std::vector of sf::Image/Sound
« Reply #13 on: March 07, 2010, 11:21:05 pm »
Quote
Sure, I understand that, but why is vector not good for that?

Why do you think it is good for that?
Laurent Gomila - SFML developer

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
Creating std::vector of sf::Image/Sound
« Reply #14 on: March 08, 2010, 12:37:46 am »
Nexus -> Nice thorough, comprehensible explanation - Thanks! :)
It still leaves me thinking that std::vector is the best solution in most cases, though, provided that we stick to current standard C++. If we include boost and non-standard extensions, such as tr1, sure, there are probably better solutions. But I don't use those (yet), and I am guessing the original poster doesn't either.

Laurent -> I already gave you an example of that, and if you look at the last paragraph in Nexus' post, you can find even more reasons. You, however, have not stated one single reason why an olden timey array would be better for anything. :shock:
Luckily, Nexus was kind enough to do so, so don't worry about it. :)