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那样格式化输出 //摘录 ...
随机推荐
- Hexo博客Next主题友链页面
博客友链太多,需要自定义一个友情链接页面 link渲染文件 在 hexo/themes/next/layout 目录下建一个 link.swig文件,写入以下代码 {% block content % ...
- .Net 一套接口多实现
.Net 一套接口多实现 接口(interface)可理解为规范.标准.协议.接口是用来约束各方都在同一组规范下工作. 电脑外设USB接口,各个品牌商家生产的U盘.鼠标都能够被电脑主板识别并工作,这是 ...
- 并发编程-FutureTask解析
1.FutureTask对象介绍 Future对象大家都不陌生,是JDK1.5提供的接口,是用来以阻塞的方式获取线程异步执行完的结果. 在Java中想要通过线程执行一个任务,离不开Runnable与C ...
- 2021-7-6 Vue实现记事本功能
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...
- SSL 证书过期巡检脚本 (Python 版)
哈喽大家好,我是咸鱼 之前写了个 shell 版本的 SSL 证书过期巡检脚本 (文章:<SSL 证书过期巡检脚本>),后台反响还是很不错的 那么今天咸鱼给大家介绍一下 python 版本 ...
- 02.中台框架前台项目 admin.ui.plus 学习-介绍与简单使用
中台框架前台项目 admin.ui.plus 的初识 基于 vue3.x + CompositionAPI setup 语法糖 + typescript + vite + element plus + ...
- PIP升级+安装Django命令[WARNING: Retrying (Retry(total=4, connect=None...]
升级: >pip install -U Django 安装: >pip install Django 如果发现超时错误内容:(WARNING: Retrying (Retry(total= ...
- 《SQL与数据库基础》20. 主从复制
目录 主从复制 原理 搭建 主库配置 从库配置 测试 本文以 MySQL 为例 主从复制 主从复制是指将主数据库的 DDL 和 DML 操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执 ...
- 这才叫 API 接口设计!
API 接口设计 Token 设计 Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个 Token 便将此 Token 返回给客户端,以后客户端只需带上 ...
- BeanUtils.copyProperties:曾经是我的女神,现在是我的毒药。
前言 BeanUtils.copyProperties十有八九是你这些年工作中用的很多的其中一个,不管是Apache的还是Spring的. 网上的解释浩如烟海,我这边用一个超简单的例子直观展示给你看. ...