Trace restrict slots: Add support for slot operations at PBS end signal

tracerestrict-sx
Jonathan G Rennison 6 years ago
parent 1b4db7d86c
commit e9f5d80440

@ -2473,10 +2473,16 @@ STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT :Acquire or wait
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE :Try to acquire
STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT :Release (front)
STR_TRACE_RESTRICT_SLOT_RELEASE_BACK :Release (back)
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_ACQUIRE_WAIT :PBS end: Acquire or wait
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_TRY_ACQUIRE :PBS end: Try to acquire
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_RELEASE :PBS end: Release
STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT_ITEM :Acquire slot: {STRING1}{BLACK}{STRING}, or wait at PBS signal
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE_ITEM :Try to acquire slot: {STRING1}{BLACK}{STRING}, or continue anyway
STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT_ITEM :Release slot: {STRING1}{BLACK}{STRING} (front of train)
STR_TRACE_RESTRICT_SLOT_RELEASE_BACK_ITEM :Release slot: {STRING1}{BLACK}{STRING} (back of train)
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_ACQUIRE_WAIT_ITEM :PBS reservation ending here: Acquire slot: {STRING1}{BLACK}{STRING}, or wait at start
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_TRY_ACQUIRE_ITEM :PBS reservation ending here: Acquire slot: {STRING1}{BLACK}{STRING}, or continue anyway
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_RELEASE_ITEM :PBS reservation ending here: Release slot: {STRING1}{BLACK}{STRING}
STR_TRACE_RESTRICT_SLOT_NAME :{TRSLOT}
STR_TRACE_RESTRICT_SLOT_LIST_HEADER :{BLACK}Slot{CONSUME_ARG}{P "" s}: {LTBLUE}
STR_TRACE_RESTRICT_SLOT_LIST_SEPARATOR :{BLACK}, {LTBLUE}

@ -18,6 +18,7 @@
#include "yapf_destrail.hpp"
#include "../../viewport_func.h"
#include "../../newgrf_station.h"
#include "../../tracerestrict.h"
#include "../../safeguards.h"
@ -159,7 +160,8 @@ public:
}
/* Don't bother if the target is reserved. */
if (!IsWaitingPositionFree(Yapf().GetVehicle(), m_res_dest, m_res_dest_td)) return false;
PBSWaitingPositionRestrictedSignalInfo restricted_signal_info;
if (!IsWaitingPositionFree(Yapf().GetVehicle(), m_res_dest, m_res_dest_td, false, &restricted_signal_info)) return false;
for (Node *node = m_res_node; node->m_parent != NULL; node = node->m_parent) {
node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::ReserveSingleTrack);
@ -177,6 +179,18 @@ public:
}
}
if (restricted_signal_info.tile != INVALID_TILE) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(restricted_signal_info.tile, TrackdirToTrack(restricted_signal_info.trackdir));
if (prog && prog->actions_used_flags & TRPAUF_PBS_RES_END_SLOT) {
extern TileIndex VehiclePosTraceRestrictPreviousSignalCallback(const Train *v, const void *);
TraceRestrictProgramResult out;
TraceRestrictProgramInput input(restricted_signal_info.tile, restricted_signal_info.trackdir, &VehiclePosTraceRestrictPreviousSignalCallback, NULL);
input.permitted_slot_operations = TRPISP_PBS_RES_END_ACQUIRE | TRPISP_PBS_RES_END_RELEASE;
prog->Execute(Yapf().GetVehicle(), input, out);
}
}
if (target != NULL) target->okay = true;
if (Yapf().CanUseGlobalCache(*m_res_node)) {

@ -515,7 +515,7 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo
* @param forbid_90deg Don't allow trains to make 90 degree turns
* @return True if the position is free
*/
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg)
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg, PBSWaitingPositionRestrictedSignalInfo *restricted_signal_info)
{
Track track = TrackdirToTrack(trackdir);
TrackBits reserved = GetReservedTrackbits(tile);
@ -526,12 +526,18 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo
/* Not reserved and depot or not a pbs signal -> free. */
if (IsRailDepotTile(tile)) return true;
auto pbs_res_end_wait_test = [v](TileIndex t, Trackdir td) -> bool {
auto pbs_res_end_wait_test = [v, restricted_signal_info](TileIndex t, Trackdir td) -> bool {
if (IsRestrictedSignal(t)) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(t, TrackdirToTrack(td));
if (restricted_signal_info && prog) {
restricted_signal_info->tile = t;
restricted_signal_info->trackdir = td;
}
if (prog && prog->actions_used_flags & TRPAUF_PBS_RES_END_WAIT) {
TraceRestrictProgramInput input(t, td, &VehiclePosTraceRestrictPreviousSignalCallback, NULL);
input.permitted_slot_operations = TRPISP_PBS_RES_END_ACQ_DRY;
TraceRestrictProgramResult out;
prog->Execute(v, TraceRestrictProgramInput(t, td, &VehiclePosTraceRestrictPreviousSignalCallback, NULL), out);
prog->Execute(v, input, out);
if (out.flags & TRPRF_PBS_RES_END_WAIT) {
return false;
}

@ -46,9 +46,14 @@ struct PBSTileInfo {
PBSTileInfo(TileIndex _t, Trackdir _td, bool _okay) : tile(_t), trackdir(_td), okay(_okay) {}
};
struct PBSWaitingPositionRestrictedSignalInfo {
TileIndex tile = INVALID_TILE;
Trackdir trackdir = INVALID_TRACKDIR;
};
PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res = NULL);
bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg = false);
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false);
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false, PBSWaitingPositionRestrictedSignalInfo *restricted_signal_info = nullptr);
Train *GetTrainForReservation(TileIndex tile, Track track);

