Unity Game FrameWork—模块使用—引用池
引用池其实就是我们平常说的对象池,在程序中主要是起到防止对象被频繁创建和销毁、减少gc、预加载等作用。
GF中池子有两种,一种叫引用池,一种叫对象池,两者原理一样,但具体实现和针对的对象不同,引用池一般用来储存普通的C#类型对象,而对象池则一般用于储存UnityEngine下的对象(如Unity中的GameObject对象)
引用池的使用,基本上可以脱离引用池组件ReferencePoolComponent独立存在,组件中有且只有一个属性,即:EnableStrictCheck(是否开启强制检查)。
API使用:
向引用池中追加指定数量的引用:
ReferencePool.Add(4);
ReferencePool.Add(typeof(StructData),4);
追加的引用被标记为Unused(未使用的),引用计数+1
从引用池中获取引用:
StructData StructData1 = ReferencePool.Acquire();
获取时,若引用池是空的,则创建一个引用。若引用池中有释放的或未使用的引用,则从引用池中取出,取出后,引用池中不保留该对象。获取的引用被标记为Using(使用中),引用计数+1
释放引用:
ReferencePool.Release(StructData1);
将引用归还引用池
移除引用:
ReferencePool.Remove(2);
ReferencePool.RemoveAll(typeof(StructData));
移除是从引用池中移除,引用池中存储的是被标记为Unused、Release。
引用计数可以引用池组件的检视器面板看到
从上图可以看到数据节点、有限状态机、日志记录节点(如果有打印日志),除了显示出来的,框架中大量的事件以及相关组件有用到。
下面贴上Demo代码:
using GameFramework;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour
{ReferencePoolInfo[] Tem;State state1,state2;StructData StructData1, StructData2, StructData3;void Start(){//创建状态列表(使用引用池)state1 = ReferencePool.Acquire<State>();state1.Add("游走状态");state2 = ReferencePool.Acquire<State>();state2.Add("移动状态");StructData1 = ReferencePool.Acquire<StructData>();StructData1.Add("游走状态", new Vector2Int(0, 0));StructData2 = ReferencePool.Acquire<StructData>();StructData2.Add("移动状态", new Vector2Int(1, 15));StructData3 = ReferencePool.Acquire<StructData>();StructData3.Add("跳跃状态", new Vector2Int(4, 15));ReferencePool.Add<StructData>(4);Tem = ReferencePool.GetAllReferencePoolInfos();foreach (var item in Tem){Debug.LogError(item.Type + ":" + item.UsingReferenceCount);}}[ContextMenu("ReleaseItem")]public void ReleaseItem(){ReferencePool.Release(state2);foreach (var item in Tem){Debug.LogError(item.Type + ":" + item.UsingReferenceCount);}}[ContextMenu("ReleaseList")]public void ReleaseList(){ReferencePool.Release(StructData1);ReferencePool.Release(StructData3);ReferencePool.RemoveAll(typeof(StructData));foreach (var item in Tem){Debug.LogError(item.Type + ":" + item.UsingReferenceCount);}}[ContextMenu("AddItem")]public void AddItem(){StructData C = ReferencePool.Acquire<StructData>();}
}
public class State : IReference
{string StateName;public State(){}public void Add(string StateName){this.StateName = StateName;}public void Clear(){StateName = null;}
}
public class StructData : IReference
{string StateName;Vector2Int pos;public StructData(){}public void Add(string StateName, Vector2Int pos){this.StateName = StateName;this.pos = pos;}public void Clear(){StateName = null;pos = default(Vector2Int);}
}