refactor(ai): BrainGraph Task4 审查修复——删死字段/Global空目标校验/AiState只读转换
This commit is contained in:
@@ -6,11 +6,15 @@ namespace BaseGames.AI
|
|||||||
/// <summary>一个状态:进入/每帧/退出钩子 + 出边转换列表(按优先级有序,首个命中即转)。</summary>
|
/// <summary>一个状态:进入/每帧/退出钩子 + 出边转换列表(按优先级有序,首个命中即转)。</summary>
|
||||||
public sealed class AiState
|
public sealed class AiState
|
||||||
{
|
{
|
||||||
|
readonly List<Transition> _transitions = new List<Transition>();
|
||||||
|
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public Action<IAiContext> OnEnter { get; internal set; }
|
public Action<IAiContext> OnEnter { get; internal set; }
|
||||||
public Action<IAiContext, float> OnTick { get; internal set; } // (ctx, dt)
|
public Action<IAiContext, float> OnTick { get; internal set; } // (ctx, dt)
|
||||||
public Action<IAiContext> OnExit { get; internal set; }
|
public Action<IAiContext> OnExit { get; internal set; }
|
||||||
public List<Transition> Transitions { get; } = new List<Transition>();
|
public IReadOnlyList<Transition> Transitions => _transitions;
|
||||||
|
|
||||||
|
internal void AddTransition(Transition t) => _transitions.Add(t);
|
||||||
|
|
||||||
public AiState(string name) => Name = name;
|
public AiState(string name) => Name = name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,17 +61,16 @@ namespace BaseGames.AI
|
|||||||
public StateBuilder Tick(Action<IAiContext, float> fn) { _state.OnTick = fn; return this; }
|
public StateBuilder Tick(Action<IAiContext, float> fn) { _state.OnTick = fn; return this; }
|
||||||
public StateBuilder OnExit(Action<IAiContext> fn) { _state.OnExit = fn; return this; }
|
public StateBuilder OnExit(Action<IAiContext> fn) { _state.OnExit = fn; return this; }
|
||||||
|
|
||||||
public TransitionBuilder To(string target) => new TransitionBuilder(_owner, this, _state, target);
|
public TransitionBuilder To(string target) => new TransitionBuilder(this, _state, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class TransitionBuilder
|
public sealed class TransitionBuilder
|
||||||
{
|
{
|
||||||
readonly BrainBuilder _owner;
|
|
||||||
readonly StateBuilder _stateBuilder;
|
readonly StateBuilder _stateBuilder;
|
||||||
readonly AiState _state;
|
readonly AiState _state;
|
||||||
readonly string _target;
|
readonly string _target;
|
||||||
internal TransitionBuilder(BrainBuilder owner, StateBuilder sb, AiState state, string target)
|
internal TransitionBuilder(StateBuilder sb, AiState state, string target)
|
||||||
{ _owner = owner; _stateBuilder = sb; _state = state; _target = target; }
|
{ _stateBuilder = sb; _state = state; _target = target; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 条件转换。label 为可读标签(用于 Mermaid 边 / trace 触发原因),
|
/// 条件转换。label 为可读标签(用于 Mermaid 边 / trace 触发原因),
|
||||||
@@ -79,14 +78,14 @@ namespace BaseGames.AI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public StateBuilder When(Func<IAiContext, bool> cond, string label = null)
|
public StateBuilder When(Func<IAiContext, bool> cond, string label = null)
|
||||||
{
|
{
|
||||||
_state.Transitions.Add(Transition.OnCondition(_target, cond, label ?? "cond"));
|
_state.AddTransition(Transition.OnCondition(_target, cond, label ?? "cond"));
|
||||||
return _stateBuilder;
|
return _stateBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>事件转换。</summary>
|
/// <summary>事件转换。</summary>
|
||||||
public StateBuilder OnEvent(AiSignal evt)
|
public StateBuilder OnEvent(AiSignal evt)
|
||||||
{
|
{
|
||||||
_state.Transitions.Add(Transition.OnEvent(_target, evt));
|
_state.AddTransition(Transition.OnEvent(_target, evt));
|
||||||
return _stateBuilder;
|
return _stateBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,12 +107,16 @@ namespace BaseGames.AI
|
|||||||
|
|
||||||
public GlobalBuilder OnEvent(AiSignal evt)
|
public GlobalBuilder OnEvent(AiSignal evt)
|
||||||
{
|
{
|
||||||
|
if (_pendingTarget == null)
|
||||||
|
throw new System.InvalidOperationException("Global(): 请先调用 To(target) 再 OnEvent/When。");
|
||||||
_owner.AddGlobal(Transition.OnEvent(_pendingTarget, evt));
|
_owner.AddGlobal(Transition.OnEvent(_pendingTarget, evt));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlobalBuilder When(Func<IAiContext, bool> cond, string label = null)
|
public GlobalBuilder When(Func<IAiContext, bool> cond, string label = null)
|
||||||
{
|
{
|
||||||
|
if (_pendingTarget == null)
|
||||||
|
throw new System.InvalidOperationException("Global(): 请先调用 To(target) 再 OnEvent/When。");
|
||||||
_owner.AddGlobal(Transition.OnCondition(_pendingTarget, cond, label ?? "cond"));
|
_owner.AddGlobal(Transition.OnCondition(_pendingTarget, cond, label ?? "cond"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user