Changeset - r21529:6bf3ee37953c
[Not reviewed]
master
0 7 0
fonsinchen - 10 years ago 2014-06-14 13:35:39
fonsinchen@openttd.org
(svn r26646) -Fix [FS#6041]: Save locations instead of distances in link graphs to reduce size.
7 files changed with 71 insertions and 52 deletions:
0 comments (0 inline, 0 general)
src/linkgraph/demands.cpp
Show inline comments
 
@@ -210,7 +210,8 @@ void DemandCalculator::CalcDemand(LinkGr
 

	
 
			/* Scale the distance by mod_dist around max_distance */
 
			int32 distance = this->max_distance - (this->max_distance -
 
					(int32)job[from_id][to_id].Distance()) * this->mod_dist / 100;
 
					(int32)DistanceMaxPlusManhattan(job[from_id].XY(), job[to_id].XY())) *
 
					this->mod_dist / 100;
 

	
 
			/* Scale the accuracy by distance around accuracy / 2 */
 
			int32 divisor = this->accuracy * (this->mod_dist - 50) / 100 +
src/linkgraph/linkgraph.cpp
Show inline comments
 
@@ -21,11 +21,13 @@ INSTANTIATE_POOL_METHODS(LinkGraph)
 

	
 
/**
 
 * Create a node or clear it.
 
 * @param xy Location of the associated station.
 
 * @param st ID of the associated station.
 
 * @param demand Demand for cargo at the station.
 
 */
 
inline void LinkGraph::BaseNode::Init(StationID st, uint demand)
 
inline void LinkGraph::BaseNode::Init(TileIndex xy, StationID st, uint demand)
 
{
 
	this->xy = xy;
 
	this->supply = 0;
 
	this->demand = demand;
 
	this->station = st;
 
@@ -34,11 +36,9 @@ inline void LinkGraph::BaseNode::Init(St
 

	
 
/**
 
 * Create an edge.
 
 * @param distance Length of the link as manhattan distance.
 
 */
 
inline void LinkGraph::BaseEdge::Init(uint distance)
 
inline void LinkGraph::BaseEdge::Init()
 
{
 
	this->distance = distance;
 
	this->capacity = 0;
 
	this->usage = 0;
 
	this->last_unrestricted_update = INVALID_DATE;
 
@@ -147,21 +147,6 @@ void LinkGraph::RemoveNode(NodeID id)
 
}
 

	
 
/**
 
 * Update distances between the given node and all others.
 
 * @param id Node that changed position.
 
 * @param xy New position of the node.
 
 */
 
void LinkGraph::UpdateDistances(NodeID id, TileIndex xy)
 
{
 
	assert(id < this->Size());
 
	for (NodeID other = 0; other < this->Size(); ++other) {
 
		if (other == id) continue;
 
		this->edges[id][other].distance = this->edges[other][id].distance =
 
				DistanceMaxPlusManhattan(xy, Station::Get(this->nodes[other].station)->xy);
 
	}
 
}
 

	
 
/**
 
 * Add a node to the component and create empty edges associated with it. Set
 
 * the station's last_component to this component. Calculate the distances to all
 
 * other nodes. The distances to _all_ nodes are important as the demand
 
@@ -180,7 +165,7 @@ NodeID LinkGraph::AddNode(const Station 
 
	this->edges.Resize(new_node + 1U,
 
			max(new_node + 1U, this->edges.Height()));
 

	
 
	this->nodes[new_node].Init(st->index,
 
	this->nodes[new_node].Init(st->xy, st->index,
 
			HasBit(good.status, GoodsEntry::GES_ACCEPTANCE));
 

	
 
	BaseEdge *new_edges = this->edges[new_node];
 
@@ -189,9 +174,8 @@ NodeID LinkGraph::AddNode(const Station 
 
	new_edges[new_node].next_edge = INVALID_NODE;
 

	
 
	for (NodeID i = 0; i <= new_node; ++i) {
 
		uint distance = DistanceMaxPlusManhattan(st->xy, Station::Get(this->nodes[i].station)->xy);
 
		new_edges[i].Init(distance);
 
		this->edges[i][new_node].Init(distance);
 
		new_edges[i].Init();
 
		this->edges[i][new_node].Init();
 
	}
 
	return new_node;
 
}
src/linkgraph/linkgraph.h
Show inline comments
 
@@ -49,8 +49,9 @@ public:
 
		uint supply;             ///< Supply at the station.
 
		uint demand;             ///< Acceptance at the station.
 
		StationID station;       ///< Station ID.
 
		TileIndex xy;            ///< Location of the station referred to by the node.
 
		Date last_update;        ///< When the supply was last updated.
 
		void Init(StationID st = INVALID_STATION, uint demand = 0);
 
		void Init(TileIndex xy = INVALID_TILE, StationID st = INVALID_STATION, uint demand = 0);
 
	};
 

	
 
	/**
 
@@ -60,13 +61,12 @@ public:
 
	 * the column as next_edge.
 
	 */
 
	struct BaseEdge {
 
		uint distance;                 ///< Length of the link.
 
		uint capacity;                 ///< Capacity of the link.
 
		uint usage;                    ///< Usage of the link.
 
		Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
 
		Date last_restricted_update;   ///< When the restricted part of the link was last updated.
 
		NodeID next_edge;              ///< Destination of next valid edge starting at the same source node.
 
		void Init(uint distance = 0);
 
		void Init();
 
	};
 

	
 
	/**
 
@@ -99,12 +99,6 @@ public:
 
		uint Usage() const { return this->edge.usage; }
 

	
 
		/**
 
		 * Get edge's distance.
 
		 * @return Distance.
 
		 */
 
		uint Distance() const { return this->edge.distance; }
 

	
 
		/**
 
		 * Get the date of the last update to the edge's unrestricted capacity.
 
		 * @return Last update.
 
		 */
 
@@ -169,6 +163,12 @@ public:
 
		 * @return Last update.
 
		 */
 
		Date LastUpdate() const { return this->node.last_update; }
 

	
 
		/**
 
		 * Get the location of the station associated with the node.
 
		 * @return Location of the station.
 
		 */
 
		TileIndex XY() const { return this->node.xy; }
 
	};
 

	
 
	/**
 
@@ -413,6 +413,15 @@ public:
 
		}
 

	
 
		/**
 
		 * Update the node's location on the map.
 
		 * @param xy New location.
 
		 */
 
		void UpdateLocation(TileIndex xy)
 
		{
 
			this->node.xy = xy;
 
		}
 

	
 
		/**
 
		 * Set the node's demand.
 
		 * @param demand New demand for the node.
 
		 */
 
@@ -513,7 +522,6 @@ public:
 

	
 
	NodeID AddNode(const Station *st);
 
	void RemoveNode(NodeID id);
 
	void UpdateDistances(NodeID id, TileIndex xy);
 

	
 
protected:
 
	friend class LinkGraph::ConstNode;
src/linkgraph/mcf.cpp
Show inline comments
 
@@ -259,7 +259,6 @@ void MultiCommodityFlow::Dijkstra(NodeID
 
		for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) {
 
			if (to == from) continue; // Not a real edge but a consumption sign.
 
			Edge edge = this->job[from][to];
 
			assert(edge.Distance() < UINT_MAX);
 
			uint capacity = edge.Capacity();
 
			if (this->max_saturation != UINT_MAX) {
 
				capacity *= this->max_saturation;
 
@@ -267,7 +266,7 @@ void MultiCommodityFlow::Dijkstra(NodeID
 
				if (capacity == 0) capacity = 1;
 
			}
 
			/* punish in-between stops a little */
 
			uint distance = edge.Distance() + 1;
 
			uint distance = DistanceMaxPlusManhattan(this->job[from].XY(), this->job[to].XY()) + 1;
 
			Tannotation *dest = static_cast<Tannotation *>(paths[to]);
 
			if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance)) {
 
				annos.erase(dest);
src/saveload/linkgraph_sl.cpp
Show inline comments
 
@@ -109,24 +109,25 @@ const SaveLoad *GetLinkGraphScheduleDesc
 
 * SaveLoad desc for a link graph node.
 
 */
 
static const SaveLoad _node_desc[] = {
 
	SLE_VAR(Node, supply,      SLE_UINT32),
 
	SLE_VAR(Node, demand,      SLE_UINT32),
 
	SLE_VAR(Node, station,     SLE_UINT16),
 
	SLE_VAR(Node, last_update, SLE_INT32),
 
	SLE_END()
 
	SLE_CONDVAR(Node, xy,          SLE_UINT32, 191, SL_MAX_VERSION),
 
	    SLE_VAR(Node, supply,      SLE_UINT32),
 
	    SLE_VAR(Node, demand,      SLE_UINT32),
 
	    SLE_VAR(Node, station,     SLE_UINT16),
 
	    SLE_VAR(Node, last_update, SLE_INT32),
 
	    SLE_END()
 
};
 

	
 
/**
 
 * SaveLoad desc for a link graph edge.
 
 */
 
static const SaveLoad _edge_desc[] = {
 
	    SLE_VAR(Edge, distance,                 SLE_UINT32),
 
	    SLE_VAR(Edge, capacity,                 SLE_UINT32),
 
	    SLE_VAR(Edge, usage,                    SLE_UINT32),
 
	    SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
 
	SLE_CONDVAR(Edge, last_restricted_update,   SLE_INT32, 187, SL_MAX_VERSION),
 
	    SLE_VAR(Edge, next_edge,                SLE_UINT16),
 
	    SLE_END()
 
	SLE_CONDNULL(4, 0, 190), // distance
 
	     SLE_VAR(Edge, capacity,                 SLE_UINT32),
 
	     SLE_VAR(Edge, usage,                    SLE_UINT32),
 
	     SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
 
	 SLE_CONDVAR(Edge, last_restricted_update,   SLE_INT32, 187, SL_MAX_VERSION),
 
	     SLE_VAR(Edge, next_edge,                SLE_UINT16),
 
	     SLE_END()
 
};
 

	
 
/**
 
@@ -139,8 +140,16 @@ void SaveLoad_LinkGraph(LinkGraph &lg)
 
	for (NodeID from = 0; from < size; ++from) {
 
		Node *node = &lg.nodes[from];
 
		SlObject(node, _node_desc);
 
		for (NodeID to = 0; to < size; ++to) {
 
			SlObject(&lg.edges[from][to], _edge_desc);
 
		if (IsSavegameVersionBefore(191)) {
 
			/* We used to save the full matrix ... */
 
			for (NodeID to = 0; to < size; ++to) {
 
				SlObject(&lg.edges[from][to], _edge_desc);
 
			}
 
		} else {
 
			/* ... but as that wasted a lot of space we save a sparse matrix now. */
 
			for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) {
 
				SlObject(&lg.edges[from][to], _edge_desc);
 
			}
 
		}
 
	}
 
}
 
