GameFramework摘录 - 1. ReferencePool
GameFramework是一个结构很优秀的Unity游戏框架,但意图似乎在构建可跨引擎的框架?对要求不高的小型个人(不专业)开发来说有些设计过度了,但其中的设计精华很值得学习。
首先来说一下其中的ReferencePool “引用池”,实质是一组自动管理(不需要单独手动创建销毁)的对象池(不包括GameObject等)。
抽取核心代码,并根据个人习惯修改一些命名后,代码如下
public interface IReference
{
// 采用此类进行清理,清理后应当和刚执行new()后创建得到的新对象状态相同
void Clean();
}
IReference 是自定义的一个接口,将需要进行池化存储的类继承此接口,就可以通过引用池来存取
public static class ReferencePool
{
private sealed class ReferenceCollection
{
private readonly Queue<IReference> m_Objects;
private readonly Type m_ReferenceType;
public Type ReferenceType { get { return m_ReferenceType; } }
public int UnusedReferenceCount { get { return m_Objects.Count; } }
public int UsingReferenceCount { get; private set; }
public ReferenceCollection(Type referenceType)
{
m_Objects = new Queue<IReference>();
m_ReferenceType = referenceType;
}
public void Clear()
{
lock (m_Objects)
{
m_Objects.Clear();
}
}
public T Acquire<T>() where T : class, IReference, new()
{
if (typeof(T) != m_ReferenceType)
{
throw new Exception("Wrong Type");
}
UsingReferenceCount++;
lock (m_Objects)
{
if (m_Objects.Count > 0)
{
return m_Objects.Dequeue() as T;
}
}
return new T();
}
public void Release<T>(T obj) where T : class, IReference, new()
{
if (typeof(T) != m_ReferenceType)
{
throw new Exception("Wrong Type");
}
obj.Clean();
lock (m_Objects)
{
if (m_Objects.Contains(obj))
{
throw new Exception("The reference has been released.");
}
m_Objects.Enqueue(obj);
}
UsingReferenceCount--;
}
}
}
ReferenceCollection是被管理的对象集合(将单词“Reference”替换为“Object”更好理解),即一个通常意义的对象池,提供了获取、释放对象的接口。原代码中一些用于统计、调试的属性被移除(实际在这里UnusedReferenceCount和UsingReferenceCount也可以先移除)
public static class ReferencePool
{
private static readonly Dictionary<Type, ReferenceCollection> s_ReferenceCollections = new Dictionary<Type, ReferenceCollection>();
public static void Clear()
{
lock (s_ReferenceCollections)
{
foreach (var pair in s_ReferenceCollections)
{
pair.Value.Clear();
}
s_ReferenceCollections.Clear();
}
}
public static T Acquire<T>() where T : class, IReference, new()
{
return GetReferenceCollection<T>().Acquire<T>();
}
public static void Release<T>(T obj) where T : class, IReference, new()
{
GetReferenceCollection<T>().Release<T>(obj);
}
private static ReferenceCollection GetReferenceCollection<T>() where T : class, IReference, new()
{
ReferenceCollection referenceCollection = null;
Type type = typeof(T);
lock (s_ReferenceCollections)
{
if (!s_ReferenceCollections.TryGetValue(type, out referenceCollection))
{
referenceCollection = new ReferenceCollection(type);
s_ReferenceCollections.Add(type, referenceCollection);
}
}
return referenceCollection;
}
}
ReferencePool最终提供了统一的对外接口ReferencePool.Acquire<T>()和ReferencePool.Release<T>()
在此基础上,可以添加原代码中的添加、删除、获取、释放计数
或设置ReferenceCollection的数量上限,如一个基于GameFramework的框架 HTFramework
GameFramework摘录 - 1. ReferencePool的更多相关文章
- MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录
注:文章内容都是摘录性文字,自己阅读的一些笔记,方便日后查看. MVC MVC(Model-View-Controller),M 是指业务模型,V 是指用户界面,C 则是控制器,使用 MVC 的目的是 ...
- 《征服 C 指针》摘录1:什么是空指针?区分 NULL、0 和 '\0'
一.什么是空指针? 空指针 是一个特殊的指针值. 空指针 是指可以确保没有向任何一个对象的指针.通常使用宏定义 NULL 来表示空指针常量值. 空指针 确保它和任何非空指针进行比较都不会相等,因此经常 ...
- 《征服 C 指针》摘录2:C变量的 作用域 和 生命周期(存储期)
在开发一些小程序的时候,也许我们并不在意作用域的必要性.可是,当你书写几万行,甚至几十万行的代码的时候,没有作用域肯定是不能忍受的. C 语言有如下 3 种作用域. 1.全局变量 在函数之外声明的变量 ...
- 《征服 C 指针》摘录3:数组 与 指针
一.数组 和 指针 的微妙关系 数组 是指将固定个数.相同类型的变量排列起来的对象. 正如之前说明的那样,给指针加 N,指针前进“当前指针指向的变量类型的长度 X N”. 因此,给指向数组的某个元素的 ...
- 《征服 C 指针》摘录4:函数 与 指针
一.指向函数的指针 函数名可以在表达式中被解读成“指向函数的指针”,因此,正如代码清单 2-2 的实验那样,写成 func 就可以取得指向函数的指针. “指向函数的指针”本质上也是指针(地址),所以可 ...
- 《征服 C 指针》摘录5:函数形参 和 空的下标运算符[]
一.函数的形参的声明 C 语言可以像下面这样声明函数的形参: void func(int a[]) { // ... } 对于这种写法,无论怎么看都好像要向函数的参数传递数组. 可是,在 C ...
- 《征服 C 指针》摘录6:解读 C 的声明
一.混乱的声明——如何自然地理解 C 的声明? 通常,C 的声明 int hoge; 这样,使用“类型 变量名;”的形式进行书写. 可是,像“指向 int 的指针”类型的变量,却要像下面这样进行声明: ...
- 阅读摘录《javascript 高级程序设计》01
前言: 因为工作需要,所以开始主攻前台JS方面的技术.在以前的工作中,使用过这门脚本语言.但是都是比较凌乱的,用到什么学什么,只是为了实现业务,而去使用. 不会考虑到代码优化,封装对象等.今次特意借了 ...
- Linux 下的dd命令使用详解(摘录)
一.dd命令的解释 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: 1. ...
- wndows程序设计之书籍知识与代码摘录-封装一个类似printf的messagebox
//----------------------------------------- //本程序展示了如何实现MessageBoxPrintf函数 //本函数能像printf那样格式化输出 //摘录 ...
随机推荐
- Windows下打开指定目录并定位到具体文件
一.在Windows上,网上流传的几种方法可以打开目录并定位到指定文件: 1.使用系统调用: 使用system()函数执行操作系统的命令行命令. 在命令行命令中,使用explorer /select, ...
- 《设计模式的运用》使用策略模式+工厂模式优化代码中的if else
使用策略模式优化if else 有这样一段逻辑 function{ for{ if() if() if( if( ) ) ... } } 公司有的祖传的代码,是一段规则校验,校验的越多,每一个请求都会 ...
- 瞬间抠图!揭秘 ZEGO 绿幕抠图算法背后的技术
抠图是图像处理中最常见的操作之一,指的是将图像中需要的部分从画面中精确的提取出来. 抠图的主要功能是为了后期的合成做准备.在 Photoshop 中,抠图的方法有很多种,最常见的有通道抠图.蒙版抠图. ...
- 解密Prompt系列11. 小模型也能COT-先天不足后天来补
前两章我们分别介绍了COT的多种使用方法以及COT的影响因素.这一章更多面向应用,既现实场景中考虑成本和推理延时,大家还是希望能用6B的模型就不用100B的大模型.但是在思维链基础和进阶玩法中反复提到 ...
- 《逆向工程核心原理》之DLL注入
DLL注入 DLL注入指的是向运行中的其他进程强制插入特定的DLL文件.从技术细节来说,DLL注入命令其他进程自行调用LoadLibrary() API,加载(Loading)用户指定的DLL文件.D ...
- Spring-Bean(三)
Bean生命周期配置 init-method:指定类中的初始化方法名称 destory-method:指定类中销毁方法名称 Bean标签配置 <bean id="UserDao&quo ...
- 信创啊,信创。Solon 的 war 包,现在同时支持 jakarta.servlet(及 javax.servlet)容器了!
Solon 是个神奇的项目,不是基于 Servlet 的.但是又很支持 Servlet,尤其是 war 包.打起来还挺方便的. 如果你是做信创的(听说,很多信创项目是用 war 部署到 tomcat ...
- 手动安装vur-router并引用
安装并引用 安装 npm install vue-router 引用 步骤一:在src路径下,创建router文件夹, 其下创建index.js // router/index.js import V ...
- C# 中关于 T 泛型【C# 基础】
〇.前言 C# 里面的泛型不仅可以使用泛型函数.泛型接口,也可以使用泛型类.泛型委托等等.在使用泛型的时候,它们会自行检测你传入参数的类型,因此它可以为我们省去大量的时间,不用一个个编写方法的重载.与 ...
- 质效提升 | QA不做业务需求测试,你怎么看?
因为有的小伙伴看到公司的QA不测试业务需求,只搞流程.卡点.规范.技术创新.QA平台,行业洞察,让研发自测.研发担责上线bug和风险,所以问我,你怎么看QA不做业务需求测试这件事.其实我怎么看不重要 ...