Skip to content

Instantly share code, notes, and snippets.

@camila314
Created February 13, 2025 21:20
Show Gist options
  • Select an option

  • Save camila314/5c0b53725024715856779ceca5219061 to your computer and use it in GitHub Desktop.

Select an option

Save camila314/5c0b53725024715856779ceca5219061 to your computer and use it in GitHub Desktop.
Hot-reloadable dynamic variables for Geode
#include <Geode/cocos/include/cocos2d.h>
#include <filesystem>
#include <fstream>
#include <Geode/utils/string.hpp>
#include <string>
class DynamicVarNode : public cocos2d::CCNode {
std::filesystem::path m_path;
std::filesystem::file_time_type m_last_write;
std::string m_last_code;
int m_line;
std::function<void(std::string const&)> m_callback;
public:
inline static DynamicVarNode* create(cocos2d::CCNode* parent, std::filesystem::path const& path, int line) {
auto ret = new DynamicVarNode();
if (ret && ret->init(parent, path, line)) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
inline bool init(cocos2d::CCNode* parent, std::filesystem::path const& path, int line) {
cocos2d::CCNode::init();
parent->addChild(this);
scheduleUpdate();
m_path = path;
m_line = line;
m_last_code = "";
return true;
}
inline void operator<<(std::function<void(std::string const&)> callback) {
m_callback = callback;
update(0.0);
}
inline void update(float dt) override {
if (!m_callback)
return;
auto last_write = std::filesystem::last_write_time(m_path);
if (m_last_write == last_write)
return;
m_last_write = last_write;
std::ifstream stream(m_path);
std::string code((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
auto lines = geode::utils::string::split(code, "\n");
if (m_line >= lines.size())
return;
auto data = geode::utils::string::split(lines[m_line], "//");
if (data.size() < 2)
return;
data.erase(data.begin());
m_callback(geode::utils::string::trim(geode::utils::string::join(data, "")));
}
};
#define $dynamic(obj, var) *DynamicVarNode::create(obj, __FILE__, __LINE__ - 1) << [=, obj](std::string const& var)
/*
Example Usage:
class $modify(PauseLayer) {
void customSetup() {
PauseLayer::customSetup();
static CCSprite* btn = nullptr;
$dynamic(this, val) { // d_largeSquare_02_001.png
if (btn)
btn->removeFromParent();
btn = CCSprite::createWithSpriteFrameName(val.c_str());
btn->setPosition({100, 100});
addChild(btn);
};
}
};
Put your hot-reloadable value in a comment to the right of $dynamic
Whitespaces are trimmed and 'val' will be std::string const&
Edit the comment and save the file to trigger the $dynamic block
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment