[Unity3D]通用对象池类ResourcePool<T>

来源:互联网 发布:中国银行 mac u盾 编辑:程序博客网 时间:2024/06/01 07:31

通用对象池,使用时会将常用的对象至于池顶,如果设置了池的大小,超出池的未经常使用的对象将被移除,并且执行回调,可在回调中对移除对象进行其他操作。
可对压入的对象进行命名,通过名字来进行查找和删除。

源码

using System.Collections;using System.Collections.Generic;using System;using System.Linq;namespace XM.Tool{    public class ResourcePool<T> : IEnumerable<ResourcePool<T>.ResInfo> where T : class    {        public class ResInfo        {            public string path;            public T res;            public ResInfo(string p, T r)            {                path = p;                res = r;            }            public bool HasRes()            {                return res != null;            }        }        private Action<List<ResInfo>> _onRemove;        private int _poolMaxSize = 0;        private List<ResInfo> _poolLst = new List<ResInfo>();        //public List<ResInfo> Pool { get { return _poolLst; } }        public int PoolMaxSize { get { return _poolMaxSize; } }        public int PoolSize { get { return _poolLst.Count; } }        public ResourcePool(Action<List<ResInfo>> onRemove = null, int maxSize = 0)        {            _onRemove = onRemove;            _poolMaxSize = maxSize;        }        ~ResourcePool()        {            //            Clear();        }        public void SetRemoveCallback(Action<List<ResInfo>> onRemove)        {            _onRemove = onRemove;        }        /// <summary>        /// 设置大小        /// </summary>        /// <param name="maxSize">大于等于0,0 表示无限大</param>        public void SetMaxSize(int maxSize)        {            _poolMaxSize = maxSize;            CheckSize();        }        public List<T> GetAllRes()        {            return _poolLst.Select((t) => { return t.res; }).ToList();        }        public List<string> GetAllPath()        {            return _poolLst.Select((t) => { return t.path; }).ToList();        }        public void Push(T res, bool checkSize = true, string path = "", bool updateExsit = false)        {            ResInfo resInfo = new ResInfo(path, res);            if (updateExsit)            {                //删除已有的                List<ResInfo> removeLst = _poolLst.FindAll((t) => { return string.Compare(path, t.path) == 0; });                _poolLst.RemoveAll((t) => { return string.Compare(path, t.path) == 0; });                OnRemove(removeLst);            }            _poolLst.Add(resInfo);            if (checkSize)            {                CheckSize();            }        }        public void Push(List<T> resLst, bool checkSize = true, string path = "", bool updateExsit = false)        {            foreach (var res in resLst)            {                Push(res, false, path, updateExsit);            }            if (checkSize)            {                CheckSize();            }        }        public ResInfo Pop()        {            ResInfo res = null;            if (_poolLst.Count > 0)            {                int index = _poolLst.Count - 1;                res = _poolLst[index];                _poolLst.RemoveAt(index);            }            return res;        }        public ResInfo Pop(string path)        {            ResInfo res = null;            if (_poolLst.Count > 0)            {                int index = _poolLst.FindIndex(t => (t.path == path));                if (index != -1)                {                    res = _poolLst[index];                    _poolLst.RemoveAt(index);                }            }            return res;        }        public T PopExt(string path = null)        {            var res = Pop(path);            if (res == null)            {                return null;            }            return res.res;        }        public T PopExt()        {            var res = Pop();            if (res == null)            {                return null;            }            return res.res;        }        public ResInfo LookLast()        {            ResInfo res = null;            if (_poolLst.Count > 0)            {                res = _poolLst[0];            }            return res;        }        public ResInfo LookFirst()        {            ResInfo res = null;            if (_poolLst.Count > 0)            {                res = _poolLst[_poolLst.Count - 1];            }            return res;        }        public T Get(string path)        {            int resIndex = _poolLst.FindIndex((t) => { return string.Compare(path, t.path) == 0; });            if (resIndex == -1)            {//未找到                return null;            }            //移动到栈顶            ResInfo res = _poolLst[resIndex];            _poolLst.RemoveAt(resIndex);            _poolLst.Add(res);            return res.res;        }        public void Remove(T res)        {            List<ResInfo> removeLst = _poolLst.FindAll((t) => { return t.res == res; });            _poolLst.RemoveAll((t) => { return t.res == res; });            OnRemove(removeLst);        }        public void Remove(string path)        {            List<ResInfo> removeLst = _poolLst.FindAll((t) => { return t.path == path; });            _poolLst.RemoveAll((t) => { return t.path == path; });            OnRemove(removeLst);        }        public void Clear()        {            List<ResInfo> removeLst = new List<ResInfo>(_poolLst);            _poolLst.Clear();            OnRemove(removeLst);        }        public void CheckSize()        {            if (_poolMaxSize == 0)            {                return;            }            int overflowSize = _poolLst.Count - _poolMaxSize;            if (overflowSize > 0)            {//超出存储范围             //移除栈底元素                List<ResInfo> removeLst = _poolLst.GetRange(0, overflowSize);                _poolLst.RemoveRange(0, overflowSize);                OnRemove(removeLst);            }        }        private void OnRemove(List<ResInfo> removeLst)        {            if (_onRemove != null)            {//移除元素回调                _onRemove(removeLst);            }        }        public IEnumerator<ResInfo> GetEnumerator()        {            return ((IEnumerable<ResInfo>)_poolLst).GetEnumerator();        }        IEnumerator IEnumerable.GetEnumerator()        {            return ((IEnumerable<ResInfo>)_poolLst).GetEnumerator();        }    }}

使用方式

using System.Collections.Generic;using UnityEngine;using XM.Tool;public class Test : MonoBehaviour{    //对象池    ResourcePool<GameObject> _pool;    void Start()    {        //初始化        _pool = new ResourcePool<GameObject>(OnRemove, 5);    }    private void OnRemove(List<ResourcePool<GameObject>.ResInfo> objs)    {        //销毁移除的对象        foreach (var obj in objs)        {            //是否存在            if (obj.HasRes())            {                //销毁                Destroy(obj.res);            }        }    }    public GameObject GetObj()    {        GameObject obj = null;        //优先从pool中获取        obj = _pool.PopExt();        if (null == obj)        {//否则创建            obj = new GameObject(Time.time.ToString());        }        else        {//激活物体            obj.SetActive(true);        }        return obj;    }    public void RecycleObj(GameObject obj)    {        //禁用物体        obj.SetActive(false);        //置入pool中,等待复用        _pool.Push(obj);    }    //当前回收的对象名字    string _recycleObjName = "";    public void OnGUI()    {        //创建对象        if (GUILayout.Button("Create Obj"))        {            GetObj();        }        //回收对象        _recycleObjName = GUILayout.TextField(_recycleObjName);        if (GUILayout.Button("Recycle Obj"))        {            GameObject obj = GameObject.Find(_recycleObjName);            if (null != obj)            {                RecycleObj(obj);            }        }        //清理对象池        if (GUILayout.Button("Clear Pool"))        {            _pool.Clear();        }    }}

这里写图片描述

0 0
原创粉丝点击