Add Versioned, Recorded and FSM

This commit is contained in:
Marc Hernandez 2023-11-11 14:51:40 -08:00
parent ef746d69ba
commit c95a809bfd
3 changed files with 149 additions and 5 deletions

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0; net48</TargetFrameworks>
<TargetFrameworks>net6.0</TargetFrameworks>
<RootNamespace>lib</RootNamespace>
<AssemblyVersion>0.0.1.0</AssemblyVersion>
<FileVersion>0.0.1.0</FileVersion>
@ -25,7 +25,11 @@
<ItemGroup>
<Folder Include="Properties\" />
<Folder Include="reflect\" />
<Folder Include="fsm\" />
</ItemGroup>
<ItemGroup>
<None Remove="fsm\" />
</ItemGroup>
</Project>

61
fsm/FSM.cs Normal file
View File

@ -0,0 +1,61 @@

using System;
namespace fsm;
public record class Context : imm.Recorded<Context>
{
}
public record class State<T, CTX> : imm.Recorded<State<T, CTX>>
where T: State<T, CTX>
where CTX: Context
{
virtual public (CTX, T) onEnter(CTX ctx, State<T, CTX> oldState)
{
return (ctx, (T)this);
}
virtual public (CTX, T) onExit(CTX ctx, State<T, CTX> newState)
{
return (ctx, (T)this);
}
}
public record class FSM<T, CTX, ST> : imm.Recorded<FSM<T, CTX, ST>>
where T: FSM<T, CTX, ST>
where CTX: Context
where ST: State<ST, CTX>
{
public CTX Context { get; private set; }
public ST State { get; private set; }
public FSM(CTX context, ST state)
{
Context = context;
State = state;
}
public FSM<T, CTX, ST> Transition(ST newState)
{
var (newOldCTX, oldState) = State.onExit(Context, newState);
var (newCTX, storeState) = newState.onEnter(newOldCTX, oldState);
return this with
{
Context = newCTX,
State = storeState,
};
}
}

View File

@ -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<T>
where T: Versioned<T>
{
public uint Version { get; protected set; } = 0;
public string Reason { get; protected set; } = "";
public T Process(Func<T, T> fn, string reason = "")
{
var newT = fn((T)this);
return newT with
{
Version = newT.Version + 1,
Reason = reason,
};
}
}
public record class Recorded<T> : Versioned<T>
where T : Recorded<T>
{
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<T, T> 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
{
}
}