From 38781fb16e6a86a532ddd4c6d748205dbca6ad0c Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 15 Jul 2024 00:26:42 +0100 Subject: [PATCH] Saveload: Use table format for plans chunk --- src/sl/extended_ver_sl.cpp | 2 +- src/sl/plans_sl.cpp | 78 +++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/sl/extended_ver_sl.cpp b/src/sl/extended_ver_sl.cpp index eb960cb7cf..e929780ae9 100644 --- a/src/sl/extended_ver_sl.cpp +++ b/src/sl/extended_ver_sl.cpp @@ -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_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_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_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 }, diff --git a/src/sl/plans_sl.cpp b/src/sl/plans_sl.cpp index f3544b4839..ac9810e57d 100644 --- a/src/sl/plans_sl.cpp +++ b/src/sl/plans_sl.cpp @@ -13,44 +13,78 @@ #include "saveload.h" -/** Description of a plan within the savegame. */ -static const SaveLoad _plan_desc[] = { - SLE_VAR(Plan, owner, SLE_UINT8), - SLE_VAR(Plan, visible, SLE_BOOL), - SLE_VAR(Plan, visible_by_all, SLE_BOOL), - 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)), - 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)), +struct PlanLineStructHandler final : public TypedSaveLoadStructHandler { + NamedSaveLoadTable GetDescription() const override + { + static const NamedSaveLoad _plan_line_sub_desc[] = { + NSLT("tiles", SLE_VARVEC(PlanLine, tiles, SLE_UINT32)), + }; + return _plan_line_sub_desc; + } + + 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) -{ - SlObject(p, _plan_desc); - SlWriteUint32((uint32_t)p->lines.size()); - for (size_t i = 0; i < p->lines.size(); i++) { - PlanLine *pl = p->lines[i]; - SlWriteUint32((uint32_t)pl->tiles.size()); - SlArray(pl->tiles.data(), pl->tiles.size(), SLE_UINT32); - } -} +/** Description of a plan within the savegame. */ +static const NamedSaveLoad _plan_desc[] = { + NSL("owner", SLE_VAR(Plan, owner, SLE_UINT8)), + NSL("visible", SLE_VAR(Plan, visible, SLE_BOOL)), + NSL("visible_by_all", SLE_VAR(Plan, visible_by_all, SLE_BOOL)), + NSL("creation_date", SLE_VAR(Plan, creation_date, SLE_INT32)), + NSL("name", SLE_CONDSSTR_X(Plan, name, SLE_STR, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3))), + 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("lines"), +}; /** Save all plans. */ static void Save_PLAN() { + SaveLoadTableData slt = SlTableHeader(_plan_desc); + for (Plan *p : Plan::Iterate()) { SlSetArrayIndex(p->index); - SlAutolength(RealSave_PLAN, p); + SlObjectSaveFiltered(p, slt); } } /** Load all plans. */ 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; while ((index = SlIterateArray()) != -1) { Plan *p = new (index) Plan(); - SlObject(p, _plan_desc); + SlObjectLoadFiltered(p, slt); if (SlXvIsFeaturePresent(XSLFI_ENH_VIEWPORT_PLANS, 2)) { const size_t line_count = SlReadUint32(); p->lines.resize(line_count); @@ -90,7 +124,7 @@ static void Load_PLANLINE() /** Chunk handlers related to plans. */ 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 }, };