diff --git a/imm/FSM.cs b/imm/FSM.cs index e492ac2..8806d46 100644 --- a/imm/FSM.cs +++ b/imm/FSM.cs @@ -13,7 +13,7 @@ public record class Context : imm.Recorded } -public record class State : imm.Recorded> +public record class State( CTX Context ) : imm.Recorded> where T : State where CTX : Context { @@ -30,13 +30,13 @@ public record class State : imm.Recorded> -public record class FSM : imm.Recorded> - where T : FSM - where CTX : Context +public record class FSM : imm.Recorded> + where T : FSM where ST : State + where CTX : Context { - public CTX Context { get; private set; } - public ST State { get; private set; } + public CTX Context { get; init; } + public ST State { get; init; } public FSM( CTX context, ST stStart ) { @@ -44,20 +44,37 @@ public record class FSM : imm.Recorded> State = stStart; } - public FSM Transition(ST newState) + public FSM 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); - return this with + var newFSM = this.Process( this with { Context = newCTX, State = storeState, - }; + }, $"Trans: {origState.GetType().Name} to {newState.GetType().Name}" ); + + return newFSM; } + public FSM Process( Func fn, string reason ) + { + var newState = fn( State ); + if( object.ReferenceEquals( newState, State ) ) return this; + + FSM newFSM = this.Process( this with + { + Context = Context, + State = newState, + }, $"Processing: {newState.GetType().Name} for {reason}" ); + + return newFSM; + } }