linkgraph_sl.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "../linkgraph/linkgraph.h"
00013 #include "../linkgraph/demands.h"
00014 #include "../settings_internal.h"
00015 #include "saveload.h"
00016 #include <vector>
00017 
00018 const SettingDesc *GetSettingDescription(uint index);
00019 
00029 const SaveLoad *GetLinkGraphDesc()
00030 {
00031   static std::vector<SaveLoad> saveloads;
00032   static const char *prefix = "linkgraph.";
00033 
00034   /* Build the SaveLoad array on first call and don't touch it later on */
00035   if (saveloads.empty()) {
00036     size_t offset_gamesettings = cpp_offsetof(GameSettings, linkgraph);
00037     size_t offset_component = cpp_offsetof(LinkGraph, settings);
00038 
00039     size_t prefixlen = strlen(prefix);
00040 
00041     int setting = 0;
00042     const SettingDesc *desc = GetSettingDescription(setting);
00043     while (desc->save.cmd != SL_END) {
00044       if (desc->desc.name != NULL && strncmp(desc->desc.name, prefix, prefixlen) == 0) {
00045         SaveLoad sl = desc->save;
00046         char *&address = reinterpret_cast<char *&>(sl.address);
00047         address -= offset_gamesettings;
00048         address += offset_component;
00049         saveloads.push_back(sl);
00050       }
00051       desc = GetSettingDescription(++setting);
00052     }
00053 
00054     const SaveLoad component_desc[] = {
00055       SLE_CONDVAR(LinkGraph, num_nodes,          SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00056       SLE_CONDVAR(LinkGraph, index,              SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
00057       SLE_CONDVAR(LinkGraph, current_station_id, SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
00058       SLE_CONDVAR(LinkGraph, cargo,              SLE_UINT8,  SL_COMPONENTS, SL_MAX_VERSION),
00059       SLE_END()
00060     };
00061 
00062     int i = 0;
00063     do {
00064       saveloads.push_back(component_desc[i++]);
00065     } while (saveloads.back().cmd != SL_END);
00066   }
00067 
00068   return &saveloads[0];
00069 }
00070 
00071 /* Edges and nodes are saved in the correct order, so we don't need to save their ids. */
00072 
00076 static const SaveLoad _node_desc[] = {
00077    SLE_CONDVAR(Node, supply,    SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00078    SLE_CONDVAR(Node, demand,    SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00079    SLE_CONDVAR(Node, station,   SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
00080    SLE_END()
00081 };
00082 
00086 static const SaveLoad _edge_desc[] = {
00087    SLE_CONDVAR(Edge, distance,  SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00088    SLE_CONDVAR(Edge, capacity,  SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00089    SLE_CONDVAR(Edge, next_edge, SLE_UINT32,        SL_MCF, SL_MAX_VERSION),
00090    SLE_END()
00091 };
00092 
00097 static void SaveLoad_LinkGraphComponent(LinkGraphComponent &comp)
00098 {
00099   uint size = comp.GetSize();
00100   for (NodeID from = 0; from < size; ++from) {
00101     Node *node = &comp.GetNode(from);
00102     SlObject(node, _node_desc);
00103     for (NodeID to = 0; to < size; ++to) {
00104       SlObject(&comp.GetEdge(from, to), _edge_desc);
00105     }
00106   }
00107 }
00108 
00112 static void DoSave_LGRP(void *)
00113 {
00114   for (CargoID cargo = 0; cargo < NUM_CARGO; ++cargo) {
00115     LinkGraph &graph = _link_graphs[cargo];
00116     SlObject(&graph, GetLinkGraphDesc());
00117     SaveLoad_LinkGraphComponent(graph);
00118   }
00119 }
00120 
00124 static void Load_LGRP()
00125 {
00126   for (CargoID cargo = 0; cargo < NUM_CARGO; ++cargo) {
00127     LinkGraph &graph = _link_graphs[cargo];
00128     assert(graph.GetSize() == 0);
00129     SlObject(&graph, GetLinkGraphDesc());
00130     graph.SetSize();
00131     SaveLoad_LinkGraphComponent(graph);
00132     for (uint i = 0; i < graph.GetSize(); ++i) {
00133       Node &node = graph.GetNode(i);
00134       node.undelivered_supply = node.supply;
00135     }
00136   }
00137 }
00138 
00143 void AfterLoadLinkGraphs()
00144 {
00145   for (CargoID cargo = 0; cargo < NUM_CARGO; ++cargo) {
00146     LinkGraph &graph = _link_graphs[cargo];
00147     if (graph.GetSize() > 0) graph.SpawnThread();
00148   }
00149 }
00150 
00151 static void Save_LGRP() {
00152   SlAutolength((AutolengthProc*)DoSave_LGRP, NULL);
00153 }
00154 
00155 extern const ChunkHandler _linkgraph_chunk_handlers[] = {
00156   { 'LGRP', Save_LGRP, Load_LGRP, NULL, NULL, CH_LAST},
00157 };