diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index a6d93936..3bda82b5 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -153,13 +153,13 @@ target_link_libraries(${PROJECT_NAME} z TulipHook geode-sdk mat-json) # Use precompiled headers for faster builds if (NOT GEODE_DISABLE_PRECOMPILED_HEADERS) target_precompile_headers(${PROJECT_NAME} PRIVATE - "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/DefaultInclude.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/Geode.hpp" # "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/Utils.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/Loader.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/UI.hpp" + # "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/Loader.hpp" + # "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/UI.hpp" # "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/Bindings.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/cocos/include/cocos2d.h" - "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/cocos/extensions/cocos-ext.h" + # "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/cocos/include/cocos2d.h" + # "${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/cocos/extensions/cocos-ext.h" ) endif() diff --git a/loader/include/Geode/Utils.hpp b/loader/include/Geode/Utils.hpp index 9aadbbee..5aa821cf 100644 --- a/loader/include/Geode/Utils.hpp +++ b/loader/include/Geode/Utils.hpp @@ -10,3 +10,4 @@ #include "utils/file.hpp" #include "utils/general.hpp" #include "utils/timer.hpp" +#include "utils/MiniFunction.hpp" diff --git a/loader/include/Geode/loader/Dispatch.hpp b/loader/include/Geode/loader/Dispatch.hpp index c020c49f..dec81ba5 100644 --- a/loader/include/Geode/loader/Dispatch.hpp +++ b/loader/include/Geode/loader/Dispatch.hpp @@ -28,9 +28,9 @@ namespace geode { // template <typename... Args> // class DispatchHandler : public EventHandler<DispatchEvent<Args...>> { // std::string m_selector; - // std::function<void(Args...)> m_callback; + // utils::MiniFunction<void(Args...)> m_callback; - // DispatchHandler(std::string const& name, std::function<void(Args...)> callback) : + // DispatchHandler(std::string const& name, utils::MiniFunction<void(Args...)> callback) : // m_selector(name), m_callback(callback) {} // public: @@ -42,7 +42,7 @@ namespace geode { // } // static DispatchHandler* create( - // std::string const& name, std::function<void(Args...)> callback + // std::string const& name, utils::MiniFunction<void(Args...)> callback // ) { // return new DispatchHandler(name, callback); // } diff --git a/loader/include/Geode/loader/Event.hpp b/loader/include/Geode/loader/Event.hpp index a95ecf57..7fb0d901 100644 --- a/loader/include/Geode/loader/Event.hpp +++ b/loader/include/Geode/loader/Event.hpp @@ -41,7 +41,7 @@ namespace geode { using Callback = ListenerResult(T*); using Event = T; - ListenerResult handle(std::function<Callback> fn, T* e) { + ListenerResult handle(utils::MiniFunction<Callback> fn, T* e) { return fn(e); } }; @@ -74,7 +74,7 @@ namespace geode { this->enable(); } - EventListener(std::function<Callback> fn, T filter = T()) + EventListener(utils::MiniFunction<Callback> fn, T filter = T()) : m_callback(fn), m_filter(filter) { this->enable(); @@ -106,7 +106,7 @@ namespace geode { this->enable(); } - void bind(std::function<Callback> fn) { + void bind(utils::MiniFunction<Callback> fn) { m_callback = fn; } @@ -120,7 +120,7 @@ namespace geode { } protected: - std::function<Callback> m_callback = nullptr; + utils::MiniFunction<Callback> m_callback = nullptr; T m_filter; }; diff --git a/loader/include/Geode/loader/IPC.hpp b/loader/include/Geode/loader/IPC.hpp index ff949f75..5802d1b2 100644 --- a/loader/include/Geode/loader/IPC.hpp +++ b/loader/include/Geode/loader/IPC.hpp @@ -56,7 +56,7 @@ namespace geode { std::string m_messageID; public: - ListenerResult handle(std::function<Callback> fn, IPCEvent* event); + ListenerResult handle(utils::MiniFunction<Callback> fn, IPCEvent* event); IPCFilter( std::string const& modID, std::string const& messageID diff --git a/loader/include/Geode/loader/Index.hpp b/loader/include/Geode/loader/Index.hpp index 7ab3a995..7d23f462 100644 --- a/loader/include/Geode/loader/Index.hpp +++ b/loader/include/Geode/loader/Index.hpp @@ -26,7 +26,7 @@ namespace geode { public: using Callback = void(ModInstallEvent*); - ListenerResult handle(std::function<Callback> fn, ModInstallEvent* event); + ListenerResult handle(utils::MiniFunction<Callback> fn, ModInstallEvent* event); ModInstallFilter(std::string const& id); }; @@ -39,7 +39,7 @@ namespace geode { public: using Callback = void(IndexUpdateEvent*); - ListenerResult handle(std::function<Callback> fn, IndexUpdateEvent* event); + ListenerResult handle(utils::MiniFunction<Callback> fn, IndexUpdateEvent* event); IndexUpdateFilter(); }; diff --git a/loader/include/Geode/loader/Loader.hpp b/loader/include/Geode/loader/Loader.hpp index d6856f19..aa178009 100644 --- a/loader/include/Geode/loader/Loader.hpp +++ b/loader/include/Geode/loader/Loader.hpp @@ -2,6 +2,7 @@ #include <ghc/fs_fwd.hpp> #include "../utils/Result.hpp" +#include "../utils/MiniFunction.hpp" #include "Log.hpp" #include "ModInfo.hpp" #include "Types.hpp" @@ -10,7 +11,7 @@ #include <mutex> namespace geode { - using ScheduledFunction = std::function<void GEODE_CALL(void)>; + using ScheduledFunction = utils::MiniFunction<void GEODE_CALL(void)>; struct InvalidGeodeFile { ghc::filesystem::path path; diff --git a/loader/include/Geode/loader/ModEvent.hpp b/loader/include/Geode/loader/ModEvent.hpp index 15c63d7c..e77f11e2 100644 --- a/loader/include/Geode/loader/ModEvent.hpp +++ b/loader/include/Geode/loader/ModEvent.hpp @@ -37,7 +37,7 @@ namespace geode { Mod* m_mod; public: - ListenerResult handle(std::function<Callback> fn, ModStateEvent* event); + ListenerResult handle(utils::MiniFunction<Callback> fn, ModStateEvent* event); ModStateFilter(Mod* mod, ModEventType type); }; } diff --git a/loader/include/Geode/loader/Setting.hpp b/loader/include/Geode/loader/Setting.hpp index 8d540a9a..0c77f265 100644 --- a/loader/include/Geode/loader/Setting.hpp +++ b/loader/include/Geode/loader/Setting.hpp @@ -15,9 +15,7 @@ namespace geode { class SettingNode; class SettingValue; - template <class Json> struct JsonMaybeObject; - template <class Json> struct JsonMaybeValue; struct GEODE_DLL BoolSetting final { @@ -27,7 +25,7 @@ namespace geode { std::optional<std::string> description; bool defaultValue; - static Result<BoolSetting> parse(JsonMaybeObject<ModJson>& obj); + static Result<BoolSetting> parse(JsonMaybeObject& obj); }; struct GEODE_DLL IntSetting final { @@ -48,7 +46,7 @@ namespace geode { bool input = true; } controls; - static Result<IntSetting> parse(JsonMaybeObject<ModJson>& obj); + static Result<IntSetting> parse(JsonMaybeObject& obj); }; struct GEODE_DLL FloatSetting final { @@ -69,7 +67,7 @@ namespace geode { bool input = true; } controls; - static Result<FloatSetting> parse(JsonMaybeObject<ModJson>& obj); + static Result<FloatSetting> parse(JsonMaybeObject& obj); }; struct GEODE_DLL StringSetting final { @@ -80,7 +78,7 @@ namespace geode { ValueType defaultValue; std::optional<std::string> match; - static Result<StringSetting> parse(JsonMaybeObject<ModJson>& obj); + static Result<StringSetting> parse(JsonMaybeObject& obj); }; struct GEODE_DLL FileSetting final { @@ -94,7 +92,7 @@ namespace geode { std::vector<Filter> filters; } controls; - static Result<FileSetting> parse(JsonMaybeObject<ModJson>& obj); + static Result<FileSetting> parse(JsonMaybeObject& obj); }; struct GEODE_DLL ColorSetting final { @@ -104,7 +102,7 @@ namespace geode { std::optional<std::string> description; ValueType defaultValue; - static Result<ColorSetting> parse(JsonMaybeObject<ModJson>& obj); + static Result<ColorSetting> parse(JsonMaybeObject& obj); }; struct GEODE_DLL ColorAlphaSetting final { @@ -114,7 +112,7 @@ namespace geode { std::optional<std::string> description; ValueType defaultValue; - static Result<ColorAlphaSetting> parse(JsonMaybeObject<ModJson>& obj); + static Result<ColorAlphaSetting> parse(JsonMaybeObject& obj); }; struct GEODE_DLL CustomSetting final { @@ -142,7 +140,7 @@ namespace geode { public: static Result<Setting> parse( std::string const& key, - JsonMaybeValue<ModJson>& obj + JsonMaybeValue& obj ); Setting(std::string const& key, SettingKind const& kind); diff --git a/loader/include/Geode/loader/SettingEvent.hpp b/loader/include/Geode/loader/SettingEvent.hpp index 5bb37033..33a396c6 100644 --- a/loader/include/Geode/loader/SettingEvent.hpp +++ b/loader/include/Geode/loader/SettingEvent.hpp @@ -22,7 +22,7 @@ namespace geode { public: using Callback = void(SettingValue*); - ListenerResult handle(std::function<Callback> fn, SettingChangedEvent* event); + ListenerResult handle(utils::MiniFunction<Callback> fn, SettingChangedEvent* event); /** * Listen to changes on a setting, or all settings * @param modID Mod whose settings to listen to @@ -42,7 +42,7 @@ namespace geode { public: using Callback = void(T); - ListenerResult handle(std::function<Callback> fn, SettingChangedEvent* event) { + ListenerResult handle(utils::MiniFunction<Callback> fn, SettingChangedEvent* event) { if ( m_modID == event->mod->getID() && (!m_targetKey || m_targetKey.value() == event->value->getKey()) diff --git a/loader/include/Geode/modify/Field.hpp b/loader/include/Geode/modify/Field.hpp index 215ae308..c87b59d4 100644 --- a/loader/include/Geode/modify/Field.hpp +++ b/loader/include/Geode/modify/Field.hpp @@ -3,6 +3,7 @@ #include "Traits.hpp" #include <Geode/loader/Loader.hpp> +#include "../utils/MiniFunction.hpp" #include <cocos2d.h> #include <vector> @@ -19,7 +20,7 @@ namespace geode::modifier { class FieldContainer { private: std::vector<void*> m_containedFields; - std::vector<std::function<void(void*)>> m_destructorFunctions; + std::vector<utils::MiniFunction<void(void*)>> m_destructorFunctions; public: ~FieldContainer() { @@ -37,7 +38,7 @@ namespace geode::modifier { return m_containedFields.at(index); } - void* setField(size_t index, size_t size, std::function<void(void*)> destructor) { + void* setField(size_t index, size_t size, utils::MiniFunction<void(void*)> destructor) { m_containedFields.at(index) = operator new(size); m_destructorFunctions.at(index) = destructor; return m_containedFields.at(index); diff --git a/loader/include/Geode/ui/EnterLayerEvent.hpp b/loader/include/Geode/ui/EnterLayerEvent.hpp index 9199f369..08d595f2 100644 --- a/loader/include/Geode/ui/EnterLayerEvent.hpp +++ b/loader/include/Geode/ui/EnterLayerEvent.hpp @@ -29,7 +29,7 @@ namespace geode { std::optional<std::string> m_targetID; public: - ListenerResult handle(std::function<Callback> fn, AEnterLayerEvent* event); + ListenerResult handle(utils::MiniFunction<Callback> fn, AEnterLayerEvent* event); AEnterLayerFilter( std::optional<std::string> const& id @@ -61,7 +61,7 @@ namespace geode { std::optional<std::string> m_targetID; public: - ListenerResult handle(std::function<Callback> fn, EnterLayerEvent<N>* event) { + ListenerResult handle(utils::MiniFunction<Callback> fn, EnterLayerEvent<N>* event) { if (m_targetID == event->getID()) { fn(static_cast<T*>(event)); } diff --git a/loader/include/Geode/ui/MDPopup.hpp b/loader/include/Geode/ui/MDPopup.hpp index 9ee55160..0fb46300 100644 --- a/loader/include/Geode/ui/MDPopup.hpp +++ b/loader/include/Geode/ui/MDPopup.hpp @@ -11,13 +11,13 @@ namespace geode { class MDPopup : public Popup< std::string const&, std::string const&, char const*, char const*, - std::function<void(bool)>> { + utils::MiniFunction<void(bool)>> { protected: - std::function<void(bool)> m_onClick = nullptr; + utils::MiniFunction<void(bool)> m_onClick = nullptr; bool setup( std::string const& title, std::string const& info, char const* btn1, char const* btn2, - std::function<void(bool)> onClick + utils::MiniFunction<void(bool)> onClick ) override; void onBtn(CCObject*); @@ -27,7 +27,7 @@ namespace geode { public: static MDPopup* create( std::string const& title, std::string const& content, char const* btn1, - char const* btn2 = nullptr, std::function<void(bool)> onClick = nullptr + char const* btn2 = nullptr, utils::MiniFunction<void(bool)> onClick = nullptr ); }; } diff --git a/loader/include/Geode/ui/SelectList.hpp b/loader/include/Geode/ui/SelectList.hpp index 595889fc..ffb56dc0 100644 --- a/loader/include/Geode/ui/SelectList.hpp +++ b/loader/include/Geode/ui/SelectList.hpp @@ -14,13 +14,13 @@ namespace geode { protected: std::vector<T> m_list; size_t m_index = 0; - std::function<void(T const&, size_t)> m_onChange; + utils::MiniFunction<void(T const&, size_t)> m_onChange; cocos2d::CCLabelBMFont* m_label; CCMenuItemSpriteExtra* m_prevBtn; CCMenuItemSpriteExtra* m_nextBtn; bool init( - float width, std::vector<T> const& list, std::function<void(T const&, size_t)> onChange + float width, std::vector<T> const& list, utils::MiniFunction<void(T const&, size_t)> onChange ) { if (!cocos2d::CCMenu::init()) return false; @@ -95,7 +95,7 @@ namespace geode { public: static SelectList* create( - float width, std::vector<T> const& list, std::function<void(T const&, size_t)> onChange + float width, std::vector<T> const& list, utils::MiniFunction<void(T const&, size_t)> onChange ) { auto ret = new SelectList(); if (ret && ret->init(width, list, onChange)) { diff --git a/loader/include/Geode/ui/TextRenderer.hpp b/loader/include/Geode/ui/TextRenderer.hpp index b0719769..d749d1b5 100644 --- a/loader/include/Geode/ui/TextRenderer.hpp +++ b/loader/include/Geode/ui/TextRenderer.hpp @@ -122,7 +122,7 @@ namespace geode { * to distinguish between bold, italic and * regular text. */ - using Font = std::function<Label(int)>; + using Font = utils::MiniFunction<Label(int)>; protected: cocos2d::CCPoint m_origin = cocos2d::CCPointZero; diff --git a/loader/include/Geode/utils/JsonValidation.hpp b/loader/include/Geode/utils/JsonValidation.hpp index ea5a7b68..eafc44df 100644 --- a/loader/include/Geode/utils/JsonValidation.hpp +++ b/loader/include/Geode/utils/JsonValidation.hpp @@ -7,7 +7,6 @@ #include <variant> namespace geode { - template <class Json> struct JsonChecker; template <typename T, typename = void> @@ -73,31 +72,28 @@ namespace geode { } template <class T> - using JsonValueValidator = std::function<bool(T const&)>; + using JsonValueValidator = utils::MiniFunction<bool(T const&)>; - template <class Json> struct JsonMaybeObject; - template <class Json> struct JsonMaybeValue; - template <class Json> struct JsonMaybeSomething { protected: - JsonChecker<Json>& m_checker; - Json& m_json; + JsonChecker& m_checker; + json::Value& m_json; std::string m_hierarchy; bool m_hasValue; - friend struct JsonMaybeObject<Json>; - friend struct JsonMaybeValue<Json>; + friend struct JsonMaybeObject; + friend struct JsonMaybeValue; GEODE_DLL void setError(std::string const& error); public: - GEODE_DLL Json& json(); + GEODE_DLL json::Value& json(); GEODE_DLL JsonMaybeSomething( - JsonChecker<Json>& checker, Json& json, std::string const& hierarchy, bool hasValue + JsonChecker& checker, json::Value& json, std::string const& hierarchy, bool hasValue ); GEODE_DLL bool isError() const; @@ -106,18 +102,17 @@ namespace geode { GEODE_DLL operator bool() const; }; - template <class Json> - struct JsonMaybeValue : public JsonMaybeSomething<Json> { + struct JsonMaybeValue : public JsonMaybeSomething { bool m_inferType = true; GEODE_DLL JsonMaybeValue( - JsonChecker<Json>& checker, Json& json, std::string const& hierarchy, bool hasValue + JsonChecker& checker, json::Value& json, std::string const& hierarchy, bool hasValue ); - GEODE_DLL JsonMaybeSomething<Json>& self(); + GEODE_DLL JsonMaybeSomething& self(); template <json::Type T> - JsonMaybeValue<Json>& as() { + JsonMaybeValue& as() { if (this->isError()) return *this; if (!jsonConvertibleTo(self().m_json.type(), T)) { this->setError( @@ -129,10 +124,10 @@ namespace geode { return *this; } - GEODE_DLL JsonMaybeValue<Json>& array(); + GEODE_DLL JsonMaybeValue& array(); template <json::Type... T> - JsonMaybeValue<Json>& asOneOf() { + JsonMaybeValue& asOneOf() { if (this->isError()) return *this; bool isOneOf = (... || jsonConvertibleTo(self().m_json.type(), T)); if (!isOneOf) { @@ -146,7 +141,7 @@ namespace geode { } template <json::Type T> - JsonMaybeValue<Json>& is() { + JsonMaybeValue& is() { if (this->isError()) return *this; self().m_hasValue = jsonConvertibleTo(self().m_json.type(), T); m_inferType = false; @@ -154,7 +149,7 @@ namespace geode { } template <class T> - JsonMaybeValue<Json>& validate(JsonValueValidator<T> validator) { + JsonMaybeValue& validate(JsonValueValidator<T> validator) { if (this->isError()) return *this; try { if (!validator(self().m_json.template as<T>())) { @@ -171,35 +166,30 @@ namespace geode { } template <class T> - JsonMaybeValue<Json>& validate(bool (*validator)(T const&)) { - return this->validate(std::function(validator)); - } - - template <class T> - JsonMaybeValue<Json>& inferType() { + JsonMaybeValue& inferType() { if (this->isError() || !m_inferType) return *this; return this->as<getJsonType<T>()>(); } template <class T> - JsonMaybeValue<Json>& intoRaw(T& target) { + JsonMaybeValue& intoRaw(T& target) { if (this->isError()) return *this; target = self().m_json; return *this; } template <class T> - JsonMaybeValue<Json>& into(T& target) { + JsonMaybeValue& into(T& target) { return this->intoAs<T, T>(target); } template <class T> - JsonMaybeValue<Json>& into(std::optional<T>& target) { + JsonMaybeValue& into(std::optional<T>& target) { return this->intoAs<T, std::optional<T>>(target); } template <class A, class T> - JsonMaybeValue<Json>& intoAs(T& target) { + JsonMaybeValue& intoAs(T& target) { this->inferType<A>(); if (this->isError()) return *this; @@ -241,7 +231,7 @@ namespace geode { return T(); } - GEODE_DLL JsonMaybeObject<Json> obj(); + GEODE_DLL JsonMaybeObject obj(); template <class T> struct Iterator { @@ -267,48 +257,46 @@ namespace geode { } }; - GEODE_DLL JsonMaybeValue<Json> at(size_t i); + GEODE_DLL JsonMaybeValue at(size_t i); - GEODE_DLL Iterator<JsonMaybeValue<Json>> iterate(); + GEODE_DLL Iterator<JsonMaybeValue> iterate(); - GEODE_DLL Iterator<std::pair<std::string, JsonMaybeValue<Json>>> items(); + GEODE_DLL Iterator<std::pair<std::string, JsonMaybeValue>> items(); }; - template <class Json> - struct JsonMaybeObject : JsonMaybeSomething<Json> { + struct JsonMaybeObject : JsonMaybeSomething { std::set<std::string> m_knownKeys; GEODE_DLL JsonMaybeObject( - JsonChecker<Json>& checker, Json& json, std::string const& hierarchy, bool hasValue + JsonChecker& checker, json::Value& json, std::string const& hierarchy, bool hasValue ); - GEODE_DLL JsonMaybeSomething<Json>& self(); + GEODE_DLL JsonMaybeSomething& self(); GEODE_DLL void addKnownKey(std::string const& key); - GEODE_DLL Json& json(); + GEODE_DLL json::Value& json(); - GEODE_DLL JsonMaybeValue<Json> emptyValue(); + GEODE_DLL JsonMaybeValue emptyValue(); - GEODE_DLL JsonMaybeValue<Json> has(std::string const& key); + GEODE_DLL JsonMaybeValue has(std::string const& key); - GEODE_DLL JsonMaybeValue<Json> needs(std::string const& key); + GEODE_DLL JsonMaybeValue needs(std::string const& key); GEODE_DLL void checkUnknownKeys(); }; - template <class Json = json::Value> struct JsonChecker { std::variant<std::monostate, std::string> m_result; - Json& m_json; + json::Value& m_json; - GEODE_DLL JsonChecker(Json& json); + GEODE_DLL JsonChecker(json::Value& json); GEODE_DLL bool isError() const; GEODE_DLL std::string getError() const; - GEODE_DLL JsonMaybeValue<Json> root(std::string const& hierarchy); + GEODE_DLL JsonMaybeValue root(std::string const& hierarchy); }; } diff --git a/loader/include/Geode/utils/MiniFunction.hpp b/loader/include/Geode/utils/MiniFunction.hpp index 0dd12e46..b6e335dd 100644 --- a/loader/include/Geode/utils/MiniFunction.hpp +++ b/loader/include/Geode/utils/MiniFunction.hpp @@ -21,7 +21,7 @@ namespace geode::utils { public: Type m_func; - explicit MiniFunctionState(Type func) : m_func(std::move(func)) {} + explicit MiniFunctionState(Type func) : m_func(func) {} Ret call(Args... args) const override { return const_cast<Type&>(m_func)(args...); @@ -31,6 +31,38 @@ namespace geode::utils { return new MiniFunctionState(*this); } }; + + template <class Type, class Ret, class... Args> + class MiniFunctionStatePointer final : public MiniFunctionStateBase<Ret, Args...> { + public: + Type m_func; + + explicit MiniFunctionStatePointer(Type func) : m_func(func) {} + + Ret call(Args... args) const override { + return const_cast<Type&>(*m_func)(args...); + } + + MiniFunctionStateBase<Ret, Args...>* clone() const override { + return new MiniFunctionStatePointer(*this); + } + }; + + template <class Type, class Ret, class Class, class... Args> + class MiniFunctionStateMemberPointer final : public MiniFunctionStateBase<Ret, Class, Args...> { + public: + Type m_func; + + explicit MiniFunctionStateMemberPointer(Type func) : m_func(func) {} + + Ret call(Class self, Args... args) const override { + return const_cast<Type&>(self->*m_func)(args...); + } + + MiniFunctionStateBase<Ret, Class, Args...>* clone() const override { + return new MiniFunctionStateMemberPointer(*this); + } + }; template <class Callable, class Ret, class... Args> concept MiniFunctionCallable = requires(Callable&& func, Args... args) { @@ -49,6 +81,8 @@ namespace geode::utils { public: MiniFunction() : m_state(nullptr) {} + MiniFunction(std::nullptr_t) : MiniFunction() {} + MiniFunction(MiniFunction const& other) : m_state(other.m_state ? other.m_state->clone() : nullptr) {} @@ -65,6 +99,16 @@ namespace geode::utils { MiniFunction(Callable&& func) : m_state(new MiniFunctionState<std::decay_t<Callable>, Ret, Args...>(std::forward<Callable>(func))) {} + template <class FunctionPointer> + requires(!MiniFunctionCallable<FunctionPointer, Ret, Args...> && std::is_pointer_v<FunctionPointer> && std::is_function_v<std::remove_pointer_t<FunctionPointer>>) + MiniFunction(FunctionPointer func) : + m_state(new MiniFunctionStatePointer<FunctionPointer, Ret, Args...>(func)) {} + + template <class MemberFunctionPointer> + requires(std::is_member_function_pointer_v<MemberFunctionPointer>) + MiniFunction(MemberFunctionPointer func) : + m_state(new MiniFunctionStateMemberPointer<MemberFunctionPointer, Ret, Args...>(func)) {} + MiniFunction& operator=(MiniFunction const& other) { delete m_state; m_state = other.m_state ? other.m_state->clone() : nullptr; @@ -79,6 +123,7 @@ namespace geode::utils { } Ret operator()(Args... args) const { + if (!m_state) return Ret(); return m_state->call(args...); } diff --git a/loader/include/Geode/utils/cocos.hpp b/loader/include/Geode/utils/cocos.hpp index 52b09c78..401400fb 100644 --- a/loader/include/Geode/utils/cocos.hpp +++ b/loader/include/Geode/utils/cocos.hpp @@ -8,6 +8,7 @@ #include <functional> #include <type_traits> #include "../loader/Event.hpp" +#include "MiniFunction.hpp" // support converting ccColor3B / ccColor4B to / from json @@ -468,7 +469,7 @@ namespace geode::cocos { */ GEODE_DLL cocos2d::CCScene* switchToScene(cocos2d::CCLayer* layer); - using CreateLayerFunc = std::function<cocos2d::CCLayer*()>; + using CreateLayerFunc = utils::MiniFunction<cocos2d::CCLayer*()>; /** * Reload textures, overwriting the scene to return to after the loading @@ -518,7 +519,7 @@ namespace geode::cocos { * there is none */ template <class Type = cocos2d::CCNode> - Type* findFirstChildRecursive(cocos2d::CCNode* node, std::function<bool(Type*)> predicate) { + Type* findFirstChildRecursive(cocos2d::CCNode* node, utils::MiniFunction<bool(Type*)> predicate) { if (cast::safe_cast<Type*>(node) && predicate(static_cast<Type*>(node))) return static_cast<Type*>(node); @@ -707,7 +708,7 @@ namespace geode::cocos { } template <typename T, typename C, typename = std::enable_if_t<std::is_pointer_v<C>>> - static cocos2d::CCArray* vectorToCCArray(std::vector<T> const& vec, std::function<C(T)> convFunc) { + static cocos2d::CCArray* vectorToCCArray(std::vector<T> const& vec, utils::MiniFunction<C(T)> convFunc) { auto res = cocos2d::CCArray::createWithCapacity(vec.size()); for (auto const& item : vec) res->addObject(convFunc(item)); @@ -734,7 +735,7 @@ namespace geode::cocos { template < typename K, typename V, typename C, typename = std::enable_if_t<std::is_same_v<C, std::string> || std::is_same_v<C, intptr_t>>> - static cocos2d::CCDictionary* mapToCCDict(std::map<K, V> const& map, std::function<C(K)> convFunc) { + static cocos2d::CCDictionary* mapToCCDict(std::map<K, V> const& map, utils::MiniFunction<C(K)> convFunc) { auto res = cocos2d::CCDictionary::create(); for (auto const& [key, value] : map) res->setObject(value, convFunc(key)); diff --git a/loader/include/Geode/utils/map.hpp b/loader/include/Geode/utils/map.hpp index e5110a27..f426fe7d 100644 --- a/loader/include/Geode/utils/map.hpp +++ b/loader/include/Geode/utils/map.hpp @@ -20,7 +20,7 @@ namespace geode::utils::map { * false if not. */ template <typename T, typename R> - bool contains(std::unordered_map<T, R> const& map, std::function<bool(R)> containFunc) { + bool contains(std::unordered_map<T, R> const& map, utils::MiniFunction<bool(R)> containFunc) { for (auto const& [_, r] : map) { if (containFunc(r)) return true; } @@ -39,7 +39,7 @@ namespace geode::utils::map { * a pointer. */ template <class T, class R> - R select(std::unordered_map<T, R> const& map, std::function<bool(R)> selectFunc) { + R select(std::unordered_map<T, R> const& map, utils::MiniFunction<bool(R)> selectFunc) { for (auto const& [_, r] : map) { if (selectFunc(r)) return r; } @@ -59,7 +59,7 @@ namespace geode::utils::map { */ template <class T, class R> std::vector<R> selectAll( - std::unordered_map<T, R> const& map, std::function<bool(R)> selectFunc + std::unordered_map<T, R> const& map, utils::MiniFunction<bool(R)> selectFunc ) { std::vector<R> res; for (auto const& [_, r] : map) { @@ -111,7 +111,7 @@ namespace geode::utils::map { template <class T1, class V1, class T2, class V2> std::unordered_map<T2, V2> remap( std::unordered_map<T1, V1> const& map, - std::function<std::pair<T2, V2>(std::pair<T1, V1>)> remapFunc + utils::MiniFunction<std::pair<T2, V2>(std::pair<T1, V1>)> remapFunc ) { std::unordered_map<T2, V2> res; for (auto const& [t, v] : map) { diff --git a/loader/include/Geode/utils/web.hpp b/loader/include/Geode/utils/web.hpp index 05c18bea..286142ae 100644 --- a/loader/include/Geode/utils/web.hpp +++ b/loader/include/Geode/utils/web.hpp @@ -1,6 +1,7 @@ #pragma once #include "../DefaultInclude.hpp" +#include "MiniFunction.hpp" #include <json.hpp> #include "Result.hpp" #include "general.hpp" @@ -11,7 +12,7 @@ namespace geode::utils::web { GEODE_DLL void openLinkInBrowser(std::string const& url); - using FileProgressCallback = std::function<bool(double, double)>; + using FileProgressCallback = utils::MiniFunction<bool(double, double)>; /** * Synchronously fetch data from the internet @@ -54,11 +55,11 @@ namespace geode::utils::web { class AsyncWebResponse; class AsyncWebRequest; - using AsyncProgress = std::function<void(SentAsyncWebRequest&, double, double)>; - using AsyncExpect = std::function<void(std::string const&)>; - using AsyncExpectCode = std::function<void(std::string const&, int)>; - using AsyncThen = std::function<void(SentAsyncWebRequest&, ByteVector const&)>; - using AsyncCancelled = std::function<void(SentAsyncWebRequest&)>; + using AsyncProgress = utils::MiniFunction<void(SentAsyncWebRequest&, double, double)>; + using AsyncExpect = utils::MiniFunction<void(std::string const&)>; + using AsyncExpectCode = utils::MiniFunction<void(std::string const&, int)>; + using AsyncThen = utils::MiniFunction<void(SentAsyncWebRequest&, ByteVector const&)>; + using AsyncCancelled = utils::MiniFunction<void(SentAsyncWebRequest&)>; /** * A handle to an in-progress sent asynchronous web request. Use this to @@ -217,7 +218,7 @@ namespace geode::utils::web { * @returns The original AsyncWebRequest, where you can specify more * aspects about the request like failure and progress callbacks */ - AsyncWebRequest& then(std::function<void(T)> handle); + AsyncWebRequest& then(utils::MiniFunction<void(T)> handle); /** * Specify a callback to run after a download is finished. Runs in the * GD thread, so interacting with UI is safe @@ -225,7 +226,7 @@ namespace geode::utils::web { * @returns The original AsyncWebRequest, where you can specify more * aspects about the request like failure and progress callbacks */ - AsyncWebRequest& then(std::function<void(SentAsyncWebRequest&, T)> handle); + AsyncWebRequest& then(utils::MiniFunction<void(SentAsyncWebRequest&, T)> handle); }; class GEODE_DLL AsyncWebResponse { @@ -294,7 +295,7 @@ namespace geode::utils::web { }; template <class T> - AsyncWebRequest& AsyncWebResult<T>::then(std::function<void(T)> handle) { + AsyncWebRequest& AsyncWebResult<T>::then(utils::MiniFunction<void(T)> handle) { m_request.m_then = [converter = m_converter, handle](SentAsyncWebRequest& req, ByteVector const& arr) { auto conv = converter(arr); @@ -309,7 +310,7 @@ namespace geode::utils::web { } template <class T> - AsyncWebRequest& AsyncWebResult<T>::then(std::function<void(SentAsyncWebRequest&, T)> handle) { + AsyncWebRequest& AsyncWebResult<T>::then(utils::MiniFunction<void(SentAsyncWebRequest&, T)> handle) { m_request.m_then = [converter = m_converter, handle](SentAsyncWebRequest& req, ByteVector const& arr) { auto conv = converter(arr); diff --git a/loader/src/internal/FileWatcher.hpp b/loader/src/internal/FileWatcher.hpp index 427f8949..c42b62bf 100644 --- a/loader/src/internal/FileWatcher.hpp +++ b/loader/src/internal/FileWatcher.hpp @@ -2,14 +2,15 @@ #include <Geode/DefaultInclude.hpp> //#include <Geode/utils/general.hpp> +#include <Geode/utils/MiniFunction.hpp> #include <ghc/fs_fwd.hpp> #include <functional> #include <string> class FileWatcher { public: - using FileWatchCallback = std::function<void(ghc::filesystem::path)>; - using ErrorCallback = std::function<void(std::string)>; + using FileWatchCallback = geode::utils::MiniFunction<void(ghc::filesystem::path)>; + using ErrorCallback = geode::utils::MiniFunction<void(std::string)>; protected: ghc::filesystem::path m_file; diff --git a/loader/src/loader/IPC.cpp b/loader/src/loader/IPC.cpp index 1dd71e23..ea26d467 100644 --- a/loader/src/loader/IPC.cpp +++ b/loader/src/loader/IPC.cpp @@ -24,7 +24,7 @@ IPCEvent::IPCEvent( IPCEvent::~IPCEvent() {} -ListenerResult IPCFilter::handle(std::function<Callback> fn, IPCEvent* event) { +ListenerResult IPCFilter::handle(utils::MiniFunction<Callback> fn, IPCEvent* event) { if (event->targetModID == m_modID && event->messageID == m_messageID) { event->replyData = fn(event); return ListenerResult::Stop; diff --git a/loader/src/loader/Index.cpp b/loader/src/loader/Index.cpp index 871b9d31..e9488aca 100644 --- a/loader/src/loader/Index.cpp +++ b/loader/src/loader/Index.cpp @@ -17,7 +17,7 @@ ModInstallEvent::ModInstallEvent( std::string const& id, const UpdateStatus status ) : modID(id), status(status) {} -ListenerResult ModInstallFilter::handle(std::function<Callback> fn, ModInstallEvent* event) { +ListenerResult ModInstallFilter::handle(utils::MiniFunction<Callback> fn, ModInstallEvent* event) { if (m_id == event->modID) { fn(event); } @@ -67,7 +67,7 @@ class SourceUpdateFilter : public EventFilter<SourceUpdateEvent> { public: using Callback = void(SourceUpdateEvent*); - ListenerResult handle(std::function<Callback> fn, SourceUpdateEvent* event) { + ListenerResult handle(utils::MiniFunction<Callback> fn, SourceUpdateEvent* event) { fn(event); return ListenerResult::Propagate; } @@ -79,7 +79,7 @@ public: IndexUpdateEvent::IndexUpdateEvent(const UpdateStatus status) : status(status) {} ListenerResult IndexUpdateFilter::handle( - std::function<Callback> fn, + utils::MiniFunction<Callback> fn, IndexUpdateEvent* event ) { fn(event); diff --git a/loader/src/loader/LoaderImpl.cpp b/loader/src/loader/LoaderImpl.cpp index e915c4d6..b75d138a 100644 --- a/loader/src/loader/LoaderImpl.cpp +++ b/loader/src/loader/LoaderImpl.cpp @@ -467,8 +467,8 @@ bool Loader::Impl::platformConsoleOpen() const { } void Loader::Impl::fetchLatestGithubRelease( - std::function<void(json::Value const&)> then, - std::function<void(std::string const&)> expect + utils::MiniFunction<void(json::Value const&)> then, + utils::MiniFunction<void(std::string const&)> expect ) { if (m_latestGithubRelease) { return then(m_latestGithubRelease.value()); @@ -735,7 +735,7 @@ ResourceDownloadEvent::ResourceDownloadEvent( ) : status(status) {} ListenerResult ResourceDownloadFilter::handle( - std::function<Callback> fn, + utils::MiniFunction<Callback> fn, ResourceDownloadEvent* event ) { fn(event); @@ -749,7 +749,7 @@ LoaderUpdateEvent::LoaderUpdateEvent( ) : status(status) {} ListenerResult LoaderUpdateFilter::handle( - std::function<Callback> fn, + utils::MiniFunction<Callback> fn, LoaderUpdateEvent* event ) { fn(event); diff --git a/loader/src/loader/LoaderImpl.hpp b/loader/src/loader/LoaderImpl.hpp index 548f9c40..fde4ae6f 100644 --- a/loader/src/loader/LoaderImpl.hpp +++ b/loader/src/loader/LoaderImpl.hpp @@ -9,6 +9,7 @@ #include <Geode/utils/Result.hpp> #include <Geode/utils/map.hpp> #include <Geode/utils/ranges.hpp> +#include <Geode/utils/MiniFunction.hpp> #include "ModImpl.hpp" #include <about.hpp> #include <crashlog.hpp> @@ -31,7 +32,7 @@ namespace geode { public: using Callback = void(ResourceDownloadEvent*); - ListenerResult handle(std::function<Callback> fn, ResourceDownloadEvent* event); + ListenerResult handle(utils::MiniFunction<Callback> fn, ResourceDownloadEvent* event); ResourceDownloadFilter(); }; @@ -44,7 +45,7 @@ namespace geode { public: using Callback = void(LoaderUpdateEvent*); - ListenerResult handle(std::function<Callback> fn, LoaderUpdateEvent* event); + ListenerResult handle(utils::MiniFunction<Callback> fn, LoaderUpdateEvent* event); LoaderUpdateFilter(); }; @@ -67,7 +68,7 @@ namespace geode { std::condition_variable m_earlyLoadFinishedCV; std::mutex m_earlyLoadFinishedMutex; std::atomic_bool m_earlyLoadFinished = false; - std::vector<std::function<void(void)>> m_gdThreadQueue; + std::vector<utils::MiniFunction<void(void)>> m_gdThreadQueue; mutable std::mutex m_gdThreadMutex; bool m_platformConsoleOpen = false; std::vector<std::pair<Hook*, Mod*>> m_internalHooks; @@ -94,8 +95,8 @@ namespace geode { void downloadLoaderResources(bool useLatestRelease = false); void downloadLoaderUpdate(std::string const& url); void fetchLatestGithubRelease( - std::function<void(json::Value const&)> then, - std::function<void(std::string const&)> expect + utils::MiniFunction<void(json::Value const&)> then, + utils::MiniFunction<void(std::string const&)> expect ); bool loadHooks(); diff --git a/loader/src/loader/ModEvent.cpp b/loader/src/loader/ModEvent.cpp index 753d8e5d..d83e02a5 100644 --- a/loader/src/loader/ModEvent.cpp +++ b/loader/src/loader/ModEvent.cpp @@ -12,7 +12,7 @@ Mod* ModStateEvent::getMod() const { return m_mod; } -ListenerResult ModStateFilter::handle(std::function<Callback> fn, ModStateEvent* event) { +ListenerResult ModStateFilter::handle(utils::MiniFunction<Callback> fn, ModStateEvent* event) { if (event->getMod() == m_mod && event->getType() == m_type) { fn(event); } diff --git a/loader/src/loader/ModInfo.cpp b/loader/src/loader/ModInfo.cpp index 0529b8f8..9bd7e477 100644 --- a/loader/src/loader/ModInfo.cpp +++ b/loader/src/loader/ModInfo.cpp @@ -87,7 +87,7 @@ Result<ModInfo> ModInfo::Impl::createFromSchemaV010(ModJson const& rawJson) { root.addKnownKey("geode"); - root.needs("id").validate(&ModInfo::validateID).into(impl->m_id); + root.needs("id").validate(MiniFunction<bool(std::string const&)>(&ModInfo::validateID)).into(impl->m_id); root.needs("version").into(impl->m_version); root.needs("name").into(impl->m_name); root.needs("developer").into(impl->m_developer); @@ -105,7 +105,7 @@ Result<ModInfo> ModInfo::Impl::createFromSchemaV010(ModJson const& rawJson) { auto obj = dep.obj(); auto depobj = Dependency{}; - obj.needs("id").validate(&ModInfo::validateID).into(depobj.id); + obj.needs("id").validate(MiniFunction<bool(std::string const&)>(&ModInfo::validateID)).into(depobj.id); obj.needs("version").into(depobj.version); obj.has("required").into(depobj.required); obj.checkUnknownKeys(); diff --git a/loader/src/loader/Setting.cpp b/loader/src/loader/Setting.cpp index 63709414..4b5d0b3e 100644 --- a/loader/src/loader/Setting.cpp +++ b/loader/src/loader/Setting.cpp @@ -11,19 +11,19 @@ USE_GEODE_NAMESPACE(); template<class T> -static void parseCommon(T& sett, JsonMaybeObject<ModJson>& obj) { +static void parseCommon(T& sett, JsonMaybeObject& obj) { obj.has("name").into(sett.name); obj.has("description").into(sett.description); obj.has("default").into(sett.defaultValue); } -Result<BoolSetting> BoolSetting::parse(JsonMaybeObject<ModJson>& obj) { +Result<BoolSetting> BoolSetting::parse(JsonMaybeObject& obj) { BoolSetting sett; parseCommon(sett, obj); return Ok(sett); } -Result<IntSetting> IntSetting::parse(JsonMaybeObject<ModJson>& obj) { +Result<IntSetting> IntSetting::parse(JsonMaybeObject& obj) { IntSetting sett; parseCommon(sett, obj); obj.has("min").into(sett.min); @@ -40,7 +40,7 @@ Result<IntSetting> IntSetting::parse(JsonMaybeObject<ModJson>& obj) { return Ok(sett); } -Result<FloatSetting> FloatSetting::parse(JsonMaybeObject<ModJson>& obj) { +Result<FloatSetting> FloatSetting::parse(JsonMaybeObject& obj) { FloatSetting sett; parseCommon(sett, obj); obj.has("min").into(sett.min); @@ -57,14 +57,14 @@ Result<FloatSetting> FloatSetting::parse(JsonMaybeObject<ModJson>& obj) { return Ok(sett); } -Result<StringSetting> StringSetting::parse(JsonMaybeObject<ModJson>& obj) { +Result<StringSetting> StringSetting::parse(JsonMaybeObject& obj) { StringSetting sett; parseCommon(sett, obj); obj.has("match").into(sett.match); return Ok(sett); } -Result<FileSetting> FileSetting::parse(JsonMaybeObject<ModJson>& obj) { +Result<FileSetting> FileSetting::parse(JsonMaybeObject& obj) { FileSetting sett; parseCommon(sett, obj); if (auto controls = obj.has("control").obj()) { @@ -87,13 +87,13 @@ Result<FileSetting> FileSetting::parse(JsonMaybeObject<ModJson>& obj) { return Ok(sett); } -Result<ColorSetting> ColorSetting::parse(JsonMaybeObject<ModJson>& obj) { +Result<ColorSetting> ColorSetting::parse(JsonMaybeObject& obj) { ColorSetting sett; parseCommon(sett, obj); return Ok(sett); } -Result<ColorAlphaSetting> ColorAlphaSetting::parse(JsonMaybeObject<ModJson>& obj) { +Result<ColorAlphaSetting> ColorAlphaSetting::parse(JsonMaybeObject& obj) { ColorAlphaSetting sett; parseCommon(sett, obj); return Ok(sett); @@ -101,7 +101,7 @@ Result<ColorAlphaSetting> ColorAlphaSetting::parse(JsonMaybeObject<ModJson>& obj Result<Setting> Setting::parse( std::string const& key, - JsonMaybeValue<ModJson>& value + JsonMaybeValue& value ) { auto sett = Setting(); sett.m_key = key; @@ -378,7 +378,7 @@ SettingChangedEvent::SettingChangedEvent(Mod* mod, SettingValue* value) // SettingChangedFilter ListenerResult SettingChangedFilter::handle( - std::function<Callback> fn, SettingChangedEvent* event + utils::MiniFunction<Callback> fn, SettingChangedEvent* event ) { if (m_modID == event->mod->getID() && (!m_targetKey || m_targetKey.value() == event->value->getKey()) diff --git a/loader/src/ui/nodes/EnterLayerEvent.cpp b/loader/src/ui/nodes/EnterLayerEvent.cpp index 8583b626..3805cae2 100644 --- a/loader/src/ui/nodes/EnterLayerEvent.cpp +++ b/loader/src/ui/nodes/EnterLayerEvent.cpp @@ -8,7 +8,7 @@ AEnterLayerEvent::AEnterLayerEvent( ) : layerID(layerID), layer(layer) {} -ListenerResult AEnterLayerFilter::handle(std::function<Callback> fn, AEnterLayerEvent* event) { +ListenerResult AEnterLayerFilter::handle(utils::MiniFunction<Callback> fn, AEnterLayerEvent* event) { if (m_targetID == event->layerID) { fn(event); } diff --git a/loader/src/ui/nodes/MDPopup.cpp b/loader/src/ui/nodes/MDPopup.cpp index 96426985..64b23545 100644 --- a/loader/src/ui/nodes/MDPopup.cpp +++ b/loader/src/ui/nodes/MDPopup.cpp @@ -6,7 +6,7 @@ USE_GEODE_NAMESPACE(); bool MDPopup::setup( std::string const& title, std::string const& info, char const* btn1Text, char const* btn2Text, - std::function<void(bool)> onClick + utils::MiniFunction<void(bool)> onClick ) { this->setTitle(title.c_str(), "goldFont.fnt", .9f, 33.f); @@ -65,7 +65,7 @@ float MDPopup::estimateHeight(std::string const& content) { MDPopup* MDPopup::create( std::string const& title, std::string const& content, char const* btn1, char const* btn2, - std::function<void(bool)> onClick + utils::MiniFunction<void(bool)> onClick ) { auto ret = new MDPopup(); if (ret && diff --git a/loader/src/utils/JsonValidation.cpp b/loader/src/utils/JsonValidation.cpp index b0ef31bb..0a592fc3 100644 --- a/loader/src/utils/JsonValidation.cpp +++ b/loader/src/utils/JsonValidation.cpp @@ -2,52 +2,52 @@ USE_GEODE_NAMESPACE(); -template <class Json> -Json& JsonMaybeSomething<Json>::json() { + +json::Value& JsonMaybeSomething::json() { return m_json; } -template <class Json> -JsonMaybeSomething<Json>::JsonMaybeSomething( - JsonChecker<Json>& checker, Json& json, std::string const& hierarchy, bool hasValue + +JsonMaybeSomething::JsonMaybeSomething( + JsonChecker& checker, json::Value& json, std::string const& hierarchy, bool hasValue ) : m_checker(checker), m_json(json), m_hierarchy(hierarchy), m_hasValue(hasValue) {} -template <class Json> -bool JsonMaybeSomething<Json>::isError() const { + +bool JsonMaybeSomething::isError() const { return m_checker.isError() || !m_hasValue; } -template <class Json> -std::string JsonMaybeSomething<Json>::getError() const { + +std::string JsonMaybeSomething::getError() const { return m_checker.getError(); } -template <class Json> -JsonMaybeSomething<Json>::operator bool() const { + +JsonMaybeSomething::operator bool() const { return !isError(); } -template <class Json> -void JsonMaybeSomething<Json>::setError(std::string const& error) { + +void JsonMaybeSomething::setError(std::string const& error) { m_checker.m_result = error; } -template <class Json> -JsonMaybeValue<Json>::JsonMaybeValue( - JsonChecker<Json>& checker, Json& json, std::string const& hierarchy, bool hasValue -) : - JsonMaybeSomething<Json>(checker, json, hierarchy, hasValue) {} -template <class Json> -JsonMaybeSomething<Json>& JsonMaybeValue<Json>::self() { - return *static_cast<JsonMaybeSomething<Json>*>(this); +JsonMaybeValue::JsonMaybeValue( + JsonChecker& checker, json::Value& json, std::string const& hierarchy, bool hasValue +) : + JsonMaybeSomething(checker, json, hierarchy, hasValue) {} + + +JsonMaybeSomething& JsonMaybeValue::self() { + return *static_cast<JsonMaybeSomething*>(this); } // template<class Json> // template<nlohmann::detail::value_t T> -// JsonMaybeValue<Json>& JsonMaybeValue<Json>::as() { +// JsonMaybeValue& JsonMaybeValue::as() { // if (this->isError()) return *this; // if (!jsonConvertibleTo(self().m_json.type(), T)) { // this->setError( @@ -60,15 +60,15 @@ JsonMaybeSomething<Json>& JsonMaybeValue<Json>::self() { // return *this; // } -template <class Json> -JsonMaybeValue<Json>& JsonMaybeValue<Json>::array() { + +JsonMaybeValue& JsonMaybeValue::array() { this->as<value_t::Array>(); return *this; } // template<class Json> // template<nlohmann::detail::value_t... T> -// JsonMaybeValue<Json> JsonMaybeValue<Json>::asOneOf() { +// JsonMaybeValue JsonMaybeValue::asOneOf() { // if (this->isError()) return *this; // bool isOneOf = (... || jsonConvertibleTo(self().m_json.type(), T)); // if (!isOneOf) { @@ -84,7 +84,7 @@ JsonMaybeValue<Json>& JsonMaybeValue<Json>::array() { // template<class Json> // template<nlohmann::detail::value_t T> -// JsonMaybeValue<Json> JsonMaybeValue<Json>::is() { +// JsonMaybeValue JsonMaybeValue::is() { // if (this->isError()) return *this; // self().m_hasValue = jsonConvertibleTo(self().m_json.type(), T); // m_inferType = false; @@ -93,7 +93,7 @@ JsonMaybeValue<Json>& JsonMaybeValue<Json>::array() { // template<class Json> // template<class T> -// JsonMaybeValue<Json> JsonMaybeValue<Json>::validate(JsonValueValidator<T> validator) { +// JsonMaybeValue JsonMaybeValue::validate(JsonValueValidator<T> validator) { // if (this->isError()) return *this; // try { // if (!validator(self().m_json.template get<T>())) { @@ -110,14 +110,14 @@ JsonMaybeValue<Json>& JsonMaybeValue<Json>::array() { // template<class Json> // template<class T> -// JsonMaybeValue<Json> JsonMaybeValue<Json>::inferType() { +// JsonMaybeValue JsonMaybeValue::inferType() { // if (this->isError() || !m_inferType) return *this; // return this->as<getJsonType<T>()>(); // } // template<class Json> // template<class T> -// JsonMaybeValue<Json> JsonMaybeValue<Json>::intoRaw(T& target) { +// JsonMaybeValue JsonMaybeValue::intoRaw(T& target) { // if (this->isError()) return *this; // target = self().m_json; // return *this; @@ -125,19 +125,19 @@ JsonMaybeValue<Json>& JsonMaybeValue<Json>::array() { // template<class Json> // template<class T> -// JsonMaybeValue<Json> JsonMaybeValue<Json>::into(T& target) { +// JsonMaybeValue JsonMaybeValue::into(T& target) { // return this->intoAs<T, T>(target); // } // template<class Json> // template<class T> -// JsonMaybeValue<Json> JsonMaybeValue<Json>::into(std::optional<T>& target) { +// JsonMaybeValue JsonMaybeValue::into(std::optional<T>& target) { // return this->intoAs<T, std::optional<T>>(target); // } // template<class Json> // template<class A, class T> -// JsonMaybeValue<Json> JsonMaybeValue<Json>::intoAs(T& target) { +// JsonMaybeValue JsonMaybeValue::intoAs(T& target) { // this->inferType<A>(); // if (this->isError()) return *this; // try { @@ -153,7 +153,7 @@ JsonMaybeValue<Json>& JsonMaybeValue<Json>::array() { // template<class Json> // template<class T> -// T JsonMaybeValue<Json>::get() { +// T JsonMaybeValue::get() { // this->inferType<T>(); // if (this->isError()) return T(); // try { @@ -167,15 +167,15 @@ JsonMaybeValue<Json>& JsonMaybeValue<Json>::array() { // return T(); // } -template <class Json> -JsonMaybeObject<Json> JsonMaybeValue<Json>::obj() { + +JsonMaybeObject JsonMaybeValue::obj() { this->as<value_t::Object>(); return JsonMaybeObject(self().m_checker, self().m_json, self().m_hierarchy, self().m_hasValue); } // template<class Json> // template<class T> -// struct JsonMaybeValue<Json>::Iterator { +// struct JsonMaybeValue::Iterator { // std::vector<T> m_values; // using iterator = typename std::vector<T>::iterator; @@ -196,8 +196,8 @@ JsonMaybeObject<Json> JsonMaybeValue<Json>::obj() { // } // }; -template <class Json> -JsonMaybeValue<Json> JsonMaybeValue<Json>::at(size_t i) { + +JsonMaybeValue JsonMaybeValue::at(size_t i) { this->as<value_t::Array>(); if (this->isError()) return *this; @@ -211,15 +211,15 @@ JsonMaybeValue<Json> JsonMaybeValue<Json>::at(size_t i) { ); return *this; } - return JsonMaybeValue<Json>( + return JsonMaybeValue( self().m_checker, json.at(i), self().m_hierarchy + "." + std::to_string(i), self().m_hasValue ); } -template <class Json> -typename JsonMaybeValue<Json>::template Iterator<JsonMaybeValue<Json>> JsonMaybeValue<Json>::iterate() { + +typename JsonMaybeValue::template Iterator<JsonMaybeValue> JsonMaybeValue::iterate() { this->as<value_t::Array>(); - Iterator<JsonMaybeValue<Json>> iter; + Iterator<JsonMaybeValue> iter; if (this->isError()) return iter; auto& json = self().m_json.as_array(); @@ -232,72 +232,71 @@ typename JsonMaybeValue<Json>::template Iterator<JsonMaybeValue<Json>> JsonMaybe return iter; } -template <class Json> -typename JsonMaybeValue<Json>::template Iterator<std::pair<std::string, JsonMaybeValue<Json>>> JsonMaybeValue< - Json>::items() { + +typename JsonMaybeValue::template Iterator<std::pair<std::string, JsonMaybeValue>> JsonMaybeValue::items() { this->as<value_t::Object>(); - Iterator<std::pair<std::string, JsonMaybeValue<Json>>> iter; + Iterator<std::pair<std::string, JsonMaybeValue>> iter; if (this->isError()) return iter; for (auto& [k, v] : self().m_json.as_object()) { iter.m_values.emplace_back( k, - JsonMaybeValue<Json>(self().m_checker, v, self().m_hierarchy + "." + k, self().m_hasValue) + JsonMaybeValue(self().m_checker, v, self().m_hierarchy + "." + k, self().m_hasValue) ); } return iter; } -template <class Json> -JsonMaybeObject<Json>::JsonMaybeObject( - JsonChecker<Json>& checker, Json& json, std::string const& hierarchy, bool hasValue -) : - JsonMaybeSomething<Json>(checker, json, hierarchy, hasValue) {} -template <class Json> -JsonMaybeSomething<Json>& JsonMaybeObject<Json>::self() { - return *static_cast<JsonMaybeSomething<Json>*>(this); +JsonMaybeObject::JsonMaybeObject( + JsonChecker& checker, json::Value& json, std::string const& hierarchy, bool hasValue +) : + JsonMaybeSomething(checker, json, hierarchy, hasValue) {} + + +JsonMaybeSomething& JsonMaybeObject::self() { + return *static_cast<JsonMaybeSomething*>(this); } -template <class Json> -void JsonMaybeObject<Json>::addKnownKey(std::string const& key) { + +void JsonMaybeObject::addKnownKey(std::string const& key) { m_knownKeys.insert(key); } -template <class Json> -Json& JsonMaybeObject<Json>::json() { + +json::Value& JsonMaybeObject::json() { return self().m_json; } -template <class Json> -JsonMaybeValue<Json> JsonMaybeObject<Json>::emptyValue() { + +JsonMaybeValue JsonMaybeObject::emptyValue() { return JsonMaybeValue(self().m_checker, self().m_json, "", false); } -template <class Json> -JsonMaybeValue<Json> JsonMaybeObject<Json>::has(std::string const& key) { + +JsonMaybeValue JsonMaybeObject::has(std::string const& key) { this->addKnownKey(key); if (this->isError()) return emptyValue(); if (!self().m_json.contains(key) || self().m_json[key].is_null()) { return emptyValue(); } - return JsonMaybeValue<Json>(self().m_checker, self().m_json[key], key, true); + return JsonMaybeValue(self().m_checker, self().m_json[key], key, true); } -template <class Json> -JsonMaybeValue<Json> JsonMaybeObject<Json>::needs(std::string const& key) { + +JsonMaybeValue JsonMaybeObject::needs(std::string const& key) { this->addKnownKey(key); if (this->isError()) return emptyValue(); if (!self().m_json.contains(key)) { this->setError(self().m_hierarchy + " is missing required key \"" + key + "\""); return emptyValue(); } - return JsonMaybeValue<Json>(self().m_checker, self().m_json[key], key, true); + return JsonMaybeValue(self().m_checker, self().m_json[key], key, true); } -template <class Json> -void JsonMaybeObject<Json>::checkUnknownKeys() { + +void JsonMaybeObject::checkUnknownKeys() { for (auto& [key, _] : self().m_json.as_object()) { if (!m_knownKeys.count(key)) { log::warn("{} contains unknown key \"{}\"", self().m_hierarchy, key); @@ -305,40 +304,20 @@ void JsonMaybeObject<Json>::checkUnknownKeys() { } } -template <class Json> -JsonChecker<Json>::JsonChecker(Json& json) : m_json(json), m_result(std::monostate()) {} -template <class Json> -bool JsonChecker<Json>::isError() const { +JsonChecker::JsonChecker(json::Value& json) : m_json(json), m_result(std::monostate()) {} + + +bool JsonChecker::isError() const { return std::holds_alternative<std::string>(m_result); } -template <class Json> -std::string JsonChecker<Json>::getError() const { + +std::string JsonChecker::getError() const { return std::get<std::string>(m_result); } -template <class Json> -JsonMaybeValue<Json> JsonChecker<Json>::root(std::string const& hierarchy) { + +JsonMaybeValue JsonChecker::root(std::string const& hierarchy) { return JsonMaybeValue(*this, m_json, hierarchy, true); } - -namespace geode { - - template struct JsonMaybeSomething<json::Value>; - template struct JsonMaybeSomething<json::Value const>; - //template struct JsonMaybeSomething<ModJson>; - - template struct JsonMaybeValue<json::Value>; - template struct JsonMaybeValue<json::Value const>; - //template struct JsonMaybeValue<ModJson>; - - template struct JsonMaybeObject<json::Value>; - template struct JsonMaybeObject<json::Value const>; - //template struct JsonMaybeObject<ModJson>; - - template struct JsonChecker<json::Value>; - template struct JsonChecker<json::Value const>; - //template struct JsonChecker<ModJson>; - -} \ No newline at end of file