11#pragma once
22
3- #include < functional>
43#include < Geode/cocos/base_nodes/CCNode.h>
54#include < Geode/utils/StringMap.hpp>
65#include < Geode/utils/ZStringView.hpp>
@@ -28,34 +27,58 @@ namespace alpha::utils {
2827
2928 struct ObjectModifyInfo {
3029 int priority;
31- std::function<void (ModifyCCObject<cocos2d::CCObject>*)> method;
30+ geode::Function<void (ModifyCCObject<cocos2d::CCObject>*)> method;
31+
32+ ObjectModifyInfo (int p, geode::Function<void (ModifyCCObject<cocos2d::CCObject>*)>&& m)
33+ : priority(p), method(std::move(m)) {}
34+
35+ ObjectModifyInfo (ObjectModifyInfo&&) noexcept = default ;
36+ ObjectModifyInfo& operator =(ObjectModifyInfo&&) noexcept = default ;
37+
38+ ObjectModifyInfo (const ObjectModifyInfo&) = delete ;
39+ ObjectModifyInfo& operator =(const ObjectModifyInfo&) = delete ;
3240 };
3341
3442 class ALPHA_UTILS_API_DLL ObjectModify {
3543 protected:
3644 geode::utils::StringMap<std::vector<ObjectModifyInfo>> m_objectsToModify;
45+ geode::utils::StringMap<std::vector<ObjectModifyInfo>> m_objectBasesToModify;
3746 private:
47+ ObjectModify () = default ;
48+ ObjectModify (const ObjectModify&) = delete ;
49+ ObjectModify& operator =(const ObjectModify&) = delete ;
50+ ObjectModify (ObjectModify&&) = delete ;
51+ ObjectModify& operator =(ObjectModify&&) = delete ;
52+
3853 static ObjectModify* get ();
39- void addObjectToModify (geode::ZStringView className, int prio, std::function<void (ModifyCCObject<cocos2d::CCObject>*)> func);
54+ void addObjectToModify (geode::ZStringView className, int prio, geode::Function<void (ModifyCCObject<cocos2d::CCObject>*)> func);
55+ void addObjectToModifyBase (geode::ZStringView className, int prio, geode::Function<void (ModifyCCObject<cocos2d::CCObject>*)> func);
4056 geode::utils::StringMap<std::vector<ObjectModifyInfo>>& getObjectsToModify ();
41- void handleObject (ModifyCCObject<cocos2d::CCObject>* object );
57+ geode::utils::StringMap<std::vector<ObjectModifyInfo>>& getObjectBasesToModify ( );
4258
4359 template <class , class >
4460 friend class ClassModifyLoad ;
61+
62+ template <class , class >
63+ friend class BaseModifyLoad ;
64+
4565 friend class ModifyHandler ;
4666 };
4767
4868 template <class Derived , class Base >
4969 class ClassModifyLoad {
5070 public:
5171 ClassModifyLoad (geode::ZStringView str, bool useStr) {
52- std::string name;
53- if (useStr) name = str;
54- else name = alpha::utils::cocos::getObjectName<Base>();
55-
56- ObjectModify::get ()->addObjectToModify (name, Derived::modifyPrio (), [](ModifyCCObject<cocos2d::CCObject>* self) {
57- reinterpret_cast <Derived*>(reinterpret_cast <Base*>(self))->modify ();
58- });
72+ if (useStr) {
73+ ObjectModify::get ()->addObjectToModify (str, Derived::modifyPrio (), [](ModifyCCObject<cocos2d::CCObject>* self) {
74+ reinterpret_cast <Derived*>(reinterpret_cast <Base*>(self))->modify ();
75+ });
76+ }
77+ else {
78+ ObjectModify::get ()->addObjectToModify (alpha::utils::cocos::getObjectName<Base>(), Derived::modifyPrio (), [](ModifyCCObject<cocos2d::CCObject>* self) {
79+ reinterpret_cast <Derived*>(reinterpret_cast <Base*>(self))->modify ();
80+ });
81+ }
5982 }
6083 };
6184
@@ -72,6 +95,33 @@ namespace alpha::utils {
7295 static int modifyPrio () { return 0 ; }
7396 void modify () {}
7497 };
98+
99+ template <class Derived , class Base >
100+ class BaseModifyLoad {
101+ public:
102+ BaseModifyLoad (geode::ZStringView str) {
103+ ObjectModify::get ()->addObjectToModifyBase (str, Derived::modifyPrio (), [](ModifyCCObject<cocos2d::CCObject>* self) {
104+ if (ModifyHandler::get ()->containsBase <Base>(reinterpret_cast <cocos2d::CCObject*>(self))) {
105+ reinterpret_cast <Derived*>(reinterpret_cast <Base*>(self))->modify ();
106+ }
107+ });
108+ }
109+ };
110+
111+ template <class Derived , class Base , geode::utils::string::ConstexprString BaseStr>
112+ struct BaseObjectWrapper : public ModifyCCObject <Base> {
113+ private:
114+ static inline BaseModifyLoad<Derived, Base> s_apply{BaseStr.data ()};
115+ static inline auto s_applyRef = &BaseObjectWrapper::s_apply;
116+
117+ public:
118+ using Self = Derived;
119+
120+ ObjectFieldIntermediate<Derived, Base, BaseStr, false > m_fields;
121+ static int modifyPrio () { return 0 ; }
122+ void modify () {}
123+ };
124+
75125}
76126
77127#define ALPHA_MODIFY (baseStr, derived, baseType, useStr ) \
@@ -97,4 +147,18 @@ namespace alpha::utils {
97147 GEODE_INVOKE (GEODE_CONCAT (MODIFYNODE , GEODE_NUMBER_OF_ARGS (__VA_ARGS__)), __VA_ARGS__)
98148
99149#define $classModify(...) \
100- GEODE_INVOKE (GEODE_CONCAT (MODIFYCLASS , GEODE_NUMBER_OF_ARGS (__VA_ARGS__)), __VA_ARGS__)
150+ GEODE_INVOKE (GEODE_CONCAT (MODIFYCLASS , GEODE_NUMBER_OF_ARGS (__VA_ARGS__)), __VA_ARGS__)
151+
152+
153+ #define ALPHA_MODIFY_BASE (baseStr, derived, baseType ) \
154+ GEODE_CONCAT (derived, Dummy); \
155+ struct derived : alpha::utils::BaseObjectWrapper<derived, baseType, #baseStr>
156+
157+ #define ALPHA_MODIFY_BASE_AUTO (baseStr, baseType ) \
158+ ALPHA_MODIFY_BASE (baseStr, GEODE_CONCAT (hook, __LINE__), baseType)
159+
160+ #define MODIFYBASE1 (base ) ALPHA_MODIFY_BASE_AUTO (base, base)
161+ #define MODIFYBASE2 (derived, base ) ALPHA_MODIFY_BASE (base, derived, base)
162+
163+ #define $baseModify(...) \
164+ GEODE_INVOKE (GEODE_CONCAT (MODIFYBASE , GEODE_NUMBER_OF_ARGS (__VA_ARGS__)), __VA_ARGS__)
0 commit comments