using System; using System.Runtime.CompilerServices; namespace fsm; public class Context { } public class State where T : State where CTX : Context { virtual public void onEnter( CTX ctx, State oldState ) { } virtual public void onExit( CTX ctx, State newState ) { } } public class FSM where T : FSM where CTX : Context where ST : State { public CTX Context { get; private set; } public ST State { get; private set; } public FSM( CTX context, ST state ) { Context = context; State = state; State.onEnter( Context, state ); } public void transition( ST newState, string reason = "", [CallerMemberName] string member = "", [CallerFilePath] string path = "", [CallerLineNumber] int line = 0 ) { log.debug( $"{GetType().Name} switching to {newState.GetType().Name}from {State.GetType().Name} bcs {reason} Code {log.relativePath( path )}:({line}): {member}" ); State.onExit( Context, newState ); newState.onEnter( Context, State ); State = newState; } } /* Im going to preface this with, I use FSMs everywhere for quite a few things. */