using UniRx;
using System;
namespace SoulliesFramework.General
{
public enum ConditionFailedAction
{
Discard,
Wait
}
public interface ICommand
{
///
/// 执行指令的核心逻辑。
///
/// 包含了所有执行所需信息的上下文对象。
/// 一个代表指令完成的信号。
IObservable Execute(CommandContext context);
void ForceComplete();
}
public abstract class CommandBase : ICommand
{
protected readonly Subject forceCompleteSubject = new Subject();
public void ForceComplete() => forceCompleteSubject.OnNext(Unit.Default);
// 子类必须实现这个方法,定义指令的核心行为
protected abstract IObservable OnExecute(CommandContext context);
// 子类通过重写这个 Func 来定义自己的执行条件
protected virtual Func Condition => (ctx) => true; // 默认条件为总是 true
// 子类定义条件失败时的处理方式
protected virtual ConditionFailedAction OnConditionFailed => ConditionFailedAction.Discard;
///
/// Execute 的公共入口。
/// 它封装了条件判断、等待、或舍弃的复杂逻辑。
/// 子类不应该重写此方法,而应该实现 OnExecute。
///
public IObservable Execute(CommandContext context)
{
// 检查初始条件
if (Condition(context))
{
// 条件满足,直接执行
return CreateAsyncOperation(() => OnExecute(context));
}
// 初始条件不满足
if (OnConditionFailed == ConditionFailedAction.Discard)
{
// 策略为“舍弃”,返回一个立即完成的空操作
return Observable.Return(Unit.Default);
}
else // 策略为“等待”
{
// --- 响应式的等待逻辑 ---
return Observable.Defer(() =>
{
// Defer 用于延迟执行,确保每次重试时都重新检查条件
if (Condition(context)) return CreateAsyncOperation(() => OnExecute(context));
// 如果条件仍不满足,则开始等待游戏状态变化
return CommandQueueManager.Instance.OnStateChanged
// 检查每次状态变化后的条件
.Where(_ => Condition(context))
// 我们只需要条件第一次变为 true 的那个时刻
.First()
// 当条件满足时,切换到真正的执行逻辑
.SelectMany(_ => CreateAsyncOperation(() => OnExecute(context)));
});
}
}
// 包装异步操作,使其可以被强制完成
private IObservable CreateAsyncOperation(Func> operationFactory)
{
return operationFactory().TakeUntil(forceCompleteSubject);
}
}
}