178 lines
4.9 KiB
C#
178 lines
4.9 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 RepoItem _itemTemplate;
|
|
[SerializeField] private int _instancePoolCapacity = 8;
|
|
|
|
private readonly List<RepoItem> _activeItems = new List<RepoItem>();
|
|
private readonly HashSet<long> _boundItemIds = new HashSet<long>();
|
|
private IObjectPool<RepoItemObject> _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?.Items == null || context.Items.Length <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < context.Items.Length; i++)
|
|
{
|
|
RepoItemContext itemContext = context.Items[i];
|
|
if (itemContext == null || itemContext.InstanceId <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
RepoItem 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--)
|
|
{
|
|
RepoItem 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(RepoItemContext itemContext)
|
|
{
|
|
if (itemContext == null || itemContext.InstanceId <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (itemContext.ComponentSlotType != TowerCompSlotType.None)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (_boundItemIds.Contains(itemContext.InstanceId))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (_boundItemIds.Count >= _maxCount)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void OnDrop(PointerEventData eventData)
|
|
{
|
|
if (eventData == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameObject pointerDrag = eventData.pointerDrag;
|
|
if (pointerDrag == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RepoItem repoItem = pointerDrag.GetComponent<RepoItem>() ?? pointerDrag.GetComponentInParent<RepoItem>();
|
|
if (repoItem == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RepoItemContext itemContext = repoItem.Context;
|
|
bool assigned = CanAssign(itemContext);
|
|
repoItem.SetDropResult(assigned);
|
|
if (!assigned)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameEntry.Event.Fire(this, RepoParticipantAssignRequestedEventArgs.Create(itemContext.InstanceId));
|
|
}
|
|
|
|
private void EnsurePool()
|
|
{
|
|
if (_itemPool != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_poolName = $"ParticipantRepoItemPool_{GetInstanceID()}";
|
|
_itemPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool<RepoItemObject>(_poolName, _instancePoolCapacity);
|
|
}
|
|
|
|
private RepoItem CreateOrSpawnItem()
|
|
{
|
|
if (_itemPool == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
RepoItemObject itemObject = _itemPool.Spawn();
|
|
RepoItem item = itemObject != null ? (RepoItem)itemObject.Target : null;
|
|
if (item == null)
|
|
{
|
|
if (_itemTemplate == null)
|
|
{
|
|
Log.Warning("ParticipantArea requires an item template.");
|
|
return null;
|
|
}
|
|
|
|
item = Instantiate(_itemTemplate);
|
|
_itemPool.Register(RepoItemObject.Create(item), true);
|
|
}
|
|
|
|
if (_content != null)
|
|
{
|
|
item.transform.SetParent(_content, false);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
}
|
|
}
|