Files
Continentis/Assets/Scripts/ScriptExtensions/CommandQueue/CommandGroup.cs

65 lines
2.2 KiB
C#
Raw Normal View History

2025-10-03 00:02:43 -04:00
using System;
using System.Collections.Generic;
using System.Linq;
using UniRx;
using UnityEngine;
2025-10-23 00:49:44 -04:00
namespace SLSFramework.General
2025-10-03 00:02:43 -04:00
{
public enum ExecutionMode { Sequential, Parallel }
public class CommandGroup : CommandBase
{
2025-10-23 00:49:44 -04:00
public readonly List<CommandBase> commands = new List<CommandBase>();
public readonly ExecutionMode mode;
2025-10-03 00:02:43 -04:00
2025-10-23 00:49:44 -04:00
public CommandGroup(ExecutionMode mode, params CommandBase[] commands)
2025-10-03 00:02:43 -04:00
{
this.mode = mode;
this.commands.AddRange(commands);
}
2025-10-23 00:49:44 -04:00
public override CommandBase Clone()
{
CommandGroup newGroup = new CommandGroup(mode);
foreach (var cmd in commands)
{
newGroup.AddCommand(cmd.Clone());
}
return newGroup;
}
public CommandGroup AddCommand(CommandBase command)
2025-10-03 00:02:43 -04:00
{
commands.Add(command);
return this;
}
2025-10-23 00:49:44 -04:00
protected override IObservable<Unit> OnExecute(CommandContext outerContext)
2025-10-03 00:02:43 -04:00
{
// --- 核心修正 ---
// 我们不再直接调用 cmd.Execute(context)。
// 而是创建一个“延迟执行”的 Observable 序列。
// Defer 会将对 Execute 的调用推迟到 Concat/WhenAll 真正订阅它的时候。
var lazyCommandObservables = commands.Select(cmd =>
2025-10-23 00:49:44 -04:00
Observable.Defer(() => cmd.Execute(outerContext))
2025-10-03 00:02:43 -04:00
);
IObservable<Unit> executionFlow;
if (mode == ExecutionMode.Sequential)
{
// Concat 现在会按顺序地、一个一个地订阅 lazyCommandObservables 中的 Defer 对象。
// 每订阅一个,对应的 cmd.Execute() 才会被真正调用。
executionFlow = lazyCommandObservables.Concat();
}
else
{
// WhenAll 同样能很好地处理延迟的 Observable 序列。
executionFlow = Observable.WhenAll(lazyCommandObservables).AsUnitObservable();
}
return executionFlow;
// 注意:基类中的 TakeUntil(forceCompleteSubject) 会自动应用到这里返回的流上,所以无需重复添加。
}
}
}