ThreatSourceLibaray/ThreatSource.Tests/src/Simulation/TestSimulationAdapter.cs

252 lines
8.2 KiB
C#

using System;
using System.Collections.Generic;
using ThreatSource.Simulation;
using ThreatSource.Utils;
namespace ThreatSource.Tests.Simulation
{
/// <summary>
/// 用于测试的仿真环境适配器
/// </summary>
public class TestSimulationAdapter : ISimulationAdapter
{
private readonly Dictionary<string, object> _testEntities = [];
private readonly List<SimulationEvent> _receivedEvents = [];
private readonly List<SimulationEvent> _publishedEvents = [];
private ISimulationManager? _simulationManager;
// 存储实体状态的字典
private Dictionary<string, object> _entityStates = new();
// 存储环境数据的字典
private Dictionary<string, SimulationEnvironmentData> _environmentData = new();
// 当前仿真时间
private double _currentTime = 0;
private readonly object _eventLock = new object();
// 添加事件声明
public event EventHandler<SimulationEvent>? EventPublished;
/// <summary>
/// 构造函数,初始化测试适配器
/// </summary>
/// <param name="simulationManager">仿真管理器</param>
public TestSimulationAdapter(ISimulationManager simulationManager)
{
_simulationManager = simulationManager ?? throw new ArgumentNullException(nameof(simulationManager));
}
/// <summary>
/// 获取实体
/// </summary>
/// <param name="id">实体ID</param>
/// <returns>实体对象或null</returns>
public object? GetEntity(string id)
{
return _testEntities.TryGetValue(id, out var entity) ? entity : null;
}
/// <summary>
/// 发布事件到外部仿真
/// </summary>
/// <typeparam name="T">事件类型</typeparam>
/// <param name="evt">事件对象</param>
public void PublishToExternalSimulation<T>(T evt)
{
ArgumentNullException.ThrowIfNull(evt);
if (evt is not SimulationEvent simEvent)
{
throw new ArgumentException("事件必须继承自SimulationEvent", nameof(evt));
}
lock (_eventLock)
{
simEvent.Timestamp = _currentTime; // 使用仿真时间作为时间戳
_publishedEvents.Add(simEvent);
// 触发事件
EventPublished?.Invoke(this, simEvent);
}
}
/// <summary>
/// 接收来自外部仿真的事件
/// </summary>
/// <typeparam name="T">事件类型</typeparam>
/// <param name="evt">事件对象</param>
public void ReceiveFromExternalSimulation<T>(T evt)
{
ArgumentNullException.ThrowIfNull(evt);
if (evt is not SimulationEvent simEvent)
{
throw new ArgumentException("事件必须继承自SimulationEvent", nameof(evt));
}
lock (_eventLock)
{
simEvent.Timestamp = _currentTime; // 使用仿真时间作为时间戳
_receivedEvents.Add(simEvent);
_simulationManager?.PublishEvent(evt);
}
}
/// <summary>
/// 添加测试实体
/// </summary>
/// <param name="id">实体ID</param>
/// <param name="entity">实体对象</param>
public void AddTestEntity(string id, object entity)
{
ArgumentNullException.ThrowIfNull(entity);
_testEntities[id] = entity;
// 初始化实体状态
_entityStates[id] = new MockSimulationElement(id);
}
/// <summary>
/// 清除测试实体
/// </summary>
public void ClearTestEntities()
{
_testEntities.Clear();
_entityStates.Clear();
}
/// <summary>
/// 获取已发布的事件
/// </summary>
/// <returns>已发布的事件列表</returns>
public IReadOnlyList<SimulationEvent> GetPublishedEvents()
{
lock (_eventLock)
{
return _publishedEvents.AsReadOnly();
}
}
/// <summary>
/// 获取指定类型的已发布事件
/// </summary>
/// <typeparam name="T">事件类型</typeparam>
/// <returns>指定类型的已发布事件列表</returns>
public List<T> GetPublishedEvents<T>() where T : SimulationEvent
{
lock (_eventLock)
{
return _publishedEvents.OfType<T>().ToList();
}
}
/// <summary>
/// 获取已接收的事件
/// </summary>
/// <returns>已接收的事件列表</returns>
public IReadOnlyList<SimulationEvent> GetReceivedEvents()
{
lock (_eventLock)
{
return _receivedEvents.AsReadOnly();
}
}
/// <summary>
/// 清除事件
/// </summary>
public void ClearEvents()
{
lock (_eventLock)
{
_publishedEvents.Clear();
_receivedEvents.Clear();
}
}
/// <summary>
/// 获取实体状态
/// </summary>
/// <param name="entityId">实体ID</param>
/// <returns>实体状态对象</returns>
public object? GetEntityState(string entityId)
{
return _entityStates.TryGetValue(entityId, out var state) ? state : null;
}
/// <summary>
/// 设置实体环境数据
/// </summary>
/// <param name="entityId">实体ID</param>
/// <param name="data">环境数据</param>
public void SetEntityEnvironment(string entityId, SimulationEnvironmentData data)
{
ArgumentNullException.ThrowIfNull(data);
_environmentData[entityId] = data;
}
/// <summary>
/// 获取实体环境数据
/// </summary>
/// <param name="entityId">实体ID</param>
/// <returns>环境数据对象</returns>
public SimulationEnvironmentData? GetEntityEnvironment(string entityId)
{
return _environmentData.TryGetValue(entityId, out var data) ? data : null;
}
/// <summary>
/// 同步仿真时间
/// </summary>
/// <param name="time">时间</param>
public void SynchronizeTime(double time)
{
_currentTime = time;
// 更新所有实体状态
foreach (var entity in _testEntities.Values.OfType<SimulationElement>())
{
entity.Update(time - _currentTime);
}
}
/// <summary>
/// 获取当前仿真时间
/// </summary>
/// <returns>当前仿真时间</returns>
public double GetCurrentTime()
{
return _currentTime;
}
/// <summary>
/// 验证是否接收到特定类型的事件
/// </summary>
/// <typeparam name="T">事件类型</typeparam>
/// <param name="predicate">验证条件</param>
/// <returns>是否接收到符合条件的事件</returns>
public bool HasReceivedEvent<T>(Predicate<T> predicate) where T : SimulationEvent
{
return _receivedEvents.OfType<T>().Any(evt => predicate(evt));
}
/// <summary>
/// 验证是否发布了特定类型的事件
/// </summary>
/// <typeparam name="T">事件类型</typeparam>
/// <param name="predicate">验证条件</param>
/// <returns>是否发布了符合条件的事件</returns>
public bool HasPublishedEvent<T>(Predicate<T> predicate) where T : SimulationEvent
{
return _publishedEvents.OfType<T>().Any(evt => predicate(evt));
}
}
/// <summary>
/// 用于测试的模拟仿真元素
/// </summary>
internal class MockSimulationElement : SimulationElement
{
public MockSimulationElement(string id)
: base(id, new Vector3D(0, 0, 0), new Orientation(), 0, null!)
{
}
public override void Update(double deltaTime)
{
}
}
}