diff --git a/src/base_station_base.h b/src/base_station_base.h index 4a676361ab..91f1ec127e 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -305,4 +305,14 @@ struct SpecializedStation : public BaseStation { static Pool::IterateWrapper Iterate(size_t from = 0) { return Pool::IterateWrapper(from); } }; +/** + * Get spec mapping list for each supported custom spec type. + * @tparam T Spec type. + * @param bst Station of custom spec list. + * @return Speclist of custom spec type. + */ +template std::vector> &GetStationSpecList(BaseStation *bst); +template <> inline std::vector> &GetStationSpecList(BaseStation *bst) { return bst->speclist; } +template <> inline std::vector> &GetStationSpecList(BaseStation *bst) { return bst->roadstop_speclist; } + #endif /* BASE_STATION_BASE_H */ diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index ee86e5523e..3de5125fb8 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -202,65 +202,43 @@ static void SwapPackets(GoodsEntry *ge) } } -class SlStationSpecList : public DefaultSaveLoadHandler { +template +class SlStationSpecList : public DefaultSaveLoadHandler, BaseStation> { public: inline static const SaveLoad description[] = { - SLE_CONDVAR(SpecMapping, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION), - SLE_CONDVAR(SpecMapping, localidx, SLE_FILE_U8 | SLE_VAR_U16, SLV_27, SLV_EXTEND_ENTITY_MAPPING), - SLE_CONDVAR(SpecMapping, localidx, SLE_UINT16, SLV_EXTEND_ENTITY_MAPPING, SL_MAX_VERSION), + SLE_CONDVAR(SpecMapping, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION), + SLE_CONDVAR(SpecMapping, localidx, SLE_FILE_U8 | SLE_VAR_U16, SLV_27, SLV_EXTEND_ENTITY_MAPPING), + SLE_CONDVAR(SpecMapping, localidx, SLE_UINT16, SLV_EXTEND_ENTITY_MAPPING, SL_MAX_VERSION), }; inline const static SaveLoadCompatTable compat_description = _station_spec_list_sl_compat; - static uint8_t last_num_specs; ///< Number of specs of the last loaded station. + static inline uint8_t last_num_specs; ///< Number of specs of the last loaded station. void Save(BaseStation *bst) const override { - SlSetStructListLength(bst->speclist.size()); - for (uint i = 0; i < bst->speclist.size(); i++) { - SlObject(&bst->speclist[i], this->GetDescription()); + auto &speclist = GetStationSpecList(bst); + SlSetStructListLength(speclist.size()); + for (auto &sm : speclist) { + SlObject(&sm, this->GetDescription()); } } void Load(BaseStation *bst) const override { - uint8_t num_specs = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? last_num_specs : (uint8_t)SlGetStructListLength(UINT8_MAX); + size_t num_specs = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? last_num_specs : SlGetStructListLength(UINT8_MAX); - bst->speclist.resize(num_specs); - for (uint i = 0; i < num_specs; i++) { - SlObject(&bst->speclist[i], this->GetLoadDescription()); + 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()); } } }; -uint8_t SlStationSpecList::last_num_specs; - -class SlRoadStopSpecList : public DefaultSaveLoadHandler { -public: - inline static const SaveLoad description[] = { - SLE_VAR(SpecMapping, grfid, SLE_UINT32), - SLE_CONDVAR(SpecMapping, localidx, SLE_FILE_U8 | SLE_VAR_U16, SLV_27, SLV_EXTEND_ENTITY_MAPPING), - SLE_CONDVAR(SpecMapping, localidx, SLE_UINT16, SLV_EXTEND_ENTITY_MAPPING, SL_MAX_VERSION), - }; - inline const static SaveLoadCompatTable compat_description = _station_road_stop_spec_list_sl_compat; - - void Save(BaseStation *bst) const override - { - SlSetStructListLength(bst->roadstop_speclist.size()); - for (uint i = 0; i < bst->roadstop_speclist.size(); i++) { - SlObject(&bst->roadstop_speclist[i], this->GetDescription()); - } - } - - void Load(BaseStation *bst) const override - { - uint8_t num_specs = (uint8_t)SlGetStructListLength(UINT8_MAX); - - bst->roadstop_speclist.resize(num_specs); - for (uint i = 0; i < num_specs; i++) { - SlObject(&bst->roadstop_speclist[i], this->GetLoadDescription()); - } - } -}; +/* Instantiate SlStationSpecList classes. */ +template class SlStationSpecList; +template class SlStationSpecList; class SlStationCargo : public DefaultSaveLoadHandler { public: @@ -514,12 +492,12 @@ static const SaveLoad _old_station_desc[] = { /* Used by newstations for graphic variations */ SLE_CONDVAR(Station, random_bits, SLE_UINT16, SLV_27, SL_MAX_VERSION), SLE_CONDVAR(Station, waiting_triggers, SLE_UINT8, SLV_27, SL_MAX_VERSION), - SLEG_CONDVAR("num_specs", SlStationSpecList::last_num_specs, SLE_UINT8, SLV_27, SL_MAX_VERSION), + SLEG_CONDVAR("num_specs", SlStationSpecList::last_num_specs, SLE_UINT8, SLV_27, SL_MAX_VERSION), SLE_CONDREFLIST(Station, loading_vehicles, REF_VEHICLE, SLV_57, SL_MAX_VERSION), SLEG_STRUCTLIST("goods", SlStationGoods), - SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), + SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), }; struct STNSChunkHandler : ChunkHandler { @@ -601,7 +579,7 @@ public: /* Used by newstations for graphic variations */ SLE_VAR(BaseStation, random_bits, SLE_UINT16), SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8), - SLEG_CONDVAR("num_specs", SlStationSpecList::last_num_specs, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), + SLEG_CONDVAR("num_specs", SlStationSpecList::last_num_specs, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), }; inline const static SaveLoadCompatTable compat_description = _station_base_sl_compat; @@ -718,8 +696,8 @@ static const SaveLoad _station_desc[] = { SLE_SAVEBYTE(BaseStation, facilities), SLEG_STRUCT("normal", SlStationNormal), SLEG_STRUCT("waypoint", SlStationWaypoint), - SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), - SLEG_CONDSTRUCTLIST("roadstopspeclist", SlRoadStopSpecList, SLV_NEWGRF_ROAD_STOPS, SL_MAX_VERSION), + SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), + SLEG_CONDSTRUCTLIST("roadstopspeclist", SlStationSpecList, SLV_NEWGRF_ROAD_STOPS, SL_MAX_VERSION), }; struct STNNChunkHandler : ChunkHandler {