mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Store GS lang texts in std::strings.
parent
9c2e47d03c
commit
9b6f5e3bb8
|
@ -58,70 +58,47 @@ void NORETURN CDECL strgen_fatal(const char *s, ...)
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new container for language strings.
|
|
||||||
* @param language The language name.
|
|
||||||
* @param end If not nullptr, terminate \a language at this position.
|
|
||||||
*/
|
|
||||||
LanguageStrings::LanguageStrings(const char *language, const char *end)
|
|
||||||
{
|
|
||||||
this->language = stredup(language, end != nullptr ? end - 1 : nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Free everything. */
|
|
||||||
LanguageStrings::~LanguageStrings()
|
|
||||||
{
|
|
||||||
free(this->language);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all the raw language strings from the given file.
|
* Read all the raw language strings from the given file.
|
||||||
* @param file The file to read from.
|
* @param file The file to read from.
|
||||||
* @return The raw strings, or nullptr upon error.
|
* @return The raw strings, or nullptr upon error.
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<LanguageStrings> ReadRawLanguageStrings(const char *file)
|
LanguageStrings ReadRawLanguageStrings(const std::string &file)
|
||||||
{
|
{
|
||||||
try {
|
size_t to_read;
|
||||||
size_t to_read;
|
FILE *fh = FioFOpenFile(file.c_str(), "rb", GAME_DIR, &to_read);
|
||||||
FILE *fh = FioFOpenFile(file, "rb", GAME_DIR, &to_read);
|
if (fh == nullptr) return LanguageStrings();
|
||||||
if (fh == nullptr) return nullptr;
|
|
||||||
|
|
||||||
FileCloser fhClose(fh);
|
FileCloser fhClose(fh);
|
||||||
|
|
||||||
const char *langname = strrchr(file, PATHSEPCHAR);
|
auto pos = file.rfind(PATHSEPCHAR);
|
||||||
if (langname == nullptr) {
|
if (pos == std::string::npos) return LanguageStrings();
|
||||||
langname = file;
|
std::string langname = file.substr(pos + 1);
|
||||||
|
|
||||||
|
/* Check for invalid empty filename */
|
||||||
|
if (langname.empty() || langname.front() == '.') return LanguageStrings();
|
||||||
|
|
||||||
|
LanguageStrings ret(langname.substr(0, langname.find('.')));
|
||||||
|
|
||||||
|
char buffer[2048];
|
||||||
|
while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != nullptr) {
|
||||||
|
size_t len = strlen(buffer);
|
||||||
|
|
||||||
|
/* Remove trailing spaces/newlines from the string. */
|
||||||
|
size_t i = len;
|
||||||
|
while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--;
|
||||||
|
buffer[i] = '\0';
|
||||||
|
|
||||||
|
ret.lines.emplace_back(buffer, i);
|
||||||
|
|
||||||
|
if (len > to_read) {
|
||||||
|
to_read = 0;
|
||||||
} else {
|
} else {
|
||||||
langname++;
|
to_read -= len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for invalid empty filename */
|
|
||||||
if (*langname == '.' || *langname == 0) return nullptr;
|
|
||||||
|
|
||||||
std::unique_ptr<LanguageStrings> ret(new LanguageStrings(langname, strchr(langname, '.')));
|
|
||||||
|
|
||||||
char buffer[2048];
|
|
||||||
while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != nullptr) {
|
|
||||||
size_t len = strlen(buffer);
|
|
||||||
|
|
||||||
/* Remove trailing spaces/newlines from the string. */
|
|
||||||
size_t i = len;
|
|
||||||
while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--;
|
|
||||||
buffer[i] = '\0';
|
|
||||||
|
|
||||||
ret->lines.emplace_back(buffer, i);
|
|
||||||
|
|
||||||
if (len > to_read) {
|
|
||||||
to_read = 0;
|
|
||||||
} else {
|
|
||||||
to_read -= len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
} catch (...) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,7 +115,7 @@ struct StringListReader : StringReader {
|
||||||
* @param translation Are we reading a translation?
|
* @param translation Are we reading a translation?
|
||||||
*/
|
*/
|
||||||
StringListReader(StringData &data, const LanguageStrings &strings, bool master, bool translation) :
|
StringListReader(StringData &data, const LanguageStrings &strings, bool master, bool translation) :
|
||||||
StringReader(data, strings.language, master, translation), p(strings.lines.begin()), end(strings.lines.end())
|
StringReader(data, strings.language.c_str(), master, translation), p(strings.lines.begin()), end(strings.lines.end())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,12 +192,11 @@ struct StringNameWriter : HeaderWriter {
|
||||||
class LanguageScanner : protected FileScanner {
|
class LanguageScanner : protected FileScanner {
|
||||||
private:
|
private:
|
||||||
GameStrings *gs;
|
GameStrings *gs;
|
||||||
char *exclude;
|
std::string exclude;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Initialise */
|
/** Initialise */
|
||||||
LanguageScanner(GameStrings *gs, const char *exclude) : gs(gs), exclude(stredup(exclude)) {}
|
LanguageScanner(GameStrings *gs, const std::string &exclude) : gs(gs), exclude(exclude) {}
|
||||||
~LanguageScanner() { free(exclude); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan.
|
* Scan.
|
||||||
|
@ -232,10 +208,10 @@ public:
|
||||||
|
|
||||||
bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override
|
bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override
|
||||||
{
|
{
|
||||||
if (strcmp(filename, exclude) == 0) return true;
|
if (exclude == filename) return true;
|
||||||
|
|
||||||
auto ls = ReadRawLanguageStrings(filename);
|
auto ls = ReadRawLanguageStrings(filename);
|
||||||
if (ls == nullptr) return false;
|
if (!ls.IsValid()) return false;
|
||||||
|
|
||||||
gs->raw_strings.push_back(std::move(ls));
|
gs->raw_strings.push_back(std::move(ls));
|
||||||
return true;
|
return true;
|
||||||
|
@ -249,17 +225,16 @@ public:
|
||||||
GameStrings *LoadTranslations()
|
GameStrings *LoadTranslations()
|
||||||
{
|
{
|
||||||
const GameInfo *info = Game::GetInfo();
|
const GameInfo *info = Game::GetInfo();
|
||||||
char filename[512];
|
std::string basename(info->GetMainScript());
|
||||||
strecpy(filename, info->GetMainScript(), lastof(filename));
|
auto e = basename.rfind(PATHSEPCHAR);
|
||||||
char *e = strrchr(filename, PATHSEPCHAR);
|
if (e == std::string::npos) return nullptr;
|
||||||
if (e == nullptr) return nullptr;
|
basename.erase(e + 1);
|
||||||
e++; // Make 'e' point after the PATHSEPCHAR
|
|
||||||
|
|
||||||
strecpy(e, "lang" PATHSEP "english.txt", lastof(filename));
|
std::string filename = basename + "lang" PATHSEP "english.txt";
|
||||||
if (!FioCheckFileExists(filename, GAME_DIR)) return nullptr;
|
if (!FioCheckFileExists(filename.c_str() , GAME_DIR)) return nullptr;
|
||||||
|
|
||||||
auto ls = ReadRawLanguageStrings(filename);
|
auto ls = ReadRawLanguageStrings(filename);
|
||||||
if (ls == nullptr) return nullptr;
|
if (!ls.IsValid()) return nullptr;
|
||||||
|
|
||||||
GameStrings *gs = new GameStrings();
|
GameStrings *gs = new GameStrings();
|
||||||
try {
|
try {
|
||||||
|
@ -267,8 +242,7 @@ GameStrings *LoadTranslations()
|
||||||
|
|
||||||
/* Scan for other language files */
|
/* Scan for other language files */
|
||||||
LanguageScanner scanner(gs, filename);
|
LanguageScanner scanner(gs, filename);
|
||||||
strecpy(e, "lang" PATHSEP, lastof(filename));
|
std::string ldir = basename + "lang" PATHSEP;
|
||||||
size_t len = strlen(filename);
|
|
||||||
|
|
||||||
const char *tar_filename = info->GetTarFile();
|
const char *tar_filename = info->GetTarFile();
|
||||||
TarList::iterator iter;
|
TarList::iterator iter;
|
||||||
|
@ -281,14 +255,14 @@ GameStrings *LoadTranslations()
|
||||||
if (tar->second.tar_filename != iter->first) continue;
|
if (tar->second.tar_filename != iter->first) continue;
|
||||||
|
|
||||||
/* Check the path and extension. */
|
/* Check the path and extension. */
|
||||||
if (tar->first.size() <= len || tar->first.compare(0, len, filename) != 0) continue;
|
if (tar->first.size() <= ldir.size() || tar->first.compare(0, ldir.size(), ldir) != 0) continue;
|
||||||
if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue;
|
if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue;
|
||||||
|
|
||||||
scanner.AddFile(tar->first.c_str(), 0, tar_filename);
|
scanner.AddFile(tar->first.c_str(), 0, tar_filename);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Scan filesystem */
|
/* Scan filesystem */
|
||||||
scanner.Scan(filename);
|
scanner.Scan(ldir.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
gs->Compile();
|
gs->Compile();
|
||||||
|
@ -303,7 +277,7 @@ GameStrings *LoadTranslations()
|
||||||
void GameStrings::Compile()
|
void GameStrings::Compile()
|
||||||
{
|
{
|
||||||
StringData data(32);
|
StringData data(32);
|
||||||
StringListReader master_reader(data, *this->raw_strings[0], true, false);
|
StringListReader master_reader(data, this->raw_strings[0], true, false);
|
||||||
master_reader.ParseFile();
|
master_reader.ParseFile();
|
||||||
if (_errors != 0) throw std::exception();
|
if (_errors != 0) throw std::exception();
|
||||||
|
|
||||||
|
@ -314,12 +288,12 @@ void GameStrings::Compile()
|
||||||
|
|
||||||
for (const auto &p : this->raw_strings) {
|
for (const auto &p : this->raw_strings) {
|
||||||
data.FreeTranslation();
|
data.FreeTranslation();
|
||||||
StringListReader translation_reader(data, *p, false, strcmp(p->language, "english") != 0);
|
StringListReader translation_reader(data, p, false, p.language != "english");
|
||||||
translation_reader.ParseFile();
|
translation_reader.ParseFile();
|
||||||
if (_errors != 0) throw std::exception();
|
if (_errors != 0) throw std::exception();
|
||||||
|
|
||||||
this->compiled_strings.emplace_back(new LanguageStrings(p->language));
|
this->compiled_strings.emplace_back(p.language);
|
||||||
TranslationWriter writer(this->compiled_strings.back()->lines);
|
TranslationWriter writer(this->compiled_strings.back().lines);
|
||||||
writer.WriteLang(data);
|
writer.WriteLang(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,11 +361,11 @@ void ReconsiderGameScriptLanguage()
|
||||||
language++;
|
language++;
|
||||||
|
|
||||||
for (auto &p : _current_data->compiled_strings) {
|
for (auto &p : _current_data->compiled_strings) {
|
||||||
if (strcmp(p->language, language) == 0) {
|
if (p.language == language) {
|
||||||
_current_data->cur_language = p;
|
_current_data->cur_language = &p;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_current_data->cur_language = _current_data->compiled_strings[0];
|
_current_data->cur_language = &_current_data->compiled_strings[0];
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,23 +18,34 @@ void ReconsiderGameScriptLanguage();
|
||||||
|
|
||||||
/** Container for the raw (unencoded) language strings of a language. */
|
/** Container for the raw (unencoded) language strings of a language. */
|
||||||
struct LanguageStrings {
|
struct LanguageStrings {
|
||||||
const char *language; ///< Name of the language (base filename).
|
std::string language; ///< Name of the language (base filename). Empty string if invalid.
|
||||||
StringList lines; ///< The lines of the file to pass into the parser/encoder.
|
StringList lines; ///< The lines of the file to pass into the parser/encoder.
|
||||||
|
|
||||||
LanguageStrings(const char *language, const char *end = nullptr);
|
LanguageStrings() {}
|
||||||
~LanguageStrings();
|
LanguageStrings(const std::string &lang) : language(lang) {}
|
||||||
|
LanguageStrings(const LanguageStrings &other) : language(other.language), lines(other.lines) {}
|
||||||
|
LanguageStrings(LanguageStrings &&other) : language(std::move(other.language)), lines(std::move(other.lines)) {}
|
||||||
|
|
||||||
|
bool IsValid() const { return !this->language.empty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Container for all the game strings. */
|
/** Container for all the game strings. */
|
||||||
struct GameStrings {
|
struct GameStrings {
|
||||||
uint version; ///< The version of the language strings.
|
uint version; ///< The version of the language strings.
|
||||||
std::shared_ptr<LanguageStrings> cur_language; ///< The current (compiled) language.
|
LanguageStrings *cur_language; ///< The current (compiled) language.
|
||||||
|
|
||||||
std::vector<std::unique_ptr<LanguageStrings>> raw_strings; ///< The raw strings per language, first must be English/the master language!.
|
std::vector<LanguageStrings> raw_strings; ///< The raw strings per language, first must be English/the master language!.
|
||||||
std::vector<std::shared_ptr<LanguageStrings>> compiled_strings; ///< The compiled strings per language, first must be English/the master language!.
|
std::vector<LanguageStrings> compiled_strings; ///< The compiled strings per language, first must be English/the master language!.
|
||||||
StringList string_names; ///< The names of the compiled strings.
|
StringList string_names; ///< The names of the compiled strings.
|
||||||
|
|
||||||
void Compile();
|
void Compile();
|
||||||
|
|
||||||
|
GameStrings() = default;
|
||||||
|
|
||||||
|
GameStrings(const GameStrings &) = delete;
|
||||||
|
GameStrings(GameStrings &&) = delete;
|
||||||
|
GameStrings &operator=(const GameStrings &) = delete;
|
||||||
|
GameStrings &operator=(GameStrings &&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* GAME_TEXT_HPP */
|
#endif /* GAME_TEXT_HPP */
|
||||||
|
|
|
@ -113,23 +113,23 @@ static void Save_GSDT()
|
||||||
|
|
||||||
extern GameStrings *_current_data;
|
extern GameStrings *_current_data;
|
||||||
|
|
||||||
static const char *_game_saveload_string;
|
static std::string _game_saveload_string;
|
||||||
static uint _game_saveload_strings;
|
static uint _game_saveload_strings;
|
||||||
|
|
||||||
static const SaveLoad _game_language_header[] = {
|
static const SaveLoad _game_language_header[] = {
|
||||||
SLEG_STR(_game_saveload_string, SLE_STR),
|
SLEG_SSTR(_game_saveload_string, SLE_STR),
|
||||||
SLEG_VAR(_game_saveload_strings, SLE_UINT32),
|
SLEG_VAR(_game_saveload_strings, SLE_UINT32),
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SaveLoad _game_language_string[] = {
|
static const SaveLoad _game_language_string[] = {
|
||||||
SLEG_STR(_game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL),
|
SLEG_SSTR(_game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL),
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
static void SaveReal_GSTR(const LanguageStrings *ls)
|
static void SaveReal_GSTR(const LanguageStrings *ls)
|
||||||
{
|
{
|
||||||
_game_saveload_string = ls->language;
|
_game_saveload_string = ls->language.c_str();
|
||||||
_game_saveload_strings = (uint)ls->lines.size();
|
_game_saveload_strings = (uint)ls->lines.size();
|
||||||
|
|
||||||
SlObject(nullptr, _game_language_header);
|
SlObject(nullptr, _game_language_header);
|
||||||
|
@ -145,13 +145,13 @@ static void Load_GSTR()
|
||||||
_current_data = new GameStrings();
|
_current_data = new GameStrings();
|
||||||
|
|
||||||
while (SlIterateArray() != -1) {
|
while (SlIterateArray() != -1) {
|
||||||
_game_saveload_string = nullptr;
|
_game_saveload_string.clear();
|
||||||
SlObject(nullptr, _game_language_header);
|
SlObject(nullptr, _game_language_header);
|
||||||
|
|
||||||
std::unique_ptr<LanguageStrings> ls(new LanguageStrings(_game_saveload_string != nullptr ? _game_saveload_string : ""));
|
LanguageStrings ls(_game_saveload_string);
|
||||||
for (uint i = 0; i < _game_saveload_strings; i++) {
|
for (uint i = 0; i < _game_saveload_strings; i++) {
|
||||||
SlObject(nullptr, _game_language_string);
|
SlObject(nullptr, _game_language_string);
|
||||||
ls->lines.emplace_back(_game_saveload_string != nullptr ? _game_saveload_string : "");
|
ls.lines.emplace_back(_game_saveload_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
_current_data->raw_strings.push_back(std::move(ls));
|
_current_data->raw_strings.push_back(std::move(ls));
|
||||||
|
@ -174,7 +174,7 @@ static void Save_GSTR()
|
||||||
|
|
||||||
for (uint i = 0; i < _current_data->raw_strings.size(); i++) {
|
for (uint i = 0; i < _current_data->raw_strings.size(); i++) {
|
||||||
SlSetArrayIndex(i);
|
SlSetArrayIndex(i);
|
||||||
SlAutolength((AutolengthProc *)SaveReal_GSTR, _current_data->raw_strings[i].get());
|
SlAutolength((AutolengthProc *)SaveReal_GSTR, &_current_data->raw_strings[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "../fios.h"
|
#include "../fios.h"
|
||||||
#include "../error.h"
|
#include "../error.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
|
@ -901,6 +902,21 @@ static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType con
|
||||||
return len + SlGetArrayLength(len); // also include the length of the index
|
return len + SlGetArrayLength(len); // also include the length of the index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the gross length of the string that it
|
||||||
|
* will occupy in the savegame. This includes the real length, returned
|
||||||
|
* by SlCalcNetStringLen and the length that the index will occupy.
|
||||||
|
* @param ptr Pointer to the \c std::string.
|
||||||
|
* @return The gross length of the string.
|
||||||
|
*/
|
||||||
|
static inline size_t SlCalcStdStringLen(const void *ptr)
|
||||||
|
{
|
||||||
|
const std::string *str = reinterpret_cast<const std::string *>(ptr);
|
||||||
|
|
||||||
|
size_t len = str->length();
|
||||||
|
return len + SlGetArrayLength(len); // also include the length of the index
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save/Load a string.
|
* Save/Load a string.
|
||||||
* @param ptr the string being manipulated
|
* @param ptr the string being manipulated
|
||||||
|
@ -980,6 +996,53 @@ static void SlString(void *ptr, size_t length, VarType conv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save/Load a \c std::string.
|
||||||
|
* @param ptr the string being manipulated
|
||||||
|
* @param conv must be SLE_FILE_STRING
|
||||||
|
*/
|
||||||
|
static void SlStdString(void *ptr, VarType conv)
|
||||||
|
{
|
||||||
|
std::string *str = reinterpret_cast<std::string *>(ptr);
|
||||||
|
|
||||||
|
switch (_sl.action) {
|
||||||
|
case SLA_SAVE: {
|
||||||
|
size_t len = str->length();
|
||||||
|
SlWriteArrayLength(len);
|
||||||
|
SlCopyBytes(const_cast<void *>(static_cast<const void *>(str->c_str())), len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SLA_LOAD_CHECK:
|
||||||
|
case SLA_LOAD: {
|
||||||
|
size_t len = SlReadArrayLength();
|
||||||
|
char *buf = AllocaM(char, len + 1);
|
||||||
|
|
||||||
|
SlCopyBytes(buf, len);
|
||||||
|
buf[len] = '\0'; // properly terminate the string
|
||||||
|
|
||||||
|
StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK;
|
||||||
|
if ((conv & SLF_ALLOW_CONTROL) != 0) {
|
||||||
|
settings = settings | SVS_ALLOW_CONTROL_CODE;
|
||||||
|
if (IsSavegameVersionBefore(SLV_169)) {
|
||||||
|
str_fix_scc_encoded(buf, buf + len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((conv & SLF_ALLOW_NEWLINE) != 0) {
|
||||||
|
settings = settings | SVS_ALLOW_NEWLINE;
|
||||||
|
}
|
||||||
|
str_validate(buf, buf + len, settings);
|
||||||
|
|
||||||
|
// Store sanitized string.
|
||||||
|
str->assign(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
case SLA_PTRS: break;
|
||||||
|
case SLA_NULL: break;
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the size in bytes of a certain type of atomic array
|
* Return the size in bytes of a certain type of atomic array
|
||||||
* @param length The length of the array counted in elements
|
* @param length The length of the array counted in elements
|
||||||
|
@ -1403,6 +1466,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
|
||||||
case SL_STR:
|
case SL_STR:
|
||||||
case SL_LST:
|
case SL_LST:
|
||||||
case SL_DEQUE:
|
case SL_DEQUE:
|
||||||
|
case SL_STDSTR:
|
||||||
/* CONDITIONAL saveload types depend on the savegame version */
|
/* CONDITIONAL saveload types depend on the savegame version */
|
||||||
if (!SlIsObjectValidInSavegame(sld)) break;
|
if (!SlIsObjectValidInSavegame(sld)) break;
|
||||||
|
|
||||||
|
@ -1413,6 +1477,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
|
||||||
case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
|
case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
|
||||||
case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
|
case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
|
||||||
case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld->conv);
|
case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld->conv);
|
||||||
|
case SL_STDSTR: return SlCalcStdStringLen(GetVariableAddress(object, sld));
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1461,6 +1526,10 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
|
||||||
/* These should be pointer sized, or fixed array. */
|
/* These should be pointer sized, or fixed array. */
|
||||||
return sld->size == sizeof(void *) || sld->size == sld->length;
|
return sld->size == sizeof(void *) || sld->size == sld->length;
|
||||||
|
|
||||||
|
case SL_STDSTR:
|
||||||
|
/* These should be all pointers to std::string. */
|
||||||
|
return sld->size == sizeof(std::string);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1482,6 +1551,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
||||||
case SL_STR:
|
case SL_STR:
|
||||||
case SL_LST:
|
case SL_LST:
|
||||||
case SL_DEQUE:
|
case SL_DEQUE:
|
||||||
|
case SL_STDSTR:
|
||||||
/* CONDITIONAL saveload types depend on the savegame version */
|
/* CONDITIONAL saveload types depend on the savegame version */
|
||||||
if (!SlIsObjectValidInSavegame(sld)) return false;
|
if (!SlIsObjectValidInSavegame(sld)) return false;
|
||||||
if (SlSkipVariableOnLoad(sld)) return false;
|
if (SlSkipVariableOnLoad(sld)) return false;
|
||||||
|
@ -1510,6 +1580,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
||||||
case SL_STR: SlString(ptr, sld->length, sld->conv); break;
|
case SL_STR: SlString(ptr, sld->length, sld->conv); break;
|
||||||
case SL_LST: SlList(ptr, (SLRefType)conv); break;
|
case SL_LST: SlList(ptr, (SLRefType)conv); break;
|
||||||
case SL_DEQUE: SlDeque(ptr, conv); break;
|
case SL_DEQUE: SlDeque(ptr, conv); break;
|
||||||
|
case SL_STDSTR: SlStdString(ptr, sld->conv); break;
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -485,6 +485,7 @@ enum SaveLoadTypes {
|
||||||
SL_STR = 3, ///< Save/load a string.
|
SL_STR = 3, ///< Save/load a string.
|
||||||
SL_LST = 4, ///< Save/load a list.
|
SL_LST = 4, ///< Save/load a list.
|
||||||
SL_DEQUE = 5, ///< Save/load a deque.
|
SL_DEQUE = 5, ///< Save/load a deque.
|
||||||
|
SL_STDSTR = 6, ///< Save/load a \c std::string.
|
||||||
/* non-normal save-load types */
|
/* non-normal save-load types */
|
||||||
SL_WRITEBYTE = 8,
|
SL_WRITEBYTE = 8,
|
||||||
SL_VEH_INCLUDE = 9,
|
SL_VEH_INCLUDE = 9,
|
||||||
|
@ -567,6 +568,16 @@ typedef SaveLoad SaveLoadGlobVarList;
|
||||||
*/
|
*/
|
||||||
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to)
|
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage of a \c std::string in some savegame versions.
|
||||||
|
* @param base Name of the class or struct containing the string.
|
||||||
|
* @param variable Name of the variable in the class or struct referenced by \a base.
|
||||||
|
* @param type Storage of the data in memory and in the savegame.
|
||||||
|
* @param from First savegame version that has the string.
|
||||||
|
* @param to Last savegame version that has the string.
|
||||||
|
*/
|
||||||
|
#define SLE_CONDSSTR(base, variable, type, from, to) SLE_GENERAL(SL_STDSTR, base, variable, type, 0, from, to)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of a list in some savegame versions.
|
* Storage of a list in some savegame versions.
|
||||||
* @param base Name of the class or struct containing the list.
|
* @param base Name of the class or struct containing the list.
|
||||||
|
@ -621,6 +632,14 @@ typedef SaveLoad SaveLoadGlobVarList;
|
||||||
*/
|
*/
|
||||||
#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, SL_MIN_VERSION, SL_MAX_VERSION)
|
#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, SL_MIN_VERSION, SL_MAX_VERSION)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage of a \c std::string in every savegame version.
|
||||||
|
* @param base Name of the class or struct containing the string.
|
||||||
|
* @param variable Name of the variable in the class or struct referenced by \a base.
|
||||||
|
* @param type Storage of the data in memory and in the savegame.
|
||||||
|
*/
|
||||||
|
#define SLE_SSTR(base, variable, type) SLE_CONDSSTR(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of a list in every savegame version.
|
* Storage of a list in every savegame version.
|
||||||
* @param base Name of the class or struct containing the list.
|
* @param base Name of the class or struct containing the list.
|
||||||
|
@ -701,6 +720,15 @@ typedef SaveLoad SaveLoadGlobVarList;
|
||||||
*/
|
*/
|
||||||
#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to)
|
#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage of a global \c std::string in some savegame versions.
|
||||||
|
* @param variable Name of the global variable.
|
||||||
|
* @param type Storage of the data in memory and in the savegame.
|
||||||
|
* @param from First savegame version that has the string.
|
||||||
|
* @param to Last savegame version that has the string.
|
||||||
|
*/
|
||||||
|
#define SLEG_CONDSSTR(variable, type, from, to) SLEG_GENERAL(SL_STDSTR, variable, type, 0, from, to)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of a global list in some savegame versions.
|
* Storage of a global list in some savegame versions.
|
||||||
* @param variable Name of the global variable.
|
* @param variable Name of the global variable.
|
||||||
|
@ -738,6 +766,13 @@ typedef SaveLoad SaveLoadGlobVarList;
|
||||||
*/
|
*/
|
||||||
#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, sizeof(variable), SL_MIN_VERSION, SL_MAX_VERSION)
|
#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, sizeof(variable), SL_MIN_VERSION, SL_MAX_VERSION)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage of a global \c std::string in every savegame version.
|
||||||
|
* @param variable Name of the global variable.
|
||||||
|
* @param type Storage of the data in memory and in the savegame.
|
||||||
|
*/
|
||||||
|
#define SLEG_SSTR(variable, type) SLEG_CONDSSTR(variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of a global list in every savegame version.
|
* Storage of a global list in every savegame version.
|
||||||
* @param variable Name of the global variable.
|
* @param variable Name of the global variable.
|
||||||
|
|
Loading…
Reference in New Issue