00001
00002
00003
00004
00005
00006
00007
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
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
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
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
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 };