SFML community forums

Help => General => Topic started by: mendlo on June 15, 2015, 10:44:14 am

Title: Nested pollEvent spikes CPU
Post by: mendlo on June 15, 2015, 10:44:14 am
Hello,

I'm having trouble drawing something in the window upon an event, holding that display, then resetting the display upon another event. I've come up with a solution, however it causes a high spike in CPU utilization. In the code snippet below, the CPU spikes and remains high when [Space] is pressed. The CPU spike goes away when [Escape] is pressed.

How can I implement a better solution for this? Any help appreciated.

#include <SFML/Graphics.hpp>
#include "ResourcePath.hpp"

int main() {
    sf::RenderWindow window(sf::VideoMode(480, 320), "SFML Window");
    window.setFramerateLimit(20);

    sf::Font font;
    if (!font.loadFromFile(resourcePath() + "sansation.ttf")) {
        return 0;
    }
    sf::Text text;
    text.setFont(font);
    text.setCharacterSize(50);
    text.setStyle(sf::Text::Regular);
    text.setColor(sf::Color::Blue);

    while (window.isOpen()) {
        window.clear();
       
        text.setString("Hello SFML");
        window.draw(text);
       
        window.display();

        sf::Event event;
        while (window.pollEvent(event)) {

            if (event.type == sf::Event::Closed) {
                window.close();
                exit(0);
            }

            if (event.type == sf::Event::KeyPressed) {
               
                if (event.key.code == sf::Keyboard::Space) {
                    window.clear();
                   
                    text.setString("You pressed space");
                    window.draw(text);
                   
                    window.display();
                   
                    bool wait = true;
                    while(wait) {
                   
                        while (window.pollEvent(event)) {
                            if (event.type == sf::Event::Closed) {
                                window.close();
                                exit(0);
                            }
                           
                            if (event.type == sf::Event::KeyPressed) {
                                if (event.key.code == sf::Keyboard::Escape) {
                                    wait = false;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
}
 
Title: Re: Nested pollEvent spikes CPU
Post by: eXpl0it3r on June 15, 2015, 10:47:22 am
pollEvent is not supposed to get nested. There should only be one call to it.
If you want to check certain "states", use variables to store things (e.g. whether a key has been pressed).

Also you can't check for the key code without making sure that a key has been pressed.

I suggest you re-read the official tutorial about events. ;)
Title: Re: Nested pollEvent spikes CPU
Post by: mendlo on June 15, 2015, 11:49:24 am
Thank you for the quick and friendly reply!

Is this the tutorial you're referring to? http://www.sfml-dev.org/tutorials/2.0/window-events.php

I'd like to find more information about using the "states" you referred to.

Not checking for KeyPressed in the second loop was a silly mistake when I shrunk my code down into the snippet above. I'll correct that in my OP.
Title: Re: Nested pollEvent spikes CPU
Post by: Jesper Juhl on June 15, 2015, 04:48:49 pm
Latest version of the tutorial: http://www.sfml-dev.org/tutorials/2.3/window-events.php

As far as the 'states' eXploit3r talks about; it's as simple as remembering that a key has been pressed and then checking the variable - like a "bool escapePressed" that you keep updated with true/false according to events received.
@eXploit3r if that's not what you meant; please correct me :)

Edit: and by the way, "x-mas trees" like this are almost always an indication that you are doing something wrong:
Quote
                                }
                            }
                        }
                    }
                }
            }
        }
    }
Title: Re: Nested pollEvent spikes CPU
Post by: Hapax on June 15, 2015, 07:49:03 pm
The comments above are what you should actually do but the reason behind the CPU usage rising is that the loop that waits for the Escape key is continuous. There are no window updates and therefore the window's framerate limit doesn't take effect.
Title: Re: Nested pollEvent spikes CPU
Post by: mendlo on June 16, 2015, 01:36:17 am
Ah ha! I think I have the solution you pointed me to. The code below behaves the same as the code in my original post (as far as I can tell), but without the CPU spike:

#include <SFML/Graphics.hpp>
#include "ResourcePath.hpp"

int main() {
    sf::RenderWindow window(sf::VideoMode(480, 320), "SFML Window");
    window.setFramerateLimit(20);

    sf::Font font;
    if (!font.loadFromFile(resourcePath() + "sansation.ttf")) {
        return 0;
    }
    sf::Text text;
    text.setFont(font);
    text.setCharacterSize(50);
    text.setStyle(sf::Text::Regular);
    text.setColor(sf::Color::Blue);

    while (window.isOpen()) {
        text.setString("Hello SFML");
        window.clear();
        window.draw(text);
        window.display();
       
        bool spacePressed = false;

        sf::Event event;
        while (window.pollEvent(event) || spacePressed == true) {

            if (event.type == sf::Event::Closed) {
                window.close();
                exit(0);
            }

            if (event.type == sf::Event::KeyPressed || spacePressed == true) {
               
                if (event.key.code == sf::Keyboard::Space || spacePressed == true) {
                    spacePressed = true;
                    text.setString("You pressed space");
                    window.clear();
                    window.draw(text);
                    window.display();
                }
               
                if (event.key.code == sf::Keyboard::Escape) {
                    spacePressed = false;
                }
            }
        }
    }
    return 0;
}
 

This code has less "x-mas trees" too (I haven't seen that term before). I'm curious about that. Is the issue with too many "x-mas trees" that it looks ugly and it's easy to make mistakes in, or is there something else that causes this to be an indicator of a problem?

I appreciate all the help. Thank you!
Title: Re: Nested pollEvent spikes CPU
Post by: Hapax on June 16, 2015, 02:40:16 am
Try removing both window.clear(), window.draw(), window.display() blocks and put it once after the event loop.

I would suggest removing all of your instances of 'spacePressed == true'. You could add it to the escape key test but it's not really necessary.