Strong typedef: Use strong typedefs for date, date tick, minutes types
Add delta types Adjust/add type conversion functions Add various utility methods on types Remove the various minute macros Fix some minute conversion inconsistencies
This commit is contained in:
@@ -43,15 +43,23 @@
|
||||
typedef btree::btree_map<const DispatchSchedule *, btree::btree_set<DateTicksScaled>> schdispatch_cache_t;
|
||||
|
||||
/** A scheduled order. */
|
||||
typedef struct OrderDate
|
||||
{
|
||||
struct OrderDate {
|
||||
const Order *order; ///< The order
|
||||
const Vehicle *v; ///< The vehicle carrying out the order
|
||||
DateTicks expected_date;///< The date on which the order is expected to complete
|
||||
Ticks expected_tick; ///< The tick on which the order is expected to complete
|
||||
Ticks lateness; ///< How late this order is expected to finish
|
||||
DepartureStatus status; ///< Whether the vehicle has arrived to carry out the order yet
|
||||
uint scheduled_waiting_time; ///< Scheduled waiting time if scheduled dispatch is used
|
||||
} OrderDate;
|
||||
Ticks scheduled_waiting_time; ///< Scheduled waiting time if scheduled dispatch is used
|
||||
|
||||
inline Ticks EffectiveWaitingTime() const
|
||||
{
|
||||
if (this->scheduled_waiting_time > 0) {
|
||||
return this->scheduled_waiting_time;
|
||||
} else {
|
||||
return this->order->GetWaitTime();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static bool IsDeparture(const Order *order, StationID station) {
|
||||
return (order->GetType() == OT_GOTO_STATION &&
|
||||
@@ -93,7 +101,7 @@ static uint8 GetDepartureConditionalOrderMode(const Order *order, const Vehicle
|
||||
return _settings_client.gui.departure_conditionals;
|
||||
}
|
||||
|
||||
static bool VehicleSetNextDepartureTime(DateTicks *previous_departure, uint *waiting_time, const DateTicksScaled date_only_scaled, const Vehicle *v, const Order *order, bool arrived_at_timing_point, schdispatch_cache_t &dept_schedule_last)
|
||||
static bool VehicleSetNextDepartureTime(Ticks *previous_departure, Ticks *waiting_time, const DateTicksScaled date_ticks_base, const Vehicle *v, const Order *order, bool arrived_at_timing_point, schdispatch_cache_t &dept_schedule_last)
|
||||
{
|
||||
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
||||
auto is_current_implicit_order = [&v](const Order *o) -> bool {
|
||||
@@ -115,7 +123,7 @@ static bool VehicleSetNextDepartureTime(DateTicks *previous_departure, uint *wai
|
||||
DateTicksScaled earliest_departure = begin_time + ds.GetScheduledDispatchLastDispatch();
|
||||
|
||||
/* Earliest possible departure according to vehicle current timetable */
|
||||
const uint32 ready_to_depart_time = date_only_scaled + *previous_departure + order->GetTravelTime() + order->GetTimetabledWait();
|
||||
const DateTicksScaled ready_to_depart_time = date_ticks_base + *previous_departure + order->GetTravelTime() + order->GetTimetabledWait();
|
||||
if (earliest_departure + max_delay < ready_to_depart_time) {
|
||||
earliest_departure = ready_to_depart_time - max_delay - 1;
|
||||
/* -1 because this number is actually a moment before actual departure */
|
||||
@@ -141,8 +149,8 @@ static bool VehicleSetNextDepartureTime(DateTicks *previous_departure, uint *wai
|
||||
}
|
||||
}
|
||||
|
||||
*waiting_time = actual_departure - date_only_scaled - *previous_departure - order->GetTravelTime();
|
||||
*previous_departure = actual_departure - date_only_scaled;
|
||||
*waiting_time = (actual_departure - date_ticks_base).AsTicks() - *previous_departure - order->GetTravelTime();
|
||||
*previous_departure = (actual_departure - date_ticks_base).AsTicks();
|
||||
slot_cache.insert(actual_departure);
|
||||
|
||||
/* Return true means that vehicle lateness should be clear from this point onward */
|
||||
@@ -185,18 +193,18 @@ static void ScheduledDispatchDepartureLocalFix(DepartureList *departure_list)
|
||||
|
||||
/* Sort the departure list by arrival time */
|
||||
std::sort(d_list.begin(), d_list.end(), [](const Departure * const &a, const Departure * const &b) -> bool {
|
||||
DateTicksScaled arr_a = a->scheduled_date - (a->scheduled_waiting_time > 0 ? a->scheduled_waiting_time : a->order->GetWaitTime());
|
||||
DateTicksScaled arr_b = b->scheduled_date - (b->scheduled_waiting_time > 0 ? b->scheduled_waiting_time : b->order->GetWaitTime());
|
||||
DateTicksScaled arr_a = a->scheduled_date - a->EffectiveWaitingTime();
|
||||
DateTicksScaled arr_b = b->scheduled_date - b->EffectiveWaitingTime();
|
||||
return arr_a < arr_b;
|
||||
});
|
||||
|
||||
/* Re-assign them sequentially */
|
||||
for (size_t i = 0; i < d_list.size(); i++) {
|
||||
const DateTicksScaled arrival = d_list[i]->scheduled_date - (d_list[i]->scheduled_waiting_time > 0 ? d_list[i]->scheduled_waiting_time : d_list[i]->order->GetWaitTime());
|
||||
d_list[i]->scheduled_waiting_time = departure_time_list[i] - arrival;
|
||||
const DateTicksScaled arrival = d_list[i]->scheduled_date - d_list[i]->EffectiveWaitingTime();
|
||||
d_list[i]->scheduled_waiting_time = (departure_time_list[i] - arrival).AsTicks();
|
||||
d_list[i]->scheduled_date = departure_time_list[i];
|
||||
|
||||
if (d_list[i]->scheduled_waiting_time == d_list[i]->order->GetWaitTime()) {
|
||||
if (d_list[i]->scheduled_waiting_time == (Ticks)d_list[i]->order->GetWaitTime()) {
|
||||
d_list[i]->scheduled_waiting_time = 0;
|
||||
}
|
||||
}
|
||||
@@ -237,12 +245,11 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
std::vector<OrderDate*> next_orders;
|
||||
|
||||
/* The maximum possible date for departures to be scheduled to occur. */
|
||||
DateTicksScaled max_date = GetDeparturesMaxTicksAhead();
|
||||
const Ticks max_ticks = GetDeparturesMaxTicksAhead();
|
||||
|
||||
DateTicksScaled date_only_scaled = DateToScaledDateTicks(_date);
|
||||
DateTicksScaled date_fract_scaled = ((DateTicksScaled)_date_fract * _settings_game.economy.day_length_factor) + _tick_skip_counter;
|
||||
const DateTicksScaled date_ticks_base = _scaled_date_ticks;
|
||||
|
||||
/* The scheduled order in next_orders with the earliest expected_date field. */
|
||||
/* The scheduled order in next_orders with the earliest expected_tick field. */
|
||||
OrderDate *least_order = nullptr;
|
||||
|
||||
/* Cache for scheduled departure time */
|
||||
@@ -272,20 +279,20 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
|
||||
const Order *order = v->GetOrder(v->cur_implicit_order_index % v->GetNumOrders());
|
||||
if (order == nullptr) continue;
|
||||
DateTicks start_date = date_fract_scaled - v->current_order_time;
|
||||
Ticks start_ticks = -((Ticks)v->current_order_time);
|
||||
if (v->cur_timetable_order_index != INVALID_VEH_ORDER_ID && v->cur_timetable_order_index != v->cur_real_order_index) {
|
||||
/* vehicle is taking a conditional order branch, adjust start time to compensate */
|
||||
const Order *real_current_order = v->GetOrder(v->cur_real_order_index);
|
||||
const Order *real_timetable_order = v->GetOrder(v->cur_timetable_order_index);
|
||||
if (real_timetable_order->IsType(OT_CONDITIONAL)) {
|
||||
start_date += (real_timetable_order->GetWaitTime() - real_current_order->GetTravelTime());
|
||||
start_ticks += (real_timetable_order->GetWaitTime() - real_current_order->GetTravelTime());
|
||||
} else {
|
||||
/* This can also occur with implicit orders, when there are no real orders, do nothing */
|
||||
}
|
||||
}
|
||||
DepartureStatus status = D_TRAVELLING;
|
||||
bool should_reset_lateness = false;
|
||||
uint waiting_time = 0;
|
||||
Ticks waiting_time = 0;
|
||||
|
||||
/* If the vehicle is stopped in a depot, ignore it. */
|
||||
if (v->IsStoppedInDepot()) {
|
||||
@@ -301,20 +308,20 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
if (v->current_order.IsAnyLoadingType() || v->current_order.IsType(OT_WAITING)) {
|
||||
/* Account for the vehicle having reached the current order and being in the loading phase. */
|
||||
status = D_ARRIVED;
|
||||
start_date -= order->GetTravelTime() + ((v->lateness_counter < 0) ? v->lateness_counter : 0);
|
||||
start_ticks -= order->GetTravelTime() + ((v->lateness_counter < 0) ? v->lateness_counter : 0);
|
||||
require_travel_time = false;
|
||||
}
|
||||
|
||||
/* Loop through the vehicle's orders until we've found a suitable order or we've determined that no such order exists. */
|
||||
/* We only need to consider each order at most once. */
|
||||
for (int i = v->GetNumOrders(); i > 0; --i) {
|
||||
if (VehicleSetNextDepartureTime(&start_date, &waiting_time, date_only_scaled, v, order, status == D_ARRIVED, schdispatch_last_planned_dispatch)) {
|
||||
if (VehicleSetNextDepartureTime(&start_ticks, &waiting_time, date_ticks_base, v, order, status == D_ARRIVED, schdispatch_last_planned_dispatch)) {
|
||||
should_reset_lateness = true;
|
||||
}
|
||||
|
||||
/* If the order is a conditional branch, handle it. */
|
||||
if (order->IsType(OT_CONDITIONAL)) {
|
||||
switch(GetDepartureConditionalOrderMode(order, v, start_date + date_only_scaled)) {
|
||||
switch(GetDepartureConditionalOrderMode(order, v, date_ticks_base + start_ticks)) {
|
||||
case 0: {
|
||||
/* Give up */
|
||||
break;
|
||||
@@ -329,7 +336,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
break;
|
||||
}
|
||||
|
||||
start_date -= order->GetTravelTime();
|
||||
start_ticks -= order->GetTravelTime();
|
||||
require_travel_time = false;
|
||||
continue;
|
||||
}
|
||||
@@ -338,7 +345,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
if (status != D_CANCELLED) {
|
||||
status = D_TRAVELLING;
|
||||
}
|
||||
start_date -= order->GetWaitTime(); /* Added previously in VehicleSetNextDepartureTime */
|
||||
start_ticks -= order->GetWaitTime(); /* Added previously in VehicleSetNextDepartureTime */
|
||||
order = (order->next == nullptr) ? v->GetFirstOrder() : order->next;
|
||||
require_travel_time = true;
|
||||
continue;
|
||||
@@ -348,7 +355,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
}
|
||||
|
||||
/* If the scheduled departure date is too far in the future, stop. */
|
||||
if (start_date - v->lateness_counter > max_date) {
|
||||
if (start_ticks - v->lateness_counter > max_ticks) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -363,7 +370,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
(type == D_DEPARTURE && show_vehicles_via && IsVia(order, station)) ||
|
||||
(type == D_ARRIVAL && IsArrival(order, station))) {
|
||||
/* If the departure was scheduled to have already begun and has been cancelled, do not show it. */
|
||||
if (start_date < 0 && status == D_CANCELLED) {
|
||||
if (start_ticks < 0 && status == D_CANCELLED) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -371,7 +378,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
od->order = order;
|
||||
od->v = v;
|
||||
/* We store the expected date for now, so that vehicles will be shown in order of expected time. */
|
||||
od->expected_date = start_date;
|
||||
od->expected_tick = start_ticks;
|
||||
od->lateness = v->lateness_counter > 0 ? v->lateness_counter : 0;
|
||||
od->status = status;
|
||||
od->scheduled_waiting_time = waiting_time;
|
||||
@@ -383,15 +390,20 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
|
||||
/* If we are early, use the scheduled date as the expected date. We also take lateness to be zero. */
|
||||
if (!should_reset_lateness && v->lateness_counter < 0 && !(v->current_order.IsAnyLoadingType() || v->current_order.IsType(OT_WAITING))) {
|
||||
od->expected_date -= v->lateness_counter;
|
||||
od->expected_tick -= v->lateness_counter;
|
||||
}
|
||||
|
||||
/* Update least_order if this is the current least order. */
|
||||
if (least_order == nullptr) {
|
||||
least_order = od;
|
||||
} else if (int(least_order->expected_date - least_order->lateness - (type == D_ARRIVAL ? (least_order->scheduled_waiting_time > 0 ? least_order->scheduled_waiting_time : least_order->order->GetWaitTime()) : 0)) > int(od->expected_date - od->lateness - (type == D_ARRIVAL ? (od->scheduled_waiting_time > 0 ? od->scheduled_waiting_time : od->order->GetWaitTime()) : 0))) {
|
||||
/* Somehow my compiler perform an unsigned comparition above so integer cast is required */
|
||||
least_order = od;
|
||||
} else if (type == D_ARRIVAL) {
|
||||
if ((least_order->expected_tick - least_order->lateness - least_order->EffectiveWaitingTime()) > (od->expected_tick - od->lateness - od->EffectiveWaitingTime())) {
|
||||
least_order = od;
|
||||
}
|
||||
} else {
|
||||
if ((least_order->expected_tick - least_order->lateness) > (od->expected_tick - od->lateness)) {
|
||||
least_order = od;
|
||||
}
|
||||
}
|
||||
|
||||
next_orders.push_back(od);
|
||||
@@ -420,22 +432,22 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
for(int i = 10000; i > 0; --i) {
|
||||
/* I should probably try to convince you that this loop always terminates regardless of the safeguard. */
|
||||
/* 1. next_orders contains at least one element. */
|
||||
/* 2. The loop terminates if result->size() exceeds a fixed (for this loop) value, or if the least order's scheduled date is later than max_date. */
|
||||
/* 2. The loop terminates if result->size() exceeds a fixed (for this loop) value, or if the least order's scheduled date is later than max_ticks. */
|
||||
/* (We ignore the case that the least order's scheduled date has overflown, as it is a relative rather than absolute date.) */
|
||||
/* 3. Every time we loop round, either result->size() will have increased -OR- we will have increased the expected_date of one of the elements of next_orders. */
|
||||
/* 3. Every time we loop round, either result->size() will have increased -OR- we will have increased the expected_tick of one of the elements of next_orders. */
|
||||
/* 4. Therefore the loop must eventually terminate. */
|
||||
|
||||
/* least_order is the best candidate for the next departure. */
|
||||
|
||||
/* First, we check if we can stop looking for departures yet. */
|
||||
if (result->size() >= _settings_client.gui.max_departures ||
|
||||
least_order->expected_date - least_order->lateness > max_date) {
|
||||
least_order->expected_tick - least_order->lateness > max_ticks) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* We already know the least order and that it's a suitable departure, so make it into a departure. */
|
||||
Departure *d = new Departure();
|
||||
d->scheduled_date = date_only_scaled + least_order->expected_date - least_order->lateness;
|
||||
d->scheduled_date = date_ticks_base + least_order->expected_tick - least_order->lateness;
|
||||
d->lateness = least_order->lateness;
|
||||
d->status = least_order->status;
|
||||
d->vehicle = least_order->v;
|
||||
@@ -751,7 +763,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
|
||||
/* Go to the next order so we don't add the current order again. */
|
||||
order = (order->next == nullptr) ? least_order->v->GetFirstOrder() : order->next;
|
||||
if (VehicleSetNextDepartureTime(&least_order->expected_date, &least_order->scheduled_waiting_time, date_only_scaled, least_order->v, order, false, schdispatch_last_planned_dispatch)) {
|
||||
if (VehicleSetNextDepartureTime(&least_order->expected_tick, &least_order->scheduled_waiting_time, date_ticks_base, least_order->v, order, false, schdispatch_last_planned_dispatch)) {
|
||||
least_order->lateness = 0;
|
||||
}
|
||||
|
||||
@@ -762,7 +774,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
for (int i = least_order->v->GetNumOrders(); i > 0; --i) {
|
||||
/* If the order is a conditional branch, handle it. */
|
||||
if (order->IsType(OT_CONDITIONAL)) {
|
||||
switch(GetDepartureConditionalOrderMode(order, least_order->v, least_order->expected_date)) {
|
||||
switch(GetDepartureConditionalOrderMode(order, least_order->v, least_order->expected_tick)) {
|
||||
case 0: {
|
||||
/* Give up */
|
||||
break;
|
||||
@@ -774,8 +786,8 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
break;
|
||||
}
|
||||
|
||||
least_order->expected_date -= order->GetTravelTime(); /* Added in next VehicleSetNextDepartureTime */
|
||||
if (VehicleSetNextDepartureTime(&least_order->expected_date, &least_order->scheduled_waiting_time, date_only_scaled, least_order->v, order, false, schdispatch_last_planned_dispatch)) {
|
||||
least_order->expected_tick -= order->GetTravelTime(); /* Added in next VehicleSetNextDepartureTime */
|
||||
if (VehicleSetNextDepartureTime(&least_order->expected_tick, &least_order->scheduled_waiting_time, date_ticks_base, least_order->v, order, false, schdispatch_last_planned_dispatch)) {
|
||||
least_order->lateness = 0;
|
||||
}
|
||||
require_travel_time = false;
|
||||
@@ -783,9 +795,9 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
}
|
||||
case 2: {
|
||||
/* Do not take the branch */
|
||||
least_order->expected_date -= order->GetWaitTime(); /* Added previously in VehicleSetNextDepartureTime */
|
||||
least_order->expected_tick -= order->GetWaitTime(); /* Added previously in VehicleSetNextDepartureTime */
|
||||
order = (order->next == nullptr) ? least_order->v->GetFirstOrder() : order->next;
|
||||
if (VehicleSetNextDepartureTime(&least_order->expected_date, &least_order->scheduled_waiting_time, date_only_scaled, least_order->v, order, false, schdispatch_last_planned_dispatch)) {
|
||||
if (VehicleSetNextDepartureTime(&least_order->expected_tick, &least_order->scheduled_waiting_time, date_ticks_base, least_order->v, order, false, schdispatch_last_planned_dispatch)) {
|
||||
least_order->lateness = 0;
|
||||
}
|
||||
require_travel_time = true;
|
||||
@@ -801,7 +813,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
}
|
||||
|
||||
/* If the departure is scheduled to be too late, then stop. */
|
||||
if (least_order->expected_date - least_order->lateness > max_date) {
|
||||
if (least_order->expected_tick - least_order->lateness > max_ticks) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -815,7 +827,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
}
|
||||
|
||||
order = (order->next == nullptr) ? least_order->v->GetFirstOrder() : order->next;
|
||||
if (VehicleSetNextDepartureTime(&least_order->expected_date, &least_order->scheduled_waiting_time, date_only_scaled, least_order->v, order, false, schdispatch_last_planned_dispatch)) {
|
||||
if (VehicleSetNextDepartureTime(&least_order->expected_tick, &least_order->scheduled_waiting_time, date_ticks_base, least_order->v, order, false, schdispatch_last_planned_dispatch)) {
|
||||
least_order->lateness = 0;
|
||||
}
|
||||
require_travel_time = true;
|
||||
@@ -826,7 +838,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
/* Make sure we don't try to get departures out of this order. */
|
||||
/* This is cheaper than deleting it from next_orders. */
|
||||
/* If we ever get to a state where _date * DAY_TICKS is close to INT_MAX, then we'll have other problems anyway as departures' scheduled dates will wrap around. */
|
||||
least_order->expected_date = INT32_MAX;
|
||||
least_order->expected_tick = INT32_MAX;
|
||||
}
|
||||
|
||||
/* The vehicle can't possibly have arrived at its next candidate departure yet. */
|
||||
@@ -838,15 +850,15 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
for (uint i = 0; i < next_orders.size(); ++i) {
|
||||
OrderDate *od = next_orders[i];
|
||||
|
||||
DateTicks lod = least_order->expected_date - least_order->lateness;
|
||||
DateTicks odd = od->expected_date - od->lateness;
|
||||
DateTicks lod = least_order->expected_tick - least_order->lateness;
|
||||
DateTicks odd = od->expected_tick - od->lateness;
|
||||
|
||||
if (type == D_ARRIVAL) {
|
||||
lod -= least_order->scheduled_waiting_time > 0 ? least_order->scheduled_waiting_time : least_order->order->GetWaitTime();
|
||||
odd -= od->scheduled_waiting_time > 0 ? od->scheduled_waiting_time : od->order->GetWaitTime();
|
||||
}
|
||||
|
||||
if (lod > odd && od->expected_date - od->lateness < max_date) {
|
||||
if (lod > odd && od->expected_tick - od->lateness < max_ticks) {
|
||||
least_order = od;
|
||||
}
|
||||
}
|
||||
@@ -864,7 +876,7 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
|
||||
return result;
|
||||
}
|
||||
|
||||
DateTicksScaled GetDeparturesMaxTicksAhead()
|
||||
Ticks GetDeparturesMaxTicksAhead()
|
||||
{
|
||||
if (_settings_time.time_in_minutes) {
|
||||
return _settings_client.gui.max_departure_time_minutes * _settings_time.ticks_per_minute;
|
||||
|
Reference in New Issue
Block a user