Files
SoulliesOfficial ac98ec3aef 更新
2026-04-17 12:01:50 -04:00

168 lines
6.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using Continentis.MainGame.Character;
using Cysharp.Threading.Tasks;
namespace SLSUtilities.General
{
/// <summary>
/// 命令静态工厂。
/// Mod 制作者通过此类创建常用命令,无需直接实例化具体命令类。
/// </summary>
public static class Cmd
{
// ── 基础工厂 ─────────────────────────────────────────────────────
/// <summary>创建一条等待指定秒数后完成的命令。</summary>
public static CommandBase Wait(float seconds)
{
return new WaitCommand(seconds);
}
/// <summary>创建一条执行同步 Action 的命令。</summary>
public static CommandBase Do(Action action)
{
return new ActionCommand(action);
}
/// <summary>创建一条执行异步 UniTask 的命令。</summary>
public static CommandBase Do(Func<UniTask> asyncAction)
{
return new AsyncActionCommand(asyncAction);
}
/// <summary>创建一条延迟指定秒数后执行同步 Action 的命令。</summary>
public static CommandBase After(float seconds, Action action)
{
return new ActionCommand(action).SetDelay(seconds);
}
/// <summary>
/// 创建一条"等待外部信号"命令。
/// 调用返回的 <paramref name="signal"/> Action 时,命令立即完成,队列继续执行。
/// 典型用法:等待玩家点击按钮确认。
/// </summary>
/// <param name="signal">外部调用此委托以释放命令。</param>
public static CommandBase WaitForSignal(out Action signal)
{
var tcs = new UniTaskCompletionSource();
signal = () => tcs.TrySetResult();
return new WaitForSignalCommand(tcs);
}
// ── 组合工厂 ─────────────────────────────────────────────────────
/// <summary>创建一个顺序执行的命令组。</summary>
public static CommandGroup Sequential(params CommandBase[] cmds)
{
return new CommandGroup(ExecutionMode.Sequential, cmds);
}
/// <summary>创建一个并行执行的命令组。</summary>
public static CommandGroup Parallel(params CommandBase[] cmds)
{
return new CommandGroup(ExecutionMode.Parallel, cmds);
}
// ── Target 遍历工厂 ───────────────────────────────────────────────
/// <summary>
/// 对 <paramref name="targets"/> 列表中的每个目标调用 <paramref name="factory"/>
/// 将结果按顺序组合为一个 Sequential <see cref="CommandGroup"/>。
/// </summary>
public static CommandGroup ForEachTarget(
List<CharacterBase> targets,
Func<CharacterBase, CommandBase> factory)
{
var group = new CommandGroup(ExecutionMode.Sequential);
foreach (CharacterBase target in targets)
{
CharacterBase captured = target;
group.AddCommand(factory(captured));
}
return group;
}
/// <summary>
/// 对 <paramref name="targets"/> 列表中的每个目标调用 <paramref name="factory"/>
/// 将结果按顺序组合为一个 Sequential <see cref="CommandGroup"/>。
/// </summary>
public static CommandGroup ForEachTarget(
List<CharacterBase> targets,
Func<CharacterBase, CommandGroup> factory)
{
var group = new CommandGroup(ExecutionMode.Sequential);
foreach (CharacterBase target in targets)
{
CharacterBase captured = target;
group.AddCommand(factory(captured));
}
return group;
}
// ── 内部实现类 ────────────────────────────────────────────────────
private sealed class WaitCommand : CommandBase
{
private readonly float seconds;
public WaitCommand(float seconds)
{
this.seconds = seconds;
}
protected override async UniTask ExecuteAsync(CommandContext outerContext)
{
await UniTask.Delay(TimeSpan.FromSeconds(seconds));
}
}
private sealed class ActionCommand : CommandBase
{
private readonly Action action;
public ActionCommand(Action action)
{
this.action = action;
}
protected override UniTask ExecuteAsync(CommandContext outerContext)
{
action?.Invoke();
return UniTask.CompletedTask;
}
}
private sealed class AsyncActionCommand : CommandBase
{
private readonly Func<UniTask> asyncAction;
public AsyncActionCommand(Func<UniTask> asyncAction)
{
this.asyncAction = asyncAction;
}
protected override async UniTask ExecuteAsync(CommandContext outerContext)
{
if (asyncAction != null)
await asyncAction();
}
}
private sealed class WaitForSignalCommand : CommandBase
{
private readonly UniTaskCompletionSource tcs;
public WaitForSignalCommand(UniTaskCompletionSource tcs)
{
this.tcs = tcs;
}
protected override async UniTask ExecuteAsync(CommandContext outerContext)
{
await tcs.Task;
}
}
}
}