Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions GFramework.Core.Abstractions/events/IEventFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace GFramework.Core.Abstractions.events;

/// <summary>
/// 事件过滤器接口
/// 用于在事件触发前进行条件判断,决定是否允许事件传递给监听器
/// </summary>
/// <typeparam name="T">事件类型</typeparam>
public interface IEventFilter<in T>
{
/// <summary>
/// 判断事件是否应该被过滤(阻止传递)
/// </summary>
/// <param name="eventData">事件数据</param>
/// <returns>如果返回 true,则事件被过滤(不传递给监听器);如果返回 false,则允许传递</returns>
bool ShouldFilter(T eventData);
}
58 changes: 58 additions & 0 deletions GFramework.Core.Abstractions/events/IEventStatistics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace GFramework.Core.Abstractions.events;

/// <summary>
/// 事件统计信息接口
/// 提供事件系统的性能统计数据
/// </summary>
public interface IEventStatistics
{
/// <summary>
/// 获取总事件发布数量
/// </summary>
long TotalPublished { get; }

/// <summary>
/// 获取总事件处理数量(监听器调用次数)
/// </summary>
long TotalHandled { get; }

/// <summary>
/// 获取总事件处理失败数量
/// </summary>
long TotalFailed { get; }

/// <summary>
/// 获取当前活跃的事件类型数量
/// </summary>
int ActiveEventTypes { get; }

/// <summary>
/// 获取当前活跃的监听器总数
/// </summary>
int ActiveListeners { get; }

/// <summary>
/// 获取指定事件类型的发布次数
/// </summary>
/// <param name="eventType">事件类型名称</param>
/// <returns>发布次数</returns>
long GetPublishCount(string eventType);

/// <summary>
/// 获取指定事件类型的监听器数量
/// </summary>
/// <param name="eventType">事件类型名称</param>
/// <returns>监听器数量</returns>
int GetListenerCount(string eventType);

/// <summary>
/// 重置统计数据
/// </summary>
void Reset();

/// <summary>
/// 生成统计报告
/// </summary>
/// <returns>格式化的统计报告字符串</returns>
string GenerateReport();
}
188 changes: 188 additions & 0 deletions GFramework.Core.Tests/events/EventFilterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
using GFramework.Core.events;
using GFramework.Core.events.filters;

namespace GFramework.Core.Tests.events;