@@ -220,6 +229,23 @@ static void Load_LGRS()
 
 */
 
void AfterLoadLinkGraphs()
 
{
 
	if (IsSavegameVersionBefore(191)) {
 
		LinkGraph *lg;
 
		FOR_ALL_LINK_GRAPHS(lg) {
 
			for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
 
				(*lg)[node_id].UpdateLocation(Station::Get((*lg)[node_id].Station())->xy);
 
			}
 
		}
 

	
 
		LinkGraphJob *lgj;
 
		FOR_ALL_LINK_GRAPH_JOBS(lgj) {
 
			lg = &(const_cast<LinkGraph &>(lgj->Graph()));
 
			for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
 
				(*lg)[node_id].UpdateLocation(Station::Get((*lg)[node_id].Station())->xy);
 
			}
 
		}
 
	}
 

	
 
	LinkGraphSchedule::Instance()->SpawnAll();
 
}
 

	
src/saveload/saveload.cpp
Show inline comments
 
@@ -258,8 +258,9 @@
 
 *  188   26169   1.4.x
 
 *  189   26450
 
 *  190   26547
 
 *  191   26646
 
 */
 
extern const uint16 SAVEGAME_VERSION = 190; ///< Current savegame version of OpenTTD.
 
extern const uint16 SAVEGAME_VERSION = 191; ///< Current savegame version of OpenTTD.
 

	
 
SavegameType _savegame_type; ///< type of savegame we are loading
 

	
src/station_cmd.cpp
Show inline comments
 
@@ -649,7 +649,7 @@ static void UpdateStationSignCoord(BaseS
 
	for (CargoID c = 0; c < NUM_CARGO; ++c) {
 
		LinkGraphID lg = full_station->goods[c].link_graph;
 
		if (!LinkGraph::IsValidID(lg)) continue;
 
		LinkGraph::Get(lg)->UpdateDistances(full_station->goods[c].node, st->xy);
 
		(*LinkGraph::Get(lg))[full_station->goods[c].node].UpdateLocation(st->xy);
 
	}
 
}
 

	
0 comments (0 inline, 0 general)