zoukankan      html  css  js  c++  java
  • GameFramework摘录

    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

  • 相关阅读:
    Linux学习记录(四):Shell脚本
    Linux学习记录(三):Vim
    基于PyTorch构建神经网络
    Python开发【第一篇】:初识Python
    asyncio 并发编程(二)
    asyncio 并发编程(一)
    Linux 文件和目录操作命令(一)
    Django Model
    Django 之 Form 组件
    Django 模板系统
  • 原文地址:https://www.cnblogs.com/lunoctis/p/12018652.html
Copyright © 2011-2022 走看看