Skip to content

Commit 80672f1

Browse files
committed
A little more safety
1 parent 2e45691 commit 80672f1

File tree

5 files changed

+54
-45
lines changed

5 files changed

+54
-45
lines changed

mod.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
"geode": "4.9.0",
2+
"geode": "4.10.0",
33
"gd": {
44
"win": "2.2074",
55
"android": "2.2074",
66
"mac": "2.2074",
77
"ios": "2.2074"
88
},
9-
"version": "v2.0.20",
9+
"version": "v2.0.21",
1010
"id": "alphalaneous.happy_textures",
1111
"name": "Happy Textures :3",
1212
"developer": "Alphalaneous",

src/NodeModding.hpp

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <Geode/Geode.hpp>
4+
#include <Geode/binding/GJGameLevel.hpp>
45
#include <Geode/modify/CCObject.hpp>
56
#include <Geode/modify/CCPoolManager.hpp>
67
#include <Geode/modify/CCDictionary.hpp>
@@ -9,6 +10,7 @@
910
#include <alphalaneous.alphas_geode_utils/include/Fields.h>
1011
#include "Macros.hpp"
1112
#include "LateQueue.hpp"
13+
#include "Utils.hpp"
1214

1315
using namespace geode::prelude;
1416

@@ -28,55 +30,22 @@ class $modify(CCDictionary) {
2830
}
2931
};
3032

31-
static std::unordered_map<CCObject*, uintptr_t> s_nodeVTables;
32-
33-
static bool checkNodeValidity(CCObject* node) {
34-
auto ret = *(uintptr_t*)node == s_nodeVTables[node];
35-
s_nodeVTables.erase(node);
36-
return ret;
37-
}
38-
39-
static void setNodeVTable(CCNode* node) {
40-
s_nodeVTables[node] = *(uintptr_t*)node;
41-
}
42-
43-
static std::unordered_map<const std::type_info*, bool> s_isNodeCache;
44-
45-
static bool isNode(CCObject* obj) {
46-
const std::type_info* ti = &typeid(*obj);
47-
48-
auto it = s_isNodeCache.find(ti);
49-
if (it != s_isNodeCache.end()) {
50-
return it->second;
51-
}
52-
53-
bool isNode = typeinfo_cast<CCNode*>(obj) != nullptr;
54-
s_isNodeCache.emplace(ti, isNode);
55-
56-
return isNode;
57-
}
5833

5934
class $modify(HTCCObject, CCObject) {
6035

61-
static std::string_view extract(std::string_view s) {
62-
if (auto pos = s.rfind("::"); pos != std::string_view::npos)
63-
return s.substr(pos + 2);
64-
return s;
65-
}
66-
6736
CCObject* autorelease() {
6837
auto modding = UIModding::get();
6938
if (!modding->doModify) return CCObject::autorelease();
7039

71-
if (isNode(this)) {
40+
if (modding->isNode(this)) {
7241
MyCCNode* node = reinterpret_cast<MyCCNode*>(this);
7342

7443
auto fields = node->m_fields.self();
7544
if (!fields->m_modified) {
76-
setNodeVTable(node);
45+
modding->setNodeVTable(node);
7746
LateQueue::get()->queue(node, [modding, node = Ref(node), fields] {
78-
if (!checkNodeValidity(node)) return;
79-
modding->doUICheckForType(extract(cocos::getObjectName(node)), node);
47+
if (!modding->checkNodeValidity(node)) return;
48+
modding->doUICheckForType(Utils::extract(cocos::getObjectName(node)), node);
8049
fields->m_modified = true;
8150
});
8251
}

src/UIModding.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,8 @@ void UIModding::handleModifications(CCNode* node, matjson::Value nodeObject, boo
14161416
void UIModding::reloadChildren(CCNode* parentNode, bool transition) {
14171417
if (!parentNode) return;
14181418
MyCCNode* myParentNode = static_cast<MyCCNode*>(parentNode);
1419+
if (!checkNodeValidity(myParentNode)) return;
1420+
14191421
for (const matjson::Value& value : myParentNode->getAttributes()) {
14201422
handleModifications(myParentNode, value, transition);
14211423
}
@@ -1607,3 +1609,34 @@ void UIModding::doUICheckForType(std::string_view type, CCNode* node) {
16071609
removalQueue.clear();
16081610
}
16091611

1612+
bool UIModding::checkNodeValidity(CCObject* node) {
1613+
auto ret = *(uintptr_t*)node == m_nodeVTables[node];
1614+
m_nodeVTables.erase(node);
1615+
return ret;
1616+
}
1617+
1618+
void UIModding::setNodeVTable(CCNode* node) {
1619+
m_nodeVTables[node] = *(uintptr_t*)node;
1620+
}
1621+
1622+
bool UIModding::isNode(CCObject* obj) {
1623+
const std::type_info* ti = &typeid(*obj);
1624+
1625+
auto it = m_isNodeCache.find(ti);
1626+
if (it != m_isNodeCache.end()) {
1627+
return it->second;
1628+
}
1629+
1630+
bool isNode = typeinfo_cast<CCNode*>(obj) && !typeinfo_cast<GJGameLevel*>(obj);
1631+
m_isNodeCache.emplace(ti, isNode);
1632+
1633+
return isNode;
1634+
}
1635+
1636+
UIModding* UIModding::get() {
1637+
1638+
if (!instance) {
1639+
instance = new UIModding();
1640+
};
1641+
return instance;
1642+
}

src/UIModding.hpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ class UIModding {
3131
std::unordered_map<CCTexture2D*, std::string> textureToNameMap;
3232
bool firstMenuLayer = true;
3333

34+
std::unordered_map<CCObject*, uintptr_t> m_nodeVTables;
35+
std::unordered_map<const std::type_info*, bool> m_isNodeCache;
36+
3437
std::vector<FileWatcher*> listeners;
3538
std::vector<Ref<CCNode>> removalQueue;
3639

@@ -103,11 +106,9 @@ class UIModding {
103106
void evaluateIf(CCNode* node, const matjson::Value& ifArray);
104107
std::vector<std::string> generateValidSprites(const std::string& path, const matjson::Value& spriteList);
105108

106-
static UIModding* get() {
109+
bool checkNodeValidity(CCObject* node);
110+
void setNodeVTable(CCNode* node);
111+
bool isNode(CCObject* obj);
107112

108-
if (!instance) {
109-
instance = new UIModding();
110-
};
111-
return instance;
112-
}
113+
static UIModding* get();
113114
};

src/Utils.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ namespace Utils {
263263
return AlphaUtils::Cocos::hasNode(child, node);
264264
}
265265

266+
static std::string_view extract(std::string_view s) {
267+
if (auto pos = s.rfind("::"); pos != std::string_view::npos)
268+
return s.substr(pos + 2);
269+
return s;
270+
}
271+
266272
static std::string_view trim(std::string_view s) {
267273
const auto is_space = [](unsigned char c) {
268274
return c == ' ' || c == '\t' || c == '\n' ||

0 commit comments

Comments
 (0)