104 lines
3.9 KiB
C#
104 lines
3.9 KiB
C#
using UniRx;
|
|
using System;
|
|
|
|
namespace SLSFramework.General
|
|
{
|
|
public enum ConditionFailedAction
|
|
{
|
|
Discard,
|
|
Wait
|
|
}
|
|
|
|
/*
|
|
public interface ICommand
|
|
{
|
|
/// <summary>
|
|
/// 执行指令的核心逻辑。
|
|
/// </summary>
|
|
/// <param name="context">包含了所有执行所需信息的上下文对象。</param>
|
|
/// <returns>一个代表指令完成的信号。</returns>
|
|
IObservable<Unit> Execute(CommandContext context);
|
|
|
|
void ForceComplete();
|
|
}
|
|
*/
|
|
|
|
public abstract class CommandBase
|
|
{
|
|
public bool insertAtFirst = false;
|
|
public CommandContext selfContext;
|
|
|
|
protected readonly Subject<Unit> forceCompleteSubject = new Subject<Unit>();
|
|
|
|
public void ForceComplete() => forceCompleteSubject.OnNext(Unit.Default);
|
|
|
|
// 子类必须实现这个方法,定义指令的核心行为
|
|
protected abstract IObservable<Unit> OnExecute(CommandContext outerContext);
|
|
|
|
protected virtual Func<CommandContext, bool> InnerCondition => (ctx) => true; // 默认条件为总是 true
|
|
|
|
// 子类通过重写这个 Func 来定义自己的执行条件
|
|
protected virtual Func<CommandContext, bool> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Execute 的公共入口。
|
|
/// 它封装了条件判断、等待、或舍弃的复杂逻辑。
|
|
/// 子类不应该重写此方法,而应该实现 OnExecute。
|
|
/// </summary>
|
|
public IObservable<Unit> 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<Unit> CreateAsyncOperation(Func<IObservable<Unit>> operationFactory)
|
|
{
|
|
return operationFactory().TakeUntil(forceCompleteSubject);
|
|
}
|
|
}
|
|
} |