geometry-tower-defense-base/src-ref/UI/Game/View/CompArea.cs

204 lines
6.5 KiB
C#

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<RepoItem> _activeComponentItems = new List<RepoItem>();
private readonly List<TowerRepoItem> _activeTowerItems = new List<TowerRepoItem>();
private readonly Dictionary<long, RepoItem> _componentItemMap = new Dictionary<long, RepoItem>();
private readonly Dictionary<long, TowerRepoItem> _towerItemMap = new Dictionary<long, TowerRepoItem>();
private IObjectPool<RepoItemObject> _componentItemPool;
private IObjectPool<TowerRepoItemObject> _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<RepoItemObject>(_componentPoolName,
_instancePoolCapacity);
}
if (_towerItemPool == null)
{
_towerPoolName = $"TowerRepoItemPool_{GetInstanceID()}";
_towerItemPool =
GameEntry.ObjectPool.CreateSingleSpawnObjectPool<TowerRepoItemObject>(_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);
}
}
}
}