前端之家收集整理的这篇文章主要介绍了
Cocos2dx-jsb 中Node的onEnter过程分析(1),
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
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->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),1,&dataVal,&retval);
}
resumeSchedulesAndActions(p);
}
else if (action == kNodeOnExit)
{
if (isFunctionOverridedInJS(JS::RootedObject(_cx,"onExit",js_cocos2dx_Node_onExit))
{
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj),&retval);
}
pauseSchedulesAndActions(p);
}
else if (action == kNodeOnEnterTransitionDidFinish)
{
if (isFunctionOverridedInJS(JS::RootedObject(_cx,"onEnterTransitionDidFinish",js_cocos2dx_Node_onEnterTransitionDidFinish))
{
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj),&retval);
}
}
else if (action == kNodeOnExitTransitionDidStart)
{
if (isFunctionOverridedInJS(JS::RootedObject(_cx,"onExitTransitionDidStart",js_cocos2dx_Node_onExitTransitionDidStart))
{
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj),&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")
}