Unity3d:GameFramework解析:实体,对象池,资源管理,获取计数,引用计数,自动释放

基本概念

1.GF万物基于引用池IReference
2.ObjectBase : IReference类的m_Target持有unity中Mono,资源,GameObejct
3.AssetObject : ObjectBase类m_Target持有Assetbundle中的Asset,具有获取,引用两个计数管理释放
4.ResourceObject : ObjectBase类m_Target持有Assetbundle,具有获取,引用两个计数管理释放
5.EntityInstanceObject : ObjectBase类m_Target指向Assetbundle中的Asset实例化后的GameObject,内部m_EntityAsset也是Assetbundle中的Asset
6.对象池具有按照间隔自动释放无用对象,对于实体,获取为0,即无用对象;对于AssetObject,ResourceObject要获取为0,父依赖(自己被别依赖)为0,即无用
7.引用的概念为资源被依赖,例如bundleA依赖bundleB,于是bundleB的引用=1
8.获取的概念:针对资源为对象再派生(关联)出别的对象,例如ResourceObjectA派生出AssetObjectA,即ResourceObjectA获取为1;AssetObjectA再派生出EntityInstanceObjectA,AssetObjectA的获取为1

对象池创建

InstancePool

只能单获取,即不能对一个对象反复Spawn

m_InstancePool = objectPoolManager.CreateSingleSpawnObjectPool<EntityInstanceObject>(Utility.Text.Format("Entity Instance Pool ({0})", name), instanceCapacity, instanceExpireTime, instancePriority);

AssetPool与ResourceObject

public void SetObjectPoolManager(IObjectPoolManager objectPoolManager)
{m_AssetPool = objectPoolManager.CreateMultiSpawnObjectPool<AssetObject>("Asset Pool");m_ResourcePool = objectPoolManager.CreateMultiSpawnObjectPool<ResourceObject>("Resource Pool");
}

EntityInstanceObject实体对象

1.每次使用看实体对象池中有无,有是指存在空闲未使用实体对象,取出来用
2.没有的话,需要从资源加载流程中走一遍

释放时

UnityGameFramework.Runtime.DefaultEntityHelper.ReleaseEntity

        /// <summary>/// 释放实体。/// </summary>/// <param name="entityAsset">要释放的实体资源。</param>/// <param name="entityInstance">要释放的实体实例。</param>public override void ReleaseEntity(object entityAsset, object entityInstance){m_ResourceComponent.UnloadAsset(entityAsset);Destroy((Object)entityInstance);}

1.AssetPool中把entityAsset的获取-1
2.销毁asset实例出来的GameObject

ResourceObject

何时引用+1

在assetA加载完,assetA的依赖asset的bundle引用+1。注意是依赖的asset的bundle,自身的bundle并不会引用+1
GameFramework.Resource.ResourceManager.ResourceLoader.LoadResourceAgent.OnLoadResourceAgentHelperLoadComplete

