From 0fc7feb3f02dab98c8d6f2a8cbf024be39f8e344 Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Tue, 18 Sep 2012 17:38:33 -0700 Subject: [PATCH 1/9] Updating CCBReader to support Scripting Owners --- extensions/CCBReader/CCBReader.h | 6 ++++-- extensions/CCBReader/CCBSelectorResolver.h | 12 ++++++++++-- extensions/CCBReader/CCNodeLoader.cpp | 11 +++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/extensions/CCBReader/CCBReader.h b/extensions/CCBReader/CCBReader.h index a4314e37d2..459fe23416 100644 --- a/extensions/CCBReader/CCBReader.h +++ b/extensions/CCBReader/CCBReader.h @@ -235,7 +235,8 @@ public: static float getResolutionScale(); CCNode* readFileWithCleanUp(bool bCleanUp); - + bool hasScriptingOwner = false; + private: void cleanUpNodeGraph(CCNode *pNode); bool readSequences(); @@ -250,6 +251,7 @@ private: bool getBit(); void alignBits(); CCString* readUTF8(); + }; // end of effects group @@ -257,4 +259,4 @@ private: NS_CC_EXT_END -#endif \ No newline at end of file +#endif diff --git a/extensions/CCBReader/CCBSelectorResolver.h b/extensions/CCBReader/CCBSelectorResolver.h index 3ec7737e75..97d5c5df5b 100644 --- a/extensions/CCBReader/CCBSelectorResolver.h +++ b/extensions/CCBReader/CCBSelectorResolver.h @@ -3,6 +3,7 @@ #include "cocos2d.h" #include "ExtensionMacros.h" +#include "../GUI/CCControlExtension/CCInvocation.h" USING_NS_CC; NS_CC_EXT_BEGIN @@ -18,11 +19,18 @@ NS_CC_EXT_BEGIN class CCBSelectorResolver { public: virtual ~CCBSelectorResolver() {}; - - virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName) = 0; + virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName) = 0; + virtual cocos2d::extension::SEL_CCControlHandler onResolveCCBCCControlSelector(CCObject * pTarget, CCString * pSelectorName) = 0; }; + +class CCBScriptOwnerProtocol { +public: + virtual ~CCBScriptOwnerProtocol() {}; + virtual CCBSelectorResolver * createNew() = 0; +}; + NS_CC_EXT_END #endif diff --git a/extensions/CCBReader/CCNodeLoader.cpp b/extensions/CCBReader/CCNodeLoader.cpp index 7f092916f0..a482a867ad 100644 --- a/extensions/CCBReader/CCNodeLoader.cpp +++ b/extensions/CCBReader/CCNodeLoader.cpp @@ -686,6 +686,17 @@ BlockData * CCNodeLoader::parsePropTypeBlock(CCNode * pNode, CCNode * pParent, C target = pCCBReader->getAnimationManager()->getRootNode(); } else if(selectorTarget == kCCBTargetTypeOwner) { target = pCCBReader->getOwner(); + + /* Scripting specific code because selector function is common for all callbacks. + * So if we had 1 target and 1 selector function, the context (callback function name) + * would get lost. Hence the need for a new target for each callback. + */ + if(pCCBReader->hasScriptingOwner) { + CCBScriptOwnerProtocol *proxy = dynamic_cast(pCCBReader->getOwner()); + if(proxy) { + target = dynamic_cast(proxy->createNew()); + } + } } if(target != NULL) { From 57680ec2d61c62472ee3dfc16ddb4721ce754ee3 Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Tue, 18 Sep 2012 18:19:28 -0700 Subject: [PATCH 2/9] Adding CCBuilderReader JS bindings --- .../bindings/js_bindings_ccbreader.cpp | 148 ++++++++++++++++++ .../bindings/js_bindings_ccbreader.h | 62 ++++++++ 2 files changed, 210 insertions(+) create mode 100644 scripting/javascript/bindings/js_bindings_ccbreader.cpp create mode 100644 scripting/javascript/bindings/js_bindings_ccbreader.h diff --git a/scripting/javascript/bindings/js_bindings_ccbreader.cpp b/scripting/javascript/bindings/js_bindings_ccbreader.cpp new file mode 100644 index 0000000000..0e4ae90323 --- /dev/null +++ b/scripting/javascript/bindings/js_bindings_ccbreader.cpp @@ -0,0 +1,148 @@ +// +// js_bindings_ccbreader.cpp +// watermelon +// +// Created by Rohan Kuruvilla on 14/08/2012. +// +// + +#include "js_bindings_ccbreader.h" +#include "ScriptingCore.h" +#include "CCNodeLoaderLibrary.h" + +USING_NS_CC; +USING_NS_CC_EXT; + + +SEL_MenuHandler CCBScriptCallbackProxy::onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, + cocos2d::CCString * pSelectorName) { + this->callBackProp = pSelectorName->getCString(); + return menu_selector(CCBScriptCallbackProxy::menuItemCallback); +} + +SEL_CCControlHandler CCBScriptCallbackProxy::onResolveCCBCCControlSelector(CCObject * pTarget, + CCString * pSelectorName) { + + this->callBackProp = pSelectorName->getCString(); + return cccontrol_selector(CCBScriptCallbackProxy::controlCallback); +} + +bool CCBScriptCallbackProxy::onAssignCCBMemberVariable(CCObject * pTarget, + CCString * pMemberVariableName, + CCNode * pNode) { +} + +void CCBScriptCallbackProxy::onNodeLoaded(CCNode * pNode, + CCNodeLoader * pNodeLoader) {} + +CCBSelectorResolver * CCBScriptCallbackProxy::createNew() { + CCBScriptCallbackProxy * ret = new CCBScriptCallbackProxy(); + ret->setJSOwner(this->owner); + return dynamic_cast(ret); +} + +void CCBScriptCallbackProxy::menuItemCallback(CCObject *pSender) { + ScriptingCore::getInstance()->executeFunctionWithOwner(owner, callBackProp.c_str() , JSVAL_NULL); +} + +void CCBScriptCallbackProxy::controlCallback(CCObject *pSender, CCControlEvent event) { + ScriptingCore::getInstance()->executeFunctionWithOwner(owner, callBackProp.c_str() , JSVAL_NULL); +} + +void CCBScriptCallbackProxy::setCallbackProperty(const char *prop) { + callBackProp = prop; +} + +void CCBScriptCallbackProxy::setJSOwner(jsval ownr) { + owner = ownr; +} + +jsval CCBScriptCallbackProxy::getJSOwner() { + return owner; +} + + +static CCNode* loadReader(const char *file, jsval owner) { + /* Create an autorelease CCNodeLoaderLibrary. */ + + /* Create an autorelease CCBReader. */ + CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); + + ccNodeLoaderLibrary->registerCCNodeLoader("", JSLayerLoader::loader()); + + cocos2d::extension::CCBReader * ccbReader = new cocos2d::extension::CCBReader(ccNodeLoaderLibrary); + ccbReader->autorelease(); + + /* Read a ccbi file. */ + ccbReader->hasScriptingOwner = true; + + CCBScriptCallbackProxy *ccBCallbackProxy = new CCBScriptCallbackProxy(); + ccBCallbackProxy->setJSOwner(owner); + //ccbReader->setOwner(dynamic_cast(ccBCallbackProxy)); + + CCBSelectorResolver * targetAsCCBSelectorResolver = dynamic_cast(ccBCallbackProxy); + if(targetAsCCBSelectorResolver != NULL) { + js_log("NOT NULL"); + } + + CCNode * node = ccbReader->readNodeGraphFromFile("./", file, dynamic_cast(ccBCallbackProxy)); + + return node; +} + + +JSBool js_CocosBuilder_Run(JSContext *cx, uint32_t argc, jsval *vp) +{ + if (argc >= 1) { + jsval *argv = JS_ARGV(cx, vp); + const char *arg0; + do { + JSString *tmp = JS_ValueToString(cx, argv[0]); + arg0 = JS_EncodeString(cx, tmp); + } + while (0); + + jsval obj = argc >= 2 ? argv[1] : JSVAL_NULL; + js_log("%s: + ", JSVAL_TO_OBJECT(obj)); + CCNode * ret = loadReader(arg0, obj); + jsval jsret; + if (ret) { + js_proxy_t *proxy; + JS_GET_PROXY(proxy, ret); + if (proxy) { + jsret = OBJECT_TO_JSVAL(proxy->obj); + } else { + // create a new js obj of that class + proxy = js_get_or_create_proxy(cx, ret); + jsret = OBJECT_TO_JSVAL(proxy->obj); + } + } else { + jsret = JSVAL_NULL; + } + JS_SET_RVAL(cx, vp, jsret); + return JS_TRUE; + + } + return JS_FALSE; +} + + +void register_CCBuilderReader(JSContext *cx, JSObject *obj) { + + + jsval nsval; + JSObject *ns; + JS_GetProperty(cx, obj, "cc", &nsval); + if (nsval == JSVAL_VOID) { + ns = JS_NewObject(cx, NULL, NULL, NULL); + nsval = OBJECT_TO_JSVAL(ns); + JS_SetProperty(cx, obj, "cc", &nsval); + } else { + JS_ValueToObject(cx, nsval, &ns); + } + obj = ns; + + JSObject *tmpObj = JSVAL_TO_OBJECT(anonEvaluate(cx, obj, "(function () { cc = cc || {}; cc.Reader = cc.Reader || {}; return cc.Reader; })()")); + JS_DefineFunction(cx, tmpObj, "load", js_CocosBuilder_Run, 2, JSPROP_READONLY | JSPROP_PERMANENT) ; + +} diff --git a/scripting/javascript/bindings/js_bindings_ccbreader.h b/scripting/javascript/bindings/js_bindings_ccbreader.h new file mode 100644 index 0000000000..2ddc9f60c0 --- /dev/null +++ b/scripting/javascript/bindings/js_bindings_ccbreader.h @@ -0,0 +1,62 @@ +// +// js_bindings_ccbreader.h +// watermelon +// +// Created by Rohan Kuruvilla on 14/08/2012. +// +// +#include "jsapi.h" +#include "CCBReader.h" +#include "CCBSelectorResolver.h" +#include "CCBMemberVariableAssigner.h" +#include "CCInvocation.h" +#include "ExtensionMacros.h" +#include "CCLayerLoader.h" + +#include "cocos2d_specifics.hpp" + + +class CCBScriptCallbackProxy: public cocos2d::CCLayer +, public cocos2d::extension::CCBScriptOwnerProtocol +, public cocos2d::extension::CCBSelectorResolver +, public cocos2d::extension::CCBMemberVariableAssigner { + + std::string callBackProp; + jsval owner; + +public: + + + CCBScriptCallbackProxy () {} + virtual ~CCBScriptCallbackProxy() {} + + CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(CCBScriptCallbackProxy, create); + virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, + cocos2d::CCString * pSelectorName); + + virtual cocos2d::extension::SEL_CCControlHandler onResolveCCBCCControlSelector(cocos2d::CCObject * pTarget, + cocos2d::CCString * pSelectorName); + virtual bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, cocos2d::CCString * pMemberVariableName, + cocos2d::CCNode * pNode); + virtual void onNodeLoaded(cocos2d::CCNode * pNode, + cocos2d::extension::CCNodeLoader * pNodeLoader); + + virtual CCBSelectorResolver * createNew(); + void menuItemCallback(CCObject *pSender); + void controlCallback(CCObject *pSender, cocos2d::extension::CCControlEvent event); + void setCallbackProperty(const char *prop); + void setJSOwner(jsval ownr); + jsval getJSOwner(); +}; + + +class JSLayerLoader : public cocos2d::extension::CCLayerLoader { +public: + CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(JSLayerLoader, loader); + +protected: + CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(CCBScriptCallbackProxy); +}; + +void register_CCBuilderReader(JSContext *cx, JSObject *global); +JSBool js_CocosBuilder_Run(JSContext *cx, uint32_t argc, jsval *vp); From dde8d50d1576c90f6162bbf17483b05f8160c34c Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Tue, 18 Sep 2012 18:21:07 -0700 Subject: [PATCH 3/9] Adding member function executeFunctionWithOwner to ScriptingCore --- scripting/javascript/bindings/ScriptingCore.cpp | 8 ++++++++ scripting/javascript/bindings/ScriptingCore.h | 1 + 2 files changed, 9 insertions(+) diff --git a/scripting/javascript/bindings/ScriptingCore.cpp b/scripting/javascript/bindings/ScriptingCore.cpp index d516ba38bd..3cc51f897b 100644 --- a/scripting/javascript/bindings/ScriptingCore.cpp +++ b/scripting/javascript/bindings/ScriptingCore.cpp @@ -565,6 +565,14 @@ int ScriptingCore::executeFunctionWithObjectData(CCNode *self, const char *name, return 1; } +int ScriptingCore::executeFunctionWithOwner(jsval owner, const char *name, jsval data) { + jsval retval; + + executeJSFunctionWithName(this->cx, JSVAL_TO_OBJECT(owner), name, data, retval); + + return 1; +} + int ScriptingCore::executeCustomTouchesEvent(int eventType, CCSet *pTouches, JSObject *obj) { diff --git a/scripting/javascript/bindings/ScriptingCore.h b/scripting/javascript/bindings/ScriptingCore.h index 3597796854..3a5464ac37 100644 --- a/scripting/javascript/bindings/ScriptingCore.h +++ b/scripting/javascript/bindings/ScriptingCore.h @@ -81,6 +81,7 @@ public: virtual int executeLayerTouchEvent(CCLayer* pLayer, int eventType, CCTouch *pTouch); int executeFunctionWithObjectData(CCNode *self, const char *name, JSObject *obj); + int executeFunctionWithOwner(jsval owner, const char *name, jsval data); void executeJSFunctionWithThisObj(jsval thisObj, jsval callback, jsval data); From d1493a862f27348d0d8f3c6d700bfdb5128ed0b7 Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Tue, 18 Sep 2012 18:33:34 -0700 Subject: [PATCH 4/9] Updating template to support CCBuilderReader --- template/xcode4/cocos2dx_js.xctemplate/Classes/AppDelegate.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/template/xcode4/cocos2dx_js.xctemplate/Classes/AppDelegate.cpp b/template/xcode4/cocos2dx_js.xctemplate/Classes/AppDelegate.cpp index 2a4f303e40..c0b3a774af 100644 --- a/template/xcode4/cocos2dx_js.xctemplate/Classes/AppDelegate.cpp +++ b/template/xcode4/cocos2dx_js.xctemplate/Classes/AppDelegate.cpp @@ -8,6 +8,7 @@ #include "cocos2d_specifics.hpp" #include "js_bindings_chipmunk_manual.hpp" #include "js_bindings_chipmunk_functions.hpp" +#include "js_bindings_ccbreader.h" USING_NS_CC; using namespace CocosDenshion; @@ -43,6 +44,7 @@ bool AppDelegate::applicationDidFinishLaunching() sc->addRegisterCallback(register_cocos2dx_js_extensions); sc->addRegisterCallback(register_chipmunk_manual); sc->addRegisterCallback(register_CCPhysicsSprite); + sc->addRegisterCallback(register_CCBuilderReader); From 9e1e64509bfd77178cf8d828d9b48d015b6b691c Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Tue, 18 Sep 2012 18:44:21 -0700 Subject: [PATCH 5/9] Copying changes previously made into cxx-generator/targets/spidermonkey/common 1. Fixed memory leak while removing proxy objects 2. Fixed JS Context restart 3. Added JS conversion for CCArray 4. Updated generated bindings with some more classes --- .../javascript/bindings/ScriptingCore.cpp | 34 +++++++++++++++++-- scripting/javascript/bindings/ScriptingCore.h | 3 ++ .../javascript/bindings/cocos2d_specifics.cpp | 2 ++ .../bindings/spidermonkey_specifics.h | 4 +-- tools/tojs/cocos2dx.ini | 5 ++- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/scripting/javascript/bindings/ScriptingCore.cpp b/scripting/javascript/bindings/ScriptingCore.cpp index 3cc51f897b..dc4019e376 100644 --- a/scripting/javascript/bindings/ScriptingCore.cpp +++ b/scripting/javascript/bindings/ScriptingCore.cpp @@ -14,6 +14,7 @@ #include #include "ScriptingCore.h" #include "cocos2d.h" +#include "cocos2d_specifics.hpp" #ifdef ANDROID #include @@ -275,8 +276,19 @@ void ScriptingCore::addRegisterCallback(sc_register_sth callback) { registrationList.push_back(callback); } +void ScriptingCore::removeAllRoots(JSContext *cx) { + js_proxy_t *current, *tmp; + HASH_ITER(hh, _js_native_global_ht, current, tmp) { + JS_RemoveObjectRoot(cx, ¤t->obj); + } + HASH_CLEAR(hh, _js_native_global_ht); + HASH_CLEAR(hh, _native_js_global_ht); + HASH_CLEAR(hh, _js_global_type_ht); +} + void ScriptingCore::createGlobalContext() { - if (this->cx && this->rt) { + if (this->cx && this->rt) { + ScriptingCore::removeAllRoots(this->cx); JS_DestroyContext(this->cx); JS_DestroyRuntime(this->rt); this->cx = NULL; @@ -368,8 +380,8 @@ void ScriptingCore::removeScriptObjectByCCObject(CCObject* pObj) JS_GET_PROXY(nproxy, ptr); if (nproxy) { JSContext *cx = ScriptingCore::getInstance()->getGlobalContext(); - JS_RemoveObjectRoot(cx, &nproxy->obj); JS_GET_NATIVE_PROXY(jsproxy, nproxy->obj); + JS_RemoveObjectRoot(cx, &jsproxy->obj); JS_REMOVE_PROXY(nproxy, jsproxy); } } @@ -784,7 +796,23 @@ CCArray* jsval_to_ccarray(JSContext* cx, jsval v) { return NULL; } -// from native + +jsval ccarray_to_jsval(JSContext* cx, CCArray *arr) { + + JSObject *jsretArr = JS_NewArrayObject(cx, 0, NULL); + + for(int i = 0; i < arr->count(); ++i) { + + CCObject *obj = arr->objectAtIndex(i); + js_proxy_t *proxy = js_get_or_create_proxy(cx, obj); + jsval arrElement = OBJECT_TO_JSVAL(proxy->obj); + + if(!JS_SetElement(cx, jsretArr, i, &arrElement)) { + break; + } + } + return OBJECT_TO_JSVAL(jsretArr); +} jsval long_long_to_jsval(JSContext* cx, long long v) { JSObject *tmp = JS_NewUint32Array(cx, 2); diff --git a/scripting/javascript/bindings/ScriptingCore.h b/scripting/javascript/bindings/ScriptingCore.h index 3a5464ac37..b3cc01dfe3 100644 --- a/scripting/javascript/bindings/ScriptingCore.h +++ b/scripting/javascript/bindings/ScriptingCore.h @@ -115,6 +115,8 @@ public: * and create a new one. */ void createGlobalContext(); + + static void removeAllRoots(JSContext *cx); int executeCustomTouchEvent(int eventType, @@ -181,6 +183,7 @@ ccColor4B jsval_to_cccolor4b(JSContext *cx, jsval v); ccColor4F jsval_to_cccolor4f(JSContext *cx, jsval v); ccColor3B jsval_to_cccolor3b(JSContext *cx, jsval v); CCArray* jsval_to_ccarray(JSContext* cx, jsval v); +jsval ccarray_to_jsval(JSContext* cx, CCArray *arr); // from native jsval long_long_to_jsval(JSContext* cx, long long v); jsval std_string_to_jsval(JSContext* cx, std::string& v); diff --git a/scripting/javascript/bindings/cocos2d_specifics.cpp b/scripting/javascript/bindings/cocos2d_specifics.cpp index 70a0e1f0d2..f3b4151b38 100644 --- a/scripting/javascript/bindings/cocos2d_specifics.cpp +++ b/scripting/javascript/bindings/cocos2d_specifics.cpp @@ -451,6 +451,8 @@ JSBool js_cocos2dx_swap_native_object(JSContext *cx, uint32_t argc, jsval *vp) js_proxy_t *jsproxy; JS_GET_PROXY(jsproxy, ptrTwo); if (jsproxy) { + JS_RemoveObjectRoot(cx, &nproxy->obj); + JS_REMOVE_PROXY(jsproxy, nproxy); JS_NEW_PROXY(nproxy, ptrTwo, one); } diff --git a/scripting/javascript/bindings/spidermonkey_specifics.h b/scripting/javascript/bindings/spidermonkey_specifics.h index d482c56e01..a166b15356 100644 --- a/scripting/javascript/bindings/spidermonkey_specifics.h +++ b/scripting/javascript/bindings/spidermonkey_specifics.h @@ -77,8 +77,8 @@ do { \ #define JS_REMOVE_PROXY(nproxy, jsproxy) \ do { \ - if (nproxy) HASH_DEL(_native_js_global_ht, nproxy); \ - if (jsproxy) HASH_DEL(_js_native_global_ht, jsproxy); \ + if (nproxy) { HASH_DEL(_native_js_global_ht, nproxy); free(nproxy); } \ + if (jsproxy) { HASH_DEL(_js_native_global_ht, jsproxy); free(jsproxy); } \ } while (0) #define TEST_NATIVE_OBJECT(cx, native_obj) \ diff --git a/tools/tojs/cocos2dx.ini b/tools/tojs/cocos2dx.ini index 8962a0e55f..e06a960fe8 100644 --- a/tools/tojs/cocos2dx.ini +++ b/tools/tojs/cocos2dx.ini @@ -27,7 +27,8 @@ headers = %(cocosdir)s/cocos2dx/include/cocos2d.h # what classes to produce code for. You can use regular expressions here. When testing the regular # expression, it will be enclosed in "^$", like this: "^CCMenu*$". -classes = CCSprite.* CCScene CCNode CCDirector CCLayer.* CCMenu.* CCTouch CC.*Action.* CCMove.* CCRotate.* CCBlink.* CCTint.* CCSequence CCRepeat.* CCFade.* CCEase.* CCScale.* CCTransition.* CCSpawn CCSequence CCAnimat.* CCFlip.* CCDelay.* CCSkew.* CCJump.* CCPlace.* CCShow.* CCProgress.* CCToggleVisibility.* CCHide CCParticle.* CCLabel.* CCAtlas.* CCTextureCache.* CCTexture2D CCParallaxNode CCTileMap.* CCTMX.* CCCallFunc CCRenderTexture CCGridAction CCGrid3DAction CCShaky3D CCWaves3D CCFlipX3D CCFlipY3D CCSpeed CCSet + +classes = CCSprite.* CCScene CCNode CCDirector CCLayer.* CCMenu.* CCTouch CC.*Action.* CCMove.* CCRotate.* CCBlink.* CCTint.* CCSequence CCRepeat.* CCFade.* CCEase.* CCScale.* CCTransition.* CCSpawn CCSequence CCAnimat.* CCFlip.* CCDelay.* CCSkew.* CCJump.* CCPlace.* CCShow.* CCProgress.* CCToggleVisibility.* CCHide CCParticle.* CCLabel.* CCAtlas.* CCTextureCache.* CCTexture2D CCParallaxNode CCTileMap.* CCTMX.* CCCallFunc CCRenderTexture CCGridAction CCGrid3DAction CCShaky3D CCWaves3D CCFlipX3D CCFlipY3D CCSpeed CCSet CCObject # what should we skip? in the format ClassName::[function function] # ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also @@ -42,7 +43,6 @@ skip = CCNode::[.*Transform convertToWindowSpace getChildren getGrid setGLServer CCMenu.*::[.*Target getSubItems create alignItemsInColumns initWithItems alignItemsInRows], CCMenuItem.*::[create], CCRGBAProtocol::[*], - CCObject::[*], CCCopying::[*], CC.*Protocol::[*], CC.*Delegate::[*], @@ -79,7 +79,6 @@ skip = CCNode::[.*Transform convertToWindowSpace getChildren getGrid setGLServer CCGrid3DAction::[create actionWith.*], CCTiledGrid3DAction::[create actionWith.*], CCTMXMapInfo::[startElement endElement textHandler], - CCTMXObjectGroup::[getObjects], CCTexture2D::[initWithPVRTCData addPVRTCImage], CCLayerMultiplex::[*], CCTextureCache::[addPVRTCImage], From d097406f18e82718076eb25c39c16ce2a1ed1bc8 Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Tue, 18 Sep 2012 18:56:54 -0700 Subject: [PATCH 6/9] Modifying MenuItemToggle bindings to make it work --- .../javascript/bindings/cocos2d_specifics.cpp | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/scripting/javascript/bindings/cocos2d_specifics.cpp b/scripting/javascript/bindings/cocos2d_specifics.cpp index f3b4151b38..db3e0ec738 100644 --- a/scripting/javascript/bindings/cocos2d_specifics.cpp +++ b/scripting/javascript/bindings/cocos2d_specifics.cpp @@ -326,27 +326,45 @@ JSBool js_cocos2dx_CCMenuItemFont_create(JSContext *cx, uint32_t argc, jsval *vp return JS_FALSE; } + JSBool js_cocos2dx_CCMenuItemToggle_create(JSContext *cx, uint32_t argc, jsval *vp) { - if (argc >= 1) { - jsval *argv = JS_ARGV(cx, vp); - cocos2d::CCMenuItemToggle* ret = cocos2d::CCMenuItemToggle::create(); - JSObject *obj = bind_menu_item(cx, ret, (argc == 2 ? argv[1] : JSVAL_VOID), argv[0]); - for (int i=1; i < argc; i++) { - js_proxy_t *proxy; - JSObject *tmpObj = JSVAL_TO_OBJECT(argv[i]); - JS_GET_NATIVE_PROXY(proxy, tmpObj); - cocos2d::CCMenuItem* item = (cocos2d::CCMenuItem*)(proxy ? proxy->ptr : NULL); - TEST_NATIVE_OBJECT(cx, item) - ret->addSubItem(item); - } - JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); - return JS_TRUE; - } - return JS_FALSE; + if (argc >= 1) { + jsval *argv = JS_ARGV(cx, vp); + cocos2d::CCMenuItemToggle* ret = cocos2d::CCMenuItemToggle::create(); + + + for (int i=0; i < argc; i++) { + js_proxy_t *proxy; + JSObject *tmpObj = JSVAL_TO_OBJECT(argv[i]); + JS_GET_NATIVE_PROXY(proxy, tmpObj); + cocos2d::CCMenuItem* item = (cocos2d::CCMenuItem*)(proxy ? proxy->ptr : NULL); + TEST_NATIVE_OBJECT(cx, item) + if(i == 0) ret->initWithItem(item); + else ret->addSubItem(item); + } + + jsval jsret; + if (ret) { + js_proxy_t *proxy; + JS_GET_PROXY(proxy, ret); + if (proxy) { + jsret = OBJECT_TO_JSVAL(proxy->obj); + } else { + // create a new js obj of that class + proxy = js_get_or_create_proxy(cx, ret); + jsret = OBJECT_TO_JSVAL(proxy->obj); + } + } else { + jsret = JSVAL_NULL; + } + + JS_SET_RVAL(cx, vp, jsret); + return JS_TRUE; + } + return JS_FALSE; } - JSBool js_cocos2dx_setCallback(JSContext *cx, uint32_t argc, jsval *vp) { if(argc == 2) { From 423bdf3f5a37d13fa67ef70bad75d4c3b069d4fa Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Thu, 20 Sep 2012 17:24:18 -0700 Subject: [PATCH 7/9] Adding createWithTotalParticles static function to CCParticleSystemQuad --- cocos2dx/particle_nodes/CCParticleSystemQuad.cpp | 12 ++++++++++++ cocos2dx/particle_nodes/CCParticleSystemQuad.h | 1 + 2 files changed, 13 insertions(+) diff --git a/cocos2dx/particle_nodes/CCParticleSystemQuad.cpp b/cocos2dx/particle_nodes/CCParticleSystemQuad.cpp index 35fe1f0e02..8619371b8f 100644 --- a/cocos2dx/particle_nodes/CCParticleSystemQuad.cpp +++ b/cocos2dx/particle_nodes/CCParticleSystemQuad.cpp @@ -120,6 +120,18 @@ CCParticleSystemQuad * CCParticleSystemQuad::create(const char *plistFile) return pRet; } +CCParticleSystemQuad * CCParticleSystemQuad::createWithTotalParticles(unsigned int numberOfParticles) { + CCParticleSystemQuad *pRet = new CCParticleSystemQuad(); + if (pRet && pRet->initWithTotalParticles(numberOfParticles)) + { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return pRet; +} + + // pointRect should be in Texture coordinates, not pixel coordinates void CCParticleSystemQuad::initTexCoordsWithRect(const CCRect& pointRect) { diff --git a/cocos2dx/particle_nodes/CCParticleSystemQuad.h b/cocos2dx/particle_nodes/CCParticleSystemQuad.h index 10822f4a24..e546bffdf1 100644 --- a/cocos2dx/particle_nodes/CCParticleSystemQuad.h +++ b/cocos2dx/particle_nodes/CCParticleSystemQuad.h @@ -110,6 +110,7 @@ public: CC_DEPRECATED_ATTRIBUTE static CCParticleSystemQuad * node(); static CCParticleSystemQuad * create(); + static CCParticleSystemQuad * createWithTotalParticles(unsigned int numberOfParticles); private: #if CC_TEXTURE_ATLAS_USE_VAO void setupVBOandVAO(); From bc35e7317990d2e26c018ca081df0a14cbdd6d6e Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Thu, 20 Sep 2012 14:49:14 -0700 Subject: [PATCH 8/9] Updating cocos2dx.ini including, 1. Adding key "rename_classes" 2. Renaming key "rename" to "rename_functions" 3. Adding CCParticleSystemQuad specific stuff --- tools/tojs/cocos2dx.ini | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/tojs/cocos2dx.ini b/tools/tojs/cocos2dx.ini index e06a960fe8..fe721313d6 100644 --- a/tools/tojs/cocos2dx.ini +++ b/tools/tojs/cocos2dx.ini @@ -79,18 +79,21 @@ skip = CCNode::[.*Transform convertToWindowSpace getChildren getGrid setGLServer CCGrid3DAction::[create actionWith.*], CCTiledGrid3DAction::[create actionWith.*], CCTMXMapInfo::[startElement endElement textHandler], + CCParticleSystemQuad::[postStep setBatchNode draw setTexture$ setTotalParticles updateQuadWithParticle setupIndices listenBackToForeground initWithTotalParticles particleWithFile node], CCTexture2D::[initWithPVRTCData addPVRTCImage], CCLayerMultiplex::[*], CCTextureCache::[addPVRTCImage], *::[copyWith.* onEnter.* onExit.* description getObjectType .*RGB.* .*HSV.*] -rename = CCDirector::[sharedDirector=getInstance], +rename_functions = CCDirector::[sharedDirector=getInstance], CCSpriteFrameCache::[sharedSpriteFrameCache=getInstance addSpriteFramesWithFile=addSpriteFrames], CCMenuItemFont::[setFontNameObj=setFontName setFontSizeObj=setFontSize fontSizeObj=fontSize fontNameObj=fontName], CCProgressTimer::[setReverseProgress=setReverseDirection], CCTextureCache::[sharedTextureCache=getInstance], CCMenuItem::[setEnabled=setIsEnabled] +rename_classes = CCParticleSystemQuad::CCParticleSystem + # for all class names, should we remove something when registering in the target VM? remove_prefix = CC From 100a7a18838c2f78ecde470747644105876208cd Mon Sep 17 00:00:00 2001 From: Rohan Kuruvilla Date: Thu, 20 Sep 2012 17:46:29 -0700 Subject: [PATCH 9/9] Adding sample game wrapper using CCBReader. Also includes small modification to CCBReader --- extensions/CCBReader/CCData.h | 2 +- .../bindings/js_bindings_ccbreader.cpp | 16 +- .../CCB/Abadi40-hd.png.REMOVED.git-id | 1 + .../CCB/Abadi40-ipad.png.REMOVED.git-id | 1 + .../Resources/CCB/Abadi40.png.REMOVED.git-id | 1 + .../Resources/CCB/Gas40-hd.png.REMOVED.git-id | 1 + .../CCB/Gas40-ipad.png.REMOVED.git-id | 1 + .../CCB/konqa32-hd.png.REMOVED.git-id | 1 + .../CCB/konqa32-ipad.png.REMOVED.git-id | 1 + .../Resources/CCB/konqa32.png.REMOVED.git-id | 1 + .../cocos2dx_js.xctemplate/Resources/hello.js | 146 ++++++++++++++++-- 11 files changed, 153 insertions(+), 19 deletions(-) create mode 100644 template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40-hd.png.REMOVED.git-id create mode 100644 template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40-ipad.png.REMOVED.git-id create mode 100644 template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40.png.REMOVED.git-id create mode 100644 template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Gas40-hd.png.REMOVED.git-id create mode 100644 template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Gas40-ipad.png.REMOVED.git-id create mode 100644 template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32-hd.png.REMOVED.git-id create mode 100644 template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32-ipad.png.REMOVED.git-id create mode 100644 template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32.png.REMOVED.git-id diff --git a/extensions/CCBReader/CCData.h b/extensions/CCBReader/CCData.h index 68814ca7be..127b6a69c0 100644 --- a/extensions/CCBReader/CCData.h +++ b/extensions/CCBReader/CCData.h @@ -3,7 +3,7 @@ #define __CCB_CCDATA_H__ #include "cocos2d.h" -#include "cocos-ext.h" +#include "ExtensionMacros.h"" NS_CC_EXT_BEGIN diff --git a/scripting/javascript/bindings/js_bindings_ccbreader.cpp b/scripting/javascript/bindings/js_bindings_ccbreader.cpp index 0e4ae90323..50e7e98a35 100644 --- a/scripting/javascript/bindings/js_bindings_ccbreader.cpp +++ b/scripting/javascript/bindings/js_bindings_ccbreader.cpp @@ -13,10 +13,19 @@ USING_NS_CC; USING_NS_CC_EXT; +static void removeSelector(std::string &str) { + size_t found; + found = str.find(":"); + while (found!=std::string::npos){ + str.replace(found, found+1, ""); + found = str.find(":"); + } +} SEL_MenuHandler CCBScriptCallbackProxy::onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName) { this->callBackProp = pSelectorName->getCString(); + removeSelector(this->callBackProp); return menu_selector(CCBScriptCallbackProxy::menuItemCallback); } @@ -24,12 +33,14 @@ SEL_CCControlHandler CCBScriptCallbackProxy::onResolveCCBCCControlSelector(CCObj CCString * pSelectorName) { this->callBackProp = pSelectorName->getCString(); + removeSelector(this->callBackProp); return cccontrol_selector(CCBScriptCallbackProxy::controlCallback); } bool CCBScriptCallbackProxy::onAssignCCBMemberVariable(CCObject * pTarget, CCString * pMemberVariableName, CCNode * pNode) { + return true; } void CCBScriptCallbackProxy::onNodeLoaded(CCNode * pNode, @@ -81,11 +92,8 @@ static CCNode* loadReader(const char *file, jsval owner) { //ccbReader->setOwner(dynamic_cast(ccBCallbackProxy)); CCBSelectorResolver * targetAsCCBSelectorResolver = dynamic_cast(ccBCallbackProxy); - if(targetAsCCBSelectorResolver != NULL) { - js_log("NOT NULL"); - } - CCNode * node = ccbReader->readNodeGraphFromFile("./", file, dynamic_cast(ccBCallbackProxy)); + CCNode * node = ccbReader->readNodeGraphFromFile(file, dynamic_cast(ccBCallbackProxy)); return node; } diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40-hd.png.REMOVED.git-id b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40-hd.png.REMOVED.git-id new file mode 100644 index 0000000000..18b9c22de9 --- /dev/null +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40-hd.png.REMOVED.git-id @@ -0,0 +1 @@ +f06c047dd32b61f12ad51e981afe518364512be6 \ No newline at end of file diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40-ipad.png.REMOVED.git-id b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40-ipad.png.REMOVED.git-id new file mode 100644 index 0000000000..717ceb89a1 --- /dev/null +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40-ipad.png.REMOVED.git-id @@ -0,0 +1 @@ +4b7c1e97acefff48ae3652f023e708245992f553 \ No newline at end of file diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40.png.REMOVED.git-id b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40.png.REMOVED.git-id new file mode 100644 index 0000000000..fb1884455b --- /dev/null +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Abadi40.png.REMOVED.git-id @@ -0,0 +1 @@ +ae62d7b07ac3e7579ed7d6a2e1f903719e45c6d9 \ No newline at end of file diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Gas40-hd.png.REMOVED.git-id b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Gas40-hd.png.REMOVED.git-id new file mode 100644 index 0000000000..5067e00b74 --- /dev/null +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Gas40-hd.png.REMOVED.git-id @@ -0,0 +1 @@ +12db20c3124e1bd864312257eb8cefe95d2ee349 \ No newline at end of file diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Gas40-ipad.png.REMOVED.git-id b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Gas40-ipad.png.REMOVED.git-id new file mode 100644 index 0000000000..8ddebffce2 --- /dev/null +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/Gas40-ipad.png.REMOVED.git-id @@ -0,0 +1 @@ +e71140c1535f16b49980f3ea0cf7d3a29a8a9788 \ No newline at end of file diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32-hd.png.REMOVED.git-id b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32-hd.png.REMOVED.git-id new file mode 100644 index 0000000000..15f23ffc85 --- /dev/null +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32-hd.png.REMOVED.git-id @@ -0,0 +1 @@ +dc235c169030151e337ecbfa1fc6302fc909e500 \ No newline at end of file diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32-ipad.png.REMOVED.git-id b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32-ipad.png.REMOVED.git-id new file mode 100644 index 0000000000..2549ab6362 --- /dev/null +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32-ipad.png.REMOVED.git-id @@ -0,0 +1 @@ +9e95a02e6eb2944fea12a49eb3f2c6fe7505a3ce \ No newline at end of file diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32.png.REMOVED.git-id b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32.png.REMOVED.git-id new file mode 100644 index 0000000000..83954562c0 --- /dev/null +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/CCB/konqa32.png.REMOVED.git-id @@ -0,0 +1 @@ +1423c81273926b3da9fb1cb36c9b710d3f14ee0e \ No newline at end of file diff --git a/template/xcode4/cocos2dx_js.xctemplate/Resources/hello.js b/template/xcode4/cocos2dx_js.xctemplate/Resources/hello.js index 3e737b8ca6..0d77bcec6d 100644 --- a/template/xcode4/cocos2dx_js.xctemplate/Resources/hello.js +++ b/template/xcode4/cocos2dx_js.xctemplate/Resources/hello.js @@ -1,5 +1,6 @@ + try { - + cc.p = cc.p || function( x, y ) { return {x:x, y:y}; }; @@ -7,23 +8,140 @@ try { cc.c4b = cc.c4 || function (r, g, b, o) { return {r: r, g: g, b: b, a: o}; }; + + + cc.c3 = cc.c3 || function (r, g, b) { + return {r: r, g: g, b: b}; + }; + cc.BLACK = cc.c3(0,0,0); + director = cc.Director.getInstance(); winSize = director.getWinSize(); + centerPos = cc.p( winSize.width/2, winSize.height/2 ); - var scene = new cc.Scene(); - var layer = new cc.LayerGradient(); + var GameCreator = function() { + + var self = {}; + self.callbacks = {}; + + self.getPlayScene = function() { + + var scene = new cc.Scene(); + var layer = new cc.LayerGradient(); + + layer.init(cc.c4b(0, 0, 0, 255), cc.c4b(0, 128, 255, 255)); + + var lab = "Houston we have liftoff!"; + var label = cc.LabelTTF.create(lab, "Arial", 28); + layer.addChild(label, 1); + label.setPosition( cc.p(winSize.width / 2, winSize.height / 2)); + + var back = cc.MenuItemFont.create("Back", this.callbacks, this.callbacks.onBack ); + back.setColor( cc.BLACK ); + + var menu = cc.Menu.create( back ); + layer.addChild( menu ); + menu.alignItemsVertically(); + menu.setPosition( cc.p( winSize.width - 50, 50) ); + + scene.addChild(layer); + + return scene; + }; + + self.getMainMenuScene = function() { + var l = cc.Layer.create(); + var scene = cc.Scene.create(); + + var node = cc.Reader.load("MainMenu.ccbi", this, winSize); + l.addChild(node); + + scene.addChild(l); + + return scene; + }; + + self.getOptionsScene = function() { + + var l = cc.LayerGradient.create(); + l.init(cc.c4b(0, 0, 0, 255), cc.c4b(255, 255, 255, 255)); + + var scene = cc.Scene.create(); + + var label1 = cc.LabelBMFont.create("MUSIC ON", "konqa32.fnt" ); + var item1 = cc.MenuItemLabel.create(label1); + var label2 = cc.LabelBMFont.create("MUSIC OFF", "konqa32.fnt" ); + var item2 = cc.MenuItemLabel.create(label2); + var toggle = cc.MenuItemToggle.create( item1, item2 ); + + this.onMusicToggle = function( sender ) { + }; + + toggle.setCallback( this, this.onMusicToggle); + + var back = cc.MenuItemFont.create("Back", this.callbacks, this.callbacks.onBack ); + var menu = cc.Menu.create( toggle, back ); + l.addChild( menu ); + menu.alignItemsVertically(); + menu.setPosition( centerPos ); + + scene.addChild(l); + + return scene; + }; + + + self.getAboutScene = function() { + + var scene = cc.Scene.create(); + var l = cc.Layer.create(); + var about = cc.Reader.load("About.ccbi", this); + l.addChild( about ) + + var back = cc.MenuItemFont.create("Back", this.callbacks, this.callbacks.onBack ); + back.setColor( cc.BLACK ); + var menu = cc.Menu.create( back ); + l.addChild( menu ); + menu.alignItemsVertically(); + menu.setPosition( cc.p( winSize.width - 50, 50) ); + + scene.addChild( l ); + + return scene; + }; + + + // CCBuilder Selectors + + self.onPlay = function() { + director.replaceScene( cc.TransitionFade.create(1, this.getPlayScene()) ); + } + + self.onAbout = function() { + director.replaceScene( cc.TransitionZoomFlipY.create(1, this.getAboutScene()) ); + }; - layer.init(cc.c4b(0, 0, 0, 255), cc.c4b(0, 128, 255, 255)); + self.onOptions = function() { + director.replaceScene( cc.TransitionZoomFlipY.create(1, this.getOptionsScene()) ); + }; + + + // Manual Callbacks + + self.callbacks.onBack = function( sender) { + director.replaceScene( cc.TransitionFlipX.create(1, self.getMainMenuScene()) ); + }; + + return self; - var lab = "Houston we have liftoff!"; - var label = cc.LabelTTF.create(lab, "Arial", 28); - layer.addChild(label, 1); - label.setPosition( cc.p(winSize.width / 2, winSize.height / 2)); + }; + + var game = GameCreator(); + + __jsc__.garbageCollect(); + + director.runWithScene(game.getMainMenuScene()); + +} catch(e) {log(e);} - - scene.addChild(layer); - - director.runWithScene(scene); - -} catch(e) {log(e);} \ No newline at end of file