OpenTTD Source: src/sortlist_type.h Source File

OpenTTD Source 15.3

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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#ifndef SORTLIST_TYPE_H
11#define SORTLIST_TYPE_H
12
13#include "core/enum_type.hpp"
14#include "timer/timer_game_tick.h"
15
17 enum class SortListFlag : uint8_t {
18 Desc,
19 Resort,
20 Rebuild,
21 Filter,
22};
23using SortListFlags = EnumBitSet<SortListFlag, uint8_t>;
24
26 struct Listing {
27 bool order;
28 uint8_t criteria;
29};
31 struct Filtering {
32 bool state;
33 uint8_t criteria;
34};
35
42template <typename T, typename P = std::nullptr_t, typename F = std::string_view>
43 class GUIList : public std::vector<T> {
44public:
45 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)>;
46 using FilterFunction = bool(const T*, F);
47
48protected:
49 std::span<SortFunction * const> sort_func_list;
50 std::span<FilterFunction * const> filter_func_list;
51 SortListFlags flags;
52 uint8_t sort_type;
53 uint8_t filter_type;
54 uint16_t resort_timer;
55
56 /* If sort parameters are used then params must be a reference, however if not then params cannot be a reference as
57 * it will not be able to reference anything. */
58 using SortParameterReference = std::conditional_t<std::is_same_v<P, std::nullptr_t>, P, P&>;
59 const SortParameterReference params;
60
66 bool IsSortable() const
67 {
68 return std::vector<T>::size() >= 2;
69 }
70
74 void ResetResortTimer()
75 {
76 /* Resort every 10 days */
77 this->resort_timer = Ticks::DAY_TICKS * 10;
78 }
79
80public:
81 /* If sort parameters are not used then we don't require a reference to the params. */
82 template <typename T_ = T, typename P_ = P, typename _F = F, std::enable_if_t<std::is_same_v<P_, std::nullptr_t>>* = nullptr>
83 GUIList() :
84 sort_func_list({}),
85 filter_func_list({}),
86 flags({}),
87 sort_type(0),
88 filter_type(0),
89 resort_timer(1),
90 params(nullptr)
91 {};
92
93 /* If sort parameters are used then we require a reference to the params. */
94 template <typename T_ = T, typename P_ = P, typename _F = F, std::enable_if_t<!std::is_same_v<P_, std::nullptr_t>>* = nullptr>
95 GUIList(const P &params) :
96 sort_func_list({}),
97 filter_func_list({}),
98 flags({}),
99 sort_type(0),
100 filter_type(0),
101 resort_timer(1),
102 params(params)
103 {};
104
110 uint8_t SortType() const
111 {
112 return this->sort_type;
113 }
114
120 void SetSortType(uint8_t n_type)
121 {
122 assert(n_type < std::size(this->sort_func_list));
123 if (this->sort_type != n_type) {
124 this->flags.Set(SortListFlag::Resort);
125 this->sort_type = n_type;
126 }
127 }
128
134 Listing GetListing() const
135 {
136 Listing l;
137 l.order = this->flags.Test(SortListFlag::Desc);
138 l.criteria = this->sort_type;
139
140 return l;
141 }
142
148 void SetListing(Listing l)
149 {
150 if (l.order) {
151 this->flags.Set(SortListFlag::Desc);
152 } else {
153 this->flags.Reset(SortListFlag::Desc);
154 }
155 this->sort_type = l.criteria;
156 }
157
163 uint8_t FilterType() const
164 {
165 return this->filter_type;
166 }
167
173 void SetFilterType(uint8_t n_type)
174 {
175 assert(n_type < std::size(this->filter_func_list));
176 if (this->filter_type != n_type) {
177 this->filter_type = n_type;
178 }
179 }
180
186 Filtering GetFiltering() const
187 {
188 Filtering f;
189 f.state = this->flags.Test(SortListFlag::Filter);
190 f.criteria = this->filter_type;
191
192 return f;
193 }
194
200 void SetFiltering(Filtering f)
201 {
202 if (f.state) {
203 this->flags.Set(SortListFlag::Filter);
204 } else {
205 this->flags.Reset(SortListFlag::Filter);
206 }
207 this->filter_type = f.criteria;
208 }
209
218 bool NeedResort()
219 {
220 if (--this->resort_timer == 0) {
221 this->flags.Set(SortListFlag::Resort);
222 this->ResetResortTimer();
223 return true;
224 }
225 return false;
226 }
227
232 void ForceResort()
233 {
234 this->flags.Set(SortListFlag::Resort);
235 }
236
242 bool IsDescSortOrder() const
243 {
244 return this->flags.Test(SortListFlag::Desc);
245 }
246
252 void ToggleSortOrder()
253 {
254 this->flags.Flip(SortListFlag::Desc);
255
256 if (this->IsSortable()) std::reverse(std::vector<T>::begin(), std::vector<T>::end());
257 }
258
265 template <typename Comp>
266 bool Sort(Comp compare)
267 {
268 /* Do not sort if the resort bit is not set */
269 if (!this->flags.Test(SortListFlag::Resort)) return false;
270
271 this->flags.Reset(SortListFlag::Resort);
272
273 this->ResetResortTimer();
274
275 /* Do not sort when the list is not sortable */
276 if (!this->IsSortable()) return false;
277
278 const bool desc = this->flags.Test(SortListFlag::Desc);
279
280 if constexpr (std::is_same_v<P, std::nullptr_t>) {
281 std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
282 } else {
283 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); });
284 }
285 return true;
286 }
287
293 void SetSortFuncs(std::span<SortFunction * const> n_funcs)
294 {
295 this->sort_func_list = n_funcs;
296 }
297
304 bool Sort()
305 {
306 if (this->sort_func_list.empty()) return false;
307 assert(this->sort_type < this->sort_func_list.size());
308 return this->Sort(this->sort_func_list[this->sort_type]);
309 }
310
316 bool IsFilterEnabled() const
317 {
318 return this->flags.Test(SortListFlag::Filter);
319 }
320
326 void SetFilterState(bool state)
327 {
328 if (state) {
329 this->flags.Set(SortListFlag::Filter);
330 } else {
331 this->flags.Reset(SortListFlag::Filter);
332 }
333 }
334
342 bool Filter(FilterFunction *decide, F filter_data)
343 {
344 /* Do not filter if the filter bit is not set */
345 if (!this->flags.Test(SortListFlag::Filter)) return false;
346
347 bool changed = false;
348 for (auto it = std::vector<T>::begin(); it != std::vector<T>::end(); /* Nothing */) {
349 if (!decide(&*it, filter_data)) {
350 it = std::vector<T>::erase(it);
351 changed = true;
352 } else {
353 it++;
354 }
355 }
356
357 return changed;
358 }
359
365 void SetFilterFuncs(std::span<FilterFunction * const> n_funcs)
366 {
367 this->filter_func_list = n_funcs;
368 }
369
376 bool Filter(F filter_data)
377 {
378 if (this->filter_func_list.empty()) return false;
379 assert(this->filter_type < this->filter_func_list.size());
380 return this->Filter(this->filter_func_list[this->filter_type], filter_data);
381 }
382
387 bool NeedRebuild() const
388 {
389 return this->flags.Test(SortListFlag::Rebuild);
390 }
391
395 void ForceRebuild()
396 {
397 this->flags.Set(SortListFlag::Rebuild);
398 }
399
405 void RebuildDone()
406 {
407 this->flags.Reset(SortListFlag::Rebuild);
408 this->flags.Set(SortListFlag::Resort);
409 }
410};
411
412#endif /* SORTLIST_TYPE_H */
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::Reset
constexpr Timpl & Reset()
Reset all bits.
Definition base_bitset_type.hpp:83
BaseBitSet::Flip
constexpr Timpl & Flip(Tvalue_type value)
Flip the value-th bit.
Definition base_bitset_type.hpp:116
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
EnumBitSet< SortListFlag, uint8_t >
GUIList
List template of 'things' T to sort in a GUI.
Definition sortlist_type.h:43
GUIList::Filter
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
Definition sortlist_type.h:342
GUIList::RebuildDone
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition sortlist_type.h:405
GUIList::SetFiltering
void SetFiltering(Filtering f)
Import filter conditions.
Definition sortlist_type.h:200
GUIList::SetListing
void SetListing(Listing l)
Import sort conditions.
Definition sortlist_type.h:148
GUIList::IsSortable
bool IsSortable() const
Check if the list is sortable.
Definition sortlist_type.h:66
GUIList::resort_timer
uint16_t resort_timer
resort list after a given amount of ticks if set
Definition sortlist_type.h:54
GUIList::SetFilterState
void SetFilterState(bool state)
Enable or disable the filter.
Definition sortlist_type.h:326
GUIList::IsDescSortOrder
bool IsDescSortOrder() const
Check if the sort order is descending.
Definition sortlist_type.h:242
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:252
GUIList::FilterFunction
bool(const T *, F) FilterFunction
Signature of filter function.
Definition sortlist_type.h:46
GUIList::SetFilterFuncs
void SetFilterFuncs(std::span< FilterFunction *const > n_funcs)
Hand the filter function pointers to the GUIList.
Definition sortlist_type.h:365
GUIList::GetFiltering
Filtering GetFiltering() const
Export current filter conditions.
Definition sortlist_type.h:186
GUIList::NeedRebuild
bool NeedRebuild() const
Check if a rebuild is needed.
Definition sortlist_type.h:387
GUIList::SetFilterType
void SetFilterType(uint8_t n_type)
Set the filtertype of the list.
Definition sortlist_type.h:173
GUIList::filter_func_list
std::span< FilterFunction *const > filter_func_list
the filter criteria functions
Definition sortlist_type.h:50
GUIList::ResetResortTimer
void ResetResortTimer()
Reset the resort timer.
Definition sortlist_type.h:74
GUIList::ForceRebuild
void ForceRebuild()
Force that a rebuild is needed.
Definition sortlist_type.h:395
GUIList::IsFilterEnabled
bool IsFilterEnabled() const
Check if the filter is enabled.
Definition sortlist_type.h:316
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:45
GUIList::sort_func_list
std::span< SortFunction *const > sort_func_list
the sort criteria functions
Definition sortlist_type.h:49
GUIList::Sort
bool Sort(Comp compare)
Sort the list.
Definition sortlist_type.h:266
GUIList::ForceResort
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Definition sortlist_type.h:232
GUIList::SortType
uint8_t SortType() const
Get the sorttype of the list.
Definition sortlist_type.h:110
GUIList::Filter
bool Filter(F filter_data)
Filter the data with the currently selected filter.
Definition sortlist_type.h:376
GUIList::Sort
bool Sort()
Overload of #Sort(SortFunction *compare) Overloaded to reduce external code.
Definition sortlist_type.h:304
GUIList::GetListing
Listing GetListing() const
Export current sort conditions.
Definition sortlist_type.h:134
GUIList::sort_type
uint8_t sort_type
what criteria to sort on
Definition sortlist_type.h:52
GUIList::SetSortFuncs
void SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
Definition sortlist_type.h:293
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:218
GUIList::SetSortType
void SetSortType(uint8_t n_type)
Set the sorttype of the list.
Definition sortlist_type.h:120
GUIList::filter_type
uint8_t filter_type
what criteria to filter on
Definition sortlist_type.h:53
GUIList::flags
SortListFlags flags
used to control sorting/resorting/etc.
Definition sortlist_type.h:51
GUIList::FilterType
uint8_t FilterType() const
Get the filtertype of the list.
Definition sortlist_type.h:163
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.
SortListFlag
SortListFlag
Flags of the sort list.
Definition sortlist_type.h:17
SortListFlag::Rebuild
@ Rebuild
rebuild the sort list
SortListFlag::Desc
@ Desc
sort descending or ascending
SortListFlag::Resort
@ Resort
instruct the code to resort the list in the next loop
SortListFlag::Filter
@ Filter
filter disabled/enabled
Filtering
Data structure describing what to show in the list (filter criteria).
Definition sortlist_type.h:31
Filtering::criteria
uint8_t criteria
Filtering criteria.
Definition sortlist_type.h:33
Filtering::state
bool state
Filter on/off.
Definition sortlist_type.h:32
Listing
Data structure describing how to show the list (what sort direction and criteria).
Definition sortlist_type.h:26
Listing::criteria
uint8_t criteria
Sorting criteria.
Definition sortlist_type.h:28
Listing::order
bool order
Ascending/descending.
Definition sortlist_type.h:27
timer_game_tick.h
Definition of the tick-based game-timer.