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

Author Topic: Why is sf::Music non-copyable?  (Read 3559 times)

0 Members and 1 Guest are viewing this topic.

Schulterblatt

  • Newbie
  • *
  • Posts: 2
    • View Profile
Why is sf::Music non-copyable?
« on: April 29, 2015, 07:35:49 pm »
class MusicManager
{
private:
        std::vector<sf::Music> music;
        int iCrt;

public:
        void Add(const std::string& s)
        {
                sf::Music m;
                if (!m.openFromFile(s)) return;
                music.push_back(std::move(m));
        }

        void SetCurrent(int index)
        { iCrt = index; }

        sf::Music& GetCurrent()
        { return music[iCrt]; }
};

int main()
{
        MusicManager mm;
        mm.Add("content/audio/music/Caught.wav");
        mm.SetCurrent(0);
        mm.GetCurrent().play();

        getchar();
}
 

Since sf::Music inherits from sf::NonCopyable, this code will not run, giving me the error message error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable' using Visual C++ 12.

Why is sf::Music non-copyable? Neither sf::Sound nor sf::SoundBuffer has this restriction.

The only way I've found to fix this is to use an array of sf::Music* and create each one on the stack individually.

(Sorry if this has already been explained elsewhere, but I couldn't find it anywhere in SFML's documentation.)
« Last Edit: April 29, 2015, 07:37:40 pm by Schulterblatt »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Why is sf::Music non-copyable?
« Reply #1 on: April 29, 2015, 08:31:05 pm »
Why is sf::Music non-copyable? Neither sf::Sound nor sf::SoundBuffer has this restriction.
It doesn't make sense to copy it because it doesn't hold the entire music data. It rather streams, i.e. loads audio samples on demand.

You would need move semantics anyway, not copy semantics. Those will be supported when SFML switches to C++11.

The only way I've found to fix this is to use an array of sf::Music* and create each one on the stack individually.
You cannot use the stack for a dynamically sized container.

I would use std::vector<std::unique_ptr<sf::Music>>, a container of smart pointers. That's safe and comfortable, as you don't need to manage memory.
auto ptr = std::make_unique<sf::Music>();
if (!ptr->openFromFile(...))
   /* error */

std::vector<std::unique_ptr<sf::Music>> themes;
themes.push_back(std::move(ptr));

Consult www.cppreference.com if necessary.
« Last Edit: April 29, 2015, 08:32:51 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Schulterblatt

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Why is sf::Music non-copyable?
« Reply #2 on: April 29, 2015, 10:00:16 pm »
Quote
You cannot use the stack for a dynamically sized container.
Sorry, I meant the heap.

Quote
Those will be supported when SFML switches to C++11.
I didn't know that it hadn't. Come to think of it, that would explain the lack of rvalue references.

Well, thank you for the explanation!

 

anything