Net.Like.Xue.Tokyo/Packages-Local/Com.Project.B.Unity/WorldNodeService/UnityEvacuateService.cs

89 lines
3.4 KiB
C#

using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using BITKit;
using BITKit.Entities;
using Cysharp.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Net.Project.B.Interaction;
using Project.B.Map;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Net.Project.B.WorldNode
{
public class UnityEvacuateService:IDisposable
{
private readonly ILogger<UnityEvacuateService> _logger;
private readonly IGameMapService _gameMapService;
private readonly IEntitiesService _entitiesService;
private readonly IWorldInteractionService _interactionService;
private readonly ConcurrentDictionary<Type, ScriptableEvacuate> _scriptableEvacuates = new();
private CancellationTokenSource _cancellationTokenSource=new();
public UnityEvacuateService(IWorldInteractionService interactionService, IEntitiesService entitiesService, IGameMapService gameMapService, ILogger<UnityEvacuateService> logger)
{
_interactionService = interactionService;
_entitiesService = entitiesService;
_gameMapService = gameMapService;
_logger = logger;
_interactionService.OnInteraction += OnInteraction;
foreach (var x in entitiesService.QueryComponents<ScriptableEvacuate>())
{
_scriptableEvacuates[x.EvacuateType.GetType()] = x;
}
_gameMapService.OnMapChanging += OnMapChanging;
_entitiesService.OnAdd += OnAdd;
}
private void OnAdd(IEntity entity)
{
if(entity.ServiceProvider.QueryComponents(out UnityEvacuateNode evacuateNode) is false)return;
if(_scriptableEvacuates.TryGetValue(evacuateNode.EvacuateType.GetType(),out var scriptableEvacuate) is false)return;
scriptableEvacuate.Initialize(entity);
}
private UniTask OnMapChanging(string arg)
{
if (string.IsNullOrEmpty(arg))
{
_cancellationTokenSource.Cancel();
_cancellationTokenSource = new();
}
return UniTask.CompletedTask;
}
private void OnInteraction(object arg1, IWorldInteractable arg2, WorldInteractionProcess arg3, object arg4)
{
if(arg3 is not (WorldInteractionProcess.Performed or WorldInteractionProcess.System))return;
if(_entitiesService.TryGetEntity(arg2.Id,out var entity) is false)return;
if(entity.ServiceProvider.QueryComponents(out UnityEvacuateNode evacuateNode) is false)return;
if(entity.ServiceProvider.QueryComponents(out GameObject gameObject) is false)return;
Object.Destroy(gameObject);
if (_scriptableEvacuates.TryGetValue(evacuateNode.EvacuateType.GetType(), out var scriptableEvacuate))
{
var instance = Object.Instantiate(scriptableEvacuate);
instance.Invoke(entity,_cancellationTokenSource.Token).Forget();
_logger.LogInformation($"已执行{evacuateNode.EvacuateType.GetType().Name}");
}
else
{
_logger.LogWarning($"未找到{evacuateNode.EvacuateType.GetType().Name}");
}
}
public void Dispose()
{
_cancellationTokenSource?.Dispose();
}
}
}