@ -519,6 +519,22 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
if (input.permitted_slot_operations & TRPISP_RELEASE_FRONT) slot->Vacate(v->index);
break;
case TRSCOF_PBS_RES_END_ACQ_WAIT:
if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQUIRE) {
if (!slot->Occupy(v->index)) out.flags |= TRPRF_PBS_RES_END_WAIT;
} else if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) {
if (!slot->OccupyDryRun(v->index)) out.flags |= TRPRF_PBS_RES_END_WAIT;
}
break;
case TRSCOF_PBS_RES_END_ACQ_TRY:
if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQUIRE) slot->Occupy(v->index);
break;
case TRSCOF_PBS_RES_END_RELEASE:
if (input.permitted_slot_operations & TRPISP_PBS_RES_END_RELEASE) slot->Vacate(v->index);
break;
default:
NOT_REACHED();
break;
@ -673,6 +689,15 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
actions_used_flags |= TRPAUF_SLOT_RELEASE_FRONT;
break;
case TRSCOF_PBS_RES_END_ACQ_WAIT:
actions_used_flags |= TRPAUF_PBS_RES_END_SLOT | TRPAUF_PBS_RES_END_WAIT;
break;
case TRSCOF_PBS_RES_END_ACQ_TRY:
case TRSCOF_PBS_RES_END_RELEASE:
actions_used_flags |= TRPAUF_PBS_RES_END_SLOT;
break;
default:
NOT_REACHED();
break;
@ -1467,6 +1492,18 @@ bool TraceRestrictSlot::Occupy(VehicleID id, bool force)
return true;
}
/**
* Dry-run adding vehicle ID to occupants if possible and not already an occupant
* @param id Vehicle ID
* @return whether vehicle IDwould be an occupant
*/
bool TraceRestrictSlot::OccupyDryRun(VehicleID id)
{
if (this->IsOccupant(id)) return true;
if (this->occupants.size() >= this->max_occupancy) return false;
return true;
}
/**
* Remove vehicle ID from occupants
* @param id Vehicle ID

@ -240,6 +240,9 @@ enum TraceRestrictSlotCondOpField {
TRSCOF_ACQUIRE_TRY = 1, ///< try to acquire a slot, or carry on otherwise
TRSCOF_RELEASE_BACK = 2, ///< release a slot (back of train)
TRSCOF_RELEASE_FRONT = 3, ///< release a slot (front of train)
TRSCOF_PBS_RES_END_ACQ_WAIT = 4, ///< PBS reservations ending at this signal: acquire a slot, or wait
TRSCOF_PBS_RES_END_ACQ_TRY = 5, ///< PBS reservations ending at this signal: acquire a slot, or carry on otherwise
TRSCOF_PBS_RES_END_RELEASE = 6, ///< PBS reservations ending at this signal: release a slot
/* space up to 8 */
};
@ -287,6 +290,7 @@ enum TraceRestrictProgramActionsUsedFlags {
TRPAUF_SLOT_RELEASE_BACK = 1 << 5, ///< Slot release (back) action is present
TRPAUF_SLOT_RELEASE_FRONT = 1 << 6, ///< Slot release (front) action is present
TRPAUF_PBS_RES_END_WAIT = 1 << 7, ///< PBS reservations ending at this signal wait action is present
TRPAUF_PBS_RES_END_SLOT = 1 << 8, ///< PBS reservations ending at this signal slot action is present
};
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags)
@ -297,6 +301,9 @@ enum TraceRestrictProgramInputSlotPermissions {
TRPISP_ACQUIRE = 1 << 0, ///< Slot acquire is permitted
TRPISP_RELEASE_BACK = 1 << 1, ///< Slot release (back) is permitted
TRPISP_RELEASE_FRONT = 1 << 2, ///< Slot release (front) is permitted
TRPISP_PBS_RES_END_ACQUIRE = 1 << 3, ///< Slot acquire (PBS reservations ending at this signal) is permitted
TRPISP_PBS_RES_END_ACQ_DRY = 1 << 4, ///< Dry-run slot acquire (PBS reservations ending at this signal) is permitted
TRPISP_PBS_RES_END_RELEASE = 1 << 5, ///< Slot release (PBS reservations ending at this signal) is permitted
};
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputSlotPermissions)
@ -781,6 +788,7 @@ struct TraceRestrictSlot : TraceRestrictSlotPool::PoolItem<&_tracerestrictslot_p
}
bool Occupy(VehicleID id, bool force = false);
bool OccupyDryRun(VehicleID ids);
void Vacate(VehicleID id);
void Clear();

