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

Author Topic: Using thread on function that have music as argument  (Read 1074 times)

0 Members and 1 Guest are viewing this topic.

Pururuto

  • Newbie
  • *
  • Posts: 2
    • View Profile
Using thread on function that have music as argument
« on: May 19, 2013, 12:46:28 pm »
I'm currently trying to make a game using SFML.
And my idea is, to make a function that ends a music smoothly by decresing its volume to zero before stopping it. As I write two functions that use while statement, I realized that I can't run the screen fade and music ending functions at the same time.
So I tried to use multithreading.
But when I wanted to do that, I got this error :
\include\sfml\system\noncopyable.hpp(67) : see declaration of 'sf::NonCopyable::NonCopyable'

My function code :

void endMusic(sf::Music &music){
sf::Clock clock;
sf::Time volumeDownInterval;
while(1){
if(music.getStatus()!=0){
if(volumeDownInterval>200){
music.setVolume(music.getVolume()-5);
clock.restart();
}
if(music.getVolume<=5)music.stop();
}
}
}

in my main function, I wrote :
int main(){
sf::Music music;
music.openFromFile("music/test.wav");
music.play;
music.setLoop(TRUE);
sf::Thread thread(&endMusic,music);

...


        while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
                }
         if(sf::Mouse::isButtonPressed(sf::Mouse::Left)){
           thread.launch();
           fadeAnimation();
}
}
}

I've also read about Mutexes but I don't think there's an exception from the music function, as I tried it before and had the music to fade out first before the screen fades.
I have known SFML for only a week, so I'd be happy to hear out your opinions about my problem. Thank you.
« Last Edit: May 19, 2013, 12:54:35 pm by Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Using thread on function that have music as argument
« Reply #1 on: May 19, 2013, 12:58:27 pm »
Quote
As I write two functions that use while statement, I realized that I can't run the screen fade and music ending functions at the same time.
This is the wrong approach. What if you now want to animate a character? Of fade a second music? Are you going to spawn a separate thread for every task? Why can't you update all these tasks inside a single loop?

For your problem, there are two solutions:
- sf::Thread thread(&endMusic, std::ref(music)); (C++11 only)
- using a pointer
Laurent Gomila - SFML developer

Pururuto

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Using thread on function that have music as argument
« Reply #2 on: May 19, 2013, 01:12:37 pm »
Quote
As I write two functions that use while statement, I realized that I can't run the screen fade and music ending functions at the same time.
This is the wrong approach. What if you now want to animate a character? Of fade a second music? Are you going to spawn a separate thread for every task? Why can't you update all these tasks inside a single loop?

For your problem, there are two solutions:
- sf::Thread thread(&endMusic, std::ref(music)); (C++11 only)
- using a pointer
Thank you for answering.
Actually, I did modify my code and run both the screen fade and music fade on the same function so they can happen at the same time, I am just curious on the error " \include\sfml\system\noncopyable.hpp(67) : see declaration of 'sf::NonCopyable::NonCopyable'"
So I'll have to use sf::Thread thread(&endMusic, std::ref(music)); or change my function parameter into void endMusic(std::Music *music), right ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Using thread on function that have music as argument
« Reply #3 on: May 19, 2013, 02:40:48 pm »
Yes.

The error happens because sf::Music is not copyable, and your code tries to copy it (the constructor of sf::Thread takes it by copy, that's why you have to use std::ref if you want it to be handled by reference until it reaches your own function -- or use a pointer, which can be copied without hurting anybody).
Laurent Gomila - SFML developer