using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using BITKit; using BITKit.Entities; using Microsoft.Extensions.DependencyInjection; using Net.Project.B.WorldNode; using UnityEngine; namespace Net.Project.B.World { public class WorldSeatService : IWorldSeatService,IDisposable { private readonly IEntitiesService _entitiesService; private static readonly ConcurrentDictionary _seatNodes=new(); private static readonly ConcurrentDictionary _seatEntities=new(); public WorldSeatService(IEntitiesService entitiesService) { _entitiesService = entitiesService; _entitiesService.OnAdd += OnAdd; _entitiesService.OnRemove += OnRemove; } public IReadOnlyDictionary SeatNodes => _seatNodes; public IReadOnlyDictionary SeatEntities => _seatEntities; public bool TryGetOccupyingEntity(int id, out UnitySeatNode seatNode, out IEntity entity) { seatNode = null; return _seatEntities.TryGetValue(id, out entity) && _seatNodes.TryGetValue(id, out seatNode); } public static event Action OnSeatOccupied; event Action IWorldSeatService.OnSeatOccupied { add => OnSeatOccupied += value; remove => OnSeatOccupied -= value; } public bool OccupySeat(int seatId, IEntity entity) { if (_seatNodes.TryGetValue(seatId, out var node) is false) return false; if (_seatEntities.TryGetValue(seatId, out var currentEntity)) { _seatEntities[seatId] = entity; OnSeatOccupied?.Invoke(node,currentEntity,entity); return true; } if (!_seatEntities.TryAdd(seatId, entity)) return false; OnSeatOccupied?.Invoke(node,null,entity); _entitiesService.Entities[seatId].ServiceProvider.QueryComponents(out GameObject go); go.SetActive(false); return true; } public bool UnOccupySeat(int seatId, out IEntity entity) { entity = null; if (_seatNodes.TryGetValue(seatId, out var seatNode) is false) return false; if (_seatEntities.TryRemove(seatId, out entity) is false) return false; OnSeatOccupied?.Invoke(seatNode, entity, null); _entitiesService.Entities[seatId].ServiceProvider.QueryComponents(out GameObject go); go.SetActive(true); return true; } private void OnAdd(IEntity obj) { if(obj.ServiceProvider.GetService() is not {} seatNode)return; seatNode.Id = obj.Id; _seatNodes.TryAdd(obj.Id, seatNode); } private void OnRemove(IEntity obj) { if (_seatNodes.TryRemove(obj.Id, out _) is false) return; UnOccupySeat(obj.Id, out _); } public void Dispose() { _entitiesService.OnAdd -= OnAdd; _entitiesService.OnRemove -= OnRemove; } } }