@ -506,6 +506,9 @@ static const StringID _slot_op_cond_ops_str[] = {
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE,
STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT,
STR_TRACE_RESTRICT_SLOT_RELEASE_BACK,
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_ACQUIRE_WAIT,
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_TRY_ACQUIRE,
STR_TRACE_RESTRICT_SLOT_PBS_RES_END_RELEASE,
INVALID_STRING_ID,
};
static const uint _slot_op_cond_ops_val[] = {
@ -513,6 +516,9 @@ static const uint _slot_op_cond_ops_val[] = {
TRSCOF_ACQUIRE_TRY,
TRSCOF_RELEASE_FRONT,
TRSCOF_RELEASE_BACK,
TRSCOF_PBS_RES_END_ACQ_WAIT,
TRSCOF_PBS_RES_END_ACQ_TRY,
TRSCOF_PBS_RES_END_RELEASE,
};
/** cargo conditional operators dropdown list set */
static const TraceRestrictDropDownListSet _slot_op_cond_ops = {
@ -1079,6 +1085,18 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
instruction_string = STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT_ITEM;
break;
case TRSCOF_PBS_RES_END_ACQ_WAIT:
instruction_string = STR_TRACE_RESTRICT_SLOT_PBS_RES_END_ACQUIRE_WAIT_ITEM;
break;
case TRSCOF_PBS_RES_END_ACQ_TRY:
instruction_string = STR_TRACE_RESTRICT_SLOT_PBS_RES_END_TRY_ACQUIRE_ITEM;
break;
case TRSCOF_PBS_RES_END_RELEASE:
instruction_string = STR_TRACE_RESTRICT_SLOT_PBS_RES_END_RELEASE_ITEM;
break;
default:
NOT_REACHED();
break;

@ -2405,9 +2405,19 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, const PBSTileInfo &ori
cur_td = FindFirstTrackdir(ft.m_new_td_bits);
if (IsSafeWaitingPosition(v, tile, cur_td, true, _settings_game.pf.forbid_90_deg)) {
bool wp_free = IsWaitingPositionFree(v, tile, cur_td, _settings_game.pf.forbid_90_deg);
PBSWaitingPositionRestrictedSignalInfo restricted_signal_info;
bool wp_free = IsWaitingPositionFree(v, tile, cur_td, _settings_game.pf.forbid_90_deg, &restricted_signal_info);
if (!(wp_free && TryReserveRailTrack(tile, TrackdirToTrack(cur_td)))) break;
/* Safe position is all good, path valid and okay. */
if (restricted_signal_info.tile != INVALID_TILE) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(restricted_signal_info.tile, TrackdirToTrack(restricted_signal_info.trackdir));
if (prog && prog->actions_used_flags & TRPAUF_PBS_RES_END_SLOT) {
TraceRestrictProgramResult out;
TraceRestrictProgramInput input(restricted_signal_info.tile, restricted_signal_info.trackdir, &VehiclePosTraceRestrictPreviousSignalCallback, NULL);
input.permitted_slot_operations = TRPISP_PBS_RES_END_ACQUIRE | TRPISP_PBS_RES_END_RELEASE;
prog->Execute(v, input, out);
}
}
return PBSTileInfo(tile, cur_td, true);
}

Loading…
Cancel
Save