OpenTTD Source: src/sortlist_type.h Source File

OpenTTD Source 15.0-beta1

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
30struct Listing {
31 bool order;
32 uint8_t criteria;
33};
35 struct Filtering {
36 bool state;
37 uint8_t criteria;
38};
39
46template <typename T, typename P = std::nullptr_t, typename F = const char*>
47 class GUIList : public std::vector<T> {
48public:
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 using FilterFunction = bool(const T*, F);
51
52protected:
53 std::span<SortFunction * const> sort_func_list;
54 std::span<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
84public:
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({}),
89 filter_func_list({}),
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({}),
101 filter_func_list({}),
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 assert(n_type < std::size(this->sort_func_list));
127 if (this->sort_type != n_type) {
128 SETBITS(this->flags, VL_RESORT);
129 this->sort_type = n_type;
130 }
131 }
132
138 Listing GetListing() const
139 {
140 Listing l;
141 l.order = (this->flags & VL_DESC) != 0;
142 l.criteria = this->sort_type;
143
144 return l;
145 }
146
152 void SetListing(Listing l)
153 {
154 if (l.order) {
155 SETBITS(this->flags, VL_DESC);
156 } else {
157 CLRBITS(this->flags, VL_DESC);
158 }
159 this->sort_type = l.criteria;
160 }
161
167 uint8_t FilterType() const
168 {
169 return this->filter_type;
170 }
171
177 void SetFilterType(uint8_t n_type)
178 {
179 assert(n_type < std::size(this->filter_func_list));
180 if (this->filter_type != n_type) {
181 this->filter_type = n_type;
182 }
183 }
184
190 Filtering GetFiltering() const
191 {
192 Filtering f;
193 f.state = (this->flags & VL_FILTER) != 0;
194 f.criteria = this->filter_type;
195
196 return f;
197 }
198
204 void SetFiltering(Filtering f)
205 {
206 if (f.state) {
207 SETBITS(this->flags, VL_FILTER);
208 } else {
209 CLRBITS(this->flags, VL_FILTER);
210 }
211 this->filter_type = f.criteria;
212 }
213
222 bool NeedResort()
223 {
224 if (--this->resort_timer == 0) {
225 SETBITS(this->flags, VL_RESORT);
226 this->ResetResortTimer();
227 return true;
228 }
229 return false;
230 }
231
236 void ForceResort()
237 {
238 SETBITS(this->flags, VL_RESORT);
239 }
240
246 bool IsDescSortOrder() const
247 {
248 return (this->flags & VL_DESC) != 0;
249 }
250
256 void ToggleSortOrder()
257 {
258 this->flags ^= VL_DESC;
259
260 if (this->IsSortable()) std::reverse(std::vector<T>::begin(), std::vector<T>::end());
261 }
262
269 template <typename Comp>
270 bool Sort(Comp compare)
271 {
272 /* Do not sort if the resort bit is not set */
273 if (!(this->flags & VL_RESORT)) return false;
274
275 CLRBITS(this->flags, VL_RESORT);
276
277 this->ResetResortTimer();
278
279 /* Do not sort when the list is not sortable */
280 if (!this->IsSortable()) return false;
281
282 const bool desc = (this->flags & VL_DESC) != 0;
283
284 if constexpr (std::is_same_v<P, std::nullptr_t>) {
285 std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
286 } else {
287 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); });
288 }
289 return true;
290 }
291
297 void SetSortFuncs(std::span<SortFunction * const> n_funcs)
298 {
299 this->sort_func_list = n_funcs;
300 }
301
308 bool Sort()
309 {
310 if (this->sort_func_list.empty()) return false;
311 assert(this->sort_type < this->sort_func_list.size());
312 return this->Sort(this->sort_func_list[this->sort_type]);
313 }
314
320 bool IsFilterEnabled() const
321 {
322 return (this->flags & VL_FILTER) != 0;
323 }
324
330 void SetFilterState(bool state)
331 {
332 if (state) {
333 SETBITS(this->flags, VL_FILTER);
334 } else {
335 CLRBITS(this->flags, VL_FILTER);
336 }
337 }
338
346 bool Filter(FilterFunction *decide, F filter_data)
347 {
348 /* Do not filter if the filter bit is not set */
349 if (!(this->flags & VL_FILTER)) return false;
350
351 bool changed = false;
352 for (auto it = std::vector<T>::begin(); it != std::vector<T>::end(); /* Nothing */) {
353 if (!decide(&*it, filter_data)) {
354 it = std::vector<T>::erase(it);
355 changed = true;
356 } else {
357 it++;
358 }
359 }
360
361 return changed;
362 }
363
369 void SetFilterFuncs(std::span<FilterFunction * const> n_funcs)
370 {
371 this->filter_func_list = n_funcs;
372 }
373
380 bool Filter(F filter_data)
381 {
382 if (this->filter_func_list.empty()) return false;
383 assert(this->filter_type < this->filter_func_list.size());
384 return this->Filter(this->filter_func_list[this->filter_type], filter_data);
385 }
386
391 bool NeedRebuild() const
392 {
393 return (this->flags & VL_REBUILD) != 0;
394 }
395
399 void ForceRebuild()
400 {
401 SETBITS(this->flags, VL_REBUILD);
402 }
403
409 void RebuildDone()
410 {
411 CLRBITS(this->flags, VL_REBUILD);
412 SETBITS(this->flags, VL_RESORT);
413 }
414};
415
416#endif /* SORTLIST_TYPE_H */
bitmath_func.hpp
Functions related to bit mathematics.
CLRBITS
#define CLRBITS(x, y)
Clears several bits in a variable.
Definition bitmath_func.hpp:166
SETBITS
#define SETBITS(x, y)
Sets several bits in a variable.
Definition bitmath_func.hpp:136
GUIList
List template of 'things' T to sort in a GUI.
Definition sortlist_type.h:47
GUIList::Filter
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
Definition sortlist_type.h:346
GUIList::RebuildDone
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition sortlist_type.h:409
GUIList::SetFiltering
void SetFiltering(Filtering f)
Import filter conditions.
Definition sortlist_type.h:204
GUIList::SetListing
void SetListing(Listing l)
Import sort conditions.
Definition sortlist_type.h:152
GUIList::IsSortable
bool IsSortable() const
Check if the list is sortable.
Definition sortlist_type.h:70
GUIList::resort_timer
uint16_t resort_timer
resort list after a given amount of ticks if set
Definition sortlist_type.h:58
GUIList::SetFilterState
void SetFilterState(bool state)
Enable or disable the filter.
Definition sortlist_type.h:330
GUIList::IsDescSortOrder
bool IsDescSortOrder() const
Check if the sort order is descending.
Definition sortlist_type.h:246
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:256
GUIList::FilterFunction
bool(const T *, F) FilterFunction
Signature of filter function.
Definition sortlist_type.h:50
GUIList::SetFilterFuncs
void SetFilterFuncs(std::span< FilterFunction *const > n_funcs)
Hand the filter function pointers to the GUIList.
Definition sortlist_type.h:369
GUIList::GetFiltering
Filtering GetFiltering() const
Export current filter conditions.
Definition sortlist_type.h:190
GUIList::NeedRebuild
bool NeedRebuild() const
Check if a rebuild is needed.
Definition sortlist_type.h:391
GUIList::SetFilterType
void SetFilterType(uint8_t n_type)
Set the filtertype of the list.
Definition sortlist_type.h:177
GUIList::filter_func_list
std::span< FilterFunction *const > filter_func_list
the filter criteria functions
Definition sortlist_type.h:54
GUIList::ResetResortTimer
void ResetResortTimer()
Reset the resort timer.
Definition sortlist_type.h:78
GUIList::ForceRebuild
void ForceRebuild()
Force that a rebuild is needed.
Definition sortlist_type.h:399
GUIList::IsFilterEnabled
bool IsFilterEnabled() const
Check if the filter is enabled.
Definition sortlist_type.h:320
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::sort_func_list
std::span< SortFunction *const > sort_func_list
the sort criteria functions
Definition sortlist_type.h:53
GUIList::Sort
bool Sort(Comp compare)
Sort the list.
Definition sortlist_type.h:270
GUIList::ForceResort
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Definition sortlist_type.h:236
GUIList::SortType
uint8_t SortType() const
Get the sorttype of the list.
Definition sortlist_type.h:114
GUIList::Filter
bool Filter(F filter_data)
Filter the data with the currently selected filter.
Definition sortlist_type.h:380
GUIList::Sort
bool Sort()
Overload of #Sort(SortFunction *compare) Overloaded to reduce external code.
Definition sortlist_type.h:308
GUIList::GetListing
Listing GetListing() const
Export current sort conditions.
Definition sortlist_type.h:138
GUIList::sort_type
uint8_t sort_type
what criteria to sort on
Definition sortlist_type.h:56
GUIList::SetSortFuncs
void SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
Definition sortlist_type.h:297
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:222
GUIList::SetSortType
void SetSortType(uint8_t n_type)
Set the sorttype of the list.
Definition sortlist_type.h:124
GUIList::filter_type
uint8_t filter_type
what criteria to filter on
Definition sortlist_type.h:57
GUIList::flags
SortListFlags flags
used to control sorting/resorting/etc.
Definition sortlist_type.h:55
GUIList::FilterType
uint8_t FilterType() const
Get the filtertype of the list.
Definition sortlist_type.h:167
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:75
enum_type.hpp
Type (helpers) for enums.
DECLARE_ENUM_AS_BIT_SET
#define DECLARE_ENUM_AS_BIT_SET(enum_type)
Operators to allow to work with enum as with type safe bit set in C++.
Definition enum_type.hpp:35
mem_func.hpp
Functions related to memory operations.
SortListFlags
SortListFlags
Flags of the sort list.
Definition sortlist_type.h:19
VL_DESC
@ VL_DESC
sort descending or ascending
Definition sortlist_type.h:21
VL_RESORT
@ VL_RESORT
instruct the code to resort the list in the next loop
Definition sortlist_type.h:22
VL_NONE
@ VL_NONE
no sort
Definition sortlist_type.h:20
VL_FILTER
@ VL_FILTER
filter disabled/enabled
Definition sortlist_type.h:24
VL_REBUILD
@ VL_REBUILD
rebuild the sort list
Definition sortlist_type.h:23
Filtering
Data structure describing what to show in the list (filter criteria).
Definition sortlist_type.h:35
Filtering::criteria
uint8_t criteria
Filtering criteria.
Definition sortlist_type.h:37
Filtering::state
bool state
Filter on/off.
Definition sortlist_type.h:36
Listing
Data structure describing how to show the list (what sort direction and criteria).
Definition sortlist_type.h:30
Listing::criteria
uint8_t criteria
Sorting criteria.
Definition sortlist_type.h:32
Listing::order
bool order
Ascending/descending.
Definition sortlist_type.h:31
timer_game_tick.h
Definition of the tick-based game-timer.