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