mirror of https://github.com/OpenTTD/OpenTTD
Codechange: validate the developer didn't schedule two timers on the same trigger/priority
parent
3ebc7ad16e
commit
387d5eb74f
|
@ -98,3 +98,20 @@ void TimerManager<TimerGameCalendar>::Elapsed(TimerGameCalendar::TElapsed delta)
|
||||||
for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year);
|
for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_ASSERT
|
||||||
|
template<>
|
||||||
|
void TimerManager<TimerGameCalendar>::Validate(TimerGameCalendar::TPeriod period)
|
||||||
|
{
|
||||||
|
if (period.priority == TimerGameCalendar::Priority::NONE) return;
|
||||||
|
|
||||||
|
/* Validate we didn't make a developer error and scheduled more than one
|
||||||
|
* entry on the same priority/trigger. There can only be one timer on
|
||||||
|
* a specific trigger/priority, to ensure we are deterministic. */
|
||||||
|
for (const auto &timer : TimerManager<TimerGameCalendar>::GetTimers()) {
|
||||||
|
if (timer->period.trigger != period.trigger) continue;
|
||||||
|
|
||||||
|
assert(timer->period.priority != period.priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WITH_ASSERT */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
* For example:
|
* For example:
|
||||||
* IntervalTimer<TimerGameCalendar>({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](uint count){});
|
* IntervalTimer<TimerGameCalendar>({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](uint count){});
|
||||||
*
|
*
|
||||||
|
* @note Callbacks are executed in the game-thread.
|
||||||
*/
|
*/
|
||||||
class TimerGameCalendar {
|
class TimerGameCalendar {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -28,6 +28,7 @@ class BaseTimer;
|
||||||
template <typename TTimerType>
|
template <typename TTimerType>
|
||||||
class TimerManager {
|
class TimerManager {
|
||||||
public:
|
public:
|
||||||
|
using TPeriod = typename TTimerType::TPeriod;
|
||||||
using TElapsed = typename TTimerType::TElapsed;
|
using TElapsed = typename TTimerType::TElapsed;
|
||||||
|
|
||||||
/* Avoid copying this object; it is a singleton object. */
|
/* Avoid copying this object; it is a singleton object. */
|
||||||
|
@ -40,6 +41,9 @@ public:
|
||||||
* @param timer The timer to register.
|
* @param timer The timer to register.
|
||||||
*/
|
*/
|
||||||
static void RegisterTimer(BaseTimer<TTimerType> &timer) {
|
static void RegisterTimer(BaseTimer<TTimerType> &timer) {
|
||||||
|
#ifdef WITH_ASSERT
|
||||||
|
Validate(timer.period);
|
||||||
|
#endif /* WITH_ASSERT */
|
||||||
GetTimers().insert(&timer);
|
GetTimers().insert(&timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +56,21 @@ public:
|
||||||
GetTimers().erase(&timer);
|
GetTimers().erase(&timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_ASSERT
|
||||||
|
/**
|
||||||
|
* Validate that a new period is actually valid.
|
||||||
|
*
|
||||||
|
* For most timers this is not an issue, but some want to make sure their
|
||||||
|
* period is unique, to ensure deterministic game-play.
|
||||||
|
*
|
||||||
|
* This is meant purely to protect a developer from making a mistake.
|
||||||
|
* As such, assert() when validation fails.
|
||||||
|
*
|
||||||
|
* @param period The period to validate.
|
||||||
|
*/
|
||||||
|
static void Validate(TPeriod period);
|
||||||
|
#endif /* WITH_ASSERT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when time for this timer elapsed.
|
* Called when time for this timer elapsed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -58,3 +58,10 @@ void TimerManager<TimerWindow>::Elapsed(TimerWindow::TElapsed delta)
|
||||||
timer->Elapsed(delta);
|
timer->Elapsed(delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_ASSERT
|
||||||
|
template<>
|
||||||
|
void TimerManager<TimerWindow>::Validate(TimerWindow::TPeriod period)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* WITH_ASSERT */
|
||||||
|
|
Loading…
Reference in New Issue