【六】CocosCreator-CCObject.js源码分析

2024-02-06 02:44

本文主要是介绍【六】CocosCreator-CCObject.js源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PS:只是看源码学习过程中把认为重要的内容以笔记的形式记录下来。       

        本来是想写CCNode的,结果发现CCNode继承BaseNode,BaseNode再继承CCObject,那么,就先来看CCObject吧~

        在CCObject类中,他是通过给原型方法赋值来实现类似成员函数相关的功能,如:prototype.destroy = function () {}。

【1】destroy():销毁对象。【因为这个方法很重要,所以我每步都插入关键的核心代码】
1.把需要销毁的对象加到销毁队列objectsToDestroy中。(不会立马销毁)

prototype.destroy = function () {// 省略上下文objectsToDestroy.push(this);// 省略上下文
};


2.在CCDirector的主循环里,再当前帧渲染之前调用deferredDestroy()进行销毁。

mainLoop: CC_EDITOR ? function (deltaTime, updateAnimate) {// 省略上下文} : function (now) {// 省略上下文// Updateif (!this._paused) {// 省略上下文// Destroy entities that have been removed recentlyObj._deferredDestroy();}// 省略上下文}},


3.【deferredDestroy函数内部】遍历objectsToDestroy,如果对象还没销毁,则调用_destroyImmediate。然后把删掉的对象从objectsToDestroy队列里面清除。

function deferredDestroy () {var deleteCount = objectsToDestroy.length;for (var i = 0; i < deleteCount; ++i) {var obj = objectsToDestroy[i];if (!(obj._objFlags & Destroyed)) {obj._destroyImmediate();}}// if we called b.destory() in a.onDestroy(), objectsToDestroy will be resized,// but we only destroy the objects which called destory in this frame.if (deleteCount === objectsToDestroy.length) {objectsToDestroy.length = 0;}else {objectsToDestroy.splice(0, deleteCount);}if (CC_EDITOR) {deferredDestroyTimer = null;}
}


4.【_destroyImmediate函数内部】在对象销毁前,调用_onPreDestroy(). 所有的子类就可以在这个接口里做一些销毁对象前需要执行的操作了。
5.【_destroyImmediate函数内部】调用_destruct(),清除实例的所有引用。

prototype._destroyImmediate = function () {if (this._objFlags & Destroyed) {cc.errorID(5000);return;}// engine internal callbackif (this._onPreDestroy) {this._onPreDestroy();}if ((CC_TEST ? (/* make CC_EDITOR mockable*/ Function('return !CC_EDITOR'))() : !CC_EDITOR) || cc.engine._isPlaying) {this._destruct();}this._objFlags |= Destroyed;
};


6.【_destruct函数内部】调用compileDestruct()构造出“析构函数”,然后调用destruct(this)析构函数清除实例的所有引用。

prototype._destruct = function () {var ctor = this.constructor;var destruct = ctor.__destruct__;if (!destruct) {destruct = compileDestruct(this, ctor);js.value(ctor, '__destruct__', destruct, true);}destruct(this);
};


7.【compileDestruct函数内部】会遍历对象的key,然后用自带的原型方法hasOwnProperty去检测对象的自有属性,然后把所有自有属性置空再赋值给propsToReset。
8.【compileDestruct函数内部】判断如果有构造函数,则是类类型,同样把类里面的string、object、funciton等置空赋值给propsToReset。
PS:上面的7,8两个步骤很关键,大致意思就是构建一个propsToReset出来,key值用对象的key,value就是置空的值。
9.【compileDestruct函数内部】返回一个方法(可以勉强理解为“析构函数”),方法内部其实就是遍历propsToReset,把propsToReset的值赋值给对象,从而真正实现了清除实例的所有引用。

function compileDestruct (obj, ctor) {var shouldSkipId = obj instanceof cc._BaseNode || obj instanceof cc.Component;var idToSkip = shouldSkipId ? '_id' : null;var key, propsToReset = {};for (key in obj) {if (obj.hasOwnProperty(key)) {if (key === idToSkip) {continue;}switch (typeof obj[key]) {case 'string':propsToReset[key] = '';break;case 'object':case 'function':propsToReset[key] = null;break;}}}// Overwrite propsToReset according to Classif (cc.Class._isCCClass(ctor)) {var attrs = cc.Class.Attr.getClassAttrs(ctor);var propList = ctor.__props__;for (var i = 0; i < propList.length; i++) {key = propList[i];var attrKey = key + cc.Class.Attr.DELIMETER + 'default';if (attrKey in attrs) {if (shouldSkipId && key === '_id') {continue;}switch (typeof attrs[attrKey]) {case 'string':propsToReset[key] = '';break;case 'object':case 'function':propsToReset[key] = null;break;case 'undefined':propsToReset[key] = undefined;break;}}}}if (CC_SUPPORT_JIT) {// compile codevar func = '';for (key in propsToReset) {var statement;if (CCClass.IDENTIFIER_RE.test(key)) {statement = 'o.' + key + '=';}else {statement = 'o[' + CCClass.escapeForJS(key) + ']=';}var val = propsToReset[key];if (val === '') {val = '""';}func += (statement + val + ';\n');}return Function('o', func);}else {return function (o) {for (var key in propsToReset) {o[key] = propsToReset[key];}};}
}

【2】_objFlags:应该是记录对象的状态吧,状态的定义在CCObject.js也有,但具体每个状态什么时候用到,暂时在CCObject还没看到,估计是给子类使用的?

【3】cc.isValid():这个我们经常用来判断对象是否还有效的方法,就是通过_objFlags的状态来判断的。

这篇关于【六】CocosCreator-CCObject.js源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件