Merge pull request #2766 from dumganhar/jsb-delegate-crash-develop

fixed #2143: cc.ScrollView(TableView, EditBox).setDelegate(tmp object) causes crash.
This commit is contained in:
James Chen 2013-06-04 23:58:56 -07:00
commit 7c2ce0da64
4 changed files with 166 additions and 9 deletions

View File

@ -107,6 +107,11 @@ void CCEditBox::setDelegate(CCEditBoxDelegate* pDelegate)
}
}
CCEditBoxDelegate* CCEditBox::getDelegate()
{
return m_pDelegate;
}
void CCEditBox::setText(const char* pText)
{
if (pText != NULL)

View File

@ -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.
*

View File

@ -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;
}

View File

@ -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]