diff --git a/src/rail_map.h b/src/rail_map.h index a42c84f784..e6f4d7e406 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -479,16 +479,24 @@ static inline bool HasOnewaySignalBlockingTrackdir(TileIndex tile, Trackdir td) !HasSignalOnTrackdir(tile, td) && IsOnewaySignal(tile, TrackdirToTrack(td)); } -static inline bool IsRestrictedSignal(TileIndex t) +/** + * Does signal tile have "one or more trace restrict mappings present" bit set + * @param tile the tile to check + */ +static inline bool IsRestrictedSignal(TileIndex tile) { - assert(GetRailTileType(t) == RAIL_TILE_SIGNALS); - return (bool) GB(_m[t].m2, 12, 1); + assert(GetRailTileType(tile) == RAIL_TILE_SIGNALS); + return (bool) GB(_m[tile].m2, 12, 1); } -static inline void SetRestrictedSignal(TileIndex t, bool is_restricted) +/** + * Set signal tile "one or more trace restrict mappings present" bit + * @param tile the tile to set + */ +static inline void SetRestrictedSignal(TileIndex tile, bool is_restricted) { - assert(GetRailTileType(t) == RAIL_TILE_SIGNALS); - SB(_m[t].m2, 12, 1, is_restricted); + assert(GetRailTileType(tile) == RAIL_TILE_SIGNALS); + SB(_m[tile].m2, 12, 1, is_restricted); } diff --git a/src/saveload/tracerestrict_sl.cpp b/src/saveload/tracerestrict_sl.cpp index a646c3a72a..93d43cf3ea 100644 --- a/src/saveload/tracerestrict_sl.cpp +++ b/src/saveload/tracerestrict_sl.cpp @@ -20,6 +20,9 @@ static const SaveLoad _trace_restrict_mapping_desc[] = { SLE_END() }; +/** + * Load mappings + */ static void Load_TRRM() { int index; @@ -29,6 +32,9 @@ static void Load_TRRM() } } +/** + * Save mappings + */ static void Save_TRRM() { for (TraceRestrictMapping::iterator iter = _tracerestrictprogram_mapping.begin(); @@ -38,6 +44,7 @@ static void Save_TRRM() } } +/** program length save header struct */ struct TraceRestrictProgramStub { uint32 length; }; @@ -47,6 +54,9 @@ static const SaveLoad _trace_restrict_program_stub_desc[] = { SLE_END() }; +/** + * Load program pool + */ static void Load_TRRP() { int index; @@ -60,6 +70,9 @@ static void Load_TRRP() } } +/** + * Save a program, used by SlAutolength + */ static void RealSave_TRRP(TraceRestrictProgram *prog) { TraceRestrictProgramStub stub; @@ -68,6 +81,9 @@ static void RealSave_TRRP(TraceRestrictProgram *prog) SlArray(&(prog->items[0]), stub.length, SLE_UINT32); } +/** + * Save program pool + */ static void Save_TRRP() { TraceRestrictProgram *prog; @@ -78,6 +94,9 @@ static void Save_TRRP() } } +/** + * Update program reference counts from just-loaded mapping + */ void AfterLoadTraceRestrict() { for (TraceRestrictMapping::iterator iter = _tracerestrictprogram_mapping.begin(); @@ -87,6 +106,6 @@ void AfterLoadTraceRestrict() } extern const ChunkHandler _trace_restrict_chunk_handlers[] = { - { 'TRRM', Save_TRRM, Load_TRRM, NULL, NULL, CH_SPARSE_ARRAY}, - { 'TRRP', Save_TRRP, Load_TRRP, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'TRRM', Save_TRRM, Load_TRRM, NULL, NULL, CH_SPARSE_ARRAY}, // Trace Restrict Mapping chunk + { 'TRRP', Save_TRRP, Load_TRRP, NULL, NULL, CH_ARRAY | CH_LAST}, // Trace Restrict Mapping Program Pool chunk }; diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 6bd9c8e7c5..ccfee30c39 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -5,7 +5,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 . */ -/** @file tracerestrict.h Header file for Trace Restriction. */ +/** @file tracerestrict.cpp Main file for Trace Restrict */ #include "stdafx.h" #include "tracerestrict.h" @@ -21,7 +21,9 @@ #include "pathfinder/yapf/yapf_cache.h" #include -/** Trace Restrict Data Storage Model Notes: +/** @file + * + * Trace Restrict Data Storage Model Notes: * * Signals may have 0, 1 or 2 trace restrict programs attached to them, * up to one for each track. Two-way signals share the same program. @@ -54,7 +56,6 @@ * to be gained by doing so. */ -/** Initialize the program pool */ TraceRestrictProgramPool _tracerestrictprogram_pool("TraceRestrictProgram"); INSTANTIATE_POOL_METHODS(TraceRestrictProgram) @@ -65,12 +66,20 @@ INSTANTIATE_POOL_METHODS(TraceRestrictProgram) */ TraceRestrictMapping _tracerestrictprogram_mapping; -/// This should be used when all pools have been or are immediately about to be also cleared -/// Calling this at other times will leave dangling refcounts +/** + * This should be used when all pools have been or are immediately about to be also cleared + * Calling this at other times will leave dangling refcounts + */ void ClearTraceRestrictMapping() { _tracerestrictprogram_mapping.clear(); } +/** + * Flags used for the program execution condition stack + * Each 'if' pushes onto the stack + * Each 'end if' pops from the stack + * Elif/orif/else may modify the stack top + */ enum TraceRestrictCondStackFlags { TRCSF_DONE_IF = 1<<0, ///< The if/elif/else is "done", future elif/else branches will not be executed TRCSF_SEEN_ELSE = 1<<1, ///< An else branch has been seen already, error if another is seen afterwards @@ -79,6 +88,9 @@ enum TraceRestrictCondStackFlags { }; DECLARE_ENUM_AS_BIT_SET(TraceRestrictCondStackFlags) +/** + * Helper function to handle condition stack manipulatoin + */ static void HandleCondition(std::vector &condstack, TraceRestrictCondFlags condflags, bool value) { if (condflags & TRCF_OR) { @@ -111,7 +123,10 @@ static void HandleCondition(std::vector &condstack, } } -/// Test value op condvalue +/** + * Integer condition testing + * Test value op condvalue + */ static bool TestCondition(uint16 value, TraceRestrictCondOp condop, uint16 condvalue) { switch (condop) { @@ -133,6 +148,9 @@ static bool TestCondition(uint16 value, TraceRestrictCondOp condop, uint16 condv } } +/** + * Binary condition testing helper function + */ static bool TestBinaryConditionCommon(TraceRestrictItem item, bool input) { switch (GetTraceRestrictCondOp(item)) { @@ -148,8 +166,10 @@ static bool TestBinaryConditionCommon(TraceRestrictItem item, bool input) } } -/// Test order condition -/// order may be NULL +/** + * Test order condition + * @p order may be NULL + */ static bool TestOrderCondition(const Order *order, TraceRestrictItem item) { bool result = false; @@ -176,7 +196,9 @@ static bool TestOrderCondition(const Order *order, TraceRestrictItem item) return TestBinaryConditionCommon(item, result); } -/// Test station condition +/** + * Test station condition + */ static bool TestStationCondition(StationID station, TraceRestrictItem item) { bool result = (GetTraceRestrictAuxField(item) == TROCAF_STATION) && (station == GetTraceRestrictValue(item)); @@ -184,7 +206,11 @@ static bool TestStationCondition(StationID station, TraceRestrictItem item) } -/// Execute program on train and store results in out +/** + * Execute program on train and store results in out + * @p v may not be NULL + * @p out should be zero-initialised + */ void TraceRestrictProgram::Execute(const Train* v, TraceRestrictProgramResult& out) const { // static to avoid needing to re-alloc/resize on each execution @@ -288,6 +314,9 @@ void TraceRestrictProgram::Execute(const Train* v, TraceRestrictProgramResult& o assert(condstack.empty()); } +/** + * Decrement ref count, only use when removing a mapping + */ void TraceRestrictProgram::DecrementRefCount() { assert(this->refcount > 0); this->refcount--; @@ -296,10 +325,13 @@ void TraceRestrictProgram::DecrementRefCount() { } } -/// returns successful result if program seems OK -/// This only validates that conditional nesting is correct, at present +/** + * Validate a instruction list + * Returns successful result if program seems OK + * This only validates that conditional nesting is correct, at present + */ CommandCost TraceRestrictProgram::Validate(const std::vector &items) { - // static to avoid needing to re-alloc/resize on each execution + // static to avoid needing to re-alloc/resize on each execution static std::vector condstack; condstack.clear(); @@ -345,6 +377,9 @@ CommandCost TraceRestrictProgram::Validate(const std::vector return CommandCost(); } +/** + * Set the value and aux field of @p item, as per the value type in @p value_type + */ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueType value_type) { switch (value_type) { @@ -373,9 +408,9 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp } } -/// Set the type field of a TraceRestrictItem, and -/// reset any other fields which are no longer valid/meaningful -/// to sensible defaults +/** + * Set the type field of a TraceRestrictItem, and resets any other fields which are no longer valid/meaningful to sensible defaults + */ void SetTraceRestrictTypeAndNormalise(TraceRestrictItem &item, TraceRestrictItemType type) { if (item != 0) { @@ -395,6 +430,10 @@ void SetTraceRestrictTypeAndNormalise(TraceRestrictItem &item, TraceRestrictItem } } +/** + * Sets the "signal has a trace restrict mapping" bit + * This looks for mappings with that tile index + */ void SetIsSignalRestrictedBit(TileIndex t) { // First mapping for this tile, or later @@ -407,6 +446,10 @@ void SetIsSignalRestrictedBit(TileIndex t) SetRestrictedSignal(t, lower_bound != upper_bound); } +/** + * Create a new program mapping to an existing program + * If a mapping already exists, it is removed + */ void TraceRestrictCreateProgramMapping(TraceRestrictRefId ref, TraceRestrictProgram *prog) { std::pair insert_result = @@ -427,6 +470,9 @@ void TraceRestrictCreateProgramMapping(TraceRestrictRefId ref, TraceRestrictProg YapfNotifyTrackLayoutChange(tile, track); } +/** + * Remove a program mapping + */ void TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref) { TraceRestrictMapping::iterator iter = _tracerestrictprogram_mapping.find(ref); @@ -443,9 +489,10 @@ void TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref) } } -/// Gets the trace restrict program for the tile/track ref ID identified by @p ref. -/// An empty program will be constructed if none exists, and @p create_new is true -/// unless the pool is full +/** + * Gets the signal program for the tile ref @p ref + * An empty program will be constructed if none exists, and @p create_new is true, unless the pool is full + */ TraceRestrictProgram *GetTraceRestrictProgram(TraceRestrictRefId ref, bool create_new) { // Optimise for lookup, creating doesn't have to be that fast @@ -471,8 +518,10 @@ TraceRestrictProgram *GetTraceRestrictProgram(TraceRestrictRefId ref, bool creat } } -/// Notify that a signal is being removed -/// Remove any trace restrict items associated with it +/** + * Notify that a signal is being removed + * Remove any trace restrict mappings associated with it + */ void TraceRestrictNotifySignalRemoval(TileIndex tile, Track track) { TraceRestrictRefId ref = MakeTraceRestrictRefId(tile, track); @@ -480,6 +529,9 @@ void TraceRestrictNotifySignalRemoval(TileIndex tile, Track track) DeleteWindowById(WC_TRACE_RESTRICT, ref); } +/** + * Helper function to perform parameter bit-packing and call DoCommandP, for instruction modification actions + */ void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, uint32 offset, uint32 value, StringID error_msg) { uint32 p1 = 0; @@ -490,6 +542,9 @@ void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommand DoCommandP(tile, p1, value, CMD_PROGRAM_TRACERESTRICT_SIGNAL | CMD_MSG(error_msg)); } +/** + * Check whether a tile/tracl pair contains a usable signal + */ static CommandCost TraceRestrictCheckTileIsUsable(TileIndex tile, Track track) { // Check that there actually is a signal here @@ -662,6 +717,9 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u return CommandCost(); } +/** + * Helper function to perform parameter bit-packing and call DoCommandP, for program management actions + */ void TraceRestrictProgMgmtWithSourceDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, TileIndex source_tile, Track source_track, StringID error_msg) { @@ -779,6 +837,10 @@ CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag return CommandCost(); } +/** + * This is called when a station, waypoint or depot is about to be deleted + * Scan program pool and change any references to it to the invalid station ID, to avoid dangling references + */ void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint16 index) { TraceRestrictProgram *prog; diff --git a/src/tracerestrict.h b/src/tracerestrict.h index 424daa9fc8..91148facc7 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -5,7 +5,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 . */ -/** @file tracerestrict.h Header file for Trace Restriction. */ +/** @file tracerestrict.h Header file for Trace Restrict */ #ifndef TRACERESTRICT_H #define TRACERESTRICT_H @@ -22,10 +22,11 @@ struct Train; -/** Unique identifiers for a trace restrict nodes. */ +/** Program pool ID type. */ typedef uint32 TraceRestrictProgramID; struct TraceRestrictProgram; +/** Tile/track mapping type. */ typedef uint32 TraceRestrictRefId; /** Type of the pool for trace restrict programs. */ @@ -36,6 +37,7 @@ extern TraceRestrictProgramPool _tracerestrictprogram_pool; #define FOR_ALL_TRACE_RESTRICT_PROGRAMS_FROM(var, start) FOR_ALL_ITEMS_FROM(TraceRestrictProgram, tr_index, var, start) #define FOR_ALL_TRACE_RESTRICT_PROGRAMS(var) FOR_ALL_TRACE_RESTRICT_PROGRAMS_FROM(var, 0) +/** Type used for the TraceRestrictRefId -> TraceRestrictProgramID mapping */ struct TraceRestrictMappingItem { TraceRestrictProgramID program_id; @@ -46,13 +48,24 @@ struct TraceRestrictMappingItem { }; typedef std::map TraceRestrictMapping; + +/** The actual mapping from TraceRestrictRefId to TraceRestrictProgramID. */ extern TraceRestrictMapping _tracerestrictprogram_mapping; void ClearTraceRestrictMapping(); -/// Of the fields below, the type and cond flags seem the most likely -/// to need future expansion, hence the reserved bits are placed -/// immediately after them +/** Type of a single instruction, this is bit-packed as per TraceRestrictItemFlagAllocation */ +typedef uint32 TraceRestrictItem; + +/** + * Describes the allocation of bits to fields in TraceRestrictItem + * Of the fields below, the type seem the most likely + * to need future expansion, hence the reserved bits are placed + * immediately after them + * + * COUNT values describe the field bit width + * OFFSET values describe the field bit offset + */ enum TraceRestrictItemFlagAllocation { TRIFA_TYPE_COUNT = 5, TRIFA_TYPE_OFFSET = 0, @@ -72,12 +85,18 @@ enum TraceRestrictItemFlagAllocation { TRIFA_VALUE_OFFSET = 16, }; +/** + * Enumeration of TraceRestrictItem type field + * This is split into two halves: + * * non-conditionals < TRIT_COND_BEGIN + * * conditionals, >= TRIT_COND_BEGIN + */ enum TraceRestrictItemType { - TRIT_NULL = 0, - TRIT_PF_DENY = 1, - TRIT_PF_PENALTY = 2, + TRIT_NULL = 0, ///< Null-type, not in programs and not valid for execution, mainly used with TraceRestrictNullTypeSpecialValue for start/end + TRIT_PF_DENY = 1, ///< Pathfinder deny/allow + TRIT_PF_PENALTY = 2, ///< Add to pathfinder penalty - TRIT_COND_BEGIN = 8, ///< Start of conditional item types + TRIT_COND_BEGIN = 8, ///< Start of conditional item types, note that this has the save value as TRIT_COND_ENDIF TRIT_COND_ENDIF = 8, ///< This is an endif block or an else block TRIT_COND_UNDEFINED = 9, ///< This condition has no type defined (evaluate as false) TRIT_COND_TRAIN_LENGTH = 10, ///< Test train length @@ -89,53 +108,72 @@ enum TraceRestrictItemType { /* space up to 31 */ }; -/* no flags set indicates end if for TRIT_COND_ENDIF, if otherwise */ +/** + * TraceRestrictItem condition flags field, only valid with conditional types (IsTraceRestrictTypeConditional() is true) + */ enum TraceRestrictCondFlags { - TRCF_DEFAULT = 0, - TRCF_ELSE = 1 << 0, - TRCF_OR = 1 << 1, + TRCF_DEFAULT = 0, ///< indicates end if for type: TRIT_COND_ENDIF, if otherwise + TRCF_ELSE = 1 << 0, ///< indicates an else block for type: TRIT_COND_ENDIF, elif otherwise + TRCF_OR = 1 << 1, ///< indicates an orif block, not valid with type: TRIT_COND_ENDIF /* 1 bit spare */ }; DECLARE_ENUM_AS_BIT_SET(TraceRestrictCondFlags) -enum TraceRestictNullTypeSpecialValue { - TRNTSV_NULL = 0, - TRNTSV_START = 1, - TRNTSV_END = 2, +/** + * Enumeration of TraceRestrictItemvalue type field when type is TRIT_NULL + */ +enum TraceRestrictNullTypeSpecialValue { + TRNTSV_NULL = 0, ///< null, what you get when you zero-init a TraceRestrictItemvalue + TRNTSV_START = 1, ///< start tag, generated within GUI + TRNTSV_END = 2, ///< end tag, generated within GUI }; +/** + * TraceRestrictItem condition operator field, only valid with conditional types (IsTraceRestrictTypeConditional() is true) + */ enum TraceRestrictCondOp { - TRCO_IS = 0, - TRCO_ISNOT = 1, - TRCO_LT = 2, - TRCO_LTE = 3, - TRCO_GT = 4, - TRCO_GTE = 5, + TRCO_IS = 0, ///< equality test, or can carry test for cargo + TRCO_ISNOT = 1, ///< inequality test, or can't carry test for cargo + TRCO_LT = 2, ///< less than test + TRCO_LTE = 3, ///< less than or equal test + TRCO_GT = 4, ///< greater than test + TRCO_GTE = 5, ///< greater than or equal test /* space up to 7 */ }; +/** + * TraceRestrictItem auxiliary type field, for order type conditionals + */ enum TraceRestrictOrderCondAuxField { - TROCAF_STATION = 0, - TROCAF_WAYPOINT = 1, - TROCAF_DEPOT = 2, - /* space up to 7 */ + TROCAF_STATION = 0, ///< value field is a station StationID + TROCAF_WAYPOINT = 1, ///< value field is a waypoint StationID + TROCAF_DEPOT = 2, ///< value field is a depot DepotID + /* space up to 3 */ }; +/** + * Enumeration for TraceRestrictProgramResult::flags + */ enum TraceRestrictProgramResultFlags { - TRPRF_DENY = 1 << 0, + TRPRF_DENY = 1 << 0, ///< Pathfinder deny is set }; DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags) +/** + * Execution result of a TraceRestrictProgram + */ struct TraceRestrictProgramResult { - uint32 penalty; - TraceRestrictProgramResultFlags flags; + uint32 penalty; ///< Total additional pathfinder penalty + TraceRestrictProgramResultFlags flags; ///< Flags of other actions to take TraceRestrictProgramResult() : penalty(0), flags(static_cast(0)) { } }; -typedef uint32 TraceRestrictItem; - +/** + * Program type, this stores the instruction list + * This is refcounted, see info at top of tracerestrict.cpp + */ struct TraceRestrictProgram : TraceRestrictProgramPool::PoolItem<&_tracerestrictprogram_pool> { std::vector items; uint32 refcount; @@ -145,99 +183,131 @@ struct TraceRestrictProgram : TraceRestrictProgramPool::PoolItem<&_tracerestrict void Execute(const Train *v, TraceRestrictProgramResult &out) const; + /** + * Increment ref count, only use when creating a mapping + */ void IncrementRefCount() { refcount++; } void DecrementRefCount(); static CommandCost Validate(const std::vector &items); + /** + * Call validation function on current program instruction list + */ CommandCost Validate() const { return TraceRestrictProgram::Validate(items); } }; +/** Get TraceRestrictItem type field */ static inline TraceRestrictItemType GetTraceRestrictType(TraceRestrictItem item) { return static_cast(GB(item, TRIFA_TYPE_OFFSET, TRIFA_TYPE_COUNT)); } +/** Get TraceRestrictItem condition flags field */ static inline TraceRestrictCondFlags GetTraceRestrictCondFlags(TraceRestrictItem item) { return static_cast(GB(item, TRIFA_COND_FLAGS_OFFSET, TRIFA_COND_FLAGS_COUNT)); } +/** Get TraceRestrictItem condition operator field */ static inline TraceRestrictCondOp GetTraceRestrictCondOp(TraceRestrictItem item) { return static_cast(GB(item, TRIFA_COND_OP_OFFSET, TRIFA_COND_OP_COUNT)); } +/** Get TraceRestrictItem auxiliary field */ static inline uint8 GetTraceRestrictAuxField(TraceRestrictItem item) { return GB(item, TRIFA_AUX_FIELD_OFFSET, TRIFA_AUX_FIELD_COUNT); } +/** Get TraceRestrictItem value field */ static inline uint16 GetTraceRestrictValue(TraceRestrictItem item) { return static_cast(GB(item, TRIFA_VALUE_OFFSET, TRIFA_VALUE_COUNT)); } +/** Set TraceRestrictItem type field */ static inline void SetTraceRestrictType(TraceRestrictItem &item, TraceRestrictItemType type) { SB(item, TRIFA_TYPE_OFFSET, TRIFA_TYPE_COUNT, type); } +/** Set TraceRestrictItem condition operator field */ static inline void SetTraceRestrictCondOp(TraceRestrictItem &item, TraceRestrictCondOp condop) { SB(item, TRIFA_COND_OP_OFFSET, TRIFA_COND_OP_COUNT, condop); } +/** Set TraceRestrictItem condition flags field */ static inline void SetTraceRestrictCondFlags(TraceRestrictItem &item, TraceRestrictCondFlags condflags) { SB(item, TRIFA_COND_FLAGS_OFFSET, TRIFA_COND_FLAGS_COUNT, condflags); } +/** Set TraceRestrictItem auxiliary field */ static inline void SetTraceRestrictAuxField(TraceRestrictItem &item, uint8 data) { SB(item, TRIFA_AUX_FIELD_OFFSET, TRIFA_AUX_FIELD_COUNT, data); } +/** Set TraceRestrictItem value field */ static inline void SetTraceRestrictValue(TraceRestrictItem &item, uint16 value) { SB(item, TRIFA_VALUE_OFFSET, TRIFA_VALUE_COUNT, value); } +/** Is TraceRestrictItemType a conditional type? */ static inline bool IsTraceRestrictTypeConditional(TraceRestrictItemType type) { return type >= TRIT_COND_BEGIN; } +/** Is TraceRestrictItem type field a conditional type? */ static inline bool IsTraceRestrictConditional(TraceRestrictItem item) { return IsTraceRestrictTypeConditional(GetTraceRestrictType(item)); } +/** + * Categorisation of what is allowed in the TraceRestrictItem condition op field + * see TraceRestrictTypePropertySet + */ enum TraceRestrictConditionOpType { TRCOT_NONE = 0, ///< takes no condition op TRCOT_BINARY = 1, ///< takes "is" and "is not" condition ops TRCOT_ALL = 2, ///< takes all condition ops (i.e. all relational ops) }; +/** + * Categorisation of what is in the TraceRestrictItem value field + * see TraceRestrictTypePropertySet + */ enum TraceRestrictValueType { TRVT_NONE = 0, ///< value field not used (set to 0) TRVT_SPECIAL = 1, ///< special handling of value field - TRVT_INT = 2, ///< takes an integer value + TRVT_INT = 2, ///< takes an unsigned integer value TRVT_DENY = 3, ///< takes a value 0 = deny, 1 = allow (cancel previous deny) TRVT_SPEED = 4, ///< takes an integer speed value TRVT_ORDER = 5, ///< takes an order target ID, as per the auxiliary field as type: TraceRestrictOrderCondAuxField TRVT_CARGO_ID = 6, ///< takes a CargoID }; -void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueType value_type); -void SetTraceRestrictTypeAndNormalise(TraceRestrictItem &item, TraceRestrictItemType type); - +/** + * Describes formats of TraceRestrictItem condition op and value fields + */ struct TraceRestrictTypePropertySet { TraceRestrictConditionOpType cond_type; TraceRestrictValueType value_type; }; +void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueType value_type); +void SetTraceRestrictTypeAndNormalise(TraceRestrictItem &item, TraceRestrictItemType type); + +/** + * Get TraceRestrictTypePropertySet for a given instruction, only looks at value field + */ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceRestrictItem item) { TraceRestrictTypePropertySet out; @@ -291,16 +361,19 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR return out; } +/** Get mapping ref ID from tile and track */ static inline TraceRestrictRefId MakeTraceRestrictRefId(TileIndex t, Track track) { return (t << 3) | track; } +/** Get tile from mapping ref ID */ static inline TileIndex GetTraceRestrictRefIdTileIndex(TraceRestrictRefId ref) { return static_cast(ref >> 3); } +/** Get track from mapping ref ID */ static inline Track GetTraceRestrictRefIdTrack(TraceRestrictRefId ref) { return static_cast(ref & 7); @@ -309,16 +382,13 @@ static inline Track GetTraceRestrictRefIdTrack(TraceRestrictRefId ref) void TraceRestrictCreateProgramMapping(TraceRestrictRefId ref, TraceRestrictProgram *prog); void TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref); -/// Gets the signal program for the tile identified by @p t and @p track. -/// An empty program will be constructed if none exists, and create_new is true -/// unless the pool is full TraceRestrictProgram *GetTraceRestrictProgram(TraceRestrictRefId ref, bool create_new); -/// Notify that a signal is being removed -/// Remove any trace restrict items associated with it void TraceRestrictNotifySignalRemoval(TileIndex tile, Track track); -/// Gets the signal program for the tile identified by @p t and @p track, or NULL +/** + * Gets the existing signal program for the tile identified by @p t and @p track, or NULL + */ static inline const TraceRestrictProgram *GetExistingTraceRestrictProgram(TileIndex t, Track track) { if (IsRestrictedSignal(t)) { @@ -328,16 +398,18 @@ static inline const TraceRestrictProgram *GetExistingTraceRestrictProgram(TileIn } } -// do not re-order +/** + * Enumeration for command action type field, indicates what command to do + */ enum TraceRestrictDoCommandType { - TRDCT_INSERT_ITEM = 0, - TRDCT_MODIFY_ITEM = 1, - TRDCT_REMOVE_ITEM = 2, + TRDCT_INSERT_ITEM = 0, ///< insert new instruction before offset field as given value + TRDCT_MODIFY_ITEM = 1, ///< modify instruction at offset field to given value + TRDCT_REMOVE_ITEM = 2, ///< remove instruction at offset field - TRDCT_PROG_COPY = 3, - TRDCT_PROG_SHARE = 4, - TRDCT_PROG_UNSHARE = 5, - TRDCT_PROG_RESET = 6, + TRDCT_PROG_COPY = 3, ///< copy program operation. Do not re-order this with respect to other values + TRDCT_PROG_SHARE = 4, ///< share program operation + TRDCT_PROG_UNSHARE = 5, ///< unshare program (copy as a new program) + TRDCT_PROG_RESET = 6, ///< reset program state of signal }; void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, uint32 offset, uint32 value, StringID error_msg); @@ -345,6 +417,9 @@ void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommand void TraceRestrictProgMgmtWithSourceDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, TileIndex source_tile, Track source_track, StringID error_msg); +/** + * Short-hand to call TraceRestrictProgMgmtWithSourceDoCommandP with 0 for source tile/track + */ inline void TraceRestrictProgMgmtDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, StringID error_msg) { TraceRestrictProgMgmtWithSourceDoCommandP(tile, track, type, static_cast(0), static_cast(0), error_msg); diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index 940aefabd6..1255b28a1d 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -7,7 +7,10 @@ * 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 . */ -/** @file tracerestrict_gui.cpp GUI related to signal tracerestrict */ +/** @file tracerestrict_gui.cpp GUI code for Trace Restrict + * + * This is largely based on the programmable signals patch's GUI + * */ #include "stdafx.h" #include "tracerestrict.h" @@ -35,6 +38,7 @@ extern uint ConvertSpeedToDisplaySpeed(uint speed); extern uint ConvertDisplaySpeedToSpeed(uint speed); +/** Widget IDs */ enum TraceRestrictWindowWidgets { TR_WIDGET_CAPTION, TR_WIDGET_INSTRUCTION_LIST, @@ -68,6 +72,7 @@ enum TraceRestrictWindowWidgets { TR_WIDGET_UNSHARE, }; +/** Selection mappings for NWID_SELECTION selectors */ enum PanelWidgets { // Left 2 DPL2_TYPE = 0, @@ -93,9 +98,13 @@ enum PanelWidgets { DPS_UNSHARE, }; -/// value_array *must* be at least as long as string_array, -/// where the length of string_array is defined as the offset -/// of the first INVALID_STRING_ID +/** + * drop down list string array, and corresponding integer values + * + * value_array *must* be at least as long as string_array, + * where the length of string_array is defined as the offset + * of the first INVALID_STRING_ID + */ struct TraceRestrictDropDownListSet { const StringID *string_array; const uint *value_array; @@ -109,17 +118,18 @@ static const StringID _program_insert_str[] = { STR_TRACE_RESTRICT_PF_PENALTY, INVALID_STRING_ID }; -static const uint _program_insert_else_flag = 0x100; -static const uint32 _program_insert_else_hide_mask = 4; -static const uint32 _program_insert_else_if_hide_mask = 2; +static const uint _program_insert_else_flag = 0x100; ///< flag to indicate that TRCF_ELSE should be set +static const uint32 _program_insert_else_hide_mask = 4; ///< disable bitmask for else +static const uint32 _program_insert_else_if_hide_mask = 2; ///< disable bitmask for elif static const uint _program_insert_val[] = { - TRIT_COND_UNDEFINED, /// if block - TRIT_COND_UNDEFINED | _program_insert_else_flag, /// elif block - TRIT_COND_ENDIF | _program_insert_else_flag, /// else block - TRIT_PF_DENY, /// deny - TRIT_PF_PENALTY, /// penalty + TRIT_COND_UNDEFINED, // if block + TRIT_COND_UNDEFINED | _program_insert_else_flag, // elif block + TRIT_COND_ENDIF | _program_insert_else_flag, // else block + TRIT_PF_DENY, // deny + TRIT_PF_PENALTY, // penalty }; +/** insert drop down list strings and values */ static const TraceRestrictDropDownListSet _program_insert = { _program_insert_str, _program_insert_val, }; @@ -134,10 +144,15 @@ static const uint _deny_value_val[] = { 1, }; +/** value drop down list for deny types strings and values */ static const TraceRestrictDropDownListSet _deny_value = { _deny_value_str, _deny_value_val, }; +/** + * Get index of @p value in @p list_set + * if @p value is not present, assert if @p missing_ok is false, otherwise return -1 + */ static int GetDropDownListIndexByValue(const TraceRestrictDropDownListSet *list_set, uint value, bool missing_ok) { const StringID *string_array = list_set->string_array; @@ -152,11 +167,18 @@ static int GetDropDownListIndexByValue(const TraceRestrictDropDownListSet *list_ return -1; } +/** + * Get StringID correspoding to @p value, in @list_set + * @p value must be present + */ static StringID GetDropDownStringByValue(const TraceRestrictDropDownListSet *list_set, uint value) { return list_set->string_array[GetDropDownListIndexByValue(list_set, value, false)]; } +/** + * Return the appropriate type dropdown TraceRestrictDropDownListSet for the given item type @p type + */ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictItemType type) { static const StringID str_action[] = { @@ -198,6 +220,9 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictI return IsTraceRestrictTypeConditional(type) ? &set_cond : &set_action; } +/** + * Get a TraceRestrictDropDownListSet of the sorted cargo list + */ static const TraceRestrictDropDownListSet *GetSortedCargoTypeDropDownListSet() { static StringID cargo_list_str[NUM_CARGO + 1]; @@ -225,21 +250,31 @@ static const uint _cargo_cond_ops_val[] = { TRCO_IS, TRCO_ISNOT, }; +/** cargo conditional operators dropdown list set */ static const TraceRestrictDropDownListSet _cargo_cond_ops = { _cargo_cond_ops_str, _cargo_cond_ops_val, }; +/** + * Get the StringID for a given CargoID @p cargo, or STR_NEWGRF_INVALID_CARGO + */ static StringID GetCargoStringByID(CargoID cargo) { const CargoSpec *cs = CargoSpec::Get(cargo); return cs->IsValid() ? cs->name : STR_NEWGRF_INVALID_CARGO; } +/** + * Get the StringID for a given item type @p type + */ static StringID GetTypeString(TraceRestrictItemType type) { return GetDropDownStringByValue(GetTypeDropDownListSet(type), type); } +/** + * Get the conditional operator field drop down list set for a given type property set @p properties + */ static const TraceRestrictDropDownListSet *GetCondOpDropDownListSet(TraceRestrictTypePropertySet properties) { static const StringID str_long[] = { @@ -292,6 +327,9 @@ static const TraceRestrictDropDownListSet *GetCondOpDropDownListSet(TraceRestric return NULL; } +/** + * Return true if item type field @p type is an integer value type + */ static bool IsIntegerValueType(TraceRestrictValueType type) { switch (type) { @@ -304,6 +342,9 @@ static bool IsIntegerValueType(TraceRestrictValueType type) } } +/** + * Convert integer values between internal units and display units + */ static uint ConvertIntegerValue(TraceRestrictValueType type, uint in, bool to_display) { switch (type) { @@ -321,37 +362,40 @@ static uint ConvertIntegerValue(TraceRestrictValueType type, uint in, bool to_di } } +/** String values for TraceRestrictCondFlags, value gives offset into array */ static const StringID _program_cond_type[] = { - /* 0 */ STR_TRACE_RESTRICT_CONDITIONAL_IF, - /* TRCF_ELSE */ STR_TRACE_RESTRICT_CONDITIONAL_ELIF, - /* TRCF_OR */ STR_TRACE_RESTRICT_CONDITIONAL_ORIF, + STR_TRACE_RESTRICT_CONDITIONAL_IF, // TRCF_DEFAULT + STR_TRACE_RESTRICT_CONDITIONAL_ELIF, // TRCF_ELSE + STR_TRACE_RESTRICT_CONDITIONAL_ORIF, // TRCF_OR }; +/** condition flags field drop down value types */ enum CondFlagsDropDownType { CFDDT_ELSE = 0, ///< This is an else block CFDDT_ELIF = TRCF_ELSE, ///< This is an else-if block CFDDT_ORIF = TRCF_OR, ///< This is an or-if block }; -static const uint32 _condflags_dropdown_else_hide_mask = 1; -static const uint32 _condflags_dropdown_else_if_hide_mask = 6; +static const uint32 _condflags_dropdown_else_hide_mask = 1; ///< disable bitmask for CFDDT_ELSE +static const uint32 _condflags_dropdown_else_if_hide_mask = 6; ///< disable bitmask for CFDDT_ELIF and CFDDT_ORIF + static const StringID _condflags_dropdown_str[] = { - /* CFDDT_ELSE */ STR_TRACE_RESTRICT_CONDITIONAL_ELSE, - /* CFDDT_ELIF */ STR_TRACE_RESTRICT_CONDITIONAL_ELIF, - /* CFDDT_ORIF */ STR_TRACE_RESTRICT_CONDITIONAL_ORIF, + STR_TRACE_RESTRICT_CONDITIONAL_ELSE, + STR_TRACE_RESTRICT_CONDITIONAL_ELIF, + STR_TRACE_RESTRICT_CONDITIONAL_ORIF, INVALID_STRING_ID, }; - static const uint _condflags_dropdown_val[] = { CFDDT_ELSE, CFDDT_ELIF, CFDDT_ORIF, }; - +/** condition flags dropdown list set */ static const TraceRestrictDropDownListSet _condflags_dropdown = { _condflags_dropdown_str, _condflags_dropdown_val, }; +/** Common function for drawing an ordinary conditional instruction */ static void DrawInstructionStringConditionalCommon(TraceRestrictItem item, const TraceRestrictTypePropertySet &properties) { assert(GetTraceRestrictCondFlags(item) <= TRCF_OR); @@ -360,6 +404,7 @@ static void DrawInstructionStringConditionalCommon(TraceRestrictItem item, const SetDParam(2, GetDropDownStringByValue(GetCondOpDropDownListSet(properties), GetTraceRestrictCondOp(item))); } +/** Common function for drawing an integer conditional instruction */ static void DrawInstructionStringConditionalIntegerCommon(TraceRestrictItem item, const TraceRestrictTypePropertySet &properties) { DrawInstructionStringConditionalCommon(item, properties); @@ -486,14 +531,15 @@ static void DrawInstructionString(TraceRestrictItem item, int y, bool selected, DrawString(left + indent * 16, right, y, instruction_string, selected ? TC_WHITE : TC_BLACK); } +/** Main GUI window class */ class TraceRestrictWindow: public Window { - TileIndex tile; - Track track; - int selected_instruction; // NB: this is offset by one due to the display of the "start" item - Scrollbar *vscroll; - std::map drop_down_list_mapping; - TraceRestrictItem expecting_inserted_item; - int current_placement_widget; + TileIndex tile; ///< tile this window is for + Track track; ///< track this window is for + int selected_instruction; ///< selected instruction index, this is offset by one due to the display of the "start" item + Scrollbar *vscroll; ///< scrollbar widget + std::map drop_down_list_mapping; ///< mapping of widget IDs to drop down list sets + TraceRestrictItem expecting_inserted_item; ///< set to instruction when performing an instruction insertion, used to handle selection update on insertion + int current_placement_widget; ///< which widget has a SetObjectToPlaceWnd, if any public: TraceRestrictWindow(WindowDesc *desc, TileIndex tile, Track track) @@ -516,7 +562,7 @@ public: { switch (widget) { case TR_WIDGET_INSTRUCTION_LIST: { - int sel = this->GetInstructionFromPt(pt.y); + int sel = this->GetItemIndexFromPt(pt.y); if (_ctrl_pressed) { // scroll to target (for stations, waypoints, depots) @@ -820,6 +866,9 @@ public: } } + /** + * Common OnPlaceObject handler for program management actions which involve clicking on a signal + */ void OnPlaceObjectSignal(Point pt, TileIndex source_tile, int widget, int error_message) { if (!IsPlainRailTile(source_tile)) { @@ -868,6 +917,9 @@ public: } } + /** + * Common OnPlaceObject handler for instruction value modification actions which involve selecting an order target + */ void OnPlaceObjectDestination(Point pt, TileIndex tile, int widget, int error_message) { TraceRestrictItem item = GetSelected(); @@ -967,13 +1019,13 @@ public: } } - virtual void OnInvalidateData(int data, bool gui_scope) { + virtual void OnInvalidateData(int data, bool gui_scope) + { if (gui_scope) { this->ReloadProgramme(); } } - virtual void SetStringParameters(int widget) const { switch (widget) { @@ -1000,7 +1052,10 @@ public: } private: - TraceRestrictItem MakeSpecialItem(TraceRestictNullTypeSpecialValue value) const + /** + * Helper function to make start and end instructions (these are not stored in the actual program) + */ + TraceRestrictItem MakeSpecialItem(TraceRestrictNullTypeSpecialValue value) const { TraceRestrictItem item = 0; SetTraceRestrictType(item, TRIT_NULL); @@ -1008,6 +1063,9 @@ private: return item; } + /** + * Get item count of program, including start and end markers + */ int GetItemCount(const TraceRestrictProgram *prog) const { if (prog) { @@ -1017,13 +1075,21 @@ private: } } - /// This may return NULL if no program currently exists + /** + * Get current program + * This may return NULL if no program currently exists + */ const TraceRestrictProgram *GetProgram() const { return GetTraceRestrictProgram(MakeTraceRestrictRefId(tile, track), false); } - /// prog may be NULL + /** + * Get instruction at @p index in program @p prog + * This correctly handles start/end markers, offsets, etc. + * This returns a 0 instruction if out of bounds + * @p prog may be NULL + */ TraceRestrictItem GetItem(const TraceRestrictProgram *prog, int index) const { if (index < 0) { @@ -1056,17 +1122,26 @@ private: } } + /** + * Get selected instruction, or a zero instruction + */ TraceRestrictItem GetSelected() const { return this->GetItem(this->GetProgram(), this->selected_instruction); } + /** + * Get owner of the signal tile this window is pointing at + */ Owner GetOwner() { - return GetTileOwner(tile); + return GetTileOwner(this->tile); } - int GetInstructionFromPt(int y) + /** + * Return item index from point in instruction list widget + */ + int GetItemIndexFromPt(int y) { NWidgetBase *nwid = this->GetWidget(TR_WIDGET_INSTRUCTION_LIST); int sel = (y - nwid->pos_y - WD_FRAMERECT_TOP) / nwid->resize_y; // Selected line @@ -1078,6 +1153,9 @@ private: return (sel < this->GetItemCount(this->GetProgram()) && sel >= 0) ? sel : -1; } + /** + * Reload details of program, and adjust length/selection position as necessary + */ void ReloadProgramme() { const TraceRestrictProgram *prog = this->GetProgram(); @@ -1098,6 +1176,9 @@ private: this->UpdateButtonState(); } + /** + * Update button states, text values, etc. + */ void UpdateButtonState() { this->RaiseWidget(TR_WIDGET_INSERT); @@ -1289,6 +1370,10 @@ private: this->SetDirty(); } + /** + * Show a drop down list using @p list_set, setting the pre-selected item to the one corresponding to @p value + * This asserts if @p value is not in @p list_set, and @p missing_ok is false + */ void ShowDropDownListWithValue(const TraceRestrictDropDownListSet *list_set, uint value, bool missing_ok, int button, uint32 disabled_mask, uint32 hidden_mask, uint width) { @@ -1297,6 +1382,9 @@ private: ShowDropDownMenu(this, list_set->string_array, selected, button, disabled_mask, hidden_mask, width); } + /** + * Helper function to set or unset a SetObjectToPlaceWnd, for the given widget and cursor type + */ void SetObjectToPlaceAction(int widget, CursorID cursor) { this->ToggleWidgetLoweredState(widget); @@ -1310,7 +1398,11 @@ private: } } - /// This used for testing whether else or else-if blocks could be inserted, or replace the selection + /** + * This used for testing whether else or else-if blocks could be inserted, or replace the selection + * If @p replace is true, replace selection with @p item, else insert @p item before selection + * Returns true if resulting instruction list passes validation + */ bool GenericElseInsertionDryRun(TraceRestrictItem item, bool replace) { if (this->selected_instruction < 1) return false; @@ -1332,6 +1424,9 @@ private: return TraceRestrictProgram::Validate(items).Succeeded(); } + /** + * Run GenericElseInsertionDryRun with an else instruction + */ bool ElseInsertionDryRun(bool replace) { TraceRestrictItem item = 0; @@ -1340,6 +1435,9 @@ private: return GenericElseInsertionDryRun(item, replace); } + /** + * Run GenericElseInsertionDryRun with an elif instruction + */ bool ElseIfInsertionDryRun(bool replace) { TraceRestrictItem item = 0; @@ -1430,6 +1528,9 @@ static WindowDesc _program_desc( _nested_program_widgets, lengthof(_nested_program_widgets) ); +/** + * Show or create program window for given @p tile and @p track + */ void ShowTraceRestrictProgramWindow(TileIndex tile, Track track) { if (BringWindowToFrontById(WC_TRACE_RESTRICT, MakeTraceRestrictRefId(tile, track)) != NULL) {