diff --git a/CHANGELOG.md b/CHANGELOG.md index 71b01a4e..0aaa5148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ * Fix json library not actually being dynamically exported/imported (5f65d97) * Update TulipHook, gets rid of keystone dependency and adds stdcall support (efcbf58, 7b90903) * Make resources.zip platform dependent (e41784e) + * Fix MacOS HSV button missing in `CustomizeObjectLayer` (d98cb2d) + * Make missing functions and members private (d98cb2d) + * Update Broma to latest version (0a58432) ## v1.0.3 * Fix mod changelogs only showing Geode's own changelog (2945422) diff --git a/bindings/Cocos2d.bro b/bindings/Cocos2d.bro index a96f4e02..67e8c369 100644 --- a/bindings/Cocos2d.bro +++ b/bindings/Cocos2d.bro @@ -1,9 +1,11 @@ // clang-format off +[[link(win)]] class cocos2d::CCActionTween { static cocos2d::CCActionTween* create(float, char const*, float, float) = mac 0x447590; } +[[link(win)]] class cocos2d::CCActionManager { auto addAction(cocos2d::CCAction*, cocos2d::CCNode*, bool) = mac 0x10bed0; auto pauseTarget(cocos2d::CCObject*) = mac 0x10bc50; @@ -11,14 +13,17 @@ class cocos2d::CCActionManager { auto resumeTarget(cocos2d::CCObject*) = mac 0x10bd20; } +[[link(win)]] class cocos2d::CCAnimate { static cocos2d::CCAnimate* create(cocos2d::CCAnimation*) = mac 0x1f8fc0; } +[[link(win)]] class cocos2d::CCAnimation { static auto createWithSpriteFrames(cocos2d::CCArray*, float) = mac 0x140df0; } +[[link(win)]] class cocos2d::CCApplication { virtual auto run(); virtual auto getCurrentLanguage() = mac 0x1a3f40, ios 0x10e508; @@ -32,6 +37,7 @@ class cocos2d::CCApplication { ~CCApplication() {} } +[[link(win)]] class cocos2d::CCArray { // auto addObject(cocos2d::CCObject*) = mac 0x419f90, ios 0x16504c; auto addObjectNew(cocos2d::CCObject*) = mac 0x41a450; @@ -53,22 +59,27 @@ class cocos2d::CCArray { // auto stringAtIndex(unsigned int) = mac 0x41a320; } +[[link(win)]] class cocos2d::CCBezierTo { static cocos2d::CCBezierTo* create(float, cocos2d::_ccBezierConfig const&) = mac 0x1f6c10; } +[[link(win)]] class cocos2d::CCBMFontConfiguration { static cocos2d::CCBMFontConfiguration* create(char const*) = mac 0x3450f0; } +[[link(win)]] class cocos2d::CCCallFunc { static auto create(cocos2d::CCObject*, cocos2d::SEL_CallFunc) = mac 0x454d90; } +[[link(win)]] class cocos2d::CCCallFuncO { static auto create(cocos2d::CCObject*, cocos2d::SEL_CallFuncO, cocos2d::CCObject*) = mac 0x455940; } +[[link(win)]] class cocos2d::CCClippingNode { CCClippingNode() { m_pStencil = nullptr; @@ -96,16 +107,18 @@ class cocos2d::CCClippingNode { } // not sure how the entire class is supposed to be added to only windows cuz idk if it even exists on mac -//class cocos2d::CCControllerHandler { +// class cocos2d::CCControllerHandler { // CCControllerHandler(int userIndex) = win 0xc7f50; // cocos2d::CCControllerState getState() = win 0xc7f80; // void updateConnected() = win 0xc7fb0; //} +[[link(win)]] class cocos2d::CCDelayTime { static cocos2d::CCDelayTime* create(float) = mac 0x1f4380; } +[[link(win)]] class cocos2d::CCDictionary { auto allKeys() = mac 0x190450, ios 0x2de774; auto count() = mac 0x190430; @@ -121,6 +134,7 @@ class cocos2d::CCDictionary { auto valueForKey(gd::string const&) = mac 0x1907a0; } +[[link(win)]] class cocos2d::CCDirector { CCDirector() {} ~CCDirector() {} @@ -163,6 +177,7 @@ class cocos2d::CCDirector { auto popSceneWithTransition(float, cocos2d::PopTransition) = mac 0x24a8b0; } +[[link(win)]] class cocos2d::CCDrawNode { CCDrawNode() = mac 0x378b40, win 0x6b9f0; auto clear() = mac 0x379e80; @@ -178,6 +193,7 @@ class cocos2d::CCDrawNode { virtual ~CCDrawNode() = mac 0x378cc0, win 0x6ba60; } +[[link(win)]] class cocos2d::CCAction { CCAction() = mac 0x35b610, win 0x7a6d0; virtual ~CCAction() = mac 0x35b6b0, win 0x7a7f0; @@ -189,11 +205,13 @@ class cocos2d::CCAction { auto update(float time) = mac 0x35b890; } +[[link(win)]] class cocos2d::CCFiniteTimeAction { // same as CCActionInterval::reverse i think auto reverse() = mac 0x1f2720; } +[[link(win)]] class cocos2d::CCActionInterval { auto copyWithZone(cocos2d::CCZone* zone) = mac 0x1f2550; auto isDone() = mac 0x1f2640; @@ -203,30 +221,37 @@ class cocos2d::CCActionInterval { bool initWithDuration(float d) = mac 0x1f2510; } +[[link(win)]] class cocos2d::CCEaseBackIn { static cocos2d::CCEaseBackIn* create(cocos2d::CCActionInterval*) = mac 0x2a41b0; } +[[link(win)]] class cocos2d::CCEaseElasticIn { static cocos2d::CCEaseElasticIn* create(cocos2d::CCActionInterval*, float) = mac 0x2a2e00; } +[[link(win)]] class cocos2d::CCEaseElasticOut { static cocos2d::CCEaseElasticOut* create(cocos2d::CCActionInterval*, float) = mac 0x2a3080; } +[[link(win)]] class cocos2d::CCEaseIn { static cocos2d::CCEaseIn* create(cocos2d::CCActionInterval*, float) = mac 0x2a1960; } +[[link(win)]] class cocos2d::CCEaseInOut { static cocos2d::CCEaseInOut* create(cocos2d::CCActionInterval*, float) = mac 0x2a1d80; } +[[link(win)]] class cocos2d::CCEaseOut { static cocos2d::CCEaseOut* create(cocos2d::CCActionInterval*, float) = mac 0x2a1b70; } +[[link(win)]] class cocos2d::CCEGLView { CCEGLView(); static cocos2d::CCEGLView* sharedOpenGLView() = mac 0x295320; @@ -250,6 +275,7 @@ class cocos2d::CCEGLView { void onGLFWWindowSizeFunCallback(GLFWwindow* window, int width, int height); } +[[link(win)]] class cocos2d::CCEGLViewProtocol { CCEGLViewProtocol() = win 0xbac00; virtual ~CCEGLViewProtocol() = win 0xbacc0; @@ -260,14 +286,17 @@ class cocos2d::CCEGLViewProtocol { auto setFrameSize(float, float) = mac 0x29d960; } +[[link(win)]] class cocos2d::CCFadeOut { static cocos2d::CCFadeOut* create(float) = mac 0x1f7d80; } +[[link(win)]] class cocos2d::CCFadeTo { static cocos2d::CCFadeTo* create(float, unsigned char) = mac 0x1f7ff0; } +[[link(win)]] class cocos2d::CCFileUtils : cocos2d::TypeInfo { static cocos2d::CCFileUtils* sharedFileUtils() = mac 0x377030, ios 0x159450; static void purgeFileUtils(); @@ -277,15 +306,18 @@ class cocos2d::CCFileUtils : cocos2d::TypeInfo { void removeAllPaths() = mac 0x241600; } +[[link(win)]] class cocos2d::CCGLProgram { auto setUniformsForBuiltins() = mac 0x232c70; auto use() = mac 0x231d70; } +[[link(win)]] class cocos2d::CCHide { static cocos2d::CCHide* create() = mac 0x4543e0; } +[[link(win)]] class cocos2d::CCIMEDelegate { ~CCIMEDelegate() { CCIMEDispatcher::sharedDispatcher()->removeDelegate(this); @@ -297,6 +329,7 @@ class cocos2d::CCIMEDelegate { } } +[[link(win)]] class cocos2d::CCIMEDispatcher { static auto sharedDispatcher() = mac 0x2773f0, ios 0x12d170; auto addDelegate(cocos2d::CCIMEDelegate*) = mac 0x277480, ios 0x12d204; @@ -305,6 +338,7 @@ class cocos2d::CCIMEDispatcher { void dispatchDeleteBackward() = mac 0x277af0; } +[[link(win)]] class cocos2d::CCImage { CCImage() = mac 0x24fa00, win 0xc5fd0; virtual ~CCImage() = mac 0x24fa80, win 0xc6100; @@ -313,17 +347,20 @@ class cocos2d::CCImage { auto initWithImageData(void*, int, cocos2d::CCImage::EImageFormat, int, int, int) = mac 0x24fcb0; } +[[link(win)]] class cocos2d::CCKeyboardDispatcher { bool dispatchKeyboardMSG(cocos2d::enumKeyCodes, bool) = mac 0xe8190; const char* keyToString(cocos2d::enumKeyCodes) = mac 0xe8450; } +[[link(win)]] class cocos2d::CCKeyboardHandler { static cocos2d::CCKeyboardHandler* handlerWithDelegate(cocos2d::CCKeyboardDelegate*) = mac 0x242030; virtual auto initWithDelegate(cocos2d::CCKeyboardDelegate*) = mac 0x241ff0, ios 0x13f8b8; ~CCKeyboardHandler() = mac 0x241e90, ios 0x13f87c, win 0x99a10; } +[[link(win)]] class cocos2d::CCKeypadHandler { static cocos2d::CCKeypadHandler* handlerWithDelegate(cocos2d::CCKeypadDelegate*) = mac 0x1ff2d0; virtual auto initWithDelegate(cocos2d::CCKeypadDelegate*) = mac 0x1ff290, ios 0x69; // iOS stub @@ -332,6 +369,7 @@ class cocos2d::CCKeypadHandler { } +[[link(win)]] class cocos2d::CCLabelBMFont { static cocos2d::CCLabelBMFont* create(char const*, char const*) = mac 0x347660; auto limitLabelWidth(float, float, float) = mac 0x34a6e0, ios 0x21b740; @@ -371,6 +409,7 @@ class cocos2d::CCLabelBMFont { virtual ~CCLabelBMFont() = mac 0x347e80, win 0x9be70; } +[[link(win)]] class cocos2d::CCLabelTTF { static cocos2d::CCLabelTTF* create() = mac 0x1fa7e0; static cocos2d::CCLabelTTF* create(char const*, char const*, float) = mac 0x1fa840; @@ -378,6 +417,7 @@ class cocos2d::CCLabelTTF { virtual auto setString(char const*) = mac 0x1fad70; } +[[link(win)]] class cocos2d::CCLayer { CCLayer() = mac 0x2725b0, ios 0xc7708, win 0xa15e0; virtual auto ccTouchBegan(cocos2d::CCTouch*, cocos2d::CCEvent*) = mac 0x2734d0, ios 0xc810c; @@ -418,6 +458,7 @@ class cocos2d::CCLayer { virtual ~CCLayer() = mac 0x2727b0, ios 0xc7848, win 0xa1940; } +[[link(win)]] class cocos2d::CCLayerColor { CCLayerColor() = mac 0x274320, ios 0xc8aec, win 0xa1710; static cocos2d::CCLayerColor* create(cocos2d::_ccColor4B const&, float, float) = mac 0x2745e0; @@ -435,6 +476,7 @@ class cocos2d::CCLayerColor { virtual ~CCLayerColor() = mac 0x2743d0, ios 0x2743e0, win 0xa1a20; } +[[link(win)]] class cocos2d::CCLayerRGBA { CCLayerRGBA() = mac 0x2738d0, ios 0xc85cc, win 0xa1890; virtual auto init() = mac 0x273b40, ios 0xc8de8; @@ -455,6 +497,7 @@ class cocos2d::CCLayerRGBA { virtual ~CCLayerRGBA() = mac 0x273aa0, ios 0xc77b0, win 0xa1b20; } +[[link(win)]] class cocos2d::CCMenu { auto alignItemsHorizontallyWithPadding(float) = mac 0x4393e0, ios 0x132508; auto alignItemsVerticallyWithPadding(float) = mac 0x439190; @@ -478,6 +521,7 @@ class cocos2d::CCMenu { cocos2d::CCMenuItem* itemForTouch(cocos2d::CCTouch*) = mac 0x438dd0; } +[[link(win)]] class cocos2d::CCMenuItem { bool initWithTarget(cocos2d::CCObject*, cocos2d::SEL_MenuHandler) = mac 0x1fb7f0; virtual ~CCMenuItem() = mac 0x1fb8e0, ios 0x2cdf4, win 0xab9c0; @@ -493,11 +537,13 @@ class cocos2d::CCMenuItem { auto rect() = mac 0x1fbb00, ios 0x2cf3c; } +[[link(win)]] class cocos2d::CCMenuItemImage { // virtual ~CCMenuItemImage() = mac 0x1febb0; virtual auto init() = mac 0x1fd750; } +[[link(win)]] class cocos2d::CCMenuItemLabel { virtual ~CCMenuItemLabel() = mac 0x1fc0d0; virtual auto activate() = mac 0x1fc240; @@ -510,6 +556,7 @@ class cocos2d::CCMenuItemLabel { virtual auto setLabel(cocos2d::CCNode*) = mac 0x1fbbc0; } +[[link(win)]] class cocos2d::CCMenuItemSprite { // virtual ~CCMenuItemSprite() = mac 0x1feab0; virtual auto selected() = mac 0x1fd3f0, ios 0x2d2cc; @@ -529,6 +576,7 @@ class cocos2d::CCMenuItemSprite { static auto create(cocos2d::CCNode*, cocos2d::CCNode*, cocos2d::CCObject*, cocos2d::SEL_MenuHandler) = mac 0x1fd2d0; } +[[link(win)]] class cocos2d::CCMotionStreak { CCMotionStreak() = win 0xae310; virtual ~CCMotionStreak() = win 0xae450; @@ -539,25 +587,30 @@ class cocos2d::CCMotionStreak { virtual auto draw(); } +[[link(win)]] class cocos2d::CCMouseDispatcher { bool dispatchScrollMSG(float x, float y) = mac 0x2e8f40; void removeDelegate(cocos2d::CCMouseDelegate* delegate); } +[[link(win)]] class cocos2d::CCMouseHandler { static cocos2d::CCMouseHandler* handlerWithDelegate(cocos2d::CCMouseDelegate*) = mac 0x12ef80; virtual auto initWithDelegate(cocos2d::CCMouseDelegate*) = mac 0x12ef40, ios 0x43798; ~CCMouseHandler() = mac 0x12ede0, ios 0x4375c, win 0xb1fd0; } +[[link(win)]] class cocos2d::CCMoveBy { static cocos2d::CCMoveBy* create(float, cocos2d::CCPoint const&) = mac 0x1f50e0; } +[[link(win)]] class cocos2d::CCMoveTo { static cocos2d::CCMoveTo* create(float, cocos2d::CCPoint const&) = mac 0x1f54d0; } +[[link(win)]] class cocos2d::CCNode { CCNode() = mac 0x122550, win 0x5e7d0; auto boundingBox() = mac 0x123030; @@ -677,6 +730,7 @@ class cocos2d::CCNode { virtual ~CCNode() = mac 0x122750, ios 0x6c98, win 0x5ea40; } +[[link(win)]] class cocos2d::CCNodeRGBA { CCNodeRGBA() = mac 0x124b30, win 0x5e9d0; virtual ~CCNodeRGBA() = mac 0x124bb0, ios 0x15f748, win 0x5ebb0; @@ -695,6 +749,7 @@ class cocos2d::CCNodeRGBA { virtual auto setCascadeColorEnabled(bool) = mac 0x125340, ios 0x15fb80; } +[[link(win)]] class cocos2d::CCObject { CCObject() = mac 0x250ca0, ios 0x43864, win 0x69230; auto acceptVisitor(cocos2d::CCDataVisitor&) = mac 0x250f30, ios 0x439f0; @@ -710,6 +765,7 @@ class cocos2d::CCObject { ~CCObject() = mac 0x250d20, ios 0x6ac0, win 0x69270; } +[[link(win)]] class cocos2d::CCParticleSystem { CCParticleSystem() = win 0xb6650; virtual ~CCParticleSystem() = win 0xb68e0; @@ -720,6 +776,7 @@ class cocos2d::CCParticleSystem { auto stopSystem() = mac 0x46bd10; } +[[link(win)]] class cocos2d::CCParticleSystemQuad { CCParticleSystemQuad() = win 0xb9bd0; virtual ~CCParticleSystemQuad() = win 0xb9c10; @@ -728,15 +785,18 @@ class cocos2d::CCParticleSystemQuad { auto setupVBO(); } +[[link(win)]] class cocos2d::CCPoolManager { auto pop() = mac 0x214620; static cocos2d::CCPoolManager* sharedPoolManager() = mac 0x2142c0; } +[[link(win)]] class cocos2d::CCRemoveSelf { static cocos2d::CCRemoveSelf* create(bool) = mac 0x454700; } +[[link(win)]] class cocos2d::CCRenderTexture { auto begin() = mac 0x35ce10; auto end() = mac 0x35d2c0; @@ -746,37 +806,45 @@ class cocos2d::CCRenderTexture { auto beginWithClear(float r, float g, float b, float a) = mac 0x35d010; } +[[link(win)]] class cocos2d::CCRepeat { static cocos2d::CCRepeat* create(cocos2d::CCFiniteTimeAction*, unsigned int) = mac 0x1f3230; } +[[link(win)]] class cocos2d::CCRepeatForever { static cocos2d::CCRepeatForever* create(cocos2d::CCActionInterval*) = mac 0x1f3920; } +[[link(win)]] class cocos2d::CCRotateBy { static cocos2d::CCRotateBy* create(float, float) = mac 0x1f4c50; } +[[link(win)]] class cocos2d::CCRotateTo { static cocos2d::CCRotateTo* create(float, float) = mac 0x1f47b0; } +[[link(win)]] class cocos2d::CCScaleTo { static cocos2d::CCScaleTo* create(float, float) = mac 0x1f6ff0; static cocos2d::CCScaleTo* create(float, float, float) = mac 0x1f70f0; } +[[link(win)]] class cocos2d::CCScaleBy { static cocos2d::CCScaleTo* create(float, float) = mac 0x1f73c0; static cocos2d::CCScaleTo* create(float, float, float) = mac 0x1f7480; } +[[link(win)]] class cocos2d::CCScene { static cocos2d::CCScene* create() = mac 0x13c140, ios 0x163070; auto getHighestChildZ() = mac 0x13c200, ios 0x1630e4; } +[[link(win)]] class cocos2d::CCScheduler { auto scheduleSelector(cocos2d::SEL_SCHEDULE, cocos2d::CCObject*, float, unsigned int, float, bool) = mac 0x242b20; void scheduleSelector(cocos2d::SEL_SCHEDULE selector, cocos2d::CCObject* target, float interval, bool paused) { @@ -791,10 +859,12 @@ class cocos2d::CCScheduler { virtual void update(float delta) = mac 0x2446d0; } +[[link(win)]] class cocos2d::CCSequence { static auto createWithVariableList(cocos2d::CCFiniteTimeAction*, va_list) = mac 0x1f2910; } +[[link(win)]] class cocos2d::CCSet { CCSet() = mac 0x45ad80, ios 0x10e870, win 0x699e0; static auto create() = mac 0x45b0b0; @@ -804,11 +874,13 @@ class cocos2d::CCSet { auto anyObject() = mac 0x45b410; } +[[link(win)]] class cocos2d::CCShaderCache { static auto sharedShaderCache() = mac 0xe6d10; auto programForKey(const char*) = mac 0xe7d40; } +[[link(win)]] class cocos2d::CCSprite { virtual ~CCSprite() = mac 0x133430, ios 0x15b92c, win 0xd2f90; virtual auto init() = mac 0x132ef0, ios 0x15b488; @@ -883,6 +955,7 @@ class cocos2d::CCSprite { void setFlipY(bool) = mac 0x134c30; } +[[link(win)]] class cocos2d::CCSpriteBatchNode { static cocos2d::CCSpriteBatchNode* create(char const*, unsigned int) = mac 0xbb540; static auto createWithTexture(cocos2d::CCTexture2D*, unsigned int) = mac 0xbb310; @@ -907,24 +980,28 @@ class cocos2d::CCSpriteBatchNode { virtual auto getBlendFunc() = mac 0xbcd50, ios 0x131a60; } +[[link(win)]] class cocos2d::CCSpriteFrame { static auto createWithTexture(cocos2d::CCTexture2D*, cocos2d::CCRect const&, bool, cocos2d::CCPoint const&, cocos2d::CCSize const&) = mac 0x1ac7f0; static auto createWithTexture(cocos2d::CCTexture2D*, cocos2d::CCRect const&) = mac 0x1ac5c0; auto getTexture() = mac 0x1ad250; } +[[link(win)]] class cocos2d::CCSpriteFrameCache { auto addSpriteFramesWithFile(char const*) = mac 0x199a10, ios 0x29e818; static cocos2d::CCSpriteFrameCache* sharedSpriteFrameCache() = mac 0x198970, ios 0x29dc4c; auto spriteFrameByName(char const*) = mac 0x19a7e0; } +[[link(win)]] class cocos2d::CCStandardTouchHandler { static cocos2d::CCStandardTouchHandler* handlerWithDelegate(cocos2d::CCTouchDelegate*, int) = mac 0x247f30; virtual auto initWithDelegate(cocos2d::CCTouchDelegate*, int) = mac 0x247ed0, ios 0x69; // iOS stub ~CCStandardTouchHandler() = mac 0x2482a0, ios 0x6d28, win 0xf5a40; } +[[link(win)]] class cocos2d::CCString { // virtual ~CCString() = mac 0x44c590; virtual auto isEqual(cocos2d::CCObject const*) = mac 0x44c8f0, ios 0x1a1e6c; @@ -940,6 +1017,7 @@ class cocos2d::CCString { auto intValue() const = mac 0x44c780, ios 0x1a1ca8; } +[[link(win)]] class cocos2d::CCTargetedTouchHandler { static cocos2d::CCTargetedTouchHandler* handlerWithDelegate(cocos2d::CCTouchDelegate*, int, bool) = mac 0x248010; auto initWithDelegate(cocos2d::CCTouchDelegate*, int, bool) = mac 0x2480f0, ios 0x69; // iOS stub @@ -947,6 +1025,7 @@ class cocos2d::CCTargetedTouchHandler { } +[[link(win)]] class cocos2d::CCTexture2D { CCTexture2D() = mac 0x246280, win 0xe9300; ~CCTexture2D() = mac 0x246350, win 0xe93f0; @@ -971,6 +1050,7 @@ class cocos2d::CCTexture2D { auto setTexParameters(cocos2d::_ccTexParams*) = mac 0x247980; } +[[link(win)]] class cocos2d::CCTextureAtlas { CCTextureAtlas() = win 0xea680; virtual ~CCTextureAtlas() = win 0xea6c0; @@ -978,10 +1058,12 @@ class cocos2d::CCTextureAtlas { auto mapBuffers(); } +[[link(win)]] class cocos2d::CCTextFieldTTF { static auto textFieldWithPlaceHolder(char const*, char const*, float) = mac 0x126220; } +[[link(win)]] class cocos2d::CCTextureCache { auto addImage(char const*, bool) = mac 0x358120, ios 0xa8388; auto textureForKey(char const*) = mac 0x359050; @@ -989,14 +1071,17 @@ class cocos2d::CCTextureCache { static cocos2d::CCTextureCache* sharedTextureCache() = mac 0x356e00, ios 0xa81ec; } +[[link(win)]] class cocos2d::CCTime { static auto gettimeofdayCocos2d(cocos2d::cc_timeval*, void*) = mac 0x19eac0; } +[[link(win)]] class cocos2d::CCTintTo { static cocos2d::CCTintTo* create(float, unsigned char, unsigned char, unsigned char) = mac 0x1f82a0; } +[[link(win)]] class cocos2d::CCTouch { auto getDelta() const = mac 0x38340; auto getLocationInView() const = mac 0x38250; @@ -1005,6 +1090,7 @@ class cocos2d::CCTouch { auto getStartLocation() const = mac 0x382e0; } +[[link(win)]] class cocos2d::CCTouchDispatcher { auto addTargetedDelegate(cocos2d::CCTouchDelegate*, int, bool) = mac 0x281180; auto addStandardDelegate(cocos2d::CCTouchDelegate*, int) = mac 0x281060; @@ -1014,22 +1100,26 @@ class cocos2d::CCTouchDispatcher { void touches(cocos2d::CCSet*, cocos2d::CCEvent*, unsigned int) = mac 0x281a60; } +[[link(win)]] class cocos2d::CCTouchHandler { virtual auto initWithDelegate(cocos2d::CCTouchDelegate*, int) = mac 0x247d10, ios 0x69f8; auto getPriority() = mac 0x247c20; ~CCTouchHandler() = mac 0x247de0, ios 0x6ac0; } +[[link(win)]] class cocos2d::CCTransitionFade { static cocos2d::CCTransitionFade* create(float, cocos2d::CCScene*) = mac 0x8ea30, ios 0x12c244; } +[[link(win)]] class cocos2d::ZipUtils { static auto compressString(gd::string, bool, int) = mac 0xe9a50; static auto decompressString(gd::string, bool, int) = mac 0xea380; static int ccDeflateMemory(unsigned char*, unsigned int, unsigned char**) = mac 0xe9cf0; } +[[link(win)]] class cocos2d::extension::CCControl { CCControl() {} virtual bool init() = mac 0x1a71c0; @@ -1053,6 +1143,7 @@ class cocos2d::extension::CCControl { auto isSelected() = mac 0x1a7ec0; } +[[link(win)]] class cocos2d::extension::CCControlColourPicker { CCControlColourPicker() {} ~CCControlColourPicker() = mac 0x1aae30; @@ -1066,11 +1157,13 @@ class cocos2d::extension::CCControlColourPicker { } +[[link(win)]] class cocos2d::extension::CCControlUtils { static cocos2d::extension::HSV HSVfromRGB(cocos2d::extension::RGBA) = mac 0x1e6750; static cocos2d::extension::RGBA RGBfromHSV(cocos2d::extension::HSV) = mac 0x1e6850; } +[[link(win)]] class cocos2d::extension::CCScale9Sprite { CCScale9Sprite() = mac 0x211330; static cocos2d::extension::CCScale9Sprite* create(char const*) = mac 0x2130d0; @@ -1116,6 +1209,7 @@ class cocos2d::extension::CCScale9Sprite { virtual auto setSpriteFrame(cocos2d::CCSpriteFrame*) = mac 0x213a90; } +[[link(win)]] class cocos2d::extension::CCScrollView { CCScrollView() = mac 0x214800; virtual ~CCScrollView() = mac 0x214c30; @@ -1134,6 +1228,7 @@ class cocos2d::extension::CCScrollView { virtual auto setTouchEnabled(bool) = mac 0x215250; } +[[link(win)]] class cocos2d { static auto FNTConfigLoadFile(char const*) = mac 0x344f10; static auto ccGLBlendFunc(GLenum, GLenum) = mac 0x1ae560; @@ -1146,6 +1241,7 @@ class cocos2d { static void CCMessageBox(const char* msg, const char* title) = mac 0xbabc0; } +[[link(win)]] class DS_Dictionary { DS_Dictionary() = mac 0xbe9a0; ~DS_Dictionary() = mac 0x393c30; @@ -1156,6 +1252,7 @@ class DS_Dictionary { void setIntegerForKey(char const*, int) = mac 0xc26b0; } +[[link(win)]] class pugi::xml_document { xml_document() = mac 0x393a80; ~xml_document() = mac 0x393b50; diff --git a/bindings/GeometryDash.bro b/bindings/GeometryDash.bro index e85f2854..86cdfbb0 100644 --- a/bindings/GeometryDash.bro +++ b/bindings/GeometryDash.bro @@ -16,6 +16,8 @@ class GDString { void macDestroy() = mac 0x489f78; } +void testFunction(int a) = mac 0x100000; + class AchievementBar : cocos2d::CCNodeRGBA { static AchievementBar* create(const char* title, const char* desc, const char* icon, bool quest) = mac 0x379f80, win 0x3b120, ios 0x1a4784; diff --git a/codegen/CMakeLists.txt b/codegen/CMakeLists.txt index 190f7f1c..2e3833a5 100644 --- a/codegen/CMakeLists.txt +++ b/codegen/CMakeLists.txt @@ -4,7 +4,7 @@ project(Codegen LANGUAGES C CXX) include(../cmake/CPM.cmake) CPMAddPackage("gh:fmtlib/fmt#9.1.0") -CPMAddPackage("gh:geode-sdk/Broma#a9c1d2e") +CPMAddPackage("gh:geode-sdk/Broma#460f82d") file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp diff --git a/codegen/src/AddressGen.cpp b/codegen/src/AddressGen.cpp index d432b1f1..bc154b1c 100644 --- a/codegen/src/AddressGen.cpp +++ b/codegen/src/AddressGen.cpp @@ -73,10 +73,34 @@ Result geode::modifier::handlerMetadataForAddress( } } -std::string generateAddressHeader(Root& root) { +std::string generateAddressHeader(Root const& root) { std::string output; output += format_strings::address_begin; + for (auto& f : root.functions) { + std::string address_str; + + if (codegen::getStatus(f) == BindStatus::Binded) { + address_str = fmt::format( + "addresser::getNonVirtual(Resolve<{}>::func(&{}))", + codegen::getParameterTypes(f.prototype), + f.prototype.name + ); + } + else if (codegen::getStatus(f) == BindStatus::NeedsBinding) { + address_str = fmt::format("base::get() + 0x{:x}", codegen::platformNumber(f.binds)); + } + else { + continue; + } + + output += fmt::format( + format_strings::declare_address, + fmt::arg("address", address_str), + fmt::arg("index", codegen::getId(&f)) + ); + } + for (auto& c : root.classes) { for (auto& field : c.fields) { std::string address_str; @@ -87,7 +111,16 @@ std::string generateAddressHeader(Root& root) { continue; } - if (codegen::getStatus(field) == BindStatus::Binded) { + + if (codegen::getStatus(field) == BindStatus::NeedsBinding || codegen::platformNumber(field)) { + if (is_cocos_class(field.parent) && codegen::platform == Platform::Windows) { + address_str = fmt::format("base::getCocos() + 0x{:x}", codegen::platformNumber(fn->binds)); + } + else { + address_str = fmt::format("base::get() + 0x{:x}", codegen::platformNumber(fn->binds)); + } + } + else if (codegen::getStatus(field) == BindStatus::Binded && fn->prototype.type == FunctionType::Normal) { address_str = fmt::format( "addresser::get{}Virtual(Resolve<{}>::func(&{}::{}))", str_if("Non", !fn->prototype.is_virtual), @@ -96,22 +129,14 @@ std::string generateAddressHeader(Root& root) { fn->prototype.name ); } - else if (codegen::getStatus(field) == BindStatus::NeedsBinding) { - if (is_cocos_class(field.parent) && codegen::platform == Platform::Windows) { - address_str = fmt::format("base::getCocos() + 0x{:x}", codegen::platformNumber(fn->binds)); - } - else { - address_str = fmt::format("base::get() + 0x{:x}", codegen::platformNumber(fn->binds)); - } - } else { continue; } output += fmt::format( - ::format_strings::declare_address, + format_strings::declare_address, fmt::arg("address", address_str), - fmt::arg("index", field.field_id) + fmt::arg("index", codegen::getId(&field)) ); } } diff --git a/codegen/src/BindingGen.cpp b/codegen/src/BindingGen.cpp index 90db47d0..eb4359c3 100644 --- a/codegen/src/BindingGen.cpp +++ b/codegen/src/BindingGen.cpp @@ -83,17 +83,17 @@ inline std::string nameForPlatform(Platform platform) { } } - -std::string generateAddressDocs(Field const& field, FunctionBindField* fn) { +template +std::string generateAddressDocs(T const& f, PlatformNumber pn) { std::string ret; for (auto platform : {Platform::Mac, Platform::Windows, Platform::iOS, Platform::Android}) { - auto status = codegen::getStatusWithPlatform(platform, field); + auto status = codegen::getStatusWithPlatform(platform, f); if (status == BindStatus::NeedsBinding) { ret += fmt::format(" * @note[short] {}: 0x{:x}\n", nameForPlatform(platform), - codegen::platformNumberWithPlatform(platform, fn->binds) + codegen::platformNumberWithPlatform(platform, pn) ); } else if (status == BindStatus::Binded) { @@ -118,9 +118,42 @@ std::string generateDocs(std::string const& docs) { return ret; } -std::string generateBindingHeader(Root& root, ghc::filesystem::path const& singleFolder) { +std::string generateBindingHeader(Root const& root, ghc::filesystem::path const& singleFolder) { std::string output; + { + std::string filename = "Standalones.hpp"; + output += fmt::format(format_strings::binding_include, + fmt::arg("file_name", filename) + ); + + std::string single_output; + single_output += format_strings::class_includes; + + for (auto& f : root.functions) { + FunctionProto const* fb = &f.prototype; + char const* used_format = format_strings::function_definition; + + std::string addressDocs = generateAddressDocs(f, f.binds); + std::string docs = generateDocs(fb->docs); + + single_output += fmt::format(used_format, + fmt::arg("virtual", ""), + fmt::arg("static", ""), + fmt::arg("class_name", ""), + fmt::arg("const", ""), + fmt::arg("function_name", fb->name), + fmt::arg("parameters", codegen::getParameters(*fb)), + fmt::arg("return_type", fb->ret.name), + fmt::arg("docs_addresses", addressDocs), + fmt::arg("docs", docs) + ); + + } + + writeFile(singleFolder / filename, single_output); + } + for (auto& cls : root.classes) { if (is_cocos_class(cls.name)) continue; @@ -207,7 +240,7 @@ std::string generateBindingHeader(Root& root, ghc::filesystem::path const& singl continue; } - addressDocs = generateAddressDocs(field, fn); + addressDocs = generateAddressDocs(field, fn->binds); } std::string docs = generateDocs(fb->docs); @@ -218,7 +251,6 @@ std::string generateBindingHeader(Root& root, ghc::filesystem::path const& singl fmt::arg("class_name", cls.name), fmt::arg("const", str_if(" const ", fb->is_const)), fmt::arg("function_name", fb->name), - fmt::arg("index", field.field_id), fmt::arg("parameters", codegen::getParameters(*fb)), fmt::arg("return_type", fb->ret.name), fmt::arg("docs_addresses", addressDocs), diff --git a/codegen/src/Main.cpp b/codegen/src/Main.cpp index 834b3bcd..3b904c03 100644 --- a/codegen/src/Main.cpp +++ b/codegen/src/Main.cpp @@ -4,6 +4,8 @@ using namespace codegen; +std::map codegen::idMap; + int main(int argc, char** argv) try { if (argc != 4) throw codegen::error("Invalid number of parameters (expected 3 found {})", argc - 1); @@ -35,10 +37,10 @@ int main(int argc, char** argv) try { } } + codegen::populateIds(root); + writeFile(writeDir / "GeneratedAddress.cpp", generateAddressHeader(root)); writeFile(writeDir / "GeneratedModify.hpp", generateModifyHeader(root, writeDir / "modify")); - // writeFile(writeDir / "GeneratedWrapper.hpp", generateWrapperHeader(root)); - // writeFile(writeDir / "GeneratedType.hpp", generateTypeHeader(root)); writeFile(writeDir / "GeneratedBinding.hpp", generateBindingHeader(root, writeDir / "binding")); writeFile(writeDir / "GeneratedPredeclare.hpp", generatePredeclareHeader(root)); writeFile(writeDir / "GeneratedSource.cpp", generateBindingSource(root)); diff --git a/codegen/src/ModifyGen.cpp b/codegen/src/ModifyGen.cpp index b105e7e9..937cd527 100644 --- a/codegen/src/ModifyGen.cpp +++ b/codegen/src/ModifyGen.cpp @@ -54,10 +54,10 @@ namespace geode::modifier {{ } } -std::string generateModifyHeader(Root& root, ghc::filesystem::path const& singleFolder) { +std::string generateModifyHeader(Root const& root, ghc::filesystem::path const& singleFolder) { std::string output; - for (auto c : root.classes) { + for (auto& c : root.classes) { if (c.name == "cocos2d") continue; std::string filename = (codegen::getUnqualifiedClassName(c.name) + ".hpp"); @@ -83,11 +83,11 @@ std::string generateModifyHeader(Root& root, ghc::filesystem::path const& single std::string statics; std::set used; for (auto& f : c.fields) { - if (auto fn = f.get_fn()) { - if (fn->type == FunctionType::Normal && !used.count(fn->name)) { - used.insert(fn->name); + if (auto fn = f.get_as()) { + if (fn->prototype.type == FunctionType::Normal && !used.count(fn->prototype.name)) { + used.insert(fn->prototype.name); statics += fmt::format( - format_strings::statics_declare_identifier, fmt::arg("function_name", fn->name) + format_strings::statics_declare_identifier, fmt::arg("function_name", fn->prototype.name) ); } } @@ -102,32 +102,44 @@ std::string generateModifyHeader(Root& root, ghc::filesystem::path const& single // modify for (auto& f : c.fields) { - if (codegen::getStatus(f) != BindStatus::Unbindable) { - auto begin = f.get_fn(); + auto fn = f.get_as(); - std::string format_string; - - switch (begin->type) { - case FunctionType::Normal: - format_string = format_strings::apply_function; - break; - case FunctionType::Ctor: - format_string = format_strings::apply_constructor; - break; - case FunctionType::Dtor: - format_string = format_strings::apply_destructor; - break; - } - - single_output += fmt::format( - format_string, - fmt::arg("addr_index", f.field_id), - fmt::arg("class_name", c.name), - fmt::arg("function_name", begin->name), - fmt::arg("function_convention", codegen::getModifyConventionName(f)), - fmt::arg("parameter_types", codegen::getParameterTypes(*begin)) - ); + if (!fn) { + continue; } + + if (codegen::getStatus(f) == BindStatus::NeedsBinding || codegen::platformNumber(f)) { + + } + else if (codegen::getStatus(f) == BindStatus::Binded && fn->prototype.type == FunctionType::Normal) { + + } + else { + continue; + } + + std::string format_string; + + switch (fn->prototype.type) { + case FunctionType::Normal: + format_string = format_strings::apply_function; + break; + case FunctionType::Ctor: + format_string = format_strings::apply_constructor; + break; + case FunctionType::Dtor: + format_string = format_strings::apply_destructor; + break; + } + + single_output += fmt::format( + format_string, + fmt::arg("addr_index", codegen::getId(&f)), + fmt::arg("class_name", c.name), + fmt::arg("function_name", fn->prototype.name), + fmt::arg("function_convention", codegen::getModifyConventionName(f)), + fmt::arg("parameter_types", codegen::getParameterTypes(fn->prototype)) + ); } single_output += format_strings::modify_end; diff --git a/codegen/src/PredeclareGen.cpp b/codegen/src/PredeclareGen.cpp index e7de1cf2..426cca65 100644 --- a/codegen/src/PredeclareGen.cpp +++ b/codegen/src/PredeclareGen.cpp @@ -6,7 +6,7 @@ namespace { namespace format_strings { char const* class_predeclare = "class {class_name};\n"; }} -std::string generatePredeclareHeader(Root& root) { +std::string generatePredeclareHeader(Root const& root) { std::string output("#pragma once\n"); for (auto& cls : root.classes) { diff --git a/codegen/src/Shared.hpp b/codegen/src/Shared.hpp index ef129d6c..c8e07b6f 100644 --- a/codegen/src/Shared.hpp +++ b/codegen/src/Shared.hpp @@ -15,14 +15,11 @@ using std::istreambuf_iterator; using namespace broma; -std::string generateAddressHeader(Root& root); -std::string generateModifyHeader(Root& root, ghc::filesystem::path const& singleFolder); -std::string generateWrapperHeader(Root& root); -std::string generateTypeHeader(Root& root); -std::string generateBindingHeader(Root& root, ghc::filesystem::path const& singleFolder); -std::string generatePredeclareHeader(Root& root); -std::string generateBindingSource(Root& root); -std::string generateTidyHeader(Root& root); +std::string generateAddressHeader(Root const& root); +std::string generateModifyHeader(Root const& root, ghc::filesystem::path const& singleFolder); +std::string generateBindingHeader(Root const& root, ghc::filesystem::path const& singleFolder); +std::string generatePredeclareHeader(Root const& root); +std::string generateBindingSource(Root const& root); inline void writeFile(ghc::filesystem::path const& writePath, std::string const& output) { std::ifstream readfile; @@ -62,6 +59,30 @@ struct codegen_error : std::runtime_error { }; namespace codegen { + extern std::map idMap; + + inline void populateIds(Root const& root) { + size_t id = 0; + for (auto& f : root.functions) { + idMap[&f] = id++; + } + + for (auto& c : root.classes) { + for (auto& f : c.fields) { + if (auto fn = f.get_as()) { + idMap[&f] = id++; + } + } + } + } + + inline size_t getId(Function const* f) { + return idMap[f]; + } + + inline size_t getId(Field const* f) { + return idMap[f]; + } template inline codegen_error error(Args... args) { @@ -85,37 +106,25 @@ namespace codegen { return platformNumberWithPlatform(codegen::platform, p); } - inline BindStatus getStatusWithPlatform(Platform p, Field const& field) { - MemberFunctionProto const* fb; - + inline uintptr_t platformNumber(Field const& field) { if (auto fn = field.get_as()) { + return platformNumberWithPlatform(codegen::platform, fn->binds); + } + return 0; + } + + inline BindStatus getStatusWithPlatform(Platform p, Field const& field) { + if (auto fn = field.get_as()) { + if ((fn->links & p) != Platform::None) return BindStatus::Binded; if (platformNumberWithPlatform(p, fn->binds)) return BindStatus::NeedsBinding; - - fb = &fn->prototype; - } - else if (auto fn = field.get_as()) { - fb = &fn->prototype; - } - else return BindStatus::Unbindable; - - // if (field.parent.rfind("GDString", 0) == 0) return BindStatus::NeedsBinding; - - if (p == Platform::Android) { - for (auto& [type, name] : fb->args) { - if (type.name.find("gd::") != std::string::npos) return BindStatus::NeedsBinding; - } - - if (field.parent.rfind("cocos2d::CCEGLView", 0) == 0) return BindStatus::Unbindable; - - return BindStatus::Binded; } - if (fb->type == FunctionType::Normal) { - if (field.parent.rfind("fmod::", 0) == 0) return BindStatus::Binded; - if ((field.parent.rfind("cocos2d::", 0) == 0 || field.parent == "DS_Dictionary") && - p == Platform::Windows) - return BindStatus::Binded; - } + return BindStatus::Unbindable; + } + + inline BindStatus getStatusWithPlatform(Platform p, Function const& f) { + if ((f.links & p) != Platform::None) return BindStatus::Binded; + if (platformNumberWithPlatform(p, f.binds)) return BindStatus::NeedsBinding; return BindStatus::Unbindable; } @@ -124,6 +133,10 @@ namespace codegen { return getStatusWithPlatform(codegen::platform, field); } + inline BindStatus getStatus(Function const& f) { + return getStatusWithPlatform(codegen::platform, f); + } + inline std::string getParameters(FunctionProto const& f) { // int p0, float p1 std::vector parameters; @@ -154,17 +167,17 @@ namespace codegen { return fmt::format("{}", fmt::join(parameters, ", ")); } - inline std::string getModifyConventionName(Field& f) { + inline std::string getModifyConventionName(Field const& f) { if (codegen::platform != Platform::Windows) return "Default"; - if (auto fn = f.get_fn()) { + if (auto fn = f.get_as()) { auto status = getStatus(f); - if (fn->is_static) { + if (fn->prototype.is_static) { if (status == BindStatus::Binded) return "Cdecl"; else return "Optcall"; } - else if (fn->is_virtual || fn->is_callback) { + else if (fn->prototype.is_virtual || fn->prototype.is_callback) { return "Thiscall"; } else { @@ -175,13 +188,19 @@ namespace codegen { else throw codegen::error("Tried to get convention of non-function"); } - inline std::string getConvention(Field& f) { + inline std::string getModifyConventionName(Function const& f) { + if (codegen::platform != Platform::Windows) return "Default"; + + return "Cdecl"; + } + + inline std::string getConvention(Field const& f) { if (codegen::platform != Platform::Windows) return "DefaultConv"; return std::string("x86::") + getModifyConventionName(f); } - inline std::string getModifyConvention(Field& f) { + inline std::string getModifyConvention(Field const& f) { if (codegen::platform != Platform::Windows) return "tulip::hook::DefaultConvention"; return std::string("tulip::hook::") + getModifyConventionName(f) + "Convention"; diff --git a/codegen/src/SourceGen.cpp b/codegen/src/SourceGen.cpp index 3f6a1f9b..35f58962 100644 --- a/codegen/src/SourceGen.cpp +++ b/codegen/src/SourceGen.cpp @@ -117,26 +117,50 @@ auto {class_name}::{function_name}({parameters}){const} -> decltype({function_na char const* ool_structor_function_definition = R"GEN( {class_name}::{function_name}({parameters}){const} {definition} +)GEN"; + + char const* declare_standalone = R"GEN( +auto {function_name}({parameters}) -> decltype({function_name}({arguments})) {{ + using FunctionType = decltype({function_name}({arguments}))(*)({parameter_types}); + static auto func = wrapFunction(address<{addr_index}>(), tulip::hook::WrapperMetadata{{ + .m_convention = geode::hook::createConvention(tulip::hook::TulipConvention::{convention}), + .m_abstract = tulip::hook::AbstractFunction::from(FunctionType(nullptr)), + }}); + return reinterpret_cast(func)({arguments}); +}} )GEN"; }} -std::string generateBindingSource(Root& root) { +std::string generateBindingSource(Root const& root) { std::string output(format_strings::source_start); + for (auto& f : root.functions) { + if (codegen::getStatus(f) != BindStatus::NeedsBinding) { + continue; + } + + output += fmt::format(format_strings::declare_standalone, + fmt::arg("convention", codegen::getModifyConventionName(f)), + fmt::arg("function_name", f.prototype.name), + fmt::arg("addr_index", codegen::getId(&f)), + fmt::arg("parameters", codegen::getParameters(f.prototype)), + fmt::arg("parameter_types", codegen::getParameterTypes(f.prototype)), + fmt::arg("arguments", codegen::getParameterNames(f.prototype)), + fmt::arg("parameter_comma", str_if(", ", !f.prototype.args.empty())) + ); + } + for (auto& c : root.classes) { for (auto& f : c.fields) { if (auto i = f.get_as()) { - if (codegen::platform == Platform::Mac || codegen::platform == Platform::iOS) { - if (is_cocos_class(c.name)) - output += i->inner + "\n"; - } - } else if (auto fn = f.get_as()) { - if (codegen::getStatus(f) != BindStatus::Unbindable) + // yeah there are no inlines on cocos + } + else if (auto fn = f.get_as()) { + if ((c.links & codegen::platform) != Platform::None) { continue; - - // no cocos2d definitions on windows - if (codegen::platform == Platform::Windows && is_cocos_class(f.parent)) { + } + if (codegen::getStatus(f) != BindStatus::Unbindable) { continue; } @@ -163,14 +187,15 @@ std::string generateBindingSource(Root& root) { break; } - } else if (auto fn = f.get_as()) { + } + else if (auto fn = f.get_as()) { char const* used_declare_format = nullptr; - if (codegen::platform == Platform::Windows && is_cocos_class(f.parent)) { - // no cocos2d definitions on windows - continue; - } - else if (!codegen::platformNumber(fn->binds) && fn->prototype.is_virtual && fn->prototype.type != FunctionType::Dtor) { + if ( + codegen::getStatus(f) == BindStatus::Unbindable && + !codegen::platformNumber(fn->binds) && + fn->prototype.is_virtual && fn->prototype.type != FunctionType::Dtor + ) { used_declare_format = format_strings::declare_virtual_error; } else if (codegen::getStatus(f) != BindStatus::NeedsBinding) { @@ -203,7 +228,7 @@ std::string generateBindingSource(Root& root) { fmt::arg("const", str_if(" const ", fn->prototype.is_const)), fmt::arg("convention", codegen::getModifyConventionName(f)), fmt::arg("function_name", fn->prototype.name), - fmt::arg("addr_index", f.field_id), + fmt::arg("addr_index", codegen::getId(&f)), fmt::arg("parameters", codegen::getParameters(fn->prototype)), fmt::arg("parameter_types", codegen::getParameterTypes(fn->prototype)), fmt::arg("arguments", codegen::getParameterNames(fn->prototype)), diff --git a/codegen/src/WrapperGen.cpp b/codegen/src/WrapperGen.cpp deleted file mode 100644 index 9397ac6b..00000000 --- a/codegen/src/WrapperGen.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "Shared.hpp" -#include - -namespace { namespace format_strings { - - char const* declare_member_type = R"GEN( -GEODE_WRAPPER_FOR_IDENTIFIER({function_name}) )GEN"; -}} - -using std::set; - -std::string generateWrapperHeader(Root& root) { - std::string output; - std::set used; - - for (auto& c : root.classes) { - for (auto& f : c.fields) { - if (auto fn = f.get_fn()) { - if (fn->type == FunctionType::Normal && !used.count(fn->name)) { - used.insert(fn->name); - output += fmt::format(format_strings::declare_member_type, - fmt::arg("function_name", fn->name) - ); - } - } - } - } - - return output; -}