foreach (object dependencyAsset in dependencyAssets)
{object dependencyResource = null;if (m_ResourceLoader.m_AssetToResourceMap.TryGetValue(dependencyAsset, out dependencyResource)){m_Task.ResourceObject.AddDependencyResource(dependencyResource); //所有依赖这个asset的resource引用+1}

同时被依赖的bundleB加入到主bundleA的ResourceObject依赖列表中
GameFramework.Resource.ResourceManager.ResourceLoader.ResourceObject.AddDependencyResource

m_DependencyResources.Add(dependencyResource);

何时引用-1

bundle被释放时,子依赖bundle引用-1
GameFramework.Resource.ResourceManager.ResourceLoader.ResourceObject.Release

 foreach (object dependencyResource in m_DependencyResources)
{int referenceCount = 0;if (m_ResourceLoader.m_ResourceDependencyCount.TryGetValue(dependencyResource, out referenceCount)){m_ResourceLoader.m_ResourceDependencyCount[dependencyResource] = referenceCount - 1;//只会-1,不会对为 0 的Assetbundle进行卸载}

何时获取+1

bundleA中获取assetA时,获取+1。此时有有两种情况,
1.执行加载asset任务时,主bundle已加载,从ResourcePool中获取
GameFramework.Resource.ResourceManager.ResourceLoader.LoadResourceAgent.Start

ResourceObject resourceObject = m_ResourceLoader.m_ResourcePool.Spawn(resourceName);
if (resourceObject != null)
{GameFrameworkLog.Info("ResourcePool获取到了{0},说明asset:{1}的bundle已经加好了,返回bundle", resourceName, m_Task.AssetName);//从resource对象池中取出,说明之前加载过Assetbundle,任务可以接着执行OnResourceObjectReady(resourceObject);return StartTaskStatus.CanResume;
}

2.bundle未加载,加载完后注册入对象池,获取+1
GameFramework.Resource.ResourceManager.ResourceLoader.LoadResourceAgent.OnLoadResourceAgentHelperReadFileComplete

private void OnLoadResourceAgentHelperReadFileComplete(object sender, LoadResourceAgentHelperReadFileCompleteEventArgs e)
{GameFrameworkLog.Info("Assetbundle加载完成:{0}", m_Task.ResourceInfo.ResourceName.Name);ResourceObject resourceObject = ResourceObject.Create(m_Task.ResourceInfo.ResourceName.Name, e.Resource, m_ResourceHelper, m_ResourceLoader);m_ResourceLoader.m_ResourcePool.Register(resourceObject, true);s_LoadingResourceNames.Remove(m_Task.ResourceInfo.ResourceName.Name);OnResourceObjectReady(resourceObject);
}

何时获取-1

GameFramework.Resource.ResourceManager.ResourceLoader.AssetObject.Release

m_ResourceLoader.m_ResourcePool.Unspawn(m_Resource);

AssetObject

何时引用+1

assetA新加载完成时,创建AssetObjectA,把子依赖asset引用+1
GameFramework.Resource.ResourceManager.ResourceLoader.AssetObject.Create

//所有依赖的asset 引用+1,它自己次数不会+1
foreach (object dependencyAsset in dependencyAssets)
{int referenceCount = 0;GameFrameworkLog.Info("AssetObject创建-->{0}引用次数+1", dependencyAsset);if (resourceLoader.m_AssetDependencyCount.TryGetValue(dependencyAsset, out referenceCount)){resourceLoader.m_AssetDependencyCount[dependencyAsset] = referenceCount + 1;}else{resourceLoader.m_AssetDependencyCount.Add(dependencyAsset, 1);}
}

何时引用-1

AssetObjectA释放时,把所有子依赖资源-1。这里只会找直接子依赖(子节点),不会找到孙节点上
GameFramework.Resource.ResourceManager.ResourceLoader.AssetObject.Release

foreach (object dependencyAsset in m_DependencyAssets)
{int referenceCount = 0;if (m_ResourceLoader.m_AssetDependencyCount.TryGetValue(dependencyAsset, out referenceCount)){m_ResourceLoader.m_AssetDependencyCount[dependencyAsset] = referenceCount - 1;//子依赖的asset -1}

何时获取+1

AssetObject的获取,是为了给实例对象实例化。两种情况下
1.任务执行时,AssetPool有,直接返回,获取+1
GameFramework.Resource.ResourceManager.ResourceLoader.LoadResourceAgent.Start

//从对象池里拿一个 
AssetObject assetObject = m_ResourceLoader.m_AssetPool.Spawn(m_Task.AssetName);
if (assetObject != null)
{//说明资源之前加载过,且在AssetObject缓存池中//一旦成功执行Spawn,Spawn+1,在释放资源时不为0会跳过GameFrameworkLog.Info("AssetPool获取到了{0},不需要加载,直接返回asset", m_Task.AssetName);//如果是实体,实例化asset,并且新建一个实体对象OnAssetObjectReady(assetObject);return StartTaskStatus.Done;
}

2.AssetPool没有,从Assetbundle中加载完成asset,创建新AssetObject,并注册进入AssetPool,获取+1
GameFramework.Resource.ResourceManager.ResourceLoader.LoadResourceAgent.OnLoadResourceAgentHelperLoadComplete

            assetObject = AssetObject.Create(m_Task.AssetName, e.Asset, dependencyAssets, m_Task.ResourceObject.Target, m_ResourceHelper, m_ResourceLoader);GameFrameworkLog.Info("asset-->{0}加载完成,并且创建AssetObject到m_AssetPool缓冲池中", m_Task.AssetName);m_ResourceLoader.m_AssetPool.Register(assetObject, true);

何时获取-1

EntityInstanceObject释放时
UnityGameFramework.Runtime.DefaultEntityHelper.ReleaseEntity

        /// <summary>/// 释放实体。/// </summary>/// <param name="entityAsset">要释放的实体资源。</param>/// <param name="entityInstance">要释放的实体实例。</param>public override void ReleaseEntity(object entityAsset, object entityInstance){m_ResourceComponent.UnloadAsset(entityAsset);Destroy((Object)entityInstance);}

加载实体创建各个asset任务

加载一个实体,一个asset作为主任务,asset依赖的各个asset作为依赖任务
在这里插入图片描述

单个asest任务加载任务执行

在这里插入图片描述

任务

任务派生LoadAssetTask,LoadDependencyAssetTask,LoadSceneTask

任务完成的标志

资源准备好,即任务完成。不管是是从AssetPool中获取,还是异步加载完成

private void OnAssetObjectReady(AssetObject assetObject)
{m_Helper.Reset();object asset = assetObject.Target;if (m_Task.IsScene){m_ResourceLoader.m_SceneToAssetMap.Add(m_Task.AssetName, asset);}m_Task.OnLoadAssetSuccess(this, asset, (float)(DateTime.UtcNow - m_Task.StartTime).TotalSeconds);m_Task.Done = true;
}

自动释放

隐藏某实体时,在对象池自动释放中,如果改实体池依赖的asset获取为0,再判断出bundle获取为0,触发assetbundle.Unload(true),释放内存
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/104366.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线索二叉树——找前驱、后继

前言 一个二叉树被线索化之后&#xff0c;一个节点的前驱或后继会存在两种情况&#xff0c; 1、tag1&#xff0c;有明确的线索化前驱或后继&#xff0c; 2、tag0&#xff0c;只存在左右孩子&#xff0c;但是没用明确的线索化前驱后继&#xff0c;需要分析 //线索二叉树结点定义…

如何将PC电脑变成web服务器:将内网主机映射到外网实现远程访问

如何将PC电脑变成web服务器&#xff1a;将内网主机映射到外网实现远程访问 我是艾西&#xff0c;今天跟大家分享内容还是比较多人问的一个问题&#xff1a;如何将PC电脑变成web服务器。内网主机作为web服务器&#xff0c;内容包括本地内网映射、多层内网映射解决方案、绕过电信…

Linux socket网络编程概述 和 相关API讲解

socket网络编程的步骤 大体上&#xff0c;连接的建立过程就是&#xff1a;服务器在确定协议类型后&#xff0c;向外广播IP地址和端口号&#xff0c;并监听等待&#xff0c;直到客户端获取了IP地址和端口号并成功连接&#xff1a; 使用socket来进行tcp协议的网络编程的大体步骤…

创邻科技张晨:图数据库,激活数据要素的新基建

“数据经济时代&#xff0c;数据要素产业链的各细分领域均蕴含机遇&#xff0c;图技术作为网络协同和数据智能的底层发动机&#xff0c;将深度掘金数字中国价值潜能”。 8月22日&#xff0c;在2023中国&#xff08;南京&#xff09;国际软件产品和信息服务交易博览会的信息技术…

操作系统期末考试复习——简答题总结

最近考研在复习OS&#xff0c;顺便把大二期末考试的简答题整理了一下~ 1、操作系统的定义 “操作系统&#xff08;operating system&#xff0c;简称OS&#xff09;是管理计算机硬件与软件资源的计算机程序 2、操作系统的基本类型及特征 批处理操作系统、分时操作系统、实时…

400电话系统如何进行数据分析和优化?

400电话系统可以通过以下方式进行数据分析和优化&#xff1a; 呼叫记录&#xff1a;400电话系统会记录每一次呼叫的相关信息&#xff0c;包括呼叫时间、呼叫持续时间、呼叫地点等。通过分析呼叫记录&#xff0c;企业可以了解客户的呼叫习惯和行为模式&#xff0c;如高峰时段、呼…

新唐Nuc980学习笔记1 - 工程创建和下载

一、新唐nuc980 新唐nuc980 iot开发板是Linux 工业物联网开发平台&#xff0c;新唐科技提供工业物联网开发平台采用 NUC980DK 微处理器&#xff0c;此为一套完整的工业用物联网开平台&#xff0c;包含了完整的硬件设计与软件参考设计。包含了新唐执行速度 300 MHz 的 ARM9 MPU …

idea的debug断点的使用

添加断点&#xff08;目前不知道如何添加断点&#xff0c;就给AutoConfigurationImportSelector的每个方法都加上断点&#xff09;&#xff1a; 然后将StockApplication启动类以debug方式运行&#xff0c;然后程序就会停在119行 点击上边的step over让程序往下运行一行&#x…

有效降低传导辐射干扰

一直以来&#xff0c;设计中的电磁干扰&#xff08;EMI&#xff09;问题十分令人头疼&#xff0c;尤其是在汽车领域。为了尽可能的减小电磁干扰&#xff0c;设计人员通常会在设计原理图和绘制布局时&#xff0c;通过降低高di / dt的环路面积以及开关转换速率来减小噪声源。 但…

Mybatis动态之灵活使用下

目录 ​编辑 前言&#xff1a; 1.mybatis的分页 1.1分页的应用场景 1.2分页的使用方式 2.mybatis中特殊字符处理 2.1mybatis中特殊字符介绍 2.2mybatis中特殊字符的使用方式 前言&#xff1a; 上篇我已经写了Mybatis动态之灵活使用&#xff0c;接着上篇写mybatis的分页…

Django基础3——视图函数

文章目录 一、基本了解1.1 Django内置函数1.2 http请求流程 二、HttpRequest对象&#xff08;接受客户端请求&#xff09;2.1 常用属性2.2 常用方法2.3 服务端接收URL参数2.4 QueryDict对象2.5 案例2.5.1 表单GET提交2.5.2 表单POST提交2.5.3 上传文件 三、HttpResponse对象&am…

Source Insight配置Cppcheck做静态测试(Windows)

1.安装cppcheck 先从cppcheck官方网站下载cppcheck的安装包。 注&#xff1a; &#xff08;1&#xff09;官网地址&#xff1a;https://sourceforge.net/projects/cppcheck &#xff08;2&#xff09;截止2023年8月&#xff0c;官方发布的最新版本是cppcheck-2.11-x64-Setup.…

rabbitmq卸载重新安装3.8版本

卸载之前的版本的rabbitmq 卸载rabbitmq 卸载前先停止rabbitmq服务 /usr/lib/rabbitmq/bin/rabbitmqctl stop查看rabbitmq安装的相关列表 yum list | grep rabbitmq卸载rabbitmq相关内容 yum -y remove rabbitmq-server.noarch 卸载erlang 查看erlang安装的相关列表 …

漏洞扫描和漏洞评估

进行漏洞扫描和漏洞评估是确保系统和应用程序安全性的重要步骤。 下面是一个详细的步骤指南&#xff0c;说明如何进行漏洞扫描和漏洞评估。 步骤&#xff1a; 信息收集&#xff1a; 在开始漏洞扫描之前&#xff0c;收集有关目标系统和应用程序的信息&#xff0c;包括IP地址、…

OnePlus Open可折叠手机:规格、价格、发布日期等详细信息汇总!

我们知道OnePlus可折叠手机即将问世,无论它是否被命名为OnePlus Open。我们迫不及待地想让它到来,为该公司再添一根弦,为最好的可折叠手机增添一个新的竞争对手。 OnePlus以前没有生产过任何可折叠产品,但它确实拥有合作伙伴公司Oppo的丰富知识,并可以向三星、摩托罗拉和…

前端工程化之模块化

模块化的背景 前端模块化是一种标准&#xff0c;不是实现理解模块化是理解前端工程化的前提前端模块化是前端项目规模化的必然结果 什么是前端模块化? 前端模块化就是将复杂程序根据规范拆分成若干模块&#xff0c;一个模块包括输入和输出。而且模块的内部实现是私有的&…

利用LLM模型微调的短课程;钉钉宣布开放智能化底座能力

&#x1f989; AI新闻 &#x1f680; 钉钉宣布开放智能化底座能力AI PaaS&#xff0c;推动企业数智化转型发展 摘要&#xff1a;钉钉在生态大会上宣布开放智能化底座能力AI PaaS&#xff0c;与生态伙伴探寻企业服务的新发展道路。AI PaaS结合5G、云计算和人工智能技术的普及和…

Android相机-HAL-Rockchip-hal3

引言&#xff1a; 对于Android相机的 HAL层而言对上实现一套Framework的API接口&#xff0c;对下通过V4L2框架实现与kernel的交互。不同的平台会有不同的实现方案。主要是对Android HAL3的接口的实现。看看rockchip是怎么支持hal3的&#xff1f; 代码目录&#xff1a; hardw…

destoon8.0自媒体类型综合资讯门户模板

随着时代发展&#xff0c;自媒体资讯适合当前的互联网情形。呕心沥血开发的一套自媒体综合门户网站模板&#xff0c;本模板采用纯手写开发&#xff0c;带会员中心。首页&#xff0c;列表页&#xff0c;内容页&#xff0c;搜索页面精心编写&#xff0c;非常大气&#xff0c;并配…

Stable Diffusion 文生图技术原理

图像生成模型简介 图片生成领域来说&#xff0c;有四大主流生成模型&#xff1a;生成对抗模型&#xff08;GAN&#xff09;、变分自动编码器&#xff08;VAE&#xff09;、流模型&#xff08;Flow based Model&#xff09;、扩散模型&#xff08;Diffusion Model&#xff09;。…