# 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 };