# 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/linkgraphjob.h"
    00015 #include "../linkgraph/linkgraphschedule.h"
    00016 #include "../settings_internal.h"
    00017 #include "saveload.h"
    00018
    00019 typedef LinkGraph::BaseNode Node;
    00020 typedef LinkGraph::BaseEdge Edge;
    00021
    00022 const SettingDesc *GetSettingDescription(uint index);
    00023
    00024 static uint _num_nodes;
    00025
    00030 const SaveLoad *GetLinkGraphDesc()
    00031 {
    00032   static const SaveLoad link_graph_desc[] = {
    00033       SLE_CONDVAR(LinkGraph, last_compression, SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00034      SLEG_CONDVAR(_num_nodes,                  SLE_UINT16, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00035       SLE_CONDVAR(LinkGraph, cargo,            SLE_UINT8,  SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00036       SLE_END()
    00037   };
    00038   return link_graph_desc;
    00039 }
    00040
    00050 const SaveLoad *GetLinkGraphJobDesc()
    00051 {
    00052   static SmallVector<SaveLoad, 16> saveloads;
    00053   static const char *prefix = "linkgraph.";
    00054
    00055   /* Build the SaveLoad array on first call and don't touch it later on */
    00056   if (saveloads.Length() == 0) {
    00057     size_t offset_gamesettings = cpp_offsetof(GameSettings, linkgraph);
    00058     size_t offset_component = cpp_offsetof(LinkGraphJob, settings);
    00059
    00060     size_t prefixlen = strlen(prefix);
    00061
    00062     int setting = 0;
    00063     const SettingDesc *desc = GetSettingDescription(setting);
    00064     while (desc->save.cmd != SL_END) {
    00065       if (desc->desc.name != NULL && strncmp(desc->desc.name, prefix, prefixlen) == 0) {
    00066         SaveLoad sl = desc->save;
    00067         char *&address = reinterpret_cast<char *&>(sl.address);
    00068         address -= offset_gamesettings;
    00069         address += offset_component;
    00070         *(saveloads.Append()) = sl;
    00071       }
    00072       desc = GetSettingDescription(++setting);
    00073     }
    00074
    00075     const SaveLoad job_desc[] = {
    00076       SLE_CONDVAR(LinkGraphJob, join_date,        SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00077       SLE_CONDVAR(LinkGraphJob, link_graph.index, SLE_UINT16, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00078       SLE_END()
    00079     };
    00080
    00081     int i = 0;
    00082     do {
    00083       *(saveloads.Append()) = job_desc[i++];
    00084     } while (saveloads[saveloads.Length() - 1].cmd != SL_END);
    00085   }
    00086
    00087   return &saveloads[0];
    00088 }
    00089
    00094 const SaveLoad *GetLinkGraphScheduleDesc()
    00095 {
    00096   static const SaveLoad schedule_desc[] = {
    00097     SLE_CONDLST(LinkGraphSchedule, schedule, REF_LINK_GRAPH,     SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00098     SLE_CONDLST(LinkGraphSchedule, running,  REF_LINK_GRAPH_JOB, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00099     SLE_END()
    00100   };
    00101   return schedule_desc;
    00102 }
    00103
    00104 /* Edges and nodes are saved in the correct order, so we don't need to save their ids. */
    00105
    00109 static const SaveLoad _node_desc[] = {
    00110    SLE_CONDVAR(Node, supply,      SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00111    SLE_CONDVAR(Node, demand,      SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00112    SLE_CONDVAR(Node, station,     SLE_UINT16, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00113    SLE_CONDVAR(Node, last_update, SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00114    SLE_END()
    00115 };
    00116
    00120 static const SaveLoad _edge_desc[] = {
    00121    SLE_CONDVAR(Edge, distance,    SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00122    SLE_CONDVAR(Edge, capacity,    SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00123    SLE_CONDVAR(Edge, usage,       SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00124    SLE_CONDVAR(Edge, last_update, SLE_UINT32, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00125    SLE_CONDVAR(Edge, next_edge,   SLE_UINT16, SL_LINKGRAPH_JOB, SL_MAX_VERSION),
    00126    SLE_END()
    00127 };
    00128
    00133 void SaveLoad_LinkGraph(LinkGraph &lg)
    00134 {
    00135   uint size = lg.Size();
    00136   for (NodeID from = 0; from < size; ++from) {
    00137     Node *node = &lg.nodes[from];
    00138     SlObject(node, _node_desc);
    00139     for (NodeID to = 0; to < size; ++to) {
    00140       SlObject(&lg.edges[from][to], _edge_desc);
    00141     }
    00142   }
    00143 }
    00144
    00149 static void DoSave_LGRJ(LinkGraphJob *lgj)
    00150 {
    00151   SlObject(lgj, GetLinkGraphJobDesc());
    00152   _num_nodes = lgj->Size();
    00153   SlObject(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc());
    00154   SaveLoad_LinkGraph(const_cast<LinkGraph &>(lgj->Graph()));
    00155 }
    00156
    00161 static void DoSave_LGRP(LinkGraph *lg)
    00162 {
    00163   _num_nodes = lg->Size();
    00164   SlObject(lg, GetLinkGraphDesc());
    00165   SaveLoad_LinkGraph(*lg);
    00166 }
    00167
    00171 static void Load_LGRP()
    00172 {
    00173   int index;
    00174   while ((index = SlIterateArray()) != -1) {
    00175     if (!LinkGraph::CanAllocateItem()) {
    00176       /* Impossible as they have been present in previous game. */
    00177       NOT_REACHED();
    00178     }
    00179     LinkGraph *lg = new (index) LinkGraph();
    00180     SlObject(lg, GetLinkGraphDesc());
    00181     lg->Init(_num_nodes);
    00182     SaveLoad_LinkGraph(*lg);
    00183   }
    00184 }
    00185
    00189 static void Load_LGRJ()
    00190 {
    00191   int index;
    00192   while ((index = SlIterateArray()) != -1) {
    00193     if (!LinkGraphJob::CanAllocateItem()) {
    00194       /* Impossible as they have been present in previous game. */
    00195       NOT_REACHED();
    00196     }
    00197     LinkGraphJob *lgj = new (index) LinkGraphJob();
    00198     SlObject(lgj, GetLinkGraphJobDesc());
    00199     LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph());
    00200     SlObject(&lg, GetLinkGraphDesc());
    00201     lg.Init(_num_nodes);
    00202     SaveLoad_LinkGraph(lg);
    00203   }
    00204 }
    00205
    00209 static void Load_LGRS()
    00210 {
    00211   SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
    00212 }
    00213
    00218 void AfterLoadLinkGraphs()
    00219 {
    00220   LinkGraphSchedule::Instance()->SpawnAll();
    00221 }
    00222
    00226 static void Save_LGRP()
    00227 {
    00228   LinkGraph *lg;
    00229   FOR_ALL_LINK_GRAPHS(lg) {
    00230     SlSetArrayIndex(lg->index);
    00231     SlAutolength((AutolengthProc*)DoSave_LGRP, lg);
    00232   }
    00233 }
    00234
    00238 static void Save_LGRJ()
    00239 {
    00240   LinkGraphJob *lgj;
    00241   FOR_ALL_LINK_GRAPH_JOBS(lgj) {
    00242     SlSetArrayIndex(lgj->index);
    00243     SlAutolength((AutolengthProc*)DoSave_LGRJ, lgj);
    00244   }
    00245 }
    00246
    00250 static void Save_LGRS()
    00251 {
    00252   SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
    00253 }
    00254
    00258 static void Ptrs_LGRS()
    00259 {
    00260   SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
    00261 }
    00262
    00263 extern const ChunkHandler _linkgraph_chunk_handlers[] = {
    00264   { 'LGRP', Save_LGRP, Load_LGRP, NULL,      NULL, CH_ARRAY},
    00265   { 'LGRJ', Save_LGRJ, Load_LGRJ, NULL,      NULL, CH_ARRAY},
    00266   { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, NULL, CH_LAST},
    00267 };