Compare commits
2 Commits
2b5940bef6
...
28d8c145b5
| Author | SHA1 | Date | |
|---|---|---|---|
| 28d8c145b5 | |||
| 65e7ed1b24 |
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net9.0;net8.0;net10.0</TargetFrameworks>
|
<TargetFrameworks>net9.0;net10.0</TargetFrameworks>
|
||||||
<RootNamespace>lib</RootNamespace>
|
<RootNamespace>lib</RootNamespace>
|
||||||
<AssemblyVersion>0.0.1.0</AssemblyVersion>
|
<AssemblyVersion>0.0.1.0</AssemblyVersion>
|
||||||
<FileVersion>0.0.1.0</FileVersion>
|
<FileVersion>0.0.1.0</FileVersion>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
|
||||||
namespace exp;
|
namespace exp;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
24
imm/FSM.cs
24
imm/FSM.cs
@ -1,4 +1,4 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@ -12,7 +12,7 @@ public abstract record class FsmContextBase<TSelf> : io.Recorded<TSelf>
|
|||||||
where TSelf : FsmContextBase<TSelf>
|
where TSelf : FsmContextBase<TSelf>
|
||||||
{
|
{
|
||||||
// Required for 'with' expressions.
|
// Required for 'with' expressions.
|
||||||
protected FsmContextBase( io.Recorded<TSelf> original ) : base( original ) { }
|
protected FsmContextBase(io.Recorded<TSelf> original) : base(original) { }
|
||||||
protected FsmContextBase() { }
|
protected FsmContextBase() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ public abstract record class FsmStateBase<TSelf, TCtx> : io.Recorded<TSelf>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when entering this state.
|
/// Called when entering this state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual (TCtx Context, TSelf State) OnEnter( TCtx context, FsmStateBase<TSelf, TCtx> oldState )
|
public virtual (TCtx Context, TSelf State) OnEnter(TCtx context, FsmStateBase<TSelf, TCtx> oldState)
|
||||||
{
|
{
|
||||||
return (context, (TSelf)this);
|
return (context, (TSelf)this);
|
||||||
}
|
}
|
||||||
@ -37,13 +37,13 @@ public abstract record class FsmStateBase<TSelf, TCtx> : io.Recorded<TSelf>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when exiting this state.
|
/// Called when exiting this state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual (TCtx Context, TSelf State) OnExit( TCtx context, FsmStateBase<TSelf, TCtx> newState )
|
public virtual (TCtx Context, TSelf State) OnExit(TCtx context, FsmStateBase<TSelf, TCtx> newState)
|
||||||
{
|
{
|
||||||
return (context, (TSelf)this);
|
return (context, (TSelf)this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required for 'with' expressions.
|
// Required for 'with' expressions.
|
||||||
protected FsmStateBase( io.Recorded<TSelf> original ) : base( original ) { }
|
protected FsmStateBase(io.Recorded<TSelf> original) : base(original) { }
|
||||||
protected FsmStateBase() { }
|
protected FsmStateBase() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,14 +62,14 @@ public abstract record class FsmBase<TSelf, TState, TCtx> : io.Recorded<TSelf>
|
|||||||
public TCtx Context { get; init; }
|
public TCtx Context { get; init; }
|
||||||
public TState State { get; init; }
|
public TState State { get; init; }
|
||||||
|
|
||||||
protected FsmBase( TCtx initialContext, TState initialState )
|
protected FsmBase(TCtx initialContext, TState initialState)
|
||||||
{
|
{
|
||||||
Context = initialContext;
|
Context = initialContext;
|
||||||
State = initialState;
|
State = initialState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required for 'with' expressions.
|
// Required for 'with' expressions.
|
||||||
protected FsmBase( io.Recorded<TSelf> original ) : base( original )
|
protected FsmBase(io.Recorded<TSelf> original) : base(original)
|
||||||
{
|
{
|
||||||
var o = original as FsmBase<TSelf, TState, TCtx>;
|
var o = original as FsmBase<TSelf, TState, TCtx>;
|
||||||
Context = o!.Context;
|
Context = o!.Context;
|
||||||
@ -78,7 +78,7 @@ public abstract record class FsmBase<TSelf, TState, TCtx> : io.Recorded<TSelf>
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Transitions the FSM. It automatically uses the 'Process'
|
/// Transitions the FSM. It automatically uses the 'Process'
|
||||||
/// method appropriate for io.ecorded or Timed, thanks to virtual overrides.
|
/// method appropriate for io.Recorded or Timed, thanks to virtual overrides.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TSelf Transition(
|
public TSelf Transition(
|
||||||
TState newState,
|
TState newState,
|
||||||
@ -86,12 +86,12 @@ public abstract record class FsmBase<TSelf, TState, TCtx> : io.Recorded<TSelf>
|
|||||||
[CallerMemberName] string memberName = "",
|
[CallerMemberName] string memberName = "",
|
||||||
[CallerFilePath] string filePath = "",
|
[CallerFilePath] string filePath = "",
|
||||||
[CallerLineNumber] int lineNumber = 0,
|
[CallerLineNumber] int lineNumber = 0,
|
||||||
[CallerArgumentExpression( "newState" )] string expression = "" )
|
[CallerArgumentExpression("newState")] string expression = "")
|
||||||
{
|
{
|
||||||
Console.WriteLine( $"[FSM] Transition: {State.GetType().Name} -> {newState.GetType().Name}. Reason: {reason}" );
|
Console.WriteLine($"[FSM] Transition: {State.GetType().Name} -> {newState.GetType().Name}. Reason: {reason}");
|
||||||
|
|
||||||
var (ctxAfterExit, stateAfterExit) = State.OnExit( Context, newState );
|
var (ctxAfterExit, stateAfterExit) = State.OnExit(Context, newState);
|
||||||
var (ctxAfterEnter, stateAfterEnter) = newState.OnEnter( ctxAfterExit, stateAfterExit );
|
var (ctxAfterEnter, stateAfterEnter) = newState.OnEnter(ctxAfterExit, stateAfterExit);
|
||||||
|
|
||||||
// Since 'this' is at least 'io.Recorded<TSelf>', we can call the
|
// Since 'this' is at least 'io.Recorded<TSelf>', we can call the
|
||||||
// detailed 'Process'. If 'this' is actually 'Timed<TSelf>', C#'s
|
// detailed 'Process'. If 'this' is actually 'Timed<TSelf>', C#'s
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
//#nullable enable
|
//#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper static class for processing immutable objects using a 'ref' pattern.
|
/// Helper static class for processing immutable objects using a 'ref' pattern.
|
||||||
/// Provides different levels of processing based on the type.
|
/// Provides different levels of processing based on the type.
|
||||||
@ -16,8 +15,8 @@ public static class imm
|
|||||||
public static T LightProcess<T>(
|
public static T LightProcess<T>(
|
||||||
ref T obj,
|
ref T obj,
|
||||||
Func<T, T> fn,
|
Func<T, T> fn,
|
||||||
string reason = "Processed" // TODO Replace the string with a $"" that cinludes some info
|
string reason = "Processed" )
|
||||||
) where T : io.Versioned<T>
|
where T : io.Versioned<T>
|
||||||
{
|
{
|
||||||
obj = obj.Process( fn, reason );
|
obj = obj.Process( fn, reason );
|
||||||
return obj;
|
return obj;
|
||||||
|
|||||||
42
imm/List.cs
42
imm/List.cs
@ -11,7 +11,7 @@ namespace io;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// An immutable list implementation that tracks history, metadata, and time.
|
/// An immutable list implementation that tracks history, metadata, and time.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record class List<T> : io.Timed<List<T>>, IImmutableList<T>
|
public record class List<T> : Timed<List<T>>, IImmutableList<T>
|
||||||
{
|
{
|
||||||
static public List<T> Empty { get; } = new();
|
static public List<T> Empty { get; } = new();
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ public record class List<T> : io.Timed<List<T>>, IImmutableList<T>
|
|||||||
|
|
||||||
public List() { }
|
public List() { }
|
||||||
// Required for 'with' expressions to work with the base class hierarchy
|
// Required for 'with' expressions to work with the base class hierarchy
|
||||||
protected List( io.Timed<List<T>> original ) : base( original ) { }
|
protected List(Timed<List<T>> original) : base(original) { }
|
||||||
|
|
||||||
// Helper to apply changes using the Process method
|
// Helper to apply changes using the Process method
|
||||||
private List<T> Change(
|
private List<T> Change(
|
||||||
@ -29,37 +29,37 @@ public record class List<T> : io.Timed<List<T>>, IImmutableList<T>
|
|||||||
[CallerLineNumber] int dbgLine = -1,
|
[CallerLineNumber] int dbgLine = -1,
|
||||||
[CallerArgumentExpression( "listChange" )] string reason = "" )
|
[CallerArgumentExpression( "listChange" )] string reason = "" )
|
||||||
{
|
{
|
||||||
var newValues = listChange( Values );
|
var newValues = listChange(Values);
|
||||||
return ReferenceEquals( Values, newValues )
|
return ReferenceEquals(Values, newValues)
|
||||||
? this
|
? this
|
||||||
: Process( l => l with { Values = newValues }, reason, dbgMethod, dbgPath, dbgLine, reason );
|
: Process(l => l with { Values = newValues }, reason, dbgMethod, dbgPath, dbgLine, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- IImmutableList<T> implementation using the Change helper ---
|
// --- IImmutableList<T> implementation using the Change helper ---
|
||||||
public T this[int index] => Values[index];
|
public T this[int index] => Values[index];
|
||||||
public int Count => Values.Count;
|
public int Count => Values.Count;
|
||||||
|
|
||||||
public List<T> Add( T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Add( value ), dbgMethod, dbgPath, dbgLine );
|
public List<T> Add(T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1) => Change(v => v.Add(value), dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> AddRange( IEnumerable<T> items, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.AddRange( items ), dbgMethod, dbgPath, dbgLine );
|
public List<T> AddRange(IEnumerable<T> items, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1) => Change(v => v.AddRange(items), dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> Clear( [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Clear(), dbgMethod, dbgPath, dbgLine );
|
public List<T> Clear([CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1) => Change(v => v.Clear(), dbgMethod, dbgPath, dbgLine);
|
||||||
#region IImmutableList Implementati, dbgMethod, dbgPath, dbgLineon
|
#region IImmutableList Implementati, dbgMethod, dbgPath, dbgLineon
|
||||||
public List<T> Insert( int index, T element, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Insert( index, element ), dbgMethod, dbgPath, dbgLine );
|
public List<T> Insert( int index, T element, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Insert( index, element ) , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> InsertRange( int index, IEnumerable<T> items, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.InsertRange( index, items ), dbgMethod, dbgPath, dbgLine );
|
public List<T> InsertRange( int index, IEnumerable<T> items, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.InsertRange( index, items ) , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> Remove( T value, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Remove( value, equalityComparer ), dbgMethod, dbgPath, dbgLine );
|
public List<T> Remove( T value, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Remove( value, equalityComparer ) , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> Remove( T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Remove( value, EqualityComparer<T>.Default, dbgMethod, dbgPath, dbgLine );
|
public List<T> Remove( T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Remove( value, EqualityComparer<T>.Default , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> RemoveAll( Predicate<T> match, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveAll( match ), dbgMethod, dbgPath, dbgLine );
|
public List<T> RemoveAll( Predicate<T> match, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveAll( match ) , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> RemoveAt( int index, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveAt( index ), dbgMethod, dbgPath, dbgLine );
|
public List<T> RemoveAt( int index, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveAt( index ) , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> RemoveRange( int index, int count, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveRange( index, count ), dbgMethod, dbgPath, dbgLine );
|
public List<T> RemoveRange( int index, int count, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveRange( index, count ) , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> RemoveRange( IEnumerable<T> items, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveRange( items, equalityComparer ), dbgMethod, dbgPath, dbgLine );
|
public List<T> RemoveRange( IEnumerable<T> items, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveRange( items, equalityComparer ) , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> Replace( T oldValue, T newValue, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Replace( oldValue, newValue, equalityComparer ), dbgMethod, dbgPath, dbgLine );
|
public List<T> Replace( T oldValue, T newValue, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Replace( oldValue, newValue, equalityComparer ) , dbgMethod, dbgPath, dbgLine);
|
||||||
public List<T> SetItem( int index, T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.SetItem( index, value ), dbgMethod, dbgPath, dbgLine );
|
public List<T> SetItem( int index, T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.SetItem( index, value ) , dbgMethod, dbgPath, dbgLine);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public int IndexOf( T item, int index, int count, IEqualityComparer<T>? equalityComparer ) => Values.IndexOf( item, index, count, equalityComparer ?? EqualityComparer<T>.Default );
|
public int IndexOf( T item, int index, int count, IEqualityComparer<T>? equalityComparer ) => Values.IndexOf( item, index, count, equalityComparer ?? EqualityComparer<T>.Default );
|
||||||
public int LastIndexOf( T item, int index, int count, IEqualityComparer<T>? equalityComparer ) => Values.LastIndexOf( item, index, count, equalityComparer ?? EqualityComparer<T>.Default );
|
public int LastIndexOf( T item, int index, int count, IEqualityComparer<T>? equalityComparer) => Values.LastIndexOf( item, index, count, equalityComparer ?? EqualityComparer<T>.Default );
|
||||||
|
|
||||||
public int IndexOf( T item, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => IndexOf( item, 0, Count, EqualityComparer<T>.Default );
|
public int IndexOf( T item, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => IndexOf( item, 0, Count, EqualityComparer<T>.Default);
|
||||||
|
|
||||||
|
|
||||||
IImmutableList<T> IImmutableList<T>.Clear() => Clear();
|
IImmutableList<T> IImmutableList<T>.Clear() => Clear();
|
||||||
@ -78,5 +78,5 @@ public record class List<T> : io.Timed<List<T>>, IImmutableList<T>
|
|||||||
|
|
||||||
// --- Standard Interfaces ---
|
// --- Standard Interfaces ---
|
||||||
public IEnumerator<T> GetEnumerator() => Values.GetEnumerator();
|
public IEnumerator<T> GetEnumerator() => Values.GetEnumerator();
|
||||||
IEnumerator IEnumerable.GetEnumerator() => ( (IEnumerable)Values ).GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)Values).GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,2 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|||||||
15
imm/io.cs
15
imm/io.cs
@ -23,7 +23,7 @@ public interface Obj
|
|||||||
/// Gets the previous version as a base object, if available.
|
/// Gets the previous version as a base object, if available.
|
||||||
/// Returns null if this is the first version or if history is not tracked.
|
/// Returns null if this is the first version or if history is not tracked.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Obj? DebugOld { get; }
|
Obj? Old { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new version without functional change.
|
/// Creates a new version without functional change.
|
||||||
@ -174,11 +174,11 @@ public record class Versioned<T> : Obj<T> where T : Versioned<T>
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public ChangeDelegate<T> OnChange { get; set; } = ( o, n ) => { };
|
public ChangeDelegate<T> OnChange { get; set; } = ( o, n ) => { };
|
||||||
|
|
||||||
public virtual Obj? DebugOld => null;
|
public virtual Obj? Old => null;
|
||||||
|
|
||||||
Metadata_Versioned Obj.Meta => this.Meta;
|
Metadata_Versioned Obj.Meta => this.Meta;
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
Obj? Obj.DebugOld => this.DebugOld;
|
Obj? Obj.Old => this.Old;
|
||||||
|
|
||||||
public Versioned() { }
|
public Versioned() { }
|
||||||
protected Versioned( Versioned<T> original )
|
protected Versioned( Versioned<T> original )
|
||||||
@ -239,9 +239,9 @@ public record class Recorded<T> : Versioned<T> where T : Recorded<T>
|
|||||||
new public Metadata_Recorded Meta { get; init; } = new();
|
new public Metadata_Recorded Meta { get; init; } = new();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
new public T? DebugOld => Meta.OldObject as T;
|
new public T? Old => Meta.OldObject as T;
|
||||||
|
|
||||||
//public override Obj? DebugOld => this.DebugOld;
|
//public override Obj? Old => this.Old;
|
||||||
//Metadata_Versioned Obj.Meta => this.Meta;
|
//Metadata_Versioned Obj.Meta => this.Meta;
|
||||||
|
|
||||||
public Recorded() { }
|
public Recorded() { }
|
||||||
@ -261,8 +261,7 @@ public record class Recorded<T> : Versioned<T> where T : Recorded<T>
|
|||||||
if( ReferenceEquals( current, next ) )
|
if( ReferenceEquals( current, next ) )
|
||||||
return current;
|
return current;
|
||||||
|
|
||||||
var newMeta = current.Meta with
|
var newMeta = current.Meta with {
|
||||||
{
|
|
||||||
Version = current.Meta.Version + 1,
|
Version = current.Meta.Version + 1,
|
||||||
Reason = reason,
|
Reason = reason,
|
||||||
MemberName = dbgName,
|
MemberName = dbgName,
|
||||||
@ -295,7 +294,7 @@ public record class Timed<T> : Recorded<T> where T : Timed<T>
|
|||||||
{
|
{
|
||||||
new public Metadata_Timed Meta { get; init; } = new();
|
new public Metadata_Timed Meta { get; init; } = new();
|
||||||
//Metadata_Versioned Obj.Meta => this.Meta;
|
//Metadata_Versioned Obj.Meta => this.Meta;
|
||||||
public TimeSpan SinceLastTouch => Meta.TouchedAt - ( DebugOld?.Meta as Metadata_Timed )?.TouchedAt ?? TimeSpan.Zero;
|
public TimeSpan SinceLastTouch => Meta.TouchedAt - ( Old?.Meta as Metadata_Timed )?.TouchedAt ?? TimeSpan.Zero;
|
||||||
public TimeSpan TotalAge => Meta.TouchedAt - Meta.CreatedAt;
|
public TimeSpan TotalAge => Meta.TouchedAt - Meta.CreatedAt;
|
||||||
|
|
||||||
public Timed() { }
|
public Timed() { }
|
||||||
|
|||||||
@ -186,8 +186,7 @@ namespace lib
|
|||||||
|
|
||||||
doc.Load( reader );
|
doc.Load( reader );
|
||||||
|
|
||||||
if( doc.DocumentElement == null )
|
if( doc.DocumentElement == null ) return null;
|
||||||
return null;
|
|
||||||
|
|
||||||
if( t == null )
|
if( t == null )
|
||||||
return Deserialize( doc.DocumentElement );
|
return Deserialize( doc.DocumentElement );
|
||||||
@ -257,8 +256,7 @@ namespace lib
|
|||||||
{
|
{
|
||||||
TypeCode typeCode = Type.GetTypeCode( type );
|
TypeCode typeCode = Type.GetTypeCode( type );
|
||||||
|
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"{type.FriendlyName()}.{name} {existing} {mi?.Name}" );
|
||||||
log.info( $"{type.FriendlyName()}.{name} {existing} {mi?.Name}" );
|
|
||||||
|
|
||||||
if( typeCode != TypeCode.Object )
|
if( typeCode != TypeCode.Object )
|
||||||
{
|
{
|
||||||
@ -278,8 +276,7 @@ namespace lib
|
|||||||
|
|
||||||
if( obj is ser.I_Serialize iser )
|
if( obj is ser.I_Serialize iser )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"" );
|
||||||
log.info( $"" );
|
|
||||||
obj = iser.OnDeserialize( null );
|
obj = iser.OnDeserialize( null );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,8 +314,7 @@ namespace lib
|
|||||||
|
|
||||||
private object DeserializeConcrete( XmlElement elem, MemberInfo mi, string name, Type type )
|
private object DeserializeConcrete( XmlElement elem, MemberInfo mi, string name, Type type )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"" );
|
||||||
log.info( $"" );
|
|
||||||
|
|
||||||
string val = "";
|
string val = "";
|
||||||
|
|
||||||
@ -402,8 +398,7 @@ namespace lib
|
|||||||
|
|
||||||
private object HydrateObject( XmlElement elem, MemberInfo mi, Type finalType, object obj )
|
private object HydrateObject( XmlElement elem, MemberInfo mi, Type finalType, object obj )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"" );
|
||||||
log.info( $"" );
|
|
||||||
|
|
||||||
if( obj is IList )
|
if( obj is IList )
|
||||||
{
|
{
|
||||||
@ -493,10 +488,9 @@ namespace lib
|
|||||||
|
|
||||||
private object HydrateObjectOfNarrowType( XmlElement elem, MemberInfo mi, Type narrowType, object obj )
|
private object HydrateObjectOfNarrowType( XmlElement elem, MemberInfo mi, Type narrowType, object obj )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"" );
|
||||||
log.info( $"" );
|
|
||||||
|
|
||||||
var isImm = typeof( io.Obj ).IsAssignableFrom( narrowType );
|
var isImm = typeof(io.Obj).IsAssignableFrom( narrowType );
|
||||||
|
|
||||||
XmlNodeList allChildren = elem.ChildNodes;
|
XmlNodeList allChildren = elem.ChildNodes;
|
||||||
|
|
||||||
@ -648,14 +642,14 @@ namespace lib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !isImm )
|
if(!isImm)
|
||||||
{
|
{
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var imm = obj as io.Obj;
|
var immObj = obj as io.Obj;
|
||||||
var newObj = imm.Record( $"From XML {fromStr}:{elem.ParentNode?.Name}{elem.Name}" );
|
var newObj = immObj.Record( $"From XML {fromStr}:{elem.ParentNode?.Name}{elem.Name}" );
|
||||||
return newObj;
|
return newObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,8 +686,7 @@ namespace lib
|
|||||||
|
|
||||||
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
||||||
|
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"{finalType?.FriendlyName()}({type?.FriendlyName()}) refInt {refInt} exitingObj = {obj?.ToString()}" );
|
||||||
log.info( $"{finalType?.FriendlyName()}({type?.FriendlyName()}) refInt {refInt} exitingObj = {obj?.ToString()}" );
|
|
||||||
|
|
||||||
obj = createObject( elem, finalType, refInt, obj );
|
obj = createObject( elem, finalType, refInt, obj );
|
||||||
|
|
||||||
@ -702,8 +695,7 @@ namespace lib
|
|||||||
|
|
||||||
private object DeserializeList( XmlElement elem, MemberInfo mi, Type type, IList list )
|
private object DeserializeList( XmlElement elem, MemberInfo mi, Type type, IList list )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"" );
|
||||||
log.info( $"" );
|
|
||||||
|
|
||||||
XmlNodeList arrNodeList = elem.ChildNodes;
|
XmlNodeList arrNodeList = elem.ChildNodes;
|
||||||
|
|
||||||
@ -739,8 +731,7 @@ namespace lib
|
|||||||
typeElem = typeof( KeyValuePair<,> ).MakeGenericType( type.GenericTypeArguments );
|
typeElem = typeof( KeyValuePair<,> ).MakeGenericType( type.GenericTypeArguments );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"DserCol {type.GetType().FriendlyName()} {typeElem.Name} into reflT {mi.ReflectedType.FriendlyName()} declT {mi.DeclaringType.FriendlyName()} {mi.Name}" );
|
||||||
log.info( $"DserCol {type.GetType().FriendlyName()} {typeElem.Name} into reflT {mi.ReflectedType.FriendlyName()} declT {mi.DeclaringType.FriendlyName()} {mi.Name}" );
|
|
||||||
|
|
||||||
string refString = elem.GetAttribute( "ref" );
|
string refString = elem.GetAttribute( "ref" );
|
||||||
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
||||||
@ -785,8 +776,7 @@ namespace lib
|
|||||||
|
|
||||||
var typeGen = Type.MakeGenericSignatureType( type );
|
var typeGen = Type.MakeGenericSignatureType( type );
|
||||||
|
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"TypeGen: {typeGen.FriendlyName()}" );
|
||||||
log.info( $"TypeGen: {typeGen.FriendlyName()}" );
|
|
||||||
|
|
||||||
if( type == typeof( ImmutableArray<> ).MakeGenericType( typeElem ) )
|
if( type == typeof( ImmutableArray<> ).MakeGenericType( typeElem ) )
|
||||||
{
|
{
|
||||||
@ -843,8 +833,7 @@ namespace lib
|
|||||||
|
|
||||||
private object DeserializeArray( XmlElement elem, MemberInfo mi, Type type )
|
private object DeserializeArray( XmlElement elem, MemberInfo mi, Type type )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"" );
|
||||||
log.info( $"" );
|
|
||||||
|
|
||||||
Type typeElem = type.GetElementType();
|
Type typeElem = type.GetElementType();
|
||||||
|
|
||||||
@ -894,8 +883,7 @@ namespace lib
|
|||||||
|
|
||||||
if( _cfg.datastructure == Datastructure.Graph && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
|
if( _cfg.datastructure == Datastructure.Graph && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"Reuse object" );
|
||||||
log.info( $"Reuse object" );
|
|
||||||
return m_alreadySerialized[refInt];
|
return m_alreadySerialized[refInt];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,8 +893,7 @@ namespace lib
|
|||||||
|
|
||||||
if( isProxy )
|
if( isProxy )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"use Proxy" );
|
||||||
log.info( $"use Proxy" );
|
|
||||||
object obj = null;
|
object obj = null;
|
||||||
|
|
||||||
var tryType = type;
|
var tryType = type;
|
||||||
@ -950,8 +937,7 @@ namespace lib
|
|||||||
|
|
||||||
if( isSubclass )
|
if( isSubclass )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"Using existing obj {existingObj?.ToString()}" );
|
||||||
log.info( $"Using existing obj {existingObj?.ToString()}" );
|
|
||||||
return existingObj;
|
return existingObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,14 +953,12 @@ namespace lib
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"For {type.FriendlyName()} check for constructors" );
|
||||||
log.info( $"For {type.FriendlyName()} check for constructors" );
|
|
||||||
|
|
||||||
var cons = type.GetConstructor( Type.EmptyTypes );
|
var cons = type.GetConstructor( Type.EmptyTypes );
|
||||||
if( cons != null )
|
if( cons != null)
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"Activator.CreateInstance" );
|
||||||
log.info( $"Activator.CreateInstance" );
|
|
||||||
obj = Activator.CreateInstance( type );
|
obj = Activator.CreateInstance( type );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -983,18 +967,15 @@ namespace lib
|
|||||||
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
|
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"Got obj {obj?.ToString()}" );
|
||||||
log.info( $"Got obj {obj?.ToString()}" );
|
|
||||||
}
|
}
|
||||||
catch( Exception )
|
catch( Exception )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"GetUninitializedObject" );
|
||||||
log.info( $"GetUninitializedObject" );
|
|
||||||
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
|
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
|
||||||
if( _cfg.VerboseLogging )
|
if( _cfg.VerboseLogging ) log.info( $"Got obj {obj?.ToString()}" );
|
||||||
log.info( $"Got obj {obj?.ToString()}" );
|
|
||||||
}
|
}
|
||||||
catch( Exception exInner )
|
catch( Exception exInner )
|
||||||
{
|
{
|
||||||
@ -1309,7 +1290,7 @@ namespace lib
|
|||||||
HashSet<string> whitelistFields, whitelistProps;
|
HashSet<string> whitelistFields, whitelistProps;
|
||||||
GetFilters( _cfg.TypesDefault, mi, narrowType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps );
|
GetFilters( _cfg.TypesDefault, mi, narrowType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps );
|
||||||
|
|
||||||
var isImm = typeof( io.Obj ).IsAssignableFrom( narrowType );
|
var isImm = typeof(io.Obj).IsAssignableFrom( narrowType );
|
||||||
|
|
||||||
if( doFields || doImpls )
|
if( doFields || doImpls )
|
||||||
{
|
{
|
||||||
@ -1342,10 +1323,8 @@ namespace lib
|
|||||||
|
|
||||||
if( isImm )
|
if( isImm )
|
||||||
{
|
{
|
||||||
if( name == "MetaStorage" )
|
if( name == "MetaStorage" ) continue;
|
||||||
continue;
|
if( name == "Fn" ) continue;
|
||||||
if( name == "Fn" )
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !doAtt.Any() && FilterField( filterFields, doImpls, whitelistFields, childFi as MemberInfo, name ) )
|
if( !doAtt.Any() && FilterField( filterFields, doImpls, whitelistFields, childFi as MemberInfo, name ) )
|
||||||
@ -1386,10 +1365,8 @@ namespace lib
|
|||||||
|
|
||||||
if( isImm )
|
if( isImm )
|
||||||
{
|
{
|
||||||
if( name == "MetaStorage" )
|
if( name == "MetaStorage" ) continue;
|
||||||
continue;
|
if( name == "Fn" ) continue;
|
||||||
if( name == "Fn" )
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FilterField( filterProps, doImpls, whitelistProps, childPi as MemberInfo, name ) )
|
if( FilterField( filterProps, doImpls, whitelistProps, childPi as MemberInfo, name ) )
|
||||||
@ -1436,10 +1413,8 @@ namespace lib
|
|||||||
Type type = root.GetType();
|
Type type = root.GetType();
|
||||||
|
|
||||||
Type typeOfMember = typeof( object );
|
Type typeOfMember = typeof( object );
|
||||||
if( mi is FieldInfo fi )
|
if( mi is FieldInfo fi ) typeOfMember = fi.FieldType;
|
||||||
typeOfMember = fi.FieldType;
|
if( mi is PropertyInfo pi ) typeOfMember = pi.PropertyType;
|
||||||
if( mi is PropertyInfo pi )
|
|
||||||
typeOfMember = pi.PropertyType;
|
|
||||||
if( typeOfMember != type )
|
if( typeOfMember != type )
|
||||||
{
|
{
|
||||||
log.info( $"SerArr {typeOfMember.FriendlyName()} {mi?.Name} != {type.FriendlyName()}" );
|
log.info( $"SerArr {typeOfMember.FriendlyName()} {mi?.Name} != {type.FriendlyName()}" );
|
||||||
|
|||||||
111
logging/Log.cs
111
logging/Log.cs
@ -18,10 +18,10 @@ using System.Text;
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
T O D O :
|
T O D O :
|
||||||
|
x) Hook the C# prints from glue.
|
||||||
|
x) Fix
|
||||||
x) Refactor various logs in order to do automagic structured logging
|
x) Refactor various logs in order to do automagic structured logging
|
||||||
ref: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler
|
ref: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler
|
||||||
x) Add support for structured logging (e.g., JSON, XML)
|
|
||||||
x) Implement a centralized logger that can be used across the application
|
|
||||||
|
|
||||||
|
|
||||||
D O N E:
|
D O N E:
|
||||||
@ -32,63 +32,7 @@ N O T D O I N G :
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#region Helpers
|
||||||
/*
|
|
||||||
// L L M
|
|
||||||
# Context: Logging Infrastructure (`log` static class)
|
|
||||||
**Strict Rule:** DO NOT use `Console.WriteLine`, `Debug.WriteLine`, or standard `ILogger`. Use the static `log` class for all diagnostics.
|
|
||||||
|
|
||||||
## Core Design Pattern
|
|
||||||
The logging system uses **Caller Info Attributes** (`[CallerMemberName]`, `[CallerFilePath]`, etc.) to automatically capture context. Do not manually format method names or file paths in messages.
|
|
||||||
|
|
||||||
## API Surface
|
|
||||||
### 1. Standard Levels. Standard goto loggin
|
|
||||||
* `log.trace(msg)`, `log.debug(msg)`, `log.info(msg)`
|
|
||||||
* `log.warn(msg)`, `log.high(msg)`
|
|
||||||
* `log.error(msg)`, `log.fatal(msg)`
|
|
||||||
* **Signature:** `(string msg, string cat = "", SourceLoc? loc = null)`
|
|
||||||
* *Note:* `cat` (Category) and `loc` (SourceLocation) are optional; the system auto-resolves `cat` based on directory structure if omitted.
|
|
||||||
|
|
||||||
### 2. Functional Pass-Throughs If necessary
|
|
||||||
Use these to log data flow without breaking the statement chain.
|
|
||||||
* `T log.var<T>(T val)`: Logs `name_of_var = value` and returns `val`.
|
|
||||||
* `T log.call<T>(Func<T> func)`: Logs entry, executes `func`, logs exit + result, returns result.
|
|
||||||
* `void log.call(Action func)`: Logs entry, executes `action`, logs exit.
|
|
||||||
* `log.operations(Action/Func)`: Wraps execution with info logs.
|
|
||||||
|
|
||||||
### 3. Special Types
|
|
||||||
* `Value<T>`: A struct wrapper to capture variable expressions alongside values. Use `log.Value(var)` when you need explicit expression capturing in custom constructs.
|
|
||||||
* `log.exception(Exception ex, string msg)`: specialized dump for exceptions.
|
|
||||||
* `log.logProps(object obj, string header)`: Reflection-based dump of all properties on an object.
|
|
||||||
|
|
||||||
## Idiomatic Usage Examples
|
|
||||||
**Good:**
|
|
||||||
```csharp
|
|
||||||
// Variable inspection (Pass-through)
|
|
||||||
int x = log.var(Calculate());
|
|
||||||
|
|
||||||
// Function tracing
|
|
||||||
var result = log.call(() => ComplexCalculation(input));
|
|
||||||
|
|
||||||
// Exception handling
|
|
||||||
try { ... }
|
|
||||||
catch (Exception ex) { log.exception(ex, "Calculation failed"); }
|
|
||||||
|
|
||||||
// Object Dump
|
|
||||||
log.logProps(userConfig, "Current Config State");
|
|
||||||
```
|
|
||||||
|
|
||||||
**Bad:**
|
|
||||||
```csharp
|
|
||||||
int x = Calculate();
|
|
||||||
Console.WriteLine("x is " + x); // Forbidden
|
|
||||||
log.info($"x = {x}"); // Redundant manual formatting
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public record struct Value<T>( T _val, string _exp = "" )
|
public record struct Value<T>( T _val, string _exp = "" )
|
||||||
{
|
{
|
||||||
public static T Default = default!;
|
public static T Default = default!;
|
||||||
@ -144,13 +88,10 @@ public struct SourceLoc
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endregion // Helpers
|
||||||
|
|
||||||
static public class log
|
static public class log
|
||||||
{
|
{
|
||||||
|
|
||||||
//static
|
|
||||||
|
|
||||||
#region CLR Logging
|
#region CLR Logging
|
||||||
|
|
||||||
|
|
||||||
@ -212,14 +153,6 @@ static public class log
|
|||||||
|
|
||||||
#endregion // CLR Logging
|
#endregion // CLR Logging
|
||||||
|
|
||||||
static public Value<T> Value<T>( T val,
|
|
||||||
[CallerArgumentExpression("val")]
|
|
||||||
string dbgExp = ""
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return new( val, dbgExp );
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum LogType
|
public enum LogType
|
||||||
{
|
{
|
||||||
@ -247,7 +180,9 @@ static public class log
|
|||||||
All = File | Console,
|
All = File | Console,
|
||||||
}
|
}
|
||||||
|
|
||||||
#region LogEvent
|
|
||||||
|
#region LogEvent
|
||||||
|
|
||||||
public struct LogEvent
|
public struct LogEvent
|
||||||
{
|
{
|
||||||
public DateTime Time;
|
public DateTime Time;
|
||||||
@ -311,7 +246,6 @@ static public class log
|
|||||||
|
|
||||||
return logEvent;
|
return logEvent;
|
||||||
}
|
}
|
||||||
#endregion // LogEvent
|
|
||||||
|
|
||||||
public delegate void Log_delegate( LogEvent evt );
|
public delegate void Log_delegate( LogEvent evt );
|
||||||
|
|
||||||
@ -322,7 +256,7 @@ static public class log
|
|||||||
ImmutableInterlocked.AddOrUpdate( ref s_logEPforCat, cat, ep, ( k, v ) => ep );
|
ImmutableInterlocked.AddOrUpdate( ref s_logEPforCat, cat, ep, ( k, v ) => ep );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion // LogEvent
|
||||||
|
|
||||||
static public void shutdown()
|
static public void shutdown()
|
||||||
{
|
{
|
||||||
@ -462,32 +396,32 @@ static public class log
|
|||||||
}
|
}
|
||||||
|
|
||||||
[StackTraceHidden]
|
[StackTraceHidden]
|
||||||
static public void info( string msg, string cat = "", SourceLoc? loc = null,
|
static public void info( string msg, string cat = "",SourceLoc? loc = null,
|
||||||
[CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
[CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
||||||
{
|
{
|
||||||
logBase( msg, LogType.Info, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
logBase( msg, LogType.Info, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||||
}
|
}
|
||||||
|
|
||||||
[StackTraceHidden]
|
[StackTraceHidden]
|
||||||
static public void debug( string msg, string cat = "", SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
static public void debug( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
||||||
{
|
{
|
||||||
logBase( msg, LogType.Debug, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
logBase( msg, LogType.Debug, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||||
}
|
}
|
||||||
|
|
||||||
[StackTraceHidden]
|
[StackTraceHidden]
|
||||||
static public void trace( string msg, string cat = "", SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
static public void trace( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
||||||
{
|
{
|
||||||
logBase( msg, LogType.Trace, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
logBase( msg, LogType.Trace, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||||
}
|
}
|
||||||
|
|
||||||
[StackTraceHidden]
|
[StackTraceHidden]
|
||||||
static public void warn( string msg, string cat = "", SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
static public void warn( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
||||||
{
|
{
|
||||||
logBase( msg, LogType.Warn, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
logBase( msg, LogType.Warn, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||||
}
|
}
|
||||||
|
|
||||||
[StackTraceHidden]
|
[StackTraceHidden]
|
||||||
static public void high( string msg, string cat = "", SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
static public void high( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
||||||
{
|
{
|
||||||
logBase( msg, LogType.High, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
logBase( msg, LogType.High, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||||
}
|
}
|
||||||
@ -522,12 +456,12 @@ static public class log
|
|||||||
|
|
||||||
|
|
||||||
[StackTraceHidden]
|
[StackTraceHidden]
|
||||||
static public void fatal( string msg, string cat = "", SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
static public void fatal( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
||||||
{
|
{
|
||||||
logBase( msg, LogType.Fatal, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
logBase( msg, LogType.Fatal, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||||
}
|
}
|
||||||
|
|
||||||
//new LogEvent( LogType.Raw, $"", "", 0, "", "lib.time", "", null )
|
//new LogEvent( LogType.Raw, $"", "", 0, "", "lib.time", "", null )
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -612,14 +546,14 @@ static public class log
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public LogEvent logCreateEvent( string msg, LogType type = LogType.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "", SourceLoc? loc = null )
|
static public LogEvent logCreateEvent( string msg, LogType type = LogType.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "",SourceLoc? loc = null )
|
||||||
{
|
{
|
||||||
LogEvent evt = new LogEvent( type, msg, dbgPath, dbgLine, dbgMethod, cat, exp, loc );
|
LogEvent evt = new LogEvent( type, msg, dbgPath, dbgLine, dbgMethod, cat, exp, loc );
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StackTraceHidden]
|
[StackTraceHidden]
|
||||||
static public void logBase( string msg, LogType type = LogType.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "", SourceLoc? loc = null )
|
static public void logBase( string msg, LogType type = LogType.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "",SourceLoc? loc = null )
|
||||||
{
|
{
|
||||||
var evt = logCreateEvent( msg, type, dbgPath, dbgLine, dbgMethod, cat, exp );
|
var evt = logCreateEvent( msg, type, dbgPath, dbgLine, dbgMethod, cat, exp );
|
||||||
|
|
||||||
@ -1078,4 +1012,13 @@ static public class log
|
|||||||
|
|
||||||
private static ArrayList s_delegates = new ArrayList();
|
private static ArrayList s_delegates = new ArrayList();
|
||||||
|
|
||||||
}
|
static public Value<T> Value<T>( T val,
|
||||||
|
[CallerArgumentExpression("val")]
|
||||||
|
string dbgExp = ""
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return new( val, dbgExp );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end static class log
|
||||||
|
|||||||
@ -182,7 +182,7 @@ public class Ref<T> : Ref where T : class, new()
|
|||||||
// Let's assume you'll add saving logic here.
|
// Let's assume you'll add saving logic here.
|
||||||
// Mgr.Save(value, path); // Example: Needs implementation
|
// Mgr.Save(value, path); // Example: Needs implementation
|
||||||
|
|
||||||
var immMeta = ( value as io.Obj )?.Meta;
|
var immMeta = (value as io.Obj)?.Meta;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -433,7 +433,7 @@ public static class Mgr
|
|||||||
var loadedObject = loaderHolder.Load( filename, reason, dbgName, dbgPath, dbgLine );
|
var loadedObject = loaderHolder.Load( filename, reason, dbgName, dbgPath, dbgLine );
|
||||||
if( loadedObject is T value )
|
if( loadedObject is T value )
|
||||||
{
|
{
|
||||||
var meta = ( value as io.Obj )?.Meta;
|
var meta = (value as io.Obj)?.Meta;
|
||||||
|
|
||||||
// If it's an immutable object, record its loading.
|
// If it's an immutable object, record its loading.
|
||||||
if( value is io.Obj imm )
|
if( value is io.Obj imm )
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user