mirror of
https://github.com/geode-sdk/geode.git
synced 2025-02-17 00:30:26 -05:00
fix setting value changes not being broadcast
This commit is contained in:
parent
93bf3e7121
commit
7089194be9
6 changed files with 130 additions and 22 deletions
|
@ -102,7 +102,34 @@ namespace geode {
|
|||
bool hasSetting(std::string const& key) const;
|
||||
std::optional<Setting> getSettingDefinition(std::string const& key) const;
|
||||
SettingValue* getSetting(std::string const& key) const;
|
||||
|
||||
/**
|
||||
* Register a custom setting's value class. See Mod::addCustomSetting
|
||||
* for a convenience wrapper that creates the value in-place to avoid
|
||||
* code duplication. Also see
|
||||
* [the tutorial page](https://docs.geode-sdk.org/mods/settings) for
|
||||
* more information about custom settings
|
||||
* @param key The setting's key
|
||||
* @param value The SettingValue class that shall handle this setting
|
||||
* @see addCustomSetting
|
||||
*/
|
||||
void registerCustomSetting(std::string const& key, std::unique_ptr<SettingValue> value);
|
||||
/**
|
||||
* Register a custom setting's value class. The new SettingValue class
|
||||
* will be created in-place using `std::make_unique`. See
|
||||
* [the tutorial page](https://docs.geode-sdk.org/mods/settings) for
|
||||
* more information about custom settings
|
||||
* @param key The setting's key
|
||||
* @param value The value of the custom setting
|
||||
* @example
|
||||
* $on_mod(Loaded) {
|
||||
* Mod::get()->addCustomSetting<MySettingValue>("setting-key", DEFAULT_VALUE);
|
||||
* }
|
||||
*/
|
||||
template <class T, class V>
|
||||
void addCustomSetting(std::string const& key, V const& value) {
|
||||
this->registerCustomSetting(key, std::make_unique<T>(key, this->getID(), value));
|
||||
}
|
||||
|
||||
json::Value& getSaveContainer();
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace geode {
|
|||
struct JsonMaybeObject;
|
||||
struct JsonMaybeValue;
|
||||
|
||||
/**
|
||||
* A Setting for a boolean value. Represented in-game as a simple toggle
|
||||
*/
|
||||
struct GEODE_DLL BoolSetting final {
|
||||
using ValueType = bool;
|
||||
|
||||
|
@ -28,6 +31,10 @@ namespace geode {
|
|||
static Result<BoolSetting> parse(JsonMaybeObject& obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* A Setting for an integer value. The value can be limited using the min
|
||||
* and max options
|
||||
*/
|
||||
struct GEODE_DLL IntSetting final {
|
||||
using ValueType = int64_t;
|
||||
|
||||
|
@ -49,6 +56,10 @@ namespace geode {
|
|||
static Result<IntSetting> parse(JsonMaybeObject& obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* A Setting for a float value. The value can be limited using the min
|
||||
* and max options
|
||||
*/
|
||||
struct GEODE_DLL FloatSetting final {
|
||||
using ValueType = double;
|
||||
|
||||
|
@ -70,17 +81,27 @@ namespace geode {
|
|||
static Result<FloatSetting> parse(JsonMaybeObject& obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* A Setting for a string value
|
||||
*/
|
||||
struct GEODE_DLL StringSetting final {
|
||||
using ValueType = std::string;
|
||||
|
||||
std::optional<std::string> name;
|
||||
std::optional<std::string> description;
|
||||
ValueType defaultValue;
|
||||
/**
|
||||
* A regex the string must succesfully match against
|
||||
*/
|
||||
std::optional<std::string> match;
|
||||
|
||||
static Result<StringSetting> parse(JsonMaybeObject& obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* A Setting for a file input. Lets the user select a file from their
|
||||
* local device
|
||||
*/
|
||||
struct GEODE_DLL FileSetting final {
|
||||
using ValueType = ghc::filesystem::path;
|
||||
using Filter = utils::file::FilePickOptions::Filter;
|
||||
|
@ -95,6 +116,10 @@ namespace geode {
|
|||
static Result<FileSetting> parse(JsonMaybeObject& obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* A Setting for an RGB color. See ColorAlphaSetting for a setting that
|
||||
* also allows customizing alpha
|
||||
*/
|
||||
struct GEODE_DLL ColorSetting final {
|
||||
using ValueType = cocos2d::ccColor3B;
|
||||
|
||||
|
@ -105,6 +130,10 @@ namespace geode {
|
|||
static Result<ColorSetting> parse(JsonMaybeObject& obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* A Setting for an RGBA color. See ColorSetting for a setting that doesn't
|
||||
* have alpha
|
||||
*/
|
||||
struct GEODE_DLL ColorAlphaSetting final {
|
||||
using ValueType = cocos2d::ccColor4B;
|
||||
|
||||
|
@ -115,6 +144,11 @@ namespace geode {
|
|||
static Result<ColorAlphaSetting> parse(JsonMaybeObject& obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* A custom setting, defined by the mod. See
|
||||
* [the tutorial page](https://docs.geode-sdk.org/mods/settings) for more
|
||||
* information about how to create custom settings
|
||||
*/
|
||||
struct GEODE_DLL CustomSetting final {
|
||||
std::shared_ptr<ModJson> json;
|
||||
};
|
||||
|
@ -130,9 +164,19 @@ namespace geode {
|
|||
CustomSetting
|
||||
>;
|
||||
|
||||
/**
|
||||
* Represents a saved value for a mod that can be customized by the user
|
||||
* through an in-game UI. This class is for modeling the setting's
|
||||
* definition - what values are accepted, its name etc.
|
||||
* See [the tutorial page](https://docs.geode-sdk.org/mods/settings)
|
||||
* for more information about how settings work
|
||||
* @see SettingValue
|
||||
* @see SettingNode
|
||||
*/
|
||||
struct GEODE_DLL Setting final {
|
||||
private:
|
||||
std::string m_key;
|
||||
std::string m_modID;
|
||||
SettingKind m_kind;
|
||||
|
||||
Setting() = default;
|
||||
|
@ -140,9 +184,14 @@ namespace geode {
|
|||
public:
|
||||
static Result<Setting> parse(
|
||||
std::string const& key,
|
||||
std::string const& mod,
|
||||
JsonMaybeValue& obj
|
||||
);
|
||||
Setting(std::string const& key, SettingKind const& kind);
|
||||
Setting(
|
||||
std::string const& key,
|
||||
std::string const& mod,
|
||||
SettingKind const& kind
|
||||
);
|
||||
|
||||
template<class T>
|
||||
std::optional<T> get() {
|
||||
|
@ -156,13 +205,22 @@ namespace geode {
|
|||
bool isCustom() const;
|
||||
std::string getDisplayName() const;
|
||||
std::optional<std::string> getDescription() const;
|
||||
std::string getModID() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores the actual, current value of a Setting. See
|
||||
* [the tutorial page](https://docs.geode-sdk.org/mods/settings) for more
|
||||
* information, and how to create custom settings
|
||||
*/
|
||||
class GEODE_DLL SettingValue {
|
||||
protected:
|
||||
std::string m_key;
|
||||
std::string m_modID;
|
||||
|
||||
SettingValue(std::string const& key);
|
||||
SettingValue(std::string const& key, std::string const& mod);
|
||||
|
||||
void valueChanged();
|
||||
|
||||
public:
|
||||
virtual ~SettingValue() = default;
|
||||
|
@ -171,6 +229,7 @@ namespace geode {
|
|||
virtual SettingNode* createNode(float width) = 0;
|
||||
|
||||
std::string getKey() const;
|
||||
std::string getModID() const;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
@ -187,8 +246,8 @@ namespace geode {
|
|||
GEODE_DLL Valid toValid(ValueType const& value) const;
|
||||
|
||||
public:
|
||||
GeodeSettingValue(std::string const& key, T const& definition)
|
||||
: SettingValue(key),
|
||||
GeodeSettingValue(std::string const& key, std::string const& modID, T const& definition)
|
||||
: SettingValue(key, modID),
|
||||
m_definition(definition),
|
||||
m_value(definition.defaultValue) {}
|
||||
|
||||
|
@ -200,7 +259,7 @@ namespace geode {
|
|||
return m_definition;
|
||||
}
|
||||
Setting getDefinition() const {
|
||||
return Setting(m_key, m_definition);
|
||||
return Setting(m_key, m_modID, m_definition);
|
||||
}
|
||||
|
||||
ValueType getValue() const {
|
||||
|
|
|
@ -113,7 +113,7 @@ Result<ModInfo> ModInfo::Impl::createFromSchemaV010(ModJson const& rawJson) {
|
|||
}
|
||||
|
||||
for (auto& [key, value] : root.has("settings").items()) {
|
||||
GEODE_UNWRAP_INTO(auto sett, Setting::parse(key, value));
|
||||
GEODE_UNWRAP_INTO(auto sett, Setting::parse(key, impl->m_id, value));
|
||||
impl->m_settings.push_back({key, sett});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "../ui/internal/settings/GeodeSettingNode.hpp"
|
||||
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/loader/Setting.hpp>
|
||||
#include <Geode/loader/SettingEvent.hpp>
|
||||
#include <Geode/loader/SettingNode.hpp>
|
||||
|
@ -101,10 +102,12 @@ Result<ColorAlphaSetting> ColorAlphaSetting::parse(JsonMaybeObject& obj) {
|
|||
|
||||
Result<Setting> Setting::parse(
|
||||
std::string const& key,
|
||||
std::string const& mod,
|
||||
JsonMaybeValue& value
|
||||
) {
|
||||
auto sett = Setting();
|
||||
sett.m_key = key;
|
||||
sett.m_modID = mod;
|
||||
if (auto obj = value.obj()) {
|
||||
std::string type;
|
||||
obj.needs("type").into(type);
|
||||
|
@ -156,31 +159,34 @@ Result<Setting> Setting::parse(
|
|||
return Ok(sett);
|
||||
}
|
||||
|
||||
Setting::Setting(std::string const& key, SettingKind const& kind)
|
||||
: m_key(key), m_kind(kind) {}
|
||||
Setting::Setting(
|
||||
std::string const& key,
|
||||
std::string const& mod,
|
||||
SettingKind const& kind
|
||||
) : m_key(key), m_modID(mod), m_kind(kind) {}
|
||||
|
||||
std::unique_ptr<SettingValue> Setting::createDefaultValue() const {
|
||||
return std::visit(makeVisitor {
|
||||
[&](BoolSetting const& sett) -> std::unique_ptr<SettingValue> {
|
||||
return std::make_unique<BoolSettingValue>(m_key, sett);
|
||||
return std::make_unique<BoolSettingValue>(m_key, m_modID, sett);
|
||||
},
|
||||
[&](IntSetting const& sett) -> std::unique_ptr<SettingValue> {
|
||||
return std::make_unique<IntSettingValue>(m_key, sett);
|
||||
return std::make_unique<IntSettingValue>(m_key, m_modID, sett);
|
||||
},
|
||||
[&](FloatSetting const& sett) -> std::unique_ptr<SettingValue> {
|
||||
return std::make_unique<FloatSettingValue>(m_key, sett);
|
||||
return std::make_unique<FloatSettingValue>(m_key, m_modID, sett);
|
||||
},
|
||||
[&](StringSetting const& sett) -> std::unique_ptr<SettingValue> {
|
||||
return std::make_unique<StringSettingValue>(m_key, sett);
|
||||
return std::make_unique<StringSettingValue>(m_key, m_modID, sett);
|
||||
},
|
||||
[&](FileSetting const& sett) -> std::unique_ptr<SettingValue> {
|
||||
return std::make_unique<FileSettingValue>(m_key, sett);
|
||||
return std::make_unique<FileSettingValue>(m_key, m_modID, sett);
|
||||
},
|
||||
[&](ColorSetting const& sett) -> std::unique_ptr<SettingValue> {
|
||||
return std::make_unique<ColorSettingValue>(m_key, sett);
|
||||
return std::make_unique<ColorSettingValue>(m_key, m_modID, sett);
|
||||
},
|
||||
[&](ColorAlphaSetting const& sett) -> std::unique_ptr<SettingValue> {
|
||||
return std::make_unique<ColorAlphaSettingValue>(m_key, sett);
|
||||
return std::make_unique<ColorAlphaSettingValue>(m_key, m_modID, sett);
|
||||
},
|
||||
[&](auto const& sett) -> std::unique_ptr<SettingValue> {
|
||||
return nullptr;
|
||||
|
@ -214,14 +220,31 @@ std::optional<std::string> Setting::getDescription() const {
|
|||
}, m_kind);
|
||||
}
|
||||
|
||||
std::string Setting::getModID() const {
|
||||
return m_modID;
|
||||
}
|
||||
|
||||
// SettingValue
|
||||
|
||||
SettingValue::SettingValue(std::string const& key) : m_key(key) {}
|
||||
SettingValue::SettingValue(std::string const& key, std::string const& mod)
|
||||
: m_key(key), m_modID(mod) {}
|
||||
|
||||
std::string SettingValue::getKey() const {
|
||||
return m_key;
|
||||
}
|
||||
|
||||
std::string SettingValue::getModID() const {
|
||||
return m_modID;
|
||||
}
|
||||
|
||||
void SettingValue::valueChanged() {
|
||||
// this is actually p neat because now if the mod gets disabled this wont
|
||||
// post the event so that side-effect is automatically handled :3
|
||||
if (auto mod = Loader::get()->getLoadedMod(m_modID)) {
|
||||
SettingChangedEvent(mod, this).post();
|
||||
}
|
||||
}
|
||||
|
||||
// GeodeSettingValue & SettingValueSetter specializations
|
||||
|
||||
#define IMPL_NODE_AND_SETTERS(type_) \
|
||||
|
@ -236,6 +259,7 @@ std::string SettingValue::getKey() const {
|
|||
type_##Setting \
|
||||
>::setValue(ValueType const& value) { \
|
||||
m_value = this->toValid(value).first; \
|
||||
this->valueChanged(); \
|
||||
} \
|
||||
template<> \
|
||||
Result<> GeodeSettingValue< \
|
||||
|
|
|
@ -107,6 +107,7 @@ BOOL WINAPI DllMain(HINSTANCE lib, DWORD reason, LPVOID) {
|
|||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
$execute {
|
||||
listenForSettingChanges("show-platform-console", +[](bool value) {
|
||||
if (value) {
|
||||
|
|
|
@ -23,8 +23,8 @@ protected:
|
|||
Icon m_icon;
|
||||
|
||||
public:
|
||||
MySettingValue(std::string const& key, Icon icon)
|
||||
: SettingValue(key), m_icon(icon) {}
|
||||
MySettingValue(std::string const& key, std::string const& modID, Icon icon)
|
||||
: SettingValue(key, modID), m_icon(icon) {}
|
||||
|
||||
bool load(json::Value const& json) override {
|
||||
try {
|
||||
|
@ -151,10 +151,7 @@ struct MyMenuLayer : Modify<MyMenuLayer, MenuLayer> {
|
|||
};
|
||||
|
||||
$on_mod(Loaded) {
|
||||
Mod::get()->registerCustomSetting(
|
||||
"overcast-skies",
|
||||
std::make_unique<MySettingValue>("overcast-skies", DEFAULT_ICON)
|
||||
);
|
||||
Mod::get()->addCustomSetting<MySettingValue>("overcast-skies", DEFAULT_ICON);
|
||||
|
||||
// Dispatcher::get()->addFunction<void(GJGarageLayer*)>("test-garage-open", [](GJGarageLayer*
|
||||
// gl) { auto label = CCLabelBMFont::create("Dispatcher works!", "bigFont.fnt");
|
||||
|
|
Loading…
Reference in a new issue