73 lines
3.2 KiB
C#
73 lines
3.2 KiB
C#
#nullable enable
|
|
|
|
using System.Collections.Generic;
|
|
using Demo2.Domain;
|
|
using Demo2.ECS;
|
|
using Unity.Collections;
|
|
using Unity.Entities;
|
|
using UnityEngine;
|
|
|
|
namespace Demo2.Runtime
|
|
{
|
|
public sealed class Demo2MachineProxyPool : MonoBehaviour
|
|
{
|
|
[SerializeField] private Sprite[] machineSprites = new Sprite[8];
|
|
private readonly Dictionary<int, SpriteRenderer> _active = new();
|
|
private readonly Stack<SpriteRenderer> _pool = new();
|
|
private readonly HashSet<int> _seen = new();
|
|
private readonly List<int> _stale = new();
|
|
|
|
public void SetSprites(Sprite[] sprites) => machineSprites = sprites;
|
|
|
|
public void Refresh(Demo2EcsWorld? world)
|
|
{
|
|
if (world == null) { ReleaseAll(); return; }
|
|
var manager = world.EntityManager;
|
|
var query = manager.CreateEntityQuery(typeof(Demo2StableId), typeof(Demo2GridPosition), typeof(Demo2MachineState));
|
|
using var entities = query.ToEntityArray(Allocator.Temp);
|
|
using var ids = query.ToComponentDataArray<Demo2StableId>(Allocator.Temp);
|
|
using var positions = query.ToComponentDataArray<Demo2GridPosition>(Allocator.Temp);
|
|
_seen.Clear();
|
|
for (var i = 0; i < entities.Length; i++)
|
|
{
|
|
var id = ids[i].Value;
|
|
_seen.Add(id);
|
|
if (!_active.TryGetValue(id, out var renderer))
|
|
{
|
|
renderer = Acquire();
|
|
_active[id] = renderer;
|
|
}
|
|
var machine = manager.GetComponentData<Demo2MachineState>(entities[i]);
|
|
renderer.name = $"MachineProxy_{id}_{machine.Kind}";
|
|
renderer.transform.position = new Vector3(positions[i].X + 0.5f, Demo2Protocol.GridHeight - positions[i].Y - 0.5f, 0);
|
|
renderer.transform.rotation = Quaternion.Euler(0, 0, -90f * machine.Rotation);
|
|
renderer.transform.localScale = Vector3.one * 0.92f;
|
|
renderer.sprite = SpriteFor(machine.Kind);
|
|
renderer.color = machine.Faults > 0 ? new Color(1f, 0.52f, 0.42f) : Color.white;
|
|
}
|
|
_stale.Clear();
|
|
foreach (var pair in _active) if (!_seen.Contains(pair.Key)) _stale.Add(pair.Key);
|
|
foreach (var id in _stale) { Release(_active[id]); _active.Remove(id); }
|
|
}
|
|
|
|
private SpriteRenderer Acquire()
|
|
{
|
|
if (_pool.Count > 0) { var reused = _pool.Pop(); reused.gameObject.SetActive(true); return reused; }
|
|
var go = new GameObject("MachineProxy");
|
|
go.transform.SetParent(transform, false);
|
|
var renderer = go.AddComponent<SpriteRenderer>();
|
|
renderer.sortingOrder = 5;
|
|
return renderer;
|
|
}
|
|
|
|
private void Release(SpriteRenderer renderer) { renderer.gameObject.SetActive(false); _pool.Push(renderer); }
|
|
private void ReleaseAll() { foreach (var renderer in _active.Values) Release(renderer); _active.Clear(); }
|
|
|
|
private Sprite? SpriteFor(Demo2MachineKind kind)
|
|
{
|
|
var index = kind == Demo2MachineKind.NightShiftSmelter ? (int)Demo2MachineKind.Smelter : (int)kind;
|
|
return index >= 0 && index < machineSprites.Length ? machineSprites[index] : null;
|
|
}
|
|
}
|
|
}
|