Show predicted scheduled dispatch arr/dep times in timetable window

pull/362/head
Jonathan G Rennison 2 years ago
parent 8754e1c5d0
commit 21ef4902c6

@ -618,6 +618,15 @@ private:
int32 scheduled_dispatch_last_dispatch = 0; ///< Last vehicle dispatched offset
int32 scheduled_dispatch_max_delay = 0; ///< Maximum allowed delay
inline void CopyBasicFields(const DispatchSchedule &other)
{
this->scheduled_dispatch_duration = other.scheduled_dispatch_duration;
this->scheduled_dispatch_start_date = other.scheduled_dispatch_start_date;
this->scheduled_dispatch_start_full_date_fract = other.scheduled_dispatch_start_full_date_fract;
this->scheduled_dispatch_last_dispatch = other.scheduled_dispatch_last_dispatch;
this->scheduled_dispatch_max_delay = other.scheduled_dispatch_max_delay;
}
public:
/**
* Get the vector of all scheduled dispatch slot
@ -629,6 +638,7 @@ public:
void AddScheduledDispatch(uint32 offset);
void RemoveScheduledDispatch(uint32 offset);
void ClearScheduledDispatch() { this->scheduled_dispatch.clear(); }
bool UpdateScheduledDispatchToDate(DateTicksScaled now);
void UpdateScheduledDispatch();
/**
@ -701,6 +711,17 @@ public:
* @return scheduled dispatch last dispatch
*/
inline int32 GetScheduledDispatchDelay() const { return this->scheduled_dispatch_max_delay; }
inline void BorrowSchedule(DispatchSchedule &other)
{
this->CopyBasicFields(other);
this->scheduled_dispatch = std::move(other.scheduled_dispatch);
}
inline void ReturnSchedule(DispatchSchedule &other)
{
other.scheduled_dispatch = std::move(this->scheduled_dispatch);
}
};
/**

@ -453,14 +453,11 @@ void DispatchSchedule::RemoveScheduledDispatch(uint32 offset)
this->scheduled_dispatch.erase(erase_position);
}
/**
* Update the scheduled dispatch start time to be the most recent possible.
*/
void DispatchSchedule::UpdateScheduledDispatch()
bool DispatchSchedule::UpdateScheduledDispatchToDate(DateTicksScaled now)
{
bool update_windows = false;
if (this->GetScheduledDispatchStartTick() == 0) {
int64 start = _scaled_date_ticks - (_scaled_date_ticks % this->GetScheduledDispatchDuration());
int64 start = now - (now % this->GetScheduledDispatchDuration());
SchdispatchConvertToFullDateFract(
start,
&this->scheduled_dispatch_start_date, &this->scheduled_dispatch_start_full_date_fract);
@ -474,7 +471,7 @@ void DispatchSchedule::UpdateScheduledDispatch()
}
}
/* Most of the time this loop does not runs. It makes sure start date in in past */
while (this->GetScheduledDispatchStartTick() > _scaled_date_ticks) {
while (this->GetScheduledDispatchStartTick() > now) {
OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch;
last_dispatch += this->GetScheduledDispatchDuration();
this->scheduled_dispatch_last_dispatch = last_dispatch;
@ -484,7 +481,7 @@ void DispatchSchedule::UpdateScheduledDispatch()
update_windows = true;
}
/* Most of the time this loop runs once. It makes sure the start date is as close to current time as possible. */
while (this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration() <= _scaled_date_ticks) {
while (this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration() <= now) {
OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch;
last_dispatch -= this->GetScheduledDispatchDuration();
this->scheduled_dispatch_last_dispatch = last_dispatch;
@ -493,5 +490,15 @@ void DispatchSchedule::UpdateScheduledDispatch()
&this->scheduled_dispatch_start_date, &this->scheduled_dispatch_start_full_date_fract);
update_windows = true;
}
if (update_windows) InvalidateWindowClassesData(WC_SCHDISPATCH_SLOTS, VIWD_MODIFY_ORDERS);
return update_windows;
}
/**
* Update the scheduled dispatch start time to be the most recent possible.
*/
void DispatchSchedule::UpdateScheduledDispatch()
{
if (this->UpdateScheduledDispatchToDate(_scaled_date_ticks)) {
InvalidateWindowClassesData(WC_SCHDISPATCH_SLOTS, VIWD_MODIFY_ORDERS);
}
}

