Saveload: Add value conversion support to settings xref
This commit is contained in:
@@ -1530,6 +1530,10 @@ static int OrderTownGrowthRate(uint nth)
|
||||
|
||||
/* End - GUI order callbacks */
|
||||
|
||||
/* Begin - xref conversion callbacks */
|
||||
|
||||
/* End - xref conversion callbacks */
|
||||
|
||||
/**
|
||||
* Prepare for reading and old diff_custom by zero-ing the memory.
|
||||
*/
|
||||
@@ -2368,9 +2372,9 @@ void IConsoleListSettings(const char *prefilter)
|
||||
* a pointer to a struct which is getting saved
|
||||
*/
|
||||
static void LoadSettingsXref(const SettingDesc *osd, void *object) {
|
||||
DEBUG(sl, 3, "PATS chunk: Loading xref setting: '%s'", osd->xref);
|
||||
DEBUG(sl, 3, "PATS chunk: Loading xref setting: '%s'", osd->xref.target);
|
||||
uint index = 0;
|
||||
const SettingDesc *setting_xref = GetSettingFromName(osd->xref, &index, true);
|
||||
const SettingDesc *setting_xref = GetSettingFromName(osd->xref.target, &index, true);
|
||||
assert(setting_xref != nullptr);
|
||||
|
||||
// Generate a new SaveLoad from the xref target using the version params from the source
|
||||
@@ -2381,7 +2385,9 @@ static void LoadSettingsXref(const SettingDesc *osd, void *object) {
|
||||
void *ptr = GetVariableAddress(object, &sld);
|
||||
|
||||
if (!SlObjectMember(ptr, &sld)) return;
|
||||
if (IsNumericType(sld.conv)) Write_ValidateSetting(ptr, setting_xref, ReadValue(ptr, sld.conv));
|
||||
int64 val = ReadValue(ptr, sld.conv);
|
||||
if (osd->xref.conv != nullptr) val = osd->xref.conv(val);
|
||||
if (IsNumericType(sld.conv)) Write_ValidateSetting(ptr, setting_xref, val);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2397,7 +2403,7 @@ static void LoadSettings(const SettingDesc *osd, void *object)
|
||||
for (; osd->save.cmd != SL_END; osd++) {
|
||||
if (osd->patx_name != nullptr) continue;
|
||||
const SaveLoad *sld = &osd->save;
|
||||
if (osd->xref != nullptr) {
|
||||
if (osd->xref.target != nullptr) {
|
||||
if (sld->ext_feature_test.IsFeaturePresent(_sl_version, sld->version_from, sld->version_to)) LoadSettingsXref(osd, object);
|
||||
continue;
|
||||
}
|
||||
@@ -2422,7 +2428,7 @@ static void SaveSettings(const SettingDesc *sd, void *object)
|
||||
size_t length = 0;
|
||||
for (i = sd; i->save.cmd != SL_END; i++) {
|
||||
if (i->patx_name != nullptr) continue;
|
||||
if (i->xref != nullptr) continue;
|
||||
if (i->xref.target != nullptr) continue;
|
||||
length += SlCalcObjMemberLength(object, &i->save);
|
||||
}
|
||||
SlSetLength(length);
|
||||
|
@@ -89,6 +89,7 @@ enum SettingType {
|
||||
typedef bool OnChange(int32 var); ///< callback prototype on data modification
|
||||
typedef size_t OnConvert(const char *value); ///< callback prototype for conversion error
|
||||
typedef int OnGuiOrder(uint nth); ///< callback prototype for GUI ordering
|
||||
typedef int64 OnXrefValueConvert(int64 val); ///< callback prototype for xref value conversion
|
||||
|
||||
/** The last entry in an array of struct SettingDescEnumEntry must use STR_NULL. */
|
||||
struct SettingDescEnumEntry {
|
||||
@@ -115,11 +116,19 @@ struct SettingDescBase {
|
||||
const SettingDescEnumEntry *enumlist; ///< For SGF_ENUM. The last entry must use STR_NULL
|
||||
};
|
||||
|
||||
struct SettingsXref {
|
||||
const char *target;
|
||||
OnXrefValueConvert *conv;
|
||||
|
||||
SettingsXref() : target(nullptr), conv(nullptr) {}
|
||||
SettingsXref(const char *target_, OnXrefValueConvert *conv_) : target(target_), conv(conv_) {}
|
||||
};
|
||||
|
||||
struct SettingDesc {
|
||||
SettingDescBase desc; ///< Settings structure (going to configuration file)
|
||||
SaveLoad save; ///< Internal structure (going to savegame, parts to config)
|
||||
const char *patx_name; ///< Name to save/load setting from in PATX chunk, if nullptr save/load from PATS chunk as normal
|
||||
const char *xref; ///< Name of SettingDesc to use instead of the contents of this one, useful for loading legacy savegames, if nullptr save/load as normal
|
||||
SettingsXref xref; ///< Details of SettingDesc to use instead of the contents of this one, useful for loading legacy savegames, if target field nullptr save/load as normal
|
||||
OnGuiOrder *orderproc; ///< Callback procedure for GUI re-ordering
|
||||
|
||||
bool IsEditable(bool do_command = false) const;
|
||||
|
@@ -60,7 +60,7 @@ static size_t ConvertLandscape(const char *value);
|
||||
/* Macros for various objects to go in the configuration file.
|
||||
* This section is for global variables */
|
||||
#define SDTG_GENERAL2(name, sdt_cmd, sle_cmd, type, flags, guiflags, var, length, def, min, max, interval, full, str, strhelp, strval, proc, from, to, cat, extver, patxname, orderproc, enumlist)\
|
||||
{NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, nullptr, cat, enumlist), SLEG_GENERAL_X(sle_cmd, var, type | flags, length, from, to, extver), patxname, nullptr, orderproc}
|
||||
{NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, nullptr, cat, enumlist), SLEG_GENERAL_X(sle_cmd, var, type | flags, length, from, to, extver), patxname, SettingsXref(), orderproc}
|
||||
|
||||
#define SDTG_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, var, length, def, min, max, interval, full, str, strhelp, strval, proc, from, to, cat, extver, patxname)\
|
||||
SDTG_GENERAL2(name, sdt_cmd, sle_cmd, type, flags, guiflags, var, length, def, min, max, interval, full, str, strhelp, strval, proc, from, to, cat, extver, patxname, nullptr, nullptr)
|
||||
@@ -87,14 +87,14 @@ static size_t ConvertLandscape(const char *value);
|
||||
SDTG_GENERAL(name, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, 0, 0, full, str, strhelp, strval, proc, from, to, cat, extver, patxname)
|
||||
|
||||
#define SDTG_NULL(length, from, to, extver)\
|
||||
{{"", nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLEG_NULL_X(length, from, to, extver), nullptr, nullptr, nullptr}
|
||||
{{"", nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLEG_NULL_X(length, from, to, extver), nullptr, SettingsXref(), nullptr}
|
||||
|
||||
#define SDTG_END() {{nullptr, nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLEG_END(), nullptr, nullptr, nullptr}
|
||||
#define SDTG_END() {{nullptr, nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLEG_END(), nullptr, SettingsXref(), nullptr}
|
||||
|
||||
/* Macros for various objects to go in the configuration file.
|
||||
* This section is for structures where their various members are saved */
|
||||
#define SDT_GENERAL2(name, sdt_cmd, sle_cmd, type, flags, guiflags, base, var, length, def, min, max, interval, full, str, strhelp, strval, proc, load, from, to, cat, extver, patxname, orderproc, enumlist)\
|
||||
{NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, load, cat, enumlist), SLE_GENERAL_X(sle_cmd, base, var, type | flags, length, from, to, extver), patxname, nullptr, orderproc}
|
||||
{NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, load, cat, enumlist), SLE_GENERAL_X(sle_cmd, base, var, type | flags, length, from, to, extver), patxname, SettingsXref(), orderproc}
|
||||
|
||||
#define SDT_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, base, var, length, def, min, max, interval, full, str, strhelp, strval, proc, load, from, to, cat, extver, patxname)\
|
||||
SDT_GENERAL2(name, sdt_cmd, sle_cmd, type, flags, guiflags, base, var, length, def, min, max, interval, full, str, strhelp, strval, proc, load, from, to, cat, extver, patxname, nullptr, nullptr)
|
||||
@@ -124,7 +124,7 @@ static size_t ConvertLandscape(const char *value);
|
||||
SDT_GENERAL(#var, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, 0, 0, full, str, strhelp, strval, proc, nullptr, from, to, cat, extver, patxname)
|
||||
|
||||
#define SDT_NULL(length, from, to, extver)\
|
||||
{{"", nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLE_CONDNULL_X(length, from, to, extver), nullptr, nullptr, nullptr}
|
||||
{{"", nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLE_CONDNULL_X(length, from, to, extver), nullptr, SettingsXref(), nullptr}
|
||||
|
||||
|
||||
#define SDTC_VAR(var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, proc, from, to, cat, extver, patxname, orderproc)\
|
||||
@@ -145,8 +145,8 @@ static size_t ConvertLandscape(const char *value);
|
||||
#define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, cat, extver, patxname)\
|
||||
SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat, extver, patxname)
|
||||
|
||||
#define SDT_XREF(from, to, extver, xref)\
|
||||
{{"", nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLE_CONDNULL_X(0, from, to, extver), nullptr, xref, nullptr}
|
||||
#define SDT_XREF(from, to, extver, xref, xrefcvt)\
|
||||
{{"", nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLE_CONDNULL_X(0, from, to, extver), nullptr, SettingsXref(xref, xrefcvt), nullptr}
|
||||
|
||||
#define SDT_END() {{nullptr, nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLE_END(), nullptr, nullptr, nullptr}
|
||||
#define SDT_END() {{nullptr, nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE, nullptr}, SLE_END(), nullptr, SettingsXref(), nullptr}
|
||||
|
||||
|
@@ -65,6 +65,10 @@ static int OrderTownGrowthRate(uint nth);
|
||||
|
||||
/* End - GUI order callbacks */
|
||||
|
||||
/* Begin - xref conversion callbacks */
|
||||
|
||||
/* End - xref conversion callbacks */
|
||||
|
||||
static const SettingDescEnumEntry _linkgraph_mode_symmetric[] = {
|
||||
{ DT_MANUAL, STR_CONFIG_SETTING_DISTRIBUTION_MANUAL },
|
||||
{ DT_SYMMETRIC, STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC },
|
||||
@@ -118,7 +122,7 @@ SDT_STR = SDT_STR($base, $var, $type, $flags, $guiflags, $def,
|
||||
SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver, $patxname, $orderproc),
|
||||
SDT_ENUM = SDT_ENUM($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $proc, $from, $to, $cat, $extver, $patxname, $enumlist),
|
||||
SDT_NULL = SDT_NULL($length, $from, $to, $extver),
|
||||
SDT_XREF = SDT_XREF( $from, $to, $extver, $xref),
|
||||
SDT_XREF = SDT_XREF( $from, $to, $extver, $xref, $xrefcvt),
|
||||
SDT_END = SDT_END()
|
||||
|
||||
SDT_LINKGRAPH_PER_CARGO = SDT_ENUM(GameSettings, linkgraph.distribution_per_cargo[$linkgraph_cargo], SLE_UINT8, $flags | SLF_NOT_IN_CONFIG, $guiflags | SGF_NO_NEWGAME, DT_PER_CARGO_DEFAULT, STR_CONFIG_SETTING_DISTRIBUTION_PER_CARGO, STR_CONFIG_SETTING_DISTRIBUTION_PER_CARGO_HELPTEXT, $proc, $from, $to, SC_EXPERT, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_MODES), nullptr, _linkgraph_mode_per_cargo),
|
||||
@@ -138,6 +142,7 @@ cat = SC_ADVANCED
|
||||
extver = SlXvFeatureTest()
|
||||
patxname = nullptr
|
||||
xref = <this parameter must be set>
|
||||
xrefcvt = nullptr
|
||||
orderproc = nullptr
|
||||
enumlist = <this parameter must be set>
|
||||
|
||||
|
Reference in New Issue
Block a user