using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using BITKit; using BITKit.Entities; using UnityEngine; namespace Net.Project.B.Mark { public class UnityMarkService:IMarkService,IDisposable { private HashSet Marking { get; }= new(); private readonly IEntitiesService _entitiesService; private readonly ITicker _ticker; private readonly ConcurrentDictionary _marks = new(); private readonly HashSet _addHash = new(); private readonly HashSet _removeHash = new(); private readonly HashSet _swapHash = new(); public UnityMarkService(IEntitiesService entitiesService, ITicker ticker) { _entitiesService = entitiesService; _ticker = ticker; ticker.Add(OnTick); } private void OnTick(float obj) { _swapHash.Clear(); _swapHash.UnionWith(_addHash); _swapHash.ExceptWith(_removeHash); foreach (var id in _swapHash) { if(Marking.Add(id) is false)continue; if(_entitiesService.TryGetEntity(id,out var entity) is false)continue; if (entity.ServiceProvider.QueryComponents(out var markComponent)) { _marks[id] = markComponent; } OnMark?.Invoke(id,true); } foreach (var id in _removeHash) { if(Marking.Remove(id) is false)continue; OnMark?.Invoke(id,false); _marks.TryRemove(id, out _); } _addHash.Clear(); _removeHash.Clear(); foreach (var id in Marking) { if (_entitiesService.TryGetEntity(id, out var entity) is false) { _removeHash.Add(id); continue; } if (!entity.ServiceProvider.QueryComponents(out Transform transform) || !transform) _removeHash.Add(id); } } public void Mark(int id) { _addHash.Add(id); } public void CancelMark(int id) { _removeHash.Add(id); } public event Action OnMark; public HashSet InMarking => Marking; public void Dispose() { _ticker.Remove(OnTick); } } }