diff --git a/GFramework.Core/coroutine/extensions/CommandCoroutineExtensions.cs b/GFramework.Core/coroutine/extensions/CommandCoroutineExtensions.cs index 817b8c3..76da41a 100644 --- a/GFramework.Core/coroutine/extensions/CommandCoroutineExtensions.cs +++ b/GFramework.Core/coroutine/extensions/CommandCoroutineExtensions.cs @@ -52,10 +52,18 @@ public static class CommandCoroutineExtensions /// /// 发送 Command 并等待指定 Event /// + /// 命令类型,必须实现 IAsyncCommand 接口 + /// 事件类型 + /// 上下文感知对象 + /// 要执行的命令实例 + /// 事件触发时的回调处理 + /// 等待超时时间(秒),0表示无限等待 + /// 返回协程指令枚举器 public static IEnumerator SendCommandAndWaitEventCoroutine( this IContextAware contextAware, TCommand command, - Action? onEvent = null) + Action? onEvent = null, + float timeout = 0f) where TCommand : IAsyncCommand where TEvent : class { @@ -73,10 +81,26 @@ public static class CommandCoroutineExtensions var task = context.SendCommandAsync(command); yield return task.AsCoroutineInstruction(); - // 等待事件触发 - yield return wait; + // 如果有超时设置,使用超时等待 + if (timeout > 0f) + { + var timeoutWait = new WaitForEventWithTimeout(wait, timeout); + yield return timeoutWait; - // 调用回调 + // 检查是否超时 + if (timeoutWait.IsTimeout) + { + // 超时处理 + throw new TimeoutException($"wait for the event ${typeof(TEvent).Name} timeout."); + } + } + else + { + // 等待事件触发(无超时) + yield return wait; + } + + // 调用事件回调 if (onEvent != null && wait.EventData != null) { onEvent.Invoke(wait.EventData); diff --git a/GFramework.Core/events/EventListenerScope.cs b/GFramework.Core/events/EventListenerScope.cs new file mode 100644 index 0000000..6a7e186 --- /dev/null +++ b/GFramework.Core/events/EventListenerScope.cs @@ -0,0 +1,64 @@ +// 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.events; + +namespace GFramework.Core.events; + +/// +/// 事件监听器作用域,用于监听特定类型的事件并在触发时提供事件数据 +/// +/// 要监听的事件类型 +public sealed class EventListenerScope : IDisposable +{ + private readonly IUnRegister? _unRegister; + private TEvent? _eventData; + private volatile bool _triggered; + + /// + /// 初始化事件监听器作用域的新实例 + /// + /// 事件总线实例,用于注册事件监听器 + public EventListenerScope(IEventBus eventBus) + { + _unRegister = eventBus.Register(OnEventTriggered); + } + + /// + /// 获取接收到的事件数据 + /// + public TEvent? EventData => _eventData; + + /// + /// 获取事件是否已被触发 + /// + public bool IsTriggered => _triggered; + + /// + /// 释放资源,取消事件监听器的注册 + /// + public void Dispose() + { + _unRegister?.UnRegister(); + } + + /// + /// 事件触发时的回调方法,用于存储事件数据并标记已触发状态 + /// + /// 接收到的事件数据 + private void OnEventTriggered(TEvent eventData) + { + _eventData = eventData; + _triggered = true; + } +} \ No newline at end of file