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

Author Topic: Problem with sf::Sleep  (Read 23740 times)

0 Members and 1 Guest are viewing this topic.

marcin107

  • Newbie
  • *
  • Posts: 23
    • View Profile
Problem with sf::Sleep
« on: February 21, 2014, 12:32:12 pm »
Hi guys, recently i have a big problem with sf::sleep. The problem is that sf::sleep stops the whole application. I'm using sf::sleep only in threads, but in some threads sf::sleep wants to work properly, in some doesn't. 
What is the difference i saw:
When i call the thread during getting event(for example when i press Q then i call the thread), sf::sleep works
but when i made an AI thread in while(window.isOpen()) and not in getting events sf::sleep lags the whole program. Any ideas why it is like that? My whole program has 2800 lines, so it's hard to show you all of them.
while (window.isOpen())
    {
        // ruchy AI
        if(AI_MOVES == 1 && menuswitch == 3)
        {
            if(waitforr != 2)
            {
                if(ordershield == 1 && canuse[2][AI] == 0)
                {
                    ordershield = 0;
                    Wspellenemy();
                }
                random[0] = rand() % 100;
                random[1] = rand() % 100;
                random[2] = rand() % 100;
                thread_aiattackfunction.launch();
            }
            else thread_rspellenemy.launch();

        }
// ...

void aiattackfunction()
{
    if(random[0] >= 0 && random[0] <= 50)
    {
        if(canuse[0][AI] == 0 && blockspells[0][AI] != 1)
        {
            canuse[0][AI] = 1;
            if(random[1] > stats[avoid][USER])
            {
                if(random[2] <= stats[critic][AI])
                    dealdmg(stats[ad][AI]*2, 0);
                else dealdmg(stats[ad][AI], 0);
            }
            else cout << "Uniknalem\n";
        }
    }
    else if(random[0] >= 51 && random[0] <= 75)
    {
        if( canuse[1][AI] == 0 && blockspells[1][AI] != 1)
            Qspellenemy();
    }
    else if(random[0] >= 76 && random[0] <= 100)
    {
        if( canuse[2][AI] == 0 && blockspells[2][AI] != 1)
            Rspellenemy();
    }
}
void Rspellenemy()
{
    if(waitforr != 2 && waitforr != 1)
    {
        if(stunned[0] != 1)
        {
            waitforr = 1;
            canuse[2][AI] = 1;
            T_wait = sf::Time::Zero;
            blockspells[0][AI] = 1;
            blockspells[1][AI] = 1;
            blockspells[2][AI] = 1;
            string15.setString("Press Space!");
        }
    }
    else if(waitforr == 2)
    {
        ultiamount += 1;
        if(ultiamount >= 30)
            S_Rultibar.setTextureRect(sf::IntRect(0, 0, 271, 10));
        else S_Rultibar.setTextureRect(sf::IntRect(0, 0, ultiamount*271/30, 10));
        if(ultiamount == 30) // ignore
        {
            dealdmg(50, USER);
            statrefresh(hp, USER); // update the hp bar
            sf::sleep(sf::milliseconds(200));
            dealdmg(50, USER);
            statrefresh(hp, USER);
            sf::sleep(sf::milliseconds(200));
            dealdmg(50, USER);
            statrefresh(hp, USER);
            sf::sleep(sf::milliseconds(2000));
            blockspells[0][AI] = 0;
            blockspells[1][AI] = 0;
            blockspells[2][AI] = 0;
            waitforr = 0;
        }
        sf::sleep(sf::milliseconds(170));
    }
}
 
The problem is in Rspellenemy before it whole end the program is lagged.
The qeustion is how to do the AI(where to call it), to make its spells not lag the whole program.
if u don't understand what i exactly wrote, please ask, i'll try to translate it better.

« Last Edit: February 21, 2014, 01:40:12 pm by marcin107 »

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Problem with sf::Sleep
« Reply #1 on: February 21, 2014, 01:47:40 pm »
sf::sleep() puts the entire process to sleep. That is what it is supposed to do.
You don't want to use sleeping in threads for synchronization. Use proper primitives like mutexes,semaphores,condition variables etc for that.
But, if possible, avoid threads unless you like headaches and her to debug bugs  :P

marcin107

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Problem with sf::Sleep
« Reply #2 on: February 21, 2014, 02:17:37 pm »
This is a thread which I launch after i press Q
void Qspellplayer()
{
    if(stats[herotype][USER] == 3)
    {
        stats[mana][USER] -= 90;
        statrefresh(mana, USER);
        canuse[1][USER] = 1;
        fireball_fly.play();
        sf::sleep(sf::milliseconds(1000));
        ordershield = 1;
        sf::sleep(sf::milliseconds(1000));
        if(isdead(1) == 0)
        {
            dealdmg(230+stats[ap][USER], 1);
            ordershield = 0;
            fireball_hit.play();
        }
    }
}
 
It works and during sleeps i can press others keys and they will be also working.
Other example when i press R
 canuse[3][USER] = 1;
        multifireball_fly.play();
        sf::sleep(sf::milliseconds(1000));
        ordershield = 1;
        sf::sleep(sf::milliseconds(1000));
        multifireball_hit.play();
        dealdmg(90+stats[ap][USER], 1);
        if(isdead(1) == 0)
        {
            sf::sleep(sf::milliseconds(570));
            dealdmg(90+stats[ap][USER], 1);
        }
        if(isdead(1) == 0)
        {
            sf::sleep(sf::milliseconds(800));
            dealdmg(160+stats[ap][USER], 1);
        }
        ordershield = 0;
 
It is also working without interfering in other functions.
I think that the problem is not in threads but in where the AI moves in code are(i mean just right when the while (window.isOpen()) starts)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Problem with sf::Sleep
« Reply #3 on: February 21, 2014, 02:18:32 pm »
sf::sleep() puts the entire process to sleep. That is what it is supposed to do.
No, sleep() should only affect the current thread. That's also what the SFML documentation says.

But I agree, don't use threads unless they're really necessary. And before you do so, make sure you know C++ well enough and you've read the theoretical backgrounds of multithreading.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Problem with sf::Sleep
« Reply #4 on: February 21, 2014, 02:20:20 pm »
My mistake. I was mixing up sleep functions from different libraries.
Sorry about that.

marcin107

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Problem with sf::Sleep
« Reply #5 on: February 21, 2014, 02:41:38 pm »
So how to correct it? My spells threads launched by event loop work, only AI got some problems and not with order of execution tasks, but with sf::sleep.(or i didn't get it how mutexes work)
Mutexes aren't related with threads?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Problem with sf::Sleep
« Reply #6 on: February 21, 2014, 02:54:24 pm »
Of course mutexes are related to threads... You really need to learn the basics instead of randomly doing things.

So how to correct it?
As stated, avoid multithreading. I don't see why you need it.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

marcin107

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Problem with sf::Sleep
« Reply #7 on: February 21, 2014, 07:21:13 pm »
So if i have to avoid threads, what can i replace sf::sleep with?
It's my first project in SFML i'm beginner and i don't understand enough.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Problem with sf::Sleep
« Reply #8 on: February 21, 2014, 07:27:56 pm »
What do you actually want to achieve? You somehow think that sf::sleep() is the solution, but what is even the problem (from a high-level standpoint)?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

marcin107

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Problem with sf::Sleep
« Reply #9 on: February 21, 2014, 07:43:37 pm »
Here is my project, please download(coudn't attach here 13MB) it and follow in menu's - "Start, priest, Walka"
http://speedy.sh/Mt95A/sfml-project.rar
In "walka" you can see, that i use other functions(on keyboard Q, W, E, R) which needs to wait some time to synchronize it with sounds.
« Last Edit: February 21, 2014, 08:04:50 pm by marcin107 »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Problem with sf::Sleep
« Reply #10 on: February 21, 2014, 08:07:30 pm »
Can't you describe your problem here? People don't want to download a whole project and guess from it what might be the issue...

Please read this thread, it will help you ask the right questions and get meaningful answers.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

marcin107

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Problem with sf::Sleep
« Reply #11 on: February 21, 2014, 08:29:44 pm »
Okey so i'll try to explain again.
My game is a real time fight. In game i created a spell called fireball
This is a code of fireball
        statrefresh(mana, USER);
        canuse[1][USER] = 1;
        fireball_fly.play();
        sf::sleep(sf::milliseconds(1000));
        ordershield = 1;
        sf::sleep(sf::milliseconds(1000));
        if(isdead(1) == 0)
        {
            dealdmg(230+stats[ap][USER], 1);
            ordershield = 0;
            fireball_hit.play();
        }
I use a sleep function to make an effect more realistic i play sound, then the program wait 1sec to order enemy to use his shield, then again one second to hit the enemy with fireball. This is why i use sleep.
Everything would be fine, if i wouldn't start to make spells for enemy. Because the game is a real time fight i coudn't make an enemy ai to answer only on my moves(example: i use fireball, then he use shield), so i had to make ai "get random" function for moves put at the begging of main loop. When i use sleep function in any thread, which starts from "ai make move" function it doesn't work properly, it stops the whole game. To compare the situation when i use my spell which is associated to my Q bind keyboard event it doesn't sleep my whole program. Why it is like that?
This is my beginning of program main loop
 
while (window.isOpen())
    {
        if(AI_MOVES == 1 && menuswitch == 3)
        {
            if(waitforr != 2)
            {
                if(ordershield == 1 && canuse[2][AI] == 0)
                {
                    ordershield = 0;
                    Wspellenemy();
                }
                random[0] = rand() % 100;
                random[1] = rand() % 100;
                random[2] = rand() % 100;
                thread_aiattackfunction.launch();
            }
            else thread_Rspellenemy.launch();

        }
 
Okey, so let's suppose that our waitforr variable is equal to 2
This is the thread and case of waitforr equal to 2
Code: [Select]
...
else if(waitforr == 2)
    {
        ultiamount += 1;
        if(ultiamount >= 30)
            S_Rultibar.setTextureRect(sf::IntRect(0, 0, 271, 10));
        else S_Rultibar.setTextureRect(sf::IntRect(0, 0, ultiamount*271/30, 10));
        if(ultiamount == 30)
        {
            dealdmg(50, USER);
            statrefresh2;
            sf::sleep(sf::milliseconds(200));
            dealdmg(50, USER);
            statrefresh2();
            sf::sleep(sf::milliseconds(200));
            dealdmg(50, USER);
            dealdmg(150, USER);
            sf::sleep(sf::milliseconds(2000));
statrefresh2();
            blockspells[0][AI] = 0;
            blockspells[1][AI] = 0;
            blockspells[2][AI] = 0;
            waitforr = 0;
        }
        sf::sleep(sf::milliseconds(170));
    }
Here the sf::sleep lags my whole program not the thread <-- this is the problem.
« Last Edit: February 21, 2014, 08:35:26 pm by marcin107 »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Problem with sf::Sleep
« Reply #12 on: February 21, 2014, 08:37:48 pm »
You don't want sleep because it blocks the thread. Why don't you use sf::Clock, or even better, count the fixed-timestep frames to know when the effect is over?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

marcin107

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Problem with sf::Sleep
« Reply #13 on: February 21, 2014, 08:47:03 pm »
fixed-timestep - i really don't what it is, as i told you, it's my first project in SFML.
About sf::Clock in my opinion it takes a bit too much space.
My example
if (T_baseattackcd2 >= baseattackcooldown2 && menuswitch == 3 && canuse[0][AI] == 1)
        {
            canuse[0][AI] = 0;
            T_baseattackcd2 = sf::Time::Zero;
            // cooldown finished
        }
        else if(canuse[0][AI] == 0)
        {
            T_baseattackcd2 = sf::Time::Zero;
        }
 
And during the fight i have already 10 working clocks, so or there is easier way to make it for my example than i know, or clocks in this case for me is complicated to use.

Rosme

  • Full Member
  • ***
  • Posts: 169
  • Proud member of the shoe club
    • View Profile
    • Code-Concept
Re: Problem with sf::Sleep
« Reply #14 on: February 22, 2014, 06:41:13 am »
sf::Clock is lightweight. You could easily implement a trigger timer that would trigger a callback function at certain interval.

As for the fixed-timestep, a little bit of research wouldn't do you any bad. First link would be the one you're searching for. And such theory is unrelated to the SFML. It's related to game in general.
GitHub
Code Concept
Twitter
Rosme on IRC/Discord