OpenTTD
sortlist_type.h
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifndef SORTLIST_TYPE_H
13 #define SORTLIST_TYPE_H
14 
15 #include "core/enum_type.hpp"
16 #include "core/bitmath_func.hpp"
17 #include "core/smallvec_type.hpp"
18 #include "date_type.h"
19 
22  VL_NONE = 0,
23  VL_DESC = 1 << 0,
24  VL_RESORT = 1 << 1,
25  VL_REBUILD = 1 << 2,
26  VL_FIRST_SORT = 1 << 3,
27  VL_FILTER = 1 << 4,
28  VL_END = 1 << 5,
29 };
31 
32 
33 struct Listing {
34  bool order;
35  byte criteria;
36 };
38 struct Filtering {
39  bool state;
40  byte criteria;
41 };
42 
48 template <typename T, typename F = const char*>
49 class GUIList : public std::vector<T> {
50 public:
51  typedef bool SortFunction(const T&, const T&);
52  typedef bool CDECL FilterFunction(const T*, F);
53 
54 protected:
55  SortFunction * const *sort_func_list;
56  FilterFunction * const *filter_func_list;
58  uint8 sort_type;
59  uint8 filter_type;
60  uint16 resort_timer;
61 
67  bool IsSortable() const
68  {
69  return std::vector<T>::size() >= 2;
70  }
71 
76  {
77  /* Resort every 10 days */
78  this->resort_timer = DAY_TICKS * 10;
79  }
80 
81 public:
82  GUIList() :
83  sort_func_list(nullptr),
84  filter_func_list(nullptr),
85  flags(VL_FIRST_SORT),
86  sort_type(0),
87  filter_type(0),
88  resort_timer(1)
89  {};
90 
96  uint8 SortType() const
97  {
98  return this->sort_type;
99  }
100 
106  void SetSortType(uint8 n_type)
107  {
108  if (this->sort_type != n_type) {
109  SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
110  this->sort_type = n_type;
111  }
112  }
113 
120  {
121  Listing l;
122  l.order = (this->flags & VL_DESC) != 0;
123  l.criteria = this->sort_type;
124 
125  return l;
126  }
127 
134  {
135  if (l.order) {
136  SETBITS(this->flags, VL_DESC);
137  } else {
138  CLRBITS(this->flags, VL_DESC);
139  }
140  this->sort_type = l.criteria;
141 
142  SETBITS(this->flags, VL_FIRST_SORT);
143  }
144 
150  uint8 FilterType() const
151  {
152  return this->filter_type;
153  }
154 
160  void SetFilterType(uint8 n_type)
161  {
162  if (this->filter_type != n_type) {
163  this->filter_type = n_type;
164  }
165  }
166 
173  {
174  Filtering f;
175  f.state = (this->flags & VL_FILTER) != 0;
176  f.criteria = this->filter_type;
177 
178  return f;
179  }
180 
187  {
188  if (f.state) {
189  SETBITS(this->flags, VL_FILTER);
190  } else {
191  CLRBITS(this->flags, VL_FILTER);
192  }
193  this->filter_type = f.criteria;
194  }
195 
204  bool NeedResort()
205  {
206  if (--this->resort_timer == 0) {
207  SETBITS(this->flags, VL_RESORT);
208  this->ResetResortTimer();
209  return true;
210  }
211  return false;
212  }
213 
218  void ForceResort()
219  {
220  SETBITS(this->flags, VL_RESORT);
221  }
222 
228  bool IsDescSortOrder() const
229  {
230  return (this->flags & VL_DESC) != 0;
231  }
232 
239  {
240  this->flags ^= VL_DESC;
241 
242  if (this->IsSortable()) MemReverseT(std::vector<T>::data(), std::vector<T>::size());
243  }
244 
255  bool Sort(SortFunction *compare)
256  {
257  /* Do not sort if the resort bit is not set */
258  if (!(this->flags & VL_RESORT)) return false;
259 
260  CLRBITS(this->flags, VL_RESORT);
261 
262  this->ResetResortTimer();
263 
264  /* Do not sort when the list is not sortable */
265  if (!this->IsSortable()) return false;
266 
267  const bool desc = (this->flags & VL_DESC) != 0;
268 
269  if (this->flags & VL_FIRST_SORT) {
270  CLRBITS(this->flags, VL_FIRST_SORT);
271 
272  std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
273  return true;
274  }
275 
276  std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
277  return true;
278  }
279 
285  void SetSortFuncs(SortFunction * const *n_funcs)
286  {
287  this->sort_func_list = n_funcs;
288  }
289 
296  bool Sort()
297  {
298  assert(this->sort_func_list != nullptr);
299  return this->Sort(this->sort_func_list[this->sort_type]);
300  }
301 
307  bool IsFilterEnabled() const
308  {
309  return (this->flags & VL_FILTER) != 0;
310  }
311 
318  {
319  if (state) {
320  SETBITS(this->flags, VL_FILTER);
321  } else {
322  CLRBITS(this->flags, VL_FILTER);
323  }
324  }
325 
333  bool Filter(FilterFunction *decide, F filter_data)
334  {
335  /* Do not filter if the filter bit is not set */
336  if (!(this->flags & VL_FILTER)) return false;
337 
338  bool changed = false;
339  for (auto it = std::vector<T>::begin(); it != std::vector<T>::end(); /* Nothing */) {
340  if (!decide(&*it, filter_data)) {
341  it = std::vector<T>::erase(it);
342  changed = true;
343  } else {
344  it++;
345  }
346  }
347 
348  return changed;
349  }
350 
356  void SetFilterFuncs(FilterFunction * const *n_funcs)
357  {
358  this->filter_func_list = n_funcs;
359  }
360 
367  bool Filter(F filter_data)
368  {
369  if (this->filter_func_list == nullptr) return false;
370  return this->Filter(this->filter_func_list[this->filter_type], filter_data);
371  }
372 
377  bool NeedRebuild() const
378  {
379  return (this->flags & VL_REBUILD) != 0;
380  }
381 
386  {
387  SETBITS(this->flags, VL_REBUILD);
388  }
389 
395  void RebuildDone()
396  {
397  CLRBITS(this->flags, VL_REBUILD);
398  SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
399  }
400 };
401 
402 #endif /* SORTLIST_TYPE_H */
List template of &#39;things&#39; T to sort in a GUI.
Definition: sortlist_type.h:49
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:59
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:60
#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:30
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:57
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:79
rebuild the sort list
Definition: sortlist_type.h:25
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:38
bool NeedRebuild() const
Check if a rebuild is needed.
sort descending or ascending
Definition: sortlist_type.h:23
void ForceRebuild()
Force that a rebuild is needed.
bool IsSortable() const
Check if the list is sortable.
Definition: sortlist_type.h:67
byte criteria
Filtering criteria.
Definition: sortlist_type.h:40
SortFunction *const * sort_func_list
the sort criteria functions
Definition: sortlist_type.h:55
void ResetResortTimer()
Reset the resort timer.
Definition: sortlist_type.h:75
Listing GetListing() const
Export current sort conditions.
bool order
Ascending/descending.
Definition: sortlist_type.h:34
sort with quick sort first
Definition: sortlist_type.h:26
bool state
Filter on/off.
Definition: sortlist_type.h:39
instruct the code to resort the list in the next loop
Definition: sortlist_type.h:24
SortListFlags
Flags of the sort list.
Definition: sortlist_type.h:21
no sort
Definition: sortlist_type.h:22
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:58
void SetFilterState(bool state)
Enable or disable the filter.
filter disabled/enabled
Definition: sortlist_type.h:27
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:52
Data structure describing how to show the list (what sort direction and criteria).
Definition: sortlist_type.h:33
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:35
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:51
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:56
uint8 SortType() const
Get the sorttype of the list.
Definition: sortlist_type.h:96