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的更多相关文章

  1. 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 的目的是 ...

  2. 《征服 C 指针》摘录1:什么是空指针?区分 NULL、0 和 '\0'

    一.什么是空指针? 空指针 是一个特殊的指针值. 空指针 是指可以确保没有向任何一个对象的指针.通常使用宏定义 NULL 来表示空指针常量值. 空指针 确保它和任何非空指针进行比较都不会相等,因此经常 ...

  3. 《征服 C 指针》摘录2:C变量的 作用域 和 生命周期(存储期)

    在开发一些小程序的时候,也许我们并不在意作用域的必要性.可是,当你书写几万行,甚至几十万行的代码的时候,没有作用域肯定是不能忍受的. C 语言有如下 3 种作用域. 1.全局变量 在函数之外声明的变量 ...

  4. 《征服 C 指针》摘录3:数组 与 指针

    一.数组 和 指针 的微妙关系 数组 是指将固定个数.相同类型的变量排列起来的对象. 正如之前说明的那样,给指针加 N,指针前进“当前指针指向的变量类型的长度 X N”. 因此,给指向数组的某个元素的 ...

  5. 《征服 C 指针》摘录4:函数 与 指针

    一.指向函数的指针 函数名可以在表达式中被解读成“指向函数的指针”,因此,正如代码清单 2-2 的实验那样,写成 func 就可以取得指向函数的指针. “指向函数的指针”本质上也是指针(地址),所以可 ...

  6. 《征服 C 指针》摘录5:函数形参 和 空的下标运算符[]

    一.函数的形参的声明 C 语言可以像下面这样声明函数的形参: void func(int a[]) {     // ... } 对于这种写法,无论怎么看都好像要向函数的参数传递数组. 可是,在 C ...

  7. 《征服 C 指针》摘录6:解读 C 的声明

    一.混乱的声明——如何自然地理解 C 的声明? 通常,C 的声明 int hoge; 这样,使用“类型 变量名;”的形式进行书写. 可是,像“指向 int 的指针”类型的变量,却要像下面这样进行声明: ...

  8. 阅读摘录《javascript 高级程序设计》01

    前言: 因为工作需要,所以开始主攻前台JS方面的技术.在以前的工作中,使用过这门脚本语言.但是都是比较凌乱的,用到什么学什么,只是为了实现业务,而去使用. 不会考虑到代码优化,封装对象等.今次特意借了 ...

  9. Linux 下的dd命令使用详解(摘录)

    一.dd命令的解释 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: 1. ...

  10. wndows程序设计之书籍知识与代码摘录-封装一个类似printf的messagebox

    //----------------------------------------- //本程序展示了如何实现MessageBoxPrintf函数 //本函数能像printf那样格式化输出 //摘录 ...

随机推荐

  1. GGTalk 开源即时通讯系统源码剖析之:服务端全局缓存

    继上篇<GGTalk 开源即时通讯系统源码剖析之:数据库设计>介绍了 GGTalk 数据库中所有表的结构后,接下来我们将进入GGTalk服务端的核心部分. GGTalk 对需要频繁查询数据 ...

  2. Java 中怎样将 bytes 转换为 long 类型?

    将bytes 转换为long类型: 第一种方式: String 接收 bytes 的构造器转成 String,再 Long.parseLong: 但此种情况需要注意:字节数组中的每个字节都必须是有效的 ...

  3. windows下安装及配置JDK(详解版)

    1.下载JDK 本文以JDK1.8为主 JDK1.8官方下载链接 https://www.oracle.com/java/technologies/javase/javase-jdk8-downloa ...

  4. React:如何在普通函数中使用Hook

    解决方案

  5. js面向对象编程,你需要知道这些

    javascript中对象由key和value组成,key是标识符,value可以为任意类型 创建对象的方式 1.通过构造函数 var obj = new Object() obj.name = 'a ...

  6. centos7安装weblogic

    前言 简介:weblogic是java应用服务器软件的一种,类似于tomcat,但功能更多,适用于大型应用场景. 版本: 系统:centos 7(最小化安装,无图形化界面) jdk: oraclejd ...

  7. JOIN 关联表中 ON、WHERE 后面跟条件的区别

    SQL中join连接查询时条件放在on后与where后的区别 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和wh ...

  8. 在 Spring 6 中使用虚拟线程

    一.简介 在这个简短的教程中,我们将了解如何在 Spring Boot 应用程序中利用虚拟线程的强大功能. 虚拟线程是Java 19 的预览功能,这意味着它们将在未来 12 个月内包含在官方 JDK ...

  9. 4.go语言复合类型简述

    目录 1. 本章前瞻 2.来自leetcode的例题 描述 分析 题解 3. 复合类型新版本的变化 3.1 string和[]byte的高效转化 3.2 内置函数clear 4. 复合类型概述 4.1 ...

  10. 一款国产开源 Web 防火墙神器!

    随着开源 Web 框架和各种建站工具的兴起,搭建网站已经是一件成本非常低的事情,但是网站的安全性很少有人关注,以至于 WAF 这个品类也鲜为人知. 一.WAF 是什么? WAF 是 Web 应用防火墙 ...