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_VAR(LinkGraph, last_compression, SLE_INT32),
00034 SLEG_VAR(_num_nodes, SLE_UINT16),
00035 SLE_VAR(LinkGraph, cargo, SLE_UINT8),
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_VAR(LinkGraphJob, join_date, SLE_INT32),
00077 SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
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_LST(LinkGraphSchedule, schedule, REF_LINK_GRAPH),
00098 SLE_LST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB),
00099 SLE_END()
00100 };
00101 return schedule_desc;
00102 }
00103
00104
00105
00109 static const SaveLoad _node_desc[] = {
00110 SLE_VAR(Node, supply, SLE_UINT32),
00111 SLE_VAR(Node, demand, SLE_UINT32),
00112 SLE_VAR(Node, station, SLE_UINT16),
00113 SLE_VAR(Node, last_update, SLE_INT32),
00114 SLE_END()
00115 };
00116
00120 static const SaveLoad _edge_desc[] = {
00121 SLE_VAR(Edge, distance, SLE_UINT32),
00122 SLE_VAR(Edge, capacity, SLE_UINT32),
00123 SLE_VAR(Edge, usage, SLE_UINT32),
00124 SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
00125 SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, 187, SL_MAX_VERSION),
00126 SLE_VAR(Edge, next_edge, SLE_UINT16),
00127 SLE_END()
00128 };
00129
00134 void SaveLoad_LinkGraph(LinkGraph &lg)
00135 {
00136 uint size = lg.Size();
00137 for (NodeID from = 0; from < size; ++from) {
00138 Node *node = &lg.nodes[from];
00139 SlObject(node, _node_desc);
00140 for (NodeID to = 0; to < size; ++to) {
00141 SlObject(&lg.edges[from][to], _edge_desc);
00142 }
00143 }
00144 }
00145
00150 static void DoSave_LGRJ(LinkGraphJob *lgj)
00151 {
00152 SlObject(lgj, GetLinkGraphJobDesc());
00153 _num_nodes = lgj->Size();
00154 SlObject(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc());
00155 SaveLoad_LinkGraph(const_cast<LinkGraph &>(lgj->Graph()));
00156 }
00157
00162 static void DoSave_LGRP(LinkGraph *lg)
00163 {
00164 _num_nodes = lg->Size();
00165 SlObject(lg, GetLinkGraphDesc());
00166 SaveLoad_LinkGraph(*lg);
00167 }
00168
00172 static void Load_LGRP()
00173 {
00174 int index;
00175 while ((index = SlIterateArray()) != -1) {
00176 if (!LinkGraph::CanAllocateItem()) {
00177
00178 NOT_REACHED();
00179 }
00180 LinkGraph *lg = new (index) LinkGraph();
00181 SlObject(lg, GetLinkGraphDesc());
00182 lg->Init(_num_nodes);
00183 SaveLoad_LinkGraph(*lg);
00184 }
00185 }
00186
00190 static void Load_LGRJ()
00191 {
00192 int index;
00193 while ((index = SlIterateArray()) != -1) {
00194 if (!LinkGraphJob::CanAllocateItem()) {
00195
00196 NOT_REACHED();
00197 }
00198 LinkGraphJob *lgj = new (index) LinkGraphJob();
00199 SlObject(lgj, GetLinkGraphJobDesc());
00200 LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph());
00201 SlObject(&lg, GetLinkGraphDesc());
00202 lg.Init(_num_nodes);
00203 SaveLoad_LinkGraph(lg);
00204 }
00205 }
00206
00210 static void Load_LGRS()
00211 {
00212 SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
00213 }
00214
00219 void AfterLoadLinkGraphs()
00220 {
00221 LinkGraphSchedule::Instance()->SpawnAll();
00222 }
00223
00227 static void Save_LGRP()
00228 {
00229 LinkGraph *lg;
00230 FOR_ALL_LINK_GRAPHS(lg) {
00231 SlSetArrayIndex(lg->index);
00232 SlAutolength((AutolengthProc*)DoSave_LGRP, lg);
00233 }
00234 }
00235
00239 static void Save_LGRJ()
00240 {
00241 LinkGraphJob *lgj;
00242 FOR_ALL_LINK_GRAPH_JOBS(lgj) {
00243 SlSetArrayIndex(lgj->index);
00244 SlAutolength((AutolengthProc*)DoSave_LGRJ, lgj);
00245 }
00246 }
00247
00251 static void Save_LGRS()
00252 {
00253 SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
00254 }
00255
00259 static void Ptrs_LGRS()
00260 {
00261 SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
00262 }
00263
00264 extern const ChunkHandler _linkgraph_chunk_handlers[] = {
00265 { 'LGRP', Save_LGRP, Load_LGRP, NULL, NULL, CH_ARRAY },
00266 { 'LGRJ', Save_LGRJ, Load_LGRJ, NULL, NULL, CH_ARRAY },
00267 { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, NULL, CH_LAST }
00268 };