Complex nested object pools (4) - object pools that manage multi-class instances and multi-stage instances

【Classification of objects】

 Throughout the game, there are many objects, which can be classified according to certain standards: for example, these objects belong to the UI, those objects belong to the terrain, and some objects belong to the character, etc.; some objects only appear in the first stage, some only Appear in the second stage, some only appear in the third stage, etc.; some objects belong to a certain plot or task; some objects are in a certain location or range, etc.

If we want to manage all instance objects in the game, then we need to make a complex nested super object pool to manage. How to nest the object pool, that is, how to classify objects, needs to be based on the game, that is, for business. We need to think about it in advance, which also reflects whether we can grasp the game as a whole.

In this article, the objects are classified into different categories and different stages. Here, it is considered that there are different types of objects in different stages, and it is also possible to make different types of objects in different stages. The codes are basically the same, and they are all from the previous article. Object pools that manage single instance objects are based on object pools that manage multiple instances.

[Implementation of managing multi-class instance object pools]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

namespace Cache
{
    public enum ObjectType
    {
        Common = 0,
        UI = 1,
        Role = 2,
        Effect = 3,
        Terrain = 4,
        Collider = 5,
        Camera = 6,
        Special
    }

    public class ObjectTypePool : ObjectPoolBase
    {
        private Cache<ObjectType, MultiObjectPool> _poolCache;//ObjectType本质是string,只不过数量少些用枚举,而不是MultiObjectPool中用string
        private Dictionary<int, ObjectType> lentInstance2ObjectType = new Dictionary<int, ObjectType>();


        private Dictionary<string, ObjectType> nameMap = new Dictionary<string, ObjectType>();
        public ObjectTypePool(int capacity, string poolName, CacheWeedOutStrategy cacheWeedOutStrategy, Action<bool> onlendObjectOut = null, Action<bool> onRecycleObject = null) : base(capacity, poolName, onlendObjectOut, onRecycleObject)
        {
            poolCache = new Cache<ObjectType, MultiObjectPool>(cacheWeedOutStrategy, capacity, OnWeedOut);
            _poolCache = poolCache as Cache<ObjectType, MultiObjectPool>;
            foreach (ObjectType item in Enum.GetValues(typeof(ObjectType)))
            {
                nameMap.Add(item.ToString(), item);
            }
        }

        public ObjectTypePool(PoolInfo poolInfo, Action<bool> onlendObjectOut = null, Action<bool> onRecycleObject = null) : base(poolInfo, onlendObjectOut, onRecycleObject)
        {
            if (poolInfo != null)
            {
                foreach (ObjectType item in Enum.GetValues(typeof(ObjectType)))
                {
                    nameMap.Add(item.ToString(), item);
                }

                if (poolInfo.poolType == PoolType.ObjectType)
                {
                    poolCache = new Cache<ObjectType, MultiObjectPool>(poolInfo.cacheWeedOutStrategy, poolInfo.capacity, OnWeedOut);
                    _poolCache = poolCache as Cache<ObjectType, MultiObjectPool>;

                    //初始化子对象池
                    foreach (var item in poolInfo.subPoolInfo)
                    {
                        var subPool = new MultiObjectPool(item, OnLendObjectOut, OnRecycleObject);
                        _poolCache.Put(nameMap[subPool.poolName], subPool);
                        TotalCapcity += subPool.TotalCapcity;
                    }
                    //使用默认的池子设置
                    for (int i = poolInfo.subPoolInfo.Count; i < poolInfo.subPoolCount; i++)
                    {
                        var subPool = new MultiObjectPool(poolInfo.defaultSubPoolInfo, OnLendObjectOut, OnRecycleObject);
                        _poolCache.Put(nameMap[subPool.poolName], subPool);
                        TotalCapcity += subPool.TotalCapcity;
                    }
                }
            }
        }

        public override GameObject LendObjectOut(string objectName, Transform parent = null, object[] extradata = null)
        {
            GameObject go = null;
            if (string.IsNullOrEmpty(objectName))
                return null;

            MultiObjectPool multiObjectPool = null;

            ObjectType objectType;//要将对象类型的参数传进来
            if(Enum.TryParse<ObjectType>(extradata[0].ToString(),out objectType))
            {
                if (_poolCache.Get(objectType, out multiObjectPool))
                {
                    go = multiObjectPool.LendObjectOut(objectName, parent);
                }
            }
            if(go != null)
                lentInstance2ObjectType[go.GetInstanceID()] = objectType;
            return go;
            
        }

        public override bool RecycleObject(GameObject go)
        {
            if (go == null)
                return false;

            if (!lentInstance2ObjectType.ContainsKey(go.GetInstanceID()))
                return false;

            MultiObjectPool pool;
            if (_poolCache.Get(lentInstance2ObjectType[go.GetInstanceID()], out pool))
            {
                if (pool.RecycleObject(go))
                {
                    lentInstance2ObjectType.Remove(go.GetInstanceID());
                    return true;
                }
            }
            return false;
        }

        private void OnWeedOut(MultiObjectPool multiObjectPool)
        {      
            TotalCount -= multiObjectPool.TotalCount;
            CachedCount -= multiObjectPool.CachedCount;
            TotalCapcity -= multiObjectPool.TotalCapcity;
            multiObjectPool.Dispose();
        }
        private void OnLendObjectOut(bool instantiated)
        {
            if (instantiated)
                TotalCount++;
            else
                CachedCount--;
            onlendObjectOut?.Invoke(instantiated);
        }

