From 47c8205e3948ead4dba752aee7a4a6506de8ed93 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 5 Jun 2013 14:30:14 +0800 Subject: [PATCH 1/3] issue #2143: Adding CCEditBox::getDelegate. --- extensions/GUI/CCEditBox/CCEditBox.cpp | 5 +++++ extensions/GUI/CCEditBox/CCEditBox.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/extensions/GUI/CCEditBox/CCEditBox.cpp b/extensions/GUI/CCEditBox/CCEditBox.cpp index 137e4d4fb2..51e02140ed 100755 --- a/extensions/GUI/CCEditBox/CCEditBox.cpp +++ b/extensions/GUI/CCEditBox/CCEditBox.cpp @@ -107,6 +107,11 @@ void CCEditBox::setDelegate(CCEditBoxDelegate* pDelegate) } } +CCEditBoxDelegate* CCEditBox::getDelegate() +{ + return m_pDelegate; +} + void CCEditBox::setText(const char* pText) { if (pText != NULL) diff --git a/extensions/GUI/CCEditBox/CCEditBox.h b/extensions/GUI/CCEditBox/CCEditBox.h index c00beace51..4b820da3d5 100755 --- a/extensions/GUI/CCEditBox/CCEditBox.h +++ b/extensions/GUI/CCEditBox/CCEditBox.h @@ -196,9 +196,10 @@ public: bool initWithSizeAndBackgroundSprite(const CCSize& size, CCScale9Sprite* pNormal9SpriteBg); /** - * Set the delegate for edit box. + * Gets/Sets the delegate for edit box. */ void setDelegate(CCEditBoxDelegate* pDelegate); + CCEditBoxDelegate* getDelegate(); /** * Registers a script function that will be called for EditBox events. * From 5d92a98287098d0d8e6aae9bd7e9b4b308f6fa63 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 5 Jun 2013 14:31:07 +0800 Subject: [PATCH 2/3] fixed #2143: cc.ScrollView(TableView, EditBox).setDelegate(tmp object) causes crash. --- .../jsb_cocos2dx_extension_manual.cpp | 165 +++++++++++++++++- 1 file changed, 158 insertions(+), 7 deletions(-) diff --git a/scripting/javascript/bindings/jsb_cocos2dx_extension_manual.cpp b/scripting/javascript/bindings/jsb_cocos2dx_extension_manual.cpp index cf3c2f12b0..1899216cdf 100644 --- a/scripting/javascript/bindings/jsb_cocos2dx_extension_manual.cpp +++ b/scripting/javascript/bindings/jsb_cocos2dx_extension_manual.cpp @@ -13,9 +13,25 @@ USING_NS_CC; USING_NS_CC_EXT; -class JSB_ScrollViewDelegate : public CCScrollViewDelegate +class JSB_ScrollViewDelegate +: public CCNode +, public CCScrollViewDelegate { public: + JSB_ScrollViewDelegate() + : m_pJSDelegate(NULL) + , m_bNeedUnroot(false) + {} + + virtual ~JSB_ScrollViewDelegate() + { + if (m_bNeedUnroot) + { + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JS_RemoveObjectRoot(cx, &m_pJSDelegate); + } + } + virtual void scrollViewDidScroll(CCScrollView* view) { js_proxy_t * p = jsb_get_native_proxy(view); @@ -37,9 +53,19 @@ public: void setJSDelegate(JSObject* pJSDelegate) { m_pJSDelegate = pJSDelegate; + + // Check whether the js delegate is a pure js object. + js_proxy_t* p = jsb_get_js_proxy(m_pJSDelegate); + if (!p) + { + m_bNeedUnroot = true; + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JS_AddNamedObjectRoot(cx, &m_pJSDelegate, "TableViewDelegate"); + } } private: JSObject* m_pJSDelegate; + bool m_bNeedUnroot; }; static JSBool js_cocos2dx_CCScrollView_setDelegate(JSContext *cx, uint32_t argc, jsval *vp) @@ -55,8 +81,17 @@ static JSBool js_cocos2dx_CCScrollView_setDelegate(JSContext *cx, uint32_t argc, JSObject *jsDelegate = JSVAL_TO_OBJECT(argv[0]); JSB_ScrollViewDelegate* nativeDelegate = new JSB_ScrollViewDelegate(); nativeDelegate->setJSDelegate(jsDelegate); + + JSB_ScrollViewDelegate* oldDelegate = (JSB_ScrollViewDelegate*)cobj->getDelegate(); + if (oldDelegate) + { + oldDelegate->removeFromParent(); + } + cobj->addChild(nativeDelegate); cobj->setDelegate(nativeDelegate); + nativeDelegate->release(); + JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } @@ -64,9 +99,25 @@ static JSBool js_cocos2dx_CCScrollView_setDelegate(JSContext *cx, uint32_t argc, return JS_FALSE; } -class JSB_TableViewDelegate : public CCTableViewDelegate +class JSB_TableViewDelegate +: public CCNode +, public CCTableViewDelegate { public: + JSB_TableViewDelegate() + : m_pJSDelegate(NULL) + , m_bNeedUnroot(false) + {} + + virtual ~JSB_TableViewDelegate() + { + if (m_bNeedUnroot) + { + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JS_RemoveObjectRoot(cx, &m_pJSDelegate); + } + } + virtual void scrollViewDidScroll(CCScrollView* view) { callJSDelegate(view, "scrollViewDidScroll"); @@ -100,6 +151,15 @@ public: void setJSDelegate(JSObject* pJSDelegate) { m_pJSDelegate = pJSDelegate; + + // Check whether the js delegate is a pure js object. + js_proxy_t* p = jsb_get_js_proxy(m_pJSDelegate); + if (!p) + { + m_bNeedUnroot = true; + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JS_AddNamedObjectRoot(cx, &m_pJSDelegate, "TableViewDelegate"); + } } @@ -129,6 +189,7 @@ private: } JSObject* m_pJSDelegate; + bool m_bNeedUnroot; }; static JSBool js_cocos2dx_CCTableView_setDelegate(JSContext *cx, uint32_t argc, jsval *vp) @@ -144,8 +205,18 @@ static JSBool js_cocos2dx_CCTableView_setDelegate(JSContext *cx, uint32_t argc, JSObject *jsDelegate = JSVAL_TO_OBJECT(argv[0]); JSB_TableViewDelegate* nativeDelegate = new JSB_TableViewDelegate(); nativeDelegate->setJSDelegate(jsDelegate); + + + JSB_TableViewDelegate* oldDelegate = (JSB_TableViewDelegate*)cobj->getDelegate(); + if (oldDelegate) + { + oldDelegate->removeFromParent(); + } + cobj->addChild(nativeDelegate); cobj->setDelegate(nativeDelegate); + nativeDelegate->release(); + JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } @@ -153,9 +224,25 @@ static JSBool js_cocos2dx_CCTableView_setDelegate(JSContext *cx, uint32_t argc, return JS_FALSE; } -class JSB_TableViewDataSource : public CCTableViewDataSource +class JSB_TableViewDataSource +: public CCNode +, public CCTableViewDataSource { public: + JSB_TableViewDataSource() + : m_pJSTableViewDataSource(NULL) + , m_bNeedUnroot(false) + {} + + virtual ~JSB_TableViewDataSource() + { + if (m_bNeedUnroot) + { + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JS_RemoveObjectRoot(cx, &m_pJSTableViewDataSource); + } + } + virtual CCSize tableCellSizeForIndex(CCTableView *table, unsigned int idx) { jsval ret; @@ -211,6 +298,15 @@ public: void setTableViewDataSource(JSObject* pJSSource) { m_pJSTableViewDataSource = pJSSource; + + // Check whether the js delegate is a pure js object. + js_proxy_t* p = jsb_get_js_proxy(m_pJSTableViewDataSource); + if (!p) + { + m_bNeedUnroot = true; + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JS_AddNamedObjectRoot(cx, &m_pJSTableViewDataSource, "TableViewDataSource"); + } } private: @@ -273,6 +369,7 @@ private: private: JSObject* m_pJSTableViewDataSource; + bool m_bNeedUnroot; }; static JSBool js_cocos2dx_CCTableView_setDataSource(JSContext *cx, uint32_t argc, jsval *vp) @@ -284,11 +381,19 @@ static JSBool js_cocos2dx_CCTableView_setDataSource(JSContext *cx, uint32_t argc JSB_PRECONDITION2( cobj, cx, JS_FALSE, "Invalid Native Object"); if (argc == 1) { - CCTableViewDataSource* pOldDataSource = cobj->getDataSource(); - CC_SAFE_DELETE(pOldDataSource); JSB_TableViewDataSource* pNativeSource = new JSB_TableViewDataSource(); pNativeSource->setTableViewDataSource(JSVAL_TO_OBJECT(argv[0])); + + JSB_TableViewDataSource* oldDataSource = (JSB_TableViewDataSource*)cobj->getDataSource(); + if (oldDataSource) + { + oldDataSource->removeFromParent(); + } + cobj->addChild(pNativeSource); cobj->setDataSource(pNativeSource); + + pNativeSource->release(); + JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } @@ -310,8 +415,16 @@ static JSBool js_cocos2dx_CCTableView_create(JSContext *cx, uint32_t argc, jsval ok &= jsval_to_ccsize(cx, argv[1], &arg1); cocos2d::extension::CCTableView* ret = NULL; ret = new CCTableView(); - ret->setDataSource(pNativeSource); ret->autorelease(); + + JSB_TableViewDataSource* oldDataSource = (JSB_TableViewDataSource*)ret->getDataSource(); + if (oldDataSource) + { + oldDataSource->removeFromParent(); + } + + ret->setDataSource(pNativeSource); + jsval jsret; do { if (ret) { @@ -341,6 +454,9 @@ static JSBool js_cocos2dx_CCTableView_create(JSContext *cx, uint32_t argc, jsval } ret->reloadData(); + ret->addChild(pNativeSource); + pNativeSource->release(); + JS_SET_RVAL(cx, vp, jsret); return JS_TRUE; } @@ -349,9 +465,25 @@ static JSBool js_cocos2dx_CCTableView_create(JSContext *cx, uint32_t argc, jsval return JS_FALSE; } -class JSB_EditBoxDelegate : public CCEditBoxDelegate +class JSB_EditBoxDelegate +: public CCNode +, public CCEditBoxDelegate { public: + JSB_EditBoxDelegate() + : m_pJSDelegate(NULL) + , m_bNeedUnroot(false) + {} + + virtual ~JSB_EditBoxDelegate() + { + if (m_bNeedUnroot) + { + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JS_RemoveObjectRoot(cx, &m_pJSDelegate); + } + } + virtual void editBoxEditingDidBegin(CCEditBox* editBox) { js_proxy_t * p = jsb_get_native_proxy(editBox); @@ -395,9 +527,19 @@ public: void setJSDelegate(JSObject* pJSDelegate) { m_pJSDelegate = pJSDelegate; + + // Check whether the js delegate is a pure js object. + js_proxy_t* p = jsb_get_js_proxy(m_pJSDelegate); + if (!p) + { + m_bNeedUnroot = true; + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JS_AddNamedObjectRoot(cx, &m_pJSDelegate, "TableViewDelegate"); + } } private: JSObject* m_pJSDelegate; + bool m_bNeedUnroot; }; static JSBool js_cocos2dx_CCEditBox_setDelegate(JSContext *cx, uint32_t argc, jsval *vp) @@ -413,8 +555,17 @@ static JSBool js_cocos2dx_CCEditBox_setDelegate(JSContext *cx, uint32_t argc, js JSObject *jsDelegate = JSVAL_TO_OBJECT(argv[0]); JSB_EditBoxDelegate* nativeDelegate = new JSB_EditBoxDelegate(); nativeDelegate->setJSDelegate(jsDelegate); + + JSB_EditBoxDelegate* oldDelegate = (JSB_EditBoxDelegate*)cobj->getDelegate(); + if (oldDelegate) + { + oldDelegate->removeFromParent(); + } + cobj->addChild(nativeDelegate); cobj->setDelegate(nativeDelegate); + nativeDelegate->release(); + JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } From e4a8cad3c2afbf6db87e27433e63dbb1f3bbd5ad Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 5 Jun 2013 14:56:06 +0800 Subject: [PATCH 3/3] Updating cocos2dx_extension.ini --- tools/tojs/cocos2dx_extension.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tojs/cocos2dx_extension.ini b/tools/tojs/cocos2dx_extension.ini index d0f7b41f80..60eee93cfc 100644 --- a/tools/tojs/cocos2dx_extension.ini +++ b/tools/tojs/cocos2dx_extension.ini @@ -41,7 +41,7 @@ skip = CCBReader::[^CCBReader$ addOwnerCallbackName isJSControlled readByte getC CC.*Delegate::[*], CC.*Loader.*::[*], *::[^visit$ copyWith.* onEnter.* onExit.* ^description$ getObjectType], - CCEditBox::[setDelegate ^keyboard.* touchDownAction getScriptEditBoxHandler registerScriptEditBoxHandler unregisterScriptEditBoxHandler], + CCEditBox::[(g|s)etDelegate ^keyboard.* touchDownAction getScriptEditBoxHandler registerScriptEditBoxHandler unregisterScriptEditBoxHandler], CCTableView::[create (g|s)etDataSource$ (g|s)etDelegate], CCControl::[removeHandleOfControlEvent addHandleOfControlEvent]