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

Author Topic: Weirdness with sf::Clock and sf::Time  (Read 7338 times)

0 Members and 2 Guests are viewing this topic.

MrPlow442

  • Newbie
  • *
  • Posts: 14
    • View Profile
Weirdness with sf::Clock and sf::Time
« 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

The Hatchet

  • Full Member
  • ***
  • Posts: 135
    • View Profile
    • Email
Re: Weirdness with sf::Clock and sf::Time
« Reply #1 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.

MrPlow442

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Weirdness with sf::Clock and sf::Time
« Reply #2 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?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Weirdness with sf::Clock and sf::Time
« Reply #3 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.
Laurent Gomila - SFML developer

MrPlow442

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Weirdness with sf::Clock and sf::Time
« Reply #4 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.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Weirdness with sf::Clock and sf::Time
« Reply #5 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.
Laurent Gomila - SFML developer

slotdev

  • Sr. Member
  • ****
  • Posts: 385
    • View Profile
Re: Weirdness with sf::Clock and sf::Time
« Reply #6 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?
« Last Edit: August 01, 2013, 05:39:15 pm by slotdev »
SFML 2.1

MrPlow442

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Weirdness with sf::Clock and sf::Time
« Reply #7 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

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Weirdness with sf::Clock and sf::Time
« Reply #8 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?
Laurent Gomila - SFML developer

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Weirdness with sf::Clock and sf::Time
« Reply #9 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.
« Last Edit: August 01, 2013, 09:23:34 pm by Foaly »