OpenTTD Source: src/sortlist_type.h Source File

OpenTTD Source 14.0-beta3

sortlist_type.h
Go to the documentation of this file.
1 /*
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/>.
6 */
7
10 #ifndef SORTLIST_TYPE_H
11 #define SORTLIST_TYPE_H
12
13 #include "core/enum_type.hpp"
14 #include "core/bitmath_func.hpp"
15 #include "core/mem_func.hpp"
16 #include "timer/timer_game_tick.h"
17
19 enum SortListFlags {
20 VL_NONE = 0,
21 VL_DESC = 1 << 0,
22 VL_RESORT = 1 << 1,
23 VL_REBUILD = 1 << 2,
24 VL_FILTER = 1 << 3,
25 VL_END = 1 << 4,
26 };
27 DECLARE_ENUM_AS_BIT_SET(SortListFlags)
28
29
30 struct Listing {
31 bool order;
32 byte criteria;
33 };
35 struct Filtering {
36 bool state;
37 byte criteria;
38 };
39
46 template <typename T, typename P = std::nullptr_t, typename F = const char*>
47 class GUIList : public std::vector<T> {
48 public:
49 using SortFunction = std::conditional_t<std::is_same_v<P, std::nullptr_t>, bool (const T&, const T&), bool (const T&, const T&, const P)>;
50 typedef bool CDECL FilterFunction(const T*, F);
51
52 protected:
53 SortFunction * const *sort_func_list;
54 FilterFunction * const *filter_func_list;
55 SortListFlags flags;
56 uint8_t sort_type;
57 uint8_t filter_type;
58 uint16_t resort_timer;
59
60 /* If sort parameters are used then params must be a reference, however if not then params cannot be a reference as
61 * it will not be able to reference anything. */
62 using SortParameterReference = std::conditional_t<std::is_same_v<P, std::nullptr_t>, P, P&>;
63 const SortParameterReference params;
64
70 bool IsSortable() const
71 {
72 return std::vector<T>::size() >= 2;
73 }
74
78 void ResetResortTimer()
79 {
80 /* Resort every 10 days */
81 this->resort_timer = Ticks::DAY_TICKS * 10;
82 }
83
84 public:
85 /* If sort parameters are not used then we don't require a reference to the params. */
86 template <typename T_ = T, typename P_ = P, typename _F = F, std::enable_if_t<std::is_same_v<P_, std::nullptr_t>>* = nullptr>
87 GUIList() :
88 sort_func_list(nullptr),
89 filter_func_list(nullptr),
90 flags(VL_NONE),
91 sort_type(0),
92 filter_type(0),
93 resort_timer(1),
94 params(nullptr)
95 {};
96
97 /* If sort parameters are used then we require a reference to the params. */
98 template <typename T_ = T, typename P_ = P, typename _F = F, std::enable_if_t<!std::is_same_v<P_, std::nullptr_t>>* = nullptr>
99 GUIList(const P &params) :
100 sort_func_list(nullptr),
101 filter_func_list(nullptr),
102 flags(VL_NONE),
103 sort_type(0),
104 filter_type(0),
105 resort_timer(1),
106 params(params)
107 {};
108
114 uint8_t SortType() const
115 {
116 return this->sort_type;
117 }
118
124 void SetSortType(uint8_t n_type)
125 {
126 if (this->sort_type != n_type) {
127 SETBITS(this->flags, VL_RESORT);
128 this->sort_type = n_type;
129 }
130 }
131
137 Listing GetListing() const
138 {
139 Listing l;
140 l.order = (this->flags & VL_DESC) != 0;
141 l.criteria = this->sort_type;
142
143 return l;
144 }
145
151 void SetListing(Listing l)
152 {
153 if (l.order) {
154 SETBITS(this->flags, VL_DESC);
155 } else {
156 CLRBITS(this->flags, VL_DESC);
157 }
158 this->sort_type = l.criteria;
159 }
160
166 uint8_t FilterType() const
167 {
168 return this->filter_type;
169 }
170
176 void SetFilterType(uint8_t n_type)
177 {
178 if (this->filter_type != n_type) {
179 this->filter_type = n_type;
180 }
181 }
182
188 Filtering GetFiltering() const
189 {
190 Filtering f;
191 f.state = (this->flags & VL_FILTER) != 0;
192 f.criteria = this->filter_type;
193
194 return f;
195 }
196
202 void SetFiltering(Filtering f)
203 {
204 if (f.state) {
205 SETBITS(this->flags, VL_FILTER);
206 } else {
207 CLRBITS(this->flags, VL_FILTER);
208 }
209 this->filter_type = f.criteria;
210 }
211
220 bool NeedResort()
221 {
222 if (--this->resort_timer == 0) {
223 SETBITS(this->flags, VL_RESORT);
224 this->ResetResortTimer();
225 return true;
226 }
227 return false;
228 }
229
234 void ForceResort()
235 {
236 SETBITS(this->flags, VL_RESORT);
237 }
238
244 bool IsDescSortOrder() const
245 {
246 return (this->flags & VL_DESC) != 0;
247 }
248
254 void ToggleSortOrder()
255 {
256 this->flags ^= VL_DESC;
257
258 if (this->IsSortable()) std::reverse(std::vector<T>::begin(), std::vector<T>::end());
259 }
260
267 template <typename Comp>
268 bool Sort(Comp compare)
269 {
270 /* Do not sort if the resort bit is not set */
271 if (!(this->flags & VL_RESORT)) return false;
272
273 CLRBITS(this->flags, VL_RESORT);
274
275 this->ResetResortTimer();
276
277 /* Do not sort when the list is not sortable */
278 if (!this->IsSortable()) return false;
279
280 const bool desc = (this->flags & VL_DESC) != 0;
281
282 if constexpr (std::is_same_v<P, std::nullptr_t>) {
283 std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
284 } else {
285 std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a, params) : compare(a, b, params); });
286 }
287 return true;
288 }
289
295 void SetSortFuncs(SortFunction * const *n_funcs)
296 {
297 this->sort_func_list = n_funcs;
298 }
299
306 bool Sort()
307 {
308 assert(this->sort_func_list != nullptr);
309 return this->Sort(this->sort_func_list[this->sort_type]);
310 }
311
317 bool IsFilterEnabled() const
318 {
319 return (this->flags & VL_FILTER) != 0;
320 }
321
327 void SetFilterState(bool state)
328 {
329 if (state) {
330 SETBITS(this->flags, VL_FILTER);
331 } else {
332 CLRBITS(this->flags, VL_FILTER);
333 }
334 }
335
343 bool Filter(FilterFunction *decide, F filter_data)
344 {
345 /* Do not filter if the filter bit is not set */
346 if (!(this->flags & VL_FILTER)) return false;
347
348 bool changed = false;
349 for (auto it = std::vector<T>::begin(); it != std::vector<T>::end(); /* Nothing */) {
350 if (!decide(&*it, filter_data)) {
351 it = std::vector<T>::erase(it);
352 changed = true;
353 } else {
354 it++;
355 }
356 }
357
358 return changed;
359 }
360
366 void SetFilterFuncs(FilterFunction * const *n_funcs)
367 {
368 this->filter_func_list = n_funcs;
369 }
370
377 bool Filter(F filter_data)
378 {
379 if (this->filter_func_list == nullptr) return false;
380 return this->Filter(this->filter_func_list[this->filter_type], filter_data);
381 }
382
387 bool NeedRebuild() const
388 {
389 return (this->flags & VL_REBUILD) != 0;
390 }
391
395 void ForceRebuild()
396 {
397 SETBITS(this->flags, VL_REBUILD);
398 }
399
405 void RebuildDone()
406 {
407 CLRBITS(this->flags, VL_REBUILD);
408 SETBITS(this->flags, VL_RESORT);
409 }
410 };
411
412 #endif /* SORTLIST_TYPE_H */
GUIList::Filter
bool Filter(F filter_data)
Filter the data with the currently selected filter.
Definition: sortlist_type.h:377
GUIList::IsSortable
bool IsSortable() const
Check if the list is sortable.
Definition: sortlist_type.h:70
GUIList::ResetResortTimer
void ResetResortTimer()
Reset the resort timer.
Definition: sortlist_type.h:78
mem_func.hpp
GUIList::SetFilterState
void SetFilterState(bool state)
Enable or disable the filter.
Definition: sortlist_type.h:327
Filtering::state
bool state
Filter on/off.
Definition: sortlist_type.h:36
GUIList
List template of 'things' T to sort in a GUI.
Definition: sortlist_type.h:47
VL_RESORT
@ VL_RESORT
instruct the code to resort the list in the next loop
Definition: sortlist_type.h:22
SortListFlags
SortListFlags
Flags of the sort list.
Definition: sortlist_type.h:19
GUIList::filter_type
uint8_t filter_type
what criteria to filter on
Definition: sortlist_type.h:57
GUIList::SetSortType
void SetSortType(uint8_t n_type)
Set the sorttype of the list.
Definition: sortlist_type.h:124
GUIList::filter_func_list
FilterFunction *const * filter_func_list
the filter criteria functions
Definition: sortlist_type.h:54
GUIList::resort_timer
uint16_t resort_timer
resort list after a given amount of ticks if set
Definition: sortlist_type.h:58
GUIList::NeedRebuild
bool NeedRebuild() const
Check if a rebuild is needed.
Definition: sortlist_type.h:387
SETBITS
#define SETBITS(x, y)
Sets several bits in a variable.
Definition: bitmath_func.hpp:136
GUIList::Sort
bool Sort()
Overload of #Sort(SortFunction *compare) Overloaded to reduce external code.
Definition: sortlist_type.h:306
bitmath_func.hpp
Filtering::criteria
byte criteria
Filtering criteria.
Definition: sortlist_type.h:37
GUIList::GetFiltering
Filtering GetFiltering() const
Export current filter conditions.
Definition: sortlist_type.h:188
VL_FILTER
@ VL_FILTER
filter disabled/enabled
Definition: sortlist_type.h:24
GUIList::NeedResort
bool NeedResort()
Check if a resort is needed next loop If used the resort timer will decrease every call till 0.
Definition: sortlist_type.h:220
Listing
Data structure describing how to show the list (what sort direction and criteria).
Definition: sortlist_type.h:30
GUIList::flags
SortListFlags flags
used to control sorting/resorting/etc.
Definition: sortlist_type.h:55
GUIList::Filter
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
Definition: sortlist_type.h:343
GUIList::SortFunction
std::conditional_t< std::is_same_v< P, std::nullptr_t >, bool(const T &, const T &), bool(const T &, const T &, const P)> SortFunction
Signature of sort function.
Definition: sortlist_type.h:49
GUIList::ForceResort
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Definition: sortlist_type.h:234
Listing::order
bool order
Ascending/descending.
Definition: sortlist_type.h:31
GUIList::ToggleSortOrder
void ToggleSortOrder()
Toggle the sort order Since that is the worst condition for the sort function reverse the list here.
Definition: sortlist_type.h:254
GUIList::sort_func_list
SortFunction *const * sort_func_list
the sort criteria functions
Definition: sortlist_type.h:53
GUIList::FilterType
uint8_t FilterType() const
Get the filtertype of the list.
Definition: sortlist_type.h:166
Filtering
Data structure describing what to show in the list (filter criteria).
Definition: sortlist_type.h:35
timer_game_tick.h
GUIList::IsDescSortOrder
bool IsDescSortOrder() const
Check if the sort order is descending.
Definition: sortlist_type.h:244
GUIList::ForceRebuild
void ForceRebuild()
Force that a rebuild is needed.
Definition: sortlist_type.h:395
VL_DESC
@ VL_DESC
sort descending or ascending
Definition: sortlist_type.h:21
GUIList::GetListing
Listing GetListing() const
Export current sort conditions.
Definition: sortlist_type.h:137
enum_type.hpp
DECLARE_ENUM_AS_BIT_SET
DECLARE_ENUM_AS_BIT_SET(GenderEthnicity) enum CompanyManagerFaceVariable
Bitgroups of the CompanyManagerFace variable.
Definition: company_manager_face.h:29
GUIList::SetFilterFuncs
void SetFilterFuncs(FilterFunction *const *n_funcs)
Hand the array of filter function pointers to the sort list.
Definition: sortlist_type.h:366
GUIList::SortType
uint8_t SortType() const
Get the sorttype of the list.
Definition: sortlist_type.h:114
GUIList::SetSortFuncs
void SetSortFuncs(SortFunction *const *n_funcs)
Hand the array of sort function pointers to the sort list.
Definition: sortlist_type.h:295
GUIList::RebuildDone
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition: sortlist_type.h:405
GUIList::IsFilterEnabled
bool IsFilterEnabled() const
Check if the filter is enabled.
Definition: sortlist_type.h:317
GUIList::FilterFunction
bool CDECL FilterFunction(const T *, F)
Signature of filter function.
Definition: sortlist_type.h:50
Ticks::DAY_TICKS
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
Definition: timer_game_tick.h:48
VL_NONE
@ VL_NONE
no sort
Definition: sortlist_type.h:20
Listing::criteria
byte criteria
Sorting criteria.
Definition: sortlist_type.h:32
VL_REBUILD
@ VL_REBUILD
rebuild the sort list
Definition: sortlist_type.h:23
GUIList::Sort
bool Sort(Comp compare)
Sort the list.
Definition: sortlist_type.h:268
GUIList::sort_type
uint8_t sort_type
what criteria to sort on
Definition: sortlist_type.h:56
CLRBITS
#define CLRBITS(x, y)
Clears several bits in a variable.
Definition: bitmath_func.hpp:166
GUIList::SetFiltering
void SetFiltering(Filtering f)
Import filter conditions.
Definition: sortlist_type.h:202
GUIList::SetFilterType
void SetFilterType(uint8_t n_type)
Set the filtertype of the list.
Definition: sortlist_type.h:176
GUIList::SetListing
void SetListing(Listing l)
Import sort conditions.
Definition: sortlist_type.h:151