| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765 | using System;using System.Collections.Generic;using System.Reflection;using CombatLibrary.CombatLibrary.CombatCore.Utility;using Fort23.Core;#if !COMBAT_SERVERusing UnityEngine;using Object = UnityEngine.Object;#endifnamespace Fort23.UTool{    public class GameObjectQueue    {        public string poolName        {            get { return _poolName; }        }        private bool _isDis;        private string _poolName;        private string _prefabName;#if !COMBAT_SERVER        /// <summary>        /// 池子的父亲        /// </summary>        private AssetHandle _PoolObjectFather;        public bool isOne;        private readonly List<IGObjectPoolInterface> _usePool = new List<IGObjectPoolInterface>();        private readonly List<IGObjectPoolInterface> _queue = new List<IGObjectPoolInterface>();        private readonly List<IGObjectPoolInterface> _destroyPool = new List<IGObjectPoolInterface>();        private readonly List<IGObjectPoolInterface> _delayHide = new List<IGObjectPoolInterface>();        public int initCopunt;        public void Init(string poolName, string prefabName)        {            _poolName = poolName;            _prefabName = prefabName;        }        public async CTask Enqueue(IGObjectPoolInterface poolInterface, bool isNotAwaitDelay = false)        {            if (poolInterface == null || poolInterface.own == null)            {                return;            }            if (_queue.Contains(poolInterface))            {                return;            }            if (_delayHide.Contains(poolInterface))            {                return;            }            _delayHide.Add(poolInterface);            if (!isNotAwaitDelay)            {                await poolInterface.DelayHide();            }            if (_isDis)            {                return;            }            _delayHide.Remove(poolInterface);            poolInterface.isUse = false;            _usePool.Remove(poolInterface);            if (poolInterface.own != null)            {                poolInterface.DormancyObj();                this._queue.Add(poolInterface);            }        }        public void AddDestroy(IGObjectPoolInterface poolInterface, bool immediately = false)        {            if (poolInterface.own == null)            {                return;            }            if (!_destroyPool.Contains(poolInterface))            {                if (immediately)                {                    poolInterface.DestroyTimer = null;                    GameObjectDestroyPool.Instance.DestroyObject(poolInterface.own);                }                else                {                    TimerComponent.Instance.Remove(poolInterface.DestroyTimer);                    poolInterface.DestroyTimer =                        TimerComponent.Instance.AddTimer(6000, delegate                        {                            _destroyPool.Remove(poolInterface);                            poolInterface.DestroyTimer = null;                            GameObjectDestroyPool.Instance.DestroyObject(poolInterface.own);                        });                    _destroyPool.Add(poolInterface);                }            }        }        public void DormancyPool()        {            List<IGObjectPoolInterface> alliG = new List<IGObjectPoolInterface>();            IGObjectPoolInterface[] all = _usePool.ToArray();            if (all != null)            {                alliG.AddRange(all);            }            for (int i = 0; i < alliG.Count; i++)            {                IGObjectPoolInterface poolInterface = alliG[i];                Enqueue(poolInterface);            }            // _usePool.Clear();        }        public async CTask Preset<T>(Clock clock,bool isUseSynchronous) where T : IGObjectPoolInterface        {            DormancyPool();            for (int i = 0; i < Count; i++)            {                IGObjectPoolInterface poolInterface = _queue[i];                DisposePoolEntity(poolInterface);                poolInterface.Preset();            }            for (int i = 0; i < _usePool.Count; i++)            {                IGObjectPoolInterface poolInterface = _usePool[i];                DisposePoolEntity(poolInterface);                poolInterface.Preset();            }            for (int i = 0; i < _destroyPool.Count; i++)            {                DisposePoolEntity(_destroyPool[i]);            }            _destroyPool.Clear();            T OBJ = await Dequeue<T>(true, clock,isUseSynchronous);            Enqueue(OBJ, true);        }        private async CTask<AssetHandle> LoadAsset(Clock clock,bool isUseSynchronous)        {            if (AssetBundleLoadManager.Instance != null)            {                CTask<AssetHandle> cTask =                    AssetBundleLoadManager.Instance.LoadAssetAsyncTask<GameObject>(_prefabName, clock: clock,isUseSynchronous:isUseSynchronous);                AssetHandle assetHandle = await cTask;                return assetHandle;            }            return null;        }        public T DequeuForSynchronize<T>(GameObject gameObject, bool isActive) where T : IGObjectPoolInterface        {            if (_queue.Count <= 0)            {                return CreateInstance<T>(isActive, gameObject);            }            if (_destroyPool.Count > 0)            {                for (int i = 0; i < _destroyPool.Count; i++)                {                    DisposePoolEntity(_destroyPool[i]);                }                _destroyPool.Clear();            }            for (int i = 0; i < _queue.Count; i++)            {                if (_queue[i].own == null)                {                    _queue.RemoveAt(i);                    i--;                    continue;                }                else                {                    IGObjectPoolInterface objectPoolInterface = this._queue[0];                    _queue.RemoveAt(0);                    UseObject(objectPoolInterface, isActive);                    return (T)objectPoolInterface;                }            }            return CreateInstance<T>(isActive, gameObject);        }        public async CTask<T> Dequeue<T>(bool isActive, Clock clock,bool isUseSynchronous) where T : IGObjectPoolInterface        {            for (int i = 0; i < _queue.Count; i++)            {                if (_queue[i].own == null)                {                    _queue.RemoveAt(i);                    i--;                    continue;                }                else                {                    IGObjectPoolInterface objectPoolInterface = this._queue[i];                    if (objectPoolInterface.own == null)                    {                        continue;                    }                    _queue.RemoveAt(i);                    UseObject(objectPoolInterface, isActive);                    return (T)objectPoolInterface;                }            }            bool isUsePoolObject = false;            if ((_PoolObjectFather == null || _PoolObjectFather.IsNull()) && !string.IsNullOrEmpty(_prefabName))            {                _PoolObjectFather = await LoadAsset(clock,isUseSynchronous);                isUsePoolObject = true;            }            // if (clock != null && clock.isBreak)            // {            //     if (isUsePoolObject)            //     {            //         Debug.LogError("已打断,但是有初始化数据" + _PoolObjectFather);            //     }            //     // return default;            // }            if (_queue.Count <= 0)            {                AssetHandle assetHandle = _PoolObjectFather;                if (!isUsePoolObject)                {                    assetHandle= await _PoolObjectFather.InstantiateSync(isUseSynchronous);                }                // AssetHandle assetHandle = isUsePoolObject ? _PoolObjectFather : _PoolObjectFather;                             return CreateInstance<T>(isActive, assetHandle);            }            if (_destroyPool.Count > 0)            {                for (int i = 0; i < _destroyPool.Count; i++)                {                    DisposePoolEntity(_destroyPool[i]);                }                _destroyPool.Clear();            }            AssetHandle assetHandle2 = _PoolObjectFather;            if (!isUsePoolObject)            {                assetHandle2= await _PoolObjectFather.InstantiateSync(isUseSynchronous);            }            assetHandle2= await assetHandle2.InstantiateSync(isUseSynchronous);            return CreateInstance<T>(isActive, assetHandle2);        }        private T CreateInstance<T>(bool isActive, AssetHandle assetHandle) where T : IGObjectPoolInterface        {            if (assetHandle == null)            {                return default;            }            T poolInerface = Activator.CreateInstance<T>();            GameObject go = assetHandle.AssetObject<GameObject>();            GameObjectEntity objectEntity = go.GetComponent<GameObjectEntity>();            if (objectEntity == null)            {                objectEntity = go.AddComponent<GameObjectEntity>();            }            objectEntity.IgObjectPoolInterface = poolInerface;            objectEntity.OnDestroyCallBack = DestroyEntity;            poolInerface.SetGameObject(go);            poolInerface.poolObjName = _poolName;            poolInerface.AssetHandle = assetHandle;            UseObject(poolInerface, isActive);            initCopunt++;            return poolInerface;        }        private T CreateInstance<T>(bool isActive, GameObject gameObject) where T : IGObjectPoolInterface        {            if (gameObject == null)            {                return default;            }            T poolInerface = Activator.CreateInstance<T>();            GameObject go = GameObject.Instantiate(gameObject);            GameObjectEntity objectEntity = go.GetComponent<GameObjectEntity>();            if (objectEntity == null)            {                objectEntity = go.AddComponent<GameObjectEntity>();            }            objectEntity.IgObjectPoolInterface = poolInerface;            objectEntity.OnDestroyCallBack = DestroyEntity;            poolInerface.SetGameObject(go);            poolInerface.poolObjName = _poolName;            poolInerface.AssetHandle = null;            UseObject(poolInerface, isActive);            initCopunt++;            return poolInerface;        }        private void DestroyEntity(IGObjectPoolInterface poolInterface)        {            if (poolInterface != null)            {                _queue.Remove(poolInterface);                _usePool.Remove(poolInterface);            }            else            {                return;            }            DisposePoolEntity(poolInterface);            // poolInterface.DormancyObj();            poolInterface.DestroyObj();            poolInterface.AssetHandle?.Release();            if (poolInterface.AssetHandle == _PoolObjectFather)            {                _PoolObjectFather = null;                if (_queue.Count > 0)                {                    _PoolObjectFather = _queue[0].AssetHandle;                }            }            if (_queue.Count <= 0 && _usePool.Count <= 0) //池子已经被释放完,把父物体也释掉            {                GObjectPool.Instance.DestroyPool(poolName);            }        }        private void UseObject(IGObjectPoolInterface objectPoolInterface, bool isActive)        {            _usePool.Add(objectPoolInterface);            DisposePoolEntity(objectPoolInterface);            // TimerComponent.Instance.Remove(objectPoolInterface.DestroyTimer);            // GameObjectDestroyPool.Instance.RomoveDestroyObject(objectPoolInterface.own);            objectPoolInterface.isUse = true;            objectPoolInterface.ResetData();            if (isActive)            {                objectPoolInterface.ActiveObj();            }        }        public int Count => this._queue.Count;        public void Dispose()        {            _isDis = true;            for (int i = 0; i < Count; i++)            {                IGObjectPoolInterface poolInterface = _queue[i];                DisposePoolEntity(poolInterface);                if (poolInterface.own != null)                {                    GameObjectEntity gameObjectEntity = poolInterface.own.GetComponent<GameObjectEntity>();                    if (gameObjectEntity != null)                    {                        gameObjectEntity.IgObjectPoolInterface = null;                        gameObjectEntity.OnDestroyCallBack = null;                    }                    poolInterface.own.SetActive(false);                    poolInterface.DormancyObj();                    poolInterface.DestroyObj();                    poolInterface.AssetHandle?.Release();                    GameObjectDestroyPool.Instance.DestroyObject(poolInterface.own);                }            }            for (int i = 0; i < _delayHide.Count; i++)            {                IGObjectPoolInterface poolInterface = _delayHide[i];                DisposePoolEntity(poolInterface);                if (poolInterface.own != null)                {                    GameObjectEntity gameObjectEntity = poolInterface.own.GetComponent<GameObjectEntity>();                    if (gameObjectEntity != null)                    {                        gameObjectEntity.IgObjectPoolInterface = null;                        gameObjectEntity.OnDestroyCallBack = null;                    }                    poolInterface.own.SetActive(false);                    poolInterface.DormancyObj();                    poolInterface.DestroyObj();                    poolInterface.AssetHandle?.Release();                    GameObjectDestroyPool.Instance.DestroyObject(poolInterface.own);                }            }            for (int i = 0; i < _usePool.Count; i++)            {                IGObjectPoolInterface poolInterface = _usePool[i];                DisposePoolEntity(poolInterface);                if (poolInterface.own != null)                {                    GameObjectEntity gameObjectEntity = poolInterface.own.GetComponent<GameObjectEntity>();                    if (gameObjectEntity != null)                    {                        gameObjectEntity.IgObjectPoolInterface = null;                        gameObjectEntity.OnDestroyCallBack = null;                    }                    poolInterface.own.SetActive(false);                    poolInterface.DormancyObj();                    poolInterface.DestroyObj();                    GameObjectDestroyPool.Instance.DestroyObject(poolInterface.own);                }            }            _PoolObjectFather = null;            _delayHide.Clear();            _queue.Clear();            _destroyPool.Clear();            _usePool.Clear();        }        private void DisposePoolEntity(IGObjectPoolInterface poolInterface)        {            _destroyPool.Remove(poolInterface);            TimerComponent.Instance.Remove(poolInterface.DestroyTimer);            GameObjectDestroyPool.Instance.RomoveDestroyObject(poolInterface.own);            poolInterface.DestroyTimer = null;        }#endif    }    public class GObjectPool    {        private static GObjectPool _instance;        public static GObjectPool Instance        {            get            {                if (_instance == null)                {                    _instance = new GObjectPool();                }                return _instance;            }        }        /// <summary>        /// key是gameObject.name.GetHashCode();        /// </summary>        private readonly Dictionary<string, GameObjectQueue> _dictionary = new Dictionary<string, GameObjectQueue>();        /// <summary>        /// 在ab包里面的东西,都可以通过这个方法获取        /// </summary>        /// <param name="prefabName"></param>        /// <param name="callBack"></param>        /// <param name="clock"></param>        /// <param name="Prestore"></param>        /// <param name="poolName"></param>        /// <typeparam name="T"></typeparam>        /// <returns></returns>        public async CTask<T> FetchAsync<T>(string prefabName, System.Action<T> callBack = null, Clock clock = null,            bool Prestore = false, string poolName = null,bool isUseSynchronous=false) where T : IGObjectPoolInterface        {            if (!prefabName.Contains(".prefab"))            {                prefabName += ".prefab";            }            T poolInerface = await FetchObjectAsync<T>(prefabName, clock, Prestore, poolName,isUseSynchronous:isUseSynchronous);            if (Prestore)            {                return default;            }            if (poolInerface == null)            {                return default;            }            if (clock != null && clock.isBreak)            {                Recycle(poolInerface);                return default;            }            callBack?.Invoke(poolInerface);            return poolInerface;        }        private string GetPoolName<T>(string name)        {            return name + typeof(T);        }#if !COMBAT_SERVER        public T FetchAsyncForGameObject<T>(GameObject gameObject, string poolName        ) where T : IGObjectPoolInterface        {            T poolInerface = Fetch<T>(poolName, gameObject);            if (poolInerface == null)            {                return default;            }            return poolInerface;        }        public T Fetch<T>(string poolName, GameObject gameObject, bool isActive = true) where T : IGObjectPoolInterface        {            string newPoolName = GetPoolName<T>(poolName);            GameObjectQueue gameObjectQueue = null;            if (!this._dictionary.TryGetValue(newPoolName, out gameObjectQueue))            {                gameObjectQueue = EnterPool<T>(newPoolName, null);            }            return gameObjectQueue.DequeuForSynchronize<T>(gameObject, isActive);        }#endif        private async CTask<T> FetchObjectAsync<T>(string prefabName, Clock clock, bool Prestore, string poolName,            bool isActive = true,bool isUseSynchronous=false) where T : IGObjectPoolInterface        {#if !COMBAT_SERVER            try            {                GameObjectQueue gameObjectQueue = null;                poolName = poolName == null ? prefabName : poolName;                poolName = GetPoolName<T>(poolName);                // 加一个协程锁,让同时加载资源的时候lock住                using (await CoroutineLockComponent.Instance.Wait(poolName,20000))                {                    if (clock != null && clock.isBreak)                    {                        return default;                    }                    if (this._dictionary.TryGetValue(poolName, out gameObjectQueue))                    {                        if (Prestore)                        {                            await gameObjectQueue.Preset<T>(clock,isUseSynchronous);                            return default;                        }                        return await gameObjectQueue.Dequeue<T>(isActive, clock,isUseSynchronous);                    }                    if (!this._dictionary.TryGetValue(poolName, out gameObjectQueue))                    {                        gameObjectQueue = EnterPool<T>(poolName, prefabName);                    }                    if (gameObjectQueue == null)                    {                        return default;                    }                    if (Prestore)                    {                        await gameObjectQueue.Preset<T>(clock,isUseSynchronous);                        return default;                    }                    return await gameObjectQueue.Dequeue<T>(isActive, clock,isUseSynchronous);                }            }            catch (Exception e)            {                LogTool.Exception(e);                return default;            }#else            return default;#endif        }#if !COMBAT_SERVER        private Transform _parent;        private GameObjectQueue EnterPool<T>(string poolName, string prefabName) where T : IGObjectPoolInterface        {            if (_parent == null)            {                _parent = new GameObject().transform;                _parent.gameObject.name = "Pool";            }            GameObjectQueue queue = new GameObjectQueue();            queue.Init(poolName, prefabName);            _dictionary.Add(poolName, queue);            return queue;        }#endif        public void Recycle(IGObjectPoolInterface poolInterface)        {            if (poolInterface == null)            {                return;            }#if !COMBAT_SERVER            GameObjectQueue queue;            if (!this._dictionary.TryGetValue(poolInterface.poolObjName, out queue))            {                LogTool.Error("不再池子之中 " + poolInterface.poolObjName);                return;            }            queue.Enqueue(poolInterface);#endif        }        public async CTask Recycle(IGObjectPoolInterface poolInterface, bool isNotAwaitDelay)        {            if (poolInterface == null)            {                return;            }#if !COMBAT_SERVER            GameObjectQueue queue;            if (!this._dictionary.TryGetValue(poolInterface.poolObjName, out queue))            {                LogTool.Error("不再池子之中 " + poolInterface.poolObjName);                return;            }            await queue.Enqueue(poolInterface, isNotAwaitDelay);#endif        }        public void RecycleForDestroy(IGObjectPoolInterface poolInterface, bool immediately = false)        {            if (poolInterface == null)            {                return;            }#if !COMBAT_SERVER            GameObjectQueue queue;            if (!this._dictionary.TryGetValue(poolInterface.poolObjName, out queue))            {                LogTool.Error("不再池子之中 " + poolInterface.poolObjName);                return;            }            queue.Enqueue(poolInterface);            queue.AddDestroy(poolInterface, immediately);#endif        }        public void DestroyPool(string poolObjName)        {#if !COMBAT_SERVER            GameObjectQueue queue;            if (!this._dictionary.TryGetValue(poolObjName, out queue))            {                // LogTool.Warning("没有这个池子 " + poolObjName);                return;            }            _dictionary.Remove(poolObjName);            queue.Dispose();#endif        }        /// <summary>        /// 休眠一个池子        /// </summary>        /// <param name="poolName"></param>        public void DormancyPool<T>(string poolName)        {#if !COMBAT_SERVER            GameObjectQueue queue;            if (!this._dictionary.TryGetValue(poolName, out queue))            {                string poolObjName = GetPoolName<T>(poolName);                if (!this._dictionary.TryGetValue(poolObjName, out queue))                {                    // LogTool.Warning("没有这个池子 " + poolObjName);                    return;                }            }            queue?.DormancyPool();#endif        }        /// <summary>        /// 清除所有池子        /// </summary>        public void Clear()        {            Dispose();        }        /// <summary>        /// 清除所有池子        /// </summary>        public void Dispose()        {#if !COMBAT_SERVER            foreach (KeyValuePair<string, GameObjectQueue> kv in this._dictionary)            {                kv.Value.Dispose();            }            this._dictionary.Clear();            _instance = null;#endif        }    }}
 |