Cocos2dx-jsb 中Node的onEnter过程分析(1)
发布时间:2020-12-14 16:32:57 所属栏目:百科 来源:网络整理
导读:Cocos2dx-jsb 中Node的onEnter过程分析(1):1、当一个子节点被接入到父节点上时,都会调用Node::addChild方法,if( _running ) { child-onEnter(); //调用子节点的onEnter方法 // prevent onEnterTransitionDidFinish to be called twice when a node is add
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+++++++++++++++++++++++++2222211") this._super(); // 第○3部分是在这里调用的,下一篇再进行分析。 cc.log("onEnter+++++++++++++++++++++++++2222222") } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |