you shouldn't have to increment a float per timer at all.
Instead use uint64 as a current time from starting the application in milliseconds and make each timer object hold a uint64 for when it should be triggered.
That way the code only needs to compare the new current_time against each timer's trigger time. And if you can keep the timers in some kind of ordered structure (a priority queue) so you can peek at the one that needs triggering the soonest and then early out once the top timer doesn't need to be triggered.
| Timer* timer;
while(timer_queue_peek(&timer) && timer->trigger_time <= current_time){
uint64 time_until_next_trigger = timer->func(timer->data);
if(time_until_next_trigger > 0){ //optimization for recurring events
timer->trigger_time = timer->trigger_time + time_until_next_trigger;
timer_queue_push_down();
} else {
timer_queue_pop();
}
}
|
you can also add a limiter here on how many timers can be triggered per frame to avoid getting stuck in a infinite loop.
By having the timer function return the next time you can make coroutine-like functions in your timers though perhaps having only time as trigger for the next event is a bit limiting.