using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class CommonPool<T> where T : Component
{
    public readonly Transform poolRoot;
    public readonly T prefab;
    public readonly UnityAction<T> createAction;
    private readonly Queue<T> _pool;
    private bool _kill;

    public CommonPool(Transform poolRoot, T prefab, UnityAction<T> createAction = null)
    {
        this.poolRoot = poolRoot;
        this.prefab = prefab;
        this.createAction = createAction;
        _pool = new Queue<T>();
    }

    // 回收
    public void PushItem(T item)
    {
        if (!_kill)
        {
            item.gameObject.SetActive(false);
            item.transform.SetParent(poolRoot, false);
            if (prefab != null)
                item.transform.localScale = prefab.transform.localScale;
            // 恢复缩放数值,防止缩放被其他组件修改
            _pool.Enqueue(item);
            OnPushItem(item);
        }
    }

    // 获取
    public T PullItem(Transform parent)
    {
        return PullItem(parent, Quaternion.identity, Vector3.one);
    }

    public T PullItem(Transform parent, Quaternion rotation, Vector3 scale)
    {
        T item = null;
        if (!_kill)
        {
            if (_pool.Count > 0)
            {
                item = _pool.Dequeue();
                item.transform.SetParent(parent, false);
            }
            else
                item = CreateItem(parent);
            // 注:Prefab现在修改为不激活状态了
            item.gameObject.SetActive(true);
            item.transform.rotation = rotation;
            item.transform.localScale = scale;
            OnPullItem(item);
        }

        return item;
    }

    public T CreateItem(Transform parent)
    {
        var item = Object.Instantiate(prefab, parent, false);
        item.gameObject.TrimCloneInName();
        GCGame.Utils.ResetShader(item.gameObject);
        if (createAction != null)
            createAction(item);
        return item;
    }

    public virtual void Kill(bool destroyCache = false)
    {
        _kill = true;
        // 注:特殊处理,Prefab在当前项目是为激活的实例化物体,而不是传统Prefab
//        if (prefab != null)
//            Object.Destroy(prefab.gameObject);
        // 注:实例物体随池根节点或者场景切换摧毁,不需要主动摧毁
        // 不切换场景析构时,需要同时析构缓存物体
        if (destroyCache)
        {
            while (_pool.Count > 0)
            {
                var item = _pool.Dequeue();
                if (item != null)
                    Object.Destroy(item.gameObject);
            }
        }
    }

    protected virtual void OnPullItem(T item)
    {
    }

    protected virtual void OnPushItem(T item)
    {
    }
}