Files
Net.Like.Xue.Tokyo/Packages-Local/Com.Project.B.Unity/World/WorldSeatService.cs
2025-06-24 23:49:13 +08:00

103 lines
3.3 KiB
C#

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<int, UnitySeatNode> _seatNodes=new();
private static readonly ConcurrentDictionary<int,IEntity> _seatEntities=new();
public WorldSeatService(IEntitiesService entitiesService)
{
_entitiesService = entitiesService;
_entitiesService.OnAdd += OnAdd;
_entitiesService.OnRemove += OnRemove;
}
public IReadOnlyDictionary<int, UnitySeatNode> SeatNodes => _seatNodes;
public IReadOnlyDictionary<int, IEntity> 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<UnitySeatNode, IEntity, IEntity> OnSeatOccupied;
event Action<UnitySeatNode, IEntity, IEntity> 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<UnitySeatNode>() 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;
}
}
}