diff --git a/src/timer/timer_game_calendar.h b/src/timer/timer_game_calendar.h new file mode 100644 --- /dev/null +++ b/src/timer/timer_game_calendar.h @@ -0,0 +1,76 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file timer_game_calendar.h Definition of the game-calendar-timer */ + +#ifndef TIMER_GAME_CALENDAR_H +#define TIMER_GAME_CALENDAR_H + +/** + * Timer that is increased every 27ms, and counts towards ticks / days / months / years. + * + * The amount of days in a month depends on the month and year (leap-years). + * There are always 74 ticks in a day (and with 27ms, this makes 1 day 1.998 seconds). + * + * IntervalTimer and TimeoutTimer based on this Timer are a bit unusual, as their count is always one. + * You create those timers based on a transition: a new day, a new month or a new year. + * + * Additionally, you need to set a priority. To ensure deterministic behaviour, events are executed + * in priority. It is important that if you assign NONE, you do not use Random() in your callback. + * Other than that, make sure you only set one callback per priority. + * + * For example: + * IntervalTimer({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](uint count){}); + * + */ +class TimerGameCalendar { +public: + enum Trigger { + DAY, + MONTH, + YEAR, + }; + enum Priority { + NONE, ///< These timers can be executed in any order; there is no Random() in them, so order is not relevant. + + /* All other may have a Random() call in them, so order is important. + * For safety, you can only setup a single timer on a single priority. */ + AUTOSAVE, + COMPANY, + DISASTER, + ENGINE, + INDUSTRY, + STATION, + SUBSIDY, + TOWN, + VEHICLE, + }; + + struct TPeriod { + Trigger trigger; + Priority priority; + + TPeriod(Trigger trigger, Priority priority) : trigger(trigger), priority(priority) {} + + bool operator < (const TPeriod &other) const + { + if (this->trigger != other.trigger) return this->trigger < other.trigger; + return this->priority < other.priority; + } + + bool operator == (const TPeriod &other) const + { + return this->trigger == other.trigger && this->priority == other.priority; + } + }; + + using TElapsed = uint; + struct TStorage { + }; +}; + +#endif /* TIMER_GAME_CALENDAR_H */