mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Add VectorSaveLoadHandler to simplify handlers for vectors. (#13093)
This reduces the duplication needed for each saved complex vector.pull/12345/head
parent
a6c526cfa0
commit
d903806e59
|
@ -441,7 +441,7 @@ public:
|
|||
void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
|
||||
};
|
||||
|
||||
class SlAllowListData : public DefaultSaveLoadHandler<SlAllowListData, CompanyProperties> {
|
||||
class SlAllowListData : public VectorSaveLoadHandler<SlAllowListData, CompanyProperties, std::string> {
|
||||
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<std::string> &GetVector(CompanyProperties *cprops) const override { return cprops->allow_list; }
|
||||
|
||||
void LoadCheck(CompanyProperties *cprops) const override { this->Load(cprops); }
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
static OldPersistentStorage _old_ind_persistent_storage;
|
||||
|
||||
class SlIndustryAccepted : public DefaultSaveLoadHandler<SlIndustryAccepted, Industry> {
|
||||
class SlIndustryAccepted : public VectorSaveLoadHandler<SlIndustryAccepted, Industry, Industry::AcceptedCargo, INDUSTRY_NUM_INPUTS> {
|
||||
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<Industry::AcceptedCargo> &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<CargoID, INDUSTRY_NUM_INPUTS> old_cargo;
|
||||
static inline std::array<uint16_t, INDUSTRY_NUM_INPUTS> old_waiting;
|
||||
static inline std::array<TimerGameEconomy::Date, INDUSTRY_NUM_INPUTS> old_last_accepted;
|
||||
|
@ -95,7 +77,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class SlIndustryProduced : public DefaultSaveLoadHandler<SlIndustryProduced, Industry> {
|
||||
class SlIndustryProduced : public VectorSaveLoadHandler<SlIndustryProduced, Industry, Industry::ProducedCargo, INDUSTRY_NUM_OUTPUTS> {
|
||||
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<Industry::ProducedCargo> &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<CargoID, INDUSTRY_NUM_OUTPUTS> old_cargo;
|
||||
static inline std::array<uint16_t, INDUSTRY_NUM_OUTPUTS> old_waiting;
|
||||
static inline std::array<uint8_t, INDUSTRY_NUM_OUTPUTS> old_rate;
|
||||
|
|
|
@ -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 TImpl, class TObject, class TElementType, size_t MAX_LENGTH = UINT32_MAX>
|
||||
class VectorSaveLoadHandler : public DefaultSaveLoadHandler<TImpl, TObject> {
|
||||
public:
|
||||
/**
|
||||
* Get instance of vector to load/save.
|
||||
* @param object Object containing vector.
|
||||
* @returns Vector to load/save.
|
||||
*/
|
||||
virtual std::vector<TElementType> &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 */
|
||||
|
|
|
@ -201,7 +201,7 @@ static void SwapPackets(GoodsEntry *ge)
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
class SlStationSpecList : public DefaultSaveLoadHandler<SlStationSpecList<T>, BaseStation> {
|
||||
class SlStationSpecList : public VectorSaveLoadHandler<SlStationSpecList<T>, BaseStation, SpecMapping<T>> {
|
||||
public:
|
||||
inline static const SaveLoad description[] = {
|
||||
SLE_CONDVAR(SpecMapping<T>, 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<T>(bst);
|
||||
SlSetStructListLength(speclist.size());
|
||||
for (auto &sm : speclist) {
|
||||
SlObject(&sm, this->GetDescription());
|
||||
}
|
||||
}
|
||||
std::vector<SpecMapping<T>> &GetVector(BaseStation *bst) const override { return GetStationSpecList<T>(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<T>(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<SlRoadStopTileData, BaseStation> {
|
||||
class SlRoadStopTileData : public VectorSaveLoadHandler<SlRoadStopTileData, BaseStation, RoadStopTileData> {
|
||||
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<RoadStopTileData> &GetVector(BaseStation *bst) const override { return bst->custom_roadstop_tile_data; }
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue