Fix #8316: Make sort industries by production and transported with a cargo filter...
[openttd-github.git] / src / script / api / script_list.hpp
blob0dbb2c45d70735ef1177002bfaf7bb9e9bf00ac7
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 */
8 /** @file script_list.hpp A list which can keep item/value pairs, which you can walk. */
9 /** @defgroup ScriptList Classes that create a list of items. */
11 #ifndef SCRIPT_LIST_HPP
12 #define SCRIPT_LIST_HPP
14 #include "script_object.hpp"
15 #include <map>
16 #include <set>
18 class ScriptListSorter;
20 /**
21 * Class that creates a list which can keep item/value pairs, which you can walk.
22 * @api ai game
24 class ScriptList : public ScriptObject {
25 public:
26 /** Type of sorter */
27 enum SorterType {
28 SORT_BY_VALUE, ///< Sort the list based on the value of the item.
29 SORT_BY_ITEM, ///< Sort the list based on the item itself.
32 /** Sort ascending */
33 static const bool SORT_ASCENDING = true;
34 /** Sort descending */
35 static const bool SORT_DESCENDING = false;
37 private:
38 ScriptListSorter *sorter; ///< Sorting algorithm
39 SorterType sorter_type; ///< Sorting type
40 bool sort_ascending; ///< Whether to sort ascending or descending
41 bool initialized; ///< Whether an iteration has been started
42 int modifications; ///< Number of modification that has been done. To prevent changing data while valuating.
44 public:
45 typedef std::set<int64> ScriptItemList; ///< The list of items inside the bucket
46 typedef std::map<int64, ScriptItemList> ScriptListBucket; ///< The bucket list per value
47 typedef std::map<int64, int64> ScriptListMap; ///< List per item
49 ScriptListMap items; ///< The items in the list
50 ScriptListBucket buckets; ///< The items in the list, sorted by value
52 ScriptList();
53 ~ScriptList();
55 #ifdef DOXYGEN_API
56 /**
57 * Add a single item to the list.
58 * @param item the item to add. Should be unique, otherwise it is ignored.
59 * @param value the value to assign.
61 void AddItem(int64 item, int64 value);
62 #else
63 void AddItem(int64 item, int64 value = 0);
64 #endif /* DOXYGEN_API */
66 /**
67 * Remove a single item from the list.
68 * @param item the item to remove. If not existing, it is ignored.
70 void RemoveItem(int64 item);
72 /**
73 * Clear the list, making Count() returning 0 and IsEmpty() returning true.
75 void Clear();
77 /**
78 * Check if an item is in the list.
79 * @param item the item to check for.
80 * @return true if the item is in the list.
82 bool HasItem(int64 item);
84 /**
85 * Go to the beginning of the list and return the item. To get the value use list.GetValue(list.Begin()).
86 * @return the first item.
87 * @note returns 0 if beyond end-of-list. Use IsEnd() to check for end-of-list.
89 int64 Begin();
91 /**
92 * Go to the next item in the list and return the item. To get the value use list.GetValue(list.Next()).
93 * @return the next item.
94 * @note returns 0 if beyond end-of-list. Use IsEnd() to check for end-of-list.
96 int64 Next();
98 /**
99 * Check if a list is empty.
100 * @return true if the list is empty.
102 bool IsEmpty();
105 * Check if there is a element left. In other words, if this is false,
106 * the last call to Begin() or Next() returned a valid item.
107 * @return true if the current item is beyond end-of-list.
109 bool IsEnd();
112 * Returns the amount of items in the list.
113 * @return amount of items in the list.
115 int32 Count();
118 * Get the value that belongs to this item.
119 * @param item the item to get the value from
120 * @return the value that belongs to this item.
122 int64 GetValue(int64 item);
125 * Set a value of an item directly.
126 * @param item the item to set the value for.
127 * @param value the value to give to the item
128 * @return true if we could set the item to value, false otherwise.
129 * @note Changing values of items while looping through a list might cause
130 * entries to be skipped. Be very careful with such operations.
132 bool SetValue(int64 item, int64 value);
135 * Sort this list by the given sorter and direction.
136 * @param sorter the type of sorter to use
137 * @param ascending if true, lowest value is on top, else at bottom.
138 * @note the current item stays at the same place.
139 * @see SORT_ASCENDING SORT_DESCENDING
141 void Sort(SorterType sorter, bool ascending);
144 * Add one list to another one.
145 * @param list The list that will be added to the caller.
146 * @post The list to be added ('list') stays unmodified.
147 * @note All added items keep their value as it was in 'list'.
148 * @note If the item already exists inside the caller, the value of the
149 * list that is added is set on the item.
151 void AddList(ScriptList *list);
154 * Swap the contents of two lists.
155 * @param list The list that will be swapped with.
157 void SwapList(ScriptList *list);
160 * Removes all items with a higher value than 'value'.
161 * @param value the value above which all items are removed.
163 void RemoveAboveValue(int64 value);
166 * Removes all items with a lower value than 'value'.
167 * @param value the value below which all items are removed.
169 void RemoveBelowValue(int64 value);
172 * Removes all items with a value above start and below end.
173 * @param start the lower bound of the to be removed values (exclusive).
174 * @param end the upper bound of the to be removed values (exclusive).
176 void RemoveBetweenValue(int64 start, int64 end);
179 * Remove all items with this value.
180 * @param value the value to remove.
182 void RemoveValue(int64 value);
185 * Remove the first count items.
186 * @param count the amount of items to remove.
188 void RemoveTop(int32 count);
191 * Remove the last count items.
192 * @param count the amount of items to remove.
194 void RemoveBottom(int32 count);
197 * Remove everything that is in the given list from this list (same item index that is).
198 * @param list the list of items to remove.
199 * @pre list != nullptr
201 void RemoveList(ScriptList *list);
204 * Keep all items with a higher value than 'value'.
205 * @param value the value above which all items are kept.
207 void KeepAboveValue(int64 value);
210 * Keep all items with a lower value than 'value'.
211 * @param value the value below which all items are kept.
213 void KeepBelowValue(int64 value);
216 * Keep all items with a value above start and below end.
217 * @param start the lower bound of the to be kept values (exclusive).
218 * @param end the upper bound of the to be kept values (exclusive).
220 void KeepBetweenValue(int64 start, int64 end);
223 * Keep all items with this value.
224 * @param value the value to keep.
226 void KeepValue(int64 value);
229 * Keep the first count items, i.e. remove everything except the first count items.
230 * @param count the amount of items to keep.
232 void KeepTop(int32 count);
235 * Keep the last count items, i.e. remove everything except the last count items.
236 * @param count the amount of items to keep.
238 void KeepBottom(int32 count);
241 * Keeps everything that is in the given list from this list (same item index that is).
242 * @param list the list of items to keep.
243 * @pre list != nullptr
245 void KeepList(ScriptList *list);
247 #ifndef DOXYGEN_API
249 * Used for 'foreach()' and [] get from Squirrel.
251 SQInteger _get(HSQUIRRELVM vm);
254 * Used for [] set from Squirrel.
256 SQInteger _set(HSQUIRRELVM vm);
259 * Used for 'foreach()' from Squirrel.
261 SQInteger _nexti(HSQUIRRELVM vm);
264 * The Valuate() wrapper from Squirrel.
266 SQInteger Valuate(HSQUIRRELVM vm);
267 #else
269 * Give all items a value defined by the valuator you give.
270 * @param valuator_function The function which will be doing the valuation.
271 * @param params The params to give to the valuators (minus the first param,
272 * which is always the index-value we are valuating).
273 * @note You may not add, remove or change (setting the value of) items while
274 * valuating. You may also not (re)sort while valuating.
275 * @note You can write your own valuators and use them. Just remember that
276 * the first parameter should be the index-value, and it should return
277 * an integer.
278 * @note Example:
279 * list.Valuate(ScriptBridge.GetPrice, 5);
280 * list.Valuate(ScriptBridge.GetMaxLength);
281 * function MyVal(bridge_id, myparam)
283 * return myparam * bridge_id; // This is silly
285 * list.Valuate(MyVal, 12);
287 void Valuate(void *valuator_function, int params, ...);
288 #endif /* DOXYGEN_API */
291 #endif /* SCRIPT_LIST_HPP */