mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
feat(coroutine): 添加Mediator模式与协程集成的扩展方法
- 实现SendCommandCoroutine方法,支持以协程方式发送命令并处理异常 - 实现SendCommandAndWaitEventCoroutine方法,支持发送命令并等待特定事件 - 添加超时控制功能,支持设置等待事件的超时间 - 集成IEventBus和IMediator服务,提供完整的事件驱动协程支持 - 提供异常回调处理机制,增强错误处理能力 - 实现资源清理机制,确保WaitForEvent对象正确释放
This commit is contained in:
parent
82cd2585d5
commit
b196cd40bb
@ -0,0 +1,108 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using GFramework.Core.Abstractions.coroutine;
|
||||
using GFramework.Core.Abstractions.events;
|
||||
using GFramework.Core.Abstractions.rule;
|
||||
using GFramework.Core.coroutine.instructions;
|
||||
using Mediator;
|
||||
|
||||
namespace GFramework.Core.coroutine.extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 提供Mediator模式与协程集成的扩展方法。
|
||||
/// 包含发送命令和等待事件的协程实现。
|
||||
/// </summary>
|
||||
public static class MediatorCoroutineExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 以协程方式发送命令并处理可能的异常。
|
||||
/// </summary>
|
||||
/// <typeparam name="TCommand">命令的类型</typeparam>
|
||||
/// <param name="contextAware">上下文感知对象,用于获取服务</param>
|
||||
/// <param name="command">要发送的命令对象</param>
|
||||
/// <param name="onError">发生异常时的回调处理函数</param>
|
||||
/// <returns>协程枚举器,用于协程执行</returns>
|
||||
public static IEnumerator<IYieldInstruction> SendCommandCoroutine<TCommand>(
|
||||
this IContextAware contextAware,
|
||||
TCommand command,
|
||||
Action<Exception>? onError = null)
|
||||
where TCommand : notnull
|
||||
{
|
||||
var mediator = contextAware
|
||||
.GetContext()
|
||||
.GetService<IMediator>()!;
|
||||
|
||||
var task = mediator.Send(command).AsTask();
|
||||
|
||||
yield return task.AsCoroutineInstruction();
|
||||
|
||||
if (task.IsFaulted)
|
||||
onError?.Invoke(task.Exception!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送命令并等待特定事件的协程实现,支持超时控制。
|
||||
/// </summary>
|
||||
/// <typeparam name="TCommand">命令的类型</typeparam>
|
||||
/// <typeparam name="TEvent">要等待的事件类型</typeparam>
|
||||
/// <param name="contextAware">上下文感知对象,用于获取服务</param>
|
||||
/// <param name="command">要发送的命令对象</param>
|
||||
/// <param name="onEvent">接收到事件时的回调处理函数</param>
|
||||
/// <param name="timeout">超时时间(秒),0表示无超时</param>
|
||||
/// <returns>协程枚举器,用于协程执行</returns>
|
||||
public static IEnumerator<IYieldInstruction> SendCommandAndWaitEventCoroutine<TCommand, TEvent>(
|
||||
this IContextAware contextAware,
|
||||
TCommand command,
|
||||
Action<TEvent>? onEvent = null,
|
||||
float timeout = 0f)
|
||||
where TCommand : notnull
|
||||
where TEvent : class
|
||||
{
|
||||
var context = contextAware.GetContext();
|
||||
var mediator = context.GetService<IMediator>()!;
|
||||
var eventBus = context.GetService<IEventBus>()!;
|
||||
|
||||
WaitForEvent<TEvent>? wait = null;
|
||||
|
||||
try
|
||||
{
|
||||
wait = new WaitForEvent<TEvent>(eventBus);
|
||||
|
||||
var task = mediator.Send(command).AsTask();
|
||||
|
||||
yield return task.AsCoroutineInstruction();
|
||||
|
||||
if (timeout > 0f)
|
||||
{
|
||||
var timeoutWait = new WaitForEventWithTimeout<TEvent>(wait, timeout);
|
||||
yield return timeoutWait;
|
||||
|
||||
if (timeoutWait.IsTimeout)
|
||||
throw new TimeoutException(
|
||||
$"wait for event {typeof(TEvent).Name} timeout.");
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return wait;
|
||||
}
|
||||
|
||||
if (wait.EventData != null)
|
||||
onEvent?.Invoke(wait.EventData);
|
||||
}
|
||||
finally
|
||||
{
|
||||
wait?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user