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

Author Topic: How to do something every x milliseconds  (Read 5455 times)

0 Members and 1 Guest are viewing this topic.

JPB515

  • Newbie
  • *
  • Posts: 6
    • View Profile
How to do something every x milliseconds
« on: June 30, 2016, 10:01:30 am »
Hi,

I'm working on a project with SFML and am having a problem.

As the title suggests, I need to spawn a sprite every x milliseconds, where x is at least 100ms but variable (set at compile time) up to about 500ms. I'm using an if-else block, as I will sometimes (usually) need to delete an old sprite when a new one is created. My problem is that occasionally, the sprite won't be created. Some debug messaging confirms that the if branch has not been taken. I should note that by occasionally, I have determined about 1 missing sprite in every 500 or so. There is no obvious pattern to when one is missing.

My initial thought is that the problem is to do with the OS process scheduling and that the process might not always be running at the right time to trigger the branch. Performing an action at regular intervals can't be an uncommon problem though, so is there a better way of doing this?

I should mention that this if-else block is running in a separate thread, which loops over the block (for the moment) from the end of the initialisation routine in main() until the program exits.

I'd be grateful for any advice.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10194
    • View Profile
    • development blog
    • Email
AW: How to do something every x milliseconds
« Reply #1 on: June 30, 2016, 11:02:07 am »
Just use a sf::Clock and spawn an object when the clock is over x ms. It won't be accurate to the ms since it depends on the gameloop, but I highly doubt you'll need ms precision.

Usinv a separate thread is not recommended since you need to have in depth knowledge on parallel programming and shared memory access etc.
Official FAQ: https://www.sfml-dev.org/faq.php
Nightly Builds: https://www.nightlybuilds.ch/
——————————————————————
Dev Blog: https://dev.my-gate.net/
Thor: http://www.bromeon.ch/libraries/thor/

JPB515

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to do something every x milliseconds
« Reply #2 on: June 30, 2016, 01:27:07 pm »
Ah, I was doing 'if (time % 100)', so your way will give me the tolerance I need. I do have to be quite regular when spawning sprites, but a few ms out is certainly better than having sprites missing!

Thanks for your input!

EDIT:
Just in case anyone else finds this thread and wants to do the same thing, another way is to put the thread to sleep for the time interval, and loop over the sleep period and the action you want to perform regularly

I didn't think of this before I designed my data structures, but it might help someone further down the line.
« Last Edit: June 30, 2016, 02:36:49 pm by JPB515 »

man'O'war

  • Newbie
  • *
  • Posts: 46
  • What needs to be done is done by those capable.
    • View Profile
Re: How to do something every x milliseconds
« Reply #3 on: August 17, 2016, 04:45:35 pm »
Hi,

For more accuracy, use can use a TimeStep. Same technique, but instead of tolerating the loss of x microseconds after your 100 ms, you'll save it and account it for the next execution.

    // Total time passed
    sf::Time elapsed_time;
    sf::Clock r;

    // Update/Refresh frequency
    sf::Time delta_time = sf::milliseconds(100);

    elapsed_time += r.restart();

    // We have enough time to spawn a sprite. ( may be for several ? )
    while( elapsed_time >= delta_time ){
        // Spawn your sprite
        // ...

        // Substract the time consumed
        elapsed_time -= delta_time;
    }

    // When it goes out of the loop, mean all your time has been consumed, and may be a portion of it less than delta_time is still available

    // Then loop again and again. accordingly to your gamelogic
 

Just be carefull to declare elapsed_time and the Clock somewhere else, so it wont reinit its value on every call.

Best regards.