x) Add observable list
x) Fix immutability helpers x) Small FSM fixes
This commit is contained in:
parent
8bc0aafebc
commit
dbdd6ea748
@ -37,10 +37,15 @@ public class FSM<T, CTX, ST>
|
|||||||
{
|
{
|
||||||
Context = context;
|
Context = context;
|
||||||
State = state;
|
State = state;
|
||||||
|
|
||||||
|
State.onEnter( Context, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Transition(ST newState)
|
public void Transition(ST newState)
|
||||||
{
|
{
|
||||||
|
State.onExit( Context, newState );
|
||||||
|
newState.onEnter( Context, State );
|
||||||
|
State = newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
66
imm/Imm.cs
66
imm/Imm.cs
@ -1,22 +1,27 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
// A spot for immutable helpers
|
// A spot for immutable helpers
|
||||||
|
|
||||||
namespace imm
|
namespace imm
|
||||||
{
|
{
|
||||||
|
|
||||||
public record class Versioned<T>
|
public record class Versioned<T>
|
||||||
where T : Versioned<T>
|
where T : Versioned<T>
|
||||||
{
|
{
|
||||||
|
public delegate void ChangeDelegate( T old, T next );
|
||||||
|
|
||||||
public uint Version { get; protected set; } = 0;
|
public uint Version { get; protected set; } = 0;
|
||||||
public string Reason { get; protected set; } = "";
|
public string Reason { get; protected set; } = "";
|
||||||
|
|
||||||
|
public ChangeDelegate OnChange;
|
||||||
|
|
||||||
public T Process( Func<T, T> fn, string reason = "" )
|
public T Process( Func<T, T> fn, string reason = "" )
|
||||||
{
|
{
|
||||||
var newT = fn( ( T )this );
|
var newT = fn( ( T )this );
|
||||||
@ -45,15 +50,21 @@ namespace imm
|
|||||||
{
|
{
|
||||||
var orig = ( T )this;
|
var orig = ( T )this;
|
||||||
|
|
||||||
var newT = base.Process( ( old ) => old with
|
var next = ( T ) this with
|
||||||
{
|
{
|
||||||
|
//Do the Versioned code here
|
||||||
|
Version = orig.Version + 1,
|
||||||
|
Reason = reason,
|
||||||
|
|
||||||
Old = orig,
|
Old = orig,
|
||||||
MemberName = memberName,
|
MemberName = memberName,
|
||||||
FilePath = filePath,
|
FilePath = filePath,
|
||||||
LineNumber = lineNumber,
|
LineNumber = lineNumber,
|
||||||
}, reason );
|
};
|
||||||
|
|
||||||
return newT;
|
OnChange( orig, next );
|
||||||
|
|
||||||
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Process( Func<T, T> fn, string reason = "",
|
public T Process( Func<T, T> fn, string reason = "",
|
||||||
@ -65,10 +76,13 @@ namespace imm
|
|||||||
{
|
{
|
||||||
var orig = ( T )this;
|
var orig = ( T )this;
|
||||||
|
|
||||||
return ( T )this with
|
var next = ( T )fn( orig );
|
||||||
|
|
||||||
|
var ret = ( T )next with
|
||||||
{
|
{
|
||||||
//Do the Versioned code here
|
//Do the Versioned code here
|
||||||
Version = orig.Version + 1,
|
Version = orig.Version + 1,
|
||||||
|
Reason = reason,
|
||||||
|
|
||||||
//Recorded
|
//Recorded
|
||||||
Old = orig,
|
Old = orig,
|
||||||
@ -77,6 +91,10 @@ namespace imm
|
|||||||
FilePath = filePath,
|
FilePath = filePath,
|
||||||
LineNumber = lineNumber,
|
LineNumber = lineNumber,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
OnChange( orig, ret );
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +105,19 @@ namespace imm
|
|||||||
public readonly DateTime CreatedAt = DateTime.Now;
|
public readonly DateTime CreatedAt = DateTime.Now;
|
||||||
public DateTime TouchedAt { get; set; } = DateTime.Now;
|
public DateTime TouchedAt { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
public T Process( Func<T, T> fn, string reason = "",
|
|
||||||
|
public T Process( T next, string reason = "",
|
||||||
|
[CallerMemberName] string memberName = "",
|
||||||
|
[CallerFilePath] string filePath = "",
|
||||||
|
[CallerLineNumber] int lineNumber = 0,
|
||||||
|
[CallerArgumentExpression("next")]
|
||||||
|
string expression = default )
|
||||||
|
{
|
||||||
|
return Process( ( old ) => next, reason, memberName, filePath, lineNumber, expression );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
new public T Process( Func<T, T> fn, string reason = "",
|
||||||
[CallerMemberName] string memberName = "",
|
[CallerMemberName] string memberName = "",
|
||||||
[CallerFilePath] string filePath = "",
|
[CallerFilePath] string filePath = "",
|
||||||
[CallerLineNumber] int lineNumber = 0,
|
[CallerLineNumber] int lineNumber = 0,
|
||||||
@ -96,10 +126,13 @@ namespace imm
|
|||||||
{
|
{
|
||||||
var orig = ( T )this;
|
var orig = ( T )this;
|
||||||
|
|
||||||
return ( T )this with
|
var next = ( T )fn( orig );
|
||||||
|
|
||||||
|
var ret = ( T )next with
|
||||||
{
|
{
|
||||||
//Versioned
|
//Versioned
|
||||||
Version = orig.Version + 1,
|
Version = orig.Version + 1,
|
||||||
|
Reason = reason,
|
||||||
|
|
||||||
//Recorded
|
//Recorded
|
||||||
Old = orig,
|
Old = orig,
|
||||||
@ -108,8 +141,13 @@ namespace imm
|
|||||||
FilePath = filePath,
|
FilePath = filePath,
|
||||||
LineNumber = lineNumber,
|
LineNumber = lineNumber,
|
||||||
|
|
||||||
|
//Timed
|
||||||
TouchedAt = DateTime.Now,
|
TouchedAt = DateTime.Now,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
OnChange( orig, ret );
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,5 +159,5 @@ namespace imm
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
158
imm/List.cs
Normal file
158
imm/List.cs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
|
namespace imm;
|
||||||
|
|
||||||
|
public record class List<T> : Timed<List<T>>, IImmutableList<T>
|
||||||
|
{
|
||||||
|
|
||||||
|
ImmutableList<T> Values = ImmutableList<T>.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public T this[int index] => (( IReadOnlyList<T> )Values)[index];
|
||||||
|
|
||||||
|
public int Count => Values.Count;
|
||||||
|
|
||||||
|
public List<T> Add( T value )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.Add( value ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> AddRange( IEnumerable<T> items )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.AddRange( items ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> Clear()
|
||||||
|
{
|
||||||
|
return this with { Values = Values.Clear() };
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<T> GetEnumerator()
|
||||||
|
{
|
||||||
|
return Values.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOf( T item, int index, int count, IEqualityComparer<T> equalityComparer )
|
||||||
|
{
|
||||||
|
return Values.IndexOf( item, index, count, equalityComparer );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOf( T item )
|
||||||
|
{
|
||||||
|
return Values.IndexOf( item, 0, Count, EqualityComparer<T>.Default );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> Insert( int index, T element )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.Insert( index, element ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> InsertRange( int index, IEnumerable<T> items )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.InsertRange( index, items ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastIndexOf( T item, int index, int count, IEqualityComparer<T> equalityComparer )
|
||||||
|
{
|
||||||
|
return Values.LastIndexOf( item, index, count, equalityComparer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<T> Remove( T value )
|
||||||
|
{
|
||||||
|
return Remove( value, EqualityComparer<T>.Default );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> Remove( T value, IEqualityComparer<T> equalityComparer )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.Remove( value, equalityComparer ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> RemoveAll( Predicate<T> match )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.RemoveAll( match ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> RemoveAt( int index )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.RemoveAt( index ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> RemoveRange( IEnumerable<T> items, IEqualityComparer<T> equalityComparer )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.RemoveRange( items, equalityComparer ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> RemoveRange( int index, int count )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.RemoveRange( index, count ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> Replace( T oldValue, T newValue, IEqualityComparer<T> equalityComparer )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.Replace( oldValue, newValue, equalityComparer ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> SetItem( int index, T value )
|
||||||
|
{
|
||||||
|
return this with { Values = Values.SetItem( index, value ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return (( IEnumerable )Values).GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.Clear()
|
||||||
|
{
|
||||||
|
return Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.Add( T value )
|
||||||
|
{
|
||||||
|
return Add( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.AddRange( IEnumerable<T> items )
|
||||||
|
{
|
||||||
|
return AddRange( items );
|
||||||
|
}
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.Insert( int index, T element )
|
||||||
|
{
|
||||||
|
return Insert( index, element );
|
||||||
|
}
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.InsertRange( int index, IEnumerable<T> items )
|
||||||
|
{
|
||||||
|
return InsertRange( index, items );
|
||||||
|
}
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.Remove( T value, IEqualityComparer<T> equalityComparer )
|
||||||
|
{
|
||||||
|
return Remove( value, equalityComparer );
|
||||||
|
}
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.RemoveAll( Predicate<T> match )
|
||||||
|
{
|
||||||
|
return RemoveAll( match );
|
||||||
|
}
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.RemoveAt( int index ) => RemoveAt( index );
|
||||||
|
|
||||||
|
IImmutableList<T> IImmutableList<T>.RemoveRange( IEnumerable<T> items, IEqualityComparer<T> equalityComparer )
|
||||||
|
=> RemoveRange( items, equalityComparer );
|
||||||
|
|
||||||
|
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>.SetItem( int index, T value ) => SetItem( index, value );
|
||||||
|
}
|
||||||
|
|
||||||
4
imm/Util.cs
Normal file
4
imm/Util.cs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace imm;
|
||||||
@ -14,6 +14,9 @@ namespace math
|
|||||||
static public class fn
|
static public class fn
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static public float ToDeg( float rad ) => ( float )(180.0 / Math.PI) * rad;
|
||||||
|
static public float ToRad( float deg ) => ( float )(Math.PI / 180.0) * deg;
|
||||||
|
|
||||||
static public float Clamp( float v, float min, float max )
|
static public float Clamp( float v, float min, float max )
|
||||||
{
|
{
|
||||||
return v < min ? min : v > max ? max : v;
|
return v < min ? min : v > max ? max : v;
|
||||||
|
|||||||
@ -62,7 +62,8 @@ namespace lib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityPermission( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter )]
|
|
||||||
|
//[SecurityPermission( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter )]
|
||||||
void ISerializable.GetObjectData( SerializationInfo info, StreamingContext context )
|
void ISerializable.GetObjectData( SerializationInfo info, StreamingContext context )
|
||||||
{
|
{
|
||||||
info.AddValue( "ItemCount", this.Count );
|
info.AddValue( "ItemCount", this.Count );
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user