1
0
Fork 0

Codechange: Use economy dates for linkgraphs

pull/11588/head
Tyler Trahan 2023-04-29 12:02:28 -04:00
parent b08e2e0527
commit 6c95929831
9 changed files with 60 additions and 62 deletions

View File

@ -29,7 +29,7 @@ LinkGraph::BaseNode::BaseNode(TileIndex xy, StationID st, uint demand)
this->supply = 0;
this->demand = demand;
this->station = st;
this->last_update = CalendarTime::INVALID_DATE;
this->last_update = EconomyTime::INVALID_DATE;
}
/**
@ -40,8 +40,8 @@ LinkGraph::BaseEdge::BaseEdge(NodeID dest_node)
this->capacity = 0;
this->usage = 0;
this->travel_time_sum = 0;
this->last_unrestricted_update = CalendarTime::INVALID_DATE;
this->last_restricted_update = CalendarTime::INVALID_DATE;
this->last_unrestricted_update = EconomyTime::INVALID_DATE;
this->last_restricted_update = EconomyTime::INVALID_DATE;
this->dest_node = dest_node;
}
@ -50,22 +50,22 @@ LinkGraph::BaseEdge::BaseEdge(NodeID dest_node)
* This is useful if the date has been modified with the cheat menu.
* @param interval Number of days to be added or subtracted.
*/
void LinkGraph::ShiftDates(TimerGameCalendar::Date interval)
void LinkGraph::ShiftDates(TimerGameEconomy::Date interval)
{
this->last_compression += interval;
for (NodeID node1 = 0; node1 < this->Size(); ++node1) {
BaseNode &source = this->nodes[node1];
if (source.last_update != CalendarTime::INVALID_DATE) source.last_update += interval;
if (source.last_update != EconomyTime::INVALID_DATE) source.last_update += interval;
for (BaseEdge &edge : this->nodes[node1].edges) {
if (edge.last_unrestricted_update != CalendarTime::INVALID_DATE) edge.last_unrestricted_update += interval;
if (edge.last_restricted_update != CalendarTime::INVALID_DATE) edge.last_restricted_update += interval;
if (edge.last_unrestricted_update != EconomyTime::INVALID_DATE) edge.last_unrestricted_update += interval;
if (edge.last_restricted_update != EconomyTime::INVALID_DATE) edge.last_restricted_update += interval;
}
}
}
void LinkGraph::Compress()
{
this->last_compression = (TimerGameCalendar::date + this->last_compression).base() / 2;
this->last_compression = (TimerGameEconomy::date + this->last_compression).base() / 2;
for (NodeID node1 = 0; node1 < this->Size(); ++node1) {
this->nodes[node1].supply /= 2;
for (BaseEdge &edge : this->nodes[node1].edges) {
@ -89,8 +89,8 @@ void LinkGraph::Compress()
*/
void LinkGraph::Merge(LinkGraph *other)
{
TimerGameCalendar::Date age = TimerGameCalendar::date - this->last_compression + 1;
TimerGameCalendar::Date other_age = TimerGameCalendar::date - other->last_compression + 1;
TimerGameEconomy::Date age = TimerGameEconomy::date - this->last_compression + 1;
TimerGameEconomy::Date other_age = TimerGameEconomy::date - other->last_compression + 1;
NodeID first = this->Size();
for (NodeID node1 = 0; node1 < other->Size(); ++node1) {
Station *st = Station::Get(other->nodes[node1].station);
@ -172,8 +172,8 @@ void LinkGraph::BaseNode::AddEdge(NodeID to, uint capacity, uint usage, uint32_t
edge.capacity = capacity;
edge.usage = usage;
edge.travel_time_sum = static_cast<uint64_t>(travel_time) * capacity;
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = TimerGameCalendar::date;
if (mode & EUM_RESTRICTED) edge.last_restricted_update = TimerGameCalendar::date;
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = TimerGameEconomy::date;
if (mode & EUM_RESTRICTED) edge.last_restricted_update = TimerGameEconomy::date;
}
/**
@ -239,8 +239,8 @@ void LinkGraph::BaseEdge::Update(uint capacity, uint usage, uint32_t travel_time
}
this->usage = std::max(this->usage, usage);
}
if (mode & EUM_UNRESTRICTED) this->last_unrestricted_update = TimerGameCalendar::date;
if (mode & EUM_RESTRICTED) this->last_restricted_update = TimerGameCalendar::date;
if (mode & EUM_UNRESTRICTED) this->last_unrestricted_update = TimerGameEconomy::date;
if (mode & EUM_RESTRICTED) this->last_restricted_update = TimerGameEconomy::date;
}
/**

View File

@ -13,7 +13,7 @@
#include "../core/pool_type.hpp"
#include "../station_base.h"
#include "../cargotype.h"
#include "../timer/timer_game_calendar.h"
#include "../timer/timer_game_economy.h"
#include "../saveload/saveload.h"
#include "linkgraph_type.h"
#include <utility>
@ -43,8 +43,8 @@ public:
uint capacity; ///< Capacity of the link.
uint usage; ///< Usage of the link.
uint64_t travel_time_sum; ///< Sum of the travel times of the link, in ticks.
TimerGameCalendar::Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
TimerGameCalendar::Date last_restricted_update; ///< When the restricted part of the link was last updated.
TimerGameEconomy::Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
TimerGameEconomy::Date last_restricted_update; ///< When the restricted part of the link was last updated.
NodeID dest_node; ///< Destination of the edge.
BaseEdge(NodeID dest_node = INVALID_NODE);
@ -59,11 +59,11 @@ public:
* Get the date of the last update to any part of the edge's capacity.
* @return Last update.
*/
TimerGameCalendar::Date LastUpdate() const { return std::max(this->last_unrestricted_update, this->last_restricted_update); }
TimerGameEconomy::Date LastUpdate() const { return std::max(this->last_unrestricted_update, this->last_restricted_update); }
void Update(uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode);
void Restrict() { this->last_unrestricted_update = CalendarTime::INVALID_DATE; }
void Release() { this->last_restricted_update = CalendarTime::INVALID_DATE; }
void Restrict() { this->last_unrestricted_update = EconomyTime::INVALID_DATE; }
void Release() { this->last_restricted_update = EconomyTime::INVALID_DATE; }
/** Comparison operator based on \c dest_node. */
bool operator <(const BaseEdge &rhs) const
@ -92,7 +92,7 @@ public:
uint demand; ///< Acceptance at the station.
StationID station; ///< Station ID.
TileIndex xy; ///< Location of the station referred to by the node.
TimerGameCalendar::Date last_update; ///< When the supply was last updated.
TimerGameEconomy::Date last_update; ///< When the supply was last updated.
std::vector<BaseEdge> edges; ///< Sorted list of outgoing edges from this node.
@ -105,7 +105,7 @@ public:
void UpdateSupply(uint supply)
{
this->supply += supply;
this->last_update = TimerGameCalendar::date;
this->last_update = TimerGameEconomy::date;
}
/**
@ -170,10 +170,10 @@ public:
static const uint MIN_TIMEOUT_DISTANCE = 32;
/** Number of days before deleting links served only by vehicles stopped in depot. */
static constexpr TimerGameCalendar::Date STALE_LINK_DEPOT_TIMEOUT = 1024;
static constexpr TimerGameEconomy::Date STALE_LINK_DEPOT_TIMEOUT = 1024;
/** Minimum number of days between subsequent compressions of a LG. */
static constexpr TimerGameCalendar::Date COMPRESSION_INTERVAL = 256;
static constexpr TimerGameEconomy::Date COMPRESSION_INTERVAL = 256;
/**
* Scale a value from a link graph of age orig_age for usage in one of age
@ -183,7 +183,7 @@ public:
* @param orig_age Age of the original link graph.
* @return scaled value.
*/
inline static uint Scale(uint val, TimerGameCalendar::Date target_age, TimerGameCalendar::Date orig_age)
inline static uint Scale(uint val, TimerGameEconomy::Date target_age, TimerGameEconomy::Date orig_age)
{
return val > 0 ? std::max(1U, val * target_age.base() / orig_age.base()) : 0;
}
@ -194,10 +194,10 @@ public:
* Real constructor.
* @param cargo Cargo the link graph is about.
*/
LinkGraph(CargoID cargo) : cargo(cargo), last_compression(TimerGameCalendar::date) {}
LinkGraph(CargoID cargo) : cargo(cargo), last_compression(TimerGameEconomy::date) {}
void Init(uint size);
void ShiftDates(TimerGameCalendar::Date interval);
void ShiftDates(TimerGameEconomy::Date interval);
void Compress();
void Merge(LinkGraph *other);
@ -233,7 +233,7 @@ public:
* Get date of last compression.
* @return Date of last compression.
*/
inline TimerGameCalendar::Date LastCompression() const { return this->last_compression; }
inline TimerGameEconomy::Date LastCompression() const { return this->last_compression; }
/**
* Get the cargo ID this component's link graph refers to.
@ -248,7 +248,7 @@ public:
*/
inline uint Monthly(uint base) const
{
return base * 30 / (TimerGameCalendar::date - this->last_compression + 1).base();
return base * 30 / (TimerGameEconomy::date - this->last_compression + 1).base();
}
NodeID AddNode(const Station *st);
@ -262,7 +262,7 @@ protected:
friend class LinkGraphJob;
CargoID cargo; ///< Cargo of this component's link graph.
TimerGameCalendar::Date last_compression; ///< Last time the capacities and supplies were compressed.
TimerGameEconomy::Date last_compression; ///< Last time the capacities and supplies were compressed.
NodeVector nodes; ///< Nodes in the component.
};

View File

@ -37,7 +37,7 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig) :
* This is on purpose. */
link_graph(orig),
settings(_settings_game.linkgraph),
join_date(TimerGameCalendar::date + (_settings_game.linkgraph.recalc_time / CalendarTime::SECONDS_PER_DAY)),
join_date(TimerGameEconomy::date + (_settings_game.linkgraph.recalc_time / EconomyTime::SECONDS_PER_DAY)),
job_completed(false),
job_aborted(false)
{
@ -131,14 +131,14 @@ LinkGraphJob::~LinkGraphJob()
if (st2 == nullptr || st2->goods[this->Cargo()].link_graph != this->link_graph.index ||
st2->goods[this->Cargo()].node != dest_id ||
!(*lg)[node_id].HasEdgeTo(dest_id) ||
(*lg)[node_id][dest_id].LastUpdate() == CalendarTime::INVALID_DATE) {
(*lg)[node_id][dest_id].LastUpdate() == EconomyTime::INVALID_DATE) {
/* Edge has been removed. Delete flows. */
StationIDStack erased = flows.DeleteFlows(to);
/* Delete old flows for source stations which have been deleted
* from the new flows. This avoids flow cycles between old and
* new flows. */
while (!erased.IsEmpty()) ge.flows.erase(erased.Pop());
} else if ((*lg)[node_id][dest_id].last_unrestricted_update == CalendarTime::INVALID_DATE) {
} else if ((*lg)[node_id][dest_id].last_unrestricted_update == EconomyTime::INVALID_DATE) {
/* Edge is fully restricted. */
flows.RestrictFlows(to);
}

View File

@ -163,7 +163,7 @@ protected:
const LinkGraph link_graph; ///< Link graph to by analyzed. Is copied when job is started and mustn't be modified later.
const LinkGraphSettings settings; ///< Copy of _settings_game.linkgraph at spawn time.
std::thread thread; ///< Thread the job is running in or a default-constructed thread if it's running in the main thread.
TimerGameCalendar::Date join_date; ///< Date when the job is to be joined.
TimerGameEconomy::Date join_date; ///< Date when the job is to be joined.
NodeAnnotationVector nodes; ///< Extra node data necessary for link graph calculation.
std::atomic<bool> job_completed; ///< Is the job still running. This is accessed by multiple threads and reads may be stale.
std::atomic<bool> job_aborted; ///< Has the job been aborted. This is accessed by multiple threads and reads may be stale.
@ -178,7 +178,7 @@ public:
* settings have to be brutally const-casted in order to populate them.
*/
LinkGraphJob() : settings(_settings_game.linkgraph),
join_date(CalendarTime::INVALID_DATE), job_completed(false), job_aborted(false) {}
join_date(EconomyTime::INVALID_DATE), job_completed(false), job_aborted(false) {}
LinkGraphJob(const LinkGraph &orig);
~LinkGraphJob();
@ -211,19 +211,19 @@ public:
* Check if job is supposed to be finished.
* @return True if job should be finished by now, false if not.
*/
inline bool IsScheduledToBeJoined() const { return this->join_date <= TimerGameCalendar::date; }
inline bool IsScheduledToBeJoined() const { return this->join_date <= TimerGameEconomy::date; }
/**
* Get the date when the job should be finished.
* @return Join date.
*/
inline TimerGameCalendar::Date JoinDate() const { return join_date; }
inline TimerGameEconomy::Date JoinDate() const { return join_date; }
/**
* Change the join date on date cheating.
* @param interval Number of days to add.
*/
inline void ShiftJoinDate(TimerGameCalendar::Date interval) { this->join_date += interval; }
inline void ShiftJoinDate(TimerGameEconomy::Date interval) { this->join_date += interval; }
/**
* Get the link graph settings for this component.
@ -254,7 +254,7 @@ public:
* Get the date when the underlying link graph was last compressed.
* @return Compression date.
*/
inline TimerGameCalendar::Date LastCompression() const { return this->link_graph.LastCompression(); }
inline TimerGameEconomy::Date LastCompression() const { return this->link_graph.LastCompression(); }
/**
* Get the ID of the underlying link graph.

View File

@ -132,7 +132,7 @@ void LinkGraphSchedule::SpawnAll()
* graph jobs by the number of days given.
* @param interval Number of days to be added or subtracted.
*/
void LinkGraphSchedule::ShiftDates(TimerGameCalendar::Date interval)
void LinkGraphSchedule::ShiftDates(TimerGameEconomy::Date interval)
{
for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(interval);
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) lgj->ShiftJoinDate(interval);
@ -163,10 +163,10 @@ LinkGraphSchedule::~LinkGraphSchedule()
}
/**
* Pause the game if in 2 TimerGameCalendar::date_fract ticks, we would do a join with the next
* Pause the game if in 2 TimerGameEconomy::date_fract ticks, we would do a join with the next
* link graph job, but it is still running.
* The check is done 2 TimerGameCalendar::date_fract ticks early instead of 1, as in multiplayer
* calls to DoCommandP are executed after a delay of 1 TimerGameCalendar::date_fract tick.
* The check is done 2 TimerGameEconomy::date_fract ticks early instead of 1, as in multiplayer
* calls to DoCommandP are executed after a delay of 1 TimerGameEconomy::date_fract tick.
* If we previously paused, unpause if the job is now ready to be joined with.
*/
void StateGameLoop_LinkGraphPauseControl()
@ -177,10 +177,10 @@ void StateGameLoop_LinkGraphPauseControl()
Command<CMD_PAUSE>::Post(PM_PAUSED_LINK_GRAPH, false);
}
} else if (_pause_mode == PM_UNPAUSED &&
TimerGameCalendar::date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 &&
TimerGameCalendar::date.base() % (_settings_game.linkgraph.recalc_interval / CalendarTime::SECONDS_PER_DAY) == (_settings_game.linkgraph.recalc_interval / CalendarTime::SECONDS_PER_DAY) / 2 &&
TimerGameEconomy::date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 &&
TimerGameEconomy::date.base() % (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY) == (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY) / 2 &&
LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) {
/* Perform check two TimerGameCalendar::date_fract ticks before we would join, to make
/* Perform check two TimerGameEconomy::date_fract ticks before we would join, to make
* sure it also works in multiplayer. */
Command<CMD_PAUSE>::Post(PM_PAUSED_LINK_GRAPH, true);
}
@ -204,11 +204,11 @@ void AfterLoad_LinkGraphPauseControl()
*/
void OnTick_LinkGraph()
{
if (TimerGameCalendar::date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK) return;
TimerGameCalendar::Date offset = TimerGameCalendar::date.base() % (_settings_game.linkgraph.recalc_interval / CalendarTime::SECONDS_PER_DAY);
if (TimerGameEconomy::date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK) return;
TimerGameEconomy::Date offset = TimerGameEconomy::date.base() % (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY);
if (offset == 0) {
LinkGraphSchedule::instance.SpawnNext();
} else if (offset == (_settings_game.linkgraph.recalc_interval / CalendarTime::SECONDS_PER_DAY) / 2) {
} else if (offset == (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY) / 2) {
if (!_networking || _network_server) {
PerformanceMeasurer::SetInactive(PFE_GL_LINKGRAPH);
LinkGraphSchedule::instance.JoinNext();

View File

@ -58,7 +58,7 @@ public:
bool IsJoinWithUnfinishedJobDue() const;
void JoinNext();
void SpawnAll();
void ShiftDates(TimerGameCalendar::Date interval);
void ShiftDates(TimerGameEconomy::Date interval);
/**
* Queue a link graph for execution.

View File

@ -105,7 +105,7 @@ Station::~Station()
for (NodeID node = 0; node < lg->Size(); ++node) {
Station *st = Station::Get((*lg)[node].station);
st->goods[c].flows.erase(this->index);
if ((*lg)[node].HasEdgeTo(this->goods[c].node) && (*lg)[node][this->goods[c].node].LastUpdate() != CalendarTime::INVALID_DATE) {
if ((*lg)[node].HasEdgeTo(this->goods[c].node) && (*lg)[node][this->goods[c].node].LastUpdate() != EconomyTime::INVALID_DATE) {
st->goods[c].flows.DeleteFlows(this->index);
RerouteCargo(st, c, this->index, st->index);
}

View File

@ -3813,9 +3813,9 @@ void DeleteStaleLinks(Station *from)
for (Edge &edge : (*lg)[ge.node].edges) {
Station *to = Station::Get((*lg)[edge.dest_node].station);
assert(to->goods[c].node == edge.dest_node);
assert(TimerGameCalendar::date >= edge.LastUpdate());
auto timeout = TimerGameCalendar::Date(LinkGraph::MIN_TIMEOUT_DISTANCE + (DistanceManhattan(from->xy, to->xy) >> 3));
if (TimerGameCalendar::date - edge.LastUpdate() > timeout) {
assert(TimerGameEconomy::date >= edge.LastUpdate());
auto timeout = TimerGameEconomy::Date(LinkGraph::MIN_TIMEOUT_DISTANCE + (DistanceManhattan(from->xy, to->xy) >> 3));
if (TimerGameEconomy::date - edge.LastUpdate() > timeout) {
bool updated = false;
if (auto_distributed) {
@ -3843,10 +3843,10 @@ void DeleteStaleLinks(Station *from)
while (iter != vehicles.end()) {
Vehicle *v = *iter;
/* Do not refresh links of vehicles that have been stopped in depot for a long time. */
if (!v->IsStoppedInDepot() || TimerGameCalendar::date - v->date_of_last_service <= LinkGraph::STALE_LINK_DEPOT_TIMEOUT) {
if (!v->IsStoppedInDepot() || TimerGameEconomy::date - v->date_of_last_service <= LinkGraph::STALE_LINK_DEPOT_TIMEOUT) {
LinkRefresher::Run(v, false); // Don't allow merging. Otherwise lg might get deleted.
}
if (edge.LastUpdate() == TimerGameCalendar::date) {
if (edge.LastUpdate() == TimerGameEconomy::date) {
updated = true;
break;
}
@ -3869,19 +3869,19 @@ void DeleteStaleLinks(Station *from)
ge.flows.DeleteFlows(to->index);
RerouteCargo(from, c, to->index, from->index);
}
} else if (edge.last_unrestricted_update != CalendarTime::INVALID_DATE && TimerGameCalendar::date - edge.last_unrestricted_update > timeout) {
} else if (edge.last_unrestricted_update != EconomyTime::INVALID_DATE && TimerGameEconomy::date - edge.last_unrestricted_update > timeout) {
edge.Restrict();
ge.flows.RestrictFlows(to->index);
RerouteCargo(from, c, to->index, from->index);
} else if (edge.last_restricted_update != CalendarTime::INVALID_DATE && TimerGameCalendar::date - edge.last_restricted_update > timeout) {
} else if (edge.last_restricted_update != EconomyTime::INVALID_DATE && TimerGameEconomy::date - edge.last_restricted_update > timeout) {
edge.Release();
}
}
/* Remove dead edges. */
for (NodeID r : to_remove) (*lg)[ge.node].RemoveEdge(r);
assert(TimerGameCalendar::date >= lg->LastCompression());
if (TimerGameCalendar::date - lg->LastCompression() > LinkGraph::COMPRESSION_INTERVAL) {
assert(TimerGameEconomy::date >= lg->LastCompression());
if (TimerGameEconomy::date - lg->LastCompression() > LinkGraph::COMPRESSION_INTERVAL) {
lg->Compress();
}
}

View File

@ -15,7 +15,6 @@
#include "timer.h"
#include "timer_game_calendar.h"
#include "../vehicle_base.h"
#include "../linkgraph/linkgraph.h"
#include "../safeguards.h"
@ -114,7 +113,6 @@ void TimerManager<TimerGameCalendar>::Elapsed([[maybe_unused]] TimerGameCalendar
TimerGameCalendar::year--;
days_this_year = TimerGameCalendar::IsLeapYear(TimerGameCalendar::year) ? CalendarTime::DAYS_IN_LEAP_YEAR : CalendarTime::DAYS_IN_YEAR;
TimerGameCalendar::date -= days_this_year;
for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year);
}
}