unity 对象池
2016-01-29 15:39
399 查看
对象池背后的理念其实是非常简单的。我们将对象存储在一个池子中,当需要时在再次使用,而不是每次都实例化一个新的对象。池的最重要的特性,也就是对象池设计模式的本质是允许我们获取一个“新的”对象而不管它真的是一个新的对象还是循环使用的对象。
这是网上找的解释。
我们游戏中大量用到了对象池。
今天看了下对象池底层的代码。下面这篇文章写得挺好
http://www.cnblogs.com/mezero/p/3955130.html
废话不多说,上我们自己的对象池代码。
这是网上找的解释。
我们游戏中大量用到了对象池。
今天看了下对象池底层的代码。下面这篇文章写得挺好
http://www.cnblogs.com/mezero/p/3955130.html
废话不多说,上我们自己的对象池代码。
using System; using UnityEngine; using System.Collections; using System.Collections.Generic; // 清0操作由调用者负责编写 // 提供对非unity对象的缓存,即逻辑对象缓存 // 注意必须是class哈 // 提供接口 IObjectClear, Release时自动调用 public interface IObjectClear { void Clear(); } public class ObjectPool { class ObjectGroup { public Stack<object> m_freeStack; public int m_iMaxNum; // 最大数量,为0表示不限制,否则超过最大数量,Release时直接delete public ObjectGroup() { m_freeStack = new Stack<object>(); m_iMaxNum = 0; } } Dictionary< Type, ObjectGroup > m_typeDic; object m_locker = new object(); bool m_bIsthreadSafe; public ObjectPool(bool bIsthreadSafe = false) { m_typeDic = new Dictionary< Type, ObjectGroup >(); m_bIsthreadSafe = bIsthreadSafe; } public void Register<T>( int iInitNum, int iMaxNum = 0 ) where T : class, new() { if (iInitNum < 0) { throw new ArgumentException("Init num < 0"); } ObjectGroup group = null; if ( m_typeDic.TryGetValue(typeof(T), out group) ) { // 已存在 return; } group = new ObjectGroup(); group.m_iMaxNum = iMaxNum; if (iInitNum > 0) { for (int i = 0; i < iInitNum; i++) { T obj = new T(); if (m_bIsthreadSafe) { lock (m_locker) { group.m_freeStack.Push(obj); } } else { group.m_freeStack.Push(obj); } } } m_typeDic[typeof(T)] = group; } public T Get<T>() where T : class, new() { ObjectGroup group = null; if (!m_typeDic.TryGetValue(typeof(T), out group)) { Register<T>(1); return Get<T>(); } T obj = null; if (0 == group.m_freeStack.Count) { obj = new T(); }else { if (m_bIsthreadSafe) { lock (m_locker) { obj = group.m_freeStack.Pop() as T; } } else { obj = group.m_freeStack.Pop() as T; } } return obj; } public void Release<T>(T obj) where T : class, new() { if (null == obj) { throw new ArgumentException("obj is null!!"); } ObjectGroup group = null; Type t = ((object)obj).GetType(); if (!m_typeDic.TryGetValue(t, out group)) { throw new ArgumentException("obj's type is not registered!"); } if (obj is IObjectClear) { ((IObjectClear)obj).Clear(); } if (group.m_iMaxNum > 0 && group.m_freeStack.Count >= group.m_iMaxNum) { if (obj is IDisposable) { ((IDisposable)obj).Dispose(); } obj = null; System.GC.Collect(); } else { // add to free list if (m_bIsthreadSafe) { lock (m_locker) { group.m_freeStack.Push(obj); } } else { group.m_freeStack.Push(obj); } } } private void _DestroyGroup( ObjectGroup group ) { object obj = null; while (group.m_freeStack.Count > 0) { if (m_bIsthreadSafe) { lock (m_locker) { obj = group.m_freeStack.Pop(); } } else { obj = group.m_freeStack.Pop(); } if (obj is IDisposable) { ((IDisposable)obj).Dispose(); } obj = null; } if (m_bIsthreadSafe) { lock (m_locker) { group.m_freeStack.Clear(); } } else { group.m_freeStack.Clear(); } } public void DestroyType<T>() where T : class, new() { ObjectGroup group = null; if (!m_typeDic.TryGetValue(typeof(T), out group)) { throw new ArgumentException("obj's type is not registered!"); } this._DestroyGroup(group); } // destroy所有实列 public void DestroyAll() { foreach (var it in m_typeDic) { ObjectGroup group = it.Value; this._DestroyGroup(group); group = null; } m_typeDic.Clear(); System.GC.Collect(); } }
相关文章推荐
- 在Unity中StartCoroutine/yield return的原理和模式
- 【官方说明】Unity 5 引擎专业版和个人版解析
- Unity协程(Coroutine)原理深入剖析
- [Unity3D]脚本中Start()和Awake()的区别
- Unity3D研究院之两种方式播放游戏视频(二十五)
- Unity 安卓项目 接入调用java代码
- Unity3D 画线插件 Vectrosity_Simple2DLine
- 【我的书】Unity Shader的书 — 目录(2016.5.19最后一次更新)
- 【Unity Shader】2D动态云彩
- 【Unity Shader】2D动态云彩
- Unity3D项目之 Survival Shooter 记录
- EVP5 Unity5 汽车物理引擎demo分析
- Unity全屏模糊
- unity+slua热更流程演示
- 关于 Unity UGUI 中修改 Mask 组件下 Image 等子节点组件的材质无效的问题
- unity c# enum
- Unity WebPlayer自定义进度条界面
- [置顶] 一些值得学习的Unity教程
- unity3D 插件plugins
- 使用unity做的绩点计算器