Saveload: Use table format for plans chunk

This commit is contained in:
Jonathan G Rennison 2024-07-15 00:26:42 +01:00
parent 0bde627c74
commit 38781fb16e
2 changed files with 57 additions and 23 deletions

View File

@ -101,7 +101,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 2, 2, "tt_wait_in_depot", nullptr, nullptr, nullptr }, { XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 2, 2, "tt_wait_in_depot", nullptr, nullptr, nullptr },
{ XSLFI_AUTO_TIMETABLE, XSCF_NULL, 5, 5, "auto_timetables", nullptr, nullptr, nullptr }, { XSLFI_AUTO_TIMETABLE, XSCF_NULL, 5, 5, "auto_timetables", nullptr, nullptr, nullptr },
{ XSLFI_VEHICLE_REPAIR_COST, XSCF_NULL, 2, 2, "vehicle_repair_cost", nullptr, nullptr, nullptr }, { XSLFI_VEHICLE_REPAIR_COST, XSCF_NULL, 2, 2, "vehicle_repair_cost", nullptr, nullptr, nullptr },
{ XSLFI_ENH_VIEWPORT_PLANS, XSCF_IGNORABLE_ALL, 4, 4, "enh_viewport_plans", nullptr, nullptr, "PLAN" }, { XSLFI_ENH_VIEWPORT_PLANS, XSCF_IGNORABLE_ALL, 5, 5, "enh_viewport_plans", nullptr, nullptr, "PLAN" },
{ XSLFI_INFRA_SHARING, XSCF_NULL, 2, 2, "infra_sharing", nullptr, nullptr, "CPDP" }, { XSLFI_INFRA_SHARING, XSCF_NULL, 2, 2, "infra_sharing", nullptr, nullptr, "CPDP" },
{ XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 7, 7, "variable_day_length", nullptr, nullptr, nullptr }, { XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 7, 7, "variable_day_length", nullptr, nullptr, nullptr },
{ XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr }, { XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr },

View File

@ -13,44 +13,78 @@
#include "saveload.h" #include "saveload.h"
/** Description of a plan within the savegame. */ struct PlanLineStructHandler final : public TypedSaveLoadStructHandler<PlanLineStructHandler, Plan> {
static const SaveLoad _plan_desc[] = { NamedSaveLoadTable GetDescription() const override
SLE_VAR(Plan, owner, SLE_UINT8), {
SLE_VAR(Plan, visible, SLE_BOOL), static const NamedSaveLoad _plan_line_sub_desc[] = {
SLE_VAR(Plan, visible_by_all, SLE_BOOL), NSLT("tiles", SLE_VARVEC(PlanLine, tiles, SLE_UINT32)),
SLE_VAR(Plan, creation_date, SLE_INT32), };
SLE_CONDSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3)), return _plan_line_sub_desc;
SLE_CONDSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_20)), }
SLE_CONDVAR_X(Plan, colour, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 4)),
void Save(Plan *p) const override
{
SlSetStructListLength(p->lines.size());
for (PlanLine *pl : p->lines) {
SlObjectSaveFiltered(pl, this->GetLoadDescription());
}
}
void Load(Plan *p) const override
{
size_t line_count = SlGetStructListLength(UINT32_MAX);
p->lines.resize(line_count);
for (size_t i = 0; i < line_count; i++) {
PlanLine *pl = new PlanLine();
p->lines[i] = pl;
SlObjectLoadFiltered(pl, this->GetLoadDescription());
pl->UpdateVisualExtents();
}
}
}; };
static void RealSave_PLAN(Plan *p) /** Description of a plan within the savegame. */
{ static const NamedSaveLoad _plan_desc[] = {
SlObject(p, _plan_desc); NSL("owner", SLE_VAR(Plan, owner, SLE_UINT8)),
SlWriteUint32((uint32_t)p->lines.size()); NSL("visible", SLE_VAR(Plan, visible, SLE_BOOL)),
for (size_t i = 0; i < p->lines.size(); i++) { NSL("visible_by_all", SLE_VAR(Plan, visible_by_all, SLE_BOOL)),
PlanLine *pl = p->lines[i]; NSL("creation_date", SLE_VAR(Plan, creation_date, SLE_INT32)),
SlWriteUint32((uint32_t)pl->tiles.size()); NSL("name", SLE_CONDSSTR_X(Plan, name, SLE_STR, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3))),
SlArray(pl->tiles.data(), pl->tiles.size(), SLE_UINT32); NSL("name", SLE_CONDSSTR_X(Plan, name, SLE_STR, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_20))),
} NSL("colour", SLE_CONDVAR_X(Plan, colour, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 4))),
} NSLT_STRUCTLIST<PlanLineStructHandler>("lines"),
};
/** Save all plans. */ /** Save all plans. */
static void Save_PLAN() static void Save_PLAN()
{ {
SaveLoadTableData slt = SlTableHeader(_plan_desc);
for (Plan *p : Plan::Iterate()) { for (Plan *p : Plan::Iterate()) {
SlSetArrayIndex(p->index); SlSetArrayIndex(p->index);
SlAutolength(RealSave_PLAN, p); SlObjectSaveFiltered(p, slt);
} }
} }
/** Load all plans. */ /** Load all plans. */
static void Load_PLAN() static void Load_PLAN()
{ {
SaveLoadTableData slt = SlTableHeaderOrRiff(_plan_desc);
if (SlIsTableChunk()) {
int index;
while ((index = SlIterateArray()) != -1) {
Plan *p = new (index) Plan();
SlObjectLoadFiltered(p, slt);
p->SetVisibility(false);
}
return;
}
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Plan *p = new (index) Plan(); Plan *p = new (index) Plan();
SlObject(p, _plan_desc); SlObjectLoadFiltered(p, slt);
if (SlXvIsFeaturePresent(XSLFI_ENH_VIEWPORT_PLANS, 2)) { if (SlXvIsFeaturePresent(XSLFI_ENH_VIEWPORT_PLANS, 2)) {
const size_t line_count = SlReadUint32(); const size_t line_count = SlReadUint32();
p->lines.resize(line_count); p->lines.resize(line_count);
@ -90,7 +124,7 @@ static void Load_PLANLINE()
/** Chunk handlers related to plans. */ /** Chunk handlers related to plans. */
static const ChunkHandler plan_chunk_handlers[] = { static const ChunkHandler plan_chunk_handlers[] = {
{ 'PLAN', Save_PLAN, Load_PLAN, nullptr, nullptr, CH_ARRAY }, { 'PLAN', Save_PLAN, Load_PLAN, nullptr, nullptr, CH_TABLE },
{ 'PLLN', nullptr, Load_PLANLINE, nullptr, nullptr, CH_READONLY }, { 'PLLN', nullptr, Load_PLANLINE, nullptr, nullptr, CH_READONLY },
}; };