Cocos2dx-jsb 中Node的onEnter过程分析(1)

2024-04-06 03:58

本文主要是介绍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 onEnterif (_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_BINDINGif (_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 NodescriptEngine->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 JSAutoCompartmentif (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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/878940

相关文章

Django HTTPResponse响应体中返回openpyxl生成的文件过程

《DjangoHTTPResponse响应体中返回openpyxl生成的文件过程》Django返回文件流时需通过Content-Disposition头指定编码后的文件名,使用openpyxl的sa... 目录Django返回文件流时使用指定文件名Django HTTPResponse响应体中返回openp

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

批量导入txt数据到的redis过程

《批量导入txt数据到的redis过程》用户通过将Redis命令逐行写入txt文件,利用管道模式运行客户端,成功执行批量删除以Product*匹配的Key操作,提高了数据清理效率... 目录批量导入txt数据到Redisjs把redis命令按一条 一行写到txt中管道命令运行redis客户端成功了批量删除k

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Win10安装Maven与环境变量配置过程

《Win10安装Maven与环境变量配置过程》本文介绍Maven的安装与配置方法,涵盖下载、环境变量设置、本地仓库及镜像配置,指导如何在IDEA中正确配置Maven,适用于Java及其他语言项目的构建... 目录Maven 是什么?一、下载二、安装三、配置环境四、验证测试五、配置本地仓库六、配置国内镜像地址

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致