diff --git a/SharpLib.csproj b/SharpLib.csproj index 5d1cd2c..82a9526 100644 --- a/SharpLib.csproj +++ b/SharpLib.csproj @@ -1,7 +1,7 @@  - net6.0; net48 + net6.0 lib 0.0.1.0 0.0.1.0 @@ -25,7 +25,11 @@ + + + + diff --git a/fsm/FSM.cs b/fsm/FSM.cs new file mode 100644 index 0000000..e13c147 --- /dev/null +++ b/fsm/FSM.cs @@ -0,0 +1,61 @@ + + +using System; + + + +namespace fsm; + + + +public record class Context : imm.Recorded +{ + +} + +public record class State : imm.Recorded> + where T: State + where CTX: Context +{ + virtual public (CTX, T) onEnter(CTX ctx, State oldState) + { + return (ctx, (T)this); + } + + virtual public (CTX, T) onExit(CTX ctx, State newState) + { + return (ctx, (T)this); + } +} + +public record class FSM : imm.Recorded> + 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; + } + + public FSM Transition(ST newState) + { + var (newOldCTX, oldState) = State.onExit(Context, newState); + + var (newCTX, storeState) = newState.onEnter(newOldCTX, oldState); + + return this with + { + Context = newCTX, + State = storeState, + }; + } + + + +} + diff --git a/imm/Imm.cs b/imm/Imm.cs index 42522bb..aa65efc 100644 --- a/imm/Imm.cs +++ b/imm/Imm.cs @@ -2,14 +2,93 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; // A spot for immutable helpers -public static class imm -{ - - +namespace imm +{ + public record class Versioned + where T: Versioned + { + public uint Version { get; protected set; } = 0; + public string Reason { get; protected set; } = ""; + + public T Process(Func fn, string reason = "") + { + var newT = fn((T)this); + + return newT with + { + Version = newT.Version + 1, + Reason = reason, + }; + } + } + + public record class Recorded : Versioned + where T : Recorded + { + public T? Old { get; private set; } + public string Expression { get; private set; } = ""; + public string MemberName { get; private set; } = ""; + public string FilePath { get; private set; } = ""; + public int LineNumber { get; private set; } = -1; + + public T Record(string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0) + { + var orig = (T)this; + + var newT = base.Process((old) => old with + { + Old = orig, + MemberName = memberName, + FilePath = filePath, + LineNumber = lineNumber, + }, reason); + + return newT; + } + + + public T Process(Func fn, string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0, + [CallerArgumentExpression("fn")] + string expression = default) + { + var orig = (T)this; + + return (T)this with + { + //Do the Versioned code here + Version = orig.Version + 1, + + //Recorded + Old = orig, + Expression = expression, + MemberName = memberName, + FilePath = filePath, + LineNumber = lineNumber, + }; + } + } + + + public static class Util + { + + + + + } + } +