Skip to content

Commit

Permalink
Merge pull request #32 from altalk23/footprint-removal
Browse files Browse the repository at this point in the history
Footprint removal of CCObject::autorelease and CCScene::create
  • Loading branch information
Alphalaneous authored Jan 6, 2025
2 parents 3c25a6a + abe0281 commit e97ee17
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 43 deletions.
2 changes: 1 addition & 1 deletion mod.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"geode": "4.0.1",
"geode": "4.1.1",
"gd": {
"win": "2.2074",
"android": "2.2074",
Expand Down
73 changes: 57 additions & 16 deletions src/NodeModding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,66 @@

using namespace geode::prelude;

class $modify(MyCCObject, CCObject) {
class CCAutoreleasePoolHack : public CCObject {
public:
CCArray* m_pManagedObjectArray;
};

static void onModify(auto& self) {
HOOK_LATEST("cocos2d::CCObject::autorelease");
class CCPoolManagerHack {
public:
CCArray* m_pReleasePoolStack;
CCAutoreleasePool* m_pCurReleasePool;
};

class NodeModding : public CCObject {
public:
static NodeModding* create() {
auto ret = new NodeModding();
ret->autorelease();
return ret;
}

static NodeModding* get() {
static NodeModding* instance = nullptr;
if (!instance) {
instance = NodeModding::create();
}
return instance;
}

void handleCurrentNode(CCNode* node) {
std::string className = Utils::getNodeName(node);
UIModding::get()->doUICheckForType(className, node);
}

void handleArray(CCArray* array) {
auto scene = CCDirector::sharedDirector()->getRunningScene();

if (scene && UIModding::get()->doModify && UIModding::get()->finishedLoad && !Callbacks::get()->m_ignoreUICheck) {

for (auto object : CCArrayExt<CCObject*>(array)) {
if (auto node = typeinfo_cast<CCNode*>(object)) {
handleCurrentNode(node);
}
}
}
}
};

#include <Geode/modify/CCPoolManager.hpp>

CCObject* autorelease() {
if (!UIModding::get()->finishedLoad || !UIModding::get()->doModify || Callbacks::get()->m_ignoreUICheck)
return CCObject::autorelease();

if (CCNode* node = typeinfo_cast<CCNode*>(this)) {
node->retain();
std::string className = Utils::getNodeName(this);
queueInMainThread([=] {
UIModding::get()->doUICheckForType(className, node);
node->release();
});
class $modify(CCPoolManager) {
void pop() {
auto poolManager = reinterpret_cast<CCPoolManagerHack*>(this);

if (poolManager && poolManager->m_pCurReleasePool) {
auto pool = reinterpret_cast<CCAutoreleasePoolHack*>(poolManager->m_pCurReleasePool);

if (pool->m_pManagedObjectArray) {
NodeModding::get()->handleArray(pool->m_pManagedObjectArray);
}
}
return CCObject::autorelease();

return CCPoolManager::pop();
}
};
65 changes: 39 additions & 26 deletions src/nodes/CCScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,50 @@

using namespace geode::prelude;

class $modify(MyCCScene, CCScene) {

static void onModify(auto& self) {
HOOK_LATEST("cocos2d::CCScene::create");
class SceneHandler : public CCObject {
public:
static SceneHandler* create() {
auto ret = new SceneHandler();
ret->autorelease();
return ret;
}

struct Fields {
int m_currentCount = 0;
bool m_isMenuLayer = false;
};
CCScene* m_currentScene = nullptr;

// IMPORTANT: might contain dangling pointers,
// do not use for anything other than checking
std::unordered_set<CCNode*> m_handledNodes;

static CCScene* create() {
auto ret = CCScene::create();
if (UIModding::get()->doModify) {
ret->schedule(schedule_selector(MyCCScene::checkForUpdates));
void checkForUpdates(CCScene* scene) {
if (Callbacks::get()->m_ignoreUICheck) return;

if (scene != m_currentScene) {
// we're in a new scene, clear the handled nodes
m_handledNodes.clear();
m_currentScene = scene;
}

for (auto node : CCArrayExt<CCNode*>(scene->getChildren())) {
if (m_handledNodes.find(node) != m_handledNodes.end()) continue;
m_handledNodes.insert(node);

if (node->getID() == "MenuLayer") continue; // hardcoded for now

UIModding::get()->doUICheck(node);
}
return ret;
}

void checkForUpdates(float dt) {
if (this->getChildrenCount() != m_fields->m_currentCount && (this->getChildrenCount() != 1 || m_fields->m_currentCount == 0)) {
int idx = 0;

for (CCNode* node : CCArrayExt<CCNode*>(this->getChildren())) {
idx++;
if (node->getID() == "MenuLayer" || Callbacks::get()->m_ignoreUICheck) continue;
if (idx > m_fields->m_currentCount) {
UIModding::get()->doUICheck(node);
}
}
void update(float dt) {
auto scene = CCDirector::sharedDirector()->getRunningScene();

if (scene && UIModding::get()->doModify) {
this->checkForUpdates(scene);
}
m_fields->m_currentCount = this->getChildrenCount();
}
};
};

$execute {
Loader::get()->queueInMainThread([]{
CCScheduler::get()->scheduleUpdateForTarget(SceneHandler::create(), INT_MAX, false);
});
}

0 comments on commit e97ee17

Please sign in to comment.