本文共 2419 字,大约阅读时间需要 8 分钟。
从使用者视角给出需求
首先,我所希望的这个内存池的代码最后使用应该是这样的。Bullet a = Pool.Take(); //从池中立刻获取一个单元,如果单元不存在,则它需要为我立刻创建出来。返回一个Bullet脚本以便于后续控制。注意这里使用泛型,也就是说它应该可以兼容任意的脚本类型。
Pool.restore(a);//当使用完成Bullet之后,我可以使用此方法回收这个对象。注意这里实际上我已经把Bullet这个组件的回收等同于某个GameObject(这里是子弹的GameObject)的回收。 使用上就差不多是这样了,希望可以有极其简单的方法来进行获取和回收操作。内存池单元结构最简单的内存池形式,差不多就是两个List,一个处于工作状态,一个处于闲置状态。工作完毕的对象被移动到闲置状态列表,以便于后续的再次获取和利用,形成一个循环。我们这里也会设计一个结构来管理这两个List,用于处理同一类的对象。 接下来是考虑内存池单元的形式,我们考虑到内存池单元要尽可能容易扩展,就是可以兼容任意数据类型,也就是说,假设我们的内存池单元定为Pool_Unit,那么它不能影响后续继承它的类型,那我们最好使用接口,一旦使用类,那么就已经无法兼容Unity组件,因为我们自定义的Unity组件全部继承自MonoBehavior。接下来考虑这个内存单元该具有的功能,差不多有两个基本功能要有:restore();//自己主动回收,为了方便后续调用,回收操作最好自己就有。
getState();//获取状态,这里是指获取当前是处于工作状态还是闲置状态,也是一个标记,用于后续快速判断。因为接口中无法存储单元,这里使用变通的方法,就是留给实现去处理,接口中要求具体实现需要提供一个状态标记。 综合内存池单元和状态标记,给出如下代码:namespace AndrewBox.Pool{ public interface Pool_Unit{ Pool_UnitState state();void setParentList(object parentList);void restore();}public enum Pool_Type{ Idle,Work}public class Pool_UnitState{ public Pool_Type InPool{ get;set;}}}单元组结构接下来考虑单元组,也就是前面所说的针对某一类的单元进行管理的结构。它内部有两个列表,一个工作,一个闲置,单元在工作和闲置之间转换循环。它应该具有以下功能:创建新单元;使用抽象方法,不限制具体创建方法。对于Unity而言,可能需要从Prefab克隆,那么最好有方法可以从指定的Prefab模板复制创建。
获取单元;从闲置表中查找,找不到则创建。回收单元;将其子单元进行回收。 综合单元组结构的功能,给出如下代码:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AndrewBox.Pool
{ public abstract class Pool_UnitList where T:class,Pool_Unit{ protected object m_template;protected List m_idleList;protected List m_workList;protected int m_createdNum = 0;public Pool_UnitList(){ m_idleList = new List();m_workList = new List();}///
/// 获取一个闲置的单元,如果不存在则创建一个新的/// /// 闲置单元public virtual T takeUnit() where UT:T{ T unit;if (m_idleList.Count > 0){ unit = m_idleList[0];m_idleList.RemoveAt(0);}else{ unit = createNewUnit();unit.setParentList(this);m_createdNum++;}m_workList.Add(unit);unit.state().InPool = Pool_Type.Work;OnUnitChangePool(unit);return unit;}/// /// 归还某个单元/// /// 单元public virtual void restoreUnit(T unit){ if (unit!=null && unit.state().InPool == Pool_Type.Work){ m_workList.Remove(unit);m_idleList.Add(unit);unit.state().InPool = Pool_Type.Idle;OnUnitChangePool(unit);}}/// /// 设置模板/// /// /// public void setTemplate(object template){ m_template = template;}protected abstract void OnUnitChangePool(T unit);protected abstract T createNewUnit() where UT : T;}}更多unity2018的功能介绍请到paws3d爪爪学院查找。转载地址:http://fqkdm.baihongyu.com/