OpenTTD Source  1.10.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 <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  template <typename Comp>
254  bool Sort(Comp compare)
255  {
256  /* Do not sort if the resort bit is not set */
257  if (!(this->flags & VL_RESORT)) return false;
258 
259  CLRBITS(this->flags, VL_RESORT);
260 
261  this->ResetResortTimer();
262 
263  /* Do not sort when the list is not sortable */
264  if (!this->IsSortable()) return false;
265 
266  const bool desc = (this->flags & VL_DESC) != 0;
267 
268  if (this->flags & VL_FIRST_SORT) {
269  CLRBITS(this->flags, VL_FIRST_SORT);
270 
271  std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
272  return true;
273  }
274 
275  std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
276  return true;
277  }
278 
284  void SetSortFuncs(SortFunction * const *n_funcs)
285  {
286  this->sort_func_list = n_funcs;
287  }
288 
295  bool Sort()
296  {
297  assert(this->sort_func_list != nullptr);
298  return this->Sort(this->sort_func_list[this->sort_type]);
299  }
300 
306  bool IsFilterEnabled() const
307  {
308  return (this->flags & VL_FILTER) != 0;
309  }
310 
317  {
318  if (state) {
319  SETBITS(this->flags, VL_FILTER);
320  } else {
321  CLRBITS(this->flags, VL_FILTER);
322  }
323  }
324 
332  bool Filter(FilterFunction *decide, F filter_data)
333  {
334  /* Do not filter if the filter bit is not set */
335  if (!(this->flags & VL_FILTER)) return false;
336 
337  bool changed = false;
338  for (auto it = std::vector<T>::begin(); it != std::vector<T>::end(); /* Nothing */) {
339  if (!decide(&*it, filter_data)) {
340  it = std::vector<T>::erase(it);
341  changed = true;
342  } else {
343  it++;
344  }
345  }
346 
347  return changed;
348  }
349 
355  void SetFilterFuncs(FilterFunction * const *n_funcs)
356  {
357  this->filter_func_list = n_funcs;
358  }
359 
366  bool Filter(F filter_data)
367  {
368  if (this->filter_func_list == nullptr) return false;
369  return this->Filter(this->filter_func_list[this->filter_type], filter_data);
370  }
371 
376  bool NeedRebuild() const
377  {
378  return (this->flags & VL_REBUILD) != 0;
379  }
380 
385  {
386  SETBITS(this->flags, VL_REBUILD);
387  }
388 
394  void RebuildDone()
395  {
396  CLRBITS(this->flags, VL_REBUILD);
397  SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
398  }
399 };
400 
401 #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
bool Sort(Comp compare)
Sort the list.
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.
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