Better whitespace changes
This commit is contained in:
parent
28d8c145b5
commit
6b1e193c90
@ -1,41 +1,41 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net9.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>
|
||||||
<Copyright>2003..2025 Marc Hernandez</Copyright>
|
<Copyright>2003..2025 Marc Hernandez</Copyright>
|
||||||
<Description>A core set of libraries</Description>
|
<Description>A core set of libraries</Description>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<LangVersion>14.0</LangVersion>
|
<LangVersion>14.0</LangVersion>
|
||||||
<Copyright>Copyright 2003..2025 Marc Hernandez</Copyright>
|
<Copyright>Copyright 2003..2025 Marc Hernandez</Copyright>
|
||||||
<Description>A base set of </Description>
|
<Description>A base set of </Description>
|
||||||
<!--
|
<!--
|
||||||
I Want to turn this on, but cant yet. Implementing nullability 1 file at a gime
|
I Want to turn this on, but cant yet. Implementing nullability 1 file at a gime
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
-->
|
-->
|
||||||
<NoWarn>$(NoWarn);SYSLIB0050;CS8981; CS8632</NoWarn>
|
<NoWarn>$(NoWarn);SYSLIB0050;CS8981; CS8632</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
|
||||||
<PackageReference Include="Optional" Version="4.0.0" />
|
<PackageReference Include="Optional" Version="4.0.0" />
|
||||||
<PackageReference Include="Optional.Async" Version="1.3.0" />
|
<PackageReference Include="Optional.Async" Version="1.3.0" />
|
||||||
<PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
|
<PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.6.1" />
|
<PackageReference Include="System.ValueTuple" Version="4.6.1" />
|
||||||
|
|
||||||
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.621003" />
|
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.621003" />
|
||||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.24" />
|
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.24" />
|
||||||
|
|
||||||
<Folder Include="Properties\" />
|
<Folder Include="Properties\" />
|
||||||
<Folder Include="reflect\" />
|
<Folder Include="reflect\" />
|
||||||
<Folder Include="fsm\" />
|
<Folder Include="fsm\" />
|
||||||
|
|
||||||
<None Remove="fsm\" />
|
<None Remove="fsm\" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
20
imm/FSM.cs
20
imm/FSM.cs
@ -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;
|
||||||
@ -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
|
||||||
|
|||||||
72
imm/Imm.cs
72
imm/Imm.cs
@ -9,43 +9,43 @@ using System.Runtime.CompilerServices;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class imm
|
public static class imm
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes a 'Versioned' object (Level 1).
|
/// Processes a 'Versioned' object (Level 1).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
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" )
|
string reason = "Processed" )
|
||||||
where T : io.Versioned<T>
|
where T : io.Versioned<T>
|
||||||
{
|
|
||||||
obj = obj.Process( fn, reason );
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Processes a 'Recorded' object (Level 2), capturing caller info.
|
|
||||||
/// </summary>
|
|
||||||
public static T Process<T>(
|
|
||||||
ref T obj,
|
|
||||||
Func<T, T> fn,
|
|
||||||
string reason = "",
|
|
||||||
[CallerMemberName] string dbgName = "",
|
|
||||||
[CallerFilePath] string dbgPath = "",
|
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
|
||||||
[CallerArgumentExpression( "fn" )] string dbgExpression = "" )
|
|
||||||
where T : io.Recorded<T> // Catches Recorded and Timed
|
|
||||||
{
|
|
||||||
// This will call the 'Timed' override if T is Timed,
|
|
||||||
// or the 'Recorded' override if T is Recorded.
|
|
||||||
obj = obj.Process( fn, reason, dbgName, dbgPath, dbgLine, dbgExpression );
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string LogDiff<T>( T cur, T old, [CallerArgumentExpression( "cur" )] string dbgExpCur = "", [CallerArgumentExpression( "old" )] string dbgExpOld = "" )
|
|
||||||
{
|
{
|
||||||
return $"{dbgExpCur} changed from {old} to {cur}";
|
obj = obj.Process( fn, reason );
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No specific Process needed for Timed, as it's caught by Recorded<T>
|
/// <summary>
|
||||||
// and its Process override handles the timing.
|
/// Processes a 'Recorded' object (Level 2), capturing caller info.
|
||||||
|
/// </summary>
|
||||||
|
public static T Process<T>(
|
||||||
|
ref T obj,
|
||||||
|
Func<T, T> fn,
|
||||||
|
string reason = "",
|
||||||
|
[CallerMemberName] string dbgName = "",
|
||||||
|
[CallerFilePath] string dbgPath = "",
|
||||||
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
|
[CallerArgumentExpression( "fn" )] string dbgExpression = "" )
|
||||||
|
where T : io.Recorded<T> // Catches Recorded and Timed
|
||||||
|
{
|
||||||
|
// This will call the 'Timed' override if T is Timed,
|
||||||
|
// or the 'Recorded' override if T is Recorded.
|
||||||
|
obj = obj.Process( fn, reason, dbgName, dbgPath, dbgLine, dbgExpression );
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string LogDiff<T>( T cur, T old, [CallerArgumentExpression( "cur" )] string dbgExpCur = "", [CallerArgumentExpression( "old" )] string dbgExpOld = "" )
|
||||||
|
{
|
||||||
|
return $"{dbgExpCur} changed from {old} to {cur}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// No specific Process needed for Timed, as it's caught by Recorded<T>
|
||||||
|
// and its Process override handles the timing.
|
||||||
}
|
}
|
||||||
|
|||||||
86
imm/List.cs
86
imm/List.cs
@ -13,56 +13,56 @@ namespace io;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public record class List<T> : 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();
|
||||||
|
|
||||||
public ImmutableList<T> Values { get; init; } = ImmutableList<T>.Empty;
|
public ImmutableList<T> Values { get; init; } = ImmutableList<T>.Empty;
|
||||||
|
|
||||||
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(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(
|
||||||
Func<ImmutableList<T>, ImmutableList<T>> listChange,
|
Func<ImmutableList<T>, ImmutableList<T>> listChange,
|
||||||
[CallerMemberName] string dbgMethod = "",
|
[CallerMemberName] string dbgMethod = "",
|
||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[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();
|
||||||
IImmutableList<T> IImmutableList<T>.Add( T value ) => Add( value );
|
IImmutableList<T> IImmutableList<T>.Add( T value ) => Add( value );
|
||||||
IImmutableList<T> IImmutableList<T>.AddRange( IEnumerable<T> items ) => AddRange( items );
|
IImmutableList<T> IImmutableList<T>.AddRange( IEnumerable<T> items ) => AddRange( items );
|
||||||
IImmutableList<T> IImmutableList<T>.Insert( int index, T element ) => Insert( index, element );
|
IImmutableList<T> IImmutableList<T>.Insert( int index, T element ) => Insert( index, element );
|
||||||
@ -74,9 +74,9 @@ public record class List<T> : Timed<List<T>>, IImmutableList<T>
|
|||||||
IImmutableList<T> IImmutableList<T>.RemoveRange( int index, int count ) => RemoveRange( index, count );
|
IImmutableList<T> IImmutableList<T>.RemoveRange( int index, int count ) => RemoveRange( index, count );
|
||||||
IImmutableList<T> IImmutableList<T>.Replace( T oldValue, T newValue, IEqualityComparer<T>? equalityComparer ) => Replace( oldValue, newValue, equalityComparer );
|
IImmutableList<T> IImmutableList<T>.Replace( T oldValue, T newValue, IEqualityComparer<T>? equalityComparer ) => Replace( oldValue, newValue, equalityComparer );
|
||||||
IImmutableList<T> IImmutableList<T>.SetItem( int index, T value ) => SetItem( index, value );
|
IImmutableList<T> IImmutableList<T>.SetItem( int index, T value ) => SetItem( index, value );
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// --- 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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -261,7 +261,8 @@ 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,
|
||||||
|
|||||||
256
lib/CodeGen.cs
256
lib/CodeGen.cs
@ -19,164 +19,164 @@ namespace ser;
|
|||||||
|
|
||||||
public record CodeGenConfig : io.Recorded<CodeGenConfig>
|
public record CodeGenConfig : io.Recorded<CodeGenConfig>
|
||||||
{
|
{
|
||||||
// Whitelists (if needed, otherwise rely on attributes/defaults)
|
// Whitelists (if needed, otherwise rely on attributes/defaults)
|
||||||
public ImmutableDictionary<string, ImmutableList<string>> WLProps { get; init; } = ImmutableDictionary<string, ImmutableList<string>>.Empty;
|
public ImmutableDictionary<string, ImmutableList<string>> WLProps { get; init; } = ImmutableDictionary<string, ImmutableList<string>>.Empty;
|
||||||
public ImmutableDictionary<string, ImmutableList<string>> WLFields { get; init; } = ImmutableDictionary<string, ImmutableList<string>>.Empty;
|
public ImmutableDictionary<string, ImmutableList<string>> WLFields { get; init; } = ImmutableDictionary<string, ImmutableList<string>>.Empty;
|
||||||
|
|
||||||
// Default member types to process
|
// Default member types to process
|
||||||
public ser.Types TypesDefault { get; init; } = ser.Types.Fields | ser.Types.Props;
|
public ser.Types TypesDefault { get; init; } = ser.Types.Fields | ser.Types.Props;
|
||||||
|
|
||||||
// How to handle backing fields (might be less relevant for code gen)
|
// How to handle backing fields (might be less relevant for code gen)
|
||||||
public BackingFieldNaming Naming { get; init; } = BackingFieldNaming.Regular;
|
public BackingFieldNaming Naming { get; init; } = BackingFieldNaming.Regular;
|
||||||
|
|
||||||
public static CodeGenConfig Default { get; } = new CodeGenConfig();
|
public static CodeGenConfig Default { get; } = new CodeGenConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public record GenMemberMeta(
|
public record GenMemberMeta(
|
||||||
MemberInfo Info,
|
MemberInfo Info,
|
||||||
Type Type,
|
Type Type,
|
||||||
string Name, // Name for code generation (usually original)
|
string Name, // Name for code generation (usually original)
|
||||||
bool IsPrimitive,
|
bool IsPrimitive,
|
||||||
bool IsCollection,
|
bool IsCollection,
|
||||||
Type? CollectionElementType,
|
Type? CollectionElementType,
|
||||||
bool HasDo,
|
bool HasDo,
|
||||||
bool HasDont
|
bool HasDont
|
||||||
);
|
);
|
||||||
|
|
||||||
public record TypeStructureInfo(
|
public record TypeStructureInfo(
|
||||||
Type Type,
|
Type Type,
|
||||||
List<GenMemberMeta> Members,
|
List<GenMemberMeta> Members,
|
||||||
bool IsValueType,
|
bool IsValueType,
|
||||||
bool IsCollection
|
bool IsCollection
|
||||||
);
|
);
|
||||||
|
|
||||||
public class TypeStructureAnalyzer
|
public class TypeStructureAnalyzer
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<Type, TypeStructureInfo> _cache = new();
|
private readonly ConcurrentDictionary<Type, TypeStructureInfo> _cache = new();
|
||||||
private readonly CodeGenConfig _cfg;
|
private readonly CodeGenConfig _cfg;
|
||||||
|
|
||||||
public TypeStructureAnalyzer( CodeGenConfig cfg ) => _cfg = cfg;
|
public TypeStructureAnalyzer( CodeGenConfig cfg ) => _cfg = cfg;
|
||||||
|
|
||||||
public TypeStructureInfo Get( Type type ) => _cache.GetOrAdd( type, BuildTypeInfo );
|
public TypeStructureInfo Get( Type type ) => _cache.GetOrAdd( type, BuildTypeInfo );
|
||||||
|
|
||||||
private TypeStructureInfo BuildTypeInfo( Type type )
|
private TypeStructureInfo BuildTypeInfo( Type type )
|
||||||
{
|
{
|
||||||
var members = new List<GenMemberMeta>();
|
var members = new List<GenMemberMeta>();
|
||||||
var typesTodo = type.GetCustomAttribute<ser.Ser>( true )?.Types ?? _cfg.TypesDefault;
|
var typesTodo = type.GetCustomAttribute<ser.Ser>( true )?.Types ?? _cfg.TypesDefault;
|
||||||
bool doFields = typesTodo.HasFlag( ser.Types.Fields );
|
bool doFields = typesTodo.HasFlag( ser.Types.Fields );
|
||||||
bool doProps = typesTodo.HasFlag( ser.Types.Props );
|
bool doProps = typesTodo.HasFlag( ser.Types.Props );
|
||||||
|
|
||||||
// Track processed names to avoid duplicates (e.g., field + prop)
|
// Track processed names to avoid duplicates (e.g., field + prop)
|
||||||
var processedNames = new HashSet<string>();
|
var processedNames = new HashSet<string>();
|
||||||
|
|
||||||
// Process Properties First (often preferred interface)
|
// Process Properties First (often preferred interface)
|
||||||
if( doProps )
|
if( doProps )
|
||||||
{
|
{
|
||||||
foreach( var pi in refl.GetAllProperties( type ) )
|
foreach( var pi in refl.GetAllProperties( type ) )
|
||||||
{
|
{
|
||||||
if( ProcessMember( pi, false, false, new HashSet<string>(), false, members ) )
|
if( ProcessMember( pi, false, false, new HashSet<string>(), false, members ) )
|
||||||
{
|
{
|
||||||
processedNames.Add( pi.Name );
|
processedNames.Add( pi.Name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process Fields, avoiding those already covered by properties
|
// Process Fields, avoiding those already covered by properties
|
||||||
if( doFields )
|
if( doFields )
|
||||||
{
|
{
|
||||||
foreach( var fi in refl.GetAllFields( type ) )
|
foreach( var fi in refl.GetAllFields( type ) )
|
||||||
{
|
{
|
||||||
var (isBacking, propName) = IsBackingField( fi );
|
var (isBacking, propName) = IsBackingField( fi );
|
||||||
string nameToTest = isBacking ? propName : fi.Name;
|
string nameToTest = isBacking ? propName : fi.Name;
|
||||||
|
|
||||||
if( !processedNames.Contains( nameToTest ) )
|
if( !processedNames.Contains( nameToTest ) )
|
||||||
{
|
{
|
||||||
if( ProcessMember( fi, false, false, new HashSet<string>(), false, members ) )
|
if( ProcessMember( fi, false, false, new HashSet<string>(), false, members ) )
|
||||||
{
|
{
|
||||||
processedNames.Add( nameToTest );
|
processedNames.Add( nameToTest );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TypeStructureInfo(
|
return new TypeStructureInfo(
|
||||||
type,
|
type,
|
||||||
members,
|
members,
|
||||||
type.IsValueType,
|
type.IsValueType,
|
||||||
typeof( IEnumerable ).IsAssignableFrom( type ) && type != typeof( string )
|
typeof( IEnumerable ).IsAssignableFrom( type ) && type != typeof( string )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ProcessMember( MemberInfo mi, bool filter, bool doImpls, HashSet<string> whitelist, bool isImm, List<GenMemberMeta> members )
|
private bool ProcessMember( MemberInfo mi, bool filter, bool doImpls, HashSet<string> whitelist, bool isImm, List<GenMemberMeta> members )
|
||||||
{
|
{
|
||||||
var (hasDo, hasDont, propName) = GetMemberAttributes( mi, out var actualMiForAtts );
|
var (hasDo, hasDont, propName) = GetMemberAttributes( mi, out var actualMiForAtts );
|
||||||
|
|
||||||
if( hasDont )
|
if( hasDont )
|
||||||
return false;
|
return false;
|
||||||
if( mi.GetCustomAttribute<NonSerializedAttribute>( true ) != null )
|
if( mi.GetCustomAttribute<NonSerializedAttribute>( true ) != null )
|
||||||
return false;
|
return false;
|
||||||
if( mi.Name.Contains( "k__BackingField" ) && !propName.Any() )
|
if( mi.Name.Contains( "k__BackingField" ) && !propName.Any() )
|
||||||
return false; // Skip if backing but no prop found
|
return false; // Skip if backing but no prop found
|
||||||
|
|
||||||
string name = string.IsNullOrEmpty( propName ) ? mi.Name : propName;
|
string name = string.IsNullOrEmpty( propName ) ? mi.Name : propName;
|
||||||
|
|
||||||
// Add filtering logic if needed (based on whitelist, etc.)
|
// Add filtering logic if needed (based on whitelist, etc.)
|
||||||
|
|
||||||
var type = ( mi is FieldInfo fi ) ? fi.FieldType : ( (PropertyInfo)mi ).PropertyType;
|
var type = ( mi is FieldInfo fi ) ? fi.FieldType : ( (PropertyInfo)mi ).PropertyType;
|
||||||
bool isCollection = typeof( IEnumerable ).IsAssignableFrom( type ) && type != typeof( string );
|
bool isCollection = typeof( IEnumerable ).IsAssignableFrom( type ) && type != typeof( string );
|
||||||
Type? elementType = isCollection ? GetElementType( type ) : null;
|
Type? elementType = isCollection ? GetElementType( type ) : null;
|
||||||
bool isPrimitive = Type.GetTypeCode( type ) != TypeCode.Object && !isCollection;
|
bool isPrimitive = Type.GetTypeCode( type ) != TypeCode.Object && !isCollection;
|
||||||
|
|
||||||
members.Add( new GenMemberMeta(
|
members.Add( new GenMemberMeta(
|
||||||
mi, type, name, isPrimitive, isCollection, elementType, hasDo, hasDont
|
mi, type, name, isPrimitive, isCollection, elementType, hasDo, hasDont
|
||||||
) );
|
) );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (bool, string) IsBackingField( FieldInfo fi )
|
private (bool, string) IsBackingField( FieldInfo fi )
|
||||||
{
|
{
|
||||||
if( fi.Name.StartsWith( "<" ) && fi.Name.EndsWith( "BackingField" ) )
|
if( fi.Name.StartsWith( "<" ) && fi.Name.EndsWith( "BackingField" ) )
|
||||||
{
|
{
|
||||||
var gtIndex = fi.Name.IndexOf( '>' );
|
var gtIndex = fi.Name.IndexOf( '>' );
|
||||||
if( gtIndex > 1 )
|
if( gtIndex > 1 )
|
||||||
{
|
{
|
||||||
return (true, fi.Name.Substring( 1, gtIndex - 1 ));
|
return (true, fi.Name.Substring( 1, gtIndex - 1 ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (false, "");
|
return (false, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private (bool hasDo, bool hasDont, string propName) GetMemberAttributes( MemberInfo mi, out MemberInfo actualMi )
|
private (bool hasDo, bool hasDont, string propName) GetMemberAttributes( MemberInfo mi, out MemberInfo actualMi )
|
||||||
{
|
{
|
||||||
actualMi = mi;
|
actualMi = mi;
|
||||||
string propName = "";
|
string propName = "";
|
||||||
if( mi is FieldInfo fi && IsBackingField( fi ).Item1 )
|
if( mi is FieldInfo fi && IsBackingField( fi ).Item1 )
|
||||||
{
|
{
|
||||||
propName = IsBackingField( fi ).Item2;
|
propName = IsBackingField( fi ).Item2;
|
||||||
var propInfo = mi.DeclaringType?.GetProperty( propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
|
var propInfo = mi.DeclaringType?.GetProperty( propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
|
||||||
if( propInfo != null )
|
if( propInfo != null )
|
||||||
actualMi = propInfo;
|
actualMi = propInfo;
|
||||||
}
|
}
|
||||||
else if( mi is PropertyInfo )
|
else if( mi is PropertyInfo )
|
||||||
{
|
{
|
||||||
propName = mi.Name;
|
propName = mi.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
actualMi.GetCustomAttribute<ser.Do>() != null,
|
actualMi.GetCustomAttribute<ser.Do>() != null,
|
||||||
actualMi.GetCustomAttribute<ser.Dont>() != null,
|
actualMi.GetCustomAttribute<ser.Dont>() != null,
|
||||||
propName
|
propName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type GetElementType( Type collectionType )
|
private Type GetElementType( Type collectionType )
|
||||||
{
|
{
|
||||||
if( collectionType.IsArray )
|
if( collectionType.IsArray )
|
||||||
return collectionType.GetElementType()!;
|
return collectionType.GetElementType()!;
|
||||||
if( collectionType.IsGenericType )
|
if( collectionType.IsGenericType )
|
||||||
return collectionType.GetGenericArguments().Last(); // Usually last (e.g., List<T>, Dict<K,V>)
|
return collectionType.GetGenericArguments().Last(); // Usually last (e.g., List<T>, Dict<K,V>)
|
||||||
return typeof( object ); // Fallback
|
return typeof( object ); // Fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add GetFilters and FilterField if needed, or simplify as above
|
// Add GetFilters and FilterField if needed, or simplify as above
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,7 +139,7 @@ namespace lib
|
|||||||
|
|
||||||
private string fromStr = "";
|
private string fromStr = "";
|
||||||
|
|
||||||
void SetFromStr( Stream stream )
|
void SetFromStr( Stream stream )
|
||||||
{
|
{
|
||||||
fromStr = stream.ToString() ?? "{null}";
|
fromStr = stream.ToString() ?? "{null}";
|
||||||
|
|
||||||
@ -186,7 +186,8 @@ namespace lib
|
|||||||
|
|
||||||
doc.Load( reader );
|
doc.Load( reader );
|
||||||
|
|
||||||
if( doc.DocumentElement == null ) return null;
|
if( doc.DocumentElement == null )
|
||||||
|
return null;
|
||||||
|
|
||||||
if( t == null )
|
if( t == null )
|
||||||
return Deserialize( doc.DocumentElement );
|
return Deserialize( doc.DocumentElement );
|
||||||
@ -256,7 +257,8 @@ namespace lib
|
|||||||
{
|
{
|
||||||
TypeCode typeCode = Type.GetTypeCode( type );
|
TypeCode typeCode = Type.GetTypeCode( type );
|
||||||
|
|
||||||
if( _cfg.VerboseLogging ) log.info( $"{type.FriendlyName()}.{name} {existing} {mi?.Name}" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"{type.FriendlyName()}.{name} {existing} {mi?.Name}" );
|
||||||
|
|
||||||
if( typeCode != TypeCode.Object )
|
if( typeCode != TypeCode.Object )
|
||||||
{
|
{
|
||||||
@ -276,7 +278,8 @@ namespace lib
|
|||||||
|
|
||||||
if( obj is ser.I_Serialize iser )
|
if( obj is ser.I_Serialize iser )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging ) log.info( $"" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"" );
|
||||||
obj = iser.OnDeserialize( null );
|
obj = iser.OnDeserialize( null );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +317,8 @@ 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 ) log.info( $"" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"" );
|
||||||
|
|
||||||
string val = "";
|
string val = "";
|
||||||
|
|
||||||
@ -398,7 +402,8 @@ 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 ) log.info( $"" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"" );
|
||||||
|
|
||||||
if( obj is IList )
|
if( obj is IList )
|
||||||
{
|
{
|
||||||
@ -488,9 +493,10 @@ 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 ) log.info( $"" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"" );
|
||||||
|
|
||||||
var isImm = typeof(io.Obj).IsAssignableFrom( narrowType );
|
var isImm = typeof( io.Obj ).IsAssignableFrom( narrowType );
|
||||||
|
|
||||||
XmlNodeList allChildren = elem.ChildNodes;
|
XmlNodeList allChildren = elem.ChildNodes;
|
||||||
|
|
||||||
@ -536,7 +542,7 @@ namespace lib
|
|||||||
name = refl.TypeToIdentifier( name );
|
name = refl.TypeToIdentifier( name );
|
||||||
|
|
||||||
// @@@ TODO This doesnt yet handle propNames!
|
// @@@ TODO This doesnt yet handle propNames!
|
||||||
if( !doAtt.Any() && FilterField( filterFields, doImpls, whitelistFields, childFi as MemberInfo, name ) )
|
if( !doAtt.Any() && FilterField( filterFields, doImpls, whitelistFields, childFi as MemberInfo, name ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var useFieldName = true;
|
var useFieldName = true;
|
||||||
@ -625,7 +631,7 @@ namespace lib
|
|||||||
{
|
{
|
||||||
object existingObj = childPi.GetValue( obj );
|
object existingObj = childPi.GetValue( obj );
|
||||||
|
|
||||||
object childObj = DeserializeConcrete( elem, childPi, name, childPi.PropertyType );
|
object childObj = DeserializeConcrete( elem, childPi, name, childPi.PropertyType );
|
||||||
|
|
||||||
if( setMethod != null )
|
if( setMethod != null )
|
||||||
{
|
{
|
||||||
@ -642,7 +648,7 @@ namespace lib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isImm)
|
if( !isImm )
|
||||||
{
|
{
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -686,7 +692,8 @@ namespace lib
|
|||||||
|
|
||||||
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
||||||
|
|
||||||
if( _cfg.VerboseLogging ) log.info( $"{finalType?.FriendlyName()}({type?.FriendlyName()}) refInt {refInt} exitingObj = {obj?.ToString()}" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"{finalType?.FriendlyName()}({type?.FriendlyName()}) refInt {refInt} exitingObj = {obj?.ToString()}" );
|
||||||
|
|
||||||
obj = createObject( elem, finalType, refInt, obj );
|
obj = createObject( elem, finalType, refInt, obj );
|
||||||
|
|
||||||
@ -695,7 +702,8 @@ 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 ) log.info( $"" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"" );
|
||||||
|
|
||||||
XmlNodeList arrNodeList = elem.ChildNodes;
|
XmlNodeList arrNodeList = elem.ChildNodes;
|
||||||
|
|
||||||
@ -731,7 +739,8 @@ namespace lib
|
|||||||
typeElem = typeof( KeyValuePair<,> ).MakeGenericType( type.GenericTypeArguments );
|
typeElem = typeof( KeyValuePair<,> ).MakeGenericType( type.GenericTypeArguments );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _cfg.VerboseLogging ) log.info( $"DserCol {type.GetType().FriendlyName()} {typeElem.Name} into reflT {mi.ReflectedType.FriendlyName()} declT {mi.DeclaringType.FriendlyName()} {mi.Name}" );
|
if( _cfg.VerboseLogging )
|
||||||
|
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;
|
||||||
@ -776,7 +785,8 @@ namespace lib
|
|||||||
|
|
||||||
var typeGen = Type.MakeGenericSignatureType( type );
|
var typeGen = Type.MakeGenericSignatureType( type );
|
||||||
|
|
||||||
if( _cfg.VerboseLogging ) log.info( $"TypeGen: {typeGen.FriendlyName()}" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"TypeGen: {typeGen.FriendlyName()}" );
|
||||||
|
|
||||||
if( type == typeof( ImmutableArray<> ).MakeGenericType( typeElem ) )
|
if( type == typeof( ImmutableArray<> ).MakeGenericType( typeElem ) )
|
||||||
{
|
{
|
||||||
@ -833,7 +843,8 @@ namespace lib
|
|||||||
|
|
||||||
private object DeserializeArray( XmlElement elem, MemberInfo mi, Type type )
|
private object DeserializeArray( XmlElement elem, MemberInfo mi, Type type )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging ) log.info( $"" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"" );
|
||||||
|
|
||||||
Type typeElem = type.GetElementType();
|
Type typeElem = type.GetElementType();
|
||||||
|
|
||||||
@ -883,7 +894,8 @@ 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 ) log.info( $"Reuse object" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"Reuse object" );
|
||||||
return m_alreadySerialized[refInt];
|
return m_alreadySerialized[refInt];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -893,7 +905,8 @@ namespace lib
|
|||||||
|
|
||||||
if( isProxy )
|
if( isProxy )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging ) log.info( $"use Proxy" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"use Proxy" );
|
||||||
object obj = null;
|
object obj = null;
|
||||||
|
|
||||||
var tryType = type;
|
var tryType = type;
|
||||||
@ -937,7 +950,8 @@ namespace lib
|
|||||||
|
|
||||||
if( isSubclass )
|
if( isSubclass )
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging ) log.info( $"Using existing obj {existingObj?.ToString()}" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"Using existing obj {existingObj?.ToString()}" );
|
||||||
return existingObj;
|
return existingObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,12 +967,14 @@ namespace lib
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging ) log.info( $"For {type.FriendlyName()} check for constructors" );
|
if( _cfg.VerboseLogging )
|
||||||
|
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 ) log.info( $"Activator.CreateInstance" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"Activator.CreateInstance" );
|
||||||
obj = Activator.CreateInstance( type );
|
obj = Activator.CreateInstance( type );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -967,15 +983,18 @@ namespace lib
|
|||||||
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
|
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _cfg.VerboseLogging ) log.info( $"Got obj {obj?.ToString()}" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"Got obj {obj?.ToString()}" );
|
||||||
}
|
}
|
||||||
catch( Exception )
|
catch( Exception )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( _cfg.VerboseLogging ) log.info( $"GetUninitializedObject" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"GetUninitializedObject" );
|
||||||
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
|
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
|
||||||
if( _cfg.VerboseLogging ) log.info( $"Got obj {obj?.ToString()}" );
|
if( _cfg.VerboseLogging )
|
||||||
|
log.info( $"Got obj {obj?.ToString()}" );
|
||||||
}
|
}
|
||||||
catch( Exception exInner )
|
catch( Exception exInner )
|
||||||
{
|
{
|
||||||
@ -1290,7 +1309,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 )
|
||||||
{
|
{
|
||||||
@ -1323,8 +1342,10 @@ namespace lib
|
|||||||
|
|
||||||
if( isImm )
|
if( isImm )
|
||||||
{
|
{
|
||||||
if( name == "MetaStorage" ) continue;
|
if( name == "MetaStorage" )
|
||||||
if( name == "Fn" ) continue;
|
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 ) )
|
||||||
@ -1365,8 +1386,10 @@ namespace lib
|
|||||||
|
|
||||||
if( isImm )
|
if( isImm )
|
||||||
{
|
{
|
||||||
if( name == "MetaStorage" ) continue;
|
if( name == "MetaStorage" )
|
||||||
if( name == "Fn" ) continue;
|
continue;
|
||||||
|
if( name == "Fn" )
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FilterField( filterProps, doImpls, whitelistProps, childPi as MemberInfo, name ) )
|
if( FilterField( filterProps, doImpls, whitelistProps, childPi as MemberInfo, name ) )
|
||||||
@ -1393,15 +1416,15 @@ namespace lib
|
|||||||
var custWLProps = mi?.GetCustomAttribute<ser.ChildPropsAttribute>( true );
|
var custWLProps = mi?.GetCustomAttribute<ser.ChildPropsAttribute>( true );
|
||||||
|
|
||||||
filterFields = custWLFields != null;
|
filterFields = custWLFields != null;
|
||||||
filterProps = custWLProps != null;
|
filterProps = custWLProps != null;
|
||||||
|
|
||||||
var typesTodo = type.GetCustomAttribute<ser.Ser>( true )?.Types ?? TypesDefault;
|
var typesTodo = type.GetCustomAttribute<ser.Ser>( true )?.Types ?? TypesDefault;
|
||||||
|
|
||||||
doImpls = typesTodo.HasFlag( ser.Types.Implied );
|
doImpls = typesTodo.HasFlag( ser.Types.Implied );
|
||||||
doFields = filterFields || typesTodo.HasFlag( ser.Types.Fields );
|
doFields = filterFields || typesTodo.HasFlag( ser.Types.Fields );
|
||||||
doProps = filterProps || typesTodo.HasFlag( ser.Types.Props );
|
doProps = filterProps || typesTodo.HasFlag( ser.Types.Props );
|
||||||
whitelistFields = new( custWLFields?.Values ?? new string[0] );
|
whitelistFields = new( custWLFields?.Values ?? new string[0] );
|
||||||
whitelistProps = new( custWLProps?.Values ?? new string[0] );
|
whitelistProps = new( custWLProps?.Values ?? new string[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SerializeArray( XmlWriter writer, MemberInfo mi, Type mType, object root, int depth )
|
private void SerializeArray( XmlWriter writer, MemberInfo mi, Type mType, object root, int depth )
|
||||||
@ -1413,8 +1436,10 @@ namespace lib
|
|||||||
Type type = root.GetType();
|
Type type = root.GetType();
|
||||||
|
|
||||||
Type typeOfMember = typeof( object );
|
Type typeOfMember = typeof( object );
|
||||||
if( mi is FieldInfo fi ) typeOfMember = fi.FieldType;
|
if( mi is FieldInfo fi )
|
||||||
if( mi is PropertyInfo pi ) typeOfMember = pi.PropertyType;
|
typeOfMember = fi.FieldType;
|
||||||
|
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()}" );
|
||||||
|
|||||||
@ -174,14 +174,14 @@ static public class log
|
|||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
File = 1 << 0,
|
File = 1 << 0,
|
||||||
Console = 1 << 1,
|
Console = 1 << 1,
|
||||||
|
|
||||||
All = File | Console,
|
All = File | Console,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region LogEvent
|
#region LogEvent
|
||||||
|
|
||||||
public struct LogEvent
|
public struct LogEvent
|
||||||
{
|
{
|
||||||
@ -256,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
|
#endregion // LogEvent
|
||||||
|
|
||||||
static public void shutdown()
|
static public void shutdown()
|
||||||
{
|
{
|
||||||
@ -299,7 +299,7 @@ static public class log
|
|||||||
pathPieces = path.Split( '/' );
|
pathPieces = path.Split( '/' );
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastPathPiece = pathPieces[pathPieces.Length - 1];
|
var lastPathPiece = pathPieces[pathPieces.Length - 1];
|
||||||
|
|
||||||
ImmutableInterlocked.AddOrUpdate( ref s_files, pathHash, lastPathPiece, ( key, value ) => { return lastPathPiece; } );
|
ImmutableInterlocked.AddOrUpdate( ref s_files, pathHash, lastPathPiece, ( key, value ) => { return lastPathPiece; } );
|
||||||
|
|
||||||
@ -396,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 );
|
||||||
}
|
}
|
||||||
@ -456,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
|
||||||
|
|
||||||
@ -523,7 +523,7 @@ static public class log
|
|||||||
|
|
||||||
foreach( var fr in stackTrace.GetFrames() )
|
foreach( var fr in stackTrace.GetFrames() )
|
||||||
{
|
{
|
||||||
logBase( $"{fr.Log}", LogType.Raw );
|
logBase( $"{fr.Log}", LogType.Raw );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,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 );
|
||||||
|
|
||||||
|
|||||||
416
math/Half.cs
416
math/Half.cs
@ -29,239 +29,239 @@ using System.Runtime.Serialization;
|
|||||||
|
|
||||||
namespace math
|
namespace math
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A half precision (16 bit) floating point value.
|
/// A half precision (16 bit) floating point value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataContract]
|
[DataContract]
|
||||||
[StructLayout( LayoutKind.Sequential, Pack = 2 )]
|
[StructLayout( LayoutKind.Sequential, Pack = 2 )]
|
||||||
public struct Half
|
public struct Half
|
||||||
{
|
{
|
||||||
private ushort value;
|
private ushort value;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Number of decimal digits of precision.
|
/// Number of decimal digits of precision.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int PrecisionDigits = 3;
|
public const int PrecisionDigits = 3;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Number of bits in the mantissa.
|
/// Number of bits in the mantissa.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MantissaBits = 11;
|
public const int MantissaBits = 11;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum decimal exponent.
|
/// Maximum decimal exponent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MaximumDecimalExponent = 4;
|
public const int MaximumDecimalExponent = 4;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum binary exponent.
|
/// Maximum binary exponent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MaximumBinaryExponent = 15;
|
public const int MaximumBinaryExponent = 15;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Minimum decimal exponent.
|
/// Minimum decimal exponent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MinimumDecimalExponent = -4;
|
public const int MinimumDecimalExponent = -4;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Minimum binary exponent.
|
/// Minimum binary exponent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MinimumBinaryExponent = -14;
|
public const int MinimumBinaryExponent = -14;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Exponent radix.
|
/// Exponent radix.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int ExponentRadix = 2;
|
public const int ExponentRadix = 2;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Additional rounding.
|
/// Additional rounding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int AdditionRounding = 1;
|
public const int AdditionRounding = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Smallest such that 1.0 + epsilon != 1.0
|
/// Smallest such that 1.0 + epsilon != 1.0
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly float Epsilon;
|
public static readonly float Epsilon;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum value of the number.
|
/// Maximum value of the number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly float MaxValue;
|
public static readonly float MaxValue;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Minimum value of the number.
|
/// Minimum value of the number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly float MinValue;
|
public static readonly float MinValue;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A <see cref="Half"/> whose value is 0.0f.
|
/// A <see cref="Half"/> whose value is 0.0f.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Half Zero;
|
public static readonly Half Zero;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A <see cref="Half"/> whose value is 1.0f.
|
/// A <see cref="Half"/> whose value is 1.0f.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Half One;
|
public static readonly Half One;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Half"/> structure.
|
/// Initializes a new instance of the <see cref="Half"/> structure.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "value">The floating point value that should be stored in 16 bit format.</param>
|
/// <param name = "value">The floating point value that should be stored in 16 bit format.</param>
|
||||||
public Half( float value )
|
public Half( float value )
|
||||||
{
|
{
|
||||||
this.value = HalfUtils.Pack( value );
|
this.value = HalfUtils.Pack( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the raw 16 bit value used to back this half-float.
|
/// Gets or sets the raw 16 bit value used to back this half-float.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ushort RawValue
|
public ushort RawValue
|
||||||
{
|
{
|
||||||
get { return value; }
|
get { return value; }
|
||||||
set { this.value = value; }
|
set { this.value = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an array of half precision values into full precision values.
|
/// Converts an array of half precision values into full precision values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "values">The values to be converted.</param>
|
/// <param name = "values">The values to be converted.</param>
|
||||||
/// <returns>An array of converted values.</returns>
|
/// <returns>An array of converted values.</returns>
|
||||||
public static float[] ConvertToFloat( Half[] values )
|
public static float[] ConvertToFloat( Half[] values )
|
||||||
{
|
{
|
||||||
float[] results = new float[values.Length];
|
float[] results = new float[values.Length];
|
||||||
for( int i = 0; i < results.Length; i++ )
|
for( int i = 0; i < results.Length; i++ )
|
||||||
results[i] = HalfUtils.Unpack( values[i].RawValue );
|
results[i] = HalfUtils.Unpack( values[i].RawValue );
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an array of full precision values into half precision values.
|
/// Converts an array of full precision values into half precision values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "values">The values to be converted.</param>
|
/// <param name = "values">The values to be converted.</param>
|
||||||
/// <returns>An array of converted values.</returns>
|
/// <returns>An array of converted values.</returns>
|
||||||
public static Half[] ConvertToHalf( float[] values )
|
public static Half[] ConvertToHalf( float[] values )
|
||||||
{
|
{
|
||||||
Half[] results = new Half[values.Length];
|
Half[] results = new Half[values.Length];
|
||||||
for( int i = 0; i < results.Length; i++ )
|
for( int i = 0; i < results.Length; i++ )
|
||||||
results[i] = new Half( values[i] );
|
results[i] = new Half( values[i] );
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs an explicit conversion from <see cref = "T:System.Single" /> to <see cref = "T:math.Half" />.
|
/// Performs an explicit conversion from <see cref = "T:System.Single" /> to <see cref = "T:math.Half" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "value">The value to be converted.</param>
|
/// <param name = "value">The value to be converted.</param>
|
||||||
/// <returns>The converted value.</returns>
|
/// <returns>The converted value.</returns>
|
||||||
public static explicit operator Half( float value )
|
public static explicit operator Half( float value )
|
||||||
{
|
{
|
||||||
return new Half( value );
|
return new Half( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs an implicit conversion from <see cref = "T:math.Half" /> to <see cref = "T:System.Single" />.
|
/// Performs an implicit conversion from <see cref = "T:math.Half" /> to <see cref = "T:System.Single" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "value">The value to be converted.</param>
|
/// <param name = "value">The value to be converted.</param>
|
||||||
/// <returns>The converted value.</returns>
|
/// <returns>The converted value.</returns>
|
||||||
public static implicit operator float( Half value )
|
public static implicit operator float( Half value )
|
||||||
{
|
{
|
||||||
return HalfUtils.Unpack( value.value );
|
return HalfUtils.Unpack( value.value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests for equality between two objects.
|
/// Tests for equality between two objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "left">The first value to compare.</param>
|
/// <param name = "left">The first value to compare.</param>
|
||||||
/// <param name = "right">The second value to compare.</param>
|
/// <param name = "right">The second value to compare.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// <c>true</c> if <paramref name = "left" /> has the same value as <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
/// <c>true</c> if <paramref name = "left" /> has the same value as <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
||||||
public static bool operator ==( Half left, Half right )
|
public static bool operator ==( Half left, Half right )
|
||||||
{
|
{
|
||||||
return left.value == right.value;
|
return left.value == right.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests for inequality between two objects.
|
/// Tests for inequality between two objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "left">The first value to compare.</param>
|
/// <param name = "left">The first value to compare.</param>
|
||||||
/// <param name = "right">The second value to compare.</param>
|
/// <param name = "right">The second value to compare.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// <c>true</c> if <paramref name = "left" /> has a different value than <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
/// <c>true</c> if <paramref name = "left" /> has a different value than <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
||||||
public static bool operator !=( Half left, Half right )
|
public static bool operator !=( Half left, Half right )
|
||||||
{
|
{
|
||||||
return left.value != right.value;
|
return left.value != right.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the value of the object to its equivalent string representation.
|
/// Converts the value of the object to its equivalent string representation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The string representation of the value of this instance.</returns>
|
/// <returns>The string representation of the value of this instance.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
float num = this;
|
float num = this;
|
||||||
return num.ToString( CultureInfo.CurrentCulture );
|
return num.ToString( CultureInfo.CurrentCulture );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the hash code for this instance.
|
/// Returns the hash code for this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A 32-bit signed integer hash code.</returns>
|
/// <returns>A 32-bit signed integer hash code.</returns>
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
ushort num = value;
|
ushort num = value;
|
||||||
return ( ( num * 3 ) / 2 ) ^ num;
|
return ( ( num * 3 ) / 2 ) ^ num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified object instances are considered equal.
|
/// Determines whether the specified object instances are considered equal.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "value1">The first value.</param>
|
/// <param name = "value1">The first value.</param>
|
||||||
/// <param name = "value2">The second value.</param>
|
/// <param name = "value2">The second value.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// <c>true</c> if <paramref name = "value1" /> is the same instance as <paramref name = "value2" /> or
|
/// <c>true</c> if <paramref name = "value1" /> is the same instance as <paramref name = "value2" /> or
|
||||||
/// if both are <c>null</c> references or if <c>value1.Equals(value2)</c> returns <c>true</c>; otherwise, <c>false</c>.</returns>
|
/// if both are <c>null</c> references or if <c>value1.Equals(value2)</c> returns <c>true</c>; otherwise, <c>false</c>.</returns>
|
||||||
public static bool Equals( ref Half value1, ref Half value2 )
|
public static bool Equals( ref Half value1, ref Half value2 )
|
||||||
{
|
{
|
||||||
return value1.value == value2.value;
|
return value1.value == value2.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a value that indicates whether the current instance is equal to the specified object.
|
/// Returns a value that indicates whether the current instance is equal to the specified object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "other">Object to make the comparison with.</param>
|
/// <param name = "other">Object to make the comparison with.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||||
public bool Equals( Half other )
|
public bool Equals( Half other )
|
||||||
{
|
{
|
||||||
return other.value == value;
|
return other.value == value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a value that indicates whether the current instance is equal to a specified object.
|
/// Returns a value that indicates whether the current instance is equal to a specified object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "obj">Object to make the comparison with.</param>
|
/// <param name = "obj">Object to make the comparison with.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||||
public override bool Equals( object obj )
|
public override bool Equals( object obj )
|
||||||
{
|
{
|
||||||
if( obj == null )
|
if( obj == null )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if( obj.GetType() != GetType() )
|
if( obj.GetType() != GetType() )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Half half = (Half)obj;
|
Half half = (Half)obj;
|
||||||
return half.value == value;
|
return half.value == value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Half()
|
static Half()
|
||||||
{
|
{
|
||||||
Epsilon = 0.0004887581f;
|
Epsilon = 0.0004887581f;
|
||||||
MaxValue = 65504f;
|
MaxValue = 65504f;
|
||||||
MinValue = 6.103516E-05f;
|
MinValue = 6.103516E-05f;
|
||||||
Zero = (Half)0.0f;
|
Zero = (Half)0.0f;
|
||||||
One = (Half)1.0f;
|
One = (Half)1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1472
math/Int3.cs
1472
math/Int3.cs
File diff suppressed because it is too large
Load Diff
188
math/Size2F.cs
188
math/Size2F.cs
@ -27,108 +27,108 @@ using System.Runtime.Serialization;
|
|||||||
|
|
||||||
namespace math
|
namespace math
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines a 2D rectangular size (width,height).
|
/// Defines a 2D rectangular size (width,height).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataContract( Name = "Size2F" )]
|
[DataContract( Name = "Size2F" )]
|
||||||
[DataStyle( DataStyle.Compact )]
|
[DataStyle( DataStyle.Compact )]
|
||||||
[StructLayout( LayoutKind.Sequential, Pack = 4 )]
|
[StructLayout( LayoutKind.Sequential, Pack = 4 )]
|
||||||
public struct Size2F : IEquatable<Size2F>
|
public struct Size2F : IEquatable<Size2F>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A zero size with (width, height) = (0,0)
|
/// A zero size with (width, height) = (0,0)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Size2F Zero = new Size2F( 0, 0 );
|
public static readonly Size2F Zero = new Size2F( 0, 0 );
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A zero size with (width, height) = (0,0)
|
/// A zero size with (width, height) = (0,0)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Size2F Empty = Zero;
|
public static readonly Size2F Empty = Zero;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Size2F"/> struct.
|
/// Initializes a new instance of the <see cref="Size2F"/> struct.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="width">The x.</param>
|
/// <param name="width">The x.</param>
|
||||||
/// <param name="height">The y.</param>
|
/// <param name="height">The y.</param>
|
||||||
public Size2F( float width, float height )
|
public Size2F( float width, float height )
|
||||||
{
|
{
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Width.
|
/// Width.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataMember( Order = 0 )]
|
[DataMember( Order = 0 )]
|
||||||
public float Width;
|
public float Width;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Height.
|
/// Height.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataMember( Order = 1 )]
|
[DataMember( Order = 1 )]
|
||||||
public float Height;
|
public float Height;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="other">The <see cref="object"/> to compare with this instance.</param>
|
/// <param name="other">The <see cref="object"/> to compare with this instance.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public bool Equals( Size2F other )
|
public bool Equals( Size2F other )
|
||||||
{
|
{
|
||||||
return other.Width == Width && other.Height == Height;
|
return other.Width == Width && other.Height == Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool Equals( object obj )
|
public override bool Equals( object obj )
|
||||||
{
|
{
|
||||||
if( ReferenceEquals( null, obj ) )
|
if( ReferenceEquals( null, obj ) )
|
||||||
return false;
|
return false;
|
||||||
if( obj.GetType() != typeof( Size2F ) )
|
if( obj.GetType() != typeof( Size2F ) )
|
||||||
return false;
|
return false;
|
||||||
return Equals( (Size2F)obj );
|
return Equals( (Size2F)obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
return ( Width.GetHashCode() * 397 ) ^ Height.GetHashCode();
|
return ( Width.GetHashCode() * 397 ) ^ Height.GetHashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements the operator ==.
|
/// Implements the operator ==.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="left">The left.</param>
|
/// <param name="left">The left.</param>
|
||||||
/// <param name="right">The right.</param>
|
/// <param name="right">The right.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The result of the operator.
|
/// The result of the operator.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public static bool operator ==( Size2F left, Size2F right )
|
public static bool operator ==( Size2F left, Size2F right )
|
||||||
{
|
{
|
||||||
return left.Equals( right );
|
return left.Equals( right );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements the operator !=.
|
/// Implements the operator !=.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="left">The left.</param>
|
/// <param name="left">The left.</param>
|
||||||
/// <param name="right">The right.</param>
|
/// <param name="right">The right.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The result of the operator.
|
/// The result of the operator.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public static bool operator !=( Size2F left, Size2F right )
|
public static bool operator !=( Size2F left, Size2F right )
|
||||||
{
|
{
|
||||||
return !left.Equals( right );
|
return !left.Equals( right );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format( "({0},{1})", Width, Height );
|
return string.Format( "({0},{1})", Width, Height );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,63 +2,63 @@
|
|||||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||||
namespace math
|
namespace math
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extensions methods of the vector classes.
|
/// Extensions methods of the vector classes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class VectorExtensions
|
public static class VectorExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the Y/X components of the vector in the inverse order.
|
/// Return the Y/X components of the vector in the inverse order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vector">the input vector</param>
|
/// <param name="vector">the input vector</param>
|
||||||
public static Vec2 YX( this Vec2 vector )
|
public static Vec2 YX( this Vec2 vector )
|
||||||
{
|
{
|
||||||
return new Vec2( vector.Y, vector.X );
|
return new Vec2( vector.Y, vector.X );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the X/Y components of the vector.
|
/// Return the X/Y components of the vector.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vector">the input vector</param>
|
/// <param name="vector">the input vector</param>
|
||||||
public static Vec2 XY( this Vec3 vector )
|
public static Vec2 XY( this Vec3 vector )
|
||||||
{
|
{
|
||||||
return new Vec2( vector.X, vector.Y );
|
return new Vec2( vector.X, vector.Y );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the X/Z components of the vector.
|
/// Return the X/Z components of the vector.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vector">the input vector</param>
|
/// <param name="vector">the input vector</param>
|
||||||
public static Vec2 XZ( this Vec3 vector )
|
public static Vec2 XZ( this Vec3 vector )
|
||||||
{
|
{
|
||||||
return new Vec2( vector.X, vector.Z );
|
return new Vec2( vector.X, vector.Z );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the Y/Z components of the vector.
|
/// Return the Y/Z components of the vector.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vector">the input vector</param>
|
/// <param name="vector">the input vector</param>
|
||||||
public static Vec2 YZ( this Vec3 vector )
|
public static Vec2 YZ( this Vec3 vector )
|
||||||
{
|
{
|
||||||
return new Vec2( vector.Y, vector.Z );
|
return new Vec2( vector.Y, vector.Z );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the X/Y components of the vector.
|
/// Return the X/Y components of the vector.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vector">the input vector</param>
|
/// <param name="vector">the input vector</param>
|
||||||
public static Vec2 XY( this Vec4 vector )
|
public static Vec2 XY( this Vec4 vector )
|
||||||
{
|
{
|
||||||
return new Vec2( vector.X, vector.Y );
|
return new Vec2( vector.X, vector.Y );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the X/Y/Z components of the vector.
|
/// Return the X/Y/Z components of the vector.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vector">the input vector</param>
|
/// <param name="vector">the input vector</param>
|
||||||
public static Vec3 XYZ( this Vec4 vector )
|
public static Vec3 XYZ( this Vec4 vector )
|
||||||
{
|
{
|
||||||
return new Vec3( vector.X, vector.Y, vector.Z );
|
return new Vec3( vector.X, vector.Y, vector.Z );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 )
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.5.002.0
|
VisualStudioVersion = 17.5.002.0
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user