/// <summary>
/// 事件过滤器功能测试
/// </summary>
public sealed class EventFilterTests
{
[Test]
public void PredicateFilter_ShouldFilterBasedOnCondition()
{
// Arrange
var eventBus = new EnhancedEventBus();
var receivedEvents = new List<TestEvent>();

eventBus.RegisterFilterable<TestEvent>(e => receivedEvents.Add(e));
eventBus.AddFilter(new PredicateEventFilter<TestEvent>(e => e.Value < 10)); // 过滤 Value < 10 的事件

// Act
eventBus.SendFilterable(new TestEvent { Value = 5, Message = "Filtered" });
eventBus.SendFilterable(new TestEvent { Value = 15, Message = "Passed" });
eventBus.SendFilterable(new TestEvent { Value = 20, Message = "Passed" });

// Assert
Assert.That(receivedEvents, Has.Count.EqualTo(2));
Assert.That(receivedEvents[0].Value, Is.EqualTo(15));
Assert.That(receivedEvents[1].Value, Is.EqualTo(20));
}

[Test]
public void SamplingFilter_ShouldFilterBasedOnSamplingRate()
{
// Arrange
var eventBus = new EnhancedEventBus();
var receivedEvents = new List<TestEvent>();

eventBus.RegisterFilterable<TestEvent>(e => receivedEvents.Add(e));
eventBus.AddFilter(new SamplingEventFilter<TestEvent>(0.5)); // 50% 采样率

// Act
for (var i = 0; i < 100; i++)
{
eventBus.SendFilterable(new TestEvent { Value = i });
}

// Assert - 应该接收到大约 50 个事件
Assert.That(receivedEvents.Count, Is.InRange(45, 55));
}

[Test]
public void SamplingFilter_WithZeroRate_ShouldFilterAllEvents()
{
// Arrange
var eventBus = new EnhancedEventBus();
var receivedEvents = new List<TestEvent>();

eventBus.RegisterFilterable<TestEvent>(e => receivedEvents.Add(e));
eventBus.AddFilter(new SamplingEventFilter<TestEvent>(0.0)); // 0% 采样率

// Act
for (var i = 0; i < 10; i++)
{
eventBus.SendFilterable(new TestEvent { Value = i });
}

// Assert
Assert.That(receivedEvents, Is.Empty);
}

[Test]
public void SamplingFilter_WithFullRate_ShouldPassAllEvents()
{
// Arrange
var eventBus = new EnhancedEventBus();
var receivedEvents = new List<TestEvent>();

eventBus.RegisterFilterable<TestEvent>(e => receivedEvents.Add(e));
eventBus.AddFilter(new SamplingEventFilter<TestEvent>(1.0)); // 100% 采样率

// Act
for (var i = 0; i < 10; i++)
{
eventBus.SendFilterable(new TestEvent { Value = i });
}

// Assert
Assert.That(receivedEvents, Has.Count.EqualTo(10));
}

[Test]
public void MultipleFilters_ShouldApplyAllFilters()
{
// Arrange
var eventBus = new EnhancedEventBus();
var receivedEvents = new List<TestEvent>();

eventBus.RegisterFilterable<TestEvent>(e => receivedEvents.Add(e));
eventBus.AddFilter(new PredicateEventFilter<TestEvent>(e => e.Value < 10)); // 过滤 < 10
eventBus.AddFilter(new PredicateEventFilter<TestEvent>(e => e.Value > 50)); // 过滤 > 50

// Act
for (var i = 0; i < 100; i++)
{
eventBus.SendFilterable(new TestEvent { Value = i });
}

// Assert - 只有 10-50 之间的事件通过
Assert.That(receivedEvents, Has.Count.EqualTo(41)); // 10 到 50 包含边界
Assert.That(receivedEvents.All(e => e.Value >= 10 && e.Value <= 50), Is.True);
}

[Test]
public void RemoveFilter_ShouldStopFiltering()
{
// Arrange
var eventBus = new EnhancedEventBus();
var receivedEvents = new List<TestEvent>();
var filter = new PredicateEventFilter<TestEvent>(e => e.Value < 10);

eventBus.RegisterFilterable<TestEvent>(e => receivedEvents.Add(e));
eventBus.AddFilter(filter);

// Act - 发送事件(应该被过滤)
eventBus.SendFilterable(new TestEvent { Value = 5 });
Assert.That(receivedEvents, Is.Empty);

// 移除过滤器
eventBus.RemoveFilter(filter);

// 再次发送事件(应该通过)
eventBus.SendFilterable(new TestEvent { Value = 5 });

// Assert
Assert.That(receivedEvents, Has.Count.EqualTo(1));
}

[Test]
public void ClearFilters_ShouldRemoveAllFilters()
{
// Arrange
var eventBus = new EnhancedEventBus();
var receivedEvents = new List<TestEvent>();

eventBus.RegisterFilterable<TestEvent>(e => receivedEvents.Add(e));
eventBus.AddFilter(new PredicateEventFilter<TestEvent>(e => e.Value < 10));
eventBus.AddFilter(new PredicateEventFilter<TestEvent>(e => e.Value > 50));

// Act - 发送事件(应该被过滤)
eventBus.SendFilterable(new TestEvent { Value = 5 });
Assert.That(receivedEvents, Is.Empty);

// 清除所有过滤器
eventBus.ClearFilters<TestEvent>();

// 再次发送事件(应该通过)
eventBus.SendFilterable(new TestEvent { Value = 5 });

// Assert
Assert.That(receivedEvents, Has.Count.EqualTo(1));
}

[Test]
public void SamplingFilter_InvalidRate_ShouldThrowException()
{
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() =>
new SamplingEventFilter<TestEvent>(-0.1));

Assert.Throws<ArgumentOutOfRangeException>(() =>
new SamplingEventFilter<TestEvent>(1.1));
}

[Test]
public void PredicateFilter_NullPredicate_ShouldThrowException()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() =>
new PredicateEventFilter<TestEvent>(null!));
}

private sealed class TestEvent
{
public int Value { get; init; }
public string Message { get; init; } = string.Empty;
}
}
Loading
Loading