2024-06-30 23:55:58 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using ColdMint.scripts.debug;
|
|
|
|
|
|
|
|
|
|
namespace ColdMint.scripts.stateMachine;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>State machine template</para>
|
|
|
|
|
/// <para>状态机模板</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public abstract class StateMachineTemplate : IStateMachine
|
|
|
|
|
{
|
|
|
|
|
private StateContext? _context;
|
|
|
|
|
private IStateProcessor? _activeStatusrocessor;
|
|
|
|
|
|
|
|
|
|
public StateContext? Context
|
|
|
|
|
{
|
|
|
|
|
get => _context;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (value == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_context != null)
|
|
|
|
|
{
|
|
|
|
|
_context.OnStateChange -= OnStateChange;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_context = value;
|
|
|
|
|
value.OnStateChange += OnStateChange;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool _isRunning;
|
|
|
|
|
private Dictionary<State, IStateProcessor>? _processors;
|
|
|
|
|
public bool IsRunning => _isRunning;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>When the state in the context changes</para>
|
|
|
|
|
/// <para>当上下文内的状态改变时</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="oldState"></param>
|
|
|
|
|
/// <param name="newState"></param>
|
|
|
|
|
private void OnStateChange(State oldState, State newState)
|
|
|
|
|
{
|
|
|
|
|
if (_context == null)
|
|
|
|
|
{
|
2024-07-06 14:55:07 +00:00
|
|
|
|
LogCat.LogError("state_machine_does_not_specify_context", label: LogCat.LogLabel.StateMachineTemplate);
|
2024-06-30 23:55:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_processors == null)
|
|
|
|
|
{
|
2024-07-06 14:55:07 +00:00
|
|
|
|
LogCat.LogError("state_machine_does_not_specify_processor", label: LogCat.LogLabel.StateMachineTemplate);
|
2024-06-30 23:55:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_processors.TryGetValue(oldState, out var processor))
|
|
|
|
|
{
|
|
|
|
|
processor.Exit(_context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_processors.TryGetValue(newState, out processor))
|
|
|
|
|
{
|
|
|
|
|
processor.Enter(_context);
|
|
|
|
|
_activeStatusrocessor = processor;
|
|
|
|
|
}
|
2024-07-06 14:55:07 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LogCat.LogErrorWithFormat("state_processor_not_found", label: LogCat.LogLabel.StateMachineTemplate,
|
|
|
|
|
newState);
|
|
|
|
|
}
|
2024-06-30 23:55:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Registration status handler</para>
|
|
|
|
|
/// <para>注册状态处理器</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="processor"></param>
|
|
|
|
|
protected void RegisterProcessor(IStateProcessor processor)
|
|
|
|
|
{
|
|
|
|
|
_processors ??= new Dictionary<State, IStateProcessor>();
|
|
|
|
|
if (!_processors.TryAdd(processor.State, processor))
|
|
|
|
|
{
|
2024-07-06 14:55:07 +00:00
|
|
|
|
LogCat.LogError("state_processor_already_registered", label: LogCat.LogLabel.StateMachineTemplate);
|
2024-06-30 23:55:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Start()
|
|
|
|
|
{
|
|
|
|
|
if (_isRunning)
|
|
|
|
|
{
|
2024-07-06 14:55:07 +00:00
|
|
|
|
LogCat.LogError("try_to_open_state_machine_that_is_on", label: LogCat.LogLabel.StateMachineTemplate);
|
2024-06-30 23:55:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Context == null)
|
|
|
|
|
{
|
2024-07-06 14:55:07 +00:00
|
|
|
|
LogCat.LogError("state_machine_does_not_specify_context", label: LogCat.LogLabel.StateMachineTemplate);
|
2024-06-30 23:55:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OnStart(Context);
|
|
|
|
|
_activeStatusrocessor = _processors?[Context.CurrentState];
|
|
|
|
|
_isRunning = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>When the state machine is turned on</para>
|
|
|
|
|
/// <para>在状态机开启时</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
///<para>Register the status handler in this method<see cref="RegisterProcessor"/>.</para>
|
|
|
|
|
///<para>请在此方法内注册状态处理器<see cref="RegisterProcessor"/>。</para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
protected abstract void OnStart(StateContext context);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>When the state switch is off</para>
|
|
|
|
|
/// <para>在状态机关闭时</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected virtual void OnStop()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Stop()
|
|
|
|
|
{
|
|
|
|
|
if (!_isRunning)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_isRunning = false;
|
|
|
|
|
OnStop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Execute()
|
|
|
|
|
{
|
|
|
|
|
if (!_isRunning)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Context == null)
|
|
|
|
|
{
|
2024-07-06 14:55:07 +00:00
|
|
|
|
LogCat.LogError("state_machine_does_not_specify_context", label: LogCat.LogLabel.StateMachineTemplate);
|
2024-06-30 23:55:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_activeStatusrocessor == null)
|
|
|
|
|
{
|
2024-07-06 14:55:07 +00:00
|
|
|
|
LogCat.LogError("state_machine_does_not_specify_active_processor",
|
|
|
|
|
label: LogCat.LogLabel.StateMachineTemplate);
|
2024-06-30 23:55:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2024-07-06 14:55:07 +00:00
|
|
|
|
|
2024-06-30 23:55:58 +00:00
|
|
|
|
_activeStatusrocessor.Execute(Context);
|
|
|
|
|
}
|
|
|
|
|
}
|