Cocos2dx-jsb 中Node的onEnter过程分析(1):
1、
当一个子节点被接入到父节点上时,都会调用Node::addChild方法,
if( _running )
{
child->onEnter(); //调用子节点的onEnter方法
// prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
if (_isTransitionFinished) //如果有场景又过度,则调用onEnterTransitionDidFinish方法,和上面的onEnter方法类似。
{
child->onEnterTransitionDidFinish();
}
}
2、
onEnter方法分析:
void Node::onEnter()
{
if (_onEnterCallback) //如果有回到,则调用
_onEnterCallback();
○1#if CC_ENABLE_SCRIPT_BINDING //如果绑定了脚本,则调用
if (_scriptType == kScriptTypeJavascript)
{
○2 if (ScriptEngineManager::sendNodeEventToJS(this, kNodeOnEnter))
return;
}
#endif
○3 _isTransitionFinished = false;
for( const auto &child: _children)
child->onEnter();
this->resume();
_running = true;
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeLua)
{
ScriptEngineManager::sendNodeEventToLua(this, kNodeOnEnter);
}
#endif
}
3、
看函数的名字,发送节点事件给JS
ScriptEngineManager::sendNodeEventToJS(this, kNodeOnEnter)
bool ScriptEngineManager::sendNodeEventToJS(Node* node, int action)
{
auto scriptEngine = getInstance()->getScriptEngine();
//这里是为了防止反复调用,标记是不是从JS调用的
if (scriptEngine->isCalledFromScript())
{
// Should only be invoked at root class Node
scriptEngine->setCalledFromScript(false);
}
else
{
BasicScriptData data(node,(void*)&action);
ScriptEvent scriptEvent(kNodeEvent,(void*)&data);
if (scriptEngine->sendEvent(&scriptEvent))
return true;
}
return false;
}
4、sendEvent:
int ScriptingCore::sendEvent(ScriptEvent* evt)
{
if (NULL == evt)
return 0;
// special type, can't use this code after JSAutoCompartment
if (evt->type == kRestartGame)
{
restartVM();
return 0;
}
JSAutoCompartment ac(_cx, _global.ref().get());
//这里会根据事件的类型调用不同的函数,我们这里的是kNodeEvent事件,
//我们这次只分析这个
switch (evt->type)
{
case kNodeEvent:
{
return handleNodeEvent(evt->data);
}
break;
case kMenuClickedEvent:
break;
case kTouchEvent:
{
TouchScriptData* data = (TouchScriptData*)evt->data;
return handleTouchEvent(data->nativeObject, data->actionType, data->touch, data->event);
}
break;
case kTouchesEvent:
{
TouchesScriptData* data = (TouchesScriptData*)evt->data;
return handleTouchesEvent(data->nativeObject, data->actionType, data->touches, data->event);
}
break;
case kComponentEvent:
{
return handleComponentEvent(evt->data);
}
break;
default:
CCASSERT(false, "Invalid script event.");
break;
}
return 0;
}
5、handleNodeEvent这个函数是真正的调用Js
int ScriptingCore::handleNodeEvent(void* data)
{
if (NULL == data)
return 0;
BasicScriptData* basicScriptData = static_cast<BasicScriptData*>(data);
if (NULL == basicScriptData->nativeObject || NULL == basicScriptData->value)
return 0;
Node* node = static_cast<Node*>(basicScriptData->nativeObject);
int action = *((int*)(basicScriptData->value));
js_proxy_t * p = jsb_get_native_proxy(node);
if (!p) return 0;
int ret = 0;
JS::RootedValue retval(_cx);
jsval dataVal = INT_TO_JSVAL(1);
if (action == kNodeOnEnter)
{
//根据不同的事件,如果JS又重载,调用不同的JS重载函数。
if (isFunctionOverridedInJS(JS::RootedObject(_cx, p->obj.get()), "onEnter", js_cocos2dx_Node_onEnter))
{
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), "onEnter", 1, &dataVal, &retval);
}
resumeSchedulesAndActions(p);
}
else if (action == kNodeOnExit)
{
if (isFunctionOverridedInJS(JS::RootedObject(_cx, p->obj.get()), "onExit", js_cocos2dx_Node_onExit))
{
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), "onExit", 1, &dataVal, &retval);
}
pauseSchedulesAndActions(p);
}
else if (action == kNodeOnEnterTransitionDidFinish)
{
if (isFunctionOverridedInJS(JS::RootedObject(_cx, p->obj.get()), "onEnterTransitionDidFinish", js_cocos2dx_Node_onEnterTransitionDidFinish))
{
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), "onEnterTransitionDidFinish", 1, &dataVal, &retval);
}
}
else if (action == kNodeOnExitTransitionDidStart)
{
if (isFunctionOverridedInJS(JS::RootedObject(_cx, p->obj.get()), "onExitTransitionDidStart", js_cocos2dx_Node_onExitTransitionDidStart))
{
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), "onExitTransitionDidStart", 1, &dataVal, &retval);
}
}
else if (action == kNodeOnCleanup) {
cleanupSchedulesAndActions(p);
}
return ret;
}
6、到此为止,○1○2两部分都分析完了,那第○3部分,什么时候调用呢?
第三部分的代码:
_isTransitionFinished = false;
for( const auto &child: _children)
child->onEnter();
this->resume();
_running = true;
第三部分的其实是在JS中重载的onEnter函数:其实也就是我们的onEnter调用过程的测试代码:
onEnter : function (){
cc.log("onEnter+++++++++++++++++++++++++1111111")
this._super(); // 第○3部分是在这里调用的,下一篇再进行分析。
cc.log("onEnter+++++++++++++++++++++++++2222222")
}
Cocos2dx-jsb 中Node的onEnter过程分析(1)
最新推荐文章于 2021-11-04 11:57:53 发布