From 71a7a115e2356e6c4374d34bdbf64f01168dec89 Mon Sep 17 00:00:00 2001 From: Marc Hernandez Date: Sun, 21 Jan 2024 22:16:02 -0800 Subject: [PATCH] Various immutable changes --- imm/Imm.cs | 300 +++++++++++++++++++++++++++---------------- logging/Log.cs | 2 + ser/XmlFormatter2.cs | 4 +- 3 files changed, 195 insertions(+), 111 deletions(-) diff --git a/imm/Imm.cs b/imm/Imm.cs index 70a9ecb..0d4e575 100644 --- a/imm/Imm.cs +++ b/imm/Imm.cs @@ -9,155 +9,237 @@ using System.Threading.Tasks; // A spot for immutable helpers -namespace imm +// TODO +// TODO +// TODO +// x) Wrap metadata into its own struct + +namespace imm; + + +static public class Util { - - public record class Versioned - where T : Versioned - { - public delegate void ChangeDelegate( T old, T next ); - - public uint Version { get; protected set; } = 0; - public string Reason { get; protected set; } = ""; - - public ChangeDelegate OnChange; - - 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 + //This can handle both Timed and Recorded + static public T Process( ref T obj, Func fn, string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0, + [CallerArgumentExpression("fn")] + string expression = default ) where T : Recorded { - public T? Old { get; protected set; } - public string Expression { get; protected set; } = ""; - public string MemberName { get; protected set; } = ""; - public string FilePath { get; protected set; } = ""; - public int LineNumber { get; protected set; } = -1; + obj = obj.Process( fn, reason, memberName, filePath, lineNumber, expression ); + return obj; + } - public T Record( string reason = "", - [CallerMemberName] string memberName = "", - [CallerFilePath] string filePath = "", - [CallerLineNumber] int lineNumber = 0 ) + //This can handle both Timed and Recorded + static public T Versioned( ref T obj, Func fn, string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0, + [CallerArgumentExpression("fn")] + string expression = default ) + where T : Versioned + { + obj = obj.Process( fn, reason ); + return obj; + } +} + + +public record class Versioned + where T : Versioned +{ + public delegate void ChangeDelegate( T ZZOld, T next ); + + public record class MetaData + { + public uint Version { get; internal set; } = 0; + public string Reason { get; internal set; } = ""; + + public MetaData() { } + } + + internal Versioned( MetaData meta ) + { + MetaStorage = meta; + } + + internal MetaData MetaStorage = new(); + + public MetaData Meta => MetaStorage; + + public ChangeDelegate OnChange; + + public T Process( Func fn, string reason = "" ) + { + var newT = fn( ( T )this ); + + return newT with { - var orig = ( T )this; - - var next = ( T ) this with + MetaStorage = Meta with { - //Do the Versioned code here - Version = orig.Version + 1, + Version = newT.Meta.Version + 1, + Reason = reason, + } + }; + } +} + +public record class Recorded : Versioned + where T : Recorded +{ + new public record class MetaData : Versioned.MetaData + { + public T? ZZOld { get; internal set; } + public T? Old => ZZOld; + public string Expression { get; internal set; } = ""; + public string MemberName { get; internal set; } = ""; + public string FilePath { get; internal set; } = ""; + public int LineNumber { get; internal set; } = -1; + + public MetaData() { } + } + + public Recorded() : this( new MetaData() ) + { + } + + public Recorded(MetaData meta) : base( meta ) + { + } + + new public MetaData Meta => MetaStorage as MetaData; + + + virtual public T Record( string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0 ) + { + return Process( t => t, reason, memberName, filePath, lineNumber ); + } + + virtual public T Process( T next, string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0, + [CallerArgumentExpression("next")] + string expression = default ) + { + return Process( ( old ) => next, reason, memberName, filePath, lineNumber, expression ); + } + + virtual 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; + + var next = fn( orig ); + + var ret = next with + { + //Do the Versioned code here + MetaStorage = Meta with + { + Version = orig.Meta.Version + 1, Reason = reason, - Old = orig, + ZZOld = orig, MemberName = memberName, FilePath = filePath, LineNumber = lineNumber, - }; + } + }; - OnChange( orig, next ); + OnChange( orig, ret ); - return next; - } + return ret; + } +} - 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; - var next = ( T )fn( orig ); +public record class Timed : Recorded + where T : Timed +{ - var ret = ( T )next with - { - //Do the Versioned code here - Version = orig.Version + 1, - Reason = reason, + new public record class MetaData : Recorded.MetaData + { + public readonly DateTime CreatedAt = DateTime.Now; + public DateTime TouchedAt { get; internal set; } = DateTime.Now; + } - //Recorded - Old = orig, - Expression = expression, - MemberName = memberName, - FilePath = filePath, - LineNumber = lineNumber, - }; + public Timed() : this( new MetaData() ) + { + } - OnChange( orig, ret ); + public Timed( MetaData meta ) : base( meta ) + { + } - return ret; - } + new public MetaData Meta => MetaStorage as MetaData; + + public TimeSpan Since => Meta.TouchedAt - Meta.Old?.Meta.TouchedAt ?? TimeSpan.MaxValue; + + + override public T Record( string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0 ) + { + return Process( t => t, reason, memberName, filePath, lineNumber ); + } + + override public T Process( T next, string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0, + [CallerArgumentExpression("next")] + string expression = default ) + { + return Process( ( old ) => next, reason, memberName, filePath, lineNumber, expression ); } - public record class Timed : Recorded - where T : Timed + override public T Process( Func fn, string reason = "", + [CallerMemberName] string memberName = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0, + [CallerArgumentExpression("fn")] + string expression = default ) { - public readonly DateTime CreatedAt = DateTime.Now; - public DateTime TouchedAt { get; set; } = DateTime.Now; + var orig = ( T )this; + var next = fn( orig ); - public T Process( T next, string reason = "", - [CallerMemberName] string memberName = "", - [CallerFilePath] string filePath = "", - [CallerLineNumber] int lineNumber = 0, - [CallerArgumentExpression("next")] - string expression = default ) + var ret = next with { - return Process( ( old ) => next, reason, memberName, filePath, lineNumber, expression ); - } - - - new 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; - - var next = ( T )fn( orig ); - - var ret = ( T )next with + MetaStorage = Meta with { //Versioned - Version = orig.Version + 1, + Version = orig.Meta.Version + 1, Reason = reason, //Recorded - Old = orig, - Expression = expression, MemberName = memberName, FilePath = filePath, LineNumber = lineNumber, + ZZOld = orig, //Timed TouchedAt = DateTime.Now, - }; + } - OnChange( orig, ret ); + }; - return ret; - } + if( OnChange != null) OnChange( orig, ret ); + + return ret; } - public static class Util - { - - - - } - } - diff --git a/logging/Log.cs b/logging/Log.cs index 8012f68..753b670 100644 --- a/logging/Log.cs +++ b/logging/Log.cs @@ -34,6 +34,8 @@ static public class log Invalid = 0, File = 1 << 0, Console = 1 << 1, + + All = File | Console, } diff --git a/ser/XmlFormatter2.cs b/ser/XmlFormatter2.cs index a6df02a..37b3895 100644 --- a/ser/XmlFormatter2.cs +++ b/ser/XmlFormatter2.cs @@ -88,9 +88,9 @@ namespace lib public class XmlFormatter2Cfg: Config { - public readonly Datastructure datastructure = Datastructure.Graph; + public Datastructure datastructure = Datastructure.Graph; - public readonly int Version = 2; + public int Version = 2; } public class XmlFormatter2: IFormatter