2023-04-13 11:51:03 +08:00
|
|
|
#define DEBUG
|
|
|
|
using System;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Threading;
|
|
|
|
using Aitex.Core.RT.Log;
|
|
|
|
|
|
|
|
namespace Aitex.Core.RT.Fsm
|
|
|
|
{
|
|
|
|
public class Entity
|
|
|
|
{
|
2023-05-09 18:11:51 +08:00
|
|
|
public Entity()
|
|
|
|
{
|
|
|
|
IsEnabled = true;
|
|
|
|
}
|
|
|
|
|
2023-04-13 11:51:03 +08:00
|
|
|
protected Thread thread = null;
|
|
|
|
|
|
|
|
protected IStateMachine fsm = null;
|
|
|
|
|
2023-05-09 18:11:51 +08:00
|
|
|
public bool IsEnabled { get; set; }
|
|
|
|
|
2023-04-13 11:51:03 +08:00
|
|
|
public bool Running { get; protected set; }
|
|
|
|
|
|
|
|
public bool Initialize()
|
|
|
|
{
|
|
|
|
Debug.Assert(fsm != null);
|
|
|
|
Init();
|
|
|
|
fsm.Start();
|
|
|
|
thread = new Thread(fsm.Loop);
|
|
|
|
thread.Name = fsm.Name;
|
|
|
|
thread.Start();
|
|
|
|
while (!thread.IsAlive)
|
|
|
|
{
|
|
|
|
Thread.Sleep(1);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public virtual void Terminate()
|
|
|
|
{
|
|
|
|
fsm.Stop();
|
|
|
|
Term();
|
|
|
|
if (thread == null || !thread.IsAlive)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Thread.Sleep(100);
|
|
|
|
if (thread.IsAlive)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
thread.Abort();
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
LOG.Error($"Entity terminate has exception.", ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual bool Init()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual void Term()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void Transition<T, V>(T state, V msg, FsmFunc func, T next)
|
|
|
|
{
|
|
|
|
Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
|
|
|
|
int state2 = Convert.ToInt32(state);
|
|
|
|
int next2 = Convert.ToInt32(next);
|
|
|
|
int msg2 = Convert.ToInt32(msg);
|
|
|
|
Transition(state2, msg2, func, next2);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void Transition(int state, int msg, FsmFunc func, int next)
|
|
|
|
{
|
|
|
|
if (fsm != null)
|
|
|
|
{
|
|
|
|
fsm.Transition(state, msg, func, next);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void AnyStateTransition(int msg, FsmFunc func, int next)
|
|
|
|
{
|
|
|
|
if (fsm != null)
|
|
|
|
{
|
|
|
|
fsm.AnyStateTransition(msg, func, next);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void AnyStateTransition<T, V>(V msg, FsmFunc func, T next)
|
|
|
|
{
|
|
|
|
Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
|
|
|
|
int next2 = Convert.ToInt32(next);
|
|
|
|
int msg2 = Convert.ToInt32(msg);
|
|
|
|
AnyStateTransition(msg2, func, next2);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void EnterExitTransition<T, V>(T state, FsmFunc enter, V? msg, FsmFunc exit) where V : struct
|
|
|
|
{
|
|
|
|
Debug.Assert(typeof(T).IsEnum && (!msg.HasValue || typeof(V).IsEnum));
|
|
|
|
int state2 = Convert.ToInt32(state);
|
|
|
|
int msg2 = ((!msg.HasValue) ? 268435441 : Convert.ToInt32(msg));
|
|
|
|
EnterExitTransition(state2, enter, msg2, exit);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void EnterExitTransition(int state, FsmFunc enter, int msg, FsmFunc exit)
|
|
|
|
{
|
|
|
|
if (fsm != null)
|
|
|
|
{
|
|
|
|
fsm.EnterExitTransition(state, enter, msg, exit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void PostMsg<T>(T msg, params object[] args) where T : struct
|
|
|
|
{
|
|
|
|
Debug.Assert(typeof(T).IsEnum);
|
|
|
|
int msg2 = Convert.ToInt32(msg);
|
|
|
|
PostMsg(msg2, args);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void PostMsg(int msg, params object[] args)
|
|
|
|
{
|
|
|
|
if (fsm == null)
|
|
|
|
{
|
|
|
|
LOG.Error($"fsm is null, post msg {msg}");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fsm.PostMsg(msg, args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|