@ -778,7 +778,7 @@ void UpdateSeparationOrder(Vehicle *v_start)
}
}
static DateTicksScaled GetScheduledDispatchTime(const DispatchSchedule &ds, int wait_offset)
DateTicksScaled GetScheduledDispatchTime(const DispatchSchedule &ds, DateTicksScaled leave_time)
{
DateTicksScaled first_slot = -1;
const DateTicksScaled begin_time = ds.GetScheduledDispatchStartTick();
@ -794,7 +794,7 @@ static DateTicksScaled GetScheduledDispatchTime(const DispatchSchedule &ds, int
}
DateTicksScaled current_departure = begin_time + current_offset;
DateTicksScaled minimum = _scaled_date_ticks + wait_offset - max_delay;
DateTicksScaled minimum = leave_time - max_delay;
if (current_departure < minimum) {
current_departure += dispatch_duration * ((minimum + dispatch_duration - current_departure - 1) / dispatch_duration);
}
@ -850,7 +850,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
ds.UpdateScheduledDispatch();
const int wait_offset = real_current_order->GetTimetabledWait();
DateTicksScaled slot = GetScheduledDispatchTime(ds, wait_offset);
DateTicksScaled slot = GetScheduledDispatchTime(ds, _scaled_date_ticks + wait_offset);
if (slot > -1) {
SetBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
v->lateness_counter = _scaled_date_ticks - slot + wait_offset;

@ -33,10 +33,16 @@
#include "safeguards.h"
enum TimetableArrivalDepartureFlags {
TADF_ARRIVAL_PREDICTED,
TADF_DEPARTURE_PREDICTED,
};
/** Container for the arrival/departure dates of a vehicle */
struct TimetableArrivalDeparture {
Ticks arrival; ///< The arrival time
Ticks departure; ///< The departure time
uint flags;
};
/**
@ -121,8 +127,11 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID
/* Pre-initialize with unknown time */
for (int i = 0; i < v->GetNumOrders(); ++i) {
table[i].arrival = table[i].departure = INVALID_TICKS;
table[i].flags = 0;
}
bool predicted = false;
/* Cyclically loop over all orders until we reach the current one again.
* As we may start at the current order, do a post-checking loop */
do {
@ -134,12 +143,26 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID
if (!CanDetermineTimeTaken(order, true)) return;
sum += order->GetTimetabledTravel();
table[i].arrival = sum;
if (predicted) SetBit(table[i].flags, TADF_ARRIVAL_PREDICTED);
}
if (order->IsScheduledDispatchOrder(true) && !(i == start && !travelling)) return;
if (!CanDetermineTimeTaken(order, false)) return;
sum += order->GetTimetabledWait();
if (order->IsScheduledDispatchOrder(true) && !(i == start && !travelling)) {
extern DateTicksScaled GetScheduledDispatchTime(const DispatchSchedule &ds, DateTicksScaled leave_time);
DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(order->GetDispatchScheduleIndex());
DispatchSchedule predicted_ds;
predicted_ds.BorrowSchedule(ds);
predicted_ds.UpdateScheduledDispatchToDate(_scaled_date_ticks + sum);
DateTicksScaled slot = GetScheduledDispatchTime(predicted_ds, _scaled_date_ticks + sum + order->GetTimetabledWait());
predicted_ds.ReturnSchedule(ds);
if (slot <= -1) return;
sum = slot - _scaled_date_ticks;
predicted = true;
} else {
if (!CanDetermineTimeTaken(order, false)) return;
sum += order->GetTimetabledWait();
}
table[i].departure = sum;
if (predicted) SetBit(table[i].flags, TADF_DEPARTURE_PREDICTED);
}
++i;
@ -694,17 +717,17 @@ struct TimetableWindow : Window {
SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival);
DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY, TC_GREEN);
} else {
SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival + offset);
SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival + (HasBit(arr_dep[i / 2].flags, TADF_ARRIVAL_PREDICTED) ? 0 : offset));
DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY,
show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK);
HasBit(arr_dep[i / 2].flags, TADF_ARRIVAL_PREDICTED) ? (TextColour)(TC_IS_PALETTE_COLOUR | TC_NO_SHADE | 4) : (show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK));
}
}
} else {
if (arr_dep[i / 2].departure != INVALID_TICKS) {
DrawString(abbr_left, abbr_right, y, STR_TIMETABLE_DEPARTURE_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK);
SetDParam(0, _scaled_date_ticks + arr_dep[i/2].departure + offset);
SetDParam(0, _scaled_date_ticks + arr_dep[i/2].departure + (HasBit(arr_dep[i / 2].flags, TADF_DEPARTURE_PREDICTED) ? 0 : offset));
DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY,
show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK);
HasBit(arr_dep[i / 2].flags, TADF_DEPARTURE_PREDICTED) ? (TextColour)(TC_IS_PALETTE_COLOUR | TC_NO_SHADE | 4) : (show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK));
}
}
y += line_height;

Loading…
Cancel
Save