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

posted @   lunoctis  阅读(537)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示