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

195 lines
5.4 KiB
C#

using System.Collections.Generic;
using GameFramework.ObjectPool;
using GeometryTD.CustomEvent;
using GeometryTD.Definition;
using GeometryTD.PoolObjectBase;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class ParticipantArea : MonoBehaviour, IDropHandler
{
[SerializeField] private Transform _content;
[SerializeField] private TowerRepoItem _towerItemTemplate;
[SerializeField] private int _instancePoolCapacity = 8;
private bool _isInteractionEnabled = true;
private readonly List<TowerRepoItem> _activeItems = new List<TowerRepoItem>();
private readonly HashSet<long> _boundItemIds = new HashSet<long>();
private IObjectPool<TowerRepoItemObject> _itemPool;
private string _poolName;
private int _maxCount = 4;
public void OnInit(ParticipantAreaContext context)
{
OnReset();
EnsurePool();
_maxCount = Mathf.Max(1, context != null ? context.MaxCount : 4);
if (context?.TowerItems == null || context.TowerItems.Length <= 0)
{
return;
}
for (int i = 0; i < context.TowerItems.Length; i++)
{
TowerRepoItemContext itemContext = context.TowerItems[i];
if (itemContext == null || itemContext.InstanceId <= 0)
{
continue;
}
TowerRepoItem item = CreateOrSpawnItem();
if (item == null)
{
continue;
}
item.gameObject.SetActive(true);
item.OnInit(itemContext);
_activeItems.Add(item);
_boundItemIds.Add(itemContext.InstanceId);
}
}
public void OnReset()
{
for (int i = _activeItems.Count - 1; i >= 0; i--)
{
TowerRepoItem item = _activeItems[i];
if (item == null)
{
continue;
}
item.OnReset();
item.gameObject.SetActive(false);
_itemPool?.Unspawn(item);
}
_activeItems.Clear();
_boundItemIds.Clear();
_maxCount = 4;
}
private void OnDestroy()
{
OnReset();
_itemPool?.ReleaseAllUnused();
}
public bool CanAssign(IRepoDragItemView dragItem)
{
if (!_isInteractionEnabled)
{
return false;
}
if (dragItem == null || dragItem.InstanceId <= 0)
{
return false;
}
if (dragItem.ComponentSlotType != TowerCompSlotType.None)
{
return false;
}
if (_boundItemIds.Contains(dragItem.InstanceId))
{
return false;
}
if (_boundItemIds.Count >= _maxCount)
{
return false;
}
return true;
}
public void OnDrop(PointerEventData eventData)
{
if (!_isInteractionEnabled)
{
return;
}
if (eventData == null)
{
return;
}
GameObject pointerDrag = eventData.pointerDrag;
if (pointerDrag == null)
{
return;
}
IRepoDragItemView dragItem = pointerDrag.GetComponent<IRepoDragItemView>() ??
pointerDrag.GetComponentInParent<IRepoDragItemView>();
if (dragItem == null)
{
return;
}
bool assigned = CanAssign(dragItem);
dragItem.SetDropResult(assigned);
if (!assigned)
{
return;
}
GameEntry.Event.Fire(this, RepoParticipantAssignRequestedEventArgs.Create(dragItem.InstanceId));
}
public void SetInteractionEnabled(bool enabled)
{
_isInteractionEnabled = enabled;
}
private void EnsurePool()
{
if (_itemPool != null)
{
return;
}
_poolName = $"ParticipantTowerRepoItemPool_{GetInstanceID()}";
_itemPool =
GameEntry.ObjectPool.CreateSingleSpawnObjectPool<TowerRepoItemObject>(_poolName, _instancePoolCapacity);
}
private TowerRepoItem CreateOrSpawnItem()
{
if (_itemPool == null)
{
return null;
}
TowerRepoItemObject itemObject = _itemPool.Spawn();
TowerRepoItem item = itemObject != null ? (TowerRepoItem)itemObject.Target : null;
if (item == null)
{
if (_towerItemTemplate == null)
{
Log.Warning("ParticipantArea requires a tower item template.");
return null;
}
item = Instantiate(_towerItemTemplate);
_itemPool.Register(TowerRepoItemObject.Create(item), true);
}
if (_content != null)
{
item.transform.SetParent(_content, false);
}
return item;
}
}
}