OpenTTD Source  12.0-beta2
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_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 
45 template <typename T, typename F = const char*>
46 class GUIList : public std::vector<T> {
47 public:
48  typedef bool SortFunction(const T&, const T&);
49  typedef bool CDECL FilterFunction(const T*, F);
50 
51 protected:
55  uint8 sort_type;
56  uint8 filter_type;
57  uint16 resort_timer;
58 
64  bool IsSortable() const
65  {
66  return std::vector<T>::size() >= 2;
67  }
68 
73  {
74  /* Resort every 10 days */
75  this->resort_timer = DAY_TICKS * 10;
76  }
77 
78 public:
79  GUIList() :
80  sort_func_list(nullptr),
81  filter_func_list(nullptr),
82  flags(VL_NONE),
83  sort_type(0),
84  filter_type(0),
85  resort_timer(1)
86  {};
87 
93  uint8 SortType() const
94  {
95  return this->sort_type;
96  }
97 
103  void SetSortType(uint8 n_type)
104  {
105  if (this->sort_type != n_type) {
106  SETBITS(this->flags, VL_RESORT);
107  this->sort_type = n_type;
108  }
109  }
110 
117  {
118  Listing l;
119  l.order = (this->flags & VL_DESC) != 0;
120  l.criteria = this->sort_type;
121 
122  return l;
123  }
124 
131  {
132  if (l.order) {
133  SETBITS(this->flags, VL_DESC);
134  } else {
135  CLRBITS(this->flags, VL_DESC);
136  }
137  this->sort_type = l.criteria;
138  }
139 
145  uint8 FilterType() const
146  {
147  return this->filter_type;
148  }
149 
155  void SetFilterType(uint8 n_type)
156  {
157  if (this->filter_type != n_type) {
158  this->filter_type = n_type;
159  }
160  }
161 
168  {
169  Filtering f;
170  f.state = (this->flags & VL_FILTER) != 0;
171  f.criteria = this->filter_type;
172 
173  return f;
174  }
175 
182  {
183  if (f.state) {
184  SETBITS(this->flags, VL_FILTER);
185  } else {
186  CLRBITS(this->flags, VL_FILTER);
187  }
188  this->filter_type = f.criteria;
189  }
190 
199  bool NeedResort()
200  {
201  if (--this->resort_timer == 0) {
202  SETBITS(this->flags, VL_RESORT);
203  this->ResetResortTimer();
204  return true;
205  }
206  return false;
207  }
208 
213  void ForceResort()
214  {
215  SETBITS(this->flags, VL_RESORT);
216  }
217 
223  bool IsDescSortOrder() const
224  {
225  return (this->flags & VL_DESC) != 0;
226  }
227 
234  {
235  this->flags ^= VL_DESC;
236 
237  if (this->IsSortable()) MemReverseT(std::vector<T>::data(), std::vector<T>::size());
238  }
239 
246  template <typename Comp>
247  bool Sort(Comp compare)
248  {
249  /* Do not sort if the resort bit is not set */
250  if (!(this->flags & VL_RESORT)) return false;
251 
252  CLRBITS(this->flags, VL_RESORT);
253 
254  this->ResetResortTimer();
255 
256  /* Do not sort when the list is not sortable */
257  if (!this->IsSortable()) return false;
258 
259  const bool desc = (this->flags & VL_DESC) != 0;
260 
261  std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
262  return true;
263  }
264 
270  void SetSortFuncs(SortFunction * const *n_funcs)
271  {
272  this->sort_func_list = n_funcs;
273  }
274 
281  bool Sort()
282  {
283  assert(this->sort_func_list != nullptr);
284  return this->Sort(this->sort_func_list[this->sort_type]);
285  }
286 
292  bool IsFilterEnabled() const
293  {
294  return (this->flags & VL_FILTER) != 0;
295  }
296 
302  void SetFilterState(bool state)
303  {
304  if (state) {
305  SETBITS(this->flags, VL_FILTER);
306  } else {
307  CLRBITS(this->flags, VL_FILTER);
308  }
309  }
310 
318  bool Filter(FilterFunction *decide, F filter_data)
319  {
320  /* Do not filter if the filter bit is not set */
321  if (!(this->flags & VL_FILTER)) return false;
322 
323  bool changed = false;
324  for (auto it = std::vector<T>::begin(); it != std::vector<T>::end(); /* Nothing */) {
325  if (!decide(&*it, filter_data)) {
326  it = std::vector<T>::erase(it);
327  changed = true;
328  } else {
329  it++;
330  }
331  }
332 
333  return changed;
334  }
335 
341  void SetFilterFuncs(FilterFunction * const *n_funcs)
342  {
343  this->filter_func_list = n_funcs;
344  }
345 
352  bool Filter(F filter_data)
353  {
354  if (this->filter_func_list == nullptr) return false;
355  return this->Filter(this->filter_func_list[this->filter_type], filter_data);
356  }
357 
362  bool NeedRebuild() const
363  {
364  return (this->flags & VL_REBUILD) != 0;
365  }
366 
371  {
372  SETBITS(this->flags, VL_REBUILD);
373  }
374 
380  void RebuildDone()
381  {
382  CLRBITS(this->flags, VL_REBUILD);
383  SETBITS(this->flags, VL_RESORT);
384  }
385 };
386 
387 #endif /* SORTLIST_TYPE_H */
GUIList::SortType
uint8 SortType() const
Get the sorttype of the list.
Definition: sortlist_type.h:93
GUIList::Sort
bool Sort(Comp compare)
Sort the list.
Definition: sortlist_type.h:247
GUIList::SetFilterType
void SetFilterType(uint8 n_type)
Set the filtertype of the list.
Definition: sortlist_type.h:155
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:46
smallvec_type.hpp
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
MemReverseT
static void MemReverseT(T *ptr1, T *ptr2)
Type safe memory reverse operation.
Definition: mem_func.hpp:77
GUIList::IsSortable
bool IsSortable() const
Check if the list is sortable.
Definition: sortlist_type.h:64
GUIList::SetSortType
void SetSortType(uint8 n_type)
Set the sorttype of the list.
Definition: sortlist_type.h:103
SETBITS
#define SETBITS(x, y)
Sets several bits in a variable.
Definition: bitmath_func.hpp:136
GUIList::SetFilterFuncs
void SetFilterFuncs(FilterFunction *const *n_funcs)
Hand the array of filter function pointers to the sort list.
Definition: sortlist_type.h:341
bitmath_func.hpp
GUIList::filter_func_list
FilterFunction *const * filter_func_list
the filter criteria functions
Definition: sortlist_type.h:53
GUIList::ResetResortTimer
void ResetResortTimer()
Reset the resort timer.
Definition: sortlist_type.h:72
GUIList::Filter
bool Filter(F filter_data)
Filter the data with the currently selected filter.
Definition: sortlist_type.h:352
Filtering::criteria
byte criteria
Filtering criteria.
Definition: sortlist_type.h:37
VL_FILTER
@ VL_FILTER
filter disabled/enabled
Definition: sortlist_type.h:24
GUIList::IsDescSortOrder
bool IsDescSortOrder() const
Check if the sort order is descending.
Definition: sortlist_type.h:223
Listing
Data structure describing how to show the list (what sort direction and criteria).
Definition: sortlist_type.h:30
GUIList::SetFilterState
void SetFilterState(bool state)
Enable or disable the filter.
Definition: sortlist_type.h:302
GUIList::SortFunction
bool SortFunction(const T &, const T &)
Signature of sort function.
Definition: sortlist_type.h:48
GUIList::SetListing
void SetListing(Listing l)
Import sort conditions.
Definition: sortlist_type.h:130
GUIList::filter_type
uint8 filter_type
what criteria to filter on
Definition: sortlist_type.h:56
Listing::order
bool order
Ascending/descending.
Definition: sortlist_type.h:31
GUIList::sort_type
uint8 sort_type
what criteria to sort on
Definition: sortlist_type.h:55
GUIList::flags
SortListFlags flags
used to control sorting/resorting/etc.
Definition: sortlist_type.h:54
Filtering
Data structure describing what to show in the list (filter criteria).
Definition: sortlist_type.h:35
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:233
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:199
date_type.h
GUIList::NeedRebuild
bool NeedRebuild() const
Check if a rebuild is needed.
Definition: sortlist_type.h:362
VL_DESC
@ VL_DESC
sort descending or ascending
Definition: sortlist_type.h:21
GUIList::resort_timer
uint16 resort_timer
resort list after a given amount of ticks if set
Definition: sortlist_type.h:57
GUIList::FilterFunction
bool CDECL FilterFunction(const T *, F)
Signature of filter function.
Definition: sortlist_type.h:49
GUIList::GetListing
Listing GetListing() const
Export current sort conditions.
Definition: sortlist_type.h:116
GUIList::SetFiltering
void SetFiltering(Filtering f)
Import filter conditions.
Definition: sortlist_type.h:181
GUIList::Filter
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
Definition: sortlist_type.h:318
GUIList::FilterType
uint8 FilterType() const
Get the filtertype of the list.
Definition: sortlist_type.h:145
enum_type.hpp
GUIList::ForceResort
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Definition: sortlist_type.h:213
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::ForceRebuild
void ForceRebuild()
Force that a rebuild is needed.
Definition: sortlist_type.h:370
GUIList::IsFilterEnabled
bool IsFilterEnabled() const
Check if the filter is enabled.
Definition: sortlist_type.h:292
GUIList::Sort
bool Sort()
Overload of #Sort(SortFunction *compare) Overloaded to reduce external code.
Definition: sortlist_type.h:281
GUIList::sort_func_list
SortFunction *const * sort_func_list
the sort criteria functions
Definition: sortlist_type.h:52
GUIList::GetFiltering
Filtering GetFiltering() const
Export current filter conditions.
Definition: sortlist_type.h:167
GUIList::RebuildDone
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition: sortlist_type.h:380
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
CLRBITS
#define CLRBITS(x, y)
Clears several bits in a variable.
Definition: bitmath_func.hpp:166
DAY_TICKS
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
GUIList::SetSortFuncs
void SetSortFuncs(SortFunction *const *n_funcs)
Hand the array of sort function pointers to the sort list.
Definition: sortlist_type.h:270