Update readme and changelog for v1.27.0
[openttd-joker.git] / src / tracerestrict.h
blob2199f3c93d9a2463dd27475ed3b90eddb75fffb0
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 tracerestrict.h Header file for Trace Restrict */
10 #ifndef TRACERESTRICT_H
11 #define TRACERESTRICT_H
13 #include "stdafx.h"
14 #include "core/bitmath_func.hpp"
15 #include "core/enum_type.hpp"
16 #include "core/pool_type.hpp"
17 #include "core/container_func.hpp"
18 #include "command_func.h"
19 #include "rail_map.h"
20 #include "tile_type.h"
21 #include "group_type.h"
22 #include "vehicle_type.h"
23 #include "3rdparty/cpp-btree/btree_map.h"
24 #include <vector>
25 #include <unordered_map>
27 struct Train;
29 /** Program pool ID type. */
30 typedef uint32 TraceRestrictProgramID;
31 struct TraceRestrictProgram;
33 /** Tile/track mapping type. */
34 typedef uint32 TraceRestrictRefId;
36 /** Type of the pool for trace restrict programs. */
37 typedef Pool<TraceRestrictProgram, TraceRestrictProgramID, 16, 256000> TraceRestrictProgramPool;
38 /** The actual pool for trace restrict nodes. */
39 extern TraceRestrictProgramPool _tracerestrictprogram_pool;
41 /** Slot pool ID type. */
42 typedef uint16 TraceRestrictSlotID;
43 struct TraceRestrictSlot;
45 /** Type of the pool for trace restrict slots. */
46 typedef Pool<TraceRestrictSlot, TraceRestrictSlotID, 16, 0xFFF0> TraceRestrictSlotPool;
47 /** The actual pool for trace restrict nodes. */
48 extern TraceRestrictSlotPool _tracerestrictslot_pool;
50 static const TraceRestrictSlotID NEW_TRACE_RESTRICT_SLOT_ID = 0xFFFD; // for GUI use only
51 static const TraceRestrictSlotID ALL_TRAINS_TRACE_RESTRICT_SLOT_ID = 0xFFFE; // for GUI use only
52 static const TraceRestrictSlotID INVALID_TRACE_RESTRICT_SLOT_ID = 0xFFFF;
54 extern const uint16 _tracerestrict_pathfinder_penalty_preset_values[];
56 #define FOR_ALL_TRACE_RESTRICT_PROGRAMS_FROM(var, start) FOR_ALL_ITEMS_FROM(TraceRestrictProgram, tr_index, var, start)
57 #define FOR_ALL_TRACE_RESTRICT_PROGRAMS(var) FOR_ALL_TRACE_RESTRICT_PROGRAMS_FROM(var, 0)
59 /** Type used for the TraceRestrictRefId -> TraceRestrictProgramID mapping */
60 struct TraceRestrictMappingItem {
61 TraceRestrictProgramID program_id;
63 TraceRestrictMappingItem() { }
65 TraceRestrictMappingItem(TraceRestrictProgramID program_id_)
66 : program_id(program_id_) { }
69 typedef btree::btree_map<TraceRestrictRefId, TraceRestrictMappingItem> TraceRestrictMapping;
71 /** The actual mapping from TraceRestrictRefId to TraceRestrictProgramID. */
72 extern TraceRestrictMapping _tracerestrictprogram_mapping;
74 void ClearTraceRestrictMapping();
76 /** Type of a single instruction, this is bit-packed as per TraceRestrictItemFlagAllocation */
77 typedef uint32 TraceRestrictItem;
79 /**
80 * Describes the allocation of bits to fields in TraceRestrictItem
81 * Of the fields below, the type seem the most likely
82 * to need future expansion, hence the reserved bits are placed
83 * immediately after them
85 * COUNT values describe the field bit width
86 * OFFSET values describe the field bit offset
88 enum TraceRestrictItemFlagAllocation {
89 TRIFA_TYPE_COUNT = 5,
90 TRIFA_TYPE_OFFSET = 0,
92 /* 3 bits reserved for future use */
94 TRIFA_COND_FLAGS_COUNT = 3,
95 TRIFA_COND_FLAGS_OFFSET = 8,
97 TRIFA_AUX_FIELD_COUNT = 2,
98 TRIFA_AUX_FIELD_OFFSET = 11,
100 TRIFA_COND_OP_COUNT = 3,
101 TRIFA_COND_OP_OFFSET = 13,
103 TRIFA_VALUE_COUNT = 16,
104 TRIFA_VALUE_OFFSET = 16,
108 * Enumeration of TraceRestrictItem type field
109 * This is split into two halves:
110 * * non-conditionals < TRIT_COND_BEGIN
111 * * conditionals, >= TRIT_COND_BEGIN
113 enum TraceRestrictItemType {
114 TRIT_NULL = 0, ///< Null-type, not in programs and not valid for execution, mainly used with TraceRestrictNullTypeSpecialValue for start/end
115 TRIT_PF_DENY = 1, ///< Pathfinder deny/allow
116 TRIT_PF_PENALTY = 2, ///< Add to pathfinder penalty
117 TRIT_RESERVE_THROUGH = 3, ///< Reserve through PBS signal
118 TRIT_LONG_RESERVE = 4, ///< Long reserve PBS signal
119 TRIT_WAIT_AT_PBS = 5, ///< Wait at PBS signal
120 TRIT_SLOT = 6, ///< Slot operation
122 TRIT_COND_BEGIN = 8, ///< Start of conditional item types, note that this has the same value as TRIT_COND_ENDIF
123 TRIT_COND_ENDIF = 8, ///< This is an endif block or an else block
124 TRIT_COND_UNDEFINED = 9, ///< This condition has no type defined (evaluate as false)
125 TRIT_COND_TRAIN_LENGTH = 10, ///< Test train length
126 TRIT_COND_MAX_SPEED = 11, ///< Test train max speed
127 TRIT_COND_CURRENT_ORDER = 12, ///< Test train current order (station, waypoint or depot)
128 TRIT_COND_NEXT_ORDER = 13, ///< Test train next order (station, waypoint or depot)
129 TRIT_COND_LAST_STATION = 14, ///< Test train last visited station
130 TRIT_COND_CARGO = 15, ///< Test if train can carry cargo type
131 TRIT_COND_ENTRY_DIRECTION = 16, ///< Test which side of signal/signal tile is being entered from
132 TRIT_COND_PBS_ENTRY_SIGNAL = 17, ///< Test tile and PBS-state of previous signal
133 TRIT_COND_TRAIN_GROUP = 18, ///< Test train group membership
134 TRIT_COND_TRAIN_IN_SLOT = 19, ///< Test train slot membership
135 TRIT_COND_SLOT_OCCUPANCY = 20, ///< Test train slot occupancy state
136 /* space up to 31 */
140 * TraceRestrictItem condition flags field, only valid with conditional types (IsTraceRestrictTypeConditional() is true)
142 enum TraceRestrictCondFlags {
143 TRCF_DEFAULT = 0, ///< indicates end if for type: TRIT_COND_ENDIF, if otherwise
144 TRCF_ELSE = 1 << 0, ///< indicates an else block for type: TRIT_COND_ENDIF, elif otherwise
145 TRCF_OR = 1 << 1, ///< indicates an orif block, not valid with type: TRIT_COND_ENDIF
146 /* 1 bit spare */
148 DECLARE_ENUM_AS_BIT_SET(TraceRestrictCondFlags)
151 * Enumeration of TraceRestrictItemvalue type field when type is TRIT_NULL
153 enum TraceRestrictNullTypeSpecialValue {
154 TRNTSV_NULL = 0, ///< null, what you get when you zero-init a TraceRestrictItemvalue
155 TRNTSV_START = 1, ///< start tag, generated within GUI
156 TRNTSV_END = 2, ///< end tag, generated within GUI
160 * Enumeration of TraceRestrictItemvalue type field when value type is TRVT_DIRECTION
162 enum TraceRestrictDirectionTypeSpecialValue {
163 TRNTSV_NE = 0, ///< DIAGDIR_NE: entering at NE tile edge
164 TRNTSV_SE = 1, ///< DIAGDIR_SE: entering at SE tile edge
165 TRNTSV_SW = 2, ///< DIAGDIR_SW: entering at SW tile edge
166 TRNTSV_NW = 3, ///< DIAGDIR_NW: entering at NW tile edge
167 TRDTSV_FRONT = 4, ///< entering at front face of signal
168 TRDTSV_BACK = 5, ///< entering at rear face of signal
172 * TraceRestrictItem condition operator field, only valid with conditional types (IsTraceRestrictTypeConditional() is true)
174 enum TraceRestrictCondOp {
175 TRCO_IS = 0, ///< equality test, or can carry test for cargo
176 TRCO_ISNOT = 1, ///< inequality test, or can't carry test for cargo
177 TRCO_LT = 2, ///< less than test
178 TRCO_LTE = 3, ///< less than or equal test
179 TRCO_GT = 4, ///< greater than test
180 TRCO_GTE = 5, ///< greater than or equal test
181 /* space up to 7 */
185 * TraceRestrictItem auxiliary type field, for order type conditionals
187 enum TraceRestrictOrderCondAuxField {
188 TROCAF_STATION = 0, ///< value field is a station StationID
189 TROCAF_WAYPOINT = 1, ///< value field is a waypoint StationID
190 TROCAF_DEPOT = 2, ///< value field is a depot DepotID
191 /* space up to 3 */
195 * TraceRestrictItem auxiliary type field, for order type conditionals
197 enum TraceRestrictPathfinderPenaltyAuxField {
198 TRPPAF_VALUE = 0, ///< value field is a the pathfinder penalty to use
199 TRPPAF_PRESET = 1, ///< value field is a pathfinder penalty prefix index: TraceRestrictPathfinderPenaltyPresetIndex
200 /* space up to 3 */
204 * TraceRestrictItem repurposed condition operator field, for slot operation type actions
206 enum TraceRestrictSlotCondOpField {
207 TRSCOF_ACQUIRE_WAIT = 0, ///< acquire a slot, or wait at the current signal
208 TRSCOF_ACQUIRE_TRY = 1, ///< try to acquire a slot, or carry on otherwise
209 TRSCOF_RELEASE_BACK = 2, ///< release a slot (back of train)
210 TRSCOF_RELEASE_FRONT = 3, ///< release a slot (front of train)
211 /* space up to 8 */
215 * TraceRestrictItem auxiliary type field, for TRIT_COND_SLOT_OCCUPANCY
217 enum TraceRestrictSlotOccupancyCondAuxField {
218 TRSOCAF_OCCUPANTS = 0, ///< value field is the occupancy count of the slot
219 TRSOCAF_REMAINING = 1, ///< value field is the remaining occupancy of the slot
220 /* space up to 3 */
224 * TraceRestrictItem pathfinder penalty preset index
225 * This may not be shortened, only lengthened, as preset indexes are stored in save games
227 enum TraceRestrictPathfinderPenaltyPresetIndex {
228 TRPPPI_SMALL = 0, ///< small preset value
229 TRPPPI_MEDIUM = 1, ///< medium preset value
230 TRPPPI_LARGE = 2, ///< large preset value
231 TRPPPI_END, ///< end value
235 * Enumeration for TraceRestrictProgramResult::flags
237 enum TraceRestrictProgramResultFlags {
238 TRPRF_DENY = 1 << 0, ///< Pathfinder deny is set
239 TRPRF_RESERVE_THROUGH = 1 << 1, ///< Reserve through is set
240 TRPRF_LONG_RESERVE = 1 << 2, ///< Long reserve is set
241 TRPRF_WAIT_AT_PBS = 1 << 3, ///< Wait at PBS signal is set
243 DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags)
246 * Enumeration for TraceRestrictProgram::actions_used_flags
248 enum TraceRestrictProgramActionsUsedFlags {
249 TRPAUF_PF = 1 << 0, ///< Pathfinder deny or penalty are present
250 TRPAUF_RESERVE_THROUGH = 1 << 1, ///< Reserve through action is present
251 TRPAUF_LONG_RESERVE = 1 << 2, ///< Long reserve action is present
252 TRPAUF_WAIT_AT_PBS = 1 << 3, ///< Wait at PBS signal action is present
253 TRPAUF_SLOT_ACQUIRE = 1 << 4, ///< Slot acquire action is present
254 TRPAUF_SLOT_RELEASE_BACK = 1 << 5, ///< Slot release (back) action is present
255 TRPAUF_SLOT_RELEASE_FRONT = 1 << 6, ///< Slot release (front) action is present
257 DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags)
260 * Enumeration for TraceRestrictProgram::actions_used_flags
262 enum TraceRestrictProgramInputSlotPermissions {
263 TRPISP_ACQUIRE = 1 << 0, ///< Slot acquire is permitted
264 TRPISP_RELEASE_BACK = 1 << 1, ///< Slot release (back) is permitted
265 TRPISP_RELEASE_FRONT = 1 << 2, ///< Slot release (front) is permitted
267 DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputSlotPermissions)
270 * Execution input of a TraceRestrictProgram
272 struct TraceRestrictProgramInput {
273 typedef TileIndex PreviousSignalProc(const Train *v, const void *ptr);
275 TileIndex tile; ///< Tile of restrict signal, for direction testing
276 Trackdir trackdir; ///< Track direction on tile of restrict signal, for direction testing
277 PreviousSignalProc *previous_signal_callback; ///< Callback to retrieve tile and direction of previous signal, may be nullptr
278 const void *previous_signal_ptr; ///< Opaque pointer suitable to be passed to previous_signal_callback
279 TraceRestrictProgramInputSlotPermissions permitted_slot_operations; ///< Permitted slot operations
281 TraceRestrictProgramInput(TileIndex tile_, Trackdir trackdir_, PreviousSignalProc *previous_signal_callback_, const void *previous_signal_ptr_)
282 : tile(tile_), trackdir(trackdir_), previous_signal_callback(previous_signal_callback_), previous_signal_ptr(previous_signal_ptr_),
283 permitted_slot_operations(static_cast<TraceRestrictProgramInputSlotPermissions>(0)) { }
287 * Execution result of a TraceRestrictProgram
289 struct TraceRestrictProgramResult {
290 uint32 penalty; ///< Total additional pathfinder penalty
291 TraceRestrictProgramResultFlags flags; ///< Flags of other actions to take
293 TraceRestrictProgramResult()
294 : penalty(0), flags(static_cast<TraceRestrictProgramResultFlags>(0)) { }
298 * Program type, this stores the instruction list
299 * This is refcounted, see info at top of tracerestrict.cpp
301 struct TraceRestrictProgram : TraceRestrictProgramPool::PoolItem<&_tracerestrictprogram_pool> {
302 std::vector<TraceRestrictItem> items;
303 uint32 refcount;
304 TraceRestrictProgramActionsUsedFlags actions_used_flags;
306 TraceRestrictProgram()
307 : refcount(0), actions_used_flags(static_cast<TraceRestrictProgramActionsUsedFlags>(0)) { }
309 void Execute(const Train *v, const TraceRestrictProgramInput &input, TraceRestrictProgramResult &out) const;
312 * Increment ref count, only use when creating a mapping
314 void IncrementRefCount() { refcount++; }
316 void DecrementRefCount();
318 static CommandCost Validate(const std::vector<TraceRestrictItem> &items, TraceRestrictProgramActionsUsedFlags &actions_used_flags);
320 static size_t InstructionOffsetToArrayOffset(const std::vector<TraceRestrictItem> &items, size_t offset);
322 static size_t ArrayOffsetToInstructionOffset(const std::vector<TraceRestrictItem> &items, size_t offset);
324 /** Call InstructionOffsetToArrayOffset on current program instruction list */
325 size_t InstructionOffsetToArrayOffset(size_t offset) const
327 return TraceRestrictProgram::InstructionOffsetToArrayOffset(this->items, offset);
330 /** Call ArrayOffsetToInstructionOffset on current program instruction list */
331 size_t ArrayOffsetToInstructionOffset(size_t offset) const
333 return TraceRestrictProgram::ArrayOffsetToInstructionOffset(this->items, offset);
336 /** Get number of instructions in @p items */
337 static size_t GetInstructionCount(const std::vector<TraceRestrictItem> &items)
339 return ArrayOffsetToInstructionOffset(items, items.size());
342 /** Call GetInstructionCount on current program instruction list */
343 size_t GetInstructionCount() const
345 return TraceRestrictProgram::GetInstructionCount(this->items);
348 /** Get an iterator to the instruction at a given @p instruction_offset in @p items */
349 static std::vector<TraceRestrictItem>::iterator InstructionAt(std::vector<TraceRestrictItem> &items, size_t instruction_offset)
351 return items.begin() + TraceRestrictProgram::InstructionOffsetToArrayOffset(items, instruction_offset);
354 /** Get a const_iterator to the instruction at a given @p instruction_offset in @p items */
355 static std::vector<TraceRestrictItem>::const_iterator InstructionAt(const std::vector<TraceRestrictItem> &items, size_t instruction_offset)
357 return items.begin() + TraceRestrictProgram::InstructionOffsetToArrayOffset(items, instruction_offset);
360 /** Call validation function on current program instruction list and set actions_used_flags */
361 CommandCost Validate()
363 return TraceRestrictProgram::Validate(items, actions_used_flags);
367 /** Get TraceRestrictItem type field */
368 static inline TraceRestrictItemType GetTraceRestrictType(TraceRestrictItem item)
370 return static_cast<TraceRestrictItemType>(GB(item, TRIFA_TYPE_OFFSET, TRIFA_TYPE_COUNT));
373 /** Get TraceRestrictItem condition flags field */
374 static inline TraceRestrictCondFlags GetTraceRestrictCondFlags(TraceRestrictItem item)
376 return static_cast<TraceRestrictCondFlags>(GB(item, TRIFA_COND_FLAGS_OFFSET, TRIFA_COND_FLAGS_COUNT));
379 /** Get TraceRestrictItem condition operator field */
380 static inline TraceRestrictCondOp GetTraceRestrictCondOp(TraceRestrictItem item)
382 return static_cast<TraceRestrictCondOp>(GB(item, TRIFA_COND_OP_OFFSET, TRIFA_COND_OP_COUNT));
385 /** Get TraceRestrictItem auxiliary field */
386 static inline uint8 GetTraceRestrictAuxField(TraceRestrictItem item)
388 return GB(item, TRIFA_AUX_FIELD_OFFSET, TRIFA_AUX_FIELD_COUNT);
391 /** Get TraceRestrictItem value field */
392 static inline uint16 GetTraceRestrictValue(TraceRestrictItem item)
394 return static_cast<uint16>(GB(item, TRIFA_VALUE_OFFSET, TRIFA_VALUE_COUNT));
397 /** Set TraceRestrictItem type field */
398 static inline void SetTraceRestrictType(TraceRestrictItem &item, TraceRestrictItemType type)
400 SB(item, TRIFA_TYPE_OFFSET, TRIFA_TYPE_COUNT, type);
403 /** Set TraceRestrictItem condition operator field */
404 static inline void SetTraceRestrictCondOp(TraceRestrictItem &item, TraceRestrictCondOp condop)
406 SB(item, TRIFA_COND_OP_OFFSET, TRIFA_COND_OP_COUNT, condop);
409 /** Set TraceRestrictItem condition flags field */
410 static inline void SetTraceRestrictCondFlags(TraceRestrictItem &item, TraceRestrictCondFlags condflags)
412 SB(item, TRIFA_COND_FLAGS_OFFSET, TRIFA_COND_FLAGS_COUNT, condflags);
415 /** Set TraceRestrictItem auxiliary field */
416 static inline void SetTraceRestrictAuxField(TraceRestrictItem &item, uint8 data)
418 SB(item, TRIFA_AUX_FIELD_OFFSET, TRIFA_AUX_FIELD_COUNT, data);
421 /** Set TraceRestrictItem value field */
422 static inline void SetTraceRestrictValue(TraceRestrictItem &item, uint16 value)
424 SB(item, TRIFA_VALUE_OFFSET, TRIFA_VALUE_COUNT, value);
427 /** Is TraceRestrictItemType a conditional type? */
428 static inline bool IsTraceRestrictTypeConditional(TraceRestrictItemType type)
430 return type >= TRIT_COND_BEGIN;
433 /** Is TraceRestrictItem type field a conditional type? */
434 static inline bool IsTraceRestrictConditional(TraceRestrictItem item)
436 return IsTraceRestrictTypeConditional(GetTraceRestrictType(item));
439 /** Is TraceRestrictItem a double-item type? */
440 static inline bool IsTraceRestrictDoubleItem(TraceRestrictItem item)
442 const TraceRestrictItemType type = GetTraceRestrictType(item);
443 return type == TRIT_COND_PBS_ENTRY_SIGNAL || type == TRIT_COND_SLOT_OCCUPANCY;
447 * Categorisation of what is allowed in the TraceRestrictItem condition op field
448 * see TraceRestrictTypePropertySet
450 enum TraceRestrictConditionOpType {
451 TRCOT_NONE = 0, ///< takes no condition op
452 TRCOT_BINARY = 1, ///< takes "is" and "is not" condition ops
453 TRCOT_ALL = 2, ///< takes all condition ops (i.e. all relational ops)
457 * Categorisation of what is in the TraceRestrictItem value field
458 * see TraceRestrictTypePropertySet
460 enum TraceRestrictValueType {
461 TRVT_NONE = 0, ///< value field not used (set to 0)
462 TRVT_SPECIAL = 1, ///< special handling of value field
463 TRVT_INT = 2, ///< takes an unsigned integer value
464 TRVT_DENY = 3, ///< takes a value 0 = deny, 1 = allow (cancel previous deny)
465 TRVT_SPEED = 4, ///< takes an integer speed value
466 TRVT_ORDER = 5, ///< takes an order target ID, as per the auxiliary field as type: TraceRestrictOrderCondAuxField
467 TRVT_CARGO_ID = 6, ///< takes a CargoID
468 TRVT_DIRECTION = 7, ///< takes a TraceRestrictDirectionTypeSpecialValue
469 TRVT_TILE_INDEX = 8, ///< takes a TileIndex in the next item slot
470 TRVT_PF_PENALTY = 9, ///< takes a pathfinder penalty value or preset index, as per the auxiliary field as type: TraceRestrictPathfinderPenaltyAuxField
471 TRVT_RESERVE_THROUGH = 10, ///< takes a value 0 = reserve through, 1 = cancel previous reserve through
472 TRVT_LONG_RESERVE = 11, ///< takes a value 0 = long reserve, 1 = cancel previous long reserve
473 TRVT_GROUP_INDEX = 12, ///< takes a GroupID
474 TRVT_WAIT_AT_PBS = 13, ///< takes a value 0 = wait at PBS signal, 1 = cancel wait at PBS signal
475 TRVT_SLOT_INDEX = 14, ///< takes a TraceRestrictSlotID
476 TRVT_SLOT_INDEX_INT = 15, ///< takes a TraceRestrictSlotID, and an integer in the next item slot
480 * Describes formats of TraceRestrictItem condition op and value fields
482 struct TraceRestrictTypePropertySet {
483 TraceRestrictConditionOpType cond_type;
484 TraceRestrictValueType value_type;
487 void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueType value_type);
488 void SetTraceRestrictTypeAndNormalise(TraceRestrictItem &item, TraceRestrictItemType type, uint8 aux_data = 0);
491 * Get TraceRestrictTypePropertySet for a given instruction, only looks at value field
493 static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceRestrictItem item)
495 TraceRestrictTypePropertySet out;
497 if (GetTraceRestrictType(item) == TRIT_NULL) {
498 out.cond_type = TRCOT_NONE;
499 out.value_type = TRVT_SPECIAL;
500 } else if (GetTraceRestrictType(item) == TRIT_COND_ENDIF ||
501 GetTraceRestrictType(item) == TRIT_COND_UNDEFINED) {
502 out.cond_type = TRCOT_NONE;
503 out.value_type = TRVT_NONE;
504 } else if (IsTraceRestrictConditional(item)) {
505 out.cond_type = TRCOT_ALL;
507 switch (GetTraceRestrictType(item)) {
508 case TRIT_COND_TRAIN_LENGTH:
509 out.value_type = TRVT_INT;
510 break;
512 case TRIT_COND_MAX_SPEED:
513 out.value_type = TRVT_SPEED;
514 break;
516 case TRIT_COND_CURRENT_ORDER:
517 case TRIT_COND_NEXT_ORDER:
518 case TRIT_COND_LAST_STATION:
519 out.value_type = TRVT_ORDER;
520 out.cond_type = TRCOT_BINARY;
521 break;
523 case TRIT_COND_CARGO:
524 out.value_type = TRVT_CARGO_ID;
525 out.cond_type = TRCOT_BINARY;
526 break;
528 case TRIT_COND_ENTRY_DIRECTION:
529 out.value_type = TRVT_DIRECTION;
530 out.cond_type = TRCOT_BINARY;
531 break;
533 case TRIT_COND_PBS_ENTRY_SIGNAL:
534 out.value_type = TRVT_TILE_INDEX;
535 out.cond_type = TRCOT_BINARY;
536 break;
538 case TRIT_COND_TRAIN_GROUP:
539 out.value_type = TRVT_GROUP_INDEX;
540 out.cond_type = TRCOT_BINARY;
541 break;
543 case TRIT_COND_TRAIN_IN_SLOT:
544 out.value_type = TRVT_SLOT_INDEX;
545 out.cond_type = TRCOT_BINARY;
546 break;
548 case TRIT_COND_SLOT_OCCUPANCY:
549 out.value_type = TRVT_SLOT_INDEX_INT;
550 break;
552 default:
553 NOT_REACHED();
554 break;
556 } else {
557 out.cond_type = TRCOT_NONE;
558 if (GetTraceRestrictType(item) == TRIT_PF_PENALTY) {
559 out.value_type = TRVT_PF_PENALTY;
560 } else if (GetTraceRestrictType(item) == TRIT_PF_DENY) {
561 out.value_type = TRVT_DENY;
562 } else if (GetTraceRestrictType(item) == TRIT_RESERVE_THROUGH) {
563 out.value_type = TRVT_RESERVE_THROUGH;
564 } else if (GetTraceRestrictType(item) == TRIT_LONG_RESERVE) {
565 out.value_type = TRVT_LONG_RESERVE;
566 } else if (GetTraceRestrictType(item) == TRIT_WAIT_AT_PBS) {
567 out.value_type = TRVT_WAIT_AT_PBS;
568 } else if (GetTraceRestrictType(item) == TRIT_SLOT) {
569 out.value_type = TRVT_SLOT_INDEX;
570 } else {
571 out.value_type = TRVT_NONE;
575 return out;
578 /** Is the aux field for this TraceRestrictItemType used as a subtype which changes the type of the value field? */
579 static inline bool IsTraceRestrictTypeAuxSubtype(TraceRestrictItemType type)
581 switch (type) {
582 case TRIT_COND_SLOT_OCCUPANCY:
583 return true;
585 default:
586 return false;
590 /** Get mapping ref ID from tile and track */
591 static inline TraceRestrictRefId MakeTraceRestrictRefId(TileIndex t, Track track)
593 return (t << 3) | track;
596 /** Get tile from mapping ref ID */
597 static inline TileIndex GetTraceRestrictRefIdTileIndex(TraceRestrictRefId ref)
599 return static_cast<TileIndex>(ref >> 3);
602 /** Get track from mapping ref ID */
603 static inline Track GetTraceRestrictRefIdTrack(TraceRestrictRefId ref)
605 return static_cast<Track>(ref & 7);
608 void TraceRestrictCreateProgramMapping(TraceRestrictRefId ref, TraceRestrictProgram *prog);
609 bool TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref);
611 TraceRestrictProgram *GetTraceRestrictProgram(TraceRestrictRefId ref, bool create_new);
613 void TraceRestrictNotifySignalRemoval(TileIndex tile, Track track);
616 * Gets the existing signal program for the tile identified by @p t and @p track, or nullptr
618 static inline const TraceRestrictProgram *GetExistingTraceRestrictProgram(TileIndex t, Track track)
620 if (IsRestrictedSignal(t)) {
621 return GetTraceRestrictProgram(MakeTraceRestrictRefId(t, track), false);
622 } else {
623 return nullptr;
628 * Enumeration for command action type field, indicates what command to do
630 enum TraceRestrictDoCommandType {
631 TRDCT_INSERT_ITEM, ///< insert new instruction before offset field as given value
632 TRDCT_MODIFY_ITEM, ///< modify instruction at offset field to given value
633 TRDCT_MODIFY_DUAL_ITEM, ///< modify second item of dual-part instruction at offset field to given value
634 TRDCT_REMOVE_ITEM, ///< remove instruction at offset field
635 TRDCT_SHALLOW_REMOVE_ITEM, ///< shallow remove instruction at offset field, does not delete contents of block
636 TRDCT_MOVE_ITEM, ///< move instruction or block at offset field
638 TRDCT_PROG_COPY, ///< copy program operation. Do not re-order this with respect to other values
639 TRDCT_PROG_COPY_APPEND, ///< copy and append program operation
640 TRDCT_PROG_SHARE, ///< share program operation
641 TRDCT_PROG_UNSHARE, ///< unshare program (copy as a new program)
642 TRDCT_PROG_RESET, ///< reset program state of signal
645 void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, uint32 offset, uint32 value, StringID error_msg);
647 void TraceRestrictProgMgmtWithSourceDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type,
648 TileIndex source_tile, Track source_track, StringID error_msg);
651 * Short-hand to call TraceRestrictProgMgmtWithSourceDoCommandP with 0 for source tile/track
653 inline void TraceRestrictProgMgmtDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, StringID error_msg)
655 TraceRestrictProgMgmtWithSourceDoCommandP(tile, track, type, static_cast<TileIndex>(0), static_cast<Track>(0), error_msg);
658 CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
659 CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
661 CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &items, uint32 offset, bool shallow_mode);
662 CommandCost TraceRestrictProgramMoveItemAt(std::vector<TraceRestrictItem> &items, uint32 &offset, bool up, bool shallow_mode);
664 void ShowTraceRestrictProgramWindow(TileIndex tile, Track track);
666 void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint16 index);
667 void TraceRestrictRemoveGroupID(GroupID index);
668 void TraceRestrictRemoveSlotID(TraceRestrictSlotID index);
670 void TraceRestrictRemoveVehicleFromAllSlots(VehicleID id);
671 void TraceRestrictTransferVehicleOccupantInAllSlots(VehicleID from, VehicleID to);
672 void TraceRestrictGetVehicleSlots(VehicleID id, std::vector<TraceRestrictSlotID> &out);
674 static const uint MAX_LENGTH_TRACE_RESTRICT_SLOT_NAME_CHARS = 128; ///< The maximum length of a slot name in characters including '\0'
677 * Slot type, used for slot operations
679 struct TraceRestrictSlot : TraceRestrictSlotPool::PoolItem<&_tracerestrictslot_pool> {
680 std::vector<VehicleID> occupants;
681 uint32 max_occupancy = 1;
682 std::string name;
683 OwnerByte owner;
685 static void RebuildVehicleIndex();
686 static void PreCleanPool();
688 TraceRestrictSlot(CompanyID owner = INVALID_COMPANY)
690 this->owner = owner;
693 ~TraceRestrictSlot()
695 if (!CleaningPool()) this->Clear();
698 /** Test whether vehicle ID is already an occupant */
699 bool IsOccupant(VehicleID id) const {
700 for (size_t i = 0; i < occupants.size(); i++) {
701 if (occupants[i] == id) return true;
703 return false;
706 bool Occupy(VehicleID id, bool force = false);
707 void Vacate(VehicleID id);
708 void Clear();
710 private:
711 void DeIndex(VehicleID id);
715 #define FOR_ALL_TRACE_RESTRICT_SLOTS_FROM(var, start) FOR_ALL_ITEMS_FROM(TraceRestrictSlot, slot_index, var, start)
716 #define FOR_ALL_TRACE_RESTRICT_SLOTS(var) FOR_ALL_TRACE_RESTRICT_SLOTS_FROM(var, 0)
718 #endif /* TRACERESTRICT_H */