diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 5abf18157b..62be5ba5e2 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -441,7 +441,7 @@ public: void LoadCheck(CompanyProperties *c) const override { this->Load(c); } }; -class SlAllowListData : public DefaultSaveLoadHandler { +class SlAllowListData : public VectorSaveLoadHandler { public: struct KeyWrapper { std::string key; @@ -452,23 +452,7 @@ public: }; inline const static SaveLoadCompatTable compat_description = {}; - void Save(CompanyProperties *cprops) const override - { - SlSetStructListLength(cprops->allow_list.size()); - for (std::string &str : cprops->allow_list) { - SlObject(&str, this->GetDescription()); - } - } - - void Load(CompanyProperties *cprops) const override - { - size_t num_keys = SlGetStructListLength(UINT32_MAX); - cprops->allow_list.clear(); - cprops->allow_list.resize(num_keys); - for (std::string &str : cprops->allow_list) { - SlObject(&str, this->GetLoadDescription()); - } - } + std::vector &GetVector(CompanyProperties *cprops) const override { return cprops->allow_list; } void LoadCheck(CompanyProperties *cprops) const override { this->Load(cprops); } }; diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 6edea24e05..bb1682227a 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -19,7 +19,7 @@ static OldPersistentStorage _old_ind_persistent_storage; -class SlIndustryAccepted : public DefaultSaveLoadHandler { +class SlIndustryAccepted : public VectorSaveLoadHandler { public: inline static const SaveLoad description[] = { SLE_VAR(Industry::AcceptedCargo, cargo, SLE_UINT8), @@ -28,27 +28,9 @@ public: }; inline const static SaveLoadCompatTable compat_description = _industry_accepts_sl_compat; - void Save(Industry *i) const override - { - SlSetStructListLength(i->accepted.size()); + std::vector &GetVector(Industry *i) const override { return i->accepted; } - for (auto &a : i->accepted) { - SlObject(&a, this->GetDescription()); - } - } - - void Load(Industry *i) const override - { - size_t len = SlGetStructListLength(INDUSTRY_NUM_INPUTS); - - i->accepted.reserve(len); - for (size_t index = 0; index < len; ++index) { - auto &a = i->accepted.emplace_back(); - SlObject(&a, this->GetLoadDescription()); - } - } - - /* Old array structure used for savegames before SLV_INDUSTRY_CARGO_REORGANISE. */ + /* Old array structure used by INDYChunkHandler for savegames before SLV_INDUSTRY_CARGO_REORGANISE. */ static inline std::array old_cargo; static inline std::array old_waiting; static inline std::array old_last_accepted; @@ -95,7 +77,7 @@ public: } }; -class SlIndustryProduced : public DefaultSaveLoadHandler { +class SlIndustryProduced : public VectorSaveLoadHandler { public: inline static const SaveLoad description[] = { SLE_VAR(Industry::ProducedCargo, cargo, SLE_UINT8), @@ -105,27 +87,9 @@ public: }; inline const static SaveLoadCompatTable compat_description = _industry_produced_sl_compat; - void Save(Industry *i) const override - { - SlSetStructListLength(i->produced.size()); + std::vector &GetVector(Industry *i) const override { return i->produced; } - for (auto &p : i->produced) { - SlObject(&p, this->GetDescription()); - } - } - - void Load(Industry *i) const override - { - size_t len = SlGetStructListLength(INDUSTRY_NUM_OUTPUTS); - - i->produced.reserve(len); - for (size_t index = 0; index < len; ++index) { - auto &p = i->produced.emplace_back(); - SlObject(&p, this->GetLoadDescription()); - } - } - - /* Old array structure used for savegames before SLV_INDUSTRY_CARGO_REORGANISE. */ + /* Old array structure used by INDYChunkHandler for savegames before SLV_INDUSTRY_CARGO_REORGANISE. */ static inline std::array old_cargo; static inline std::array old_waiting; static inline std::array old_rate; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 79f533d3f8..63ccac6236 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -1314,4 +1314,55 @@ inline void SlSkipBytes(size_t length) extern std::string _savegame_format; extern bool _do_autosave; +/** + * Default handler for saving/loading a vector to/from disk. + * + * This handles a few common things for handlers, meaning the actual handler + * needs less code. + * + * @tparam TImpl The class initializing this template. + * @tparam TObject The class of the object using this SaveLoadHandler. + * @tparam TElementType The type of the elements contained within the vector. + * @tparam MAX_LENGTH maximum number of elements to load. + */ +template +class VectorSaveLoadHandler : public DefaultSaveLoadHandler { +public: + /** + * Get instance of vector to load/save. + * @param object Object containing vector. + * @returns Vector to load/save. + */ + virtual std::vector &GetVector(TObject *object) const = 0; + + /** + * Get number of elements to load into vector. + * @returns Number of elements to load into the vector. + * @note This is only overridden if the number of elements comes from a different location due to savegame changes. + */ + virtual size_t GetLength() const { return SlGetStructListLength(MAX_LENGTH); } + + void Save(TObject *object) const override + { + auto &vector = this->GetVector(object); + SlSetStructListLength(vector.size()); + + for (auto &item : vector) { + SlObject(&item, this->GetDescription()); + } + } + + void Load(TObject *object) const override + { + auto &vector = this->GetVector(object); + size_t count = this->GetLength(); + + vector.reserve(count); + while (count-- > 0) { + auto &item = vector.emplace_back(); + SlObject(&item, this->GetLoadDescription()); + } + } +}; + #endif /* SAVELOAD_H */ diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index f1c288af56..b724e423b9 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -201,7 +201,7 @@ static void SwapPackets(GoodsEntry *ge) } template -class SlStationSpecList : public DefaultSaveLoadHandler, BaseStation> { +class SlStationSpecList : public VectorSaveLoadHandler, BaseStation, SpecMapping> { public: inline static const SaveLoad description[] = { SLE_CONDVAR(SpecMapping, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION), @@ -212,25 +212,11 @@ public: static inline uint8_t last_num_specs; ///< Number of specs of the last loaded station. - void Save(BaseStation *bst) const override - { - auto &speclist = GetStationSpecList(bst); - SlSetStructListLength(speclist.size()); - for (auto &sm : speclist) { - SlObject(&sm, this->GetDescription()); - } - } + std::vector> &GetVector(BaseStation *bst) const override { return GetStationSpecList(bst); } - void Load(BaseStation *bst) const override + size_t GetLength() const override { - size_t num_specs = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? last_num_specs : SlGetStructListLength(UINT8_MAX); - - auto &speclist = GetStationSpecList(bst); - speclist.reserve(num_specs); - for (size_t index = 0; index < num_specs; ++index) { - auto &sm = speclist.emplace_back(); - SlObject(&sm, this->GetLoadDescription()); - } + return IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? last_num_specs : SlGetStructListLength(UINT8_MAX); } }; @@ -518,7 +504,7 @@ struct STNSChunkHandler : ChunkHandler { } }; -class SlRoadStopTileData : public DefaultSaveLoadHandler { +class SlRoadStopTileData : public VectorSaveLoadHandler { public: inline static const SaveLoad description[] = { SLE_VAR(RoadStopTileData, tile, SLE_UINT32), @@ -527,22 +513,7 @@ public: }; inline const static SaveLoadCompatTable compat_description = {}; - void Save(BaseStation *bst) const override - { - SlSetStructListLength(bst->custom_roadstop_tile_data.size()); - for (uint i = 0; i < bst->custom_roadstop_tile_data.size(); i++) { - SlObject(&bst->custom_roadstop_tile_data[i], this->GetDescription()); - } - } - - void Load(BaseStation *bst) const override - { - uint32_t num_tiles = (uint32_t)SlGetStructListLength(UINT32_MAX); - bst->custom_roadstop_tile_data.resize(num_tiles); - for (uint i = 0; i < num_tiles; i++) { - SlObject(&bst->custom_roadstop_tile_data[i], this->GetLoadDescription()); - } - } + std::vector &GetVector(BaseStation *bst) const override { return bst->custom_roadstop_tile_data; } }; /**