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 "../settings_internal.h"
00015 #include "saveload.h"
00016 
00017 const SettingDesc *GetSettingDescription(uint index);
00018 
00023 const SaveLoad *GetLinkGraphDesc()
00024 {
00025   static const SaveLoad link_graph_desc[] = {
00026     SLE_CONDVAR(LinkGraph, last_compression, SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00027     SLE_CONDVAR(LinkGraph, num_nodes,        SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
00028     SLE_CONDVAR(LinkGraph, cargo,            SLE_UINT8,  SL_COMPONENTS, SL_MAX_VERSION),
00029     SLE_END()
00030   };
00031   return link_graph_desc;
00032 }
00033 
00043 const SaveLoad *GetLinkGraphJobDesc()
00044 {
00045   static SmallVector<SaveLoad, 16> saveloads;
00046   static const char *prefix = "linkgraph.";
00047 
00048   /* Build the SaveLoad array on first call and don't touch it later on */
00049   if (saveloads.Length() == 0) {
00050     size_t offset_gamesettings = cpp_offsetof(GameSettings, linkgraph);
00051     size_t offset_component = cpp_offsetof(LinkGraphJob, settings);
00052 
00053     size_t prefixlen = strlen(prefix);
00054 
00055     int setting = 0;
00056     const SettingDesc *desc = GetSettingDescription(setting);
00057     while (desc->save.cmd != SL_END) {
00058       if (desc->desc.name != NULL && strncmp(desc->desc.name, prefix, prefixlen) == 0) {
00059         SaveLoad sl = desc->save;
00060         char *&address = reinterpret_cast<char *&>(sl.address);
00061         address -= offset_gamesettings;
00062         address += offset_component;
00063         *(saveloads.Append()) = sl;
00064       }
00065       desc = GetSettingDescription(++setting);
00066     }
00067 
00068     const SaveLoad job_desc[] = {
00069       SLE_CONDVAR(LinkGraphJob, join_date,        SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00070       SLE_CONDVAR(LinkGraphJob, link_graph.index, SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
00071       SLE_END()
00072     };
00073 
00074     int i = 0;
00075     do {
00076       *(saveloads.Append()) = job_desc[i++];
00077     } while (saveloads[saveloads.Length() - 1].cmd != SL_END);
00078   }
00079 
00080   return &saveloads[0];
00081 }
00082 
00087 const SaveLoad *GetLinkGraphScheduleDesc()
00088 {
00089   static const SaveLoad schedule_desc[] = {
00090     SLE_CONDLST(LinkGraphSchedule, schedule, REF_LINK_GRAPH,     SL_COMPONENTS, SL_MAX_VERSION),
00091     SLE_CONDLST(LinkGraphSchedule, running,  REF_LINK_GRAPH_JOB, SL_COMPONENTS, SL_MAX_VERSION),
00092     SLE_END()
00093   };
00094   return schedule_desc;
00095 }
00096 
00097 /* Edges and nodes are saved in the correct order, so we don't need to save their ids. */
00098 
00102 static const SaveLoad _node_desc[] = {
00103    SLE_CONDVAR(Node, supply,      SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00104    SLE_CONDVAR(Node, demand,      SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00105    SLE_CONDVAR(Node, station,     SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
00106    SLE_CONDVAR(Node, last_update, SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00107    SLE_END()
00108 };
00109 
00113 static const SaveLoad _edge_desc[] = {
00114    SLE_CONDVAR(Edge, distance,    SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00115    SLE_CONDVAR(Edge, capacity,    SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00116    SLE_CONDVAR(Edge, usage,       SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00117    SLE_CONDVAR(Edge, last_update, SLE_UINT32, SL_COMPONENTS, SL_MAX_VERSION),
00118    SLE_CONDVAR(Edge, next_edge,   SLE_UINT16, SL_COMPONENTS, SL_MAX_VERSION),
00119    SLE_END()
00120 };
00121 
00126 static void SaveLoad_LinkGraph(LinkGraph &link_graph)
00127 {
00128   uint size = link_graph.GetSize();
00129   for (NodeID from = 0; from < size; ++from) {
00130     Node *node = &link_graph.GetNode(from);
00131     SlObject(node, _node_desc);
00132     for (NodeID to = 0; to < size; ++to) {
00133       SlObject(&link_graph.GetEdge(from, to), _edge_desc);
00134     }
00135   }
00136 }
00137 
00142 static void DoSave_LGRJ(LinkGraphJob *lgj)
00143 {
00144   SlObject(lgj, GetLinkGraphJobDesc());
00145   SlObject(&lgj->Graph(), GetLinkGraphDesc());
00146   SaveLoad_LinkGraph(lgj->Graph());
00147 }
00148 
00153 static void DoSave_LGRP(LinkGraph *lg)
00154 {
00155   SlObject(lg, GetLinkGraphDesc());
00156   SaveLoad_LinkGraph(*lg);
00157 }
00158 
00162 static void Load_LGRP()
00163 {
00164   int index;
00165   while ((index = SlIterateArray()) != -1) {
00166     if (!LinkGraph::CanAllocateItem()) {
00167       /* Impossible as they have been present in previous game. */
00168       NOT_REACHED();
00169     }
00170     LinkGraph *lg = new (index) LinkGraph();
00171     SlObject(lg, GetLinkGraphDesc());
00172     lg->SetSize();
00173     SaveLoad_LinkGraph(*lg);
00174   }
00175 }
00176 
00180 static void Load_LGRJ()
00181 {
00182   int index;
00183   while ((index = SlIterateArray()) != -1) {
00184     if (!LinkGraphJob::CanAllocateItem()) {
00185       /* Impossible as they have been present in previous game. */
00186       NOT_REACHED();
00187     }
00188     LinkGraphJob *lgj = new (index) LinkGraphJob();
00189     SlObject(lgj, GetLinkGraphJobDesc());
00190     LinkGraph &lg = lgj->Graph();
00191     SlObject(&lg, GetLinkGraphDesc());
00192     lg.SetSize();
00193     SaveLoad_LinkGraph(lg);
00194   }
00195 }
00196 
00200 static void Load_LGRS()
00201 {
00202   SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
00203 }
00204 
00209 void AfterLoadLinkGraphs()
00210 {
00211   LinkGraphSchedule::Instance()->SpawnAll();
00212 }
00213 
00217 static void Save_LGRP()
00218 {
00219   LinkGraph *lg;
00220   FOR_ALL_LINK_GRAPHS(lg) {
00221     SlSetArrayIndex(lg->index);
00222     SlAutolength((AutolengthProc*)DoSave_LGRP, lg);
00223   }
00224 }
00225 
00229 static void Save_LGRJ()
00230 {
00231   LinkGraphJob *lgj;
00232   FOR_ALL_LINK_GRAPH_JOBS(lgj) {
00233     SlSetArrayIndex(lgj->index);
00234     SlAutolength((AutolengthProc*)DoSave_LGRJ, lgj);
00235   }
00236 }
00237 
00241 static void Save_LGRS()
00242 {
00243   SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
00244 }
00245 
00249 static void Ptrs_LGRS()
00250 {
00251   SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
00252 }
00253 
00254 extern const ChunkHandler _linkgraph_chunk_handlers[] = {
00255   { 'LGRP', Save_LGRP, Load_LGRP, NULL,      NULL, CH_ARRAY},
00256   { 'LGRJ', Save_LGRJ, Load_LGRJ, NULL,      NULL, CH_ARRAY},
00257   { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, NULL, CH_LAST},
00258 };