diff --git a/StgSharp.Common/Collections/ListSegment.cs b/StgSharp.Common/Collections/ListSegment.cs
index 54fb0c39..73efea66 100644
--- a/StgSharp.Common/Collections/ListSegment.cs
+++ b/StgSharp.Common/Collections/ListSegment.cs
@@ -1,4 +1,34 @@
-using System;
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="ListSegment.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -10,42 +40,67 @@ using System.Xml.Serialization;
namespace StgSharp.Collections
{
///
- /// Part of a collection. This contains a direct reference to origin collection,
- /// so all change to origin collection will be reflected in this object.
+ /// Part of a collection. This contains a direct reference to _origin collection, so all change
+ /// to _origin collection will be reflected in this object.
///
///
public struct ListSegment : ICollection
{
- private List _collection;
+
private int _begin;
private int _length;
+ private List _collection;
-
- public ListSegment(List collection, int begin, int length)
+ public ListSegment( List collection, int begin, int length )
{
- ArgumentNullException.ThrowIfNull(collection);
- ArgumentOutOfRangeException.ThrowIfLessThan(begin, 0);
- ArgumentOutOfRangeException.ThrowIfLessThan(length, 0);
- ArgumentOutOfRangeException.ThrowIfLessThan(begin + length, collection.Count);
+ ArgumentNullException.ThrowIfNull( collection );
+ ArgumentOutOfRangeException.ThrowIfLessThan( begin, 0 );
+ ArgumentOutOfRangeException.ThrowIfLessThan( length, 0 );
+ ArgumentOutOfRangeException.ThrowIfLessThan(
+ begin + length, collection.Count );
_collection = collection;
_begin = begin;
_length = length;
- }
+ }
- public int Count => _length;
-
- public bool IsReadOnly => true;
-
- public T this[int indexValue]
+ public T this[ int indexValue ]
{
- get {
- ArgumentOutOfRangeException.ThrowIfLessThan(indexValue, 0);
- ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(indexValue, _length);
- return _collection[indexValue + _begin];
+ get
+ {
+ ArgumentOutOfRangeException.ThrowIfLessThan( indexValue, 0 );
+ ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(
+ indexValue, _length );
+ return _collection[ indexValue + _begin ];
}
}
- void ICollection.Add(T item)
+ public bool IsReadOnly => true;
+
+ public int Count => _length;
+
+ public bool Contains( T item )
+ {
+ int index = _collection.IndexOf( item );
+ return index >= _begin && index < _length + index;
+ }
+
+ public void CopyTo( T[] array, int arrayIndex )
+ {
+ ArgumentNullException.ThrowIfNull( array );
+ Span span = CollectionsMarshal.AsSpan( _collection )
+ .Slice( _begin, _length );
+ Span target = new Span( array, arrayIndex, _length );
+ span.CopyTo( target );
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ for( int i = _begin; i < _length; i++ ) {
+ yield return this[ i ];
+ }
+ }
+
+ void ICollection.Add( T item )
{
throw new NotSupportedException();
}
@@ -55,29 +110,7 @@ namespace StgSharp.Collections
throw new NotSupportedException();
}
- public bool Contains(T item)
- {
- var index= _collection.IndexOf(item);
- return index >= _begin && index < _length + index;
- }
-
- public void CopyTo(T[] array, int arrayIndex)
- {
- ArgumentNullException.ThrowIfNull(array);
- var span = CollectionsMarshal.AsSpan(_collection).Slice(_begin, _length);
- var target = new Span(array, arrayIndex,_length);
- span.CopyTo(target);
- }
-
- public IEnumerator GetEnumerator()
- {
- for (int i = _begin; i < _length; i++)
- {
- yield return this[i];
- }
- }
-
- bool ICollection.Remove(T item)
+ bool ICollection.Remove( T item )
{
throw new NotSupportedException();
}
@@ -86,5 +119,6 @@ namespace StgSharp.Collections
{
return GetEnumerator();
}
+
}
}
diff --git a/StgSharp.Common/Counter.cs b/StgSharp.Common/Counter.cs
new file mode 100644
index 00000000..28045a5a
--- /dev/null
+++ b/StgSharp.Common/Counter.cs
@@ -0,0 +1,117 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="Counter.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Numerics;
+
+namespace StgSharp
+{
+ public class Counter where T: struct, INumber
+ {
+
+ internal dynamic _value;
+ internal readonly T _defaultValue;
+ internal readonly T _defualtDecreament;
+
+ internal readonly T _defualtIncreament;
+
+ public Counter(
+ T defualtValue,
+ T defualtIncreament,
+ T defualtDecreament )
+ {
+ _value = defualtValue;
+ _defaultValue = defualtValue;
+ _defualtIncreament = defualtIncreament;
+ _defualtDecreament = defualtDecreament;
+ }
+
+ public T DecreamentSoan => _defualtDecreament;
+
+ public T IncreamentSpan => _defualtIncreament;
+
+ public T CurrentSpan => _value - _defaultValue;
+
+ public T Value
+ {
+ get => _value;
+ set => _value = value;
+ }
+
+ public void Add( T value )
+ {
+ _value += value;
+ }
+
+ public void QuickAdd()
+ {
+ _value += _defualtIncreament;
+ }
+
+ public void QuickSub()
+ {
+ _value -= _defualtDecreament;
+ }
+
+ public void Reset()
+ {
+ _value = _defaultValue;
+ }
+
+ public void Sub( T value )
+ {
+ _value -= value;
+ }
+
+ public override string ToString() => Value.ToString();
+
+ public static Counter operator --( Counter counter )
+ {
+ counter.QuickSub();
+ return counter;
+ }
+
+ public static Counter operator ++( Counter counter )
+ {
+ counter.QuickAdd();
+ return counter;
+ }
+
+ public static implicit operator T( Counter counter )
+ {
+ return counter switch
+ {
+ null => T.Zero,
+ _ => counter.Value
+ };
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/StgSharp.Common/Data/ValueBox.cs b/StgSharp.Common/Data/ValueBox.cs
index 31a8111c..9bf6bd74 100644
--- a/StgSharp.Common/Data/ValueBox.cs
+++ b/StgSharp.Common/Data/ValueBox.cs
@@ -75,7 +75,7 @@ namespace StgSharp.Data
///
/// A class attempt to reduce cost of boxing, though still a bit slower than direct access to
- /// origin value type instance.
+ /// _origin value type instance.
///
/// Type of instance to be boxed.
public class ValueBox : IValueBox, IValueBox where T: struct
diff --git a/StgSharp.Common/Geometries/IInstancing.cs b/StgSharp.Common/Geometries/IInstancing.cs
index 33e26535..2c1162d9 100644
--- a/StgSharp.Common/Geometries/IInstancing.cs
+++ b/StgSharp.Common/Geometries/IInstancing.cs
@@ -88,7 +88,7 @@ namespace StgSharp.Geometries
{
get { return GlobalBuffer.CoordAndRotationList[ BufferId ].XYZ; }
set { GlobalBuffer.CoordAndRotationList[ BufferId ] = new Vec4(
- value.vec ); }
+ value.reg ); }
}
public void Move()
diff --git a/StgSharp.Common/Geometries/PlainGeometry/Cordinate.cs b/StgSharp.Common/Geometries/PlainGeometry/Cordinate.cs
index b90df786..e16686bf 100644
--- a/StgSharp.Common/Geometries/PlainGeometry/Cordinate.cs
+++ b/StgSharp.Common/Geometries/PlainGeometry/Cordinate.cs
@@ -47,14 +47,14 @@ namespace StgSharp.Geometries
internal Matrix32 axis;
///
- /// The origin of this coordinate.
+ /// The _origin of this coordinate.
///
public Vec3 origin;
public PartialPlainCoordinate(
- Vec3 origin,
- Vec3 horiziontial,
- Vec3 vertical )
+ Vec3 origin,
+ Vec3 horiziontial,
+ Vec3 vertical )
{
this.origin = origin;
axis = new Matrix32();
diff --git a/StgSharp.Common/Geometries/PlainGeometry/Plain.cs b/StgSharp.Common/Geometries/PlainGeometry/Plain.cs
index 2338a379..98ea38b6 100644
--- a/StgSharp.Common/Geometries/PlainGeometry/Plain.cs
+++ b/StgSharp.Common/Geometries/PlainGeometry/Plain.cs
@@ -38,30 +38,22 @@ namespace StgSharp.Geometries
{
internal readonly float d = -1;
- internal Vec3 origin;
+ internal Vec3 _origin;
internal Vec3 plainParameter;
internal Vec3 vec1;
internal Vec3 vec2;
- internal Plain( Vector4 origin, Vector4 p1, Vector4 p2 )
- {
- this.origin = new Vec3( origin );
-
- vec1 = new Vec3( p1 - origin );
- vec2 = new Vec3( p2 - origin );
- }
-
public Plain( Vec3 o, Vec3 v1, Vec3 v2 )
{
- this.origin = o;
- this.vec1 = v1 - ( v2 * ( v1.Y / v2.Y ) ); //计算平面在xz平面上的方向投影
- this.vec2 = v2 - ( vec1 * ( v2.X / v1.X ) ); //计算平面在yz平面上的方向投影
+ this._origin = o;
+ this.vec1 = v1 - ( v2 * ( v1.Y / v2.Y ) ); //xz
+ this.vec2 = v2 - ( vec1 * ( v2.X / v1.X ) ); //yz
- //|origin|-k1*|vec1|-k2*|vec2|计算plainParameter.Z;
- plainParameter.Z = origin.Z - ( vec1.Z * ( origin.X / vec1.X ) ) - ( vec2.Z * ( origin.Y / vec2.Y ) );
+ //|_origin|-k1*|vec1|-k2*|vec2| --> plainParameter.Z;
+ plainParameter.Z = _origin.Z - ( vec1.Z * ( _origin.X / vec1.X ) ) - ( vec2.Z * ( _origin.Y / vec2.Y ) );
- //根据plainParameter.Z和对应的方向矢量计算plainParameter.X和plainParameter.Y
+ //plainParameter.Z -> plainParameter.X, plainParameter.Y
plainParameter.X = vec1.X * ( vec1.Z / plainParameter.Z );
plainParameter.Y = vec2.Y * ( vec2.Z / plainParameter.Z );
@@ -77,13 +69,13 @@ namespace StgSharp.Geometries
Vec3 v2 = p3.Coord - origin;
- vec1 = v1 - ( v2 * ( v1.Y / v2.Y ) ); //计算平面在xz平面上的方向投影
- vec2 = v2 - ( vec1 * ( v2.X / v1.X ) ); //计算平面在yz平面上的方向投影
+ vec1 = v1 - ( v2 * ( v1.Y / v2.Y ) ); //xz
+ vec2 = v2 - ( vec1 * ( v2.X / v1.X ) ); //yz
- //|origin|-k1*|vec1|-k2*|vec2|计算plainParameter.Z;
+ //|_origin|-k1*|vec1|-k2*|vec2| --> plainParameter.Z;
plainParameter.Z = origin.Z - ( vec1.Z * ( origin.X / vec1.X ) ) - ( vec2.Z * ( origin.Y / vec2.Y ) );
- //根据plainParameter.Z和对应的方向矢量计算plainParameter.X和plainParameter.Y
+ //plainParameter.Z --> plainParameter.X, plainParameter.Y
plainParameter.X = vec1.X * ( vec1.Z / plainParameter.Z );
plainParameter.Y = vec2.Y * ( vec2.Z / plainParameter.Z );
diff --git a/StgSharp.Common/Geometries/PlainGeometry/Polygon6.cs b/StgSharp.Common/Geometries/PlainGeometry/Polygon6.cs
index be3813b0..a7b45881 100644
--- a/StgSharp.Common/Geometries/PlainGeometry/Polygon6.cs
+++ b/StgSharp.Common/Geometries/PlainGeometry/Polygon6.cs
@@ -48,24 +48,24 @@ namespace StgSharp.Geometries
}
public Polygon6(
- PlainCoordinate coordination,
- Vec2 vert0,
- Vec2 vert1,
- Vec2 vert2,
- Vec2 vert3,
- Vec2 vert4,
- Vec2 vert5,
- Vec2 vert6 )
+ PlainCoordinate coordination,
+ Vec2 vert0,
+ Vec2 vert1,
+ Vec2 vert2,
+ Vec2 vert3,
+ Vec2 vert4,
+ Vec2 vert5,
+ Vec2 vert6 )
: base( coordination )
{
vertexMat = new Vec4[6];
- vertexMat[ 0 ].vec = vert0.vec;
- vertexMat[ 1 ].vec = vert1.vec;
- vertexMat[ 2 ].vec = vert2.vec;
- vertexMat[ 3 ].vec = vert3.vec;
- vertexMat[ 4 ].vec = vert4.vec;
- vertexMat[ 5 ].vec = vert5.vec;
- vertexMat[ 6 ].vec = vert6.vec;
+ vertexMat[ 0 ].reg = vert0.reg;
+ vertexMat[ 1 ].reg = vert1.reg;
+ vertexMat[ 2 ].reg = vert2.reg;
+ vertexMat[ 3 ].reg = vert3.reg;
+ vertexMat[ 4 ].reg = vert4.reg;
+ vertexMat[ 5 ].reg = vert5.reg;
+ vertexMat[ 6 ].reg = vert6.reg;
}
public override ReadOnlySpan VertexIndices => Indices;
diff --git a/StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs b/StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs
index fe72ae61..08335369 100644
--- a/StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs
+++ b/StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs
@@ -72,10 +72,10 @@ namespace StgSharp.Graphics.OpenGL
/// Data to write in
/// How OpenGL use these _data, defined by
public void WriteMatrixData(
- int index,
- T bufferData,
- BufferUsage usage )
- where T: struct, IMat
+ int index,
+ T bufferData,
+ BufferUsage usage )
+ where T: struct, IMatrix
{
GL.BindBuffer( BufferType.ArrayBuffer, _bufferHandle[ index ] );
GL.SetBufferData( BufferType.ArrayBuffer, bufferData, usage );
@@ -89,9 +89,9 @@ namespace StgSharp.Graphics.OpenGL
/// Data to write in
/// How OpenGL use these _data, defined by
public void WriteScalerData(
- int index,
- T[] bufferArray,
- BufferUsage usage )
+ int index,
+ T[] bufferArray,
+ BufferUsage usage )
where T: struct, INumber
{
GL.BindBuffer( BufferType.ArrayBuffer, _bufferHandle[ index ] );
@@ -106,9 +106,9 @@ namespace StgSharp.Graphics.OpenGL
/// A of _data to write in
/// How OpenGL use these _data, defined by
public void WriteScalerData(
- int index,
- ReadOnlySpan scalerSpan,
- BufferUsage usage )
+ int index,
+ ReadOnlySpan scalerSpan,
+ BufferUsage usage )
where T: struct,INumber
{
GL.BindBuffer( BufferType.ArrayBuffer, _bufferHandle[ index ] );
@@ -123,10 +123,10 @@ namespace StgSharp.Graphics.OpenGL
/// A of _data to write in
/// How OpenGL use these _data, defined by
public void WriteVectorData(
- int index,
- ReadOnlySpan vectorSpan,
- BufferUsage usage )
- where T: struct, IVector
+ int index,
+ ReadOnlySpan vectorSpan,
+ BufferUsage usage )
+ where T: struct, IVector
{
GL.BindBuffer( BufferType.ArrayBuffer, _bufferHandle[ index ] );
GL.SetBufferVectorData( BufferType.ArrayBuffer, vectorSpan, usage );
@@ -140,10 +140,10 @@ namespace StgSharp.Graphics.OpenGL
/// A array of _data to write in
/// How OpenGL use these _data, defined by
public void WriteVectorData(
- int index,
- T[] vectorArray,
- BufferUsage usage )
- where T: struct, IVector
+ int index,
+ T[] vectorArray,
+ BufferUsage usage )
+ where T: struct, IVector
{
GL.BindBuffer( BufferType.ArrayBuffer, _bufferHandle[ index ] );
GL.SetBufferVectorData( BufferType.ArrayBuffer, vectorArray,
diff --git a/StgSharp.Common/Graphics/OpenGL/glFunction.cs b/StgSharp.Common/Graphics/OpenGL/glFunction.cs
index e9e5916e..6636edb7 100644
--- a/StgSharp.Common/Graphics/OpenGL/glFunction.cs
+++ b/StgSharp.Common/Graphics/OpenGL/glFunction.cs
@@ -157,7 +157,7 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public FrameBufferStatus CheckFrameBufferStatus(
- FrameBufferTarget target )
+ FrameBufferTarget target )
{
return ( FrameBufferStatus )Context.glCheckFramebufferStatus(
( uint )target );
@@ -201,8 +201,8 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void CombineFrameBufferRenderBuffer(
- FrameBufferAttachment attachment,
- GlHandle rboHandle )
+ FrameBufferAttachment attachment,
+ GlHandle rboHandle )
{
Context.glFramebufferRenderbuffer(
glConst.FRAMEBUFFER, ( uint )attachment, glConst.RENDERBUFFER,
@@ -298,10 +298,10 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void DrawElements(
- GeometryType mode,
- uint count,
- TypeCode type,
- IntPtr ptr )
+ GeometryType mode,
+ uint count,
+ TypeCode type,
+ IntPtr ptr )
{
uint a;
a = type switch
@@ -317,11 +317,11 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void DrawElementsInstanced(
- GeometryType mode,
- uint count,
- TypeCode type,
- IntPtr ptr,
- uint amount )
+ GeometryType mode,
+ uint count,
+ TypeCode type,
+ IntPtr ptr,
+ uint amount )
{
uint a;
switch( type ) {
@@ -355,11 +355,11 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void FrameBufferTexture2d(
- FrameBufferTarget target,
- uint attachment,
- Texture2DTarget texTarget,
- GlHandle textureHandle,
- int level )
+ FrameBufferTarget target,
+ uint attachment,
+ Texture2DTarget texTarget,
+ GlHandle textureHandle,
+ int level )
{
Context.glFramebufferTexture2D(
( uint )target, attachment, ( uint )texTarget,
@@ -439,7 +439,8 @@ namespace StgSharp.Graphics.OpenGL
{
IntPtr sptr = IntPtr.Zero;
if( InternalIO.glCheckShaderStatus(
- ref Context, s.handle[ index ].Value, key, ref sptr ) == 0 ) {
+ ref Context, s.handle[ index ].Value, key, ref sptr ) ==
+ 0 ) {
return Marshal.PtrToStringAnsi( sptr );
}
return string.Empty;
@@ -447,11 +448,11 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void GetTextureImage(
- Texture2DTarget target,
- int level,
- ImageChannel channel,
- PixelChannelLayout channelLayout,
- T[] dataStream )
+ Texture2DTarget target,
+ int level,
+ ImageChannel channel,
+ PixelChannelLayout channelLayout,
+ T[] dataStream )
where T: struct,INumber
{
#pragma warning disable CS8500
@@ -465,10 +466,10 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void GetTextureLevelProperty(
- uint textureTypeMask,
- int level,
- uint propertyMask,
- out int propertyValue )
+ uint textureTypeMask,
+ int level,
+ uint propertyMask,
+ out int propertyValue )
{
fixed( int* iptr = &propertyValue ) {
Context.glGetTexLevelParameteriv(
@@ -478,14 +479,15 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe GlHandle GetUniformLocation(
- GlHandle program,
- string name )
+ GlHandle program,
+ string name )
{
byte[] code = Encoding.UTF8.GetBytes( name );
fixed( byte* ptr = code ) {
int ret = Context.glGetUniformLocation( program.Value, ptr );
#if DEBUG
- if( ( ret == glConst.INVALID_OPERATION ) || ( ret == glConst.INVALID_VALUE ) ) {
+ if( ( ret == glConst.INVALID_OPERATION ) || ( ret ==
+ glConst.INVALID_VALUE ) ) {
throw new InvalidOperationException();
}
if( ret == -1 ) {
@@ -499,8 +501,8 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void LoadShaderSource(
- GlHandle shaderHandle,
- byte[] codeStream )
+ GlHandle shaderHandle,
+ byte[] codeStream )
{
fixed( byte* streamPtr = codeStream ) {
Context.glShaderSource(
@@ -509,24 +511,23 @@ namespace StgSharp.Graphics.OpenGL
}
public unsafe void LoadShaderSource(
- GlHandle shaderHandle,
- ReadOnlySpan codeStream)
+ GlHandle shaderHandle,
+ ReadOnlySpan codeStream )
{
- fixed (char* streamPtr = codeStream)
- {
- byte* bptr = (byte*)streamPtr;
+ fixed( char* streamPtr = codeStream ) {
+ byte* bptr = ( byte* )streamPtr;
Context.glShaderSource(
- shaderHandle.Value, 1, &bptr, (void*)0);
+ shaderHandle.Value, 1, &bptr, ( void* )0 );
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void ReadPixels(
- (int X, int Y) beginPosition,
- (int width, int height) size,
- FrameBufferChannel format,
- PixelChannelLayout dataType,
- ref byte[] stream )
+ (int X, int Y) beginPosition,
+ (int width, int height) size,
+ FrameBufferChannel format,
+ PixelChannelLayout dataType,
+ ref byte[] stream )
{
fixed( byte* bptr = stream ) {
Context.glReadPixels(
@@ -536,10 +537,10 @@ namespace StgSharp.Graphics.OpenGL
}
public void RereadImage(
- in Image i,
- (int X, int Y) beginPosition,
- FrameBufferChannel format,
- PixelChannelLayout dataType )
+ in Image i,
+ (int X, int Y) beginPosition,
+ FrameBufferChannel format,
+ PixelChannelLayout dataType )
{
byte[] pixels = i.PixelBuffer;
if( !pixels.CheckArrayFormat( dataType ) ) {
@@ -555,9 +556,9 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void SetBufferData(
- BufferType bufferType,
- T bufferData,
- BufferUsage usage )
+ BufferType bufferType,
+ T bufferData,
+ BufferUsage usage )
where T: struct
{
int size = Marshal.SizeOf();
@@ -571,30 +572,9 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void SetBufferData(
- BufferType bufferType,
- T[] bufferArray,
- BufferUsage usage )
- where T: struct,INumber
- {
- int size = bufferArray.Length * Marshal.SizeOf( typeof( T ) );
- if( bufferArray == null ) {
- return;
- }
- #pragma warning disable CS8500
- fixed( void* bufferPtr = bufferArray )
- #pragma warning restore CS8500
- {
- Context.glBufferData(
- ( uint )bufferType, ( IntPtr )size, ( IntPtr )bufferPtr,
- ( uint )usage );
- }
- }
-
- [MethodImpl( MethodImplOptions.AggressiveInlining )]
- public unsafe void SetBufferData(
- BufferType bufferType,
- ReadOnlySpan bufferArray,
- BufferUsage usage )
+ BufferType bufferType,
+ T[] bufferArray,
+ BufferUsage usage )
where T: struct,INumber
{
int size = bufferArray.Length * Marshal.SizeOf( typeof( T ) );
@@ -613,9 +593,30 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void SetBufferData(
- BufferType bufferType,
- Span bufferArray,
- BufferUsage usage )
+ BufferType bufferType,
+ ReadOnlySpan bufferArray,
+ BufferUsage usage )
+ where T: struct,INumber
+ {
+ int size = bufferArray.Length * Marshal.SizeOf( typeof( T ) );
+ if( bufferArray == null ) {
+ return;
+ }
+ #pragma warning disable CS8500
+ fixed( void* bufferPtr = bufferArray )
+ #pragma warning restore CS8500
+ {
+ Context.glBufferData(
+ ( uint )bufferType, ( IntPtr )size, ( IntPtr )bufferPtr,
+ ( uint )usage );
+ }
+ }
+
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public unsafe void SetBufferData(
+ BufferType bufferType,
+ Span bufferArray,
+ BufferUsage usage )
where T: struct, INumber
{
int size = bufferArray.Length * Marshal.SizeOf( typeof( T ) );
@@ -635,10 +636,10 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void SetBufferVectorData(
- BufferType bufferType,
- ReadOnlySpan bufferArray,
- BufferUsage usage )
- where T: struct, IVector
+ BufferType bufferType,
+ ReadOnlySpan bufferArray,
+ BufferUsage usage )
+ where T: struct, IVector
{
int size = bufferArray.Length * Marshal.SizeOf( typeof( T ) );
if( bufferArray == null ) {
@@ -656,10 +657,10 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void SetBufferVectorData(
- BufferType bufferType,
- T[] bufferArray,
- BufferUsage usage )
- where T: struct, IVector
+ BufferType bufferType,
+ T[] bufferArray,
+ BufferUsage usage )
+ where T: struct, IVector
{
int size = bufferArray.Length * Marshal.SizeOf( typeof( T ) );
if( bufferArray == null ) {
@@ -677,8 +678,8 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void SetRenderBufferStorage(
- RenderBufferInternalFormat internalFormat,
- (int width, int height) size )
+ RenderBufferInternalFormat internalFormat,
+ (int width, int height) size )
{
Context.glRenderbufferStorage(
glConst.RENDERBUFFER, ( uint )internalFormat, size.width,
@@ -687,8 +688,8 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe void SetRenderBufferStorage(
- RenderBufferInternalFormat internalFormat,
- (uint width, uint height) size )
+ RenderBufferInternalFormat internalFormat,
+ (uint width, uint height) size )
{
Context.glRenderbufferStorage(
glConst.RENDERBUFFER, ( uint )internalFormat, ( int )size.width,
@@ -697,12 +698,12 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetVertexAttribute(
- uint index,
- int size,
- TypeCode t,
- bool normalized,
- uint stride,
- int pointer )
+ uint index,
+ int size,
+ TypeCode t,
+ bool normalized,
+ uint stride,
+ int pointer )
{
uint type = InternalIO.GLtype[ t ];
Context.glVertexAttribPointer(
@@ -713,20 +714,20 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void TextureImage2d(
- Texture2DTarget target,
- int level,
- ImageChannel sourceChannel,
- uint width,
- uint height,
- ImageChannel targetChannel,
- PixelChannelLayout type,
- T[] pixels )
+ Texture2DTarget target,
+ int level,
+ ImageChannel sourceChannel,
+ uint width,
+ uint height,
+ ImageChannel targetChannel,
+ PixelChannelLayout type,
+ T[] pixels )
where T: struct, INumber
{
#pragma warning disable CS8500
fixed( T* tptr = pixels ) {
T* ptr = ( ( pixels == null ) || ( pixels.Length == 0 ) ) ?
- ( T* )IntPtr.Zero : tptr;
+ ( T* )IntPtr.Zero : tptr;
Context.glTexImage2D(
( uint )target, level, ( uint )sourceChannel, width, height,
0, ( uint )targetChannel, ( uint )type, tptr );
@@ -736,23 +737,23 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void TextureImage2d(
- Texture2DTarget target,
- int level,
- ImageChannel sourceChannel,
- uint width,
- uint height,
- ImageChannel targetChannel,
- PixelChannelLayout type,
- Span pixelSpan )
+ Texture2DTarget target,
+ int level,
+ ImageChannel sourceChannel,
+ uint width,
+ uint height,
+ ImageChannel targetChannel,
+ PixelChannelLayout type,
+ Span pixelSpan )
where T: struct, INumber
{
-#pragma warning disable CS8500
+ #pragma warning disable CS8500
fixed( T* tptr = pixelSpan ) {
Context.glTexImage2D(
( uint )target, level, ( uint )sourceChannel, width, height,
0, ( uint )targetChannel, ( uint )type, tptr );
}
-#pragma warning restore CS8500
+ #pragma warning restore CS8500
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
@@ -762,8 +763,8 @@ namespace StgSharp.Graphics.OpenGL
}
public static bool TryGetFunctionPackage(
- IntPtr handle,
- out OpenGLFunction functionPackage )
+ IntPtr handle,
+ out OpenGLFunction functionPackage )
{
return contextToGLMap.TryGetValue( handle, out functionPackage );
}
diff --git a/StgSharp.Common/Graphics/Pixels.cs b/StgSharp.Common/Graphics/Pixels.cs
index 9424725e..dd4b3d15 100644
--- a/StgSharp.Common/Graphics/Pixels.cs
+++ b/StgSharp.Common/Graphics/Pixels.cs
@@ -70,11 +70,36 @@ namespace StgSharp.Graphics
}
[StructLayout( LayoutKind.Explicit, Size = 32 )]
- public unsafe struct Pixel32
+ public unsafe struct Pixel32RGBA : IPixel
{
+
[FieldOffset( 0 )] private unsafe fixed byte data[ 4 ];
- internal int Size => 4;
+ public int Size => 4;
+
+ float IPixel.Alpha
+ {
+ get => data[ 3 ] / 256 ;
+ set => data[ 3 ] = ( byte )( value * 256 );
+ }
+
+ float IPixel.Blue
+ {
+ get => data[ 2 ] / 256 ;
+ set => data[ 2 ] = ( byte )( value * 256 );
+ }
+
+ float IPixel.Green
+ {
+ get => data[ 1 ] / 256 ;
+ set => data[ 1 ] = ( byte )( value * 256 );
+ }
+
+ float IPixel.Red
+ {
+ get => data[ 0 ] / 256 ;
+ set => data[ 0 ] = ( byte )( value * 256 );
+ }
}
}
diff --git a/StgSharp.Common/Graphics/PlainGeometryMesh.cs b/StgSharp.Common/Graphics/PlainGeometryMesh.cs
index 0f506367..11666a61 100644
--- a/StgSharp.Common/Graphics/PlainGeometryMesh.cs
+++ b/StgSharp.Common/Graphics/PlainGeometryMesh.cs
@@ -47,8 +47,8 @@ namespace StgSharp.Graphics
private TextureProvider _texture;
public PlainGeometryMesh(
- [NotNull] PlainGeometry shape,
- [NotNull] TextureProvider texture )
+ [NotNull] PlainGeometry shape,
+ [NotNull] TextureProvider texture )
{
if( shape.VertexCount > texture.TextureCoordinate.Length ) {
throw new ArgumentException(
@@ -62,16 +62,12 @@ namespace StgSharp.Graphics
//private Image _texture;
public PlainGeometryMesh(
- PlainGeometry shape,
- Image texture,
- Vec2[] texCoord )
+ PlainGeometry shape,
+ Image texture,
+ Vec2[] texCoord )
{
- if( shape == null ) {
- throw new ArgumentNullException( nameof( shape ) );
- }
- if( texCoord == null ) {
- throw new ArgumentNullException( nameof( texCoord ) );
- }
+ ArgumentNullException.ThrowIfNull( shape );
+ ArgumentNullException.ThrowIfNull( texCoord );
if( shape.VertexCount > texCoord.Length ) {
throw new ArgumentException(
diff --git a/StgSharp.Common/Graphics/TexturePipeline.cs b/StgSharp.Common/Graphics/TexturePipeline.cs
index bd9c3b64..6bfc4c68 100644
--- a/StgSharp.Common/Graphics/TexturePipeline.cs
+++ b/StgSharp.Common/Graphics/TexturePipeline.cs
@@ -29,7 +29,7 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
-using StgSharp.Blueprint;
+using StgSharp.PipeLine;
using System;
using System.Collections.Generic;
@@ -39,7 +39,7 @@ using System.Threading.Tasks;
namespace StgSharp.Graphics
{
- public class TexturePipeline : BlueprintPipelineArgs
+ public class TexturePipeline : PipeLineConnectorArgs
{
private Image _value;
diff --git a/StgSharp.Common/HighPerformance/M128.cs b/StgSharp.Common/HighPerformance/M128.cs
index 19b7062d..2df924a1 100644
--- a/StgSharp.Common/HighPerformance/M128.cs
+++ b/StgSharp.Common/HighPerformance/M128.cs
@@ -34,10 +34,8 @@ using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-#if NET5_0_OR_GREATER
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
-#endif
using System.Text;
@@ -48,11 +46,11 @@ namespace StgSharp.HighPerformance
{
[FieldOffset( 0 )] internal fixed byte Buffer[ 16 ];
- [FieldOffset( 0 )] internal Vector128 Vec;
+ [FieldOffset( 0 )] internal Vector128 Vec;
internal M128( Vector4 v )
{
- Vec = v.AsVector128().AsByte();
+ Vec = v.AsVector128();
}
public ref T AsRef() where T: struct, INumber
@@ -60,6 +58,12 @@ namespace StgSharp.HighPerformance
return ref Unsafe.As( ref Buffer[ 0 ] );
}
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public Vector4 AsVector4()
+ {
+ return Vec.As().AsVector4();
+ }
+
public override bool Equals( [NotNullWhen( true )] object obj )
{
if( obj is not M128 other ) {
@@ -123,61 +127,61 @@ namespace StgSharp.HighPerformance
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static explicit operator Vector128( M128 m )
{
- return m.Vec.As();
+ return m.Vec.As();
}
}
diff --git a/StgSharp.Common/Internal/Intrinsic/ColumnSet3.cs b/StgSharp.Common/Internal/Intrinsic/ColumnSet3.cs
index 809eaf36..4fe9b0e2 100644
--- a/StgSharp.Common/Internal/Intrinsic/ColumnSet3.cs
+++ b/StgSharp.Common/Internal/Intrinsic/ColumnSet3.cs
@@ -39,8 +39,9 @@ using System.Runtime.InteropServices;
namespace StgSharp.Internal.Intrinsic
{
[StructLayout( LayoutKind.Explicit, Size = 12 * sizeof( float ), Pack = 16 )]
- internal struct ColumnSet3 : IEquatable, IMat
+ internal struct ColumnSet3 : IEquatable
{
+
[FieldOffset( 0 * sizeof( float ) )] internal float m00;
[FieldOffset( 4 * sizeof( float ) )] internal float m01;
[FieldOffset( 8 * sizeof( float ) )] internal float m02;
diff --git a/StgSharp.Common/Internal/Intrinsic/ColumnSet4.cs b/StgSharp.Common/Internal/Intrinsic/ColumnSet4.cs
index b3781305..8093c0f5 100644
--- a/StgSharp.Common/Internal/Intrinsic/ColumnSet4.cs
+++ b/StgSharp.Common/Internal/Intrinsic/ColumnSet4.cs
@@ -39,7 +39,7 @@ using System.Runtime.InteropServices;
namespace StgSharp.Internal.Intrinsic
{
[StructLayout( LayoutKind.Explicit, Size = 16 * sizeof( float ) )]
- internal struct ColumnSet4 : IEquatable, IMat
+ internal struct ColumnSet4 : IEquatable
{
[FieldOffset( 0 )] internal Vector4 colum0;
diff --git a/StgSharp.Common/Math/Graphic/Camera.cs b/StgSharp.Common/Math/Graphic/Camera.cs
index 5e9f06bc..14195980 100644
--- a/StgSharp.Common/Math/Graphic/Camera.cs
+++ b/StgSharp.Common/Math/Graphic/Camera.cs
@@ -111,12 +111,13 @@ namespace StgSharp.Graphics
///
///
public unsafe void GainAllUniforms(
- ShaderProgram source,
- params string[] uniformName )
+ ShaderProgram source,
+ params string[] uniformName )
{
- if( uniformName.Length != 1 ) {
+ if( uniformName is null || uniformName.Length != 1 ) {
throw new ArgumentException(
- "Camera needs only one uniform.", nameof( uniformName ) );
+ "Camera needs exactly one uniform.",
+ nameof( uniformName ) );
}
convertedUniform = source.GetUniform( uniformName[ 0 ] );
}
@@ -143,13 +144,14 @@ namespace StgSharp.Graphics
{
//Console.WriteLine(Projection * ViewBase);
OpenGL.OpenGLFunction.CurrentGL
- .SetUniformValue( convertedUniform, Projection * View );
+ .SetUniformValue( convertedUniform, Projection * View );
}
public void SetViewDirection( Vec3 position, Vec3 target, Vec3 up )
{
Vec3 direction = position - target;
- if( ( position.vec == cameraAtt.colum3.vec ) && ( this.up == up ) && ( cameraAtt.colum2.vec == direction.vec ) ) {
+ if( ( position.reg == cameraAtt.colum3.reg ) && ( this.up == up ) && ( cameraAtt.colum2.reg ==
+ direction.reg ) ) {
//no difference with precious value
return;
}
@@ -169,10 +171,10 @@ namespace StgSharp.Graphics
Vec3 right = Linear.Orthogonalize( Linear.Cross( up, direction ) );
- cameraAtt.colum0.vec = right.vec;
- cameraAtt.colum1.vec = up.vec;
- cameraAtt.colum2.vec = direction.vec;
- cameraAtt.colum3.vec = position.vec;
+ cameraAtt.colum0.reg = right. reg;
+ cameraAtt.colum1.reg = up.reg;
+ cameraAtt.colum2.reg = direction.reg;
+ cameraAtt.colum3.reg = position. reg;
InternalPitch();
InternalRow();
@@ -180,10 +182,10 @@ namespace StgSharp.Graphics
}
public void SetViewRange(
- Radius fovRadius,
- Vec2 size,
- Vec2 offset,
- (float front, float back) dephRange )
+ Radius fovRadius,
+ Vec2 size,
+ Vec2 offset,
+ (float front, float back) dephRange )
{
float
distance = _target.GetLength(),
@@ -264,8 +266,8 @@ namespace StgSharp.Graphics
Scaler.Cos( angle ) );
partialCoord *= rotation;
- rotationAtt.colum1.vec = partialCoord.colum0.vec;
- rotationAtt.colum2.vec = partialCoord.colum1.vec;
+ rotationAtt.colum1.reg = partialCoord.colum0.reg;
+ rotationAtt.colum2.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
}
@@ -282,8 +284,8 @@ namespace StgSharp.Graphics
Scaler.Cos( angle ) );
partialCoord *= rotation;
- rotationAtt.colum0.vec = partialCoord.colum0.vec;
- rotationAtt.colum1.vec = partialCoord.colum1.vec;
+ rotationAtt.colum0.reg = partialCoord.colum0.reg;
+ rotationAtt.colum1.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
}
@@ -299,8 +301,8 @@ namespace StgSharp.Graphics
Scaler.Cos( angle ) );
partialCoord *= rotation;
- rotationAtt.colum0.vec = partialCoord.colum0.vec;
- rotationAtt.colum2.vec = partialCoord.colum1.vec;
+ rotationAtt.colum0.reg = partialCoord.colum0.reg;
+ rotationAtt.colum2.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
}
diff --git a/StgSharp.Common/Math/Linear/IMatrix.cs b/StgSharp.Common/Math/Linear/IMatrix.cs
new file mode 100644
index 00000000..7d97ce24
--- /dev/null
+++ b/StgSharp.Common/Math/Linear/IMatrix.cs
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="IMatrix.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using StgSharp.Graphics;
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace StgSharp.Math
+{
+ public interface IMatrix where TSelf: IMatrix { }
+}
diff --git a/StgSharp.Common/Math/Linear/IVector.cs b/StgSharp.Common/Math/Linear/IVector.cs
index ad02839a..e033b654 100644
--- a/StgSharp.Common/Math/Linear/IVector.cs
+++ b/StgSharp.Common/Math/Linear/IVector.cs
@@ -37,14 +37,30 @@ using System.Threading.Tasks;
namespace StgSharp.Math
{
- public interface IVector
+ public interface IVector where TSelf: struct, IVector
{
- /*
- public static TItem Create(Vector4 source) where TItem : IVector
+
+ public static abstract TSelf Zero
{
- return TItem
+ get;
+ }
+
+ public static abstract TSelf One
+ {
+ get;
+ }
+
+ public Vec2 XY
+ {
+ get;
+ set;
+ }
+
+ public Vec3 XYZ
+ {
+ get;
+ set;
}
- /**/
}
}
diff --git a/StgSharp.Common/Math/Linear/Matrix22.cs b/StgSharp.Common/Math/Linear/Matrix22.cs
index 176c6996..99f9df32 100644
--- a/StgSharp.Common/Math/Linear/Matrix22.cs
+++ b/StgSharp.Common/Math/Linear/Matrix22.cs
@@ -40,7 +40,7 @@ namespace StgSharp.Math
LayoutKind.Explicit,
Size = ( 2 * 2 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
- public struct Matrix22 : IMat
+ public struct Matrix22 : IMatrix
{
[FieldOffset( 2 * 2 * 4 * sizeof( float ) )]
@@ -101,7 +101,6 @@ namespace StgSharp.Math
float cache = _transpose.m10;
_transpose.m10 = _transpose.m01;
_transpose.m01 = cache;
-
isTransposed = true;
}
}
diff --git a/StgSharp.Common/Math/Linear/Matrix23.cs b/StgSharp.Common/Math/Linear/Matrix23.cs
index e41238cf..a0c2a81e 100644
--- a/StgSharp.Common/Math/Linear/Matrix23.cs
+++ b/StgSharp.Common/Math/Linear/Matrix23.cs
@@ -41,7 +41,7 @@ namespace StgSharp.Math
LayoutKind.Explicit,
Size = ( ( 3 + 2 ) * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
- public struct Matrix23 : IMat
+ public struct Matrix23 : IMatrix
{
[FieldOffset( 5 * 4 * sizeof( float ) )] internal bool isTransposed = false;
diff --git a/StgSharp.Common/Math/Linear/Matrix24.cs b/StgSharp.Common/Math/Linear/Matrix24.cs
index 4c29c648..6e1f007c 100644
--- a/StgSharp.Common/Math/Linear/Matrix24.cs
+++ b/StgSharp.Common/Math/Linear/Matrix24.cs
@@ -41,7 +41,7 @@ namespace StgSharp.Math
LayoutKind.Explicit,
Size = ( ( 4 + 2 ) * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
- public struct Matrix24 : IMat
+ public struct Matrix24 : IMatrix
{
[FieldOffset( 6 * 4 * sizeof( float ) )] internal bool isTransposed;
diff --git a/StgSharp.Common/Math/Linear/Matrix32.cs b/StgSharp.Common/Math/Linear/Matrix32.cs
index 460a7fdf..213fb909 100644
--- a/StgSharp.Common/Math/Linear/Matrix32.cs
+++ b/StgSharp.Common/Math/Linear/Matrix32.cs
@@ -41,7 +41,7 @@ namespace StgSharp.Math
LayoutKind.Explicit,
Size = ( 5 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
- public struct Matrix32 : IMat
+ public struct Matrix32 : IMatrix
{
[FieldOffset( 5 * 4 * sizeof( float ) )] internal bool isTransposed;
diff --git a/StgSharp.Common/Math/Linear/Matrix33.cs b/StgSharp.Common/Math/Linear/Matrix33.cs
index b7bb3f50..bd77da3f 100644
--- a/StgSharp.Common/Math/Linear/Matrix33.cs
+++ b/StgSharp.Common/Math/Linear/Matrix33.cs
@@ -41,7 +41,7 @@ namespace StgSharp.Math
LayoutKind.Explicit,
Size = ( 6 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
- public struct Matrix33 : IMat
+ public struct Matrix33 : IMatrix
{
[FieldOffset( 6 * 4 * sizeof( float ) )] internal bool isTransposed;
@@ -162,9 +162,9 @@ namespace StgSharp.Math
{
left.InternalTranspose();
return new Vec3(
- Vector4.Dot( left.transpose.colum0, right.vec ),
- Vector4.Dot( left.transpose.colum1, right.vec ),
- Vector4.Dot( left.transpose.colum2, right.vec ) );
+ Vector4.Dot( left.transpose.colum0, right.reg.AsVector4() ),
+ Vector4.Dot( left.transpose.colum1, right.reg.AsVector4() ),
+ Vector4.Dot( left.transpose.colum2, right.reg.AsVector4() ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
diff --git a/StgSharp.Common/Math/Linear/Matrix34.cs b/StgSharp.Common/Math/Linear/Matrix34.cs
index 7d5dcaf3..765c022c 100644
--- a/StgSharp.Common/Math/Linear/Matrix34.cs
+++ b/StgSharp.Common/Math/Linear/Matrix34.cs
@@ -42,7 +42,7 @@ namespace StgSharp.Math
LayoutKind.Explicit,
Size = ( 7 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
- public struct Matrix34 : IMat
+ public struct Matrix34 : IMatrix
{
[FieldOffset( 7 * 4 * sizeof( float ) )] internal bool isTransposed;
diff --git a/StgSharp.Common/Math/Linear/Matrix42.cs b/StgSharp.Common/Math/Linear/Matrix42.cs
index fc580a3c..f971c83e 100644
--- a/StgSharp.Common/Math/Linear/Matrix42.cs
+++ b/StgSharp.Common/Math/Linear/Matrix42.cs
@@ -41,7 +41,7 @@ namespace StgSharp.Math
LayoutKind.Explicit,
Size = ( ( 16 + 8 ) * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
- public struct Matrix42 : IMat
+ public struct Matrix42 : IMatrix
{
[FieldOffset( ( 16 + 8 ) * sizeof( float ) )] internal bool isTransposed;
diff --git a/StgSharp.Common/Math/Linear/Matrix43.cs b/StgSharp.Common/Math/Linear/Matrix43.cs
index 14f32935..af978c6d 100644
--- a/StgSharp.Common/Math/Linear/Matrix43.cs
+++ b/StgSharp.Common/Math/Linear/Matrix43.cs
@@ -40,10 +40,10 @@ using System.Security.AccessControl;
namespace StgSharp.Math
{
[StructLayout(
- layoutKind: LayoutKind.Explicit,
- Size = ( 7 * 4 * sizeof( float ) ) + sizeof( bool ),
- Pack = 16 )]
- public struct Matrix43 : IEquatable, IMat
+ layoutKind: LayoutKind.Explicit,
+ Size = ( 7 * 4 * sizeof( float ) ) + sizeof( bool ),
+ Pack = 16 )]
+ public struct Matrix43 : IEquatable, IMatrix
{
[FieldOffset( 7 * 4 * sizeof( float ) )]
@@ -54,36 +54,36 @@ namespace StgSharp.Math
[FieldOffset( 3 * 4 * sizeof( float ) )]
internal ColumnSet4 transpose;
- public Matrix43()
- {
- Unsafe.SkipInit(out this);
- isTransposed = false;
- }
-
internal Matrix43( Vector4 c0, Vector4 c1, Vector4 c2 )
{
- Unsafe.SkipInit(out this);
+ Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
mat.colum2 = c2;
}
- public Matrix43(
- float a00,
- float a01,
- float a02,
- float a10,
- float a11,
- float a12,
- float a20,
- float a21,
- float a22,
- float a30,
- float a31,
- float a32 )
+ public Matrix43()
{
- Unsafe.SkipInit(out this);
+ Unsafe.SkipInit( out this );
+ isTransposed = false;
+ }
+
+ public Matrix43(
+ float a00,
+ float a01,
+ float a02,
+ float a10,
+ float a11,
+ float a12,
+ float a20,
+ float a21,
+ float a22,
+ float a30,
+ float a31,
+ float a32 )
+ {
+ Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, a30 );
mat.colum1 = new Vector4( a01, a11, a21, a31 );
@@ -145,10 +145,12 @@ namespace StgSharp.Math
internal unsafe void InternalTranspose()
{
if( !isTransposed ) {
- fixed( ColumnSet3* source = &this.mat )
- fixed( ColumnSet4* target = &this.transpose ) {
- InternalIO.Intrinsic.transpose34( source, target );
+ fixed( ColumnSet3* source = &this.mat ) {
+ fixed( ColumnSet4* target = &this.transpose ) {
+ InternalIO.Intrinsic.transpose34( source, target );
+ }
}
+
isTransposed = true;
}
}
@@ -250,10 +252,12 @@ namespace StgSharp.Math
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
- public static unsafe Matrix43 operator +( Matrix43 left, Matrix43 right )
+ public static unsafe Matrix43 operator +(
+ Matrix43 left,
+ Matrix43 right )
{
Matrix43 ret = new Matrix43();
- InternalIO.Intrinsic.add_mat_3(&left.mat, &right.mat, &ret.mat);
+ InternalIO.Intrinsic.add_mat_3( &left.mat, &right.mat, &ret.mat );
return ret;
}
diff --git a/StgSharp.Common/Math/Linear/Matrix44.cs b/StgSharp.Common/Math/Linear/Matrix44.cs
index 6e633415..84756810 100644
--- a/StgSharp.Common/Math/Linear/Matrix44.cs
+++ b/StgSharp.Common/Math/Linear/Matrix44.cs
@@ -40,10 +40,10 @@ using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
- LayoutKind.Explicit,
- Size = ( 2 * 16 * sizeof( float ) ) + sizeof( bool ),
- Pack = 16 )]
- public unsafe struct Matrix44 : IEquatable, IMat
+ LayoutKind.Explicit,
+ Size = ( 2 * 16 * sizeof( float ) ) + sizeof( bool ),
+ Pack = 16 )]
+ public unsafe struct Matrix44 : IEquatable, IMatrix
{
[FieldOffset( 2 * 64 * sizeof( float ) )] internal bool isTransposed;
@@ -55,26 +55,20 @@ namespace StgSharp.Math
[FieldOffset( 8 * sizeof( float ) )] internal Vec4 colum2;
[FieldOffset( 12 * sizeof( float ) )] internal Vec4 colum3;
- public Matrix44()
- {
- Unsafe.SkipInit(out this);
- isTransposed = false;
- }
-
internal Matrix44( ColumnSet4 mat )
{
- Unsafe.SkipInit(out this);
+ Unsafe.SkipInit( out this );
isTransposed = false;
this.mat = mat;
}
internal Matrix44(
- Vector4 vec0,
- Vector4 vec1,
- Vector4 vec2,
- Vector4 vec3 )
+ Vector4 vec0,
+ Vector4 vec1,
+ Vector4 vec2,
+ Vector4 vec3 )
{
- Unsafe.SkipInit(out this);
+ Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = vec0;
mat.colum1 = vec1;
@@ -82,25 +76,31 @@ namespace StgSharp.Math
mat.colum3 = vec3;
}
- public unsafe Matrix44(
- float a00,
- float a01,
- float a02,
- float a03,
- float a10,
- float a11,
- float a12,
- float a13,
- float a20,
- float a21,
- float a22,
- float a23,
- float a30,
- float a31,
- float a32,
- float a33 )
+ public Matrix44()
{
- Unsafe.SkipInit(out this);
+ Unsafe.SkipInit( out this );
+ isTransposed = false;
+ }
+
+ public unsafe Matrix44(
+ float a00,
+ float a01,
+ float a02,
+ float a03,
+ float a10,
+ float a11,
+ float a12,
+ float a13,
+ float a20,
+ float a21,
+ float a22,
+ float a23,
+ float a30,
+ float a31,
+ float a32,
+ float a33 )
+ {
+ Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, a30 );
mat.colum1 = new Vector4( a01, a11, a21, a31 );
@@ -195,6 +195,35 @@ namespace StgSharp.Math
mat.colum2.GetHashCode(), mat.colum3.GetHashCode() );
}
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public unsafe Matrix42 Multiple( in Matrix42 right )
+ {
+ InternalTranspose();
+ Matrix42 ans = new Matrix42();
+ fixed( ColumnSet4* lptr = &transpose ) {
+ fixed( Vector4* rptr = &right.mat.colum0 ) {
+ InternalIO.Intrinsic.dot_42( lptr, rptr, &ans.mat.colum0 );
+ }
+ }
+
+ return ans;
+ }
+
+ public unsafe Matrix43 Multiple( in Matrix43 right )
+ {
+ InternalTranspose();
+
+ Matrix43 ans = new Matrix43();
+
+ fixed( Vector4* rptr = &right.mat.colum0 ) {
+ fixed( ColumnSet4* lptr = &transpose ) {
+ InternalIO.Intrinsic.dot_43( lptr, rptr, &ans.mat.colum0 );
+ }
+ }
+
+ return ans;
+ }
+
public override string ToString()
{
InternalTranspose();
@@ -214,8 +243,8 @@ namespace StgSharp.Math
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix44 operator -(
- Matrix44 left,
- Matrix44 right )
+ Matrix44 left,
+ Matrix44 right )
{
return new Matrix44(
right.mat.colum0 - left.mat.colum0,
@@ -237,50 +266,26 @@ namespace StgSharp.Math
mat.mat.colum2 * value, mat.mat.colum3 * value );
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public unsafe Matrix42 Multiple(in Matrix42 right)
- {
- InternalTranspose();
- Matrix42 ans = new Matrix42();
- fixed (ColumnSet4* lptr = &transpose)
- fixed (Vector4* rptr = &right.mat.colum0)
- {
- InternalIO.Intrinsic.dot_42(lptr,rptr, &ans.mat.colum0);
- }
- return ans;
- }
-
- [Obsolete("The operand may cause performance loss, use Matrix.Multiple() method instead.",false)]
+ [Obsolete(
+ "The operand may cause performance loss, use Matrix.Multiple() method instead.",
+ false )]
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix42 operator *(
- Matrix44 left,
- Matrix42 right )
+ Matrix44 left,
+ Matrix42 right )
{
- return left.Multiple(right);
+ return left.Multiple( right );
}
- public unsafe Matrix43 Multiple(in Matrix43 right)
- {
- InternalTranspose();
-
- Matrix43 ans = new Matrix43();
-
- fixed(Vector4* rptr = &right.mat.colum0)
- fixed (ColumnSet4* lptr = &transpose)
- {
- InternalIO.Intrinsic.dot_43(lptr,rptr,&ans.mat.colum0);
- }
- return ans;
- }
-
- [Obsolete("The operand may cause performance loss, use Matrix.Multiple() method instead.", false)]
+ [Obsolete(
+ "The operand may cause performance loss, use Matrix.Multiple() method instead.",
+ false )]
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix43 operator *( Matrix44 left, Matrix43 right )
{
- return left.Multiple(in right);
+ return left.Multiple( in right );
}
-
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix44 operator *( Matrix44 left, Matrix44 right )
{
@@ -308,10 +313,12 @@ namespace StgSharp.Math
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
- public static unsafe Matrix44 operator +(Matrix44 left, Matrix44 right )
+ public static unsafe Matrix44 operator +(
+ Matrix44 left,
+ Matrix44 right )
{
Matrix44 ret = new Matrix44();
- InternalIO.Intrinsic.add_mat_4(&left.mat, &right.mat, &ret.mat);
+ InternalIO.Intrinsic.add_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
diff --git a/StgSharp.Common/Math/Linear/Vec2.cs b/StgSharp.Common/Math/Linear/Vec2.cs
index a7c7ea12..1d8da84d 100644
--- a/StgSharp.Common/Math/Linear/Vec2.cs
+++ b/StgSharp.Common/Math/Linear/Vec2.cs
@@ -28,6 +28,9 @@
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
+using StgSharp.HighPerformance;
+
+using System.Net.Http.Headers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -35,20 +38,20 @@ using System.Runtime.InteropServices;
namespace StgSharp.Math
{
///
- /// A two dimension vector defined by two elements. Vec2Ds in StgSharp are default used as colum
+ /// A two dimension vector defined by two elements. Vec2 in StgSharp are default used as colum
/// vector.
///
[StructLayout( LayoutKind.Explicit, Size = 16, Pack = 16 )]
- public struct Vec2 : IVector
+ public struct Vec2 : IVector
{
[FieldOffset( 0 )] internal unsafe fixed float num[ 2 ];
[FieldOffset( 0 )]
- internal Vector2 v;
+ internal M128 reg;
[FieldOffset( 0 )]
- internal Vector4 vec;
+ internal Vector2 v;
[FieldOffset( 0 )]
public float X;
@@ -57,12 +60,19 @@ namespace StgSharp.Math
internal Vec2( Vector2 vec )
{
+ Unsafe.SkipInit( out reg );
+ Unsafe.SkipInit( out X );
+ Unsafe.SkipInit( out Y );
v = vec;
}
- internal Vec2( Vector4 vec )
+ internal Vec2( M128 vec )
{
- this.vec = vec;
+ Unsafe.SkipInit( out reg );
+ Unsafe.SkipInit( out X );
+ Unsafe.SkipInit( out Y );
+ reg = vec;
+ reg.Write( 1, 0 );
}
public Vec2( float x, float y )
@@ -74,6 +84,27 @@ namespace StgSharp.Math
public static Vec2 Zero => new Vec2( 0, 0 );
+ public static Vec2 One
+ {
+ get => new Vec2( 1, 1 );
+ }
+
+ public Vec2 XY
+ {
+ get => this;
+ set => this = value;
+ }
+
+ public Vec3 XYZ
+ {
+ get => new Vec3( reg );
+ set
+ {
+ reg = value.reg;
+ reg.Write( 1, 0 );
+ }
+ }
+
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public float Cross( Vec2 right )
{
diff --git a/StgSharp.Common/Math/Linear/Vec3.cs b/StgSharp.Common/Math/Linear/Vec3.cs
index 9fba0367..e24de603 100644
--- a/StgSharp.Common/Math/Linear/Vec3.cs
+++ b/StgSharp.Common/Math/Linear/Vec3.cs
@@ -38,26 +38,26 @@ using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout( LayoutKind.Explicit, Size = 16, Pack = 16 )]
- public struct Vec3 : IEquatable, IVector
+ public struct Vec3 : IEquatable, IVector
{
[FieldOffset( 0 )] internal unsafe fixed float num[ 3 ];
- [FieldOffset( 0 )]
- internal M128 reg;
+ [FieldOffset( 0 )] internal M128 reg;
- [FieldOffset( 0 )]
- internal Vector3 v;
-
- [FieldOffset( 0 )]
- internal Vector4 vec;
+ [FieldOffset( 0 )] internal Vector3 v;
[FieldOffset( 0 )] public float X;
[FieldOffset( 4 )] public float Y;
[FieldOffset( 8 )] public float Z;
- internal Vec3( Vector4 vector )
+ internal Vec3( M128 vector )
{
- vec = vector;
+ Unsafe.SkipInit( out X );
+ Unsafe.SkipInit( out Y );
+ Unsafe.SkipInit( out Z );
+ Unsafe.SkipInit( out v );
+ reg = vector;
+ reg.Write( 3, 0 );
}
internal Vec3( Vector3 vector )
@@ -67,21 +67,26 @@ namespace StgSharp.Math
public Vec3( Vec2 xy, float z )
{
- vec = xy.vec;
+ Unsafe.SkipInit( out X );
+ Unsafe.SkipInit( out Y );
+ Unsafe.SkipInit( out Z );
+ Unsafe.SkipInit( out v );
+ reg = xy.reg;
Z = z;
}
public Vec3( float x, float y, float z )
{
- #if NET5_0_OR_GREATER
- Unsafe.SkipInit( out vec );
- #endif
+ Unsafe.SkipInit( out reg );
+ Unsafe.SkipInit( out X );
+ Unsafe.SkipInit( out Y );
+ Unsafe.SkipInit( out Z );
v = new Vector3( x, y, z );
}
public unsafe Vec2 XY
{
- get => new Vec2( this.vec );
+ get => new Vec2( this.reg );
set
{
fixed( Vector3* vptr = &v ) {
@@ -93,6 +98,7 @@ namespace StgSharp.Math
public Vec3 XYZ
{
get { return new Vec3( v ); }
+ set { this = value; }
}
public static Vec3 Zero
@@ -122,7 +128,7 @@ namespace StgSharp.Math
public bool Equals( Vec3 other )
{
- return this.vec == other.vec;
+ return this.reg == other.reg;
}
public override bool Equals( object obj )
@@ -168,7 +174,7 @@ namespace StgSharp.Math
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Vec3 operator -( Vec3 vec )
{
- return new Vec3( -vec.vec );
+ return new Vec3( -vec.v );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
@@ -204,7 +210,7 @@ namespace StgSharp.Math
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Vec3 operator +( Vec3 left, Vec3 right )
{
- return new Vec3( left.vec + right.vec );
+ return new Vec3( left.v + right.v );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
@@ -217,9 +223,8 @@ namespace StgSharp.Math
public static unsafe implicit operator Vec3(
(float, float, float) tuple )
{
- Vec3 v = *( Vec3* )&tuple;
- v.vec.W = 0.0f;
- return v;
+ Vec3 vec = new Vec3( *( Vector3* )&tuple );
+ return vec;
}
}
diff --git a/StgSharp.Common/Math/Linear/Vec4.cs b/StgSharp.Common/Math/Linear/Vec4.cs
index 6382a4f4..0e8e798c 100644
--- a/StgSharp.Common/Math/Linear/Vec4.cs
+++ b/StgSharp.Common/Math/Linear/Vec4.cs
@@ -41,7 +41,7 @@ using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout( LayoutKind.Explicit, Size = 16, Pack = 16 )]
- public struct Vec4 : IEquatable, IVector
+ public struct Vec4 : IEquatable, IVector
{
[FieldOffset( 0 )] internal unsafe fixed float num[ 4 ];
@@ -57,12 +57,33 @@ namespace StgSharp.Math
internal Vec4( Vector4 v )
{
+ Unsafe.SkipInit( out X );
+ Unsafe.SkipInit( out Y );
+ Unsafe.SkipInit( out Z );
+ Unsafe.SkipInit( out W );
+ Unsafe.SkipInit( out reg );
+
vec = v;
}
- public Vec4( Vec3 v, float w )
+ internal Vec4( M128 v )
{
- vec = v.vec;
+ Unsafe.SkipInit( out X );
+ Unsafe.SkipInit( out Y );
+ Unsafe.SkipInit( out Z );
+ Unsafe.SkipInit( out W );
+ Unsafe.SkipInit( out vec );
+
+ reg = v;
+ }
+
+ public Vec4( Vec3 v3, float w )
+ {
+ Unsafe.SkipInit( out X );
+ Unsafe.SkipInit( out Y );
+ Unsafe.SkipInit( out Z );
+ Unsafe.SkipInit( out W );
+ reg = v3.reg;
W = w;
}
@@ -73,7 +94,7 @@ namespace StgSharp.Math
public unsafe Vec2 XY
{
- get => new Vec2( vec );
+ get => new Vec2( reg );
set
{
X = value.X;
@@ -83,23 +104,23 @@ namespace StgSharp.Math
public unsafe Vec3 XYZ
{
- get => new Vec3( vec );
+ get => new Vec3( reg );
set
{
float w = W;
- vec = value.vec;
+ reg = value.reg;
W = w;
}
}
public static Vec4 One
{
- get => new Vec4( Vector4.One );
+ get => new Vec4( 1, 1, 1, 1 );
}
public static Vec4 Zero
{
- get => new Vec4( Vector4.Zero );
+ get => new Vec4( 0, 0, 0, 0 );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
diff --git a/StgSharp.Common/Math/Linear/Vector.Normalize.cs b/StgSharp.Common/Math/Linear/Vector.Normalize.cs
index 5ba9919a..060e6d97 100644
--- a/StgSharp.Common/Math/Linear/Vector.Normalize.cs
+++ b/StgSharp.Common/Math/Linear/Vector.Normalize.cs
@@ -51,7 +51,7 @@ namespace StgSharp.Math
public static Vec3 Normalize( Vec3 vec )
{
- return new Vec3 { vec = Vector4.Normalize( vec.vec ) };
+ return new Vec3 { v = Vector3.Normalize( vec.v ) };
}
public static unsafe void Normalize( ref Vec4 source, ref Vec4 target )
diff --git a/StgSharp.Common/Math/Linear/Vector.Orthogonalize.cs b/StgSharp.Common/Math/Linear/Vector.Orthogonalize.cs
index 5cd1da89..37ac187e 100644
--- a/StgSharp.Common/Math/Linear/Vector.Orthogonalize.cs
+++ b/StgSharp.Common/Math/Linear/Vector.Orthogonalize.cs
@@ -55,8 +55,8 @@ namespace StgSharp.Math
}
public static unsafe void Orthogonalize(
- ref Vec4 source,
- ref Vec4 target )
+ ref Vec4 source,
+ ref Vec4 target )
{
Vector4 s = source.vec;
Vector4 t = target.vec;
@@ -79,8 +79,8 @@ namespace StgSharp.Math
///
///
public static unsafe void Orthogonalize(
- ref Vec3 source,
- ref Vec3 target )
+ ref Vec3 source,
+ ref Vec3 target )
{
Vector3 s = source.v;
Vector3 t = target.v;
diff --git a/StgSharp.Common/Math/Scalar/ACos.cs b/StgSharp.Common/Math/Scalar/ACos.cs
index 90e8744d..c352f2a6 100644
--- a/StgSharp.Common/Math/Scalar/ACos.cs
+++ b/StgSharp.Common/Math/Scalar/ACos.cs
@@ -60,7 +60,7 @@ namespace StgSharp.Math
throw new ArgumentException();
}
- float r, s, u, v = 0.0f;
+ float r, s, u, vec = 0.0f;
bool transform = (y >= 0.5f);
if (transform)
@@ -93,16 +93,16 @@ namespace StgSharp.Math
c = (r - s1 * s1) / (s + s1);
p = 2.0F * s * u - (piby2_tail - 2.0F * c);
q = hpiby2_head - 2.0F * s1;
- v = hpiby2_head - (p - q);
+ vec = hpiby2_head - (p - q);
}
else
{
- v = y + y * u;
+ vec = y + y * u;
}
- v = sign * v;
+ vec = sign * vec;
- return piby2 - v;
+ return piby2 - vec;
*/
}
diff --git a/StgSharp.Common/Math/Scalar/ASin.cs b/StgSharp.Common/Math/Scalar/ASin.cs
index 7b32d995..bb32dd13 100644
--- a/StgSharp.Common/Math/Scalar/ASin.cs
+++ b/StgSharp.Common/Math/Scalar/ASin.cs
@@ -68,7 +68,7 @@ namespace StgSharp.Math
throw new ArgumentException();
}
- float r, s, u, v = 0.0f;
+ float r, s, u, vec = 0.0f;
bool transform = (y >= 0.5f);
if (transform)
@@ -101,14 +101,14 @@ namespace StgSharp.Math
c = (r - s1 * s1) / (s + s1);
p = 2.0F * s * u - (piby2_tail - 2.0F * c);
q = hpiby2_head - 2.0F * s1;
- v = hpiby2_head - (p - q);
+ vec = hpiby2_head - (p - q);
}
else
{
- v = y + y * u;
+ vec = y + y * u;
}/*
- return sign * v;
+ return sign * vec;
*/
}
diff --git a/StgSharp.Common/Math/Scalar/ATan.cs b/StgSharp.Common/Math/Scalar/ATan.cs
index e9068cd2..b3a8c1b0 100644
--- a/StgSharp.Common/Math/Scalar/ATan.cs
+++ b/StgSharp.Common/Math/Scalar/ATan.cs
@@ -63,11 +63,11 @@ namespace StgSharp.Math
angle = 0.7853981634f;
}
- float v = 0.7853981634f * x + x * (1 - x) * (0.2447f + 0.0663f * x);
- v += angle;
- v *= sign;
+ float vec = 0.7853981634f * x + x * (1 - x) * (0.2447f + 0.0663f * x);
+ vec += angle;
+ vec *= sign;
- return v;
+ return vec;
}
@@ -105,13 +105,13 @@ namespace StgSharp.Math
angle2 = 0.7853981634f;
}
- float v = 0.7853981634f * z + z * (1 - z) * (0.2447f + 0.0663f * z);
- v *= 57.29577951f;
- v += angle2;
- v += angle;
- v *= sign;
+ float vec = 0.7853981634f * z + z * (1 - z) * (0.2447f + 0.0663f * z);
+ vec *= 57.29577951f;
+ vec += angle2;
+ vec += angle;
+ vec *= sign;
- return v;
+ return vec;
*/
}
diff --git a/StgSharp.Common/PipeLine/Blueprint.NodeCraeater.cs b/StgSharp.Common/PipeLine/Blueprint.NodeCraeater.cs
new file mode 100644
index 00000000..ba758b68
--- /dev/null
+++ b/StgSharp.Common/PipeLine/Blueprint.NodeCraeater.cs
@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="PipeLine.NodeCraeater.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace StgSharp.PipeLine
+{
+ public partial class BlueprintScheduler
+ {
+
+ public PipeLineNode CreateBlueprintNode(
+ string name,
+ BlueprintNodeOperation operation,
+ string[] inputPort,
+ string[] outputPort,
+ bool isNative )
+ {
+ PipeLineNode node = new PipeLineNode(
+ operation, name, isNative, inputPort, outputPort );
+ if( isNative ) {
+ mainThreadNodeList.Add( node );
+ } else {
+ globalNodeList.Add( node );
+ }
+ return node;
+ }
+
+ }
+}
diff --git a/StgSharp.Common/PipeLine/Blueprint.cs b/StgSharp.Common/PipeLine/Blueprint.cs
new file mode 100644
index 00000000..9d872be0
--- /dev/null
+++ b/StgSharp.Common/PipeLine/Blueprint.cs
@@ -0,0 +1,177 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="Blueprint.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+namespace StgSharp.PipeLine
+{
+ ///
+ /// A sets of complex logic designed for running in multi threads environment. Warning: do not
+ /// run a instance in multi threads more than once.
+ ///
+ public partial class BlueprintScheduler : IConvertableToBlueprintNode
+ {
+
+ private List[] _concurrentNodes, _mainThreadNodes;
+
+ private BeginningNode beginNode;
+ private Dictionary allNode;
+ private EndingNode endNode;
+
+ private Func terminate;
+ private List globalNodeList;
+ private List mainThreadNodeList;
+
+ private SemaphoreSlim runningStat;
+
+ internal int currentGlobalNodeIndex;
+ internal int currentNativeNodeIndex;
+
+ public BlueprintScheduler()
+ {
+ allNode = new Dictionary();
+ globalNodeList = new List();
+ mainThreadNodeList = new List();
+ runningStat = new SemaphoreSlim( 1, 1 );
+ beginNode = new BeginningNode( this );
+ endNode = new EndingNode( this );
+ }
+
+ public BlueprintNodeOperation Operation
+ {
+ get => ExecuteMain;
+ }
+
+ public bool IsRunning
+ {
+ get => runningStat.CurrentCount == 0;
+ }
+
+ public IEnumerable InputInterfacesName
+ {
+ get { return beginNode.OutputInterfaces.Keys; }
+ }
+
+ public IEnumerable OutputInterfacesName
+ {
+ get { return beginNode.OutputInterfaces.Keys; }
+ }
+
+ public PipeLineNode BeginLayer => beginNode;
+
+ public PipeLineNode EndLayer => endNode;
+
+ /**/
+
+ internal SemaphoreSlim RunningStat
+ {
+ get => runningStat;
+ }
+ /**/
+
+ public void AddNode( PipeLineNode node, bool isNative )
+ {
+ _ = node ?? throw new ArgumentNullException( nameof( node ) );
+ node.IsNative = isNative;
+ allNode.Add( node.Name, node );
+ }
+
+ public void ExecuteMain(
+ in Dictionary input,
+ in Dictionary output )
+ {
+ PipeLineRunner.Run( this );
+ }
+
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public (string name, PipeLineConnectorArgs arg)[] GetOutput()
+ {
+ return endNode.OutputData;
+ }
+
+ public void Init()
+ {
+ foreach( KeyValuePair item in allNode ) {
+ if( item.Value.IsNative ) {
+ mainThreadNodeList.Add( item.Value );
+ } else {
+ globalNodeList.Add( item.Value );
+ }
+ }
+ mainThreadNodeList.Sort();
+ globalNodeList.Sort();
+ }
+
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public void SetInput(
+ params (string name, PipeLineConnectorArgs arg)[] parameters )
+ {
+ beginNode.InputData = parameters;
+ }
+
+ public void Terminate()
+ {
+ Interlocked.Exchange( ref currentGlobalNodeIndex, int.MaxValue );
+ Interlocked.Exchange( ref currentNativeNodeIndex, int.MaxValue );
+ }
+
+ internal bool RequestNexGlobalNode( out PipeLineNode node )
+ {
+ if( currentGlobalNodeIndex < globalNodeList.Count ) {
+ node = globalNodeList[ currentGlobalNodeIndex ];
+ Interlocked.Increment( ref currentGlobalNodeIndex );
+ return true;
+ }
+ node = default!;
+ return false;
+ }
+
+ internal bool RequestNextNativeNode( out PipeLineNode node )
+ {
+ if( currentNativeNodeIndex < mainThreadNodeList.Count ) {
+ node = mainThreadNodeList[ currentNativeNodeIndex ];
+ Interlocked.Increment( ref currentNativeNodeIndex );
+ return true;
+ }
+ node = default!;
+ return false;
+ }
+
+ ~BlueprintScheduler()
+ {
+ runningStat.Dispose();
+ }
+
+ }
+}
diff --git a/StgSharp.Common/PipeLine/Connector.cs b/StgSharp.Common/PipeLine/Connector.cs
new file mode 100644
index 00000000..b79289af
--- /dev/null
+++ b/StgSharp.Common/PipeLine/Connector.cs
@@ -0,0 +1,168 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="Connector.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using System.Security.Authentication.ExtendedProtection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace StgSharp.PipeLine
+{
+ public class PipelineConnector
+ {
+
+ private protected PipeLineNode after;
+ private protected PipeLineNode former;
+ private protected PipeLineConnectorArgs args;
+ private protected SemaphoreSlim formerCompleteSemaphore;
+
+ public PipelineConnector( PipeLineNode former, PipeLineNode after )
+ {
+ this.former = former;
+ this.after = after;
+ formerCompleteSemaphore = new SemaphoreSlim(
+ initialCount: 0, maxCount: 1 );
+ }
+
+ public PipeLineNode After => after;
+
+ public PipeLineNode Former => former;
+
+ public PipeLineConnectorArgs Args
+ {
+ get => args;
+ set => args = value;
+ }
+
+ public int Level => former.Level;
+
+ public static void SkipAll(
+ Dictionary ports )
+ {
+ if( ports == null ) {
+ return;
+ }
+ foreach( KeyValuePair item in ports ) {
+ if( item.Value != null ) {
+ item.Value.CompleteAndSkip();
+ }
+ }
+ }
+
+ public static void WaitAll(
+ Dictionary ports )
+ {
+ if( ports == null ) {
+ return;
+ }
+ foreach( KeyValuePair item in ports ) {
+ if( item.Value != null ) {
+ item.Value.WaitForStart();
+ }
+ }
+ }
+
+ public virtual void WaitForStart()
+ {
+ //Console.WriteLine($"Waiting \t{former.ContextName}\t->\t{after.ContextName}");
+ formerCompleteSemaphore.Wait();
+ }
+
+ ~PipelineConnector()
+ {
+ formerCompleteSemaphore.Dispose();
+ }
+
+ #region pipline op
+
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public void CompleteAndSkip()
+ {
+ //Console.WriteLine($"Complete\t{former.Name}\t->\t{after.Name}");
+ formerCompleteSemaphore.Release();
+ }
+
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public void CompleteAndWriteData( PipeLineConnectorArgs args )
+ {
+ this.args = args;
+ CompleteAndSkip();
+ }
+
+ #endregion
+ }
+
+ public abstract class PipeLineConnectorArgs
+ {
+
+ public object? Value
+ {
+ get;
+ set;
+ }
+
+ public object? ValueDefault
+ {
+ get;
+ }
+
+ }
+
+ public sealed class SealedBlueprintPiipeline : PipelineConnector
+ {
+
+ internal SealedBlueprintPiipeline(
+ PipeLineNode former,
+ PipeLineNode after )
+ : base( former, after ) { }
+
+ public static SealedBlueprintPiipeline SealInput(
+ PipeLineNode node,
+ string portName )
+ {
+ return new SealedBlueprintPiipeline( PipeLineNode.Empty, node );
+ }
+
+ public static SealedBlueprintPiipeline SealOutput(
+ PipeLineNode node,
+ string portName )
+ {
+ return new SealedBlueprintPiipeline( node, PipeLineNode.Empty );
+ }
+
+ public override sealed void WaitForStart() { }
+
+ }
+}
diff --git a/StgSharp.Common/PipeLine/CrossFramePipelineNode.cs b/StgSharp.Common/PipeLine/CrossFramePipelineNode.cs
new file mode 100644
index 00000000..917d3874
--- /dev/null
+++ b/StgSharp.Common/PipeLine/CrossFramePipelineNode.cs
@@ -0,0 +1,91 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="CrossFramePipelineNode.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using StgSharp.PipeLine;
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace StgSharp.PipeLine
+{
+ public class CrossFrameOperation : IConvertableToBlueprintNode
+ {
+
+ private static string[] _inputName = ["TaskIn"];
+ private static string[] _outputName = ["TaskOut"];
+ private Action _mainExecution;
+ private int currentCount;
+ private readonly int cycleCount;
+
+ public CrossFrameOperation( Action startup, int cycleCount )
+ {
+ MainExecution = startup;
+ this.cycleCount = ( cycleCount > 1 ) ?
+ cycleCount : throw new ArgumentException(
+ $"{$"The {typeof(CrossFrameOperation).Name} crosses only one cycle, "}{$"please use a {typeof(PipeLineNode).Name} instead."}" );
+ this.cycleCount = cycleCount;
+ currentCount = cycleCount;
+ }
+
+ public Action MainExecution
+ {
+ get => _mainExecution;
+ private protected set => _mainExecution = value;
+ }
+
+ public BlueprintNodeOperation Operation
+ {
+ get => ExecuteMain;
+ }
+
+ public IEnumerable InputInterfacesName => _inputName;
+
+ public IEnumerable OutputInterfacesName => _outputName;
+
+ public void ExecuteMain(
+ in Dictionary input,
+ in Dictionary output )
+ {
+ if( currentCount < cycleCount ) {
+ Interlocked.Increment( ref currentCount );
+ } else {
+ Interlocked.Exchange( ref currentCount, 0 );
+ Task.Run( MainExecution );
+ }
+
+ //Console.WriteLine(currentCount);
+ PipelineConnector.SkipAll( output );
+ }
+
+ }
+}
diff --git a/StgSharp.Common/PipeLine/IConvertableToBlueprintNode.cs b/StgSharp.Common/PipeLine/IConvertableToBlueprintNode.cs
new file mode 100644
index 00000000..5fe329db
--- /dev/null
+++ b/StgSharp.Common/PipeLine/IConvertableToBlueprintNode.cs
@@ -0,0 +1,86 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="IConvertableToBlueprintNode.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace StgSharp.PipeLine
+{
+ public delegate void BlueprintNodeOperation(
+ in Dictionary input,
+ in Dictionary output );
+
+ public interface IConvertableToBlueprintNode
+ {
+
+ BlueprintNodeOperation Operation
+ {
+ get;
+ }
+
+ public IEnumerable InputInterfacesName
+ {
+ get;
+ }
+
+ public IEnumerable OutputInterfacesName
+ {
+ get;
+ }
+
+ }
+
+ internal class DefaultConvertableToBlueprintNode : IConvertableToBlueprintNode
+ {
+
+ private string[] _input;
+ private string[] _output;
+ private BlueprintNodeOperation _execution;
+
+ public DefaultConvertableToBlueprintNode(
+ BlueprintNodeOperation execution,
+ string[] input,
+ string[] output )
+ {
+ _input = input;
+ _output = output;
+ _execution = execution;
+ }
+
+ public BlueprintNodeOperation Operation => _execution;
+
+ public IEnumerable InputInterfacesName => _input;
+
+ public IEnumerable OutputInterfacesName => _output;
+
+ }
+}
diff --git a/StgSharp.Common/PipeLine/PipeLineNode.cs b/StgSharp.Common/PipeLine/PipeLineNode.cs
new file mode 100644
index 00000000..3cdb8bc6
--- /dev/null
+++ b/StgSharp.Common/PipeLine/PipeLineNode.cs
@@ -0,0 +1,300 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="PipeLineNode.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using StgSharp.Entities;
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace StgSharp.PipeLine
+{
+ ///
+ ///
+ ///
+ ///
+ /// Reset pipeline has risk, this operation is a direct operation to port in current node, the
+ /// port on the other node cannot get the change.
+ ///
+#pragma warning disable CA1036
+ public class PipeLineNode : IComparable
+ #pragma warning restore CA1036
+ {
+
+ private static Dictionary _emptyLayer = new();
+
+ private static PipeLineNode _emptyNode = new PipeLineNode(
+ string.Empty, null!, false );
+ private IConvertableToBlueprintNode _mainOperation;
+ private string _name;
+ private protected bool _levelAvailable, _nativeRequested;
+ private protected Dictionary _inputInterfaces;
+ private protected Dictionary _outputInterfaces;
+ private protected int _level;
+
+ internal PipeLineNode(
+ string name,
+ IConvertableToBlueprintNode node,
+ bool isNative )
+ {
+ _levelAvailable = false;
+ _name = name;
+ _nativeRequested = isNative;
+ _mainOperation = node;
+ _inputInterfaces = new Dictionary();
+ _outputInterfaces = new Dictionary();
+ foreach( string portName in node.InputInterfacesName ) {
+ _inputInterfaces.Add( portName, null! );
+ }
+
+ foreach( string portName in node.OutputInterfacesName ) {
+ _outputInterfaces.Add( portName, null! );
+ }
+ }
+
+ #pragma warning disable CS8618
+ internal PipeLineNode(
+ BlueprintNodeOperation operation,
+ string name,
+ bool isNative,
+ string[] inputPorts,
+ string[] outputPorts )
+ #pragma warning restore CS8618
+ {
+ if( ( inputPorts == null ) || ( inputPorts.Length == 0 ) ) {
+ throw new ArgumentNullException( nameof( inputPorts ) );
+ }
+ if( ( outputPorts == null ) || ( outputPorts.Length == 0 ) ) {
+ throw new ArgumentNullException( nameof( outputPorts ) );
+ }
+ _levelAvailable = false;
+ _name = name;
+ _nativeRequested = isNative;
+ operation = operation ?? DefaultOperation;
+ _mainOperation = new DefaultConvertableToBlueprintNode(
+ operation, inputPorts, outputPorts );
+ _inputInterfaces = new Dictionary();
+ _outputInterfaces = new Dictionary();
+ foreach( string portName in inputPorts ) {
+ _inputInterfaces.Add(
+ portName,
+ SealedBlueprintPiipeline.SealOutput( this, name ) );
+ }
+ foreach( string portName in outputPorts ) {
+ _outputInterfaces.Add( portName, null! );
+ }
+ }
+
+ public bool IsNative
+ {
+ get => _nativeRequested;
+ internal set => _nativeRequested = value;
+ }
+
+ public static Dictionary EmptyPortLayer
+ {
+ get => _emptyLayer;
+ }
+
+ public int Level
+ {
+ get
+ {
+ if( _levelAvailable ) {
+ return _level;
+ }
+ _level = 0;
+ foreach( KeyValuePair item in _inputInterfaces ) {
+ if( item.Value == null ) {
+ continue;
+ }
+ if( _level < item.Value.Level ) {
+ _level = item.Value.Level;
+ }
+ }
+ _level += 1;
+ _levelAvailable = true;
+ return _level;
+ }
+ }
+
+ public static PipeLineNode Empty
+ {
+ get => _emptyNode;
+ }
+
+ public string Name => _name;
+
+ internal Dictionary InputInterfaces => _inputInterfaces;
+
+ internal Dictionary OutputInterfaces => _outputInterfaces;
+
+ internal IConvertableToBlueprintNode Value
+ {
+ get => _mainOperation;
+ }
+
+ public void Append(
+ [NotNull] PipeLineNode next,
+ string thisOutputPortName,
+ string afterInputPortName )
+ {
+ this._levelAvailable = false;
+ PipelineConnector pipeline = new PipelineConnector( this, next );
+ if( next is EndingNode enode ) {
+ enode.SetCertainInputPort( afterInputPortName, pipeline );
+ } else {
+ next.SetCertainInputPort( afterInputPortName, pipeline );
+ }
+ SetCertainOutputPort( thisOutputPortName, pipeline );
+ }
+
+ public int CompareTo( PipeLineNode other )
+ {
+ if( null == other ) {
+ throw new ArgumentNullException( nameof( other ) );
+ }
+
+ return this.Level.CompareTo( other.Level );
+ }
+
+ public void Prepend(
+ [NotNull] PipeLineNode former,
+ string formerOutputPortName,
+ string thisInputPortName )
+ {
+ this._levelAvailable = false;
+ PipelineConnector pipeline = new PipelineConnector( former, this );
+ if( former is BeginningNode bnode ) {
+ bnode.SetCertainOutputPort( formerOutputPortName, pipeline );
+ } else {
+ former.SetCertainOutputPort( formerOutputPortName, pipeline );
+ }
+ SetCertainInputPort( thisInputPortName, pipeline );
+ }
+
+ public virtual void Run()
+ {
+ try {
+ //Console.WriteLine(_name);
+ PipelineConnector.WaitAll( _inputInterfaces );
+ if( _mainOperation != null ) {
+ _mainOperation.Operation(
+ in _inputInterfaces, in _outputInterfaces );
+ }
+ }
+ catch( Exception ) {
+ throw;
+ }
+ }
+
+ protected static void DefaultOperation(
+ in Dictionary input,
+ in Dictionary output )
+ {
+ PipelineConnector.SkipAll( output );
+ }
+
+ #region port operation
+
+ public PipelineConnector GetInputPort( string name )
+ {
+ PipelineConnector ret;
+ if( !_inputInterfaces.TryGetValue( name, out ret ) ) {
+ throw new ArgumentOutOfRangeException(
+ $"Cannot find the interface named {name} in node {Name}." );
+ }
+ return ret;
+ }
+
+ public PipelineConnector GetOutputPort( string name )
+ {
+ PipelineConnector ret;
+ if( !_outputInterfaces.TryGetValue( name, out ret ) ) {
+ throw new ArgumentOutOfRangeException(
+ $"Cannot find the interface named {name} in node {Name}." );
+ }
+ return ret;
+ }
+
+ public void SetCertainInputPort(
+ string name,
+ PipelineConnector pipeline )
+ {
+ if( !_inputInterfaces.ContainsKey( name ) ) {
+ throw new ArgumentException(
+ $"Cannot find the interface named {name} in node {Name}." );
+ }
+ _inputInterfaces[ name ] = pipeline;
+ }
+
+ public void SetCertainOutputPort(
+ string name,
+ PipelineConnector pipeline )
+ {
+ if( !_outputInterfaces.ContainsKey( name ) ) {
+ throw new ArgumentOutOfRangeException(
+ $"Cannot find the interface named {name} in node {Name}." );
+ }
+ _outputInterfaces[ name ] = pipeline;
+ }
+
+ #endregion
+ }//--------------------------------- end of class -----------------------------------
+
+ public class BlueprintNodeRunException : Exception
+ {
+
+ protected BlueprintNodeRunException(
+ SerializationInfo info,
+ StreamingContext context )
+ : base( info, context ) { }
+
+ public BlueprintNodeRunException() { }
+
+ public BlueprintNodeRunException( Exception ex )
+ : base( string.Empty, ex ) { }
+
+ public BlueprintNodeRunException( string message ) : base( message ) { }
+
+ public BlueprintNodeRunException(
+ string message,
+ Exception innerException )
+ : base( message, innerException ) { }
+
+ }
+}
diff --git a/StgSharp.Common/PipeLine/PipeLineRunner.cs b/StgSharp.Common/PipeLine/PipeLineRunner.cs
new file mode 100644
index 00000000..1352c9d9
--- /dev/null
+++ b/StgSharp.Common/PipeLine/PipeLineRunner.cs
@@ -0,0 +1,228 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="PipeLineRunner.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using StgSharp.Threading;
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Data;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+using System.Threading.Tasks;
+
+namespace StgSharp.PipeLine
+{
+ public static class PipeLineRunner
+ {
+
+ private static NodeRunner[] allAvailableTask = CreateBlueprintRunnerArray(
+ );
+ private static CancellationTokenSource cts = new CancellationTokenSource(
+ );
+ private static ConcurrentStack blueprintInWaiting
+ = new ConcurrentStack();
+ private static int _callingThread;
+ private static SemaphoreSlim bpLock = new SemaphoreSlim( 0, 1 );
+
+ ///
+ /// Only the following occasions of calling are valid: 1. no bp is
+ /// running or the only bp is quitting. 2. calling from the main thread or a
+ /// thread the current bp is running on.
+ ///
+ internal static bool IsValidCalling
+ {
+ get
+ {
+ if( ( NodeRunner.CurrentBlueprint == null ) || //no bp running at all
+ ( ( blueprintInWaiting.IsEmpty ) && ( NodeRunner.CurrentBlueprint.IsRunning ==
+ false ) ) ) {
+ // a bp is quitting
+ //in case no bp is running
+ return true;
+ }
+ int? id = Task.CurrentId;
+ if( id is null ) {
+ // in case calling from main thread and current running bp
+ return _callingThread == Environment.CurrentManagedThreadId;
+ }
+ foreach( NodeRunner item in allAvailableTask ) {
+ if( item.Id == id ) {
+ //if calling from any bp running task
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ public static void Run( BlueprintScheduler blueprint )
+ {
+ //Console.WriteLine();
+ if( blueprint == null ) {
+ return;
+ }
+ if( blueprint.IsRunning ) {
+ throw new InvalidOperationException(
+ "Attempt to run a blueprint instance twice." );
+ }
+ if( IsValidCalling ) {
+ //Console.WriteLine("valid and run");
+ if( InterruptAndRunNewBp( blueprint ) ) {
+ while( InterruptAndRunNewBp( NodeRunner.CurrentBlueprint ) ) { }
+ ;
+ }
+ } else {
+ bpLock.Wait();
+ if( InterruptAndRunNewBp( blueprint ) ) {
+ while( InterruptAndRunNewBp( NodeRunner.CurrentBlueprint ) ) { }
+ }
+
+ bpLock.Release();
+ }
+ Interlocked.Exchange( ref _callingThread, -1 );
+ }
+
+ public static void SetMaxTaskCount( int size )
+ {
+ if( size < 1 ) {
+ size = 1;
+ }
+ if( allAvailableTask.Length >= size ) {
+ for( int i = size; i < allAvailableTask.Length; i++ ) {
+ if( allAvailableTask[ i ] != null ) {
+ allAvailableTask[ i ].Cancel();
+ }
+ }
+ }
+ Array.Resize( ref allAvailableTask, size );
+ }
+
+ public static void Terminate()
+ {
+ cts.Cancel();
+ NodeRunner.CurrentBlueprint.Terminate();
+ foreach( NodeRunner task in allAvailableTask ) {
+ task.Cts.Cancel();
+ }
+ foreach( BlueprintScheduler bp in blueprintInWaiting ) {
+ bp.Terminate();
+ }
+ blueprintInWaiting.Clear();
+ }
+
+ internal static bool InterruptAndRunNewBp( BlueprintScheduler newBp )
+ {
+ Debug.Assert( newBp != null );
+ if( ( newBp != NodeRunner.CurrentBlueprint ) && ( NodeRunner.CurrentBlueprint !=
+ null ) ) {
+ //if a running bp exists
+ blueprintInWaiting.Push( NodeRunner.CurrentBlueprint );
+ }
+
+ //load new bp to current bp
+ Interlocked.Exchange( ref NodeRunner.CurrentBlueprint!, newBp );
+ Interlocked.Exchange(
+ ref _callingThread, Environment.CurrentManagedThreadId );
+
+ //run beginning node to init it first.
+ if( !NodeRunner.CurrentBlueprint.IsRunning ) {
+ ( NodeRunner.CurrentBlueprint.BeginLayer as BeginningNode )!.Run(
+ );
+ }
+
+ //refresh all tasks
+ for( int i = 0; i < allAvailableTask.Length; i++ ) {
+ NodeRunner item = allAvailableTask[ i ];
+ if( ( item is null ) || item.IsCompleted ) {
+ allAvailableTask[ i ] = NodeRunner.Run();
+ }
+ }
+ PipeLineNode node;
+ while( !cts.Token.IsCancellationRequested && NodeRunner.CurrentBlueprint
+ .RequestNextNativeNode( out node ) ) {
+ node.Run();
+ if( !NodeRunner.CurrentBlueprint.IsRunning ) {
+ break;
+ }
+ }
+ ( NodeRunner.CurrentBlueprint.EndLayer as EndingNode )!.Run();
+ return blueprintInWaiting.TryPeek( out NodeRunner.CurrentBlueprint );
+ }
+
+ private static NodeRunner[] CreateBlueprintRunnerArray()
+ {
+ int count = Environment.ProcessorCount;
+ return new NodeRunner[ count < 2 ? count : count - 2];
+ }
+
+ }
+
+ internal class NodeRunner : CancellableTask
+ {
+
+ private static BlueprintScheduler _current;
+
+ internal NodeRunner()
+ : base()
+ {
+ _startup = InternalRun;
+ }
+
+ internal static ref BlueprintScheduler CurrentBlueprint
+ {
+ get => ref _current;
+ }
+
+ internal static NodeRunner Run()
+ {
+ NodeRunner ret = new NodeRunner { _startup = InternalRun };
+ ret._internalTask = Task.Run( ret.InternalAction );
+ return ret;
+ }
+
+ private static void InternalRun( CancellationToken token )
+ {
+ //Console.WriteLine("Task Begin");
+ PipeLineNode item;
+ while( ( CurrentBlueprint != null ) && CurrentBlueprint.IsRunning && !token.IsCancellationRequested && CurrentBlueprint.RequestNexGlobalNode(
+ out item ) ) {
+ //Console.WriteLine($"Get node of {item.Name}, going to run.");
+ item.Run();
+ }
+
+ //Console.WriteLine("Task Completed");
+ }
+
+ }//------------------------------------- End of Class ------------------------------------------
+}
diff --git a/StgSharp.Common/PipeLine/RouteSwitch.cs b/StgSharp.Common/PipeLine/RouteSwitch.cs
new file mode 100644
index 00000000..29d66368
--- /dev/null
+++ b/StgSharp.Common/PipeLine/RouteSwitch.cs
@@ -0,0 +1,112 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="RouteSwitch.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection.Emit;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+
+namespace StgSharp.PipeLine
+{
+ public class RouteSwitch : PipeLineNode
+ {
+
+ private protected Dictionary openingRule)> outputDictionary;
+
+ public RouteSwitch( string name, bool isNative, string inputPorts )
+ : base(
+ DefaultOperation, name, isNative, [inputPorts], [string.Empty] )
+ {
+ outputDictionary = new Dictionary openingRule)>(
+ );
+ }
+
+ public new int Level
+ {
+ get
+ {
+ if( _levelAvailable ) {
+ return _level;
+ }
+ _level = 0;
+ KeyValuePair item = _inputInterfaces.First(
+ );
+ if( item.Value == null ) {
+ throw new InvalidOperationException();
+ }
+ if( _level <= item.Value.Level ) {
+ _level = item.Value.Level;
+ }
+ return _level;
+ }
+ }
+
+ public new void AddBefore(
+ PipeLineNode after,
+ string thisOutputPortName,
+ string afterInputPortName )
+ {
+ this.AppendNode( after, afterInputPortName, () => true );
+ }
+
+ public void AppendNode(
+ PipeLineNode node,
+ string portName,
+ Func openningRule )
+ {
+ if( node == null ) {
+ throw new ArgumentNullException( nameof( node ) );
+ }
+ string indexName = $"{node.Name}.{portName}";
+ PipelineConnector p = new PipelineConnector( this, node );
+ node.InputInterfaces[ portName ] = p;
+ outputDictionary.Add( indexName, (p, openningRule) );
+ }
+
+ public new void Run()
+ {
+ try {
+ PipelineConnector input = InputInterfaces.First().Value;
+ input.WaitForStart();
+ foreach( KeyValuePair openingRule)> item in outputDictionary ) {
+ if( item.Value.openingRule() ) {
+ item.Value.pipeline.CompleteAndWriteData( input.Args );
+ }
+ }
+ }
+ catch( Exception ) {
+ throw;
+ }
+ }
+
+ }
+}
diff --git a/StgSharp.Common/PipeLine/SideNode.cs b/StgSharp.Common/PipeLine/SideNode.cs
new file mode 100644
index 00000000..952c8fcf
--- /dev/null
+++ b/StgSharp.Common/PipeLine/SideNode.cs
@@ -0,0 +1,125 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="SideNode.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace StgSharp.PipeLine
+{
+ internal sealed class BeginningNode : PipeLineNode
+ {
+
+ private BlueprintScheduler _bp;
+
+ public BeginningNode( BlueprintScheduler bp )
+ : base(
+ DefaultOperation, name: "BeginningNode", true, ["default"],
+ ["default"] )
+ {
+ _bp = bp;
+ }
+
+ internal (string name, PipeLineConnectorArgs arg)[] InputData
+ {
+ set
+ {
+ if( value == null ) {
+ return;
+ }
+ foreach( (string name, PipeLineConnectorArgs arg) parameter in value ) {
+ OutputInterfaces[ parameter.name ].Args = parameter.arg;
+ }
+ }
+ }
+
+ public override void Run()
+ {
+ _bp.RunningStat.Wait();
+ PipelineConnector.SkipAll( _outputInterfaces );
+ }
+
+ public new void SetCertainOutputPort(
+ string name,
+ PipelineConnector pipeline )
+ {
+ if( _outputInterfaces.ContainsKey( name ) ) {
+ _outputInterfaces[ name ] = pipeline;
+ }
+ _outputInterfaces.Add( name, pipeline );
+ }
+
+ }
+
+ internal sealed class EndingNode : PipeLineNode
+ {
+
+ private BlueprintScheduler _bp;
+
+ public EndingNode( BlueprintScheduler bp )
+ : base(
+ DefaultOperation, name: "EndingNode", true, ["default"],
+ ["default"] )
+ {
+ _bp = bp;
+ }
+
+ internal (string name, PipeLineConnectorArgs arg)[] OutputData
+ {
+ get { return InputInterfaces.Select(
+ key => (key.Key, key.Value.Args) )
+ .ToArray(); }
+ }
+
+ public override void Run()
+ {
+ PipelineConnector.WaitAll( _inputInterfaces );
+ Interlocked.Exchange( ref _bp.currentGlobalNodeIndex, 0 );
+ Interlocked.Exchange( ref _bp.currentNativeNodeIndex, 0 );
+ _bp.RunningStat.Release();
+ }
+
+ public new void SetCertainInputPort(
+ string name,
+ PipelineConnector pipeline )
+ {
+ if( _inputInterfaces.ContainsKey( name ) ) {
+ _inputInterfaces[ name ] = pipeline;
+ }
+ _inputInterfaces.Add( name, pipeline );
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/StgSharp.Common/PlainGeometryCollisionSensor.cs b/StgSharp.Common/PlainGeometryCollisionSensor.cs
new file mode 100644
index 00000000..e8f2bfba
--- /dev/null
+++ b/StgSharp.Common/PlainGeometryCollisionSensor.cs
@@ -0,0 +1,81 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="PlainGeometryCollisionSensor.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using StgSharp.Geometries;
+
+using System;
+
+namespace StgSharp
+{
+ public class CollisionEventArgs:EventArgs
+ {
+ public CollisionEventArgs(IGeometry target, IGeometry boarder)
+ {
+ Target = target;
+ Boarder = boarder;
+ }
+
+ public IGeometry Target { get; set; }
+ public IGeometry Boarder { get; set; }
+ }
+
+ public class PlainGeometryCollisionSensor
+ where TBoarder : IGeometry
+ where TTarget : IGeometry
+ {
+ internal PlainGeometry _boarder;
+ internal PlainGeometry _target;
+ internal EventHandler _rule;
+
+ public event EventHandler Rule
+ {
+ add { _rule += value; }
+ remove
+ {
+ if (value == null)
+ {
+ return;
+ }
+#pragma warning disable CS8601
+ _rule -= value;
+#pragma warning restore CS8601
+ }
+ }
+
+ public PlainGeometry boarder => _boarder;
+
+ public PlainGeometry target
+ {
+ get => _target;
+ set => _target = value;
+ }
+
+ }
+}
diff --git a/StgSharp.Common/StateMachine.cs b/StgSharp.Common/StateMachine.cs
new file mode 100644
index 00000000..a3599e21
--- /dev/null
+++ b/StgSharp.Common/StateMachine.cs
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="StateMachine.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace StgSharp
+{
+ public interface IStateMachine where T: Enum
+ {
+
+ public T LastStableState
+ {
+ get;
+ }
+
+ public bool TryEnterState();
+
+ public bool TryExitState();
+
+ public bool TrySwitchState();
+
+ }
+
+ public interface IStateMachineWithSwitchSpan : IStateMachine
+ where TState: Enum
+ {
+
+ public bool IsInStabelState
+ {
+ get;
+ }
+
+ public TState NextStableState
+ {
+ get;
+ }
+
+ public bool TrySwitchState();
+
+ }
+}
diff --git a/StgSharp.Common/StgSharp.Common.csproj b/StgSharp.Common/StgSharp.Common.csproj
index 34092131..1a35b2b2 100644
--- a/StgSharp.Common/StgSharp.Common.csproj
+++ b/StgSharp.Common/StgSharp.Common.csproj
@@ -83,6 +83,10 @@
+
+
+
+
diff --git a/StgSharp.Common/Threading/MainThreadAssert.cs b/StgSharp.Common/Threading/MainThreadAssert.cs
index f7dd494d..e9327a40 100644
--- a/StgSharp.Common/Threading/MainThreadAssert.cs
+++ b/StgSharp.Common/Threading/MainThreadAssert.cs
@@ -50,8 +50,7 @@ namespace StgSharp.Threading
{
if( isNotMainThread.Value ) {
throw new InvalidOperationException(
- $"Attempt to call sensitive operation which can be only called from main thread "
- + $"from thread {Environment.CurrentManagedThreadId}." );
+ $"Attempt to call sensitive operation which can be only called from main thread " + $"from thread {Environment.CurrentManagedThreadId}." );
}
}
diff --git a/StgSharp.Common/Timing/TimeFunction.cs b/StgSharp.Common/Timing/TimeFunction.cs
new file mode 100644
index 00000000..388f07c3
--- /dev/null
+++ b/StgSharp.Common/Timing/TimeFunction.cs
@@ -0,0 +1,164 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="TimeFunction.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace StgSharp.Timing
+{
+ public class TimeFunction
+ {
+
+ private float _beginning, _ending;
+ private Func _timeRelatedCalculation;
+ private TimeSpanProvider _timeProvider;
+
+ internal TimeFunction() { }
+
+ public TimeFunction(
+ TimeSpanProvider timeSpanProvider,
+ Func timeRelatedCalculation,
+ float range )
+ {
+ _timeProvider = timeSpanProvider;
+ _timeRelatedCalculation = timeRelatedCalculation;
+ if( timeSpanProvider == null ) {
+ return;
+ }
+ _beginning = _timeProvider.CurrentSecond;
+ _ending = _timeProvider.CurrentSecond + range;
+ }
+
+ public virtual bool IsComplete
+ {
+ get => _timeProvider.CurrentSecond > _ending;
+ }
+
+ public Func TimeRelatedCalculation
+ {
+ get { return _timeRelatedCalculation; }
+ set { _timeRelatedCalculation = value; }
+ }
+
+ public static TimeFunction One
+ {
+ get => new TimeFunctionOne();
+ }
+
+ public TimeSpanProvider TimeSpanProvider
+ {
+ get { return _timeProvider; }
+ set { _timeProvider = value; }
+ }
+
+ public virtual float Calculate()
+ {
+ if( _timeProvider.CurrentSecond < _ending ) {
+ return 0;
+ }
+ return _timeRelatedCalculation(
+ _timeProvider.CurrentSecond - _beginning );
+ }
+
+ public static TimeFunction Proportional(
+ TimeSpanProvider time,
+ float begin,
+ float range )
+ {
+ return new TimeFunction( time, ( float t ) => t + begin, range );
+ }
+
+ public virtual TimeFunction Renew(
+ (Func func, float range) funcPair )
+ {
+ return new TimeFunction(
+ _timeProvider, funcPair.func, funcPair.range );
+ }
+
+ public virtual TimeFunction Renew(
+ Func func,
+ float range )
+ {
+ return new TimeFunction( _timeProvider, func, range );
+ }
+
+ public void Reset()
+ {
+ float range = _ending - _beginning;
+ _beginning = _timeProvider.CurrentSecond;
+ _ending = _beginning + range;
+ }
+
+ public virtual TimeFunction Reverse()
+ {
+ float range = _ending - _beginning;
+ return new TimeFunction(
+ _timeProvider, p => _timeRelatedCalculation( range - p ),
+ range );
+ }
+
+ }
+
+ public sealed class TimeFunctionOne : TimeFunction
+ {
+
+ internal TimeFunctionOne() : base() { }
+
+ public override bool IsComplete
+ {
+ get => true;
+ }
+
+ public override float Calculate()
+ {
+ return 1;
+ }
+
+ public override TimeFunction Renew(
+ (Func func, float range) funcPair )
+ {
+ throw new NotSupportedException();
+ }
+
+ public override TimeFunction Renew(
+ Func func,
+ float range )
+ {
+ throw new NotSupportedException();
+ }
+
+ #pragma warning disable CA1822
+ public new void Reset()
+ #pragma warning restore CA1822
+ { }
+
+ }
+}
diff --git a/StgSharp.Common/Timing/TimeProvider.cs b/StgSharp.Common/Timing/TimeProvider.cs
new file mode 100644
index 00000000..f045b73c
--- /dev/null
+++ b/StgSharp.Common/Timing/TimeProvider.cs
@@ -0,0 +1,152 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="TimeProvider.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+
+using StgSharp.Timing;
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+namespace StgSharp
+{
+ public static partial class StgSharp
+ {
+
+ internal static StgSharpTime mainTimeProvider = new StgSharpTime();
+
+ internal static TimeSourceProviderBase MainTimeProvider => mainTimeProvider;
+
+ }
+
+ public sealed class StgSharpTime : TimeSourceProviderBase
+ {
+
+ private static List subscriberList = new List(
+ );
+ private static long accuracy;
+ private static Stopwatch mainProvider = new Stopwatch();
+ private static Thread timeProvideThread;
+
+ internal StgSharpTime() { }
+
+ public static TimeSourceProviderBase OnlyInstance => StgSharp.MainTimeProvider;
+
+ public override sealed void StartProvidingTime()
+ {
+ if( mainProvider.IsRunning ) {
+ return;
+ }
+ mainProvider.Start();
+
+ //speed test
+ long totalMS, internalFrequncy = Stopwatch.Frequency;
+ for( int i = 0; i < 100; i++ ) {
+ totalMS = mainProvider.ElapsedTicks / ( internalFrequncy / ( 1000L * 1000L ) );
+ for( int t = 0; t < 10; t++ ) {
+ if( totalMS < 1000 ) {
+ subscriberList.Add(
+ new TimeSpanProvider(
+ 100L, TimeSpanProvider.DefaultProvider ) );
+ }
+ }
+ }
+ mainProvider.Stop();
+ subscriberList.Clear();
+ totalMS = mainProvider.ElapsedTicks / ( internalFrequncy / ( 1000L * 1000L ) ) / 100L;
+ accuracy = ( totalMS * 2 ) / 3;
+ mainProvider.Reset();
+ timeProvideThread = new Thread( new ThreadStart( ProvideTime ) );
+ timeProvideThread.Start();
+ }
+
+ public override void StopProvidingTime()
+ {
+ lock( mainProvider ) {
+ mainProvider.Stop();
+ }
+ }
+
+ public void Terminate()
+ {
+ lock( mainProvider ) {
+ mainProvider.Stop();
+ }
+ }
+
+ protected override sealed void AddSubscriberUnsynced(
+ TimeSpanProvider subscriber )
+ {
+ subscriberList.Add( subscriber );
+ }
+
+ protected override sealed void RemoveSubscriberUnsynced(
+ TimeSpanProvider subscriber )
+ {
+ subscriberList.Remove( subscriber );
+ }
+
+ private void ProvideTime()
+ {
+ long totalMS, internalFrequncy = Stopwatch.Frequency;
+ lock( mainProvider ) {
+ mainProvider.Restart();
+ }
+ while( mainProvider.IsRunning ) {
+ totalMS = mainProvider.ElapsedTicks / ( internalFrequncy / ( 1000L * 1000L ) );
+ if( subscriberList.Count == 0 ) {
+ continue;
+ }
+ CheckSubscriberSemaphore.Wait();
+ List toRemoveList = new List(
+ );
+ foreach( TimeSpanProvider subscriber in subscriberList ) {
+ if( !subscriber.CheckTime( totalMS ) ) {
+ toRemoveList.Add( subscriber );
+ InternalIO.InternalWriteLog(
+ $"Time subscriber {subscriber} is to be removed.",
+ LogType.Info );
+ }
+ ;
+ }
+ if( toRemoveList.Count != 0 ) {
+ foreach( TimeSpanProvider subscriber in toRemoveList ) {
+ subscriberList.Remove( subscriber );
+ }
+ }
+ CheckSubscriberSemaphore.Release();
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/StgSharp.Common/Timing/TimeSourceProvider.cs b/StgSharp.Common/Timing/TimeSourceProvider.cs
new file mode 100644
index 00000000..ea1fdacc
--- /dev/null
+++ b/StgSharp.Common/Timing/TimeSourceProvider.cs
@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="TimeSourceProvider.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using StgSharp;
+
+using System;
+using System.Linq;
+using System.Threading;
+
+namespace StgSharp.Timing
+{
+ public abstract class TimeSourceProviderBase
+ {
+
+ private SemaphoreSlim _addSubscriberSemaphore = new SemaphoreSlim(
+ 1, 1 );
+
+ protected SemaphoreSlim CheckSubscriberSemaphore
+ {
+ get => _addSubscriberSemaphore;
+ }
+
+ public void AddSubscriber( TimeSpanProvider subscriber )
+ {
+ try {
+ _addSubscriberSemaphore.Wait();
+ AddSubscriberUnsynced( subscriber );
+ }
+ catch( Exception ) {
+ throw;
+ }
+ finally {
+ _addSubscriberSemaphore.Release();
+ }
+ }
+
+ public void RemoveSubscriber( TimeSpanProvider subscriber )
+ {
+ _addSubscriberSemaphore.Wait();
+ try {
+ RemoveSubscriberUnsynced( subscriber );
+ }
+ catch( Exception ) {
+ throw;
+ }
+ finally {
+ _addSubscriberSemaphore.Release();
+ }
+ }
+
+ public abstract void StartProvidingTime();
+
+ public abstract void StopProvidingTime();
+
+ protected abstract void AddSubscriberUnsynced(
+ TimeSpanProvider subscriber );
+
+ protected abstract void RemoveSubscriberUnsynced(
+ TimeSpanProvider subscriber );
+
+ }
+}
diff --git a/StgSharp.Common/Timing/TimeSpanAwaitingToken.cs b/StgSharp.Common/Timing/TimeSpanAwaitingToken.cs
new file mode 100644
index 00000000..7621d81c
--- /dev/null
+++ b/StgSharp.Common/Timing/TimeSpanAwaitingToken.cs
@@ -0,0 +1,165 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="TimeSpanAwaitingToken.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace StgSharp.Timing
+{
+ #nullable enable
+
+ public sealed class TimeSpanAwaitingToken : IDisposable
+ {
+
+ private static readonly ConcurrentStack s_unusedID = new ConcurrentStack(
+ [0] );
+ private static int s_maxID;
+ private static readonly object s_lock = new object();
+
+ private EventHandler? _refreshHandler,_missHandler;
+ private int _size, _id;
+
+ private object _participantObject = new object();
+ private SemaphoreSlim _awaitingSemaphore;
+
+ private TimeSpanProvider _provider;
+
+ internal TimeSpanAwaitingToken( TimeSpanProvider provider )
+ {
+ if( s_unusedID.Count == 1 ) {
+ lock( s_lock ) {
+ s_unusedID.TryPop( out int id );
+ TokenID = id;
+ s_unusedID.Push( s_maxID++ );
+ }
+ } else {
+ s_unusedID.TryPop( out int id );
+ TokenID = id;
+ }
+ _provider = provider;
+ _size = 1;
+ _awaitingSemaphore = new SemaphoreSlim( 0, 1 );
+ }
+
+ internal TimeSpanAwaitingToken( TimeSpanProvider provider, int count )
+ {
+ if( s_unusedID.Count == 1 ) {
+ lock( s_lock ) {
+ s_unusedID.TryPop( out int id );
+ TokenID = id;
+ s_unusedID.Push( s_maxID++ );
+ }
+ } else {
+ s_unusedID.TryPop( out int id );
+ TokenID = id;
+ }
+ _provider = provider;
+ _size = count;
+ _awaitingSemaphore = new SemaphoreSlim( 0, _size );
+ }
+
+ public event EventHandler MissTimeSpanRefreshed
+ {
+ add { _missHandler += value; }
+ remove { _missHandler -= value; }
+ }
+
+ public event EventHandler TimeSpanRefreshed
+ {
+ add { _refreshHandler += value; }
+ remove { _refreshHandler -= value; }
+ }
+
+ public int TokenID
+ {
+ get => _id;
+ private set => _id = value;
+ }
+
+ internal SemaphoreSlim AwaitingSemaphoreSlim
+ {
+ get => _awaitingSemaphore;
+ }
+
+ public void Dispose()
+ {
+ _provider.QuitSpanAwaiting( this );
+ s_unusedID.Push( TokenID );
+ _awaitingSemaphore.Dispose();
+ GC.SuppressFinalize( this );
+ }
+
+ public override int GetHashCode()
+ {
+ return _id;
+ }
+
+ public void Participant()
+ {
+ lock( _participantObject ) {
+ _size++;
+ SemaphoreSlim newSemaphore = new SemaphoreSlim(
+ _awaitingSemaphore.CurrentCount, _size );
+ Interlocked.Exchange( ref _awaitingSemaphore, newSemaphore )
+ .Dispose();
+ }
+ }
+
+ public void WaitNextSpan()
+ {
+ _awaitingSemaphore.Wait();
+ }
+
+ internal void MissRefresh()
+ {
+ _missHandler?.Invoke( this, EventArgs.Empty );
+ }
+
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ internal void Refresh()
+ {
+ _refreshHandler?.Invoke( this, EventArgs.Empty );
+ }
+
+ ~TimeSpanAwaitingToken()
+ {
+ Dispose();
+ }
+
+ }
+ #nullable restore
+}
diff --git a/StgSharp.Common/Timing/TimeSpanProvider.cs b/StgSharp.Common/Timing/TimeSpanProvider.cs
new file mode 100644
index 00000000..a29eb27d
--- /dev/null
+++ b/StgSharp.Common/Timing/TimeSpanProvider.cs
@@ -0,0 +1,233 @@
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="TimeSpanProvider.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace StgSharp.Timing
+{
+ ///
+ /// A microsecond-accuracy timer. It will refresh every a certain time span.
+ ///
+ public class TimeSpanProvider
+ {
+
+ private bool _subscribed;
+
+ private ConcurrentQueue _tokenToAdd = new ConcurrentQueue(
+ );
+ private ConcurrentQueue _tokenToQuit;
+ private Counter timeSpanCount = new Counter( -1, 1, 1 );
+ private HashSet _awaitingTokens;
+ private long _maxSpanCount;
+ private long _spanBegin;
+ private readonly long _spanLength;
+ private readonly TimeSourceProviderBase _timeSource;
+
+ ///
+ /// Create a new and define the length of time span. Length
+ /// of a single time span is defined in microseconds.
+ ///
+ ///
+ ///
+ public TimeSpanProvider(
+ long spanMicroSeconds,
+ TimeSourceProviderBase provider )
+ {
+ if( provider == null ) {
+ throw new ArgumentNullException( nameof( provider ) );
+ }
+ _timeSource = provider;
+ _spanLength = spanMicroSeconds;
+ _maxSpanCount = int.MaxValue;
+ provider.AddSubscriber( this );
+ _subscribed = true;
+ _awaitingTokens = new HashSet();
+ _tokenToQuit = new ConcurrentQueue();
+ }
+
+ ///
+ /// Create a new and define the length of time span. Length
+ /// of a single time span is defined in seconds.
+ ///
+ ///
+ ///
+ public TimeSpanProvider(
+ double spanSeconds,
+ TimeSourceProviderBase provider )
+ {
+ if( provider == null ) {
+ throw new ArgumentNullException( nameof( provider ) );
+ }
+ _timeSource = provider;
+ _spanLength = ( long )( spanSeconds * 1000L * 1000L );
+ _spanBegin = -_spanLength;
+ _maxSpanCount = long.MaxValue;
+ provider.AddSubscriber( this );
+ _subscribed = true;
+ _awaitingTokens = new HashSet();
+ _tokenToQuit = new ConcurrentQueue();
+ }
+
+ ///
+ /// Create a new and define the length of time span. Length
+ /// of a single time span is defined in microseconds.
+ ///
+ ///
+ ///
+ ///
+ public TimeSpanProvider(
+ long spanLength,
+ long maxSpan,
+ TimeSourceProviderBase provider )
+ {
+ if( provider == null ) {
+ throw new ArgumentNullException( nameof( provider ) );
+ }
+ if( maxSpan <= 0 ) {
+ throw new ArgumentException(
+ "Sapn count cannot be smaller than zero" );
+ }
+ _timeSource = provider;
+ _spanLength = spanLength;
+ _spanBegin = -_spanLength;
+ provider.AddSubscriber( this );
+ _subscribed = true;
+ _awaitingTokens = new HashSet();
+ _tokenToQuit = new ConcurrentQueue();
+ }
+
+ public double SpanLength
+ {
+ get => ( _spanLength * 1.0 ) / ( 1000L * 1000L );
+ }
+
+ public float CurrentSecond
+ {
+ get => timeSpanCount.Value * SpanLengthLowPrecession;
+ }
+
+ public float SpanLengthLowPrecession
+ {
+ get => ( _spanLength * 1.0f ) / ( 1000 * 1000 );
+ }
+
+ public int CurrentSpan
+ {
+ get => timeSpanCount.Value;
+ }
+
+ ///
+ /// Time source provider provided in internal framework.
+ ///
+ public static TimeSourceProviderBase DefaultProvider => StgSharpTime.OnlyInstance;
+
+ public TimeSpanAwaitingToken ParticipantSpanAwaiting( int count )
+ {
+ TimeSpanAwaitingToken token = new TimeSpanAwaitingToken(
+ this, count );
+ _tokenToAdd.Enqueue( token );
+ return token;
+ }
+
+ public void QuitSpanAwaiting( TimeSpanAwaitingToken token )
+ {
+ _tokenToQuit.Enqueue( token );
+ }
+
+ public void StopSpanProviding()
+ {
+ Interlocked.Exchange( ref _maxSpanCount, 0 );
+ }
+
+ public void SubscribeToTimeSource(
+ TimeSourceProviderBase serviceHandler )
+ {
+ if( serviceHandler == null ) {
+ throw new ArgumentNullException( nameof( serviceHandler ) );
+ }
+ if( _subscribed ) {
+ return;
+ }
+ _subscribed = true;
+ serviceHandler.AddSubscriber( this );
+ }
+
+ public int ToInt32()
+ {
+ return timeSpanCount.Value;
+ }
+
+ internal bool CheckTime( long microseconds )
+ {
+ if( microseconds - _spanBegin < _spanLength ) {
+ return true;
+ }
+ while( !_tokenToAdd.IsEmpty ) {
+ _tokenToAdd.TryDequeue( out TimeSpanAwaitingToken tokenAdd );
+ _awaitingTokens.Add( tokenAdd );
+ }
+ while( !_tokenToQuit.IsEmpty ) {
+ _tokenToQuit.TryDequeue( out TimeSpanAwaitingToken tokenQuit );
+ _awaitingTokens.Remove( tokenQuit );
+ InternalIO.InternalWriteLog(
+ $"Awaiting token {tokenQuit!.TokenID} has been removed.",
+ LogType.Info );
+ }
+
+ _spanBegin = microseconds;
+ timeSpanCount++;
+
+ foreach( TimeSpanAwaitingToken item in _awaitingTokens ) {
+ if( item.AwaitingSemaphoreSlim.CurrentCount == 0 ) {
+ item.AwaitingSemaphoreSlim.Release();
+ item.Refresh();
+ } else {
+ item.MissRefresh();
+ }
+ }
+
+ return timeSpanCount < _maxSpanCount;
+ }
+
+ public static explicit operator int(
+ [NotNull]TimeSpanProvider provider )
+ {
+ return provider.ToInt32();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/StgSharp.Common/obj/x64/Debug/net8.0/StgSharp.Common.AssemblyInfo.cs b/StgSharp.Common/obj/x64/Debug/net8.0/StgSharp.Common.AssemblyInfo.cs
index c8978676..f32dc0e0 100644
--- a/StgSharp.Common/obj/x64/Debug/net8.0/StgSharp.Common.AssemblyInfo.cs
+++ b/StgSharp.Common/obj/x64/Debug/net8.0/StgSharp.Common.AssemblyInfo.cs
@@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("StgSharp.Common")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
-[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6222f8c8be57d511d2ec40523717e20b87fcff9d")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+753cc167bc352df7a47cd17a1ea877666683f5f0")]
[assembly: System.Reflection.AssemblyProductAttribute("StgSharp.Common")]
[assembly: System.Reflection.AssemblyTitleAttribute("StgSharp.Common")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
diff --git a/StgSharp.Generator/Blueprint/BlueprintNodeAttribute.cs b/StgSharp.Generator/Blueprint/BlueprintNodeAttribute.cs
index eb5ddc8b..ee3e0ba8 100644
--- a/StgSharp.Generator/Blueprint/BlueprintNodeAttribute.cs
+++ b/StgSharp.Generator/Blueprint/BlueprintNodeAttribute.cs
@@ -32,7 +32,7 @@ using System;
using System.Collections.Generic;
using System.Text;
-namespace StgSharp.Blueprint
+namespace StgSharp.PipeLine
{
[AttributeUsage( AttributeTargets.Method, AllowMultiple = false )]
public class BlueprintNodeExecutionAttribute : Attribute { }
diff --git a/StgSharp.Generator/SourceGenerator/BpNodeGenerator.cs b/StgSharp.Generator/SourceGenerator/BpNodeGenerator.cs
index e70739e9..990bf9f6 100644
--- a/StgSharp.Generator/SourceGenerator/BpNodeGenerator.cs
+++ b/StgSharp.Generator/SourceGenerator/BpNodeGenerator.cs
@@ -33,7 +33,7 @@ using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
-using StgSharp.Blueprint;
+using StgSharp.PipeLine;
using System;
using System.Collections.Generic;
@@ -44,76 +44,83 @@ namespace StgSharp.Generator
{
internal class BpNodeSyntaxReceiver : ISyntaxReceiver
{
+
+ private static BpNodeSyntaxReceiver receiver = new BpNodeSyntaxReceiver(
+ );
private static readonly string _indexTypeName = typeof( PartialDictionary ).Name;
- private static BpNodeSyntaxReceiver receiver = new BpNodeSyntaxReceiver();
- public List ValidMethod { get; private set; } = new List();
- public List InvalidMethod { get; private set; } = new List();
+ public BpNodeSyntaxReceiver() { }
- public BpNodeSyntaxReceiver()
+ public BpNodeSyntaxReceiver( SyntaxNode node )
{
-
+ OnVisitSyntaxNode( node );
}
- public BpNodeSyntaxReceiver(SyntaxNode node)
+ public List ValidMethod
{
- OnVisitSyntaxNode(node);
- }
+ get;
+ private set;
+ } = new List();
- public void OnVisitSyntaxNode( SyntaxNode syntaxNode )
+ public List InvalidMethod
{
- if( syntaxNode is MethodDeclarationSyntax mds && mds.AttributeLists
+ get;
+ private set;
+ } = new List();
+
+ public static void BuildNode(
+ SourceProductionContext context,
+ MethodDeclarationSyntax mds )
+ {
+ if( mds.AttributeLists
.SelectMany( list => list.Attributes )
- .Any( syntax => syntax.Name.ToString() ==
+ .Any(
+ syntax => syntax.Name.ToString() ==
typeof( BlueprintNodeExecutionAttribute ).Name ) ) {
SeparatedSyntaxList paramList = mds.ParameterList.Parameters;
if( mds.Modifiers.Any( SyntaxKind.StaticKeyword ) && paramList.Count ==
2 && paramList[ 0 ].Type!.ToString() == _indexTypeName && paramList[
1 ].Type!.ToString() ==
_indexTypeName ) {
- ValidMethod.Add(mds);
- }
- else
- {
- InvalidMethod.Add(mds);
- }
- }
- }
-
- public static void BuildNode(SourceProductionContext context, MethodDeclarationSyntax mds)
- {
- if (mds.AttributeLists
- .SelectMany(list => list.Attributes)
- .Any(syntax => syntax.Name.ToString() ==
- typeof(BlueprintNodeExecutionAttribute).Name))
- {
- SeparatedSyntaxList paramList = mds.ParameterList.Parameters;
- if (mds.Modifiers.Any(SyntaxKind.StaticKeyword) && paramList.Count ==
- 2 && paramList[0].Type!.ToString() == _indexTypeName && paramList[
- 1].Type!.ToString() ==
- _indexTypeName)
- {
- var methodName = mds.Identifier.Text;
- var sourceText = SourceText.From( """
-
- """,encoding:Encoding.UTF8);
- context.AddSource("GeneratedBlueprintNode.cs", sourceText);
- }
- else
- {
- var diagnostic = Diagnostic.Create(
+ string methodName = mds.Identifier.Text;
+ SourceText sourceText = SourceText.From(
+ string.Empty, encoding: Encoding.UTF8 );
+ context.AddSource( "GeneratedBlueprintNode.cs",
+ sourceText );
+ } else {
+ Diagnostic diagnostic = Diagnostic.Create(
new DiagnosticDescriptor(
- id:"SSE0001",
+ id: "SSE0001",
title: "Invalid Blueprint Node Method",
messageFormat: "Blueprint Node Method must be static and have two parameters of type PartialDictionary",
category: "Blueprint Node",
DiagnosticSeverity.Error,
- isEnabledByDefault: true),
- mds.GetLocation(),mds.Identifier.Text);
-
- context.ReportDiagnostic(diagnostic);
+ isEnabledByDefault: true ),
+ mds.GetLocation(), mds.Identifier.Text );
+
+ context.ReportDiagnostic( diagnostic );
}
}
}
+
+ public void OnVisitSyntaxNode( SyntaxNode syntaxNode )
+ {
+ if( syntaxNode is MethodDeclarationSyntax mds && mds.AttributeLists
+ .SelectMany( list => list.Attributes )
+ .Any(
+ syntax => syntax.Name.ToString() ==
+ typeof( BlueprintNodeExecutionAttribute ).Name ) ) {
+ SeparatedSyntaxList paramList = mds.ParameterList.Parameters;
+ if( mds.Modifiers.Any( SyntaxKind.StaticKeyword ) && paramList.Count ==
+ 2 && paramList[ 0 ].Type!.ToString() == _indexTypeName && paramList[
+ 1 ].Type!.ToString() ==
+ _indexTypeName ) {
+ ValidMethod.Add( mds );
+ } else {
+ InvalidMethod.Add( mds );
+ }
+ }
+ }
+
}
}
diff --git a/StgSharp.Model/STEP/FileStructure/IStepObject.cs b/StgSharp.Model/STEP/FileStructure/IStepObject.cs
index bdf1a443..a3bde67d 100644
--- a/StgSharp.Model/STEP/FileStructure/IStepObject.cs
+++ b/StgSharp.Model/STEP/FileStructure/IStepObject.cs
@@ -1,6 +1,36 @@
-using StgSharp.Blueprint;
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// file="IStepObject.cs"
+// Project: StgSharp
+// AuthorGroup: Nitload Space
+// Copyright (c) Nitload Space. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+//
+// The above copyright notice and
+// this permission notice shall be included in all copies
+// or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”,
+// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
using StgSharp.Geometries;
using StgSharp.Math;
+using StgSharp.PipeLine;
using System;
using System.Collections.Generic;
@@ -8,14 +38,34 @@ using System.Text;
namespace StgSharp.Modeling.STEP
{
- public abstract class IStepObject: StepExpressionBase , IGeometry
+ public abstract class IStepObject : StepExpressionBase, IGeometry
{
- public abstract Point this[int index] { get; set; }
- public abstract Vec4[] VertexStream { get; }
- public abstract CoordinationBase Coordination { get; }
- public abstract int VertexCount { get; }
- public abstract ReadOnlySpan VertexIndices { get; }
+ public abstract Point this[ int index ]
+ {
+ get;
+ set;
+ }
+
+ public abstract Vec4[] VertexStream
+ {
+ get;
+ }
+
+ public abstract CoordinationBase Coordination
+ {
+ get;
+ }
+
+ public abstract int VertexCount
+ {
+ get;
+ }
+
+ public abstract ReadOnlySpan VertexIndices
+ {
+ get;
+ }
}
}
diff --git a/StgSharp.Model/STEP/FileStructure/StepModel.cs b/StgSharp.Model/STEP/FileStructure/StepModel.cs
index 4cf42896..6476fe64 100644
--- a/StgSharp.Model/STEP/FileStructure/StepModel.cs
+++ b/StgSharp.Model/STEP/FileStructure/StepModel.cs
@@ -28,7 +28,7 @@
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
-using StgSharp.Blueprint;
+using StgSharp.PipeLine;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;