OpenTTD
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/smallvec_type.hpp"
16 #include "date_type.h"
17 
20  VL_NONE = 0,
21  VL_DESC = 1 << 0,
22  VL_RESORT = 1 << 1,
23  VL_REBUILD = 1 << 2,
24  VL_FIRST_SORT = 1 << 3,
25  VL_FILTER = 1 << 4,
26  VL_END = 1 << 5,
27 };
29 
30 
31 struct Listing {
32  bool order;
33  byte criteria;
34 };
36 struct Filtering {
37  bool state;
38  byte criteria;
39 };
40 
46 template <typename T, typename F = const char*>
47 class GUIList : public std::vector<T> {
48 public:
49  typedef bool SortFunction(const T&, const T&);
50  typedef bool CDECL FilterFunction(const T*, F);
51 
52 protected:
53  SortFunction * const *sort_func_list;
54  FilterFunction * const *filter_func_list;
56  uint8 sort_type;
57  uint8 filter_type;
58  uint16 resort_timer;
59 
65  bool IsSortable() const
66  {
67  return std::vector<T>::size() >= 2;
68  }
69 
74  {
75  /* Resort every 10 days */
76  this->resort_timer = DAY_TICKS * 10;
77  }
78 
79 public:
80  GUIList() :
81  sort_func_list(nullptr),
82  filter_func_list(nullptr),
83  flags(VL_FIRST_SORT),
84  sort_type(0),
85  filter_type(0),
86  resort_timer(1)
87  {};
88 
94  uint8 SortType() const
95  {
96  return this->sort_type;
97  }
98 
104  void SetSortType(uint8 n_type)
105  {
106  if (this->sort_type != n_type) {
107  SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
108  this->sort_type = n_type;
109  }
110  }
111 
118  {
119  Listing l;
120  l.order = (this->flags & VL_DESC) != 0;
121  l.criteria = this->sort_type;
122 
123  return l;
124  }
125 
132  {
133  if (l.order) {
134  SETBITS(this->flags, VL_DESC);
135  } else {
136  CLRBITS(this->flags, VL_DESC);
137  }
138  this->sort_type = l.criteria;
139 
140  SETBITS(this->flags, VL_FIRST_SORT);
141  }
142 
148  uint8 FilterType() const
149  {
150  return this->filter_type;
151  }
152 
158  void SetFilterType(uint8 n_type)
159  {
160  if (this->filter_type != n_type) {
161  this->filter_type = n_type;
162  }
163  }
164 
171  {
172  Filtering f;
173  f.state = (this->flags & VL_FILTER) != 0;
174  f.criteria = this->filter_type;
175 
176  return f;
177  }
178 
185  {
186  if (f.state) {
187  SETBITS(this->flags, VL_FILTER);
188  } else {
189  CLRBITS(this->flags, VL_FILTER);
190  }
191  this->filter_type = f.criteria;
192  }
193 
202  bool NeedResort()
203  {
204  if (--this->resort_timer == 0) {
205  SETBITS(this->flags, VL_RESORT);
206  this->ResetResortTimer();
207  return true;
208  }
209  return false;
210  }
211 
216  void ForceResort()
217  {
218  SETBITS(this->flags, VL_RESORT);
219  }
220 
226  bool IsDescSortOrder() const
227  {
228  return (this->flags & VL_DESC) != 0;
229  }
230 
237  {
238  this->flags ^= VL_DESC;
239 
240  if (this->IsSortable()) MemReverseT(std::vector<T>::data(), std::vector<T>::size());
241  }
242 
253  bool Sort(SortFunction *compare)
254  {
255  /* Do not sort if the resort bit is not set */
256  if (!(this->flags & VL_RESORT)) return false;
257 
258  CLRBITS(this->flags, VL_RESORT);
259 
260  this->ResetResortTimer();
261 
262  /* Do not sort when the list is not sortable */
263  if (!this->IsSortable()) return false;
264 
265  const bool desc = (this->flags & VL_DESC) != 0;
266 
267  if (this->flags & VL_FIRST_SORT) {
268  CLRBITS(this->flags, VL_FIRST_SORT);
269 
270  std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
271  return true;
272  }
273 
274  std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
275  return true;
276  }
277 
283  void SetSortFuncs(SortFunction * const *n_funcs)
284  {
285  this->sort_func_list = n_funcs;
286  }
287 
294  bool Sort()
295  {
296  assert(this->sort_func_list != nullptr);
297  return this->Sort(this->sort_func_list[this->sort_type]);
298  }
299 
305  bool IsFilterEnabled() const
306  {
307  return (this->flags & VL_FILTER) != 0;
308  }
309 
316  {
317  if (state) {
318  SETBITS(this->flags, VL_FILTER);
319  } else {
320  CLRBITS(this->flags, VL_FILTER);
321  }
322  }
323 
331  bool Filter(FilterFunction *decide, F filter_data)
332  {
333  /* Do not filter if the filter bit is not set */
334  if (!(this->flags & VL_FILTER)) return false;
335 
336  bool changed = false;
337  for (auto it = std::vector<T>::begin(); it != std::vector<T>::end(); /* Nothing */) {
338  if (!decide(&*it, filter_data)) {
339  it = std::vector<T>::erase(it);
340  changed = true;
341  } else {
342  it++;
343  }
344  }
345 
346  return changed;
347  }
348 
354  void SetFilterFuncs(FilterFunction * const *n_funcs)
355  {
356  this->filter_func_list = n_funcs;
357  }
358 
365  bool Filter(F filter_data)
366  {
367  if (this->filter_func_list == nullptr) return false;
368  return this->Filter(this->filter_func_list[this->filter_type], filter_data);
369  }
370 
375  bool NeedRebuild() const
376  {
377  return (this->flags & VL_REBUILD) != 0;
378  }
379 
384  {
385  SETBITS(this->flags, VL_REBUILD);
386  }
387 
393  void RebuildDone()
394  {
395  CLRBITS(this->flags, VL_REBUILD);
396  SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
397  }
398 };
399 
400 #endif /* SORTLIST_TYPE_H */
List template of &#39;things&#39; T to sort in a GUI.
Definition: sortlist_type.h:47
DECLARE_ENUM_AS_BIT_SET(GenderEthnicity) enum CompanyManagerFaceVariable
Bitgroups of the CompanyManagerFace variable.
void RebuildDone()
Notify the sortlist that the rebuild is done.
Simple vector class that allows allocating an item without the need to copy this->data needlessly...
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
uint8 filter_type
what criteria to filter on
Definition: sortlist_type.h:57
void SetSortFuncs(SortFunction *const *n_funcs)
Hand the array of sort function pointers to the sort list.
uint16 resort_timer
resort list after a given amount of ticks if set
Definition: sortlist_type.h:58
#define SETBITS(x, y)
Sets several bits in a variable.
void SetFilterType(uint8 n_type)
Set the filtertype of the list.
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:28
bool Filter(F filter_data)
Filter the data with the currently selected filter.
Functions related to bit mathematics.
bool NeedResort()
Check if a resort is needed next loop If used the resort timer will decrease every call till 0...
SortListFlags flags
used to control sorting/resorting/etc.
Definition: sortlist_type.h:55
void SetFilterFuncs(FilterFunction *const *n_funcs)
Hand the array of filter function pointers to the sort list.
#define CLRBITS(x, y)
Clears several bits in a variable.
static void MemReverseT(T *ptr1, T *ptr2)
Type safe memory reverse operation.
Definition: mem_func.hpp:77
rebuild the sort list
Definition: sortlist_type.h:23
void SetListing(Listing l)
Import sort conditions.
Type (helpers) for enums.
Data structure describing what to show in the list (filter criteria).
Definition: sortlist_type.h:36
bool NeedRebuild() const
Check if a rebuild is needed.
sort descending or ascending
Definition: sortlist_type.h:21
void ForceRebuild()
Force that a rebuild is needed.
bool IsSortable() const
Check if the list is sortable.
Definition: sortlist_type.h:65
byte criteria
Filtering criteria.
Definition: sortlist_type.h:38
SortFunction *const * sort_func_list
the sort criteria functions
Definition: sortlist_type.h:53
void ResetResortTimer()
Reset the resort timer.
Definition: sortlist_type.h:73
Listing GetListing() const
Export current sort conditions.
bool order
Ascending/descending.
Definition: sortlist_type.h:32
sort with quick sort first
Definition: sortlist_type.h:24
bool state
Filter on/off.
Definition: sortlist_type.h:37
instruct the code to resort the list in the next loop
Definition: sortlist_type.h:22
SortListFlags
Flags of the sort list.
Definition: sortlist_type.h:19
no sort
Definition: sortlist_type.h:20
void SetSortType(uint8 n_type)
Set the sorttype of the list.
bool Sort(SortFunction *compare)
Sort the list.
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
uint8 sort_type
what criteria to sort on
Definition: sortlist_type.h:56
void SetFilterState(bool state)
Enable or disable the filter.
filter disabled/enabled
Definition: sortlist_type.h:25
void ToggleSortOrder()
Toggle the sort order Since that is the worst condition for the sort function reverse the list here...
bool CDECL FilterFunction(const T *, F)
Signature of filter function.
Definition: sortlist_type.h:50
Data structure describing how to show the list (what sort direction and criteria).
Definition: sortlist_type.h:31
Types related to the dates in OpenTTD.
bool IsFilterEnabled() const
Check if the filter is enabled.
void SetFiltering(Filtering f)
Import filter conditions.
bool IsDescSortOrder() const
Check if the sort order is descending.
byte criteria
Sorting criteria.
Definition: sortlist_type.h:33
Filtering GetFiltering() const
Export current filter conditions.
uint8 FilterType() const
Get the filtertype of the list.
bool SortFunction(const T &, const T &)
Signature of sort function.
Definition: sortlist_type.h:49
bool Sort()
Overload of Sort(SortFunction *compare) Overloaded to reduce external code.
FilterFunction *const * filter_func_list
the filter criteria functions
Definition: sortlist_type.h:54
uint8 SortType() const
Get the sorttype of the list.
Definition: sortlist_type.h:94