OpenTTD Source  14.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 
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 };
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:
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 
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 
138  {
139  Listing l;
140  l.order = (this->flags & VL_DESC) != 0;
141  l.criteria = this->sort_type;
142 
143  return l;
144  }
145 
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 
189  {
190  Filtering f;
191  f.state = (this->flags & VL_FILTER) != 0;
192  f.criteria = this->filter_type;
193 
194  return f;
195  }
196 
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 
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 
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