2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 <http://www.gnu.org/licenses/>.
8 /** @file timer_game_common.h Definition of the common class inherited by both calendar and economy timers. */
10 #ifndef TIMER_GAME_COMMON_H
11 #define TIMER_GAME_COMMON_H
13 #include "../core/strong_typedef_type.hpp"
16 * Template class for all TimerGame based timers. As Calendar and Economy are very similar, this class is used to share code between them.
18 * IntervalTimer and TimeoutTimer based on this Timer are a bit unusual, as their count is always one.
19 * You create those timers based on a transition: a new day, a new month or a new year.
21 * Additionally, you need to set a priority. To ensure deterministic behaviour, events are executed
22 * in priority. It is important that if you assign NONE, you do not use Random() in your callback.
23 * Other than that, make sure you only set one callback per priority.
26 * IntervalTimer<TimerGameCalendar>({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](uint count) {});
28 * @note Callbacks are executed in the game-thread.
33 /** The type to store our dates in. */
34 template <class ST
> struct DateTag
;
35 using Date
= StrongType::Typedef
<int32_t, DateTag
<T
>, StrongType::Compare
, StrongType::Integer
>;
37 /** The fraction of a date we're in, i.e. the number of ticks since the last date changeover. */
38 using DateFract
= uint16_t;
40 /** Type for the year, note: 0 based, i.e. starts at the year 0. */
41 template <class ST
> struct YearTag
;
42 using Year
= StrongType::Typedef
<int32_t, struct YearTag
<T
>, StrongType::Compare
, StrongType::Integer
>;
43 /** Type for the month, note: 0 based, i.e. 0 = January, 11 = December. */
44 using Month
= uint8_t;
45 /** Type for the day of the month, note: 1 based, first day of a month is 1. */
49 * Data structure to convert between Date and triplet (year, month, and day).
50 * @see ConvertDateToYMD(), ConvertYMDToDate()
53 Year year
; ///< Year (0...)
54 Month month
; ///< Month (0..11)
55 Day day
; ///< Day (1..31)
59 * Checks whether the given year is a leap year or not.
60 * @param year The year to check.
61 * @return True if \c year is a leap year, otherwise false.
63 static constexpr bool IsLeapYear(Year year
)
65 int32_t year_as_int
= year
.base();
66 return year_as_int
% 4 == 0 && (year_as_int
% 100 != 0 || year_as_int
% 400 == 0);
69 static YearMonthDay
CalendarConvertDateToYMD(Date date
);
70 static Date
CalendarConvertYMDToDate(Year year
, Month month
, Day day
);
73 * Calculate the year of a given date.
74 * @param date The date to consider.
77 static constexpr Year
DateToYear(Date date
)
79 /* Hardcode the number of days in a year because we can't access CalendarTime from here. */
80 return date
.base() / 366;
84 * Calculate the date of the first day of a given year.
85 * @param year the year to get the first day of.
88 static constexpr Date
DateAtStartOfYear(Year year
)
90 int32_t year_as_int
= year
.base();
91 uint number_of_leap_years
= (year
== 0) ? 0 : ((year_as_int
- 1) / 4 - (year_as_int
- 1) / 100 + (year_as_int
- 1) / 400 + 1);
93 /* Hardcode the number of days in a year because we can't access CalendarTime from here. */
94 return (365 * year_as_int
) + number_of_leap_years
;
106 NONE
, ///< These timers can be executed in any order; there is no Random() in them, so order is not relevant.
108 /* All other may have a Random() call in them, so order is important.
109 * For safety, you can only setup a single timer on a single priority. */
124 TPeriod(Trigger trigger
, Priority priority
) : trigger(trigger
), priority(priority
)
127 bool operator < (const TPeriod
&other
) const
129 if (this->trigger
!= other
.trigger
) return this->trigger
< other
.trigger
;
130 return this->priority
< other
.priority
;
133 bool operator == (const TPeriod
&other
) const
135 return this->trigger
== other
.trigger
&& this->priority
== other
.priority
;
139 using TElapsed
= uint
;
144 * Template class for time constants shared by both Calendar and Economy time.
147 class TimerGameConst
{
149 static constexpr int DAYS_IN_YEAR
= 365; ///< days per year
150 static constexpr int DAYS_IN_LEAP_YEAR
= 366; ///< sometimes, you need one day more...
151 static constexpr int MONTHS_IN_YEAR
= 12; ///< months per year
153 static constexpr int SECONDS_PER_DAY
= 2; ///< approximate seconds per day, not for precise calculations
156 * ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are
157 * primarily used for loading newgrf and savegame data and returning some
158 * newgrf (callback) functions that were in the original (TTD) inherited
159 * format, where 'TimerGame<T>::date == 0' meant that it was 1920-01-01.
162 /** The minimum starting year/base year of the original TTD */
163 static constexpr typename TimerGame
<T
>::Year ORIGINAL_BASE_YEAR
= 1920;
164 /** The original ending year */
165 static constexpr typename TimerGame
<T
>::Year ORIGINAL_END_YEAR
= 2051;
166 /** The maximum year of the original TTD */
167 static constexpr typename TimerGame
<T
>::Year ORIGINAL_MAX_YEAR
= 2090;
170 * MAX_YEAR, nicely rounded value of the number of years that can
171 * be encoded in a single 32 bits date, about 2^31 / 366 years.
173 static constexpr typename TimerGame
<T
>::Year MAX_YEAR
= 5000000;
175 /** The absolute minimum year in OTTD */
176 static constexpr typename TimerGame
<T
>::Year MIN_YEAR
= 0;
178 /** The default starting year */
179 static constexpr typename TimerGame
<T
>::Year DEF_START_YEAR
= 1950;
180 /** The default scoring end year */
181 static constexpr typename TimerGame
<T
>::Year DEF_END_YEAR
= ORIGINAL_END_YEAR
- 1;
183 /** The date of the first day of the original base year. */
184 static constexpr typename TimerGame
<T
>::Date DAYS_TILL_ORIGINAL_BASE_YEAR
= TimerGame
<T
>::DateAtStartOfYear(ORIGINAL_BASE_YEAR
);
186 /** The date of the last day of the max year. */
187 static constexpr typename TimerGame
<T
>::Date MAX_DATE
= TimerGame
<T
>::DateAtStartOfYear(MAX_YEAR
+ 1) - 1;
189 /** The date on January 1, year 0. */
190 static constexpr typename TimerGame
<T
>::Date MIN_DATE
= 0;
192 static constexpr typename TimerGame
<T
>::Year INVALID_YEAR
= -1; ///< Representation of an invalid year
193 static constexpr typename TimerGame
<T
>::Date INVALID_DATE
= -1; ///< Representation of an invalid date
196 #endif /* TIMER_GAME_COMMON_H */