SFML community forums

Help => System => Topic started by: MrPlow442 on August 01, 2013, 02:37:04 am

Title: Weirdness with sf::Clock and sf::Time
Post by: MrPlow442 on August 01, 2013, 02:37:04 am
For some reason when using a modulus operator with sf::Time it doesn't seem to work properly for me

#include <iostream>

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>

int main()
{
        sf::RenderWindow window(sf::VideoMode(100,100,32), "Clock test");
        window.setVerticalSyncEnabled(true);

        sf::Clock myClock;
        while(window.isOpen())
        {
                sf::Event event;
                while(window.pollEvent(event))
                {
                        if(event.type == sf::Event::Closed) window.close();
                }
                std::cout << myClock.getElapsedTime().asMilliseconds() << std::endl; //miliseconds keep piling up
                if(myClock.getElapsedTime().asMilliseconds() % 1000 == 0) //but this doesn't work (It prints "Tick" when elapsed time is 0 and that's that)
                {
                        std::cout << "Tick" << std::endl;
                }
                window.clear(sf::Color::Black);
                window.display();
        }

        return 0;
}
 

I'm using SFML 2.1 in Visual Studio 2012
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: The Hatchet on August 01, 2013, 02:56:39 am
sf::Time/Clock don't support a modulus function.  This has been a requested feature in the feature request thread but probably won't ever be implemented unless you can supply some darn good and concrete uses for it.
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: MrPlow442 on August 01, 2013, 03:38:15 am
sf::Time/Clock don't support a modulus function.  This has been a requested feature in the feature request thread but probably won't ever be implemented unless you can supply some darn good and concrete uses for it.

I see... However myClock.getElapsedTime().asMilliseconds() returns sf::Int32 which is essentialy typedef'd int, and this code compiles and runs. So if the result is an integer and I'm making a modulus operation over an integer it should work, shouldn't it?
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: Laurent on August 01, 2013, 08:01:35 am
Your elapsed time is very unlikely to be exactly a multiple of 1000. That's why the modulo test fails most of the time.

You should rather test (elapsed >= 1000) and restart the clock everytime a second is elapsed.
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: MrPlow442 on August 01, 2013, 03:11:07 pm
Your elapsed time is very unlikely to be exactly a multiple of 1000. That's why the modulo test fails most of the time.

You should rather test (elapsed >= 1000) and restart the clock everytime a second is elapsed.

I was afraid of something like that. I hoped I could use a single clock for multiple events(Like do one action every 300ms and then when 5 seconds passes do another action and restart the clock), though I can probably still do that if I accumulate the restart time somewhere and then check that. Thanks for the answer.
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: Laurent on August 01, 2013, 03:15:15 pm
Quote
I hoped I could use a single clock for multiple events
You just have to write it slightly differently:

sf::Time lastEvent1;
sf::Time lastEvent2;

...

sf::Time now = clock.getElapsedTime();
if (now - lastEvent1 > sf::milliseconds(300))
{
    // trigger event 1...
    lastEvent1 = now;
}
if (now - lastEvent2 > sf::seconds(5))
{
    // trigger event 2...
    lastEvent2 = now;
}

This way you can have any number of events with different periods, all using the same absolute time base.
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: slotdev on August 01, 2013, 05:09:26 pm
I have a strange bug where one or more sf::Clock objects we use goes negative, at the same time. Has anyone else seen this? I can't reproduce easily enough to post a minimal example.

Ed

EDIT: I think the problem could be with QueryPerformanceCounter in ClockImpl.cpp. This function can fail on some systems, and because the local variable used to store the time is declared, it could be any number.

In previous builds of SFML, there was a check to see if QueryPerformanceCounter can be used - if not, then it defaults to GetTickCount. Why was this change made?
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: MrPlow442 on August 01, 2013, 05:15:48 pm
Quote
I hoped I could use a single clock for multiple events
You just have to write it slightly differently:

sf::Time lastEvent1;
sf::Time lastEvent2;

...

sf::Time now = clock.getElapsedTime();
if (now - lastEvent1 > sf::milliseconds(300))
{
    // trigger event 1...
    lastEvent1 = now;
}
if (now - lastEvent2 > sf::seconds(5))
{
    // trigger event 2...
    lastEvent2 = now;
}

This way you can have any number of events with different periods, all using the same absolute time base.

Sweet! Certainly less messy than what I had in mind
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: Laurent on August 01, 2013, 07:32:28 pm
Quote
I have a strange bug where one or more sf::Clock objects we use goes negative, at the same time. Has anyone else seen this? I can't reproduce easily enough to post a minimal example.

Ed

EDIT: I think the problem could be with QueryPerformanceCounter in ClockImpl.cpp. This function can fail on some systems, and because the local variable used to store the time is declared, it could be any number.

In previous builds of SFML, there was a check to see if QueryPerformanceCounter can be used - if not, then it defaults to GetTickCount. Why was this change made?
This seems to be unrelated to the current problem, could you open a new thread instead?
Title: Re: Weirdness with sf::Clock and sf::Time
Post by: Foaly on August 01, 2013, 09:21:49 pm
sf::Time/Clock don't support a modulus function.  This has been a requested feature in the feature request thread but probably won't ever be implemented unless you can supply some darn good and concrete uses for it.
By the way the modulo issue (and it's fix) are already marked for 2.2 so you can expect it to be fixed soon. There are a couple good use cases (for example resetting clocks in animations while keeping the remainder), this example right here being another one. Like all the other operator overload it's just a shorthand expression.