x) Big FSM refactor

This commit is contained in:
Marc Hernandez 2024-04-09 17:15:59 -07:00
parent e656e46e7c
commit 1a05f3b2b9

View File

@ -13,7 +13,7 @@ public record class Context : imm.Recorded<Context>
} }
public record class State<T, CTX> : imm.Recorded<State<T, CTX>> public record class State<T, CTX>( CTX Context ) : imm.Recorded<State<T, CTX>>
where T : State<T, CTX> where T : State<T, CTX>
where CTX : Context where CTX : Context
{ {
@ -30,13 +30,13 @@ public record class State<T, CTX> : imm.Recorded<State<T, CTX>>
public record class FSM<T, CTX, ST> : imm.Recorded<FSM<T, CTX, ST>> public record class FSM<T, ST, CTX> : imm.Recorded<FSM<T, ST, CTX>>
where T : FSM<T, CTX, ST> where T : FSM<T, ST, CTX>
where CTX : Context
where ST : State<ST, CTX> where ST : State<ST, CTX>
where CTX : Context
{ {
public CTX Context { get; private set; } public CTX Context { get; init; }
public ST State { get; private set; } public ST State { get; init; }
public FSM( CTX context, ST stStart ) public FSM( CTX context, ST stStart )
{ {
@ -44,20 +44,37 @@ public record class FSM<T, CTX, ST> : imm.Recorded<FSM<T, CTX, ST>>
State = stStart; State = stStart;
} }
public FSM<T, CTX, ST> Transition(ST newState) public FSM<T, ST, CTX> Transition(ST newState)
{ {
var (newOldCTX, oldState) = State.onExit(Context, newState); var origState = State;
var (newOldCTX, oldState) = State.onExit(Context, newState);
var (newCTX, storeState) = newState.onEnter(newOldCTX, oldState); var (newCTX, storeState) = newState.onEnter(newOldCTX, oldState);
return this with var newFSM = this.Process( this with
{ {
Context = newCTX, Context = newCTX,
State = storeState, State = storeState,
}; }, $"Trans: {origState.GetType().Name} to {newState.GetType().Name}" );
return newFSM;
} }
public FSM<T, ST, CTX> Process( Func<ST, ST> fn, string reason )
{
var newState = fn( State );
if( object.ReferenceEquals( newState, State ) ) return this;
FSM<T, ST, CTX> newFSM = this.Process( this with
{
Context = Context,
State = newState,
}, $"Processing: {newState.GetType().Name} for {reason}" );
return newFSM;
}
} }