        private void OnRecycleObject(bool destroyed)
        {
            if (destroyed)
            {
                TotalCount--;
                CachedCount--;
            }
            else
                CachedCount++;
            onRecycleObject?.Invoke(destroyed);
        }
    }
}

【Manage object pools for multi-stage instances】

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

namespace Cache
{
    public enum StageType
    {
        FirstStage = 1,
        SecondStage,
        ThirdStage,
        FourthStage,
        FifthStage,
    }

    public class StageObjectPool : ObjectPoolBase
    {
        private Cache<StageType, ObjectTypePool> _poolCache;
        private Dictionary<int, StageType> lentInstance2StageType = new Dictionary<int, StageType>();

        private Dictionary<string, StageType> nameMap = new Dictionary<string, StageType>();
        public StageObjectPool(int capacity, string poolName, CacheWeedOutStrategy cacheWeedOutStrategy, Action<bool> onlendObjectOut = null, Action<bool> onRecycleObject = null) : base(capacity, poolName, onlendObjectOut, onRecycleObject)
        {
            poolCache = new Cache<StageType, ObjectTypePool>(cacheWeedOutStrategy, capacity, OnWeedOut);
            _poolCache = poolCache as Cache<StageType, ObjectTypePool>;
            foreach (StageType item in Enum.GetValues(typeof(StageType)))
            {
                nameMap.Add(item.ToString(), item);
            }
        }

        public StageObjectPool(PoolInfo poolInfo, Action<bool> onlendObjectOut = null, Action<bool> onRecycleObject = null) : base(poolInfo, onlendObjectOut, onRecycleObject)
        {
            if (poolInfo != null)
            {
                foreach (StageType item in Enum.GetValues(typeof(StageType)))
                {
                    nameMap.Add(item.ToString(), item);
                }

                if (poolInfo.poolType == PoolType.StageType)
                {
                    poolCache = new Cache<StageType, ObjectTypePool>(poolInfo.cacheWeedOutStrategy, poolInfo.capacity, OnWeedOut);
                    _poolCache = poolCache as Cache<StageType, ObjectTypePool>;

                    //初始化子对象池
                    foreach (var item in poolInfo.subPoolInfo)
                    {
                        var subPool = new ObjectTypePool(item, OnLendObjectOut, OnRecycleObject);
                        _poolCache.Put(nameMap[subPool.poolName], subPool);
                        TotalCapcity += subPool.TotalCapcity;
                    }
                    //使用默认的池子设置
                    for (int i = poolInfo.subPoolInfo.Count; i < poolInfo.subPoolCount; i++)
                    {
                        var subPool = new ObjectTypePool(poolInfo.defaultSubPoolInfo, OnLendObjectOut, OnRecycleObject);
                        _poolCache.Put(nameMap[subPool.poolName], subPool);
                        TotalCapcity += subPool.TotalCapcity;
                    }
                }
            }
        }


        public override int Capacity()
        {
            return poolCache.Capacity();
        }

        public override int Count()
        {
            return poolCache.Count();
        }


        public override GameObject LendObjectOut(string objectName, Transform parent = null, object[] extradata = null)
        {
            GameObject go = null;
            if (string.IsNullOrEmpty(objectName))
                return null;

            

            StageType stageType;//要将阶段类型和对象类型也传进来
            if (Enum.TryParse<StageType>(extradata[0].ToString(), out stageType))
            {
                ObjectType objectType;
                if(Enum.TryParse<ObjectType>(extradata[0].ToString(), out objectType))
                {
                    ObjectTypePool objectTypePool = null;
                    if (_poolCache.Get(stageType, out objectTypePool))
                    {
                        go = objectTypePool.LendObjectOut(objectName, parent,objectType);
                    }
                }
                
            }
            if (go != null)
                lentInstance2StageType[go.GetInstanceID()] = stageType;
            return go;

        }

        public override bool RecycleObject(GameObject go)
        {
            if (go == null)
                return false;

            if (!lentInstance2StageType.ContainsKey(go.GetInstanceID()))
                return false;

            ObjectTypePool pool;
            if (_poolCache.Get(lentInstance2StageType[go.GetInstanceID()], out pool))
            {
                if (pool.RecycleObject(go))
                {
                    lentInstance2StageType.Remove(go.GetInstanceID());
                    return true;
                }
            }
            return false;
        }

        private void OnWeedOut(ObjectTypePool objectTypePool)
        {            
            TotalCount -= objectTypePool.TotalCount;
            CachedCount -= objectTypePool.CachedCount;
            TotalCapcity -= objectTypePool.TotalCapcity;
            objectTypePool.Dispose();
        }

        private void OnLendObjectOut(bool instantiated)
        {
            if (instantiated)
                TotalCount++;
            else
                CachedCount--;
            onlendObjectOut?.Invoke(instantiated);
        }

        private void OnRecycleObject(bool destroyed)
        {
            if (destroyed)
            {
                TotalCount--;
                CachedCount--;
            }
            else
                CachedCount++;
            onRecycleObject?.Invoke(destroyed);
        }
    }
}


【Do you need management class】

 Now there are many types of object pools, just as we need to use object pools to manage many instances, we need an object pool management class to manage many object pools. To review, the object pool of multi-class instances and the object pool of stage instances in this article also manage a series of the same objects.

Guess you like

Origin blog.csdn.net/enternalstar/article/details/125473977