MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / SlCompatTableHeader

Function SlCompatTableHeader

src/saveload/saveload.cpp:2037–2085  ·  view source on GitHub ↗

* Load a table header in a savegame compatible way. If the savegame was made * before table headers were added, it will fall back to the * SaveLoadCompatTable for the order of fields while loading. * * @note You only have to call this function if the chunk existed as a * non-table type before converting it to a table. New chunks created as * table can call SlTableHeader() directly. * * @pa

Source from the content-addressed store, hash-verified

2035 * @return When loading, the ordered SaveLoad array to use; otherwise an empty list.
2036 */
2037std::vector<SaveLoad> SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
2038{
2039 assert(_sl.action == SLA_LOAD || _sl.action == SLA_LOAD_CHECK);
2040 /* CH_TABLE / CH_SPARSE_TABLE always have a header. */
2041 if (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE) return SlTableHeader(slt);
2042
2043 std::vector<SaveLoad> saveloads;
2044
2045 /* Build a key lookup mapping based on the available fields. */
2046 std::map<std::string, std::vector<const SaveLoad *>> key_lookup;
2047 for (auto &sld : slt) {
2048 /* All entries should have a name; otherwise the entry should just be removed. */
2049 assert(!sld.name.empty());
2050
2051 key_lookup[sld.name].push_back(&sld);
2052 }
2053
2054 for (auto &slc : slct) {
2055 if (slc.name.empty()) {
2056 /* In old savegames there can be data we no longer care for. We
2057 * skip this by simply reading the amount of bytes indicated and
2058 * send those to /dev/null. */
2059 saveloads.emplace_back("", SL_NULL, GetVarFileType(slc.null_type) | SLE_VAR_NULL, slc.null_length, slc.version_from, slc.version_to, nullptr, 0, nullptr);
2060 } else {
2061 auto sld_it = key_lookup.find(slc.name);
2062 /* If this branch triggers, it means that an entry in the
2063 * SaveLoadCompat list is not mentioned in the SaveLoad list. Did
2064 * you rename a field in one and not in the other? */
2065 if (sld_it == key_lookup.end()) {
2066 /* This isn't an assert, as that leaves no information what
2067 * field was to blame. This way at least we have breadcrumbs. */
2068 Debug(sl, 0, "internal error: saveload compatibility field '{}' not found", slc.name);
2069 SlErrorCorrupt("Internal error with savegame compatibility");
2070 }
2071 for (auto &sld : sld_it->second) {
2072 saveloads.push_back(*sld);
2073 }
2074 }
2075 }
2076
2077 for (auto &sld : saveloads) {
2078 if (!SlIsObjectValidInSavegame(sld)) continue;
2079 if (sld.cmd == SL_STRUCTLIST || sld.cmd == SL_STRUCT) {
2080 sld.handler->load_description = SlCompatTableHeader(sld.handler->GetDescription(), sld.handler->GetCompatDescription());
2081 }
2082 }
2083
2084 return saveloads;
2085}
2086
2087/**
2088 * Save or Load (a list of) global variables.

Callers 15

LoadCommonMethod · 0.85
LoadMethod · 0.85
LoadMethod · 0.85
LoadMethod · 0.85
LoadMethod · 0.85
LoadMethod · 0.85
LoadMethod · 0.85
LoadMethod · 0.85
LoadMethod · 0.85
LoadCheckMethod · 0.85
LoadMethod · 0.85
LoadMethod · 0.85

Calls 10

SlTableHeaderFunction · 0.85
GetVarFileTypeFunction · 0.85
SlErrorCorruptFunction · 0.85
push_backMethod · 0.80
emptyMethod · 0.45
findMethod · 0.45
endMethod · 0.45
GetDescriptionMethod · 0.45
GetCompatDescriptionMethod · 0.45

Tested by

no test coverage detected