Files
Workspace/Assets/Demos/Demo2/Runtime/Demo2MachineProxyPool.cs
T
2026-08-18 02:03:34 +08:00

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;
}
}
}