# 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 "../stdafx.h"
    00013 #include "../linkgraph/linkgraph.h"
    00014 #include "../linkgraph/demands.h"
    00015 #include "../settings_internal.h"
    00016 #include "saveload.h"
    00017 #include <vector>
    00018
    00019 const SettingDesc *GetSettingDescription(uint index);
    00020
    00030 const SaveLoad *GetLinkGraphDesc()
    00031 {
    00032   static std::vector<SaveLoad> saveloads;
    00033   static const char *prefix = "linkgraph.";
    00034
    00035   /* Build the SaveLoad array on first call and don't touch it later on */
    00036   if (saveloads.empty()) {
    00037     size_t offset_gamesettings = cpp_offsetof(GameSettings, linkgraph);
    00038     size_t offset_component = cpp_offsetof(LinkGraph, settings);
    00039
    00040     size_t prefixlen = strlen(prefix);
    00041
    00042     int setting = 0;
    00043     const SettingDesc *desc = GetSettingDescription(setting);
    00044     while (desc->save.cmd != SL_END) {
    00045       if (desc->desc.name != NULL && strncmp(desc->desc.name, prefix, prefixlen) == 0) {
    00046         SaveLoad sl = desc->save;
    00047         char *&address = reinterpret_cast<char *&>(sl.address);
    00048         address -= offset_gamesettings;
    00049         address += offset_component;
    00050         saveloads.push_back(sl);
    00051       }
    00052       desc = GetSettingDescription(++setting);
    00053     }
    00054
    00055     const SaveLoad component_desc[] = {
    00056       SLE_CONDVAR(LinkGraph, num_nodes,          SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
    00057       SLE_CONDVAR(LinkGraph, index,              SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
    00058       SLE_CONDVAR(LinkGraph, current_station_id, SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
    00059       SLE_CONDVAR(LinkGraph, cargo,              SLE_UINT8,  SL_COMPONENTS, SL_MAX_VERSION),
    00060       SLE_END()
    00061     };
    00062
    00063     int i = 0;
    00064     do {
    00065       saveloads.push_back(component_desc[i++]);
    00066     } while (saveloads.back().cmd != SL_END);
    00067   }
    00068
    00069   return &saveloads[0];
    00070 }
    00071
    00072 /* Edges and nodes are saved in the correct order, so we don't need to save their ids. */
    00073
    00077 static const SaveLoad _node_desc[] = {
    00078    SLE_CONDVAR(Node, supply,    SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
    00079    SLE_CONDVAR(Node, demand,    SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
    00080    SLE_CONDVAR(Node, station,   SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
    00081    SLE_END()
    00082 };
    00083
    00087 static const SaveLoad _edge_desc[] = {
    00088    SLE_CONDVAR(Edge, distance,  SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
    00089    SLE_CONDVAR(Edge, capacity,  SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
    00090    SLE_CONDVAR(Edge, next_edge, SLE_UINT32,        SL_MCF, SL_MAX_VERSION),
    00091    SLE_END()
    00092 };
    00093
    00098 static void SaveLoad_LinkGraphComponent(LinkGraphComponent &comp)
    00099 {
    00100   uint size = comp.GetSize();
    00101   for (NodeID from = 0; from < size; ++from) {
    00102     Node *node = &comp.GetNode(from);
    00103     SlObject(node, _node_desc);
    00104     for (NodeID to = 0; to < size; ++to) {
    00105       SlObject(&comp.GetEdge(from, to), _edge_desc);
    00106     }
    00107   }
    00108 }
    00109
    00113 static void DoSave_LGRP(void *)
    00114 {
    00115   for (CargoID cargo = 0; cargo < NUM_CARGO; ++cargo) {
    00116     LinkGraph &graph = _link_graphs[cargo];
    00117     SlObject(&graph, GetLinkGraphDesc());
    00118     SaveLoad_LinkGraphComponent(graph);
    00119   }
    00120 }
    00121
    00125 static void Load_LGRP()
    00126 {
    00127   for (CargoID cargo = 0; cargo < NUM_CARGO; ++cargo) {
    00128     LinkGraph &graph = _link_graphs[cargo];
    00129     assert(graph.GetSize() == 0);
    00130     SlObject(&graph, GetLinkGraphDesc());
    00131     graph.SetSize();
    00132     SaveLoad_LinkGraphComponent(graph);
    00133     for (uint i = 0; i < graph.GetSize(); ++i) {
    00134       Node &node = graph.GetNode(i);
    00135       node.undelivered_supply = node.supply;
    00136     }
    00137   }
    00138 }
    00139
    00144 void AfterLoadLinkGraphs()
    00145 {
    00146   for (CargoID cargo = 0; cargo < NUM_CARGO; ++cargo) {
    00147     LinkGraph &graph = _link_graphs[cargo];
    00148     if (graph.GetSize() > 0) graph.SpawnThread();
    00149   }
    00150 }
    00151
    00152 static void Save_LGRP()
    00153 {
    00154   SlAutolength((AutolengthProc*)DoSave_LGRP, NULL);
    00155 }
    00156
    00157 extern const ChunkHandler _linkgraph_chunk_handlers[] = {
    00158   { 'LGRP', Save_LGRP, Load_LGRP, NULL, NULL, CH_LAST},
    00159 };