1717
1818namespace AlphaUtils {
1919
20- static uint64_t fnv1aHash (char const * str) {
21- uint64_t hash = 0xcbf29ce484222325 ;
22- while (*str) {
23- hash ^= *str++;
24- hash *= 0x100000001b3 ;
25- }
26- return hash;
27- }
28-
29- template <typename T>
30- class NoHashHasher ;
31-
32- template <>
33- class NoHashHasher <uint64_t > {
34- public:
35- size_t operator ()(uint64_t key) const {
36- return key;
37- }
38- };
39-
40- class ObjectFieldContainer {
41- private:
42- std::vector<void *> m_containedFields;
43- std::vector<std::function<void (void *)>> m_destructorFunctions;
44-
45- public:
46- ~ObjectFieldContainer () {
47- for (auto i = 0u ; i < m_containedFields.size (); i++) {
48- if (m_destructorFunctions[i] && m_containedFields[i]) {
49- m_destructorFunctions[i](m_containedFields[i]);
50- operator delete (m_containedFields[i]);
51- }
52- }
53- }
54-
55- void * getField (size_t index) {
56- while (m_containedFields.size () <= index) {
57- m_containedFields.push_back (nullptr );
58- m_destructorFunctions.push_back (nullptr );
59- }
60- return m_containedFields.at (index);
61- }
62-
63- void * setField (size_t index, size_t size, std::function<void (void *)> destructor) {
64- m_containedFields.at (index) = operator new (size);
65- m_destructorFunctions.at (index) = std::move (destructor);
66- return m_containedFields.at (index);
67- }
68-
69- static ObjectFieldContainer* from (cocos2d::CCObject* node, char const * forClass) {
70- // return node->getFieldContainer(forClass);
71- }
72- };
73-
74- class ObjectMetadata final : public cocos2d::CCNode {
75- private:
76- std::unordered_map<uint64_t , ObjectFieldContainer*, NoHashHasher<uint64_t >> m_classFieldContainers;
77-
78- friend class cocos2d ::CCObject;
79-
80- ObjectMetadata () {}
81-
82- virtual ~ObjectMetadata () {
83- for (auto & [_, container] : m_classFieldContainers) {
84- delete container;
85- }
86- }
87-
88- public:
89- static ObjectMetadata* set (CCObject* target) {
90- if (!target) return nullptr ;
91-
92- auto meta = new ObjectMetadata ();
93- meta->autorelease ();
94-
95- target->m_pUserObject = meta;
96- meta->retain ();
97-
98- return meta;
99- }
100-
101- ObjectFieldContainer* getFieldContainer (char const * forClass) {
102- auto hash = fnv1aHash (forClass);
103-
104- auto & container = m_classFieldContainers[hash];
105- if (!container) {
106- container = new ObjectFieldContainer ();
107- }
108-
109- return container;
110- }
111- };
112-
113- GEODE_DLL size_t getFieldIndexForClass (char const * name);
114-
115- template <class Parent , class Base >
116- class ObjectFieldIntermediate {
117- using Intermediate = Modify<Parent, Base>;
118- std::aligned_storage_t <std::alignment_of_v<Base>, std::alignment_of_v<Base>> m_padding;
119-
120- public:
121- static void fieldConstructor (void * offsetField) {
122- (void ) new (offsetField) typename Parent::Fields ();
123- }
124-
125- static void fieldDestructor (void * offsetField) {
126- static_cast <typename Parent::Fields*>(offsetField)->~Fields ();
127- }
128-
129- auto self () {
130-
131- auto node = reinterpret_cast <Parent*>(reinterpret_cast <std::byte*>(this ) - sizeof (Base));
132- auto container = ObjectFieldContainer::from (node, typeid (Base).name ());
133- static size_t index = getFieldIndexForClass (typeid (Base).name ());
134- auto offsetField = container->getField (index);
135- if (!offsetField) {
136- offsetField = container->setField (
137- index, sizeof (typename Parent::Fields), &ObjectFieldIntermediate::fieldDestructor
138- );
139- ObjectFieldIntermediate::fieldConstructor (offsetField);
140- }
141-
142- return reinterpret_cast <typename Parent::Fields*>(offsetField);
143- }
144- auto operator ->() {
145- return this ->self ();
146- }
147- };
148-
14920 struct ModifyInfo {
15021 int priority;
15122 std::function<void (cocos2d::CCNode*)> method;
@@ -199,6 +70,4 @@ struct derived : AlphaUtils::NodeWrapper<derived>
19970#define MODIFY2 (derived, base ) ALPHA_MODIFY_DECLARE(base, derived)
20071
20172#define $nodeModify(...) \
202- GEODE_INVOKE (GEODE_CONCAT(MODIFY, GEODE_NUMBER_OF_ARGS(__VA_ARGS__)), __VA_ARGS__)
203-
204- #define $objectModify(...) $nodeModify(__VA_ARGS__)
73+ GEODE_INVOKE (GEODE_CONCAT(MODIFY, GEODE_NUMBER_OF_ARGS(__VA_ARGS__)), __VA_ARGS__)
0 commit comments