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