using System.Collections.Generic; using GameFramework.ObjectPool; using GeometryTD.PoolObjectBase; using UnityEngine; using UnityEngine.Serialization; using UnityGameFramework.Runtime; namespace GeometryTD.UI { public class CompArea : MonoBehaviour { [FormerlySerializedAs("m_Content")] [SerializeField] private Transform _content; [FormerlySerializedAs("m_ItemTemplate")] [SerializeField] private RepoItem _itemTemplate; [SerializeField] private TowerRepoItem _towerItemTemplate; [FormerlySerializedAs("m_InstancePoolCapacity")] [SerializeField] private int _instancePoolCapacity = 64; private readonly List _activeComponentItems = new List(); private readonly List _activeTowerItems = new List(); private readonly Dictionary _componentItemMap = new Dictionary(); private readonly Dictionary _towerItemMap = new Dictionary(); private IObjectPool _componentItemPool; private IObjectPool _towerItemPool; private string _componentPoolName; private string _towerPoolName; public void OnInit(CompAreaContext context) { if (context == null) { OnReset(); return; } EnsurePool(); OnReset(); if (context.ComponentItems != null) { foreach (RepoItemContext itemContext in context.ComponentItems) { RepoItem item = CreateOrSpawnComponentItem(); if (item == null) { continue; } item.gameObject.SetActive(true); item.OnInit(itemContext); _activeComponentItems.Add(item); _componentItemMap[itemContext.InstanceId] = item; } } if (context.TowerItems != null) { foreach (TowerRepoItemContext itemContext in context.TowerItems) { TowerRepoItem item = CreateOrSpawnTowerItem(); if (item == null) { continue; } item.gameObject.SetActive(true); item.OnInit(itemContext); _activeTowerItems.Add(item); _towerItemMap[itemContext.InstanceId] = item; } } } public void OnReset() { for (int i = _activeComponentItems.Count - 1; i >= 0; i--) { RepoItem item = _activeComponentItems[i]; if (item == null) { continue; } item.OnReset(); item.gameObject.SetActive(false); _componentItemPool?.Unspawn(item); } for (int i = _activeTowerItems.Count - 1; i >= 0; i--) { TowerRepoItem item = _activeTowerItems[i]; if (item == null) { continue; } item.OnReset(); item.gameObject.SetActive(false); _towerItemPool?.Unspawn(item); } _activeComponentItems.Clear(); _activeTowerItems.Clear(); _componentItemMap.Clear(); _towerItemMap.Clear(); } private void OnDestroy() { OnReset(); _componentItemPool?.ReleaseAllUnused(); _towerItemPool?.ReleaseAllUnused(); } private void EnsurePool() { if (_componentItemPool == null) { _componentPoolName = $"RepoItemPool_{GetInstanceID()}"; _componentItemPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool(_componentPoolName, _instancePoolCapacity); } if (_towerItemPool == null) { _towerPoolName = $"TowerRepoItemPool_{GetInstanceID()}"; _towerItemPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool(_towerPoolName, _instancePoolCapacity); } } private RepoItem CreateOrSpawnComponentItem() { if (_componentItemPool == null) { return null; } RepoItemObject itemObject = _componentItemPool.Spawn(); RepoItem item = itemObject != null ? (RepoItem)itemObject.Target : null; if (item == null) { if (_itemTemplate == null) { Log.Warning("CompArea requires a component item template."); return null; } item = Instantiate(_itemTemplate); _componentItemPool.Register(RepoItemObject.Create(item), true); } if (_content != null) { item.transform.SetParent(_content, false); } return item; } private TowerRepoItem CreateOrSpawnTowerItem() { if (_towerItemPool == null) { return null; } TowerRepoItemObject itemObject = _towerItemPool.Spawn(); TowerRepoItem item = itemObject != null ? (TowerRepoItem)itemObject.Target : null; if (item == null) { if (_towerItemTemplate == null) { Log.Warning("CompArea requires a tower item template."); return null; } item = Instantiate(_towerItemTemplate); _towerItemPool.Register(TowerRepoItemObject.Create(item), true); } if (_content != null) { item.transform.SetParent(_content, false); } return item; } public void SetItemSelected(long itemId, bool isSelected) { if (_componentItemMap.TryGetValue(itemId, out RepoItem componentItem)) { componentItem.SetSelected(isSelected); } if (_towerItemMap.TryGetValue(itemId, out TowerRepoItem towerItem)) { towerItem.SetSelected(isSelected); } } } }