From f56d6a7fc8dc7aae290fd28ae995c9e40016373b Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 9 Jun 2025 20:27:29 +0300 Subject: [PATCH 01/91] chore: standalone physics engine not having pooled lists fixed --- Engine.Physics2D/PhysicsEngine2DStandalone.cs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Engine.Physics2D/PhysicsEngine2DStandalone.cs b/Engine.Physics2D/PhysicsEngine2DStandalone.cs index dc16d4c..5998f04 100644 --- a/Engine.Physics2D/PhysicsEngine2DStandalone.cs +++ b/Engine.Physics2D/PhysicsEngine2DStandalone.cs @@ -21,6 +21,12 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D private readonly ICollisionResolver2D collisionResolver = null!; private readonly IRaycastResolver2D raycastResolver = null!; + private readonly ListPool colliderPool = new(() => new(32)); + private readonly ListPool prePhysicsUpdatePool = new(() => new(32)); + private readonly ListPool physicsUpdatePool = new(() => new(32)); + private readonly ListPool physicsIterationPool = new(() => new(32)); + private readonly ListPool postPhysicsUpdatePool = new(() => new(32)); + public int IterationPerStep { get => _iterationCount; set => _iterationCount = value < 1 ? 1 : value; } public void AddRigidBody(IRigidBody2D rigidBody) @@ -112,11 +118,11 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D { float intervalDeltaTime = deltaTime / IterationPerStep; - List childColliders = []; - List physicsPreUpdates = []; - List physicsUpdates = []; - List physicsIterations = []; - List physicsPostUpdates = []; + List childColliders = colliderPool.Get(); + List physicsPreUpdates = prePhysicsUpdatePool.Get(); + List physicsUpdates = physicsUpdatePool.Get(); + List physicsIterations = physicsIterationPool.Get(); + List physicsPostUpdates = postPhysicsUpdatePool.Get(); rigidBody.BehaviourController.GetBehavioursInChildren(childColliders); rigidBody.BehaviourController.GetBehavioursInChildren(physicsPreUpdates); @@ -160,6 +166,12 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D for (int i = physicsPostUpdates.Count - 1; i >= 0; i--) physicsPostUpdates[i].PostPhysicsUpdate(deltaTime); + + colliderPool.Return(childColliders); + prePhysicsUpdatePool.Return(physicsPreUpdates); + physicsUpdatePool.Return(physicsUpdates); + physicsIterationPool.Return(physicsIterations); + postPhysicsUpdatePool.Return(physicsPostUpdates); } private void ResolveColliders(ICollider2D colliderX, ICollider2D colliderY) -- 2.49.1 From 30ccab1b93180fd20b14a85c2cfc34c65820fa03 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 9 Jun 2025 20:36:39 +0300 Subject: [PATCH 02/91] refactor: list pool initial count and capacity parameters added --- Engine.Core/Helpers/ListPool.cs | 6 +++--- Engine.Physics2D/PhysicsEngine2D.cs | 10 +++++----- Engine.Physics2D/PhysicsEngine2DStandalone.cs | 10 +++++----- Engine.Physics2D/RaycastResolver2D.cs | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Engine.Core/Helpers/ListPool.cs b/Engine.Core/Helpers/ListPool.cs index 19884e6..2377e79 100644 --- a/Engine.Core/Helpers/ListPool.cs +++ b/Engine.Core/Helpers/ListPool.cs @@ -31,10 +31,10 @@ public class ListPool : IPool> OnReturned?.Invoke(this, list); } - public ListPool(Func> generator, int initialCapacity = 1) + public ListPool(int initialListCount = 1, int initialListCapacity = 32) { - this.generator = generator; - for (int i = 0; i < initialCapacity; i++) + generator = () => new(initialListCapacity); + for (int i = 0; i < initialListCount; i++) queue.Enqueue(generator()); } } diff --git a/Engine.Physics2D/PhysicsEngine2D.cs b/Engine.Physics2D/PhysicsEngine2D.cs index 4e84b5b..10de29b 100644 --- a/Engine.Physics2D/PhysicsEngine2D.cs +++ b/Engine.Physics2D/PhysicsEngine2D.cs @@ -25,11 +25,11 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D protected BehaviourCollector rigidBodyCollector = new(); protected BehaviourCollector colliderCollector = new(); - private readonly ListPool colliderPool = new(() => new(32)); - private readonly ListPool prePhysicsUpdatePool = new(() => new(32)); - private readonly ListPool physicsUpdatePool = new(() => new(32)); - private readonly ListPool physicsIterationPool = new(() => new(32)); - private readonly ListPool postPhysicsUpdatePool = new(() => new(32)); + private readonly ListPool colliderPool = new(); + private readonly ListPool prePhysicsUpdatePool = new(); + private readonly ListPool physicsUpdatePool = new(); + private readonly ListPool physicsIterationPool = new(); + private readonly ListPool postPhysicsUpdatePool = new(); public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; } public float IterationPeriod { get => _iterationPeriod; set => _iterationPeriod = value.Max(0.0001f); } diff --git a/Engine.Physics2D/PhysicsEngine2DStandalone.cs b/Engine.Physics2D/PhysicsEngine2DStandalone.cs index 5998f04..5de9885 100644 --- a/Engine.Physics2D/PhysicsEngine2DStandalone.cs +++ b/Engine.Physics2D/PhysicsEngine2DStandalone.cs @@ -21,11 +21,11 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D private readonly ICollisionResolver2D collisionResolver = null!; private readonly IRaycastResolver2D raycastResolver = null!; - private readonly ListPool colliderPool = new(() => new(32)); - private readonly ListPool prePhysicsUpdatePool = new(() => new(32)); - private readonly ListPool physicsUpdatePool = new(() => new(32)); - private readonly ListPool physicsIterationPool = new(() => new(32)); - private readonly ListPool postPhysicsUpdatePool = new(() => new(32)); + private readonly ListPool colliderPool = new(); + private readonly ListPool prePhysicsUpdatePool = new(); + private readonly ListPool physicsUpdatePool = new(); + private readonly ListPool physicsIterationPool = new(); + private readonly ListPool postPhysicsUpdatePool = new(); public int IterationPerStep { get => _iterationCount; set => _iterationCount = value < 1 ? 1 : value; } diff --git a/Engine.Physics2D/RaycastResolver2D.cs b/Engine.Physics2D/RaycastResolver2D.cs index 881e4ad..726a2e5 100644 --- a/Engine.Physics2D/RaycastResolver2D.cs +++ b/Engine.Physics2D/RaycastResolver2D.cs @@ -6,7 +6,7 @@ namespace Syntriax.Engine.Physics2D; public class RaycastResolver2D : IRaycastResolver2D { - private readonly ListPool lineCacheQueue = new(() => new(4)); + private readonly ListPool lineCacheQueue = new(initialListCapacity: 4); RaycastResult? IRaycastResolver2D.RaycastAgainst(T shape, Ray2D ray, float length) { -- 2.49.1 From 2335c3ec628a3dc55fc5ba96cd6c1eea2ba1a3f9 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 13 Jun 2025 22:17:39 +0300 Subject: [PATCH 03/91] docs: added ray 2d comments --- Engine.Core/Primitives/Ray2D.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Engine.Core/Primitives/Ray2D.cs b/Engine.Core/Primitives/Ray2D.cs index a369d39..3e16bed 100644 --- a/Engine.Core/Primitives/Ray2D.cs +++ b/Engine.Core/Primitives/Ray2D.cs @@ -1,5 +1,10 @@ namespace Syntriax.Engine.Core; +/// +/// Represents an infinite ray in 2D space. +/// +/// The in 2D space where the ray starts from. +/// Normalized indicating the ray's is direction. public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) { /// -- 2.49.1 From ca0b2de91764f10bdc1255e4bf71003b4427310b Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 15 Jun 2025 13:29:53 +0300 Subject: [PATCH 04/91] docs: fixed typo on Shape2D parameter --- Engine.Core/Primitives/Shape2D.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Core/Primitives/Shape2D.cs b/Engine.Core/Primitives/Shape2D.cs index 06122c0..fbef6a2 100644 --- a/Engine.Core/Primitives/Shape2D.cs +++ b/Engine.Core/Primitives/Shape2D.cs @@ -270,7 +270,7 @@ public static class Shape2DExtensions public static Triangle ToSuperTriangle(this Shape2D shape) => Shape2D.GetSuperTriangle(shape); /// - public static void ToTrianglesConvex(this Shape2D shape, IList lines) => Shape2D.TriangulateConvex(shape, lines); + public static void ToTrianglesConvex(this Shape2D shape, IList triangles) => Shape2D.TriangulateConvex(shape, triangles); /// public static List ToTrianglesConvex(this Shape2D shape) => Shape2D.TriangulateConvex(shape); -- 2.49.1 From 4d353662a176a112f1b609c66b9a054145016002 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 15 Jun 2025 13:32:02 +0300 Subject: [PATCH 05/91] feat: xna color to engine color rgba extension method --- .../Engine.Integration.MonoGame/EngineConverter.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs b/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs index a5d047d..4a10da4 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs @@ -18,7 +18,10 @@ public static class EngineConverterExtensions public static Vector2D ToVector2D(this Vector2 vector) => new(vector.X, vector.Y); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Color ToColor(this ColorRGBA rgba) => new(rgba.R, rgba.G, rgba.B, rgba.A); + public static Color ToColor(this ColorRGBA color) => new(color.R, color.G, color.B, color.A); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ColorRGBA ToColorRGBA(this Color color) => new(color.R, color.G, color.B, color.A); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2D ToVector2D(this Point point) => new(point.X, point.Y); -- 2.49.1 From 4a3775a0dedf571c59fc456ebb67624f711fae2a Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 15 Jun 2025 14:34:52 +0300 Subject: [PATCH 06/91] perf: double copy in shape collider's world shape field --- Engine.Physics2D/Collider2DShapeBehaviour.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Physics2D/Collider2DShapeBehaviour.cs b/Engine.Physics2D/Collider2DShapeBehaviour.cs index 2ba213e..34d17ea 100644 --- a/Engine.Physics2D/Collider2DShapeBehaviour.cs +++ b/Engine.Physics2D/Collider2DShapeBehaviour.cs @@ -15,7 +15,7 @@ public class Collider2DShapeBehaviour : Collider2DBehaviourBase, IShapeCollider2 } } - private Shape2D _shapeWorld = Shape2D.Square.CreateCopy(); + private Shape2D _shapeWorld = Shape2D.Square; private Shape2D _shapeLocal = Shape2D.Square; public override void CalculateCollider() => ShapeLocal.Transform(Transform, _shapeWorld); -- 2.49.1 From e6b7b9953fe40376e509396a5b79fba7df3db244 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 15 Jun 2025 14:44:50 +0300 Subject: [PATCH 07/91] feat: ensured all primitives have ToString, GetHashCode & Equals methods --- Engine.Core/Primitives/AABB.cs | 25 ++++++++++++++++----- Engine.Core/Primitives/Circle.cs | 19 ++++++++++++++++ Engine.Core/Primitives/ColorHSV.cs | 14 ++++++------ Engine.Core/Primitives/ColorRGB.cs | 14 ++++++------ Engine.Core/Primitives/ColorRGBA.cs | 14 ++++++------ Engine.Core/Primitives/Line2D.cs | 19 ++++++++++++++++ Engine.Core/Primitives/Line2DEquation.cs | 19 ++++++++++++++++ Engine.Core/Primitives/Projection1D.cs | 19 ++++++++++++++++ Engine.Core/Primitives/Quaternion.cs | 16 +++++++------- Engine.Core/Primitives/Ray2D.cs | 19 ++++++++++++++++ Engine.Core/Primitives/Shape2D.cs | 28 ++++++++++++++++++++++++ Engine.Core/Primitives/Triangle.cs | 19 ++++++++++++++++ Engine.Core/Primitives/Vector2D.cs | 14 ++++++------ Engine.Core/Primitives/Vector3D.cs | 14 ++++++------ 14 files changed, 204 insertions(+), 49 deletions(-) diff --git a/Engine.Core/Primitives/AABB.cs b/Engine.Core/Primitives/AABB.cs index fad4569..7a04cb7 100644 --- a/Engine.Core/Primitives/AABB.cs +++ b/Engine.Core/Primitives/AABB.cs @@ -63,12 +63,6 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary) return new(lowerBoundary, upperBoundary); } - /// - /// Converts the to its string representation. - /// - /// A string representation of the . - public override string ToString() => $"{nameof(AABB)}({LowerBoundary}, {UpperBoundary})"; - /// /// Checks if two s are approximately equal. /// @@ -78,6 +72,25 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary) /// if the s are approximately equal; otherwise, . public static bool ApproximatelyEquals(AABB left, AABB right, float epsilon = float.Epsilon) => left.LowerBoundary.ApproximatelyEquals(right.LowerBoundary, epsilon) && left.UpperBoundary.ApproximatelyEquals(right.UpperBoundary, epsilon); + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is AABB aabb && LowerBoundary.Equals(aabb.LowerBoundary) && UpperBoundary.Equals(aabb.UpperBoundary); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(LowerBoundary, UpperBoundary); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(AABB)}({LowerBoundary}, {UpperBoundary})"; } /// diff --git a/Engine.Core/Primitives/Circle.cs b/Engine.Core/Primitives/Circle.cs index 1b4dccf..2d63ec3 100644 --- a/Engine.Core/Primitives/Circle.cs +++ b/Engine.Core/Primitives/Circle.cs @@ -77,6 +77,25 @@ public readonly struct Circle(Vector2D center, float radius) /// if the s are approximately equal; otherwise, . public static bool ApproximatelyEquals(Circle left, Circle right, float epsilon = float.Epsilon) => left.Center.ApproximatelyEquals(right.Center, epsilon) && left.Radius.ApproximatelyEquals(right.Radius, epsilon); + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Circle circle && Center.Equals(circle.Center) && Radius.Equals(circle.Radius); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(Center, Radius); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Circle)}({Center}, {Radius})"; } /// diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index f4404c5..12a6aeb 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -127,12 +127,6 @@ public readonly struct ColorHSV(float hue, float saturation, float value) /// The interpolated . public static ColorHSV Lerp(ColorHSV from, ColorHSV to, float t) => from + FromTo(from, to) * t; - /// - /// Converts the to its string representation. - /// - /// A string representation of the . - public override string ToString() => $"{nameof(ColorHSV)}({Hue}, {Saturation}, {Value})"; - /// /// Checks if two s are approximately equal within a specified epsilon range. /// @@ -148,13 +142,19 @@ public readonly struct ColorHSV(float hue, float saturation, float value) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is ColorHSV objVec && Hue.Equals(objVec.Hue) && Saturation.Equals(objVec.Saturation) && Value.Equals(objVec.Value); + public override bool Equals(object? obj) => obj is ColorHSV colorHSV && Hue.Equals(colorHSV.Hue) && Saturation.Equals(colorHSV.Saturation) && Value.Equals(colorHSV.Value); /// /// Generates a hash code for the . /// /// A hash code for the . public override int GetHashCode() => System.HashCode.Combine(Hue, Saturation, Value); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(ColorHSV)}({Hue}, {Saturation}, {Value})"; } /// diff --git a/Engine.Core/Primitives/ColorRGB.cs b/Engine.Core/Primitives/ColorRGB.cs index d37bfb6..d973458 100644 --- a/Engine.Core/Primitives/ColorRGB.cs +++ b/Engine.Core/Primitives/ColorRGB.cs @@ -119,24 +119,24 @@ public readonly struct ColorRGB(byte r, byte g, byte b) /// The interpolated . public static ColorRGB Lerp(ColorRGB from, ColorRGB to, float t) => from + FromTo(from, to) * t; - /// - /// Converts the to its string representation. - /// - /// A string representation of the . - public override string ToString() => $"{nameof(ColorRGB)}({R}, {G}, {B})"; - /// /// Determines whether the specified object is equal to the current . /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is ColorRGB objVec && R.Equals(objVec.R) && G.Equals(objVec.G) && B.Equals(objVec.B); + public override bool Equals(object? obj) => obj is ColorRGB colorRGB && R.Equals(colorRGB.R) && G.Equals(colorRGB.G) && B.Equals(colorRGB.B); /// /// Generates a hash code for the . /// /// A hash code for the . public override int GetHashCode() => System.HashCode.Combine(R, G, B); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(ColorRGB)}({R}, {G}, {B})"; } /// diff --git a/Engine.Core/Primitives/ColorRGBA.cs b/Engine.Core/Primitives/ColorRGBA.cs index 82d997e..01fe2b8 100644 --- a/Engine.Core/Primitives/ColorRGBA.cs +++ b/Engine.Core/Primitives/ColorRGBA.cs @@ -102,24 +102,24 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) /// The interpolated . public static ColorRGBA Lerp(ColorRGBA from, ColorRGBA to, float t) => from + FromTo(from, to) * t; - /// - /// Converts the to its string representation. - /// - /// A string representation of the . - public override string ToString() => $"{nameof(ColorRGBA)}({R}, {G}, {B}, {A})"; - /// /// Determines whether the specified object is equal to the current . /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is ColorRGBA objVec && R.Equals(objVec.R) && G.Equals(objVec.G) && B.Equals(objVec.B) && A.Equals(objVec.A); + public override bool Equals(object? obj) => obj is ColorRGBA colorRGBA && R.Equals(colorRGBA.R) && G.Equals(colorRGBA.G) && B.Equals(colorRGBA.B) && A.Equals(colorRGBA.A); /// /// Generates a hash code for the . /// /// A hash code for the . public override int GetHashCode() => System.HashCode.Combine(R, G, B, A); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(ColorRGBA)}({R}, {G}, {B}, {A})"; } /// diff --git a/Engine.Core/Primitives/Line2D.cs b/Engine.Core/Primitives/Line2D.cs index e5c2022..d4ddbb4 100644 --- a/Engine.Core/Primitives/Line2D.cs +++ b/Engine.Core/Primitives/Line2D.cs @@ -186,6 +186,25 @@ public readonly struct Line2D(Vector2D from, Vector2D to) /// if the s are approximately equal; otherwise, . public static bool ApproximatelyEquals(Line2D left, Line2D right, float epsilon = float.Epsilon) => left.From.ApproximatelyEquals(right.From, epsilon) && left.To.ApproximatelyEquals(right.To, epsilon); + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Line2D line2D && From.Equals(line2D.From) && To.Equals(line2D.To); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(From, To); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Line2D)}({From}, {To})"; } /// diff --git a/Engine.Core/Primitives/Line2DEquation.cs b/Engine.Core/Primitives/Line2DEquation.cs index d76c20d..3c036c7 100644 --- a/Engine.Core/Primitives/Line2DEquation.cs +++ b/Engine.Core/Primitives/Line2DEquation.cs @@ -38,6 +38,25 @@ public readonly struct Line2DEquation(float slope, float offsetY) /// True if the line equations are approximately equal; otherwise, false. public static bool ApproximatelyEquals(Line2DEquation left, Line2DEquation right, float epsilon = float.Epsilon) => left.Slope.ApproximatelyEquals(right.Slope, epsilon) && left.OffsetY.ApproximatelyEquals(right.OffsetY, epsilon); + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Line2DEquation lineEquation && Slope.Equals(lineEquation.Slope) && OffsetY.Equals(lineEquation.OffsetY); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(Slope, OffsetY); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Line2DEquation)}({Slope}, {OffsetY})"; } /// diff --git a/Engine.Core/Primitives/Projection1D.cs b/Engine.Core/Primitives/Projection1D.cs index 8a78413..3a664b4 100644 --- a/Engine.Core/Primitives/Projection1D.cs +++ b/Engine.Core/Primitives/Projection1D.cs @@ -70,6 +70,25 @@ public readonly struct Projection1D(float min, float max) depth = 0f; return false; } + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Projection1D projection1D && Min.Equals(projection1D.Min) && Max.Equals(projection1D.Max); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(Min, Max); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Projection1D)}({Min}, {Max})"; } /// diff --git a/Engine.Core/Primitives/Quaternion.cs b/Engine.Core/Primitives/Quaternion.cs index 75ab4f7..5124817 100644 --- a/Engine.Core/Primitives/Quaternion.cs +++ b/Engine.Core/Primitives/Quaternion.cs @@ -282,24 +282,24 @@ public readonly struct Quaternion(float x, float y, float z, float w) public static bool ApproximatelyEquals(Quaternion left, Quaternion right, float epsilon = float.Epsilon) => left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon) && left.Z.ApproximatelyEquals(right.Z, epsilon) && left.W.ApproximatelyEquals(right.W, epsilon); - /// - /// Converts the to its string representation. - /// - /// A string representation of the . - public override string ToString() => $"{nameof(Quaternion)}({W}, {X}, {Y}, {Z})"; - /// /// Determines whether the specified object is equal to the current . /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Quaternion objVec && X.Equals(objVec.X) && Y.Equals(objVec.Y) && Z.Equals(objVec.Z) && W.Equals(objVec.W); + public override bool Equals(object? obj) => obj is Quaternion quaternion && X.Equals(quaternion.X) && Y.Equals(quaternion.Y) && Z.Equals(quaternion.Z) && W.Equals(quaternion.W); /// /// Generates a hash code for the . /// /// A hash code for the . - public override int GetHashCode() => System.HashCode.Combine(X, Y, Z); + public override int GetHashCode() => System.HashCode.Combine(W, X, Y, Z); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Quaternion)}({W}, {X}, {Y}, {Z})"; } /// diff --git a/Engine.Core/Primitives/Ray2D.cs b/Engine.Core/Primitives/Ray2D.cs index 3e16bed..f72ad03 100644 --- a/Engine.Core/Primitives/Ray2D.cs +++ b/Engine.Core/Primitives/Ray2D.cs @@ -53,6 +53,25 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) return ray.Origin + ray.Direction * dot; } + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Ray2D ray2D && Origin.Equals(ray2D.Origin) && Direction.Equals(ray2D.Direction); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(Origin, Direction); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Ray2D)}({Origin}, {Direction})"; } /// diff --git a/Engine.Core/Primitives/Shape2D.cs b/Engine.Core/Primitives/Shape2D.cs index fbef6a2..7a72dd0 100644 --- a/Engine.Core/Primitives/Shape2D.cs +++ b/Engine.Core/Primitives/Shape2D.cs @@ -251,6 +251,34 @@ public class Shape2D(List vertices) : IEnumerable return true; } + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Shape2D shape2D && _vertices.Equals(shape2D._vertices); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(Vertices); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new(Vertices[0].ToString()); + for (int i = 1; i < Vertices.Count; i++) + { + stringBuilder.Append(", "); + stringBuilder.Append(Vertices[i].ToString()); + } + return $"{nameof(Shape2D)}({stringBuilder})"; + } + /// public IEnumerator GetEnumerator() => Vertices.GetEnumerator(); diff --git a/Engine.Core/Primitives/Triangle.cs b/Engine.Core/Primitives/Triangle.cs index aead0e3..064b047 100644 --- a/Engine.Core/Primitives/Triangle.cs +++ b/Engine.Core/Primitives/Triangle.cs @@ -44,6 +44,25 @@ public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C) /// true if the s are approximately equal; otherwise, false. public static bool ApproximatelyEquals(Triangle left, Triangle right, float epsilon = float.Epsilon) => left.A.ApproximatelyEquals(right.A, epsilon) && left.B.ApproximatelyEquals(right.B, epsilon) && left.C.ApproximatelyEquals(right.C, epsilon); + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Triangle triangle && A.Equals(triangle.A) && B.Equals(triangle.B) && C.Equals(triangle.C); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(A, B, C); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Triangle)}({A}, {B}, {C})"; } public static class TriangleExtensions diff --git a/Engine.Core/Primitives/Vector2D.cs b/Engine.Core/Primitives/Vector2D.cs index 0d69f05..3ede4d1 100644 --- a/Engine.Core/Primitives/Vector2D.cs +++ b/Engine.Core/Primitives/Vector2D.cs @@ -302,24 +302,24 @@ public readonly struct Vector2D(float x, float y) public static bool ApproximatelyEquals(Vector2D left, Vector2D right, float epsilon = float.Epsilon) => left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon); - /// - /// Converts the to its string representation. - /// - /// A string representation of the . - public override string ToString() => $"{nameof(Vector2D)}({X}, {Y})"; - /// /// Determines whether the specified object is equal to the current . /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Vector2D objVec && X.Equals(objVec.X) && Y.Equals(objVec.Y); + public override bool Equals(object? obj) => obj is Vector2D vector2D && X.Equals(vector2D.X) && Y.Equals(vector2D.Y); /// /// Generates a hash code for the . /// /// A hash code for the . public override int GetHashCode() => System.HashCode.Combine(X, Y); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Vector2D)}({X}, {Y})"; } /// diff --git a/Engine.Core/Primitives/Vector3D.cs b/Engine.Core/Primitives/Vector3D.cs index 420abe4..2582b30 100644 --- a/Engine.Core/Primitives/Vector3D.cs +++ b/Engine.Core/Primitives/Vector3D.cs @@ -271,24 +271,24 @@ public readonly struct Vector3D(float x, float y, float z) public static bool ApproximatelyEquals(Vector3D left, Vector3D right, float epsilon = float.Epsilon) => left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon) && left.Z.ApproximatelyEquals(right.Z, epsilon); - /// - /// Converts the to its string representation. - /// - /// A string representation of the . - public override string ToString() => $"{nameof(Vector3D)}({X}, {Y}, {Z})"; - /// /// Determines whether the specified object is equal to the current . /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Vector3D objVec && X.Equals(objVec.X) && Y.Equals(objVec.Y) && Z.Equals(objVec.Z); + public override bool Equals(object? obj) => obj is Vector3D vector3D && X.Equals(vector3D.X) && Y.Equals(vector3D.Y) && Z.Equals(vector3D.Z); /// /// Generates a hash code for the . /// /// A hash code for the . public override int GetHashCode() => System.HashCode.Combine(X, Y, Z); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Vector3D)}({X}, {Y}, {Z})"; } /// -- 2.49.1 From cf7061fd58189827edbf4ef3915636a6fd537d7c Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 15 Jun 2025 15:14:06 +0300 Subject: [PATCH 08/91] fix: shape2D triangulation order changed --- Engine.Core/Primitives/Shape2D.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Core/Primitives/Shape2D.cs b/Engine.Core/Primitives/Shape2D.cs index 7a72dd0..4a8ba84 100644 --- a/Engine.Core/Primitives/Shape2D.cs +++ b/Engine.Core/Primitives/Shape2D.cs @@ -122,7 +122,7 @@ public class Shape2D(List vertices) : IEnumerable triangles.Clear(); for (int i = 2; i < shape.Vertices.Count; i++) - triangles.Add(new Triangle(shape[0], shape[i - 1], shape[i])); + triangles.Add(new Triangle(shape[0], shape[i], shape[i - 1])); } /// -- 2.49.1 From 4c1018ddec1bc8616fea916331c9d4ca236e360a Mon Sep 17 00:00:00 2001 From: Syntriax Date: Wed, 18 Jun 2025 17:18:08 +0300 Subject: [PATCH 09/91] feat: added logger container behaviour --- Engine.Core/Debug/LoggerContainer.cs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Engine.Core/Debug/LoggerContainer.cs diff --git a/Engine.Core/Debug/LoggerContainer.cs b/Engine.Core/Debug/LoggerContainer.cs new file mode 100644 index 0000000..5a556f3 --- /dev/null +++ b/Engine.Core/Debug/LoggerContainer.cs @@ -0,0 +1,9 @@ +namespace Syntriax.Engine.Core.Debug; + +public class LoggerContainer : Behaviour, ILogger +{ + public ILogger Logger { get; set; } = new ConsoleLogger(); + + public ILogger.Level FilterLevel { get => Logger.FilterLevel; set => Logger.FilterLevel = value; } + public void Log(string message, ILogger.Level level = ILogger.Level.Info, bool force = false) => Logger.Log(message, level, force); +} -- 2.49.1 From 33cb44bf363053af1012a3a7ed87c1574ddd8fc4 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Wed, 18 Jun 2025 17:39:11 +0300 Subject: [PATCH 10/91] fix: file logger ensure directory exists --- Engine.Core/Debug/FileLogger.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Engine.Core/Debug/FileLogger.cs b/Engine.Core/Debug/FileLogger.cs index a7bc9c4..9c44b11 100644 --- a/Engine.Core/Debug/FileLogger.cs +++ b/Engine.Core/Debug/FileLogger.cs @@ -10,6 +10,10 @@ public class FileLogger : LoggerBase public FileLogger(string filePath) { FilePath = filePath; + + if (Path.GetDirectoryName(filePath) is string directoryPath) + Directory.CreateDirectory(directoryPath); + File.Open(filePath, FileMode.Create).Close(); } -- 2.49.1 From c3be8f60b7e78984bb73501dc4d273a05b1331d2 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Wed, 18 Jun 2025 17:39:23 +0300 Subject: [PATCH 11/91] feat: added logger wrapper class --- Engine.Core/Debug/LoggerWrapper.cs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Engine.Core/Debug/LoggerWrapper.cs diff --git a/Engine.Core/Debug/LoggerWrapper.cs b/Engine.Core/Debug/LoggerWrapper.cs new file mode 100644 index 0000000..15e69fb --- /dev/null +++ b/Engine.Core/Debug/LoggerWrapper.cs @@ -0,0 +1,23 @@ +namespace Syntriax.Engine.Core.Debug; + +public class LoggerWrapper(ILogger firstLogger, ILogger secondLogger) : ILogger +{ + private readonly ILogger firstLogger = firstLogger; + private readonly ILogger secondLogger = secondLogger; + + public ILogger.Level FilterLevel + { + get => firstLogger.FilterLevel; + set + { + firstLogger.FilterLevel = value; + secondLogger.FilterLevel = value; + } + } + + public void Log(string message, ILogger.Level level = ILogger.Level.Info, bool force = false) + { + firstLogger.Log(message, level, force); + secondLogger.Log(message, level, force); + } +} -- 2.49.1 From 767fc28488fbbea9d1125f91934f4b882275890c Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 21 Jun 2025 00:26:42 +0300 Subject: [PATCH 12/91] refactor: file logger relative path to full path conversion --- Engine.Core/Debug/FileLogger.cs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Engine.Core/Debug/FileLogger.cs b/Engine.Core/Debug/FileLogger.cs index 9c44b11..98b4032 100644 --- a/Engine.Core/Debug/FileLogger.cs +++ b/Engine.Core/Debug/FileLogger.cs @@ -7,18 +7,23 @@ public class FileLogger : LoggerBase { public readonly string FilePath; - public FileLogger(string filePath) - { - FilePath = filePath; - - if (Path.GetDirectoryName(filePath) is string directoryPath) - Directory.CreateDirectory(directoryPath); - - File.Open(filePath, FileMode.Create).Close(); - } - protected override void Write(string message) { File.AppendAllTextAsync(FilePath, $"{message}{Environment.NewLine}"); } + + public FileLogger(string filePath) + { + FilePath = filePath; + + bool isRelativePath = Path.GetFullPath(filePath).CompareTo(filePath) != 0; + + if (isRelativePath) + FilePath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, filePath)); + + if (Path.GetDirectoryName(FilePath) is string directoryPath) + Directory.CreateDirectory(directoryPath); + + File.Open(FilePath, FileMode.Create).Close(); + } } -- 2.49.1 From dae6549badf134d517720bfefd49c8705f1412a6 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 27 Jun 2025 11:37:20 +0300 Subject: [PATCH 13/91] refactor: Equals methods to use equality operators on primitives --- Engine.Core/Primitives/ColorHSV.cs | 2 +- Engine.Core/Primitives/ColorRGB.cs | 2 +- Engine.Core/Primitives/ColorRGBA.cs | 2 +- Engine.Core/Primitives/Quaternion.cs | 2 +- Engine.Core/Primitives/Ray2D.cs | 2 ++ Engine.Core/Primitives/Vector2D.cs | 2 +- Engine.Core/Primitives/Vector3D.cs | 2 +- 7 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index 12a6aeb..35c81c7 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -142,7 +142,7 @@ public readonly struct ColorHSV(float hue, float saturation, float value) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is ColorHSV colorHSV && Hue.Equals(colorHSV.Hue) && Saturation.Equals(colorHSV.Saturation) && Value.Equals(colorHSV.Value); + public override bool Equals(object? obj) => obj is ColorHSV colorHSV && this == colorHSV; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/ColorRGB.cs b/Engine.Core/Primitives/ColorRGB.cs index d973458..ad52500 100644 --- a/Engine.Core/Primitives/ColorRGB.cs +++ b/Engine.Core/Primitives/ColorRGB.cs @@ -124,7 +124,7 @@ public readonly struct ColorRGB(byte r, byte g, byte b) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is ColorRGB colorRGB && R.Equals(colorRGB.R) && G.Equals(colorRGB.G) && B.Equals(colorRGB.B); + public override bool Equals(object? obj) => obj is ColorRGB colorRGB && this == colorRGB; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/ColorRGBA.cs b/Engine.Core/Primitives/ColorRGBA.cs index 01fe2b8..9a1b285 100644 --- a/Engine.Core/Primitives/ColorRGBA.cs +++ b/Engine.Core/Primitives/ColorRGBA.cs @@ -107,7 +107,7 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is ColorRGBA colorRGBA && R.Equals(colorRGBA.R) && G.Equals(colorRGBA.G) && B.Equals(colorRGBA.B) && A.Equals(colorRGBA.A); + public override bool Equals(object? obj) => obj is ColorRGBA colorRGBA && this == colorRGBA; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Quaternion.cs b/Engine.Core/Primitives/Quaternion.cs index 5124817..e2e1e53 100644 --- a/Engine.Core/Primitives/Quaternion.cs +++ b/Engine.Core/Primitives/Quaternion.cs @@ -287,7 +287,7 @@ public readonly struct Quaternion(float x, float y, float z, float w) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Quaternion quaternion && X.Equals(quaternion.X) && Y.Equals(quaternion.Y) && Z.Equals(quaternion.Z) && W.Equals(quaternion.W); + public override bool Equals(object? obj) => obj is Quaternion quaternion && this == quaternion; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Ray2D.cs b/Engine.Core/Primitives/Ray2D.cs index f72ad03..721dfdd 100644 --- a/Engine.Core/Primitives/Ray2D.cs +++ b/Engine.Core/Primitives/Ray2D.cs @@ -22,6 +22,8 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) /// public readonly Ray2D Reversed => new(Origin, -Direction); + public static bool operator ==(Ray2D left, Ray2D right) => left.Origin == right.Origin; + public static bool operator !=(Ray2D left, Ray2D right) => left.Origin != right.Origin; public static implicit operator Ray2D(Line2D line) => new(line.From, line.From.FromTo(line.To).Normalized); /// diff --git a/Engine.Core/Primitives/Vector2D.cs b/Engine.Core/Primitives/Vector2D.cs index 3ede4d1..ff327e3 100644 --- a/Engine.Core/Primitives/Vector2D.cs +++ b/Engine.Core/Primitives/Vector2D.cs @@ -307,7 +307,7 @@ public readonly struct Vector2D(float x, float y) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Vector2D vector2D && X.Equals(vector2D.X) && Y.Equals(vector2D.Y); + public override bool Equals(object? obj) => obj is Vector2D vector2D && this == vector2D; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Vector3D.cs b/Engine.Core/Primitives/Vector3D.cs index 2582b30..190caf7 100644 --- a/Engine.Core/Primitives/Vector3D.cs +++ b/Engine.Core/Primitives/Vector3D.cs @@ -276,7 +276,7 @@ public readonly struct Vector3D(float x, float y, float z) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Vector3D vector3D && X.Equals(vector3D.X) && Y.Equals(vector3D.Y) && Z.Equals(vector3D.Z); + public override bool Equals(object? obj) => obj is Vector3D vector3D && this == vector3D; /// /// Generates a hash code for the . -- 2.49.1 From 0c096d39db7e2057ce1dbc1cc4f98b98659440b4 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 27 Jun 2025 11:43:44 +0300 Subject: [PATCH 14/91] docs: line equation XML comments updated --- Engine.Core/Primitives/Line2DEquation.cs | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Engine.Core/Primitives/Line2DEquation.cs b/Engine.Core/Primitives/Line2DEquation.cs index 3c036c7..5b227f5 100644 --- a/Engine.Core/Primitives/Line2DEquation.cs +++ b/Engine.Core/Primitives/Line2DEquation.cs @@ -1,41 +1,41 @@ namespace Syntriax.Engine.Core; /// -/// Represents a line equation in the form y = mx + b. +/// Represents a in the form y = mx + b. /// /// The slope of the line. -/// The y-intercept of the line. +/// The Y intercept of the line. /// -/// Initializes a new instance of the struct with the specified slope and y-intercept. +/// Initializes a new instance of the struct with the specified slope and Y intercept. /// [System.Diagnostics.DebuggerDisplay("y = {Slope}x + {OffsetY}")] public readonly struct Line2DEquation(float slope, float offsetY) { /// - /// The slope of the line equation. + /// The slope of the . /// public readonly float Slope = slope; /// - /// The y-intercept of the line equation. + /// The Y intercept of the . /// public readonly float OffsetY = offsetY; /// - /// Resolves the y-coordinate for a given x-coordinate using the line equation. + /// Resolves the Y coordinate for a given X coordinate using the . /// - /// The line equation to resolve. - /// The x-coordinate for which to resolve the y-coordinate. - /// The y-coordinate resolved using the line equation. + /// The to resolve. + /// The X coordinate for which to resolve the Y coordinate. + /// The Y coordinate resolved using the . public static float Resolve(Line2DEquation lineEquation, float x) => lineEquation.Slope * x + lineEquation.OffsetY; // y = mx + b /// - /// Checks if two line equations are approximately equal. + /// Checks if two are approximately equal. /// - /// The first line equation to compare. - /// The second line equation to compare. + /// The first to compare. + /// The second to compare. /// The epsilon range. - /// True if the line equations are approximately equal; otherwise, false. + /// True if the are approximately equal; otherwise, false. public static bool ApproximatelyEquals(Line2DEquation left, Line2DEquation right, float epsilon = float.Epsilon) => left.Slope.ApproximatelyEquals(right.Slope, epsilon) && left.OffsetY.ApproximatelyEquals(right.OffsetY, epsilon); @@ -60,7 +60,7 @@ public readonly struct Line2DEquation(float slope, float offsetY) } /// -/// Provides extension methods for the LineEquation struct. +/// Provides extension methods for the struct. /// public static class Line2DEquationExtensions { -- 2.49.1 From fa1614f2382827e3cb8439584cdeda91a05f7ba9 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 27 Jun 2025 11:44:52 +0300 Subject: [PATCH 15/91] feat: added approximately equals methods to projection 1D and ray 2D --- Engine.Core/Primitives/Projection1D.cs | 13 +++++++++++++ Engine.Core/Primitives/Ray2D.cs | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Engine.Core/Primitives/Projection1D.cs b/Engine.Core/Primitives/Projection1D.cs index 3a664b4..d144125 100644 --- a/Engine.Core/Primitives/Projection1D.cs +++ b/Engine.Core/Primitives/Projection1D.cs @@ -71,6 +71,16 @@ public readonly struct Projection1D(float min, float max) return false; } + /// + /// Checks if two s are approximately equal within a specified epsilon range. + /// + /// The first . + /// The second . + /// The epsilon range. + /// if the s are approximately equal; otherwise, . + public static bool ApproximatelyEquals(Projection1D left, Projection1D right, float epsilon = float.Epsilon) + => left.Min.ApproximatelyEquals(right.Min, epsilon) && left.Max.ApproximatelyEquals(right.Max, epsilon); + /// /// Determines whether the specified object is equal to the current . /// @@ -101,4 +111,7 @@ public static class Projection1DExtensions /// public static bool Overlaps(this Projection1D left, Projection1D right, out float depth) => Projection1D.Overlaps(left, right, out depth); + + /// + public static bool ApproximatelyEquals(this Projection1D left, Projection1D right, float epsilon = float.Epsilon) => Projection1D.ApproximatelyEquals(left, right, epsilon); } diff --git a/Engine.Core/Primitives/Ray2D.cs b/Engine.Core/Primitives/Ray2D.cs index 721dfdd..ed57996 100644 --- a/Engine.Core/Primitives/Ray2D.cs +++ b/Engine.Core/Primitives/Ray2D.cs @@ -56,6 +56,16 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) return ray.Origin + ray.Direction * dot; } + /// + /// Checks if two s are approximately equal within a specified epsilon range. + /// + /// The first . + /// The second . + /// The epsilon range. + /// if the s are approximately equal; otherwise, . + public static bool ApproximatelyEquals(Ray2D left, Ray2D right, float epsilon = float.Epsilon) + => left.Origin.ApproximatelyEquals(right.Origin, epsilon) && left.Direction.ApproximatelyEquals(right.Direction, epsilon); + /// /// Determines whether the specified object is equal to the current . /// @@ -89,4 +99,7 @@ public static class Ray2DExtensions /// + public static bool ApproximatelyEquals(this Ray2D left, Ray2D right, float epsilon = float.Epsilon) => Ray2D.ApproximatelyEquals(left, right, epsilon); } -- 2.49.1 From da5f31f9d7bd0e2cd11658f567cc7376ae8e26a3 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 27 Jun 2025 12:00:46 +0300 Subject: [PATCH 16/91] refactor: made equality operators consistent in primitives & added missing ones --- Engine.Core/Primitives/AABB.cs | 5 ++++- Engine.Core/Primitives/Circle.cs | 5 ++++- Engine.Core/Primitives/ColorHSV.cs | 4 ++-- Engine.Core/Primitives/Line2D.cs | 5 ++++- Engine.Core/Primitives/Line2DEquation.cs | 5 ++++- Engine.Core/Primitives/Projection1D.cs | 5 ++++- Engine.Core/Primitives/Ray2D.cs | 6 +++--- Engine.Core/Primitives/Triangle.cs | 5 ++++- 8 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Engine.Core/Primitives/AABB.cs b/Engine.Core/Primitives/AABB.cs index 7a04cb7..142e885 100644 --- a/Engine.Core/Primitives/AABB.cs +++ b/Engine.Core/Primitives/AABB.cs @@ -38,6 +38,9 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary) /// public readonly Vector2D SizeHalf => Size * .5f; + public static bool operator ==(AABB left, AABB right) => left.UpperBoundary == right.UpperBoundary && left.LowerBoundary == right.LowerBoundary; + public static bool operator !=(AABB left, AABB right) => left.UpperBoundary != right.UpperBoundary || left.LowerBoundary != right.LowerBoundary; + /// /// Creates an from a collection of s. /// @@ -78,7 +81,7 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is AABB aabb && LowerBoundary.Equals(aabb.LowerBoundary) && UpperBoundary.Equals(aabb.UpperBoundary); + public override bool Equals(object? obj) => obj is AABB aabb && this == aabb; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Circle.cs b/Engine.Core/Primitives/Circle.cs index 2d63ec3..9c3f2ae 100644 --- a/Engine.Core/Primitives/Circle.cs +++ b/Engine.Core/Primitives/Circle.cs @@ -38,6 +38,9 @@ public readonly struct Circle(Vector2D center, float radius) /// public static readonly Circle UnitCircle = new(Vector2D.Zero, 1f); + public static bool operator ==(Circle left, Circle right) => left.Center == right.Center && left.Radius == right.Radius; + public static bool operator !=(Circle left, Circle right) => left.Center != right.Center || left.Radius != right.Radius; + /// /// Sets the center of the . /// @@ -83,7 +86,7 @@ public readonly struct Circle(Vector2D center, float radius) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Circle circle && Center.Equals(circle.Center) && Radius.Equals(circle.Radius); + public override bool Equals(object? obj) => obj is Circle circle && this == circle; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index 35c81c7..cec3064 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -34,8 +34,8 @@ public readonly struct ColorHSV(float hue, float saturation, float value) public static ColorHSV operator *(ColorHSV color, float value) => new((color.Hue * value).Clamp(0f, 1f), (color.Saturation * value).Clamp(0f, 1f), (color.Value * value).Clamp(0f, 1f)); public static ColorHSV operator *(float value, ColorHSV color) => new((color.Hue * value).Clamp(0f, 1f), (color.Saturation * value).Clamp(0f, 1f), (color.Value * value).Clamp(0f, 1f)); public static ColorHSV operator /(ColorHSV color, float value) => new((color.Hue / value).Clamp(0f, 1f), (color.Saturation / value).Clamp(0f, 1f), (color.Value / value).Clamp(0f, 1f)); - public static bool operator ==(ColorHSV left, ColorHSV right) => left.Hue.ApproximatelyEquals(right.Hue) && left.Saturation.ApproximatelyEquals(right.Saturation) && left.Value.ApproximatelyEquals(right.Value); - public static bool operator !=(ColorHSV left, ColorHSV right) => !left.Hue.ApproximatelyEquals(right.Hue) || !left.Saturation.ApproximatelyEquals(right.Saturation) || !left.Value.ApproximatelyEquals(right.Value); + public static bool operator ==(ColorHSV left, ColorHSV right) => left.Hue == right.Hue && left.Saturation == right.Saturation && left.Value == right.Value; + public static bool operator !=(ColorHSV left, ColorHSV right) => left.Hue != right.Hue || left.Saturation != right.Saturation || left.Value != right.Value; public static implicit operator ColorHSV(ColorRGBA rgba) => (ColorRGB)rgba; public static implicit operator ColorHSV(ColorRGB rgb) diff --git a/Engine.Core/Primitives/Line2D.cs b/Engine.Core/Primitives/Line2D.cs index d4ddbb4..ee4e272 100644 --- a/Engine.Core/Primitives/Line2D.cs +++ b/Engine.Core/Primitives/Line2D.cs @@ -43,6 +43,9 @@ public readonly struct Line2D(Vector2D from, Vector2D to) /// public readonly float LengthSquared => From.FromTo(To).LengthSquared(); + public static bool operator ==(Line2D left, Line2D right) => left.From == right.From && left.To == right.To; + public static bool operator !=(Line2D left, Line2D right) => left.From != right.From || left.To != right.To; + /// /// The equation of the defined by this segment. /// @@ -192,7 +195,7 @@ public readonly struct Line2D(Vector2D from, Vector2D to) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Line2D line2D && From.Equals(line2D.From) && To.Equals(line2D.To); + public override bool Equals(object? obj) => obj is Line2D line2D && this == line2D; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Line2DEquation.cs b/Engine.Core/Primitives/Line2DEquation.cs index 5b227f5..19033bf 100644 --- a/Engine.Core/Primitives/Line2DEquation.cs +++ b/Engine.Core/Primitives/Line2DEquation.cs @@ -21,6 +21,9 @@ public readonly struct Line2DEquation(float slope, float offsetY) /// public readonly float OffsetY = offsetY; + public static bool operator ==(Line2DEquation left, Line2DEquation right) => left.Slope == right.Slope && left.OffsetY == right.OffsetY; + public static bool operator !=(Line2DEquation left, Line2DEquation right) => left.Slope != right.Slope || left.OffsetY != right.OffsetY; + /// /// Resolves the Y coordinate for a given X coordinate using the . /// @@ -44,7 +47,7 @@ public readonly struct Line2DEquation(float slope, float offsetY) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Line2DEquation lineEquation && Slope.Equals(lineEquation.Slope) && OffsetY.Equals(lineEquation.OffsetY); + public override bool Equals(object? obj) => obj is Line2DEquation lineEquation && this == lineEquation; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Projection1D.cs b/Engine.Core/Primitives/Projection1D.cs index d144125..599d53a 100644 --- a/Engine.Core/Primitives/Projection1D.cs +++ b/Engine.Core/Primitives/Projection1D.cs @@ -21,6 +21,9 @@ public readonly struct Projection1D(float min, float max) /// public readonly float Max = max; + public static bool operator ==(Projection1D left, Projection1D right) => left.Min == right.Min && left.Max == right.Max; + public static bool operator !=(Projection1D left, Projection1D right) => left.Min != right.Min || left.Max != right.Max; + /// /// Checks if two projections overlap. /// @@ -86,7 +89,7 @@ public readonly struct Projection1D(float min, float max) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Projection1D projection1D && Min.Equals(projection1D.Min) && Max.Equals(projection1D.Max); + public override bool Equals(object? obj) => obj is Projection1D projection1D && this == projection1D; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Ray2D.cs b/Engine.Core/Primitives/Ray2D.cs index ed57996..f536179 100644 --- a/Engine.Core/Primitives/Ray2D.cs +++ b/Engine.Core/Primitives/Ray2D.cs @@ -22,8 +22,8 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) /// public readonly Ray2D Reversed => new(Origin, -Direction); - public static bool operator ==(Ray2D left, Ray2D right) => left.Origin == right.Origin; - public static bool operator !=(Ray2D left, Ray2D right) => left.Origin != right.Origin; + public static bool operator ==(Ray2D left, Ray2D right) => left.Origin == right.Origin && left.Direction == right.Direction; + public static bool operator !=(Ray2D left, Ray2D right) => left.Origin != right.Origin || left.Direction != right.Direction; public static implicit operator Ray2D(Line2D line) => new(line.From, line.From.FromTo(line.To).Normalized); /// @@ -71,7 +71,7 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Ray2D ray2D && Origin.Equals(ray2D.Origin) && Direction.Equals(ray2D.Direction); + public override bool Equals(object? obj) => obj is Ray2D ray2D && this == ray2D; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Triangle.cs b/Engine.Core/Primitives/Triangle.cs index 064b047..087d977 100644 --- a/Engine.Core/Primitives/Triangle.cs +++ b/Engine.Core/Primitives/Triangle.cs @@ -7,6 +7,9 @@ public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C) public readonly Vector2D B { get; init; } = B; public readonly Vector2D C { get; init; } = C; + public static bool operator ==(Triangle left, Triangle right) => left.A == right.A && left.B == right.B && left.C == right.C; + public static bool operator !=(Triangle left, Triangle right) => left.A != right.A || left.B != right.B || left.C != right.C; + public readonly float Area => .5f * Math.Abs( A.X * (B.Y - C.Y) + @@ -50,7 +53,7 @@ public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C) /// /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . - public override bool Equals(object? obj) => obj is Triangle triangle && A.Equals(triangle.A) && B.Equals(triangle.B) && C.Equals(triangle.C); + public override bool Equals(object? obj) => obj is Triangle triangle && this == triangle; /// /// Generates a hash code for the . -- 2.49.1 From 026f343d4367a99a0a5981d240c73b23c1a9932a Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 27 Jun 2025 14:42:25 +0300 Subject: [PATCH 17/91] docs: removed unnecessary comment lines from math constants --- Engine.Core/Math.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Engine.Core/Math.cs b/Engine.Core/Math.cs index 4fe4d52..27eaecc 100644 --- a/Engine.Core/Math.cs +++ b/Engine.Core/Math.cs @@ -6,17 +6,17 @@ namespace Syntriax.Engine.Core; public static class Math { /// - /// The value of Pi (π), a mathematical constant approximately equal to 3.14159. + /// The value of Pi (π). /// public const float PI = 3.1415926535897932f; /// - /// The value of Tau (τ), a mathematical constant equal to 2π, approximately equal to 6.28319. + /// The value of Tau (τ), mathematical constant equal to 2π. /// public const float Tau = 2f * PI; /// - /// The base of the natural logarithm, approximately equal to 2.71828. + /// The base of the natural logarithm. /// public const float E = 2.718281828459045f; -- 2.49.1 From 5315db0077e85da798c1dfa48800d9c81b3b0751 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 27 Jun 2025 14:44:20 +0300 Subject: [PATCH 18/91] refactor!: renamed Math.PI to Math.Pi --- Engine.Core/Math.cs | 8 ++++---- Engine.Systems/Tween/Easings.cs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Engine.Core/Math.cs b/Engine.Core/Math.cs index 27eaecc..456dec5 100644 --- a/Engine.Core/Math.cs +++ b/Engine.Core/Math.cs @@ -8,12 +8,12 @@ public static class Math /// /// The value of Pi (π). /// - public const float PI = 3.1415926535897932f; + public const float Pi = 3.1415926535897932f; /// /// The value of Tau (τ), mathematical constant equal to 2π. /// - public const float Tau = 2f * PI; + public const float Tau = 2f * Pi; /// /// The base of the natural logarithm. @@ -23,12 +23,12 @@ public static class Math /// /// The conversion factor from radians to degrees. /// - public const float RadianToDegree = 180f / PI; + public const float RadianToDegree = 180f / Pi; /// /// The conversion factor from degrees to radians. /// - public const float DegreeToRadian = PI / 180f; + public const float DegreeToRadian = Pi / 180f; /// /// Gets one minus of given . diff --git a/Engine.Systems/Tween/Easings.cs b/Engine.Systems/Tween/Easings.cs index a629c1f..5b42480 100644 --- a/Engine.Systems/Tween/Easings.cs +++ b/Engine.Systems/Tween/Easings.cs @@ -9,8 +9,8 @@ internal static class EaseConstants internal const float c1 = 1.70158f; internal const float c2 = c1 * 1.525f; internal const float c3 = c1 + 1f; - internal const float c4 = 2f * Math.PI / 3f; - internal const float c5 = 2f * Math.PI / 4.5f; + internal const float c4 = 2f * Math.Pi / 3f; + internal const float c5 = 2f * Math.Pi / 4.5f; } public abstract class EasingBase where T : IEasing, new() { public static readonly T Instance = new(); } @@ -33,9 +33,9 @@ public class EaseInQuint : EasingBase, IEasing { public float Evalu public class EaseOutQuint : EasingBase, IEasing { public float Evaluate(float x) => 1f - Math.Pow(1f - x, 5f); } public class EaseInOutQuint : EasingBase, IEasing { public float Evaluate(float x) => x < .5f ? 16f * x * x * x * x * x : 1f - Math.Pow(-2f * x + 2f, 5f) * .5f; } -public class EaseInSine : EasingBase, IEasing { public float Evaluate(float x) => 1f - Math.Cos(x * Math.PI * .5f); } -public class EaseOutSine : EasingBase, IEasing { public float Evaluate(float x) => Math.Sin(x * Math.PI * .5f); } -public class EaseInOutSine : EasingBase, IEasing { public float Evaluate(float x) => -(Math.Cos(Math.PI * x) - 1f) * .5f; } +public class EaseInSine : EasingBase, IEasing { public float Evaluate(float x) => 1f - Math.Cos(x * Math.Pi * .5f); } +public class EaseOutSine : EasingBase, IEasing { public float Evaluate(float x) => Math.Sin(x * Math.Pi * .5f); } +public class EaseInOutSine : EasingBase, IEasing { public float Evaluate(float x) => -(Math.Cos(Math.Pi * x) - 1f) * .5f; } public class EaseInExpo : EasingBase, IEasing { public float Evaluate(float x) => x == 0f ? 0f : Math.Pow(2f, 10f * x - 10f); } public class EaseOutExpo : EasingBase, IEasing { public float Evaluate(float x) => x == 1f ? 1f : 1f - Math.Pow(2f, -10f * x); } -- 2.49.1 From 14843ddebad3173af026d5d727220ddbabc6744e Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 28 Jun 2025 12:50:03 +0300 Subject: [PATCH 19/91] refactor: removed unnecessary linq call --- Engine.Core/BehaviourController.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Engine.Core/BehaviourController.cs b/Engine.Core/BehaviourController.cs index 5e4855f..9334871 100644 --- a/Engine.Core/BehaviourController.cs +++ b/Engine.Core/BehaviourController.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; namespace Syntriax.Engine.Core; @@ -50,17 +49,13 @@ public class BehaviourController : BaseEntity, IBehaviourController public IReadOnlyList GetBehaviours() { - List? behaviours = null; + List behaviours = []; + foreach (IBehaviour behaviourItem in this.behaviours) - { - if (behaviourItem is not T behaviour) - continue; + if (behaviourItem is T behaviour) + behaviours.Add(behaviour); - behaviours ??= []; - behaviours.Add(behaviour); - } - - return behaviours ?? Enumerable.Empty().ToList(); + return behaviours; } public void GetBehaviours(IList results) -- 2.49.1 From 7212094a3d8bb74d6c9baca9213d62a13cb53713 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 28 Jun 2025 14:15:11 +0300 Subject: [PATCH 20/91] chore: updated misleading comment --- Engine.Core/Systems/UpdateManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index dcf8070..20e5f58 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -4,7 +4,7 @@ namespace Syntriax.Engine.Core; public class UpdateManager : Behaviour { - // We use Ascending order because draw calls are running from last to first + // We use Ascending order because we are using reverse for loop to call them private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); private readonly ActiveBehaviourCollectorSorted firstFrameUpdates = new() { SortBy = SortByAscendingPriority() }; -- 2.49.1 From 978cba96c801071a47eeec16b9f5422790ad15d4 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 6 Jul 2025 20:39:45 +0300 Subject: [PATCH 21/91] refactor!: event methods renamed for better clarity --- Engine.Core/Helpers/Event.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index c6dd65c..66f2550 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -9,9 +9,9 @@ public class Event private readonly List onceListeners = null!; public void AddListener(EventHandler listener) => listeners.Add(listener); - public void AddOnceListener(EventHandler listener) => onceListeners.Add(listener); + public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); public void RemoveListener(EventHandler listener) => listeners.Remove(listener); - public void RemoveOnceListener(EventHandler listener) => onceListeners.Remove(listener); + public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); public void Clear() { listeners.Clear(); onceListeners.Clear(); } public void Invoke() { @@ -56,9 +56,9 @@ public class Event private readonly List onceListeners = null!; public void AddListener(EventHandler listener) => listeners.Add(listener); - public void AddOnceListener(EventHandler listener) => onceListeners.Add(listener); + public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); public void RemoveListener(EventHandler listener) => listeners.Remove(listener); - public void RemoveOnceListener(EventHandler listener) => onceListeners.Remove(listener); + public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); public void Clear() { listeners.Clear(); onceListeners.Clear(); } public void Invoke(TSender sender) { @@ -103,9 +103,9 @@ public class Event private readonly List onceListeners = null!; public void AddListener(EventHandler listener) => listeners.Add(listener); - public void AddOnceListener(EventHandler listener) => onceListeners.Add(listener); + public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); public void RemoveListener(EventHandler listener) => listeners.Remove(listener); - public void RemoveOnceListener(EventHandler listener) => onceListeners.Remove(listener); + public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); public void Clear() { listeners.Clear(); onceListeners.Clear(); } public void Invoke(TSender sender, TArguments args) { -- 2.49.1 From a1feb0bad3823f993c11838e01aad36e7f1a6b00 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 6 Jul 2025 21:04:22 +0300 Subject: [PATCH 22/91] docs: added documentation for events --- Engine.Core/Helpers/Event.cs | 209 +++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index 66f2550..05573ae 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -3,16 +3,81 @@ using System.Collections.Generic; namespace Syntriax.Engine.Core; +/// +/// Represents a simple event with no parameters. +/// Example usage: +/// +/// public class MyBehaviour : Behaviour, IUpdate +/// { +/// public readonly Event MyEvent = new(); +/// +/// public MyBehaviour() +/// { +/// MyEvent.AddListener(OnEventTriggered); +/// MyEvent.AddOneTimeListener(OnEventTriggeredOneTime); +/// } +/// +/// public void Update() +/// { +/// MyEvent.Invoke(); +/// } +/// +/// private void OnEventTriggered() +/// { +/// Console.WriteLine($"Event occurred!"); +/// } +/// +/// private static void OnEventTriggeredOneTime() +/// { +/// Console.WriteLine($"Event called once!"); +/// } +/// } +/// +/// The output of the example code above would be: +/// +/// Event occurred! +/// Event called once! +/// Event occurred! +/// Event occurred! +/// Event occurred! +/// ... +/// +/// public class Event { private readonly List listeners = null!; private readonly List onceListeners = null!; + /// + /// Subscribes the callback to be invoked whenever the event is triggered. + /// + /// The callback to be called when the event is triggered. public void AddListener(EventHandler listener) => listeners.Add(listener); + /// + /// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once. + /// + /// The callback to be called the next time the event is triggered. public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); + + /// + /// Unsubscribes the callback that was previously registered by . + /// + /// The callback that was previously registered by public void RemoveListener(EventHandler listener) => listeners.Remove(listener); + /// + /// Unsubscribes the callback that was previously registered by . + /// + /// The callback that was previously registered by public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); + + /// + /// Unsubscribes all listeners that was previously registered by either or . + /// public void Clear() { listeners.Clear(); onceListeners.Clear(); } + + /// + /// Triggers the event. + /// public void Invoke() { for (int i = 0; i < listeners.Count; i++) @@ -50,16 +115,84 @@ public class Event public delegate void EventHandler(); } +/// +/// Represents an event with only sender parameters. +/// Example usage: +/// +/// public class MyBehaviour : Behaviour, IUpdate +/// { +/// public readonly Event<MyBehaviour> MyEvent = new(); +/// +/// public MyBehaviour() +/// { +/// MyEvent.AddListener(OnEventTriggered); +/// MyEvent.AddOneTimeListener(OnEventTriggeredOneTime); +/// } +/// +/// public void Update() +/// { +/// MyEvent.Invoke(this); +/// } +/// +/// private void OnEventTriggered(MyBehaviour sender) +/// { +/// Console.WriteLine($"{sender.Id}'s event occurred!"); +/// } +/// +/// private static void OnEventTriggeredOneTime(MyBehaviour sender) +/// { +/// Console.WriteLine($"{sender.Id}'s event called once!"); +/// } +/// } +/// +/// The output of the example code above would be: +/// +/// [Id]'s event occurred! +/// [Id]'s event called once! +/// [Id]'s event occurred! +/// [Id]'s event occurred! +/// [Id]'s event occurred! +/// ... +/// +/// +/// +/// Sender type public class Event { private readonly List listeners = null!; private readonly List onceListeners = null!; + /// + /// Subscribes the callback to be invoked whenever the event is triggered. + /// + /// The callback to be called when the event is triggered. public void AddListener(EventHandler listener) => listeners.Add(listener); + /// + /// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once. + /// + /// The callback to be called the next time the event is triggered. public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); + + /// + /// Unsubscribes the callback that was previously registered by . + /// + /// The callback that was previously registered by public void RemoveListener(EventHandler listener) => listeners.Remove(listener); + /// + /// Unsubscribes the callback that was previously registered by . + /// + /// The callback that was previously registered by public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); + + /// + /// Unsubscribes all listeners that was previously registered by either or . + /// public void Clear() { listeners.Clear(); onceListeners.Clear(); } + + /// + /// Triggers the event. + /// + /// The caller that's triggering this event. public void Invoke(TSender sender) { for (int i = 0; i < listeners.Count; i++) @@ -97,16 +230,92 @@ public class Event public delegate void EventHandler(TSender sender); } +/// +/// Represents an event with sender and argument parameters. +/// Example usage: +/// +/// public class MyBehaviour : Behaviour, IUpdate +/// { +/// public readonly Event<MyBehaviour, MyArguments> MyEvent = new(); +/// +/// private int myInt = 0; +/// private bool myBool = false; +/// +/// public MyBehaviour() +/// { +/// MyEvent.AddOneTimeListener(OnEventTriggeredOneTime); +/// MyEvent.AddListener(OnEventTriggered); +/// } +/// +/// public void Update() +/// { +/// MyEvent.Invoke(this, new MyArguments(myInt, myBool)); +/// myInt++; +/// myBool = !myBool; +/// } +/// +/// private void OnEventTriggered(MyBehaviour sender, MyArguments args) +/// { +/// Console.WriteLine($"{sender.Id}'s event occurred with MyInt: {args.MyInt} and MyBool {args.MyBool}!"); +/// } +/// +/// private static void OnEventTriggeredOneTime(MyBehaviour sender, MyArguments args) +/// { +/// Console.WriteLine($"{sender.Id}'s event called once with MyInt: {args.MyInt} and MyBool {args.MyBool}!"); +/// } +/// +/// public readonly record struct MyArguments(int MyInt, bool MyBool); +/// } +/// +/// The output of the example code above would be: +/// +/// [Id]'s event occurred with MyInt: 0 and MyBool False! +/// [Id]'s event called once with MyInt: 0 and MyBool False! +/// [Id]'s event occurred with MyInt: 1 and MyBool True! +/// [Id]'s event occurred with MyInt: 2 and MyBool False! +/// [Id]'s event occurred with MyInt: 3 and MyBool True! +/// ... +/// +/// +/// +/// Sender type public class Event { private readonly List listeners = null!; private readonly List onceListeners = null!; + /// + /// Subscribes the callback to be invoked whenever the event is triggered. + /// + /// The callback to be called when the event is triggered. public void AddListener(EventHandler listener) => listeners.Add(listener); + /// + /// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once. + /// + /// The callback to be called the next time the event is triggered. public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); + + /// + /// Unsubscribes the callback that was previously registered by . + /// + /// The callback that was previously registered by public void RemoveListener(EventHandler listener) => listeners.Remove(listener); + /// + /// Unsubscribes the callback that was previously registered by . + /// + /// The callback that was previously registered by public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); + + /// + /// Unsubscribes all listeners that was previously registered by either or . + /// public void Clear() { listeners.Clear(); onceListeners.Clear(); } + + /// + /// Triggers the event. + /// + /// The caller that's triggering this event. + /// The arguments provided for this event. public void Invoke(TSender sender, TArguments args) { for (int i = 0; i < listeners.Count; i++) -- 2.49.1 From 8f03628bd64efeb15fdea39f074bc14f1dc9f2a9 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 6 Jul 2025 22:21:20 +0300 Subject: [PATCH 23/91] fix: invocation loop inversed --- Engine.Core/Helpers/Event.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index 05573ae..7f818e5 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -80,7 +80,7 @@ public class Event /// public void Invoke() { - for (int i = 0; i < listeners.Count; i++) + for (int i = listeners.Count - 1; i >= 0; i--) try { listeners[i].Invoke(); } catch (Exception exception) { @@ -195,7 +195,7 @@ public class Event /// The caller that's triggering this event. public void Invoke(TSender sender) { - for (int i = 0; i < listeners.Count; i++) + for (int i = listeners.Count - 1; i >= 0; i--) try { listeners[i].Invoke(sender); } catch (Exception exception) { @@ -318,7 +318,7 @@ public class Event /// The arguments provided for this event. public void Invoke(TSender sender, TArguments args) { - for (int i = 0; i < listeners.Count; i++) + for (int i = listeners.Count - 1; i >= 0; i--) try { listeners[i].Invoke(sender, args); } catch (Exception exception) { -- 2.49.1 From bc1c76d746d01281ecaa3c6937e1990fd1dcdcfc Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 6 Jul 2025 22:22:57 +0300 Subject: [PATCH 24/91] feat: added priorities to events --- Engine.Core/Helpers/Event.cs | 186 +++++++++++++++++++++++++++++------ 1 file changed, 156 insertions(+), 30 deletions(-) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index 7f818e5..c8221f4 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -45,30 +45,71 @@ namespace Syntriax.Engine.Core; /// public class Event { - private readonly List listeners = null!; - private readonly List onceListeners = null!; + // We use Ascending order because draw calls are running from last to first + private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + + private readonly List listeners = null!; + private readonly List onceListeners = null!; /// /// Subscribes the callback to be invoked whenever the event is triggered. /// /// The callback to be called when the event is triggered. - public void AddListener(EventHandler listener) => listeners.Add(listener); + /// Priority of the callback. + public void AddListener(EventHandler listener, int priority = 0) + { + ListenerData listenerData = new(listener, priority); + + int insertIndex = listeners.BinarySearch(listenerData, SortByAscendingPriority); + if (insertIndex < 0) + insertIndex = ~insertIndex; + + listeners.Insert(insertIndex, listenerData); + } + /// /// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once. /// /// The callback to be called the next time the event is triggered. - public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); + /// Priority of the callback. + public void AddOneTimeListener(EventHandler listener, int priority = 0) + { + ListenerData listenerData = new(listener, priority); + + int insertIndex = onceListeners.BinarySearch(listenerData, SortByAscendingPriority); + if (insertIndex < 0) + insertIndex = ~insertIndex; + + onceListeners.Insert(insertIndex, listenerData); + } /// /// Unsubscribes the callback that was previously registered by . /// /// The callback that was previously registered by - public void RemoveListener(EventHandler listener) => listeners.Remove(listener); + public void RemoveListener(EventHandler listener) + { + for (int i = listeners.Count - 1; i >= 0; i--) + if (listeners[i].Callback == listener) + { + listeners.RemoveAt(i); + return; + } + } + /// /// Unsubscribes the callback that was previously registered by . /// /// The callback that was previously registered by - public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); + public void RemoveOneTimeListener(EventHandler listener) + { + for (int i = 0; i < onceListeners.Count; i++) + if (onceListeners[i].Callback == listener) + { + onceListeners.RemoveAt(i); + return; + } + } /// /// Unsubscribes all listeners that was previously registered by either or . @@ -81,19 +122,19 @@ public class Event public void Invoke() { for (int i = listeners.Count - 1; i >= 0; i--) - try { listeners[i].Invoke(); } + try { listeners[i].Callback.Invoke(); } catch (Exception exception) { - string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}()"; + string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}()"; Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); } for (int i = onceListeners.Count - 1; i >= 0; i--) { - try { onceListeners[i].Invoke(); } + try { onceListeners[i].Callback.Invoke(); } catch (Exception exception) { - string methodCallRepresentation = $"{onceListeners[i].Method.DeclaringType?.FullName}.{onceListeners[i].Method.Name}()"; + string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}()"; Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); } onceListeners.RemoveAt(i); @@ -113,6 +154,7 @@ public class Event } public delegate void EventHandler(); + private record struct ListenerData(EventHandler Callback, int Priority); } /// @@ -159,30 +201,71 @@ public class Event /// Sender type public class Event { - private readonly List listeners = null!; - private readonly List onceListeners = null!; + // We use Ascending order because draw calls are running from last to first + private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + + private readonly List listeners = null!; + private readonly List onceListeners = null!; /// /// Subscribes the callback to be invoked whenever the event is triggered. /// /// The callback to be called when the event is triggered. - public void AddListener(EventHandler listener) => listeners.Add(listener); + /// Priority of the callback. + public void AddListener(EventHandler listener, int priority = 0) + { + ListenerData listenerData = new(listener, priority); + + int insertIndex = listeners.BinarySearch(listenerData, SortByAscendingPriority); + if (insertIndex < 0) + insertIndex = ~insertIndex; + + listeners.Insert(insertIndex, listenerData); + } + /// /// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once. /// /// The callback to be called the next time the event is triggered. - public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); + /// Priority of the callback. + public void AddOneTimeListener(EventHandler listener, int priority = 0) + { + ListenerData listenerData = new(listener, priority); + + int insertIndex = onceListeners.BinarySearch(listenerData, SortByAscendingPriority); + if (insertIndex < 0) + insertIndex = ~insertIndex; + + onceListeners.Insert(insertIndex, listenerData); + } /// /// Unsubscribes the callback that was previously registered by . /// /// The callback that was previously registered by - public void RemoveListener(EventHandler listener) => listeners.Remove(listener); + public void RemoveListener(EventHandler listener) + { + for (int i = listeners.Count - 1; i >= 0; i--) + if (listeners[i].Callback == listener) + { + listeners.RemoveAt(i); + return; + } + } + /// /// Unsubscribes the callback that was previously registered by . /// /// The callback that was previously registered by - public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); + public void RemoveOneTimeListener(EventHandler listener) + { + for (int i = 0; i < onceListeners.Count; i++) + if (onceListeners[i].Callback == listener) + { + onceListeners.RemoveAt(i); + return; + } + } /// /// Unsubscribes all listeners that was previously registered by either or . @@ -196,19 +279,19 @@ public class Event public void Invoke(TSender sender) { for (int i = listeners.Count - 1; i >= 0; i--) - try { listeners[i].Invoke(sender); } + try { listeners[i].Callback.Invoke(sender); } catch (Exception exception) { - string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({sender})"; + string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({sender})"; Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); } for (int i = onceListeners.Count - 1; i >= 0; i--) { - try { onceListeners[i].Invoke(sender); } + try { onceListeners[i].Callback.Invoke(sender); } catch (Exception exception) { - string methodCallRepresentation = $"{onceListeners[i].Method.DeclaringType?.FullName}.{onceListeners[i].Method.Name}({sender})"; + string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({sender})"; Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); } onceListeners.RemoveAt(i); @@ -228,6 +311,7 @@ public class Event } public delegate void EventHandler(TSender sender); + private record struct ListenerData(EventHandler Callback, int Priority); } /// @@ -281,30 +365,71 @@ public class Event /// Sender type public class Event { - private readonly List listeners = null!; - private readonly List onceListeners = null!; + // We use Ascending order because draw calls are running from last to first + private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + + private readonly List listeners = null!; + private readonly List onceListeners = null!; /// /// Subscribes the callback to be invoked whenever the event is triggered. /// /// The callback to be called when the event is triggered. - public void AddListener(EventHandler listener) => listeners.Add(listener); + /// Priority of the callback. + public void AddListener(EventHandler listener, int priority = 0) + { + ListenerData listenerData = new(listener, priority); + + int insertIndex = listeners.BinarySearch(listenerData, SortByAscendingPriority); + if (insertIndex < 0) + insertIndex = ~insertIndex; + + listeners.Insert(insertIndex, listenerData); + } + /// /// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once. /// /// The callback to be called the next time the event is triggered. - public void AddOneTimeListener(EventHandler listener) => onceListeners.Add(listener); + /// Priority of the callback. + public void AddOneTimeListener(EventHandler listener, int priority = 0) + { + ListenerData listenerData = new(listener, priority); + + int insertIndex = onceListeners.BinarySearch(listenerData, SortByAscendingPriority); + if (insertIndex < 0) + insertIndex = ~insertIndex; + + onceListeners.Insert(insertIndex, listenerData); + } /// /// Unsubscribes the callback that was previously registered by . /// /// The callback that was previously registered by - public void RemoveListener(EventHandler listener) => listeners.Remove(listener); + public void RemoveListener(EventHandler listener) + { + for (int i = listeners.Count - 1; i >= 0; i--) + if (listeners[i].Callback == listener) + { + listeners.RemoveAt(i); + return; + } + } + /// /// Unsubscribes the callback that was previously registered by . /// /// The callback that was previously registered by - public void RemoveOneTimeListener(EventHandler listener) => onceListeners.Remove(listener); + public void RemoveOneTimeListener(EventHandler listener) + { + for (int i = 0; i < onceListeners.Count; i++) + if (onceListeners[i].Callback == listener) + { + onceListeners.RemoveAt(i); + return; + } + } /// /// Unsubscribes all listeners that was previously registered by either or . @@ -319,19 +444,19 @@ public class Event public void Invoke(TSender sender, TArguments args) { for (int i = listeners.Count - 1; i >= 0; i--) - try { listeners[i].Invoke(sender, args); } + try { listeners[i].Callback.Invoke(sender, args); } catch (Exception exception) { - string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", sender, args)})"; + string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({string.Join(", ", sender, args)})"; Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); } for (int i = onceListeners.Count - 1; i >= 0; i--) { - try { onceListeners[i].Invoke(sender, args); } + try { onceListeners[i].Callback.Invoke(sender, args); } catch (Exception exception) { - string methodCallRepresentation = $"{onceListeners[i].Method.DeclaringType?.FullName}.{onceListeners[i].Method.Name}({string.Join(", ", sender, args)})"; + string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({string.Join(", ", sender, args)})"; Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); } onceListeners.RemoveAt(i); @@ -351,4 +476,5 @@ public class Event } public delegate void EventHandler(TSender sender, TArguments args); + private record struct ListenerData(EventHandler Callback, int Priority); } -- 2.49.1 From c8bb991865c8efc99786a9a10767f08ce7b8709c Mon Sep 17 00:00:00 2001 From: Syntriax Date: Wed, 9 Jul 2025 22:19:44 +0300 Subject: [PATCH 25/91] refactor!: removed noise from class names Renamed classes with names XBehaviour to X --- .../{DrawableShapeBehaviour.cs => DrawableShape.cs} | 8 ++++---- .../{KeyboardInputsBehaviour.cs => KeyboardInputs.cs} | 2 +- .../{MonoGameCamera2DBehaviour.cs => MonoGameCamera2D.cs} | 8 ++++---- .../Behaviours/SpriteBatcher.cs | 4 ++-- .../Behaviours/TriangleBatcher.cs | 4 ++-- .../{Collider2DBehaviourBase.cs => Collider2DBase.cs} | 4 ++-- .../{Collider2DCircleBehaviour.cs => Collider2DCircle.cs} | 6 +++--- .../{Collider2DShapeBehaviour.cs => Collider2DShape.cs} | 6 +++--- .../Time/{StopwatchBehaviour.cs => Stopwatch.cs} | 2 +- Engine.Systems/Time/{TickerBehaviour.cs => Ticker.cs} | 2 +- Engine.Systems/Time/{TimerBehaviour.cs => Timer.cs} | 2 +- 11 files changed, 24 insertions(+), 24 deletions(-) rename Engine.Integration/Engine.Integration.MonoGame/Behaviours/{DrawableShapeBehaviour.cs => DrawableShape.cs} (68%) rename Engine.Integration/Engine.Integration.MonoGame/Behaviours/{KeyboardInputsBehaviour.cs => KeyboardInputs.cs} (98%) rename Engine.Integration/Engine.Integration.MonoGame/Behaviours/{MonoGameCamera2DBehaviour.cs => MonoGameCamera2D.cs} (93%) rename Engine.Physics2D/{Collider2DBehaviourBase.cs => Collider2DBase.cs} (97%) rename Engine.Physics2D/{Collider2DCircleBehaviour.cs => Collider2DCircle.cs} (69%) rename Engine.Physics2D/{Collider2DShapeBehaviour.cs => Collider2DShape.cs} (76%) rename Engine.Systems/Time/{StopwatchBehaviour.cs => Stopwatch.cs} (97%) rename Engine.Systems/Time/{TickerBehaviour.cs => Ticker.cs} (92%) rename Engine.Systems/Time/{TimerBehaviour.cs => Timer.cs} (97%) diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShapeBehaviour.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShape.cs similarity index 68% rename from Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShapeBehaviour.cs rename to Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShape.cs index dbfef7e..ba31f23 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShapeBehaviour.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShape.cs @@ -4,7 +4,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Integration.MonoGame; -public class DrawableShapeBehaviour : Behaviour2D, IDrawableTriangle, IPreDraw +public class DrawableShape : Behaviour2D, IDrawableTriangle, IPreDraw { private readonly Shape2D shape = new([]); private readonly List worldTriangles = []; @@ -23,7 +23,7 @@ public class DrawableShapeBehaviour : Behaviour2D, IDrawableTriangle, IPreDraw protected void UpdateWorldShape() => shape.Transform(Transform, worldShape); - public DrawableShapeBehaviour() => shape = Shape2D.Triangle; - public DrawableShapeBehaviour(Shape2D shape) => this.shape = shape; - public DrawableShapeBehaviour(Shape2D shape, ColorRGB color) { this.shape = shape; this.color = color; } + public DrawableShape() => shape = Shape2D.Triangle; + public DrawableShape(Shape2D shape) => this.shape = shape; + public DrawableShape(Shape2D shape, ColorRGB color) { this.shape = shape; this.color = color; } } diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputsBehaviour.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs similarity index 98% rename from Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputsBehaviour.cs rename to Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs index 944fcc1..350e92f 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputsBehaviour.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs @@ -8,7 +8,7 @@ using Syntriax.Engine.Systems.Input; namespace Syntriax.Engine.Integration.MonoGame; -public class KeyboardInputsBehaviour : Behaviour, IButtonInputs, IUpdate +public class KeyboardInputs : Behaviour, IButtonInputs, IUpdate { public Event, IButtonInputs.ButtonCallbackArguments> OnAnyButtonPressed { get; } = new(); public Event, IButtonInputs.ButtonCallbackArguments> OnAnyButtonReleased { get; } = new(); diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2DBehaviour.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs similarity index 93% rename from Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2DBehaviour.cs rename to Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs index 553c843..7357ae7 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2DBehaviour.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs @@ -5,7 +5,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Integration.MonoGame; -public class MonoGameCamera2DBehaviour : BehaviourBase, ICamera2D, IFirstFrameUpdate, IPreDraw +public class MonoGameCamera2D : BehaviourBase, ICamera2D, IFirstFrameUpdate, IPreDraw { public event MatrixTransformChangedArguments? OnMatrixTransformChanged = null; public event ViewportChangedArguments? OnViewportChanged = null; @@ -103,7 +103,7 @@ public class MonoGameCamera2DBehaviour : BehaviourBase, ICamera2D, IFirstFrameUp protected sealed override void InitializeInternal() => Transform = BehaviourController.GetRequiredBehaviour(); protected sealed override void FinalizeInternal() => Transform = null!; - public delegate void MatrixTransformChangedArguments(MonoGameCamera2DBehaviour sender); - public delegate void ViewportChangedArguments(MonoGameCamera2DBehaviour sender); - public delegate void ZoomChangedArguments(MonoGameCamera2DBehaviour sender); + public delegate void MatrixTransformChangedArguments(MonoGameCamera2D sender); + public delegate void ViewportChangedArguments(MonoGameCamera2D sender); + public delegate void ZoomChangedArguments(MonoGameCamera2D sender); } diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs index 88b13ac..f3f57ae 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs @@ -9,14 +9,14 @@ public class SpriteBatcher : BehaviourBase, IFirstFrameUpdate, IDraw private static Comparer SortByPriority() => Comparer.Create((x, y) => y.Priority.CompareTo(x.Priority)); private ISpriteBatch spriteBatch = null!; - private MonoGameCamera2DBehaviour camera2D = null!; + private MonoGameCamera2D camera2D = null!; private readonly ActiveBehaviourCollectorSorted drawableSprites = new() { SortBy = SortByPriority() }; public void FirstActiveFrame() { MonoGameWindowContainer windowContainer = Universe.FindRequiredBehaviour(); - camera2D = Universe.FindRequiredBehaviour(); + camera2D = Universe.FindRequiredBehaviour(); spriteBatch = new SpriteBatchWrapper(windowContainer.Window.GraphicsDevice); drawableSprites.Unassign(); diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs index 4215384..11bca97 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs @@ -11,13 +11,13 @@ public class TriangleBatcher : BehaviourBase, ITriangleBatch, IFirstFrameUpdate, private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); private TriangleBatch triangleBatch = null!; - private MonoGameCamera2DBehaviour camera2D = null!; + private MonoGameCamera2D camera2D = null!; private readonly ActiveBehaviourCollectorSorted drawableShapes = new() { SortBy = SortByAscendingPriority() }; public void FirstActiveFrame() { MonoGameWindowContainer windowContainer = BehaviourController.UniverseObject.Universe.FindRequiredBehaviour(); - camera2D = BehaviourController.UniverseObject.Universe.FindRequiredBehaviour(); + camera2D = BehaviourController.UniverseObject.Universe.FindRequiredBehaviour(); triangleBatch = new(windowContainer.Window.GraphicsDevice); drawableShapes.Unassign(); diff --git a/Engine.Physics2D/Collider2DBehaviourBase.cs b/Engine.Physics2D/Collider2DBase.cs similarity index 97% rename from Engine.Physics2D/Collider2DBehaviourBase.cs rename to Engine.Physics2D/Collider2DBase.cs index 209d860..bca0735 100644 --- a/Engine.Physics2D/Collider2DBehaviourBase.cs +++ b/Engine.Physics2D/Collider2DBase.cs @@ -2,7 +2,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D; -public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D +public abstract class Collider2DBase : Behaviour2D, ICollider2D { public Event OnCollisionDetected { get; } = new(); public Event OnCollisionResolved { get; } = new(); @@ -18,7 +18,7 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D protected bool NeedsRecalculation { get; set; } = true; protected IRigidBody2D? _rigidBody2D = null; - protected Collider2DBehaviourBase() + protected Collider2DBase() { delegateOnBehaviourAddedToController = OnBehaviourAddedToController; delegateOnBehaviourRemovedFromController = OnBehaviourRemovedFromController; diff --git a/Engine.Physics2D/Collider2DCircleBehaviour.cs b/Engine.Physics2D/Collider2DCircle.cs similarity index 69% rename from Engine.Physics2D/Collider2DCircleBehaviour.cs rename to Engine.Physics2D/Collider2DCircle.cs index 7fb9fb0..5d2f8cb 100644 --- a/Engine.Physics2D/Collider2DCircleBehaviour.cs +++ b/Engine.Physics2D/Collider2DCircle.cs @@ -2,7 +2,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D; -public class Collider2DCircleBehaviour : Collider2DBehaviourBase, ICircleCollider2D +public class Collider2DCircle : Collider2DBase, ICircleCollider2D { private Circle _circleLocal = Circle.UnitCircle; @@ -19,6 +19,6 @@ public class Collider2DCircleBehaviour : Collider2DBehaviourBase, ICircleCollide public override void CalculateCollider() => CircleWorld = Transform.Transform(_circleLocal); - public Collider2DCircleBehaviour() { } - public Collider2DCircleBehaviour(Circle circle) => CircleLocal = circle; + public Collider2DCircle() { } + public Collider2DCircle(Circle circle) => CircleLocal = circle; } diff --git a/Engine.Physics2D/Collider2DShapeBehaviour.cs b/Engine.Physics2D/Collider2DShape.cs similarity index 76% rename from Engine.Physics2D/Collider2DShapeBehaviour.cs rename to Engine.Physics2D/Collider2DShape.cs index 34d17ea..7f2b51a 100644 --- a/Engine.Physics2D/Collider2DShapeBehaviour.cs +++ b/Engine.Physics2D/Collider2DShape.cs @@ -2,7 +2,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D; -public class Collider2DShapeBehaviour : Collider2DBehaviourBase, IShapeCollider2D +public class Collider2DShape : Collider2DBase, IShapeCollider2D { public Shape2D ShapeWorld { get => _shapeWorld; protected set => _shapeWorld = value; } public Shape2D ShapeLocal @@ -20,8 +20,8 @@ public class Collider2DShapeBehaviour : Collider2DBehaviourBase, IShapeCollider2 public override void CalculateCollider() => ShapeLocal.Transform(Transform, _shapeWorld); - public Collider2DShapeBehaviour() { } - public Collider2DShapeBehaviour(Shape2D shape) + public Collider2DShape() { } + public Collider2DShape(Shape2D shape) { ShapeLocal = shape; } diff --git a/Engine.Systems/Time/StopwatchBehaviour.cs b/Engine.Systems/Time/Stopwatch.cs similarity index 97% rename from Engine.Systems/Time/StopwatchBehaviour.cs rename to Engine.Systems/Time/Stopwatch.cs index 2eab89d..40593f6 100644 --- a/Engine.Systems/Time/StopwatchBehaviour.cs +++ b/Engine.Systems/Time/Stopwatch.cs @@ -2,7 +2,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Systems.Time; -public class StopwatchBehaviour : Behaviour, IUpdate, IStopwatch +public class Stopwatch : Behaviour, IUpdate, IStopwatch { public Event OnStarted { get; } = new(); public Event OnDelta { get; } = new(); diff --git a/Engine.Systems/Time/TickerBehaviour.cs b/Engine.Systems/Time/Ticker.cs similarity index 92% rename from Engine.Systems/Time/TickerBehaviour.cs rename to Engine.Systems/Time/Ticker.cs index d7ada18..ec09f88 100644 --- a/Engine.Systems/Time/TickerBehaviour.cs +++ b/Engine.Systems/Time/Ticker.cs @@ -2,7 +2,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Systems.Time; -public class TickerBehaviour : StopwatchBehaviour, ITicker +public class Ticker : Stopwatch, ITicker { public Event OnTick { get; } = new(); diff --git a/Engine.Systems/Time/TimerBehaviour.cs b/Engine.Systems/Time/Timer.cs similarity index 97% rename from Engine.Systems/Time/TimerBehaviour.cs rename to Engine.Systems/Time/Timer.cs index 314afac..45c01fb 100644 --- a/Engine.Systems/Time/TimerBehaviour.cs +++ b/Engine.Systems/Time/Timer.cs @@ -2,7 +2,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Systems.Time; -public class TimerBehaviour : Behaviour, IUpdate, ITimer +public class Timer : Behaviour, IUpdate, ITimer { public Event OnStarted { get; } = new(); public Event OnDelta { get; } = new(); -- 2.49.1 From 0e5cc8f898cf31eaaf13ac54e9f8066d52101976 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 12 Jul 2025 16:53:01 +0300 Subject: [PATCH 26/91] feat: added loggers to event classes --- Engine.Core/Helpers/Event.cs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index c8221f4..de869ff 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using Syntriax.Engine.Core.Debug; + namespace Syntriax.Engine.Core; /// @@ -48,6 +50,9 @@ public class Event // We use Ascending order because draw calls are running from last to first private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + private ILogger _logger = new ConsoleLogger(); + public ILogger Logger { get => _logger; set => _logger = value ?? new ConsoleLogger(); } + private readonly List listeners = null!; private readonly List onceListeners = null!; @@ -126,7 +131,8 @@ public class Event catch (Exception exception) { string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}()"; - Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogError(this, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogException(this, exception); } for (int i = onceListeners.Count - 1; i >= 0; i--) @@ -135,7 +141,8 @@ public class Event catch (Exception exception) { string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}()"; - Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogError(this, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogException(this, exception); } onceListeners.RemoveAt(i); } @@ -204,6 +211,9 @@ public class Event // We use Ascending order because draw calls are running from last to first private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + private ILogger _logger = new ConsoleLogger(); + public ILogger Logger { get => _logger; set => _logger = value ?? new ConsoleLogger(); } + private readonly List listeners = null!; private readonly List onceListeners = null!; @@ -283,7 +293,8 @@ public class Event catch (Exception exception) { string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({sender})"; - Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogException(sender, exception); } for (int i = onceListeners.Count - 1; i >= 0; i--) @@ -292,7 +303,8 @@ public class Event catch (Exception exception) { string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({sender})"; - Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogException(sender, exception); } onceListeners.RemoveAt(i); } @@ -368,6 +380,9 @@ public class Event // We use Ascending order because draw calls are running from last to first private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + private ILogger _logger = new ConsoleLogger(); + public ILogger Logger { get => _logger; set => _logger = value ?? new ConsoleLogger(); } + private readonly List listeners = null!; private readonly List onceListeners = null!; @@ -448,7 +463,8 @@ public class Event catch (Exception exception) { string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({string.Join(", ", sender, args)})"; - Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogException(sender, exception); } for (int i = onceListeners.Count - 1; i >= 0; i--) @@ -457,7 +473,8 @@ public class Event catch (Exception exception) { string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({string.Join(", ", sender, args)})"; - Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + Logger.LogException(sender, exception); } onceListeners.RemoveAt(i); } -- 2.49.1 From 41245c0c1ceadba90b5e7978873425a1d5b530c0 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 12 Jul 2025 17:05:18 +0300 Subject: [PATCH 27/91] refactor: added class restriction to generic type for event senders --- Engine.Core/Helpers/Event.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index de869ff..1186593 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -206,7 +206,7 @@ public class Event /// /// /// Sender type -public class Event +public class Event where TSender : class { // We use Ascending order because draw calls are running from last to first private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); @@ -375,7 +375,7 @@ public class Event /// /// /// Sender type -public class Event +public class Event where TSender : class { // We use Ascending order because draw calls are running from last to first private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); -- 2.49.1 From 42064875a0006a9ccaabccf57b71dc5b39d15392 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 12 Jul 2025 17:34:23 +0300 Subject: [PATCH 28/91] chore: added extra line for LoggerExtensions.LogException for better clarity --- Engine.Core/Debug/LoggerExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Engine.Core/Debug/LoggerExtensions.cs b/Engine.Core/Debug/LoggerExtensions.cs index ac8e44c..e98e219 100644 --- a/Engine.Core/Debug/LoggerExtensions.cs +++ b/Engine.Core/Debug/LoggerExtensions.cs @@ -21,6 +21,7 @@ public static class LoggerExtensions public static void LogException(this ILogger logger, T caller, Exception exception, bool force = false) { + Log(logger, caller, $"Exception of type {exception.GetType().Name} occured", ILogger.Level.Error, force); Log(logger, caller, $"Message: {exception.Message}", ILogger.Level.Error, force); Log(logger, caller, $"InnerException: {exception.InnerException}", ILogger.Level.Error, force); Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{exception.StackTrace}"); -- 2.49.1 From 7db56e7f3e7491d8591a87321440d834485d410f Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 12 Jul 2025 17:34:56 +0300 Subject: [PATCH 29/91] refactor: moved event log calls to a shared method --- Engine.Core/Helpers/Event.cs | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index 1186593..570af86 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -131,8 +131,7 @@ public class Event catch (Exception exception) { string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}()"; - Logger.LogError(this, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); - Logger.LogException(this, exception); + EventHelpers.LogInvocationException(listeners[i].Callback.Target ?? this, Logger, exception, methodCallRepresentation); } for (int i = onceListeners.Count - 1; i >= 0; i--) @@ -141,8 +140,7 @@ public class Event catch (Exception exception) { string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}()"; - Logger.LogError(this, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); - Logger.LogException(this, exception); + EventHelpers.LogInvocationException(onceListeners[i].Callback.Target ?? this, Logger, exception, methodCallRepresentation); } onceListeners.RemoveAt(i); } @@ -293,8 +291,7 @@ public class Event where TSender : class catch (Exception exception) { string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({sender})"; - Logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); - Logger.LogException(sender, exception); + EventHelpers.LogInvocationException(listeners[i].Callback.Target ?? sender, Logger, exception, methodCallRepresentation); } for (int i = onceListeners.Count - 1; i >= 0; i--) @@ -303,8 +300,7 @@ public class Event where TSender : class catch (Exception exception) { string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({sender})"; - Logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); - Logger.LogException(sender, exception); + EventHelpers.LogInvocationException(onceListeners[i].Callback.Target ?? sender, Logger, exception, methodCallRepresentation); } onceListeners.RemoveAt(i); } @@ -462,9 +458,8 @@ public class Event where TSender : class try { listeners[i].Callback.Invoke(sender, args); } catch (Exception exception) { - string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({string.Join(", ", sender, args)})"; - Logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); - Logger.LogException(sender, exception); + string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({sender}, {args})"; + EventHelpers.LogInvocationException(listeners[i].Callback.Target ?? sender, Logger, exception, methodCallRepresentation); } for (int i = onceListeners.Count - 1; i >= 0; i--) @@ -472,9 +467,8 @@ public class Event where TSender : class try { onceListeners[i].Callback.Invoke(sender, args); } catch (Exception exception) { - string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({string.Join(", ", sender, args)})"; - Logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); - Logger.LogException(sender, exception); + string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({sender}, {args})"; + EventHelpers.LogInvocationException(onceListeners[i].Callback.Target ?? sender, Logger, exception, methodCallRepresentation); } onceListeners.RemoveAt(i); } @@ -495,3 +489,12 @@ public class Event where TSender : class public delegate void EventHandler(TSender sender, TArguments args); private record struct ListenerData(EventHandler Callback, int Priority); } + +internal static class EventHelpers +{ + public static void LogInvocationException(object sender, ILogger logger, Exception exception, string methodCallRepresentation) + { + logger.LogException(sender, exception); + logger.LogError(sender, $"Unexpected exception on invocation of method {methodCallRepresentation}"); + } +} -- 2.49.1 From 83b155fc5e8fd1892278876cb90e10dcb64e2154 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 12 Jul 2025 18:31:35 +0300 Subject: [PATCH 30/91] feat: trace log level added --- Engine.Core/Debug/ILogger.cs | 1 + Engine.Core/Debug/LoggerBase.cs | 2 +- Engine.Core/Debug/LoggerExtensions.cs | 11 +++++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Engine.Core/Debug/ILogger.cs b/Engine.Core/Debug/ILogger.cs index c1e78d2..c66cfb7 100644 --- a/Engine.Core/Debug/ILogger.cs +++ b/Engine.Core/Debug/ILogger.cs @@ -8,6 +8,7 @@ public interface ILogger enum Level { + Trace, Info, Warning, Error, diff --git a/Engine.Core/Debug/LoggerBase.cs b/Engine.Core/Debug/LoggerBase.cs index 6b0439c..9bbcf10 100644 --- a/Engine.Core/Debug/LoggerBase.cs +++ b/Engine.Core/Debug/LoggerBase.cs @@ -4,7 +4,7 @@ namespace Syntriax.Engine.Core.Debug; public abstract class LoggerBase : ILogger { - public ILogger.Level FilterLevel { get; set; } = ILogger.Level.Info; + public ILogger.Level FilterLevel { get; set; } = ILogger.Level.Trace; public void Log(string message, ILogger.Level level = ILogger.Level.Info, bool force = false) { diff --git a/Engine.Core/Debug/LoggerExtensions.cs b/Engine.Core/Debug/LoggerExtensions.cs index e98e219..90a7bae 100644 --- a/Engine.Core/Debug/LoggerExtensions.cs +++ b/Engine.Core/Debug/LoggerExtensions.cs @@ -16,7 +16,7 @@ public static class LoggerExtensions public static void LogError(this ILogger logger, T caller, string message, bool force = false) { Log(logger, caller, message, ILogger.Level.Error, force); - Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{new StackTrace()}"); + LogTrace(logger, caller, new StackTrace(), force); } public static void LogException(this ILogger logger, T caller, Exception exception, bool force = false) @@ -24,6 +24,13 @@ public static class LoggerExtensions Log(logger, caller, $"Exception of type {exception.GetType().Name} occured", ILogger.Level.Error, force); Log(logger, caller, $"Message: {exception.Message}", ILogger.Level.Error, force); Log(logger, caller, $"InnerException: {exception.InnerException}", ILogger.Level.Error, force); - Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{exception.StackTrace}"); + + // Not using LogTrace because exception.StackTrace is a type of string + Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{exception.StackTrace}", ILogger.Level.Trace); + } + + public static void LogTrace(this ILogger logger, T caller, StackTrace stackTrace, bool force = false) + { + Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{stackTrace ?? new()}", ILogger.Level.Trace, force); } } -- 2.49.1 From 65cfaf1b4a0d09eb396b3fdc98c52539af384f36 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 21 Jul 2025 10:18:00 +0300 Subject: [PATCH 31/91] feat: ILogger.Shared for global access --- Engine.Core/Debug/ILogger.cs | 2 ++ Engine.Core/Debug/LoggerContainer.cs | 2 +- Engine.Core/Helpers/Event.cs | 12 ++++++------ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Engine.Core/Debug/ILogger.cs b/Engine.Core/Debug/ILogger.cs index c66cfb7..babe6b6 100644 --- a/Engine.Core/Debug/ILogger.cs +++ b/Engine.Core/Debug/ILogger.cs @@ -2,6 +2,8 @@ namespace Syntriax.Engine.Core.Debug; public interface ILogger { + static ILogger Shared { get; set; } = new ConsoleLogger(); + Level FilterLevel { get; set; } void Log(string message, Level level = Level.Info, bool force = false); diff --git a/Engine.Core/Debug/LoggerContainer.cs b/Engine.Core/Debug/LoggerContainer.cs index 5a556f3..22f3490 100644 --- a/Engine.Core/Debug/LoggerContainer.cs +++ b/Engine.Core/Debug/LoggerContainer.cs @@ -2,7 +2,7 @@ namespace Syntriax.Engine.Core.Debug; public class LoggerContainer : Behaviour, ILogger { - public ILogger Logger { get; set; } = new ConsoleLogger(); + public ILogger Logger { get; set; } = ILogger.Shared; public ILogger.Level FilterLevel { get => Logger.FilterLevel; set => Logger.FilterLevel = value; } public void Log(string message, ILogger.Level level = ILogger.Level.Info, bool force = false) => Logger.Log(message, level, force); diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index 570af86..c216515 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -50,8 +50,8 @@ public class Event // We use Ascending order because draw calls are running from last to first private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); - private ILogger _logger = new ConsoleLogger(); - public ILogger Logger { get => _logger; set => _logger = value ?? new ConsoleLogger(); } + private ILogger _logger = ILogger.Shared; + public ILogger Logger { get => _logger; set => _logger = value ?? ILogger.Shared; } private readonly List listeners = null!; private readonly List onceListeners = null!; @@ -209,8 +209,8 @@ public class Event where TSender : class // We use Ascending order because draw calls are running from last to first private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); - private ILogger _logger = new ConsoleLogger(); - public ILogger Logger { get => _logger; set => _logger = value ?? new ConsoleLogger(); } + private ILogger _logger = ILogger.Shared; + public ILogger Logger { get => _logger; set => _logger = value ?? ILogger.Shared; } private readonly List listeners = null!; private readonly List onceListeners = null!; @@ -376,8 +376,8 @@ public class Event where TSender : class // We use Ascending order because draw calls are running from last to first private static readonly Comparer SortByAscendingPriority = Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); - private ILogger _logger = new ConsoleLogger(); - public ILogger Logger { get => _logger; set => _logger = value ?? new ConsoleLogger(); } + private ILogger _logger = ILogger.Shared; + public ILogger Logger { get => _logger; set => _logger = value ?? ILogger.Shared; } private readonly List listeners = null!; private readonly List onceListeners = null!; -- 2.49.1 From 200e8ae7da5609daaafef505af3b2b44267fc05f Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 21 Jul 2025 10:25:33 +0300 Subject: [PATCH 32/91] feat: ILogger WrapWith extension method added --- Engine.Core/Debug/LoggerWrapperExtensions.cs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 Engine.Core/Debug/LoggerWrapperExtensions.cs diff --git a/Engine.Core/Debug/LoggerWrapperExtensions.cs b/Engine.Core/Debug/LoggerWrapperExtensions.cs new file mode 100644 index 0000000..c98bece --- /dev/null +++ b/Engine.Core/Debug/LoggerWrapperExtensions.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core.Debug; + +public static class LoggerWrapperExtensions +{ + public static ILogger WrapWith(this ILogger thisLogger, ILogger logger) => new LoggerWrapper(thisLogger, logger); +} -- 2.49.1 From ad365dc7225df5df0d8be0729f6c62490c845f77 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 25 Jul 2025 21:40:57 +0300 Subject: [PATCH 33/91] feat: monogame content loader interface added --- .../Abstract/ILoadContent.cs | 10 ++++ .../Behaviours/LoadContentManager.cs | 53 +++++++++++++++++++ .../MonoGameWindow.cs | 3 ++ 3 files changed, 66 insertions(+) create mode 100644 Engine.Integration/Engine.Integration.MonoGame/Abstract/ILoadContent.cs create mode 100644 Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs diff --git a/Engine.Integration/Engine.Integration.MonoGame/Abstract/ILoadContent.cs b/Engine.Integration/Engine.Integration.MonoGame/Abstract/ILoadContent.cs new file mode 100644 index 0000000..042a5b7 --- /dev/null +++ b/Engine.Integration/Engine.Integration.MonoGame/Abstract/ILoadContent.cs @@ -0,0 +1,10 @@ +using Microsoft.Xna.Framework.Content; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Integration.MonoGame; + +public interface ILoadContent : IBehaviour +{ + void LoadContent(ContentManager content); +} diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs new file mode 100644 index 0000000..ccaf8da --- /dev/null +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Integration.MonoGame; + +public class LoadContentManager : Behaviour, IFirstFrameUpdate +{ + // We use Ascending order because we are using reverse for loop to call them + private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + + private readonly ActiveBehaviourCollectorSorted loadContents = new() { SortBy = SortByAscendingPriority() }; + private readonly List toCallLoadContents = new(32); + + private MonoGameWindowContainer monoGameWindowContainer = null!; + + public void FirstActiveFrame() + { + monoGameWindowContainer = Universe.FindRequiredBehaviour(); + } + + protected override void OnEnteredUniverse(IUniverse universe) + { + loadContents.Assign(universe); + + universe.OnPreUpdate.AddListener(OnPreUpdate); + } + + protected override void OnExitedUniverse(IUniverse universe) + { + loadContents.Unassign(); + + universe.OnPreUpdate.RemoveListener(OnPreUpdate); + } + + private void OnPreUpdate(IUniverse sender, IUniverse.UpdateArguments args) + { + for (int i = toCallLoadContents.Count - 1; i >= 0; i--) + { + toCallLoadContents[i].LoadContent(monoGameWindowContainer.Window.Content); + toCallLoadContents.RemoveAt(i); + } + } + + private void OnFirstFrameCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) + { + toCallLoadContents.Add(args.BehaviourCollected); + } + + public LoadContentManager() + { + loadContents.OnCollected.AddListener(OnFirstFrameCollected); + } +} diff --git a/Engine.Integration/Engine.Integration.MonoGame/MonoGameWindow.cs b/Engine.Integration/Engine.Integration.MonoGame/MonoGameWindow.cs index 62e9ae5..8b8740c 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/MonoGameWindow.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/MonoGameWindow.cs @@ -21,6 +21,9 @@ public class MonoGameWindow : Game Universe.InstantiateUniverseObject().SetUniverseObject("Window Container") .BehaviourController.AddBehaviour(this); + + Universe.InstantiateUniverseObject().SetUniverseObject("Content Loader") + .BehaviourController.AddBehaviour(); } protected override void Initialize() -- 2.49.1 From df06e8d1342ab405ee6fdf56646508cfd36ccffb Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 25 Jul 2025 23:24:08 +0300 Subject: [PATCH 34/91] feat: ticker is decoupled from stopwatch and added timer and stopwatch tickers --- Engine.Systems/Time/ITicker.cs | 2 +- .../Time/{Ticker.cs => TickerStopwatch.cs} | 6 +-- Engine.Systems/Time/TickerTimer.cs | 40 +++++++++++++++++++ Engine.Systems/Time/Timer.cs | 2 +- 4 files changed, 45 insertions(+), 5 deletions(-) rename Engine.Systems/Time/{Ticker.cs => TickerStopwatch.cs} (83%) create mode 100644 Engine.Systems/Time/TickerTimer.cs diff --git a/Engine.Systems/Time/ITicker.cs b/Engine.Systems/Time/ITicker.cs index 1d88e4a..17ec73d 100644 --- a/Engine.Systems/Time/ITicker.cs +++ b/Engine.Systems/Time/ITicker.cs @@ -2,7 +2,7 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Systems.Time; -public interface ITicker : IStopwatch +public interface ITicker { Event OnTick { get; } diff --git a/Engine.Systems/Time/Ticker.cs b/Engine.Systems/Time/TickerStopwatch.cs similarity index 83% rename from Engine.Systems/Time/Ticker.cs rename to Engine.Systems/Time/TickerStopwatch.cs index ec09f88..d0ad899 100644 --- a/Engine.Systems/Time/Ticker.cs +++ b/Engine.Systems/Time/TickerStopwatch.cs @@ -2,14 +2,14 @@ using Syntriax.Engine.Core; namespace Syntriax.Engine.Systems.Time; -public class Ticker : Stopwatch, ITicker +public class TickerStopwatch : Stopwatch, ITicker { public Event OnTick { get; } = new(); public double Period { get; set; } = 1f; public int TickCounter { get; private set; } = 0; - private double nextTick = 0f; + private double nextTick = double.MaxValue; public override void Start() { @@ -22,7 +22,7 @@ public class Ticker : Stopwatch, ITicker { base.Update(); - while (Time > nextTick) + while (Time >= nextTick) { nextTick += Period; TickCounter++; diff --git a/Engine.Systems/Time/TickerTimer.cs b/Engine.Systems/Time/TickerTimer.cs new file mode 100644 index 0000000..ec011c4 --- /dev/null +++ b/Engine.Systems/Time/TickerTimer.cs @@ -0,0 +1,40 @@ +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Time; + +public class TickerTimer : Timer, ITicker +{ + public Event OnTick { get; } = new(); + + public double Period { get; set; } = 1f; + public int TickCounter { get; private set; } = 0; + + private double nextTick = double.MinValue; + + public override void Start(double time) + { + TickCounter = 0; + base.Start(time); + nextTick = Remaining - Period; + } + + public override void Update() + { + base.Update(); + + while (Remaining <= nextTick) + { + nextTick -= Period; + TickCounter++; + OnTick?.Invoke(this); + } + } + + protected override void OnFinalize() + { + base.OnFinalize(); + + TickCounter = 0; + nextTick = 0f; + } +} diff --git a/Engine.Systems/Time/Timer.cs b/Engine.Systems/Time/Timer.cs index 45c01fb..2c8faa1 100644 --- a/Engine.Systems/Time/Timer.cs +++ b/Engine.Systems/Time/Timer.cs @@ -53,7 +53,7 @@ public class Timer : Behaviour, IUpdate, ITimer OnStopped?.Invoke(this); } - public void Update() + public virtual void Update() { if (State is not TimerState.Ticking) return; -- 2.49.1 From f8fbae613082a1e0c9a85a37cd8931548a385d6d Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 26 Jul 2025 11:55:40 +0300 Subject: [PATCH 35/91] feat: added HSVA --- Engine.Core/Primitives/ColorHSV.cs | 36 +--- Engine.Core/Primitives/ColorHSVA.cs | 189 ++++++++++++++++++ Engine.Core/Primitives/ColorRGB.cs | 26 +-- Engine.Core/Primitives/ColorRGBA.cs | 26 ++- .../EngineExtensions/TweenColorExtensions.cs | 7 +- 5 files changed, 224 insertions(+), 60 deletions(-) create mode 100644 Engine.Core/Primitives/ColorHSVA.cs diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index cec3064..85e88b2 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -37,39 +37,9 @@ public readonly struct ColorHSV(float hue, float saturation, float value) public static bool operator ==(ColorHSV left, ColorHSV right) => left.Hue == right.Hue && left.Saturation == right.Saturation && left.Value == right.Value; public static bool operator !=(ColorHSV left, ColorHSV right) => left.Hue != right.Hue || left.Saturation != right.Saturation || left.Value != right.Value; - public static implicit operator ColorHSV(ColorRGBA rgba) => (ColorRGB)rgba; - public static implicit operator ColorHSV(ColorRGB rgb) - { - float hue; - float saturation; - float value; - - float rd = rgb.R / 255f; - float gd = rgb.G / 255f; - float bd = rgb.B / 255f; - - float max = Math.Max(rd, Math.Max(gd, bd)); - float min = Math.Min(rd, Math.Min(gd, bd)); - float delta = max - min; - - if (delta.ApproximatelyEquals(0)) - hue = 0f; - else if (max.ApproximatelyEquals(rd)) - hue = 60f * ((gd - bd) / delta % 6f); - else if (max.ApproximatelyEquals(gd)) - hue = 60f * (((bd - rd) / delta) + 2f); - else - hue = 60f * (((rd - gd) / delta) + 4f); - - if (hue < 0f) - hue += 360f; - - hue /= 360f; - saturation = max.ApproximatelyEquals(0f) ? 0f : delta / max; - value = max; - - return new(hue, saturation, value); - } + public static implicit operator ColorHSV(ColorHSVA hsva) => new(hsva.Hue, hsva.Saturation, hsva.Value); + public static implicit operator ColorHSV(ColorRGBA rgba) => (ColorHSVA)rgba; + public static implicit operator ColorHSV(ColorRGB rgb) => (ColorHSVA)rgb; /// /// Inverts the given . diff --git a/Engine.Core/Primitives/ColorHSVA.cs b/Engine.Core/Primitives/ColorHSVA.cs new file mode 100644 index 0000000..ee49c6a --- /dev/null +++ b/Engine.Core/Primitives/ColorHSVA.cs @@ -0,0 +1,189 @@ +namespace Syntriax.Engine.Core; + +/// +/// Represents an HSV color. +/// +/// Hue of the . +/// Saturation of the . +/// Value of the . +/// Alpha of the . +/// +/// Initializes a new instance of the struct with the specified values. +/// +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly struct ColorHSVA(float hue, float saturation, float value, float alpha = 1) +{ + /// + /// The Hue value of the . + /// + public readonly float Hue = hue.Clamp(0f, 1f); + + /// + /// The Saturation value of the . + /// + public readonly float Saturation = saturation.Clamp(0f, 1f); + + /// + /// The Value value of the . + /// + public readonly float Value = value.Clamp(0f, 1f); + + /// + /// The Alpha value of the . + /// + public readonly float Alpha = alpha; + + public static ColorHSVA operator -(ColorHSVA color) => new(color.Hue.OneMinus(), color.Saturation.OneMinus(), color.Value.OneMinus(), color.Alpha); + public static ColorHSVA operator +(ColorHSVA left, ColorHSVA right) => new(left.Hue + right.Hue, left.Saturation + right.Saturation, left.Value + right.Value, left.Alpha + right.Alpha); + public static ColorHSVA operator -(ColorHSVA left, ColorHSVA right) => new(left.Hue - right.Hue, left.Saturation - right.Saturation, left.Value - right.Value, left.Alpha - right.Alpha); + public static ColorHSVA operator *(ColorHSVA left, ColorHSVA right) => new(left.Hue * right.Hue, left.Saturation * right.Saturation, left.Value * right.Value, left.Alpha * right.Alpha); + public static ColorHSVA operator *(ColorHSVA color, float value) => new(color.Hue * value, color.Saturation * value, color.Value * value, color.Alpha * value); + public static ColorHSVA operator *(float value, ColorHSVA color) => new(color.Hue * value, color.Saturation * value, color.Value * value, color.Alpha * value); + public static ColorHSVA operator /(ColorHSVA color, float value) => new(color.Hue / value, color.Saturation / value, color.Value / value, color.Alpha / value); + public static bool operator ==(ColorHSVA left, ColorHSVA right) => left.Hue == right.Hue && left.Saturation == right.Saturation && left.Value == right.Value; + public static bool operator !=(ColorHSVA left, ColorHSVA right) => left.Hue != right.Hue || left.Saturation != right.Saturation || left.Value != right.Value; + + public static implicit operator ColorHSVA(ColorHSV hsv) => new(hsv.Hue, hsv.Saturation, hsv.Value, 1f); + public static implicit operator ColorHSVA(ColorRGB rgb) => (ColorRGBA)rgb; + public static implicit operator ColorHSVA(ColorRGBA rgba) + { + float hue; + float saturation; + float value; + + float rd = rgba.R / 255f; + float gd = rgba.G / 255f; + float bd = rgba.B / 255f; + + float max = Math.Max(rd, Math.Max(gd, bd)); + float min = Math.Min(rd, Math.Min(gd, bd)); + float delta = max - min; + + if (delta.ApproximatelyEquals(0)) + hue = 0f; + else if (max.ApproximatelyEquals(rd)) + hue = 60f * ((gd - bd) / delta % 6f); + else if (max.ApproximatelyEquals(gd)) + hue = 60f * (((bd - rd) / delta) + 2f); + else + hue = 60f * (((rd - gd) / delta) + 4f); + + if (hue < 0f) + hue += 360f; + + hue /= 360f; + saturation = max.ApproximatelyEquals(0f) ? 0f : delta / max; + value = max; + + return new(hue, saturation, value, rgba.A / 255f); + } + + /// + /// Inverts the given . + /// + /// The . + /// The inverted . + public static ColorHSVA Invert(ColorHSVA color) => -color; + + /// + /// Adds two s. + /// + /// The first . + /// The second . + /// The sum of the two s. + public static ColorHSVA Add(ColorHSVA left, ColorHSVA right) => left + right; + + /// + /// Subtracts one from another. + /// + /// The to subtract from. + /// The to subtract. + /// The result of subtracting the second from the first. + public static ColorHSVA Subtract(ColorHSVA left, ColorHSVA right) => left - right; + + /// + /// Multiplies a by a scalar value. + /// + /// The . + /// The scalar value. + /// The result of multiplying the by the scalar value. + public static ColorHSVA Multiply(ColorHSVA color, float value) => color * value; + + /// + /// Divides a by a scalar value. + /// + /// The . + /// The scalar value. + /// The result of dividing the by the scalar value. + public static ColorHSVA Divide(ColorHSVA color, float value) => color / value; + + /// + /// Performs linear interpolation between two s. + /// + /// The starting (t = 0). + /// The ending (t = 1). + /// The interpolation parameter. + /// The interpolated . + public static ColorHSVA Lerp(ColorHSVA from, ColorHSVA to, float t) + { + float hueDiff = to.Hue - from.Hue; + float saturationDiff = to.Saturation - from.Saturation; + float valueDiff = to.Value - from.Value; + float alphaDiff = to.Alpha - from.Alpha; + + return from + new ColorHSVA(hueDiff * t, saturationDiff * t, valueDiff * t, alphaDiff * t); + } + + /// + /// Checks if two s are approximately equal within a specified epsilon range. + /// + /// The first . + /// The second . + /// The epsilon range. + /// if the s are approximately equal; otherwise, . + public static bool ApproximatelyEquals(ColorHSVA left, ColorHSVA right, float epsilon = float.Epsilon) + => left.Hue.ApproximatelyEquals(right.Hue, epsilon) && left.Saturation.ApproximatelyEquals(right.Saturation, epsilon) && left.Value.ApproximatelyEquals(right.Value, epsilon); + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is ColorHSVA colorHSVA && this == colorHSVA; + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(Hue, Saturation, Value); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(ColorHSVA)}({Hue}, {Saturation}, {Value})"; +} + +/// +/// Provides extension methods for type. +/// +public static class ColorHSVAExtensions +{ + /// + public static ColorHSVA Add(this ColorHSVA color, ColorHSVA value) => ColorHSVA.Add(color, value); + + /// + public static ColorHSVA Subtract(this ColorHSVA color, ColorHSVA value) => ColorHSVA.Subtract(color, value); + + /// + public static ColorHSVA Multiply(this ColorHSVA color, float value) => ColorHSVA.Multiply(color, value); + + /// + public static ColorHSVA Divide(this ColorHSVA color, float value) => ColorHSVA.Divide(color, value); + + /// + public static ColorHSVA Lerp(this ColorHSVA from, ColorHSVA to, float t) => ColorHSVA.Lerp(from, to, t); + + /// + public static bool ApproximatelyEquals(this ColorHSVA left, ColorHSVA right, float epsilon = float.Epsilon) => ColorHSVA.ApproximatelyEquals(left, right, epsilon); +} diff --git a/Engine.Core/Primitives/ColorRGB.cs b/Engine.Core/Primitives/ColorRGB.cs index ad52500..e5460f8 100644 --- a/Engine.Core/Primitives/ColorRGB.cs +++ b/Engine.Core/Primitives/ColorRGB.cs @@ -38,30 +38,8 @@ public readonly struct ColorRGB(byte r, byte g, byte b) public static bool operator !=(ColorRGB left, ColorRGB right) => left.R != right.R || left.G != right.G || left.B != right.B; public static implicit operator ColorRGB(ColorRGBA rgba) => new(rgba.R, rgba.G, rgba.B); - public static implicit operator ColorRGB(ColorHSV hsv) - { - float hue = hsv.Hue * 360f; - float chroma = hsv.Value * hsv.Saturation; - float x = chroma * (1f - Math.Abs(hue / 60f % 2f - 1f)); - float m = hsv.Value - chroma; - - float r1 = 0f; - float g1 = 0f; - float b1 = 0f; - - if (hue < 60) { r1 = chroma; g1 = x; b1 = 0; } - else if (hue < 120) { r1 = x; g1 = chroma; b1 = 0; } - else if (hue < 180) { r1 = 0; g1 = chroma; b1 = x; } - else if (hue < 240) { r1 = 0; g1 = x; b1 = chroma; } - else if (hue < 300) { r1 = x; g1 = 0; b1 = chroma; } - else if (hue <= 360) { r1 = chroma; g1 = 0; b1 = x; } - - byte r = (byte)Math.RoundToInt((r1 + m) * 255); - byte g = (byte)Math.RoundToInt((g1 + m) * 255); - byte b = (byte)Math.RoundToInt((b1 + m) * 255); - - return new(r, g, b); - } + public static implicit operator ColorRGB(ColorHSVA hsva) => (ColorRGBA)hsva; + public static implicit operator ColorRGB(ColorHSV hsv) => (ColorRGBA)hsv; /// /// Inverts the given . diff --git a/Engine.Core/Primitives/ColorRGBA.cs b/Engine.Core/Primitives/ColorRGBA.cs index 9a1b285..67b6464 100644 --- a/Engine.Core/Primitives/ColorRGBA.cs +++ b/Engine.Core/Primitives/ColorRGBA.cs @@ -44,7 +44,31 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) public static bool operator !=(ColorRGBA left, ColorRGBA right) => left.R != right.R || left.G != right.G || left.B != right.B || left.A != right.A; public static implicit operator ColorRGBA(ColorRGB rgb) => new(rgb.R, rgb.G, rgb.B, 255); - public static implicit operator ColorRGBA(ColorHSV hsv) => (ColorRGB)hsv; + public static implicit operator ColorRGBA(ColorHSV hsv) => (ColorHSVA)hsv; + public static implicit operator ColorRGBA(ColorHSVA hsva) + { + float hue = hsva.Hue * 360f; + float chroma = hsva.Value * hsva.Saturation; + float x = chroma * (1f - Math.Abs(hue / 60f % 2f - 1f)); + float m = hsva.Value - chroma; + + float r1 = 0f; + float g1 = 0f; + float b1 = 0f; + + if (hue < 60) { r1 = chroma; g1 = x; b1 = 0; } + else if (hue < 120) { r1 = x; g1 = chroma; b1 = 0; } + else if (hue < 180) { r1 = 0; g1 = chroma; b1 = x; } + else if (hue < 240) { r1 = 0; g1 = x; b1 = chroma; } + else if (hue < 300) { r1 = x; g1 = 0; b1 = chroma; } + else if (hue <= 360) { r1 = chroma; g1 = 0; b1 = x; } + + byte r = (byte)Math.RoundToInt((r1 + m) * 255); + byte g = (byte)Math.RoundToInt((g1 + m) * 255); + byte b = (byte)Math.RoundToInt((b1 + m) * 255); + + return new(r, g, b, (byte)(hsva.Alpha * 255)); + } /// /// Inverts the given . diff --git a/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs index 9a3b886..03b0e35 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs @@ -5,11 +5,14 @@ namespace Syntriax.Engine.Systems.Tween; public static class TweenColorExtensions { public static ITween TweenColor(this ColorRGB initialColorRGB, ITweenManager tweenManager, float duration, ColorRGB targetColorRGB, System.Action setMethod) - => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorRGB.Lerp(targetColorRGB, t))); + => TweenColor((ColorHSV)initialColorRGB, tweenManager, duration, (ColorHSV)targetColorRGB, color => setMethod?.Invoke(color)); public static ITween TweenColor(this ColorRGBA initialColorRGBA, ITweenManager tweenManager, float duration, ColorRGBA targetColorRGBA, System.Action setMethod) - => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorRGBA.Lerp(targetColorRGBA, t))); + => TweenColor((ColorHSVA)initialColorRGBA, tweenManager, duration, (ColorHSVA)targetColorRGBA, color => setMethod?.Invoke(color)); public static ITween TweenColor(this ColorHSV initialColorHSV, ITweenManager tweenManager, float duration, ColorHSV targetColorHSV, System.Action setMethod) => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorHSV.Lerp(targetColorHSV, t))); + + public static ITween TweenColor(this ColorHSVA initialColorHSVA, ITweenManager tweenManager, float duration, ColorHSVA targetColorHSVA, System.Action setMethod) + => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorHSVA.Lerp(targetColorHSVA, t))); } -- 2.49.1 From 08311acc9a96e4e155211ac82d7a586b3d1e0c13 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 26 Jul 2025 11:58:23 +0300 Subject: [PATCH 36/91] chore!: removed FromTo methods from colors --- Engine.Core/Primitives/ColorHSV.cs | 11 ----------- Engine.Core/Primitives/ColorRGB.cs | 11 ----------- Engine.Core/Primitives/ColorRGBA.cs | 11 ----------- 3 files changed, 33 deletions(-) diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index 85e88b2..1772e64 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -80,14 +80,6 @@ public readonly struct ColorHSV(float hue, float saturation, float value) /// The result of dividing the by the scalar value. public static ColorHSV Divide(ColorHSV color, float value) => color / value; - /// - /// Calculates the from one point to another. - /// - /// The starting point. - /// The ending point. - /// The from the starting point to the ending point. - public static ColorHSV FromTo(ColorHSV from, ColorHSV to) => to - from; - /// /// Performs linear interpolation between two s. /// @@ -144,9 +136,6 @@ public static class ColorHSVExtensions /// public static ColorHSV Divide(this ColorHSV color, float value) => ColorHSV.Divide(color, value); - /// - public static ColorHSV FromTo(this ColorHSV from, ColorHSV to) => ColorHSV.FromTo(from, to); - /// public static ColorHSV Lerp(this ColorHSV from, ColorHSV to, float t) => ColorHSV.Lerp(from, to, t); diff --git a/Engine.Core/Primitives/ColorRGB.cs b/Engine.Core/Primitives/ColorRGB.cs index e5460f8..1171a17 100644 --- a/Engine.Core/Primitives/ColorRGB.cs +++ b/Engine.Core/Primitives/ColorRGB.cs @@ -80,14 +80,6 @@ public readonly struct ColorRGB(byte r, byte g, byte b) /// The result of dividing the by the scalar value. public static ColorRGB Divide(ColorRGB color, float value) => color / value; - /// - /// Calculates the from one point to another. - /// - /// The starting point. - /// The ending point. - /// The from the starting point to the ending point. - public static ColorRGB FromTo(ColorRGB from, ColorRGB to) => to - from; - /// /// Performs linear interpolation between two s. /// @@ -134,9 +126,6 @@ public static class ColorRGBExtensions /// public static ColorRGB Divide(this ColorRGB color, float value) => ColorRGB.Divide(color, value); - /// - public static ColorRGB FromTo(this ColorRGB from, ColorRGB to) => ColorRGB.FromTo(from, to); - /// public static ColorRGB Lerp(this ColorRGB from, ColorRGB to, float t) => ColorRGB.Lerp(from, to, t); } diff --git a/Engine.Core/Primitives/ColorRGBA.cs b/Engine.Core/Primitives/ColorRGBA.cs index 67b6464..2e7deb5 100644 --- a/Engine.Core/Primitives/ColorRGBA.cs +++ b/Engine.Core/Primitives/ColorRGBA.cs @@ -109,14 +109,6 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) /// The result of dividing the by the scalar value. public static ColorRGBA Divide(ColorRGBA color, float value) => color / value; - /// - /// Calculates the from one point to another. - /// - /// The starting point. - /// The ending point. - /// The from the starting point to the ending point. - public static ColorRGBA FromTo(ColorRGBA from, ColorRGBA to) => to - from; - /// /// Performs linear interpolation between two s. /// @@ -163,9 +155,6 @@ public static class ColorRGBAExtensions /// public static ColorRGBA Divide(this ColorRGBA color, float value) => ColorRGBA.Divide(color, value); - /// - public static ColorRGBA FromTo(this ColorRGBA from, ColorRGBA to) => ColorRGBA.FromTo(from, to); - /// public static ColorRGBA Lerp(this ColorRGBA from, ColorRGBA to, float t) => ColorRGBA.Lerp(from, to, t); } -- 2.49.1 From 65eac57fce9722a9972edc80493ebad427173500 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 26 Jul 2025 11:59:04 +0300 Subject: [PATCH 37/91] fix: color lerp methods fixed --- Engine.Core/Primitives/ColorHSV.cs | 9 ++++++++- Engine.Core/Primitives/ColorRGB.cs | 9 ++++++++- Engine.Core/Primitives/ColorRGBA.cs | 10 +++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index 1772e64..22af2a0 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -87,7 +87,14 @@ public readonly struct ColorHSV(float hue, float saturation, float value) /// The ending (t = 1). /// The interpolation parameter. /// The interpolated . - public static ColorHSV Lerp(ColorHSV from, ColorHSV to, float t) => from + FromTo(from, to) * t; + public static ColorHSV Lerp(ColorHSV from, ColorHSV to, float t) + { + float hueDiff = to.Hue - from.Hue; + float saturationDiff = to.Saturation - from.Saturation; + float valueDiff = to.Value - from.Value; + + return from + new ColorHSV(hueDiff * t, saturationDiff * t, valueDiff * t); + } /// /// Checks if two s are approximately equal within a specified epsilon range. diff --git a/Engine.Core/Primitives/ColorRGB.cs b/Engine.Core/Primitives/ColorRGB.cs index 1171a17..67c0d99 100644 --- a/Engine.Core/Primitives/ColorRGB.cs +++ b/Engine.Core/Primitives/ColorRGB.cs @@ -87,7 +87,14 @@ public readonly struct ColorRGB(byte r, byte g, byte b) /// The ending (t = 1). /// The interpolation parameter. /// The interpolated . - public static ColorRGB Lerp(ColorRGB from, ColorRGB to, float t) => from + FromTo(from, to) * t; + public static ColorRGB Lerp(ColorRGB from, ColorRGB to, float t) + { + int redDiff = to.R - from.R; + int greenDiff = to.G - from.G; + int blueDiff = to.B - from.B; + + return from + new ColorRGB((byte)(redDiff * t), (byte)(greenDiff * t), (byte)(blueDiff * t)); + } /// /// Determines whether the specified object is equal to the current . diff --git a/Engine.Core/Primitives/ColorRGBA.cs b/Engine.Core/Primitives/ColorRGBA.cs index 2e7deb5..ea512a4 100644 --- a/Engine.Core/Primitives/ColorRGBA.cs +++ b/Engine.Core/Primitives/ColorRGBA.cs @@ -116,7 +116,15 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) /// The ending (t = 1). /// The interpolation parameter. /// The interpolated . - public static ColorRGBA Lerp(ColorRGBA from, ColorRGBA to, float t) => from + FromTo(from, to) * t; + public static ColorRGBA Lerp(ColorRGBA from, ColorRGBA to, float t) + { + int redDiff = to.R - from.R; + int greenDiff = to.G - from.G; + int blueDiff = to.B - from.B; + int alphaDiff = to.A - from.A; + + return from + new ColorRGBA((byte)(redDiff * t), (byte)(greenDiff * t), (byte)(blueDiff * t), (byte)(alphaDiff * t)); + } /// /// Determines whether the specified object is equal to the current . -- 2.49.1 From 9f4d95a57be3fa33f023b66a5f543ee85bb31c5d Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 26 Jul 2025 11:59:36 +0300 Subject: [PATCH 38/91] perf: removed unnecessary operations on hsv colors --- Engine.Core/Primitives/ColorHSV.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index 22af2a0..6fb9b2c 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -27,13 +27,13 @@ public readonly struct ColorHSV(float hue, float saturation, float value) /// public readonly float Value = value.Clamp(0f, 1f); - public static ColorHSV operator -(ColorHSV color) => new(color.Hue.OneMinus().Clamp(0f, 1f), color.Saturation.OneMinus().Clamp(0f, 1f), color.Value.OneMinus().Clamp(0f, 1f)); - public static ColorHSV operator +(ColorHSV left, ColorHSV right) => new((left.Hue + right.Hue).Clamp(0f, 1f), (left.Saturation + right.Saturation).Clamp(0f, 1f), (left.Value + right.Value).Clamp(0f, 1f)); - public static ColorHSV operator -(ColorHSV left, ColorHSV right) => new((left.Hue - right.Hue).Clamp(0f, 1f), (left.Saturation - right.Saturation).Clamp(0f, 1f), (left.Value - right.Value).Clamp(0f, 1f)); - public static ColorHSV operator *(ColorHSV left, ColorHSV right) => new((left.Hue * right.Hue).Clamp(0f, 1f), (left.Saturation * right.Saturation).Clamp(0f, 1f), (left.Value * right.Value).Clamp(0f, 1f)); - public static ColorHSV operator *(ColorHSV color, float value) => new((color.Hue * value).Clamp(0f, 1f), (color.Saturation * value).Clamp(0f, 1f), (color.Value * value).Clamp(0f, 1f)); - public static ColorHSV operator *(float value, ColorHSV color) => new((color.Hue * value).Clamp(0f, 1f), (color.Saturation * value).Clamp(0f, 1f), (color.Value * value).Clamp(0f, 1f)); - public static ColorHSV operator /(ColorHSV color, float value) => new((color.Hue / value).Clamp(0f, 1f), (color.Saturation / value).Clamp(0f, 1f), (color.Value / value).Clamp(0f, 1f)); + public static ColorHSV operator -(ColorHSV color) => new(color.Hue.OneMinus(), color.Saturation.OneMinus(), color.Value.OneMinus()); + public static ColorHSV operator +(ColorHSV left, ColorHSV right) => new(left.Hue + right.Hue, left.Saturation + right.Saturation, left.Value + right.Value); + public static ColorHSV operator -(ColorHSV left, ColorHSV right) => new(left.Hue - right.Hue, left.Saturation - right.Saturation, left.Value - right.Value); + public static ColorHSV operator *(ColorHSV left, ColorHSV right) => new(left.Hue * right.Hue, left.Saturation * right.Saturation, left.Value * right.Value); + public static ColorHSV operator *(ColorHSV color, float value) => new(color.Hue * value, color.Saturation * value, color.Value * value); + public static ColorHSV operator *(float value, ColorHSV color) => new(color.Hue * value, color.Saturation * value, color.Value * value); + public static ColorHSV operator /(ColorHSV color, float value) => new(color.Hue / value, color.Saturation / value, color.Value / value); public static bool operator ==(ColorHSV left, ColorHSV right) => left.Hue == right.Hue && left.Saturation == right.Saturation && left.Value == right.Value; public static bool operator !=(ColorHSV left, ColorHSV right) => left.Hue != right.Hue || left.Saturation != right.Saturation || left.Value != right.Value; -- 2.49.1 From 37aca44e45923511500ee1e6a8f39a30810b7f63 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 26 Jul 2025 12:03:28 +0300 Subject: [PATCH 39/91] feat: monogame premultiplied color extension method added --- .../Engine.Integration.MonoGame/EngineConverter.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs b/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs index 4a10da4..cea1b55 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs @@ -19,6 +19,12 @@ public static class EngineConverterExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Color ToColor(this ColorRGBA color) => new(color.R, color.G, color.B, color.A); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color ToPreMultipliedColor(this ColorRGBA color) + { + float alphaMultiplier = color.A / 255f; + return new((byte)(color.R * alphaMultiplier), (byte)(color.G * alphaMultiplier), (byte)(color.B * alphaMultiplier), color.A); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ColorRGBA ToColorRGBA(this Color color) => new(color.R, color.G, color.B, color.A); -- 2.49.1 From 03232f72e8f045fa3b5731a2b3839425f8ea9721 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 27 Jul 2025 19:01:50 +0300 Subject: [PATCH 40/91] fix: LogTrace not having an optional stack trace parameter --- Engine.Core/Debug/LoggerExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Core/Debug/LoggerExtensions.cs b/Engine.Core/Debug/LoggerExtensions.cs index 90a7bae..bc58c3d 100644 --- a/Engine.Core/Debug/LoggerExtensions.cs +++ b/Engine.Core/Debug/LoggerExtensions.cs @@ -29,7 +29,7 @@ public static class LoggerExtensions Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{exception.StackTrace}", ILogger.Level.Trace); } - public static void LogTrace(this ILogger logger, T caller, StackTrace stackTrace, bool force = false) + public static void LogTrace(this ILogger logger, T caller, StackTrace? stackTrace = null, bool force = false) { Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{stackTrace ?? new()}", ILogger.Level.Trace, force); } -- 2.49.1 From f6e52abcc1535be49315cffe05e69473d6f09ec5 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 2 Aug 2025 23:24:59 +0300 Subject: [PATCH 41/91] feat: testing universe entrance manager --- .../Systems/Abstract/IEnterUniverse.cs | 6 ++ Engine.Core/Systems/Abstract/IExitUniverse.cs | 6 ++ .../Systems/UniverseEntranceManager.cs | 71 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 Engine.Core/Systems/Abstract/IEnterUniverse.cs create mode 100644 Engine.Core/Systems/Abstract/IExitUniverse.cs create mode 100644 Engine.Core/Systems/UniverseEntranceManager.cs diff --git a/Engine.Core/Systems/Abstract/IEnterUniverse.cs b/Engine.Core/Systems/Abstract/IEnterUniverse.cs new file mode 100644 index 0000000..f7d67a1 --- /dev/null +++ b/Engine.Core/Systems/Abstract/IEnterUniverse.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IEnterUniverse : IBehaviour +{ + void EnterUniverse(IUniverse universe); +} diff --git a/Engine.Core/Systems/Abstract/IExitUniverse.cs b/Engine.Core/Systems/Abstract/IExitUniverse.cs new file mode 100644 index 0000000..b8c3db1 --- /dev/null +++ b/Engine.Core/Systems/Abstract/IExitUniverse.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IExitUniverse : IBehaviour +{ + void ExitUniverse(IUniverse universe); +} diff --git a/Engine.Core/Systems/UniverseEntranceManager.cs b/Engine.Core/Systems/UniverseEntranceManager.cs new file mode 100644 index 0000000..6df3d96 --- /dev/null +++ b/Engine.Core/Systems/UniverseEntranceManager.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; + +namespace Syntriax.Engine.Core; + +public class UniverseEntranceManager : Behaviour +{ + // We use Ascending order because we are using reverse for loop to call them + private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + + private readonly ActiveBehaviourCollectorSorted enterUniverses = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorSorted exitUniverses = new() { SortBy = SortByAscendingPriority() }; + + private readonly List toCallEnterUniverses = new(32); + private readonly List toCallExitUniverses = new(32); + + protected override void OnEnteredUniverse(IUniverse universe) + { + enterUniverses.Assign(universe); + + foreach (IUniverseObject universeObject in Universe.UniverseObjects) + OnUniverseObjectRegistered(Universe, new(universeObject)); + + universe.OnUniverseObjectRegistered.AddListener(OnUniverseObjectRegistered); + universe.OnUniverseObjectUnRegistered.AddListener(OnUniverseObjectUnRegistered); + } + + protected override void OnExitedUniverse(IUniverse universe) + { + enterUniverses.Unassign(); + + foreach (IUniverseObject universeObject in Universe.UniverseObjects) + OnUniverseObjectUnRegistered(Universe, new(universeObject)); + + universe.OnUniverseObjectRegistered.RemoveListener(OnUniverseObjectRegistered); + universe.OnUniverseObjectUnRegistered.RemoveListener(OnUniverseObjectUnRegistered); + } + + private void OnUniverseObjectUnRegistered(IUniverse sender, IUniverse.UniverseObjectUnRegisteredArguments args) + { + for (int i = toCallExitUniverses.Count - 1; i >= 0; i--) + { + toCallExitUniverses[i].ExitUniverse(Universe); + toCallExitUniverses.RemoveAt(i); + } + } + + private void OnUniverseObjectRegistered(IUniverse sender, IUniverse.UniverseObjectRegisteredArguments args) + { + for (int i = toCallEnterUniverses.Count - 1; i >= 0; i--) + { + toCallEnterUniverses[i].EnterUniverse(Universe); + toCallEnterUniverses.RemoveAt(i); + } + } + + private void OnEnterUniverseCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) + { + toCallEnterUniverses.Add(args.BehaviourCollected); + } + + private void OnExitUniverseCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) + { + toCallExitUniverses.Add(args.BehaviourCollected); + } + + public UniverseEntranceManager() + { + enterUniverses.OnCollected.AddListener(OnEnterUniverseCollected); + exitUniverses.OnCollected.AddListener(OnExitUniverseCollected); + } +} -- 2.49.1 From 93a79cd0757ec6fc6b719e804ba0ae40d1f025c4 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 3 Aug 2025 09:22:22 +0300 Subject: [PATCH 42/91] feat: universe pre register and unregister events --- Engine.Core/Abstract/IUniverse.cs | 10 ++++++++++ Engine.Core/Universe.cs | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/Engine.Core/Abstract/IUniverse.cs b/Engine.Core/Abstract/IUniverse.cs index 116967b..5f99c8c 100644 --- a/Engine.Core/Abstract/IUniverse.cs +++ b/Engine.Core/Abstract/IUniverse.cs @@ -37,11 +37,21 @@ public interface IUniverse : IEntity, IEnumerable /// Event OnPostDraw { get; } + /// + /// Event triggered when a is about to be registered to the . + /// + Event OnPreUniverseObjectRegistered { get; } + /// /// Event triggered when a is registered to the . /// Event OnUniverseObjectRegistered { get; } + /// + /// Event triggered when a is about to be unregistered from the . + /// + Event OnPreUniverseObjectUnRegistered { get; } + /// /// Event triggered when a is unregistered from the . /// diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index f0f82a4..f60c7ae 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -13,7 +13,9 @@ public class Universe : BaseEntity, IUniverse public Event OnPreDraw { get; } = new(); public Event OnDraw { get; } = new(); public Event OnPostDraw { get; } = new(); + public Event OnPreUniverseObjectRegistered { get; } = new(); public Event OnUniverseObjectRegistered { get; } = new(); + public Event OnPreUniverseObjectUnRegistered { get; } = new(); public Event OnUniverseObjectUnRegistered { get; } = new(); public Event OnTimeScaleChanged { get; } = new(); @@ -53,6 +55,8 @@ public class Universe : BaseEntity, IUniverse if (_universeObjects.Contains(universeObject)) throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is already registered to the {nameof(Universe)}."); + OnPreUniverseObjectRegistered?.Invoke(this, new(universeObject)); + universeObject.OnFinalized.AddListener(delegateOnUniverseObjectFinalize); universeObject.OnExitedUniverse.AddListener(delegateOnUniverseObjectExitedUniverse); @@ -88,6 +92,8 @@ public class Universe : BaseEntity, IUniverse if (!_universeObjects.Contains(universeObject)) throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is not registered to the {nameof(Universe)}."); + OnPreUniverseObjectUnRegistered?.Invoke(this, new(universeObject)); + universeObject.OnFinalized.RemoveListener(delegateOnUniverseObjectFinalize); universeObject.OnExitedUniverse.RemoveListener(delegateOnUniverseObjectExitedUniverse); -- 2.49.1 From 9824980cbfc22b543c9cdcee270c7ee1dd26b8f0 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 3 Aug 2025 09:23:30 +0300 Subject: [PATCH 43/91] chore!: behaviour collector now removes behaviours on pre unregister --- Engine.Core/BehaviourCollector.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine.Core/BehaviourCollector.cs b/Engine.Core/BehaviourCollector.cs index 19d8782..4eedb67 100644 --- a/Engine.Core/BehaviourCollector.cs +++ b/Engine.Core/BehaviourCollector.cs @@ -76,7 +76,7 @@ public class BehaviourCollector : IBehaviourCollector where T : class OnUniverseObjectRegistered(universe, new(universeObject)); universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered); - universe.OnUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); + universe.OnPreUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); Universe = universe; OnAssign(universe); @@ -94,7 +94,7 @@ public class BehaviourCollector : IBehaviourCollector where T : class OnUniverseObjectUnregistered(Universe, new(universeObject)); Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered); - Universe.OnUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); + Universe.OnPreUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); Universe = null!; OnUnassigned?.Invoke(this); -- 2.49.1 From b8217f2106dd056c0a1d9eb591e2513e466b2389 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 3 Aug 2025 09:43:18 +0300 Subject: [PATCH 44/91] feat: last active frame interface --- Engine.Core/Systems/Abstract/ILastFrameUpdate.cs | 6 ++++++ Engine.Core/Systems/UpdateManager.cs | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 Engine.Core/Systems/Abstract/ILastFrameUpdate.cs diff --git a/Engine.Core/Systems/Abstract/ILastFrameUpdate.cs b/Engine.Core/Systems/Abstract/ILastFrameUpdate.cs new file mode 100644 index 0000000..9957da1 --- /dev/null +++ b/Engine.Core/Systems/Abstract/ILastFrameUpdate.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface ILastFrameUpdate : IBehaviour +{ + void LastActiveFrame(); +} diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index 20e5f58..0777f47 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -8,6 +8,7 @@ public class UpdateManager : Behaviour private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); private readonly ActiveBehaviourCollectorSorted firstFrameUpdates = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollector lastFrameUpdates = new(); private readonly ActiveBehaviourCollectorSorted preUpdateEntities = new() { SortBy = SortByAscendingPriority() }; private readonly ActiveBehaviourCollectorSorted updateEntities = new() { SortBy = SortByAscendingPriority() }; private readonly ActiveBehaviourCollectorSorted postUpdateEntities = new() { SortBy = SortByAscendingPriority() }; @@ -17,6 +18,7 @@ public class UpdateManager : Behaviour protected override void OnEnteredUniverse(IUniverse universe) { firstFrameUpdates.Assign(universe); + lastFrameUpdates.Assign(universe); preUpdateEntities.Assign(universe); updateEntities.Assign(universe); postUpdateEntities.Assign(universe); @@ -29,6 +31,7 @@ public class UpdateManager : Behaviour protected override void OnExitedUniverse(IUniverse universe) { firstFrameUpdates.Unassign(); + lastFrameUpdates.Unassign(); preUpdateEntities.Unassign(); updateEntities.Unassign(); postUpdateEntities.Unassign(); @@ -67,8 +70,14 @@ public class UpdateManager : Behaviour toCallFirstFrameUpdates.Add(args.BehaviourCollected); } + private void OnLastFrameRemoved(IBehaviourCollector sender, IBehaviourCollector.BehaviourRemovedArguments args) + { + args.BehaviourRemoved.LastActiveFrame(); + } + public UpdateManager() { firstFrameUpdates.OnCollected.AddListener(OnFirstFrameCollected); + lastFrameUpdates.OnRemoved.AddListener(OnLastFrameRemoved); } } -- 2.49.1 From 6e87c67096d88be6754de46e278d4147a0de70ae Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 4 Aug 2025 14:45:00 +0300 Subject: [PATCH 45/91] fix: wrong assert messages are corrected --- Engine.Core/Debug/AssertHelpers.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Engine.Core/Debug/AssertHelpers.cs b/Engine.Core/Debug/AssertHelpers.cs index 0da4bc9..426ca43 100644 --- a/Engine.Core/Debug/AssertHelpers.cs +++ b/Engine.Core/Debug/AssertHelpers.cs @@ -10,21 +10,21 @@ public static class Assert [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AssertBehaviourControllerAssigned(IHasBehaviourController assignable) - => System.Diagnostics.Debug.Assert(assignable.BehaviourController is not null, $"{assignable.GetType().Name} must be initialized"); + => System.Diagnostics.Debug.Assert(assignable.BehaviourController is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IBehaviourController)}"); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AssertEntityAssigned(IHasEntity assignable) - => System.Diagnostics.Debug.Assert(assignable.Entity is not null, $"{assignable.GetType().Name} must be initialized"); + => System.Diagnostics.Debug.Assert(assignable.Entity is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IEntity)}"); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AssertUniverseAssigned(IHasUniverse assignable) - => System.Diagnostics.Debug.Assert(assignable.Universe is not null, $"{assignable.GetType().Name} must be initialized"); + => System.Diagnostics.Debug.Assert(assignable.Universe is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IUniverse)}"); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AssertUniverseObjectAssigned(IHasUniverseObject assignable) - => System.Diagnostics.Debug.Assert(assignable.UniverseObject is not null, $"{assignable.GetType().Name} must be initialized"); + => System.Diagnostics.Debug.Assert(assignable.UniverseObject is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IUniverseObject)}"); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AssertStateEnableAssigned(IHasStateEnable assignable) - => System.Diagnostics.Debug.Assert(assignable.StateEnable is not null, $"{assignable.GetType().Name} must be initialized"); + => System.Diagnostics.Debug.Assert(assignable.StateEnable is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IStateEnable)}"); } -- 2.49.1 From f246d68aa70ca2a5127b2b69e73b572a6a3dea9b Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 4 Aug 2025 14:56:43 +0300 Subject: [PATCH 46/91] fix: remove behaviour not starting the reverse for loop from count - 1 --- Engine.Core/BehaviourController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Core/BehaviourController.cs b/Engine.Core/BehaviourController.cs index 9334871..7da0e27 100644 --- a/Engine.Core/BehaviourController.cs +++ b/Engine.Core/BehaviourController.cs @@ -72,7 +72,7 @@ public class BehaviourController : BaseEntity, IBehaviourController public void RemoveBehaviour(bool removeAll = false) where T : class, IBehaviour { - for (int i = behaviours.Count; i >= 0; i--) + for (int i = behaviours.Count - 1; i >= 0; i--) { if (behaviours[i] is not T behaviour) continue; -- 2.49.1 From 11719440dca5f682805e42e4d7874f0ba41035a1 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 4 Aug 2025 20:26:45 +0300 Subject: [PATCH 47/91] fix: behaviour controller extensions not null checking in case of uninitialized state --- Engine.Core/Extensions/BehaviourControllerExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Engine.Core/Extensions/BehaviourControllerExtensions.cs b/Engine.Core/Extensions/BehaviourControllerExtensions.cs index 3f71685..435c9c1 100644 --- a/Engine.Core/Extensions/BehaviourControllerExtensions.cs +++ b/Engine.Core/Extensions/BehaviourControllerExtensions.cs @@ -27,7 +27,7 @@ public static class BehaviourControllerExtensions /// The to start searching from. /// The of the specified type if found; otherwise, throws . public static T GetRequiredBehaviour(this IBehaviourController behaviourController) where T : class - => behaviourController.GetBehaviour() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName}"); + => behaviourController.GetBehaviour() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject?.Name ?? "NULL"}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName}"); /// /// Gets an existing of the specified type, or adds and returns a new one if it doesn't exist. @@ -93,7 +93,7 @@ public static class BehaviourControllerExtensions /// The to start searching from. /// The of the specified type if found; otherwise, throws . public static T GetRequiredBehaviourInParent(this IBehaviourController behaviourController) where T : class - => behaviourController.GetBehaviourInParent() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any parent"); + => behaviourController.GetBehaviourInParent() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject?.Name ?? "NULL"}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any parent"); /// /// Gets all s of the specified type in it's 's parents recursively and stores them in the provided list. @@ -154,7 +154,7 @@ public static class BehaviourControllerExtensions /// The to start searching from. /// The of the specified type if found; otherwise, throws . public static T GetRequiredBehaviourInChildren(this IBehaviourController behaviourController) where T : class - => behaviourController.GetBehaviourInChildren() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any children "); + => behaviourController.GetBehaviourInChildren() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject?.Name ?? "NULL"}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any children "); /// /// Gets all s of the specified type in it's 's children recursively and stores them in the provided list. -- 2.49.1 From e00319d7ffbf11e5bb11db2631c72562e1215b1e Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 4 Aug 2025 22:01:16 +0300 Subject: [PATCH 48/91] fix: active checks on behaviour base and universe object not working properly --- Engine.Core/BehaviourBase.cs | 6 +++++- Engine.Core/UniverseObject.cs | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Engine.Core/BehaviourBase.cs b/Engine.Core/BehaviourBase.cs index b8a6fcc..37b521a 100644 --- a/Engine.Core/BehaviourBase.cs +++ b/Engine.Core/BehaviourBase.cs @@ -44,6 +44,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour _behaviourController = behaviourController; OnAssign(behaviourController); behaviourController.OnUniverseObjectAssigned.AddListener(delegateOnUniverseObjectAssigned); + behaviourController.StateEnable.OnEnabledChanged.AddListener(delegateOnStateEnabledChanged); if (behaviourController.UniverseObject is not null) OnUniverseObjectAssigned(behaviourController); OnBehaviourControllerAssigned?.Invoke(this); @@ -68,6 +69,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour BehaviourController.UniverseObject.OnActiveChanged.RemoveListener(delegateOnUniverseObjectActiveChanged); StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged); BehaviourController.OnUniverseObjectAssigned.RemoveListener(delegateOnUniverseObjectAssigned); + BehaviourController.StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged); base.UnassignInternal(); _behaviourController = null!; } @@ -76,6 +78,8 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour { Debug.Assert.AssertBehaviourControllerAssigned(this); Debug.Assert.AssertStateEnableAssigned(this); + + UpdateActive(); } private void OnStateEnabledChanged(IStateEnable sender, IStateEnable.EnabledChangedArguments args) => UpdateActive(); @@ -84,7 +88,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour private void UpdateActive() { bool previousActive = IsActive; - _isActive = StateEnable.Enabled && _behaviourController.UniverseObject.IsActive; + _isActive = StateEnable.Enabled && _behaviourController.StateEnable.Enabled && _behaviourController.UniverseObject.IsActive; if (previousActive != IsActive) OnActiveChanged?.Invoke(this, new(previousActive)); diff --git a/Engine.Core/UniverseObject.cs b/Engine.Core/UniverseObject.cs index 94ff25a..50d63a6 100644 --- a/Engine.Core/UniverseObject.cs +++ b/Engine.Core/UniverseObject.cs @@ -133,6 +133,7 @@ public class UniverseObject : BaseEntity, IUniverseObject base.OnAssign(stateEnable); stateEnable.OnEnabledChanged.AddListener(OnStateEnabledChanged); + UpdateActive(); } private void OnParentActiveChanged(IActive sender, IActive.ActiveChangedArguments args) => UpdateActive(); -- 2.49.1 From 63bc94c7a63b0994988650d2aa9f103cec1b2bb1 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 4 Aug 2025 22:02:48 +0300 Subject: [PATCH 49/91] fix: some factories not assigning fields correctly --- .../Factory/BehaviourControllerFactory.cs | 17 +++++++++-- Engine.Core/Factory/BehaviourFactory.cs | 15 ++++++---- Engine.Core/Factory/UniverseObjectFactory.cs | 29 ++++++++++++------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Engine.Core/Factory/BehaviourControllerFactory.cs b/Engine.Core/Factory/BehaviourControllerFactory.cs index f3302a6..13f8c46 100644 --- a/Engine.Core/Factory/BehaviourControllerFactory.cs +++ b/Engine.Core/Factory/BehaviourControllerFactory.cs @@ -4,10 +4,10 @@ namespace Syntriax.Engine.Core.Factory; public class BehaviourControllerFactory { - public static IBehaviourController Instantiate(IUniverseObject universeObject) - => Instantiate(universeObject); + public static IBehaviourController Instantiate(IUniverseObject universeObject, IStateEnable? stateEnable = null) + => Instantiate(universeObject, stateEnable); - public static T Instantiate(IUniverseObject universeObject, params object?[]? args) + public static T Instantiate(IUniverseObject universeObject, IStateEnable? stateEnable = null, params object?[]? args) where T : class, IBehaviourController { T behaviourController = TypeFactory.Get(args); @@ -18,6 +18,17 @@ public class BehaviourControllerFactory if (!behaviourController.Assign(universeObject)) throw AssignFailedException.From(behaviourController, universeObject); + if (stateEnable is not null) + { + if (!stateEnable.Assign(behaviourController)) + throw AssignFailedException.From(stateEnable, behaviourController); + + if (!behaviourController.Assign(stateEnable)) + throw AssignFailedException.From(behaviourController, stateEnable); + } + else + StateEnableFactory.Instantiate(behaviourController); + return behaviourController; } } diff --git a/Engine.Core/Factory/BehaviourFactory.cs b/Engine.Core/Factory/BehaviourFactory.cs index f9efb66..0502465 100644 --- a/Engine.Core/Factory/BehaviourFactory.cs +++ b/Engine.Core/Factory/BehaviourFactory.cs @@ -12,12 +12,15 @@ public class BehaviourFactory { T behaviour = TypeFactory.Get(args); - stateEnable ??= TypeFactory.Get(); - if (!stateEnable.Assign(behaviour)) - throw AssignFailedException.From(stateEnable, behaviour); - - if (!behaviour.Assign(stateEnable)) - throw AssignFailedException.From(behaviour, stateEnable); + if (stateEnable is not null) + { + if (!stateEnable.Assign(behaviour)) + throw AssignFailedException.From(stateEnable, behaviour); + if (!behaviour.Assign(stateEnable)) + throw AssignFailedException.From(behaviour, stateEnable); + } + else + StateEnableFactory.Instantiate(behaviour); return behaviour; } diff --git a/Engine.Core/Factory/UniverseObjectFactory.cs b/Engine.Core/Factory/UniverseObjectFactory.cs index 39c59fc..917ee18 100644 --- a/Engine.Core/Factory/UniverseObjectFactory.cs +++ b/Engine.Core/Factory/UniverseObjectFactory.cs @@ -18,18 +18,25 @@ public class UniverseObjectFactory { T universeObject = TypeFactory.Get(args); - behaviourController ??= TypeFactory.Get(); - stateEnable ??= TypeFactory.Get(); + if (behaviourController is not null) + { + if (!behaviourController.Assign(universeObject)) + throw AssignFailedException.From(behaviourController, universeObject); + if (!universeObject.Assign(behaviourController)) + throw AssignFailedException.From(universeObject, behaviourController); + } + else + BehaviourControllerFactory.Instantiate(universeObject); - if (!behaviourController.Assign(universeObject)) - throw AssignFailedException.From(behaviourController, universeObject); - if (!stateEnable.Assign(universeObject)) - throw AssignFailedException.From(stateEnable, universeObject); - - if (!universeObject.Assign(behaviourController)) - throw AssignFailedException.From(universeObject, behaviourController); - if (!universeObject.Assign(stateEnable)) - throw AssignFailedException.From(universeObject, stateEnable); + if (stateEnable is not null) + { + if (!stateEnable.Assign(universeObject)) + throw AssignFailedException.From(stateEnable, universeObject); + if (!universeObject.Assign(stateEnable)) + throw AssignFailedException.From(universeObject, stateEnable); + } + else + StateEnableFactory.Instantiate(universeObject); return universeObject; } -- 2.49.1 From 11612ff0db20c44c7d9e362c9def0d722cf7baa3 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 5 Aug 2025 09:10:35 +0300 Subject: [PATCH 50/91] feat: removed IEnumerable from IUniverseObject for intellisense clarity Use IUniverseObject.Children to access children --- Engine.Core/Abstract/IUniverseObject.cs | 2 +- Engine.Core/Extensions/BehaviourControllerExtensions.cs | 4 ++-- Engine.Core/Extensions/UniverseObjectExtensions.cs | 8 ++++---- Engine.Core/UniverseObject.cs | 3 --- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Engine.Core/Abstract/IUniverseObject.cs b/Engine.Core/Abstract/IUniverseObject.cs index 7f03950..29ad5dd 100644 --- a/Engine.Core/Abstract/IUniverseObject.cs +++ b/Engine.Core/Abstract/IUniverseObject.cs @@ -7,7 +7,7 @@ namespace Syntriax.Engine.Core; /// This interface allows for tracking the object's presence in the universe and provides events /// for notifying when the see enters or exits the universe. /// -public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourController, IEnumerable +public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourController { /// /// Event triggered when the enters the universe. diff --git a/Engine.Core/Extensions/BehaviourControllerExtensions.cs b/Engine.Core/Extensions/BehaviourControllerExtensions.cs index 435c9c1..9dbfa46 100644 --- a/Engine.Core/Extensions/BehaviourControllerExtensions.cs +++ b/Engine.Core/Extensions/BehaviourControllerExtensions.cs @@ -140,7 +140,7 @@ public static class BehaviourControllerExtensions if (behaviourController.GetBehaviour() is T localBehaviour) return localBehaviour; - foreach (IUniverseObject child in behaviourController.UniverseObject) + foreach (IUniverseObject child in behaviourController.UniverseObject.Children) if (GetBehaviourInChildren(child.BehaviourController) is T behaviour) return behaviour; @@ -176,7 +176,7 @@ public static class BehaviourControllerExtensions foreach (T behaviour in cache) behaviours.Add(behaviour); - foreach (IUniverseObject child in universeObject) + foreach (IUniverseObject child in universeObject.Children) TraverseChildrenForBehaviour(child, behaviours, cache); } } diff --git a/Engine.Core/Extensions/UniverseObjectExtensions.cs b/Engine.Core/Extensions/UniverseObjectExtensions.cs index 16ad5cb..ae9dcd1 100644 --- a/Engine.Core/Extensions/UniverseObjectExtensions.cs +++ b/Engine.Core/Extensions/UniverseObjectExtensions.cs @@ -81,7 +81,7 @@ public static class UniverseObjectExtensions /// The of the specified type if found; otherwise, null. public static T? GetUniverseObjectInParent(this IUniverseObject universeObject) where T : class { - if (universeObject.GetUniverseObject() is T localUniverseObject) + if (universeObject.Children.GetUniverseObject() is T localUniverseObject) return localUniverseObject; IUniverseObject? parent = universeObject; @@ -129,10 +129,10 @@ public static class UniverseObjectExtensions /// The of the specified type if found; otherwise, null. public static T? GetUniverseObjectInChildren(this IUniverseObject universeObject) where T : class { - if (universeObject.GetUniverseObject() is T localUniverseObject) + if (universeObject.Children.GetUniverseObject() is T localUniverseObject) return localUniverseObject; - foreach (IUniverseObject child in universeObject) + foreach (IUniverseObject child in universeObject.Children) if (GetUniverseObjectInChildren(child) is T behaviour) return behaviour; @@ -246,7 +246,7 @@ public static class UniverseObjectExtensions foreach (IUniverseObject universeObject in universeObjects) { - universeObject.Find(cache); + universeObject.Children.Find(cache); foreach (T behaviour in cache) instances.Add(behaviour); } diff --git a/Engine.Core/UniverseObject.cs b/Engine.Core/UniverseObject.cs index 50d63a6..f6b96ce 100644 --- a/Engine.Core/UniverseObject.cs +++ b/Engine.Core/UniverseObject.cs @@ -165,7 +165,4 @@ public class UniverseObject : BaseEntity, IUniverseObject { _name = GetType().Name; } - - public IEnumerator GetEnumerator() => _children.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => _children.GetEnumerator(); } -- 2.49.1 From 345219494107db2a3c7c9606799fa9233f4130fb Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 5 Aug 2025 10:46:25 +0300 Subject: [PATCH 51/91] BREAKING CHANGE: removed IUniverseObject.SetParent and made Parent property settable --- Engine.Core/Abstract/IUniverseObject.cs | 8 +-- .../Extensions/UniverseObjectExtensions.cs | 2 +- Engine.Core/Universe.cs | 2 +- Engine.Core/UniverseObject.cs | 71 ++++++++++--------- 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/Engine.Core/Abstract/IUniverseObject.cs b/Engine.Core/Abstract/IUniverseObject.cs index 29ad5dd..b2b1afd 100644 --- a/Engine.Core/Abstract/IUniverseObject.cs +++ b/Engine.Core/Abstract/IUniverseObject.cs @@ -47,7 +47,7 @@ public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourCon /// /// The parent of the . /// - IUniverseObject? Parent { get; } + IUniverseObject? Parent { get; set; } /// /// The s that have this as their . @@ -75,12 +75,6 @@ public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourCon /// internal bool ExitUniverse(); - /// - /// Sets the parent of this . - /// - /// The parent to set. - void SetParent(IUniverseObject? universeObject); - /// /// Adds a child to this . /// diff --git a/Engine.Core/Extensions/UniverseObjectExtensions.cs b/Engine.Core/Extensions/UniverseObjectExtensions.cs index ae9dcd1..96d5ec3 100644 --- a/Engine.Core/Extensions/UniverseObjectExtensions.cs +++ b/Engine.Core/Extensions/UniverseObjectExtensions.cs @@ -12,7 +12,7 @@ public static class UniverseObjectExtensions if (!string.IsNullOrWhiteSpace(name)) universeObject.Name = name; if (parent is not null) - universeObject.SetParent(parent); + universeObject.Parent = parent; return universeObject; } diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index f60c7ae..ae5a1b3 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -83,7 +83,7 @@ public class Universe : BaseEntity, IUniverse public void Remove(IUniverseObject universeObject) { - universeObject.SetParent(null); + universeObject.Parent = null; RemoveIncursive(universeObject); } diff --git a/Engine.Core/UniverseObject.cs b/Engine.Core/UniverseObject.cs index f6b96ce..ff1c57f 100644 --- a/Engine.Core/UniverseObject.cs +++ b/Engine.Core/UniverseObject.cs @@ -1,4 +1,3 @@ -using System.Collections; using System.Collections.Generic; namespace Syntriax.Engine.Core; @@ -21,8 +20,8 @@ public class UniverseObject : BaseEntity, IUniverseObject private IBehaviourController _behaviourController = null!; private bool _isActive = false; private readonly List _children = []; + private IUniverseObject? _parent = null; - public IUniverseObject? Parent { get; private set; } = null; public IReadOnlyList Children => _children; public IBehaviourController BehaviourController => _behaviourController; public IUniverse Universe => _universe; @@ -42,6 +41,40 @@ public class UniverseObject : BaseEntity, IUniverseObject } } + public IUniverseObject? Parent + { + get => _parent; + set + { + if (value == this) + throw new Exceptions.AssignFailedException($"{Name} can not parent itself"); + + if (_parent == value) + return; + + IUniverseObject? previousParent = Parent; + if (previousParent is not null) + { + previousParent.RemoveChild(this); + previousParent.OnActiveChanged.RemoveListener(OnParentActiveChanged); + } + + _parent = value; + + if (value is not null) + { + if (value.IsInUniverse && !IsInUniverse) + value.Universe.Register(this); + + value.AddChild(this); + value.OnActiveChanged.AddListener(OnParentActiveChanged); + } + + UpdateActive(); + OnParentChanged?.Invoke(this, new(previousParent, value)); + } + } + protected virtual void OnEnteringUniverse(IUniverse universe) { } bool IUniverseObject.EnterUniverse(IUniverse universe) { @@ -67,43 +100,13 @@ public class UniverseObject : BaseEntity, IUniverseObject return true; } - public void SetParent(IUniverseObject? parent) - { - if (parent == this) - throw new Exceptions.AssignFailedException($"{Name} can not parent itself"); - - if (Parent == parent) - return; - - IUniverseObject? previousParent = Parent; - if (previousParent is not null) - { - previousParent.RemoveChild(this); - previousParent.OnActiveChanged.RemoveListener(OnParentActiveChanged); - } - - Parent = parent; - - if (parent is not null) - { - if (parent.IsInUniverse && !IsInUniverse) - parent.Universe.Register(this); - - parent.AddChild(this); - parent.OnActiveChanged.AddListener(OnParentActiveChanged); - } - - UpdateActive(); - OnParentChanged?.Invoke(this, new(previousParent, parent)); - } - public void AddChild(IUniverseObject parent) { if (_children.Contains(parent)) return; _children.Add(parent); - parent.SetParent(this); + parent.Parent = this; OnChildrenAdded?.Invoke(this, new(parent)); } @@ -112,7 +115,7 @@ public class UniverseObject : BaseEntity, IUniverseObject if (!_children.Remove(child)) return; - child.SetParent(null); + child.Parent = null; OnChildrenRemoved?.Invoke(this, new(child)); } -- 2.49.1 From 6631cae7b076d218c7eaa8a59e2a118599948ffa Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 5 Aug 2025 19:27:27 +0300 Subject: [PATCH 52/91] feat: added networking system --- .../Network/Abstract/IConnection.cs | 12 + .../Network/Abstract/IEntityNetworkPacket.cs | 6 + .../Network/Abstract/INetworkCommunicator.cs | 37 ++ .../Network/Abstract/INetworkEntity.cs | 5 + .../Network/Abstract/INetworkManager.cs | 11 + .../Network/Abstract/INetworkPacket.cs | 3 + .../Network/Abstract/IPacketListenerClient.cs | 6 + .../Network/Abstract/IPacketListenerServer.cs | 6 + .../Network/Abstract/PacketDelivery.cs | 9 + Engine.Systems/Network/NetworkManager.cs | 332 ++++++++++++++++++ 10 files changed, 427 insertions(+) create mode 100644 Engine.Systems/Network/Abstract/IConnection.cs create mode 100644 Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs create mode 100644 Engine.Systems/Network/Abstract/INetworkCommunicator.cs create mode 100644 Engine.Systems/Network/Abstract/INetworkEntity.cs create mode 100644 Engine.Systems/Network/Abstract/INetworkManager.cs create mode 100644 Engine.Systems/Network/Abstract/INetworkPacket.cs create mode 100644 Engine.Systems/Network/Abstract/IPacketListenerClient.cs create mode 100644 Engine.Systems/Network/Abstract/IPacketListenerServer.cs create mode 100644 Engine.Systems/Network/Abstract/PacketDelivery.cs create mode 100644 Engine.Systems/Network/NetworkManager.cs diff --git a/Engine.Systems/Network/Abstract/IConnection.cs b/Engine.Systems/Network/Abstract/IConnection.cs new file mode 100644 index 0000000..30aeecf --- /dev/null +++ b/Engine.Systems/Network/Abstract/IConnection.cs @@ -0,0 +1,12 @@ +namespace Syntriax.Engine.Systems.Network; + +public interface IConnection +{ + string Id { get; } + + float Ping { get; } + float RoundTrip { get; } + + int PingMs { get; } + int RoundTripMs { get; } +} diff --git a/Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs b/Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs new file mode 100644 index 0000000..7d1ee2a --- /dev/null +++ b/Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Systems.Network; + +public interface IEntityNetworkPacket : INetworkPacket +{ + string EntityId { get; } +} diff --git a/Engine.Systems/Network/Abstract/INetworkCommunicator.cs b/Engine.Systems/Network/Abstract/INetworkCommunicator.cs new file mode 100644 index 0000000..95e28a1 --- /dev/null +++ b/Engine.Systems/Network/Abstract/INetworkCommunicator.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +public interface INetworkCommunicator +{ + Event OnConnectionEstablished { get; } + Event OnConnectionAbolished { get; } + + IReadOnlyDictionary Connections { get; } + + INetworkCommunicator Stop(); + + INetworkCommunicator SubscribeToPackets(Event.EventHandler callback); + INetworkCommunicator UnsubscribeFromPackets(Event.EventHandler callback); +} + +public interface INetworkCommunicatorClient : INetworkCommunicator +{ + INetworkCommunicatorClient Connect(string address, int port, string? password = null); + + INetworkCommunicatorClient SendToServer(T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); +} + +public interface INetworkCommunicatorServer : INetworkCommunicator +{ + string Password { get; } + int MaxConnectionCount { get; } + int Port { get; } + + INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null); + + INetworkCommunicatorServer SendToClient(IConnection connection, T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); + INetworkCommunicatorServer SendToAll(T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); +} diff --git a/Engine.Systems/Network/Abstract/INetworkEntity.cs b/Engine.Systems/Network/Abstract/INetworkEntity.cs new file mode 100644 index 0000000..1e6a1f6 --- /dev/null +++ b/Engine.Systems/Network/Abstract/INetworkEntity.cs @@ -0,0 +1,5 @@ +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +public interface INetworkEntity : IEntity; diff --git a/Engine.Systems/Network/Abstract/INetworkManager.cs b/Engine.Systems/Network/Abstract/INetworkManager.cs new file mode 100644 index 0000000..3f9c950 --- /dev/null +++ b/Engine.Systems/Network/Abstract/INetworkManager.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +public interface INetworkManager +{ + IReadOnlyDictionary NetworkEntities { get; } + IBehaviourCollector NetworkEntityCollector { get; } +} diff --git a/Engine.Systems/Network/Abstract/INetworkPacket.cs b/Engine.Systems/Network/Abstract/INetworkPacket.cs new file mode 100644 index 0000000..042f14d --- /dev/null +++ b/Engine.Systems/Network/Abstract/INetworkPacket.cs @@ -0,0 +1,3 @@ +namespace Syntriax.Engine.Systems.Network; + +public interface INetworkPacket; diff --git a/Engine.Systems/Network/Abstract/IPacketListenerClient.cs b/Engine.Systems/Network/Abstract/IPacketListenerClient.cs new file mode 100644 index 0000000..bfe39d7 --- /dev/null +++ b/Engine.Systems/Network/Abstract/IPacketListenerClient.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Systems.Network; + +public interface IPacketListenerClient : INetworkEntity +{ + void OnClientPacketArrived(IConnection sender, T packet); +} diff --git a/Engine.Systems/Network/Abstract/IPacketListenerServer.cs b/Engine.Systems/Network/Abstract/IPacketListenerServer.cs new file mode 100644 index 0000000..b084949 --- /dev/null +++ b/Engine.Systems/Network/Abstract/IPacketListenerServer.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Systems.Network; + +public interface IPacketListenerServer : INetworkEntity +{ + void OnServerPacketArrived(IConnection sender, T packet); +} diff --git a/Engine.Systems/Network/Abstract/PacketDelivery.cs b/Engine.Systems/Network/Abstract/PacketDelivery.cs new file mode 100644 index 0000000..2fce6d0 --- /dev/null +++ b/Engine.Systems/Network/Abstract/PacketDelivery.cs @@ -0,0 +1,9 @@ +namespace Syntriax.Engine.Systems.Network; + +public enum PacketDelivery +{ + ReliableInOrder, + ReliableOutOfOrder, + UnreliableInOrder, + UnreliableOutOfOrder, +}; diff --git a/Engine.Systems/Network/NetworkManager.cs b/Engine.Systems/Network/NetworkManager.cs new file mode 100644 index 0000000..915782b --- /dev/null +++ b/Engine.Systems/Network/NetworkManager.cs @@ -0,0 +1,332 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +/// +/// Intermediary manager that looks up in it's hierarchy for a to route/broadcast it's received packets to their destinations. +/// +public class NetworkManager : Behaviour, INetworkManager +{ + private readonly Dictionary>> clientPacketArrivalMethods = []; + private readonly Dictionary>> serverPacketArrivalMethods = []; + + private readonly Dictionary> clientPacketRouters = []; + private readonly Dictionary> serverPacketRouters = []; + + private readonly List<(Type packetType, Delegate @delegate)> packetRetrievalDelegates = []; + + private readonly Dictionary clearRoutesMethods = []; + private readonly Dictionary registerPacketListenersMethods = []; + + private readonly Dictionary _networkEntities = []; + public IReadOnlyDictionary NetworkEntities => _networkEntities; + + private readonly BehaviourCollector _networkEntityCollector = new(); + public IBehaviourCollector NetworkEntityCollector => _networkEntityCollector; + + private INetworkCommunicator _networkCommunicator = null!; + public INetworkCommunicator NetworkCommunicator + { + get => _networkCommunicator; + set + { + if (_networkCommunicator == value) + return; + + INetworkCommunicator? previousCommunicator = _networkCommunicator; + _networkCommunicator = value; + + if (previousCommunicator is not null) UnsubscribeCommunicatorMethods(previousCommunicator); + if (_networkCommunicator is not null) SubscribeCommunicatorMethods(_networkCommunicator); + } + } + + #region Communicator Subscriptions + private void SubscribeCommunicatorMethods(INetworkCommunicator networkCommunicator) + { + MethodInfo subscribeToPacketsMethod = typeof(INetworkCommunicator) + .GetMethod(nameof(INetworkCommunicator.SubscribeToPackets), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)!; + + foreach ((Type packetType, Delegate @delegate) in packetRetrievalDelegates) + { + MethodInfo genericSubscribeMethod = subscribeToPacketsMethod.MakeGenericMethod(packetType); + genericSubscribeMethod.Invoke(networkCommunicator, [@delegate]); + } + } + + private void UnsubscribeCommunicatorMethods(INetworkCommunicator networkCommunicator) + { + MethodInfo unsubscribeFromPacketsMethod = typeof(INetworkCommunicator) + .GetMethod(nameof(INetworkCommunicator.UnsubscribeFromPackets), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)!; + + foreach ((Type packetType, Delegate @delegate) in packetRetrievalDelegates) + { + MethodInfo genericUnsubscribeMethod = unsubscribeFromPacketsMethod.MakeGenericMethod(packetType); + genericUnsubscribeMethod.Invoke(networkCommunicator, [@delegate]); + } + } + #endregion + + #region Packet Routing + private void OnPacketReceived(IConnection sender, T entityDataPacket) + { + if (entityDataPacket is IEntityNetworkPacket entityPacket) + RoutePacket(sender, entityDataPacket, entityPacket); + else + BroadcastPacket(sender, entityDataPacket); + } + + private void RoutePacket(IConnection sender, T entityDataPacket, IEntityNetworkPacket entityPacket) + { + if (NetworkCommunicator is INetworkCommunicatorClient) + RoutePacket(clientPacketRouters, entityPacket.EntityId, sender, entityDataPacket); + if (NetworkCommunicator is INetworkCommunicatorServer) + RoutePacket(serverPacketRouters, entityPacket.EntityId, sender, entityDataPacket); + } + + private void BroadcastPacket(IConnection sender, T entityDataPacket) + { + if (NetworkCommunicator is INetworkCommunicatorClient) + BroadcastPacket(clientPacketRouters, sender, entityDataPacket); + if (NetworkCommunicator is INetworkCommunicatorServer) + BroadcastPacket(serverPacketRouters, sender, entityDataPacket); + } + + private static void BroadcastPacket( + Dictionary> packetRouters, + IConnection sender, + T entityDataPacket) + { + if (!packetRouters.TryGetValue(entityDataPacket!.GetType(), out Dictionary? routers)) + return; + + foreach ((string behaviourId, object routerEventReference) in routers) + { + Event routerEvent = (Event)routerEventReference; + routerEvent.Invoke(sender, entityDataPacket!); + } + } + + private static void RoutePacket( + Dictionary> packetRouters, + string entityId, + IConnection sender, + T entityDataPacket) + { + if (!packetRouters.TryGetValue(entityDataPacket!.GetType(), out Dictionary? routers)) + return; + + if (!routers.TryGetValue(entityId, out object? routerEventReference)) + return; + + Event routerEvent = (Event)routerEventReference; + routerEvent.Invoke(sender, entityDataPacket!); + } + #endregion + + #region Packet Routers + private void RegisterPacketRoutersFor( + INetworkEntity behaviour, + Dictionary> packetRouters, + Dictionary>> packetArrivalMethods, + NetworkType networkType) + { + if (!packetArrivalMethods.TryGetValue(behaviour.GetType(), out Dictionary>? arrivalMethods)) + return; + + foreach ((Type packetType, List methods) in arrivalMethods) + foreach (MethodInfo receiveMethod in methods) + { + if (!packetRouters.TryGetValue(packetType, out Dictionary? routers)) + { + routers = []; + packetRouters.Add(packetType, routers); + } + + object packetListenerEvent = CreateEventAndRegister(packetType, behaviour, networkType); + routers.Add(behaviour.Id, packetListenerEvent); + } + } + + private object CreateEventAndRegister(Type packetType, INetworkEntity behaviour, NetworkType networkType) + { + Type genericEventType = typeof(Event<,>).MakeGenericType(typeof(IConnection), packetType); + object packetListenerEvent = Activator.CreateInstance(genericEventType)!; + + if (!registerPacketListenersMethods.TryGetValue(packetType, out MethodInfo? registerPacketListenerMethod)) + throw new($"{nameof(RegisterPacketListenerEvent)} for {packetType.Name} has not been cached."); + + registerPacketListenerMethod.Invoke(this, [behaviour, packetListenerEvent, networkType]); + return packetListenerEvent; + } + + private static void RegisterPacketListenerEvent( + INetworkEntity behaviour, + Event packetListenerEvent, + NetworkType networkType) + { + switch (networkType) + { + case NetworkType.Client: packetListenerEvent.AddListener((sender, packet) => ((IPacketListenerClient)behaviour).OnClientPacketArrived(sender, packet)); break; + case NetworkType.Server: packetListenerEvent.AddListener((sender, packet) => ((IPacketListenerServer)behaviour).OnServerPacketArrived(sender, packet)); break; + } + } + + private void UnregisterPacketRoutersFor( + INetworkEntity behaviour, + Dictionary> packetRouters, + Dictionary>> packetArrivalMethods) + { + if (!packetArrivalMethods.TryGetValue(behaviour.GetType(), out Dictionary>? arrivalMethods)) + return; + + foreach ((Type packetType, List methods) in arrivalMethods) + { + if (!packetRouters.TryGetValue(packetType, out Dictionary? routers)) + continue; + + if (!routers.TryGetValue(behaviour.Id, out object? routerEventReference)) + continue; + + if (!clearRoutesMethods.TryGetValue(packetType, out MethodInfo? clearRouterMethod)) + continue; + + clearRouterMethod.Invoke(this, [routerEventReference]); + } + } + + private static void ClearRouter(object routerEventReference) + { + Event routerEvent = (Event)routerEventReference; + routerEvent.Clear(); + } + + #endregion + + #region Engine Callbacks + private void OnCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) + { + INetworkEntity collectedBehaviour = args.BehaviourCollected; + + if (!_networkEntities.TryAdd(collectedBehaviour.Id, collectedBehaviour)) + throw new($"Unable to add {collectedBehaviour.Id} to {nameof(NetworkManager)}"); + + RegisterPacketRoutersFor(collectedBehaviour, clientPacketRouters, clientPacketArrivalMethods, NetworkType.Client); + RegisterPacketRoutersFor(collectedBehaviour, serverPacketRouters, serverPacketArrivalMethods, NetworkType.Server); + } + + private void OnRemoved(IBehaviourCollector sender, IBehaviourCollector.BehaviourRemovedArguments args) + { + INetworkEntity removedBehaviour = args.BehaviourRemoved; + if (!_networkEntities.Remove(args.BehaviourRemoved.Id)) + return; + + UnregisterPacketRoutersFor(removedBehaviour, clientPacketRouters, clientPacketArrivalMethods); + UnregisterPacketRoutersFor(removedBehaviour, serverPacketRouters, serverPacketArrivalMethods); + } + + protected override void OnExitedUniverse(IUniverse universe) => _networkEntityCollector.Unassign(); + protected override void OnEnteredUniverse(IUniverse universe) + { + _networkEntityCollector.Assign(universe); + NetworkCommunicator = BehaviourController.GetRequiredBehaviourInParent(); + } + #endregion + + #region Initialization + public NetworkManager() + { + CachePacketRetrievalDelegates(); + CacheRegistrationMethods(); + CachePacketArrivalMethods(); + + _networkEntityCollector.OnCollected.AddListener(OnCollected); + _networkEntityCollector.OnRemoved.AddListener(OnRemoved); + } + + private void CachePacketRetrievalDelegates() + { + IEnumerable packetTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()) + .Where(t => typeof(INetworkPacket).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract && !t.IsGenericType); + + MethodInfo onPacketArrivedMethod = GetType() + .GetMethod(nameof(OnPacketReceived), BindingFlags.NonPublic | BindingFlags.Instance)!; + + foreach (Type packetType in packetTypes) + { + MethodInfo genericOnPacketArrivedMethod = onPacketArrivedMethod.MakeGenericMethod(packetType); + + Type genericDelegateType = typeof(Event<,>.EventHandler).MakeGenericType(typeof(IConnection), packetType); + Delegate genericPacketReceivedDelegate = Delegate.CreateDelegate(genericDelegateType, this, genericOnPacketArrivedMethod); + + packetRetrievalDelegates.Add((packetType, genericPacketReceivedDelegate)); + } + } + + private void CacheRegistrationMethods() + { + CacheRegistrationMethods(registerPacketListenersMethods, nameof(RegisterPacketListenerEvent)); + CacheRegistrationMethods(clearRoutesMethods, nameof(ClearRouter)); + } + + private void CacheRegistrationMethods(Dictionary registrationMethods, string methodName) + { + MethodInfo registerPacketMethod = typeof(NetworkManager).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Static)!; + foreach ((Type packetType, Delegate @delegate) in packetRetrievalDelegates) + { + MethodInfo genericMethod = registerPacketMethod.MakeGenericMethod(packetType); + registrationMethods.Add(packetType, genericMethod); + } + } + + private void CachePacketArrivalMethods() + { + CachePacketArrivalMethods(clientPacketArrivalMethods, typeof(IPacketListenerClient<>), nameof(IPacketListenerClient.OnClientPacketArrived)); + CachePacketArrivalMethods(serverPacketArrivalMethods, typeof(IPacketListenerServer<>), nameof(IPacketListenerServer.OnServerPacketArrived)); + } + + private static void CachePacketArrivalMethods(Dictionary>> packetArrivalMethods, Type listenerType, string packetArrivalMethodName) + { + foreach (Type listenerClass in GetGenericsWith(listenerType)) + { + Dictionary> packetRouters = []; + packetArrivalMethods.Add(listenerClass, packetRouters); + + foreach (Type packetListener in GetGenericInterfacesWith(listenerType, listenerClass)) + { + Type packetType = packetListener.GetGenericArguments().First(); + + List arrivalMethods = packetListener + .GetMethods() + .Where(m => m.Name == packetArrivalMethodName) + .ToList(); + + packetRouters.Add(packetType, arrivalMethods); + } + } + } + + private static IEnumerable GetGenericsWith(Type type) + => AppDomain.CurrentDomain + .GetAssemblies() + .SelectMany(a => + a.GetTypes().Where( + t => t.GetInterfaces().Any( + i => i.IsGenericType && i.GetGenericTypeDefinition() == type + ) + ) + ); + + private static IEnumerable GetGenericInterfacesWith(Type interfaceType, Type type) + => type.GetInterfaces().Where( + i => i.IsGenericType && i.GetGenericTypeDefinition() == interfaceType + ); + #endregion + + private enum NetworkType { Client, Server } +} -- 2.49.1 From 1644a751bb81ab0f0d467321d1dd5cd2e326227a Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 5 Aug 2025 19:27:47 +0300 Subject: [PATCH 53/91] feat: added LiteNetLib networking integration --- .../Engine.Integration.LiteNetLib.csproj | 19 ++ .../LiteNetLibClient.cs | 85 ++++++++ .../LiteNetLibClientConnection.cs | 16 ++ .../LiteNetLibCommunicatorBase.cs | 185 ++++++++++++++++++ .../LiteNetLibServer.cs | 102 ++++++++++ .../LiteNetLibServerConnection.cs | 16 ++ .../Packers/AABBNetPacker.cs | 22 +++ .../Packers/CircleNetPacker.cs | 22 +++ .../Packers/ColorHSVNetPacker.cs | 24 +++ .../Packers/ColorRGBANetPacker.cs | 26 +++ .../Packers/ColorRGBNetPacker.cs | 24 +++ .../Packers/Line2DEquationNetPacker.cs | 22 +++ .../Packers/Line2DNetPacker.cs | 22 +++ .../Packers/Projection1DNetPacker.cs | 22 +++ .../Packers/QuaternionNetPacker.cs | 26 +++ .../Packers/Shape2DNetPacker.cs | 26 +++ .../Packers/TriangleNetPacker.cs | 24 +++ .../Packers/Vector2DNetPacker.cs | 22 +++ .../Packers/Vector3DNetPacker.cs | 24 +++ Engine.sln | 19 +- 20 files changed, 747 insertions(+), 1 deletion(-) create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Engine.Integration.LiteNetLib.csproj create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClientConnection.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServerConnection.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/AABBNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/CircleNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorHSVNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBANetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DEquationNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/Projection1DNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/QuaternionNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/Shape2DNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/TriangleNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector2DNetPacker.cs create mode 100644 Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector3DNetPacker.cs diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Engine.Integration.LiteNetLib.csproj b/Engine.Integration/Engine.Integration.LiteNetLib/Engine.Integration.LiteNetLib.csproj new file mode 100644 index 0000000..3a34cb3 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Engine.Integration.LiteNetLib.csproj @@ -0,0 +1,19 @@ + + + + net9.0 + enable + enable + Syntriax.Engine.Systems.Network + Syntriax.Engine.Integration.LiteNetLib + + + + + + + + + + + diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs new file mode 100644 index 0000000..0967d57 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs @@ -0,0 +1,85 @@ +using System.Net.Sockets; + +using LiteNetLib; +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; +using Syntriax.Engine.Core.Debug; + +namespace Syntriax.Engine.Systems.Network; + +public class LiteNetLibClient : LiteNetLibCommunicatorBase, INetworkCommunicatorClient +{ + private readonly NetDataWriter netDataWriter = new(); + + private CancellationTokenSource? cancellationTokenSource = null; + + protected override IConnection GetConnection(NetPeer peer) => new LiteNetLibServerConnection(peer); + + public INetworkCommunicatorClient Connect(string address, int port, string? password = null) + { + if (!UniverseObject.IsInUniverse) + throw new($"{nameof(LiteNetLibClient)} must be in an universe to connect"); + + password ??= string.Empty; + + // Okay, for some reason sometimes LiteNetLib goes dumb when the server hostname has IPv6 address as well as IPv4 + // but the client doesn't support IPv6, it still tries to use the v6 unless we explicitly tell the ip to connect to, + // which fails to connect... So for the time being I am preferring IPv4 below over IPv6 for clients. + // TODO: I think this is something that happens on Linux only? I need to check on Windows as well just to be sure. + System.Net.IPAddress[] addresses = System.Net.Dns.GetHostAddresses(address); + string connectionAddress = addresses.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork, addresses[0]).ToString(); + + logger?.Log(this, $"Connecting to server at '{address}:{port}' with password '{password}'"); + logger?.Log(this, $"Resolved address for {address}: {connectionAddress}"); + + Manager.Start(); + Manager.Connect(connectionAddress, port, password); + + return this; + } + + public INetworkCommunicatorClient SendToServer(T packet, PacketDelivery packetDelivery) where T : class, new() + { + netDataWriter.Reset(); + netPacketProcessor.Write(netDataWriter, packet); + + switch (packetDelivery) + { + case PacketDelivery.ReliableInOrder: Manager.FirstPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); break; + case PacketDelivery.UnreliableInOrder: Manager.FirstPeer.Send(netDataWriter, DeliveryMethod.Sequenced); break; + case PacketDelivery.ReliableOutOfOrder: Manager.FirstPeer.Send(netDataWriter, DeliveryMethod.ReliableUnordered); break; + case PacketDelivery.UnreliableOutOfOrder: Manager.FirstPeer.Send(netDataWriter, DeliveryMethod.Unreliable); break; + default: Manager.FirstPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); break; + } + + return this; + } + + protected override void OnEnteredUniverse(IUniverse universe) + { + base.OnEnteredUniverse(universe); + + cancellationTokenSource = new CancellationTokenSource(); + PollEvents(cancellationTokenSource.Token); + } + + protected override void OnExitedUniverse(IUniverse universe) + { + base.OnExitedUniverse(universe); + cancellationTokenSource?.Cancel(); + } + + /// + /// Client needs to send everything as soon as possible so + /// the events are polled a separate thread running constantly + /// + private async void PollEvents(CancellationToken cancellationToken) => await Task.Run(() => + { + while (true) + { + Manager.PollEvents(); + Thread.Sleep(1); + } + }, cancellationToken); +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClientConnection.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClientConnection.cs new file mode 100644 index 0000000..5e2408f --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClientConnection.cs @@ -0,0 +1,16 @@ +using LiteNetLib; + +namespace Syntriax.Engine.Systems.Network; + +public record class LiteNetLibClientConnection(NetPeer NetPeer) : IConnection +{ + public string Id { get; } = NetPeer.Id.ToString(); + + public float Ping => NetPeer.Ping * .001f; + public float RoundTrip => NetPeer.RoundTripTime * .001f; + + public int PingMs => NetPeer.Ping; + public int RoundTripMs => NetPeer.RoundTripTime; + + public override string ToString() => $"Connection({Id})"; +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs new file mode 100644 index 0000000..ed14f12 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs @@ -0,0 +1,185 @@ +using System.Reflection; + +using LiteNetLib; +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; +using Syntriax.Engine.Core.Debug; + +namespace Syntriax.Engine.Systems.Network; + +public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicator +{ + protected readonly NetPacketProcessor netPacketProcessor = new(); + + private readonly Dictionary> listeners = []; + private readonly Dictionary _connections = []; + + private readonly Dictionary localPeerIdToConnectionDictionary = []; + + protected ILogger? logger = null; + + public IReadOnlyDictionary Connections => _connections; + public EventBasedNetListener Listener { get; private set; } = null!; + public NetManager Manager { get; private set; } = null!; + + public Event OnConnectionEstablished { get; } = new(); + public Event OnConnectionAbolished { get; } = new(); + + public INetworkCommunicator Stop() + { + Manager.Stop(); + return this; + } + + protected override void OnEnteredUniverse(IUniverse universe) + { + base.OnEnteredUniverse(universe); + logger = universe.FindBehaviour(); + } + + protected override void OnExitedUniverse(IUniverse universe) + { + base.OnExitedUniverse(universe); + logger = null; + Stop(); + } + + protected virtual void OnPacketArrived(T packet, NetPeer peer) where T : INetworkPacket + { + if (!listeners.TryGetValue(typeof(T), out Event? @event)) + return; + + @event.Invoke(localPeerIdToConnectionDictionary[peer.Id], packet); + } + + private void NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod) + { + try { netPacketProcessor.ReadAllPackets(reader, peer); } + catch (Exception exception) { logger?.LogException(this, exception, force: true); } + } + + protected abstract IConnection GetConnection(NetPeer peer); + private void ConnectionEstablished(NetPeer peer) + { + IConnection connection = GetConnection(peer); + + localPeerIdToConnectionDictionary.Add(peer.Id, connection); + _connections.Add(connection.Id, connection); + + logger?.Log(this, $"Connection established with ip '{peer.Address}' and id '{connection.Id}'"); + OnConnectionEstablished.Invoke(this, connection); + } + + private void ConnectionAbolished(NetPeer peer, DisconnectInfo disconnectInfo) + { + if (!localPeerIdToConnectionDictionary.TryGetValue(peer.Id, out IConnection? connection)) + return; + + localPeerIdToConnectionDictionary.Remove(peer.Id); + _connections.Remove(connection.Id); + + logger?.Log(this, $"Connection abolished with ip '{peer.Address}' and id '{connection.Id}'"); + OnConnectionAbolished.Invoke(this, connection); + } + + private void SetupPackets() + { + // Find network packets implementing INetworkPacket + IEnumerable packetTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()) + .Where(t => typeof(INetworkPacket).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract && !t.IsGenericType); + + MethodInfo subscribeReusableMethod = typeof(NetPacketProcessor) + .GetMethods() + .FirstOrDefault(m => m.Name == nameof(NetPacketProcessor.SubscribeReusable) && + m.GetParameters().Length == 1 && + m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(Action<,>) + )!; + + MethodInfo registerNestedTypeMethod = typeof(NetPacketProcessor) + .GetMethods() + .FirstOrDefault(m => m.Name == nameof(NetPacketProcessor.RegisterNestedType) && + m.GetParameters().Length == 0 + )!; + + MethodInfo onPacketArrivedMethod = typeof(LiteNetLibCommunicatorBase) + .GetMethod(nameof(OnPacketArrived), BindingFlags.NonPublic | BindingFlags.Instance)!; + + // Register all network packets by calling the methods bellow where T is our found network packet type + // NetPacketProcessor.SubscribeReusable(Action onReceive) + // NetPacketProcessor.RegisterNestedType() + foreach (Type packetType in packetTypes) + { + if (!packetType.IsClass) + { + MethodInfo genericRegisterNestedTypeMethod = registerNestedTypeMethod.MakeGenericMethod(packetType); + genericRegisterNestedTypeMethod.Invoke(netPacketProcessor, []); + continue; + } + + MethodInfo genericOnPacketArrivedMethod = onPacketArrivedMethod.MakeGenericMethod(packetType); + + Type delegateType = typeof(Action<,>).MakeGenericType(packetType, typeof(NetPeer)); + Delegate delegateHandler = Delegate.CreateDelegate(delegateType, this, genericOnPacketArrivedMethod); + + MethodInfo genericSubscribeReusableMethod = subscribeReusableMethod.MakeGenericMethod(packetType, typeof(NetPeer)); + genericSubscribeReusableMethod.Invoke(netPacketProcessor, [delegateHandler]); + } + } + + public LiteNetLibCommunicatorBase() + { + Listener = new EventBasedNetListener(); + Manager = new NetManager(Listener); + + Listener.NetworkReceiveEvent += NetworkReceiveEvent; + Listener.PeerConnectedEvent += ConnectionEstablished; + Listener.PeerDisconnectedEvent += ConnectionAbolished; + + SetupEnginePackets(); + SetupPackets(); + } + + private void SetupEnginePackets() + { + // I know, ugly af. I need to find a better way + netPacketProcessor.RegisterNestedType(AABBNetPacker.Write, AABBNetPacker.Read); + netPacketProcessor.RegisterNestedType(CircleNetPacker.Write, CircleNetPacker.Read); + netPacketProcessor.RegisterNestedType(ColorHSVNetPacker.Write, ColorHSVNetPacker.Read); + netPacketProcessor.RegisterNestedType(ColorRGBANetPacker.Write, ColorRGBANetPacker.Read); + netPacketProcessor.RegisterNestedType(ColorRGBNetPacker.Write, ColorRGBNetPacker.Read); + netPacketProcessor.RegisterNestedType(Line2DEquationNetPacker.Write, Line2DEquationNetPacker.Read); + netPacketProcessor.RegisterNestedType(Line2DNetPacker.Write, Line2DNetPacker.Read); + netPacketProcessor.RegisterNestedType(Projection1DNetPacker.Write, Projection1DNetPacker.Read); + netPacketProcessor.RegisterNestedType(QuaternionNetPacker.Write, QuaternionNetPacker.Read); + netPacketProcessor.RegisterNestedType(Shape2DNetPacker.Write, Shape2DNetPacker.Read); + netPacketProcessor.RegisterNestedType(TriangleNetPacker.Write, TriangleNetPacker.Read); + netPacketProcessor.RegisterNestedType(Vector2DNetPacker.Write, Vector2DNetPacker.Read); + netPacketProcessor.RegisterNestedType(Vector3DNetPacker.Write, Vector3DNetPacker.Read); + } + + public INetworkCommunicator SubscribeToPackets(Event.EventHandler callback) + { + Type type = typeof(T); + if (!listeners.TryGetValue(type, out Event? @event)) + { + @event = new(); + listeners.Add(type, @event); + } + + @event.AddListener(EventDelegateWrapper(callback)); + return this; + } + + public INetworkCommunicator UnsubscribeFromPackets(Event.EventHandler callback) + { + Type type = typeof(T); + if (!listeners.TryGetValue(type, out Event? @event)) + return this; + + @event.RemoveListener(EventDelegateWrapper(callback)); + return this; + } + + private static Event.EventHandler EventDelegateWrapper(Event.EventHandler callback) => (sender, @object) => callback.Invoke(sender, (T)@object); +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs new file mode 100644 index 0000000..d3fad8e --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs @@ -0,0 +1,102 @@ +using LiteNetLib; +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; +using Syntriax.Engine.Core.Debug; + +namespace Syntriax.Engine.Systems.Network; + +public class LiteNetLibServer : LiteNetLibCommunicatorBase, INetworkCommunicatorServer +{ + public string Password { get; private set; } = string.Empty; + public int MaxConnectionCount { get; private set; } = 2; + public int Port { get; private set; } = 8888; + + private readonly NetDataWriter netDataWriter = new(); + + public LiteNetLibServer() : this(8888, 2) { } + public LiteNetLibServer(int port, int maxConnectionCount) : base() + { + MaxConnectionCount = maxConnectionCount; + Port = port; + + Listener.ConnectionRequestEvent += OnConnectionRequest; + } + + protected override IConnection GetConnection(NetPeer peer) => new LiteNetLibClientConnection(peer); + + private void OnConnectionRequest(ConnectionRequest request) + { + logger?.Log(this, $"Connection request from ip {request.RemoteEndPoint}"); + logger?.Log(this, $"Current connection count: {Connections.Count}"); + if (Manager.ConnectedPeersCount < MaxConnectionCount) + request.AcceptIfKey(Password); + else + request.Reject(); + } + + public INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null) + { + if (!UniverseObject.IsInUniverse) + throw new($"{nameof(LiteNetLibServer)} must be in an universe to start"); + + Password = password ?? string.Empty; + MaxConnectionCount = maxConnectionCount; + Port = port; + + logger?.Log(this, $"Starting server on port '{port}' with password '{Password}' and max connection count '{maxConnectionCount}'"); + logger?.Log(this, $"Server status: {(Manager.Start(port) ? "Active" : "Failed")}"); + + return this; + } + + public INetworkCommunicatorServer SendToClient(IConnection connection, T packet, PacketDelivery packetDelivery) where T : class, new() + { + netDataWriter.Reset(); + netPacketProcessor.Write(netDataWriter, packet); + + if (Manager.ConnectedPeerList.FirstOrDefault(p => p.Id.CompareTo(connection.Id) == 0) is not NetPeer netPeer) + throw new($"Peer {connection} couldn't be found."); + + switch (packetDelivery) + { + case PacketDelivery.ReliableInOrder: netPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); break; + case PacketDelivery.UnreliableInOrder: netPeer.Send(netDataWriter, DeliveryMethod.Sequenced); break; + case PacketDelivery.ReliableOutOfOrder: netPeer.Send(netDataWriter, DeliveryMethod.ReliableUnordered); break; + case PacketDelivery.UnreliableOutOfOrder: netPeer.Send(netDataWriter, DeliveryMethod.Unreliable); break; + default: netPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); break; + } + + return this; + } + + public INetworkCommunicatorServer SendToAll(T packet, PacketDelivery packetDelivery) where T : class, new() + { + netDataWriter.Reset(); + netPacketProcessor.Write(netDataWriter, packet); + + switch (packetDelivery) + { + case PacketDelivery.ReliableInOrder: Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered); break; + case PacketDelivery.UnreliableInOrder: Manager.SendToAll(netDataWriter, DeliveryMethod.Sequenced); break; + case PacketDelivery.ReliableOutOfOrder: Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableUnordered); break; + case PacketDelivery.UnreliableOutOfOrder: Manager.SendToAll(netDataWriter, DeliveryMethod.Unreliable); break; + default: Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered); break; + } + return this; + } + + private void PollEvents(IUniverse sender, IUniverse.UpdateArguments args) => Manager.PollEvents(); + + protected override void OnEnteredUniverse(IUniverse universe) + { + base.OnEnteredUniverse(universe); + universe.OnPostUpdate.AddListener(PollEvents); + } + + protected override void OnExitedUniverse(IUniverse universe) + { + base.OnExitedUniverse(universe); + universe.OnPostUpdate.RemoveListener(PollEvents); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServerConnection.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServerConnection.cs new file mode 100644 index 0000000..66f8f3b --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServerConnection.cs @@ -0,0 +1,16 @@ +using LiteNetLib; + +namespace Syntriax.Engine.Systems.Network; + +public record class LiteNetLibServerConnection(NetPeer NetPeer) : IConnection +{ + public string Id => NetPeer.RemoteId.ToString(); + + public float Ping => NetPeer.Ping * .001f; + public float RoundTrip => NetPeer.RoundTripTime * .001f; + + public int PingMs => NetPeer.Ping; + public int RoundTripMs => NetPeer.RoundTripTime; + + public override string ToString() => $"Connection({Id})"; +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/AABBNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/AABBNetPacker.cs new file mode 100644 index 0000000..e8ed56e --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/AABBNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class AABBNetPacker +{ + internal static void Write(NetDataWriter writer, AABB data) + { + Vector2DNetPacker.Write(writer, data.LowerBoundary); + Vector2DNetPacker.Write(writer, data.UpperBoundary); + } + + internal static AABB Read(NetDataReader reader) + { + Vector2D lowerBoundary = Vector2DNetPacker.Read(reader); + Vector2D upperBoundary = Vector2DNetPacker.Read(reader); + + return new AABB(lowerBoundary, upperBoundary); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/CircleNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/CircleNetPacker.cs new file mode 100644 index 0000000..5545dca --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/CircleNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class CircleNetPacker +{ + internal static void Write(NetDataWriter writer, Circle data) + { + Vector2DNetPacker.Write(writer, data.Center); + writer.Put(data.Radius); + } + + internal static Circle Read(NetDataReader reader) + { + Vector2D center = Vector2DNetPacker.Read(reader); + float radius = reader.GetFloat(); + + return new Circle(center, radius); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorHSVNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorHSVNetPacker.cs new file mode 100644 index 0000000..af868c8 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorHSVNetPacker.cs @@ -0,0 +1,24 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class ColorHSVNetPacker +{ + internal static void Write(NetDataWriter writer, ColorHSV data) + { + writer.Put(data.Hue); + writer.Put(data.Saturation); + writer.Put(data.Value); + } + + internal static ColorHSV Read(NetDataReader reader) + { + float hue = reader.GetFloat(); + float saturation = reader.GetFloat(); + float value = reader.GetFloat(); + + return new ColorHSV(hue, saturation, value); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBANetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBANetPacker.cs new file mode 100644 index 0000000..0b20f06 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBANetPacker.cs @@ -0,0 +1,26 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class ColorRGBANetPacker +{ + internal static void Write(NetDataWriter writer, ColorRGBA data) + { + writer.Put(data.R); + writer.Put(data.G); + writer.Put(data.B); + writer.Put(data.A); + } + + internal static ColorRGBA Read(NetDataReader reader) + { + byte red = reader.GetByte(); + byte green = reader.GetByte(); + byte blue = reader.GetByte(); + byte alpha = reader.GetByte(); + + return new ColorRGBA(red, green, blue, alpha); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBNetPacker.cs new file mode 100644 index 0000000..46770e1 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBNetPacker.cs @@ -0,0 +1,24 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class ColorRGBNetPacker +{ + internal static void Write(NetDataWriter writer, ColorRGB data) + { + writer.Put(data.R); + writer.Put(data.G); + writer.Put(data.B); + } + + internal static ColorRGB Read(NetDataReader reader) + { + byte red = reader.GetByte(); + byte green = reader.GetByte(); + byte blue = reader.GetByte(); + + return new ColorRGB(red, green, blue); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DEquationNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DEquationNetPacker.cs new file mode 100644 index 0000000..3bcfe70 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DEquationNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class Line2DEquationNetPacker +{ + internal static void Write(NetDataWriter writer, Line2DEquation data) + { + writer.Put(data.Slope); + writer.Put(data.OffsetY); + } + + internal static Line2DEquation Read(NetDataReader reader) + { + float slope = reader.GetFloat(); + float offsetY = reader.GetFloat(); + + return new Line2DEquation(slope, offsetY); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DNetPacker.cs new file mode 100644 index 0000000..899b0f7 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class Line2DNetPacker +{ + internal static void Write(NetDataWriter writer, Line2D data) + { + Vector2DNetPacker.Write(writer, data.From); + Vector2DNetPacker.Write(writer, data.To); + } + + internal static Line2D Read(NetDataReader reader) + { + Vector2D from = Vector2DNetPacker.Read(reader); + Vector2D to = Vector2DNetPacker.Read(reader); + + return new Line2D(from, to); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Projection1DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Projection1DNetPacker.cs new file mode 100644 index 0000000..0a356ef --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Projection1DNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class Projection1DNetPacker +{ + internal static void Write(NetDataWriter writer, Projection1D data) + { + writer.Put(data.Min); + writer.Put(data.Max); + } + + internal static Projection1D Read(NetDataReader reader) + { + float min = reader.GetFloat(); + float max = reader.GetFloat(); + + return new Projection1D(min, max); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/QuaternionNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/QuaternionNetPacker.cs new file mode 100644 index 0000000..a1241be --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/QuaternionNetPacker.cs @@ -0,0 +1,26 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class QuaternionNetPacker +{ + internal static void Write(NetDataWriter writer, Quaternion data) + { + writer.Put(data.X); + writer.Put(data.Y); + writer.Put(data.Z); + writer.Put(data.W); + } + + internal static Quaternion Read(NetDataReader reader) + { + float x = reader.GetFloat(); + float y = reader.GetFloat(); + float z = reader.GetFloat(); + float w = reader.GetFloat(); + + return new Quaternion(x, y, z, w); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Shape2DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Shape2DNetPacker.cs new file mode 100644 index 0000000..525185f --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Shape2DNetPacker.cs @@ -0,0 +1,26 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class Shape2DNetPacker +{ + internal static void Write(NetDataWriter writer, Shape2D data) + { + writer.Put(data.Vertices.Count); + foreach (Vector2D vertex in data.Vertices) + Vector2DNetPacker.Write(writer, vertex); + } + + internal static Shape2D Read(NetDataReader reader) + { + int verticesCount = reader.GetInt(); + List vertices = new(verticesCount); + + for (int i = 0; i < verticesCount; i++) + vertices.Add(Vector2DNetPacker.Read(reader)); + + return new Shape2D(vertices); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/TriangleNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/TriangleNetPacker.cs new file mode 100644 index 0000000..8c22746 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/TriangleNetPacker.cs @@ -0,0 +1,24 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class TriangleNetPacker +{ + internal static void Write(NetDataWriter writer, Triangle data) + { + Vector2DNetPacker.Write(writer, data.A); + Vector2DNetPacker.Write(writer, data.B); + Vector2DNetPacker.Write(writer, data.C); + } + + internal static Triangle Read(NetDataReader reader) + { + Vector2D a = Vector2DNetPacker.Read(reader); + Vector2D b = Vector2DNetPacker.Read(reader); + Vector2D c = Vector2DNetPacker.Read(reader); + + return new Triangle(a, b, c); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector2DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector2DNetPacker.cs new file mode 100644 index 0000000..5f1485f --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector2DNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class Vector2DNetPacker +{ + internal static void Write(NetDataWriter writer, Vector2D data) + { + writer.Put(data.X); + writer.Put(data.Y); + } + + internal static Vector2D Read(NetDataReader reader) + { + float x = reader.GetFloat(); + float y = reader.GetFloat(); + + return new Vector2D(x, y); + } +} diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector3DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector3DNetPacker.cs new file mode 100644 index 0000000..d594104 --- /dev/null +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector3DNetPacker.cs @@ -0,0 +1,24 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Systems.Network; + +internal static class Vector3DNetPacker +{ + internal static void Write(NetDataWriter writer, Vector3D data) + { + writer.Put(data.X); + writer.Put(data.Y); + writer.Put(data.Z); + } + + internal static Vector3D Read(NetDataReader reader) + { + float x = reader.GetFloat(); + float y = reader.GetFloat(); + float z = reader.GetFloat(); + + return new Vector3D(x, y, z); + } +} diff --git a/Engine.sln b/Engine.sln index 4f5da96..b81932e 100644 --- a/Engine.sln +++ b/Engine.sln @@ -19,7 +19,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YamlDotNet", "Engine.Serial EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Integration", "Integration", "{823D4020-332D-2C13-F261-6F510F11A57E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame", "Engine.Integration\Engine.Integration.MonoGame\Engine.Integration.MonoGame.csproj", "{C3438D33-0879-44E4-9DF0-D29F5621C44C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Integration.MonoGame", "Engine.Integration\Engine.Integration.MonoGame\Engine.Integration.MonoGame.csproj", "{C3438D33-0879-44E4-9DF0-D29F5621C44C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine.Integration", "Engine.Integration", "{3122C4BF-14AF-E0C0-27A2-43B3E062692D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Integration.LiteNetLib", "Engine.Integration\Engine.Integration.LiteNetLib\Engine.Integration.LiteNetLib.csproj", "{121A7C66-1691-4DA5-B070-A681A83779AC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -115,6 +119,18 @@ Global {C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x64.Build.0 = Release|Any CPU {C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x86.ActiveCfg = Release|Any CPU {C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x86.Build.0 = Release|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Debug|x64.ActiveCfg = Debug|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Debug|x64.Build.0 = Debug|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Debug|x86.ActiveCfg = Debug|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Debug|x86.Build.0 = Debug|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Release|Any CPU.Build.0 = Release|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Release|x64.ActiveCfg = Release|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Release|x64.Build.0 = Release|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Release|x86.ActiveCfg = Release|Any CPU + {121A7C66-1691-4DA5-B070-A681A83779AC}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -123,5 +139,6 @@ Global {E9D1CDC3-5BFF-4C87-AFEB-6CE372709176} = {F88E129A-9A47-4D27-96EE-6EC02F79594B} {3D852C92-BC14-4893-AEF2-50612DAFCD8F} = {F88E129A-9A47-4D27-96EE-6EC02F79594B} {C3438D33-0879-44E4-9DF0-D29F5621C44C} = {823D4020-332D-2C13-F261-6F510F11A57E} + {121A7C66-1691-4DA5-B070-A681A83779AC} = {3122C4BF-14AF-E0C0-27A2-43B3E062692D} EndGlobalSection EndGlobal -- 2.49.1 From 3d183b21cd320e33aae5bd69c84c9951ba83a40f Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 5 Aug 2025 19:41:35 +0300 Subject: [PATCH 54/91] BREAKING CHANGE: renamed namespace & assembly names --- Engine.Core/Abstract/Assignable/IAssignable.cs | 2 +- .../Abstract/Assignable/IHasBehaviourController.cs | 2 +- Engine.Core/Abstract/Assignable/IHasEntity.cs | 2 +- Engine.Core/Abstract/Assignable/IHasStateEnable.cs | 2 +- Engine.Core/Abstract/Assignable/IHasUniverse.cs | 2 +- Engine.Core/Abstract/Assignable/IHasUniverseObject.cs | 2 +- Engine.Core/Abstract/IActive.cs | 2 +- Engine.Core/Abstract/IBehaviour.cs | 2 +- Engine.Core/Abstract/IBehaviour2D.cs | 2 +- Engine.Core/Abstract/IBehaviourCollector.cs | 2 +- Engine.Core/Abstract/IBehaviourController.cs | 2 +- Engine.Core/Abstract/ICamera2D.cs | 2 +- Engine.Core/Abstract/ICoroutineYield.cs | 2 +- Engine.Core/Abstract/IEntity.cs | 2 +- Engine.Core/Abstract/IInitializable.cs | 2 +- Engine.Core/Abstract/INameable.cs | 2 +- Engine.Core/Abstract/IStateEnable.cs | 2 +- Engine.Core/Abstract/ITransform2D.cs | 2 +- Engine.Core/Abstract/IUniverse.cs | 2 +- Engine.Core/Abstract/IUniverseObject.cs | 2 +- Engine.Core/ActiveBehaviourCollector.cs | 2 +- Engine.Core/ActiveBehaviourCollectorSorted.cs | 2 +- Engine.Core/BaseEntity.cs | 2 +- Engine.Core/Behaviour.cs | 2 +- Engine.Core/Behaviour2D.cs | 2 +- Engine.Core/BehaviourBase.cs | 2 +- Engine.Core/BehaviourCollector.cs | 2 +- Engine.Core/BehaviourCollectorSorted.cs | 2 +- Engine.Core/BehaviourController.cs | 2 +- Engine.Core/CoroutineManager.cs | 2 +- Engine.Core/CoroutineYield.cs | 2 +- Engine.Core/Debug/AssertHelpers.cs | 2 +- Engine.Core/Debug/ConsoleLogger.cs | 2 +- Engine.Core/Debug/FileLogger.cs | 2 +- Engine.Core/Debug/ILogger.cs | 2 +- Engine.Core/Debug/LoggerBase.cs | 2 +- Engine.Core/Debug/LoggerContainer.cs | 2 +- Engine.Core/Debug/LoggerExtensions.cs | 2 +- Engine.Core/Debug/LoggerWrapper.cs | 2 +- Engine.Core/Debug/LoggerWrapperExtensions.cs | 2 +- Engine.Core/Engine.Core.csproj | 3 ++- Engine.Core/Exceptions/AssignFailedException.cs | 2 +- Engine.Core/Exceptions/BehaviourNotFoundException.cs | 2 +- Engine.Core/Exceptions/NotAssignedException.cs | 2 +- Engine.Core/Exceptions/NotFoundException.cs | 2 +- Engine.Core/Exceptions/UniverseObjectNotFoundException.cs | 2 +- Engine.Core/Extensions/BehaviourControllerExtensions.cs | 4 ++-- Engine.Core/Extensions/EnumExtensions.cs | 2 +- Engine.Core/Extensions/FloatExtensions.cs | 2 +- Engine.Core/Extensions/TransformExtensions.cs | 2 +- Engine.Core/Extensions/UniverseExtensions.cs | 4 ++-- Engine.Core/Extensions/UniverseObjectExtensions.cs | 4 ++-- Engine.Core/Factory/Abstract/IFactory.cs | 2 +- Engine.Core/Factory/BehaviourControllerFactory.cs | 4 ++-- Engine.Core/Factory/BehaviourFactory.cs | 4 ++-- Engine.Core/Factory/FactoryBase.cs | 4 ++-- Engine.Core/Factory/StateEnableFactory.cs | 4 ++-- Engine.Core/Factory/TransformFactory.cs | 2 +- Engine.Core/Factory/TypeFactory.cs | 2 +- Engine.Core/Factory/UniverseObjectFactory.cs | 4 ++-- Engine.Core/Helpers/Event.cs | 4 ++-- Engine.Core/Helpers/IPool.cs | 2 +- Engine.Core/Helpers/ListPool.cs | 2 +- Engine.Core/Helpers/Pool.cs | 2 +- Engine.Core/Helpers/Progression/IProgressionTracker.cs | 2 +- .../Helpers/Progression/IReadOnlyProgressionTracker.cs | 2 +- Engine.Core/Helpers/Progression/ProgressionTracker.cs | 2 +- Engine.Core/Helpers/Progression/ProgressiveTask.cs | 2 +- Engine.Core/Math.cs | 2 +- Engine.Core/MathExtensions.cs | 2 +- Engine.Core/Preserver.cs | 2 +- Engine.Core/Primitives/AABB.cs | 2 +- Engine.Core/Primitives/Circle.cs | 2 +- Engine.Core/Primitives/ColorHSV.cs | 2 +- Engine.Core/Primitives/ColorHSVA.cs | 2 +- Engine.Core/Primitives/ColorRGB.cs | 2 +- Engine.Core/Primitives/ColorRGBA.cs | 2 +- Engine.Core/Primitives/Line2D.cs | 2 +- Engine.Core/Primitives/Line2DEquation.cs | 2 +- Engine.Core/Primitives/Projection1D.cs | 2 +- Engine.Core/Primitives/Quaternion.cs | 2 +- Engine.Core/Primitives/Ray2D.cs | 2 +- Engine.Core/Primitives/Shape2D.cs | 2 +- Engine.Core/Primitives/Triangle.cs | 2 +- Engine.Core/Primitives/Vector2D.cs | 2 +- Engine.Core/Primitives/Vector3D.cs | 2 +- .../Attributes/IgnoreSerializationAttribute.cs | 2 +- .../Serialization/Attributes/SerializeAllAttribute.cs | 2 +- .../Serialization/Attributes/SerializeAttribute.cs | 2 +- Engine.Core/Serialization/EntityReference.cs | 2 +- Engine.Core/Serialization/EntityRegistry.cs | 2 +- Engine.Core/Serialization/ISerializer.cs | 2 +- Engine.Core/Serialization/SerializedClass.cs | 4 ++-- Engine.Core/Serialization/TypeContainer.cs | 2 +- Engine.Core/Serialization/Utils.cs | 2 +- Engine.Core/StateEnable.cs | 2 +- Engine.Core/Static/Internal/Constants.cs | 2 +- Engine.Core/Systems/Abstract/IDraw.cs | 2 +- Engine.Core/Systems/Abstract/IEnterUniverse.cs | 2 +- Engine.Core/Systems/Abstract/IExitUniverse.cs | 2 +- Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs | 2 +- Engine.Core/Systems/Abstract/ILastFrameUpdate.cs | 2 +- Engine.Core/Systems/Abstract/IPostDraw.cs | 2 +- Engine.Core/Systems/Abstract/IPostUpdate.cs | 2 +- Engine.Core/Systems/Abstract/IPreDraw.cs | 2 +- Engine.Core/Systems/Abstract/IPreUpdate.cs | 2 +- Engine.Core/Systems/Abstract/IUpdate.cs | 2 +- Engine.Core/Systems/DrawManager.cs | 2 +- Engine.Core/Systems/UniverseEntranceManager.cs | 2 +- Engine.Core/Systems/UpdateManager.cs | 2 +- Engine.Core/Transform2D.cs | 4 ++-- Engine.Core/Universe.cs | 2 +- Engine.Core/UniverseObject.cs | 2 +- Engine.Core/UniverseTime.cs | 2 +- .../Engine.Integration.LiteNetLib.csproj | 4 ++-- .../Engine.Integration.LiteNetLib/LiteNetLibClient.cs | 6 +++--- .../LiteNetLibClientConnection.cs | 2 +- .../LiteNetLibCommunicatorBase.cs | 6 +++--- .../Engine.Integration.LiteNetLib/LiteNetLibServer.cs | 6 +++--- .../LiteNetLibServerConnection.cs | 2 +- .../Packers/AABBNetPacker.cs | 4 ++-- .../Packers/CircleNetPacker.cs | 4 ++-- .../Packers/ColorHSVNetPacker.cs | 4 ++-- .../Packers/ColorRGBANetPacker.cs | 4 ++-- .../Packers/ColorRGBNetPacker.cs | 4 ++-- .../Packers/Line2DEquationNetPacker.cs | 4 ++-- .../Packers/Line2DNetPacker.cs | 4 ++-- .../Packers/Projection1DNetPacker.cs | 4 ++-- .../Packers/QuaternionNetPacker.cs | 4 ++-- .../Packers/Shape2DNetPacker.cs | 4 ++-- .../Packers/TriangleNetPacker.cs | 4 ++-- .../Packers/Vector2DNetPacker.cs | 4 ++-- .../Packers/Vector3DNetPacker.cs | 4 ++-- .../Abstract/IDrawableSprite.cs | 4 ++-- .../Abstract/IDrawableTriangle.cs | 4 ++-- .../Engine.Integration.MonoGame/Abstract/ILoadContent.cs | 4 ++-- .../Engine.Integration.MonoGame/Abstract/ISpriteBatch.cs | 4 ++-- .../Abstract/ITriangleBatch.cs | 4 ++-- .../Behaviours/DrawableShape.cs | 4 ++-- .../Behaviours/KeyboardInputs.cs | 6 +++--- .../Behaviours/LoadContentManager.cs | 4 ++-- .../Behaviours/MonoGameCamera2D.cs | 8 ++++---- .../Behaviours/SpriteBatchWrapper.cs | 4 ++-- .../Behaviours/SpriteBatcher.cs | 4 ++-- .../Behaviours/TriangleBatcher.cs | 4 ++-- .../Engine.Integration.MonoGame.csproj | 3 ++- .../Engine.Integration.MonoGame/EngineConverter.cs | 4 ++-- .../Engine.Integration.MonoGame/MonoGameWindow.cs | 4 ++-- .../Engine.Integration.MonoGame/TriangleBatch.cs | 4 ++-- .../UniverseObjects/MonoGameWindowContainer.cs | 6 +++--- Engine.Physics2D/Abstract/ICircleCollider2D.cs | 4 ++-- Engine.Physics2D/Abstract/ICollider2D.cs | 4 ++-- Engine.Physics2D/Abstract/ICollisionDetector2D.cs | 2 +- Engine.Physics2D/Abstract/ICollisionResolver2D.cs | 2 +- Engine.Physics2D/Abstract/IPhysicsEngine2D.cs | 4 ++-- Engine.Physics2D/Abstract/IPhysicsMaterial2D.cs | 2 +- Engine.Physics2D/Abstract/IRaycastResolver2D.cs | 4 ++-- Engine.Physics2D/Abstract/IRigidBody2D.cs | 4 ++-- Engine.Physics2D/Abstract/IShapeCollider2D.cs | 4 ++-- Engine.Physics2D/Abstract/RaycastResult.cs | 4 ++-- Engine.Physics2D/Abstract/Updates/IPhysicsIteration.cs | 4 ++-- Engine.Physics2D/Abstract/Updates/IPhysicsUpdate.cs | 4 ++-- Engine.Physics2D/Abstract/Updates/IPostPhysicsUpdate.cs | 4 ++-- Engine.Physics2D/Abstract/Updates/IPrePhysicsUpdate.cs | 4 ++-- Engine.Physics2D/Collider2DBase.cs | 4 ++-- Engine.Physics2D/Collider2DCircle.cs | 4 ++-- Engine.Physics2D/Collider2DShape.cs | 4 ++-- Engine.Physics2D/CollisionDetectionInformation.cs | 4 ++-- Engine.Physics2D/CollisionDetector2D.cs | 6 +++--- Engine.Physics2D/CollisionResolver2D.cs | 4 ++-- Engine.Physics2D/Engine.Physics2D.csproj | 3 ++- Engine.Physics2D/Physics2D.cs | 4 ++-- Engine.Physics2D/PhysicsCoroutineManager.cs | 4 ++-- Engine.Physics2D/PhysicsEngine2D.cs | 4 ++-- Engine.Physics2D/PhysicsEngine2DStandalone.cs | 4 ++-- Engine.Physics2D/PhysicsMaterial2D.cs | 2 +- Engine.Physics2D/PhysicsMaterial2DDefault.cs | 2 +- Engine.Physics2D/Preserver.cs | 2 +- Engine.Physics2D/RaycastResolver2D.cs | 4 ++-- Engine.Physics2D/RigidBody2D.cs | 4 ++-- .../Converters/Abstract/IEngineTypeYamlConverter.cs | 6 +++--- .../Converters/BehaviourControllerConverter.cs | 6 +++--- .../Converters/BehaviourConverter.cs | 6 +++--- .../Converters/EngineTypeYamlConverterBase.cs | 6 +++--- .../Converters/Primitives/AABBConverter.cs | 4 ++-- .../Converters/Primitives/CircleConverter.cs | 4 ++-- .../Converters/Primitives/ColorHSVConverter.cs | 4 ++-- .../Converters/Primitives/ColorRGBAConverter.cs | 4 ++-- .../Converters/Primitives/ColorRGBConverter.cs | 4 ++-- .../Converters/Primitives/Line2DConverter.cs | 4 ++-- .../Converters/Primitives/Line2DEquationConverter.cs | 4 ++-- .../Converters/Primitives/Projection1DConverter.cs | 4 ++-- .../Converters/Primitives/QuaternionConverter.cs | 4 ++-- .../Converters/Primitives/Shape2DConverter.cs | 4 ++-- .../Converters/Primitives/TriangleConverter.cs | 4 ++-- .../Converters/Primitives/Vector2DConverter.cs | 4 ++-- .../Converters/Primitives/Vector3DConverter.cs | 4 ++-- .../Converters/SerializedClassConverter.cs | 8 ++++---- .../Converters/StateEnableConverter.cs | 6 +++--- .../Converters/TypeContainerConverter.cs | 6 +++--- .../Converters/UniverseConverter.cs | 6 +++--- .../Converters/UniverseObjectConverter.cs | 6 +++--- .../Engine.Serializers.Yaml.csproj | 3 ++- .../SerializerInProgressException.cs | 2 +- .../Engine.Serializers.Yaml/YamlSerializer.cs | 6 +++--- Engine.Systems/Engine.Systems.csproj | 3 ++- Engine.Systems/Input/IButtonInputs.cs | 4 ++-- Engine.Systems/Network/Abstract/IConnection.cs | 2 +- Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs | 2 +- Engine.Systems/Network/Abstract/INetworkCommunicator.cs | 4 ++-- Engine.Systems/Network/Abstract/INetworkEntity.cs | 4 ++-- Engine.Systems/Network/Abstract/INetworkManager.cs | 4 ++-- Engine.Systems/Network/Abstract/INetworkPacket.cs | 2 +- Engine.Systems/Network/Abstract/IPacketListenerClient.cs | 2 +- Engine.Systems/Network/Abstract/IPacketListenerServer.cs | 2 +- Engine.Systems/Network/Abstract/PacketDelivery.cs | 2 +- Engine.Systems/Network/NetworkManager.cs | 4 ++-- Engine.Systems/Preserver.cs | 2 +- Engine.Systems/StateMachine/IState.cs | 4 ++-- Engine.Systems/StateMachine/State.cs | 4 ++-- Engine.Systems/StateMachine/StateBehaviourBase.cs | 4 ++-- Engine.Systems/StateMachine/StateMachine.cs | 6 +++--- Engine.Systems/StateMachine/StateTransition.cs | 2 +- Engine.Systems/Time/IReadOnlyStopwatch.cs | 4 ++-- Engine.Systems/Time/IReadOnlyTicker.cs | 4 ++-- Engine.Systems/Time/IReadOnlyTimer.cs | 4 ++-- Engine.Systems/Time/IStopwatch.cs | 2 +- Engine.Systems/Time/ITicker.cs | 4 ++-- Engine.Systems/Time/ITimer.cs | 2 +- Engine.Systems/Time/Stopwatch.cs | 4 ++-- Engine.Systems/Time/TickerStopwatch.cs | 4 ++-- Engine.Systems/Time/TickerTimer.cs | 4 ++-- Engine.Systems/Time/Timer.cs | 4 ++-- Engine.Systems/Time/TimerState.cs | 2 +- Engine.Systems/Tween/Easings.cs | 4 ++-- .../Tween/EngineExtensions/TweenAABBExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenCamera2DExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenCircleExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenColorExtensions.cs | 4 ++-- .../EngineExtensions/TweenLine2DEquationExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenLine2DExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenProjection1DExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenQuaternionExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenShape2DExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenTransform2DExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenTriangleExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenVector2DExtensions.cs | 4 ++-- .../Tween/EngineExtensions/TweenVector3DExtensions.cs | 4 ++-- Engine.Systems/Tween/IEasing.cs | 2 +- Engine.Systems/Tween/ITween.cs | 4 ++-- Engine.Systems/Tween/ITweenManager.cs | 2 +- Engine.Systems/Tween/Tween.cs | 4 ++-- Engine.Systems/Tween/TweenExtensions.cs | 2 +- Engine.Systems/Tween/TweenManager.cs | 4 ++-- Engine.Systems/Tween/TweenState.cs | 2 +- .../Tween/Yields/WaitForTweenCompleteCoroutineYield.cs | 4 ++-- .../Tween/Yields/WaitForTweenDoneCoroutineYield.cs | 4 ++-- Engine/Engine.csproj | 3 ++- Engine/Preserver.cs | 2 +- 259 files changed, 411 insertions(+), 405 deletions(-) diff --git a/Engine.Core/Abstract/Assignable/IAssignable.cs b/Engine.Core/Abstract/Assignable/IAssignable.cs index b4cac2a..f5c1177 100644 --- a/Engine.Core/Abstract/Assignable/IAssignable.cs +++ b/Engine.Core/Abstract/Assignable/IAssignable.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Indicates the class implementing it has Assignable fields that are necessary for the engine to work properly. diff --git a/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs b/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs index 6feff7e..387c015 100644 --- a/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs +++ b/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Indicates the object is an with an assignable field. diff --git a/Engine.Core/Abstract/Assignable/IHasEntity.cs b/Engine.Core/Abstract/Assignable/IHasEntity.cs index 205ffe5..b972510 100644 --- a/Engine.Core/Abstract/Assignable/IHasEntity.cs +++ b/Engine.Core/Abstract/Assignable/IHasEntity.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Indicates the object is an with an assignable field. diff --git a/Engine.Core/Abstract/Assignable/IHasStateEnable.cs b/Engine.Core/Abstract/Assignable/IHasStateEnable.cs index 0a5c766..2f010bb 100644 --- a/Engine.Core/Abstract/Assignable/IHasStateEnable.cs +++ b/Engine.Core/Abstract/Assignable/IHasStateEnable.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Indicates the object is an with an assignable field. diff --git a/Engine.Core/Abstract/Assignable/IHasUniverse.cs b/Engine.Core/Abstract/Assignable/IHasUniverse.cs index bcf13f2..587a77f 100644 --- a/Engine.Core/Abstract/Assignable/IHasUniverse.cs +++ b/Engine.Core/Abstract/Assignable/IHasUniverse.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Indicates the object is an with an assignable field. diff --git a/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs b/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs index ad1081a..dd21850 100644 --- a/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs +++ b/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Indicates the object is an with an assignable field. diff --git a/Engine.Core/Abstract/IActive.cs b/Engine.Core/Abstract/IActive.cs index 7fbfd6c..9bfa751 100644 --- a/Engine.Core/Abstract/IActive.cs +++ b/Engine.Core/Abstract/IActive.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an entity which can be active or not. diff --git a/Engine.Core/Abstract/IBehaviour.cs b/Engine.Core/Abstract/IBehaviour.cs index 25ec8cd..48ca81d 100644 --- a/Engine.Core/Abstract/IBehaviour.cs +++ b/Engine.Core/Abstract/IBehaviour.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a behaviour that any object in the engine that might use to interact with itself or other objects. diff --git a/Engine.Core/Abstract/IBehaviour2D.cs b/Engine.Core/Abstract/IBehaviour2D.cs index b0918d4..3249ef9 100644 --- a/Engine.Core/Abstract/IBehaviour2D.cs +++ b/Engine.Core/Abstract/IBehaviour2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface IBehaviour2D : IBehaviour { diff --git a/Engine.Core/Abstract/IBehaviourCollector.cs b/Engine.Core/Abstract/IBehaviourCollector.cs index ad9ed56..674236d 100644 --- a/Engine.Core/Abstract/IBehaviourCollector.cs +++ b/Engine.Core/Abstract/IBehaviourCollector.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a collector for the class type of . diff --git a/Engine.Core/Abstract/IBehaviourController.cs b/Engine.Core/Abstract/IBehaviourController.cs index 590e2e8..87af209 100644 --- a/Engine.Core/Abstract/IBehaviourController.cs +++ b/Engine.Core/Abstract/IBehaviourController.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a controller for managing s. Connected to an . diff --git a/Engine.Core/Abstract/ICamera2D.cs b/Engine.Core/Abstract/ICamera2D.cs index 30bc362..4c12105 100644 --- a/Engine.Core/Abstract/ICamera2D.cs +++ b/Engine.Core/Abstract/ICamera2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a 2D camera in the engine. diff --git a/Engine.Core/Abstract/ICoroutineYield.cs b/Engine.Core/Abstract/ICoroutineYield.cs index 230ca21..c3e04a8 100644 --- a/Engine.Core/Abstract/ICoroutineYield.cs +++ b/Engine.Core/Abstract/ICoroutineYield.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface ICoroutineYield { diff --git a/Engine.Core/Abstract/IEntity.cs b/Engine.Core/Abstract/IEntity.cs index 3eeefdd..53a719a 100644 --- a/Engine.Core/Abstract/IEntity.cs +++ b/Engine.Core/Abstract/IEntity.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a basic entity in the engine. diff --git a/Engine.Core/Abstract/IInitializable.cs b/Engine.Core/Abstract/IInitializable.cs index 64230d3..a7f846d 100644 --- a/Engine.Core/Abstract/IInitializable.cs +++ b/Engine.Core/Abstract/IInitializable.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an entity that can be initialized and finalized. This information is useful for objects we know that are not in use and can be either recycled or dropped for garbage collection. diff --git a/Engine.Core/Abstract/INameable.cs b/Engine.Core/Abstract/INameable.cs index 93442be..08b287b 100644 --- a/Engine.Core/Abstract/INameable.cs +++ b/Engine.Core/Abstract/INameable.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an entity with a name. diff --git a/Engine.Core/Abstract/IStateEnable.cs b/Engine.Core/Abstract/IStateEnable.cs index 4c61668..96925f5 100644 --- a/Engine.Core/Abstract/IStateEnable.cs +++ b/Engine.Core/Abstract/IStateEnable.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an entity with an enable state that can be toggled. diff --git a/Engine.Core/Abstract/ITransform2D.cs b/Engine.Core/Abstract/ITransform2D.cs index 495ef9e..d899386 100644 --- a/Engine.Core/Abstract/ITransform2D.cs +++ b/Engine.Core/Abstract/ITransform2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents the transformation properties of an object such as position, scale, and rotation in 2D space. diff --git a/Engine.Core/Abstract/IUniverse.cs b/Engine.Core/Abstract/IUniverse.cs index 5f99c8c..e0896a1 100644 --- a/Engine.Core/Abstract/IUniverse.cs +++ b/Engine.Core/Abstract/IUniverse.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a universe responsible for managing s. diff --git a/Engine.Core/Abstract/IUniverseObject.cs b/Engine.Core/Abstract/IUniverseObject.cs index b2b1afd..64515c9 100644 --- a/Engine.Core/Abstract/IUniverseObject.cs +++ b/Engine.Core/Abstract/IUniverseObject.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an that can enter and exit a universe within the system. diff --git a/Engine.Core/ActiveBehaviourCollector.cs b/Engine.Core/ActiveBehaviourCollector.cs index f138a59..f5fbd06 100644 --- a/Engine.Core/ActiveBehaviourCollector.cs +++ b/Engine.Core/ActiveBehaviourCollector.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class ActiveBehaviourCollector : IBehaviourCollector where T : class, IBehaviour { diff --git a/Engine.Core/ActiveBehaviourCollectorSorted.cs b/Engine.Core/ActiveBehaviourCollectorSorted.cs index 292f6b5..7db7945 100644 --- a/Engine.Core/ActiveBehaviourCollectorSorted.cs +++ b/Engine.Core/ActiveBehaviourCollectorSorted.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class ActiveBehaviourCollectorSorted : ActiveBehaviourCollector where T : class, IBehaviour { diff --git a/Engine.Core/BaseEntity.cs b/Engine.Core/BaseEntity.cs index e98e387..a16b072 100644 --- a/Engine.Core/BaseEntity.cs +++ b/Engine.Core/BaseEntity.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public abstract class BaseEntity : IEntity { diff --git a/Engine.Core/Behaviour.cs b/Engine.Core/Behaviour.cs index 729c14e..06b628f 100644 --- a/Engine.Core/Behaviour.cs +++ b/Engine.Core/Behaviour.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public abstract class Behaviour : BehaviourBase { diff --git a/Engine.Core/Behaviour2D.cs b/Engine.Core/Behaviour2D.cs index a6d22c2..6622cc1 100644 --- a/Engine.Core/Behaviour2D.cs +++ b/Engine.Core/Behaviour2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public abstract class Behaviour2D : Behaviour, IBehaviour2D { diff --git a/Engine.Core/BehaviourBase.cs b/Engine.Core/BehaviourBase.cs index 37b521a..27012c0 100644 --- a/Engine.Core/BehaviourBase.cs +++ b/Engine.Core/BehaviourBase.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; [System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")] public abstract class BehaviourBase : BaseEntity, IBehaviour diff --git a/Engine.Core/BehaviourCollector.cs b/Engine.Core/BehaviourCollector.cs index 4eedb67..56617c2 100644 --- a/Engine.Core/BehaviourCollector.cs +++ b/Engine.Core/BehaviourCollector.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class BehaviourCollector : IBehaviourCollector where T : class { diff --git a/Engine.Core/BehaviourCollectorSorted.cs b/Engine.Core/BehaviourCollectorSorted.cs index 35effbc..811bb63 100644 --- a/Engine.Core/BehaviourCollectorSorted.cs +++ b/Engine.Core/BehaviourCollectorSorted.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class BehaviourCollectorSorted : BehaviourCollector where T : class { diff --git a/Engine.Core/BehaviourController.cs b/Engine.Core/BehaviourController.cs index 7da0e27..45497aa 100644 --- a/Engine.Core/BehaviourController.cs +++ b/Engine.Core/BehaviourController.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; [System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")] public class BehaviourController : BaseEntity, IBehaviourController diff --git a/Engine.Core/CoroutineManager.cs b/Engine.Core/CoroutineManager.cs index 3b60152..16f9390 100644 --- a/Engine.Core/CoroutineManager.cs +++ b/Engine.Core/CoroutineManager.cs @@ -1,7 +1,7 @@ using System.Collections; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class CoroutineManager : Behaviour, IUpdate { diff --git a/Engine.Core/CoroutineYield.cs b/Engine.Core/CoroutineYield.cs index 014a1ee..44e3f5b 100644 --- a/Engine.Core/CoroutineYield.cs +++ b/Engine.Core/CoroutineYield.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class CoroutineYield(Func condition) : ICoroutineYield { diff --git a/Engine.Core/Debug/AssertHelpers.cs b/Engine.Core/Debug/AssertHelpers.cs index 426ca43..6a2f9e5 100644 --- a/Engine.Core/Debug/AssertHelpers.cs +++ b/Engine.Core/Debug/AssertHelpers.cs @@ -1,6 +1,6 @@ using System.Runtime.CompilerServices; -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public static class Assert { diff --git a/Engine.Core/Debug/ConsoleLogger.cs b/Engine.Core/Debug/ConsoleLogger.cs index 242b818..a76b699 100644 --- a/Engine.Core/Debug/ConsoleLogger.cs +++ b/Engine.Core/Debug/ConsoleLogger.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public class ConsoleLogger : LoggerBase { diff --git a/Engine.Core/Debug/FileLogger.cs b/Engine.Core/Debug/FileLogger.cs index 98b4032..ff305e2 100644 --- a/Engine.Core/Debug/FileLogger.cs +++ b/Engine.Core/Debug/FileLogger.cs @@ -1,7 +1,7 @@ using System; using System.IO; -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public class FileLogger : LoggerBase { diff --git a/Engine.Core/Debug/ILogger.cs b/Engine.Core/Debug/ILogger.cs index babe6b6..664ec45 100644 --- a/Engine.Core/Debug/ILogger.cs +++ b/Engine.Core/Debug/ILogger.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public interface ILogger { diff --git a/Engine.Core/Debug/LoggerBase.cs b/Engine.Core/Debug/LoggerBase.cs index 9bbcf10..2626b69 100644 --- a/Engine.Core/Debug/LoggerBase.cs +++ b/Engine.Core/Debug/LoggerBase.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public abstract class LoggerBase : ILogger { diff --git a/Engine.Core/Debug/LoggerContainer.cs b/Engine.Core/Debug/LoggerContainer.cs index 22f3490..5cbc259 100644 --- a/Engine.Core/Debug/LoggerContainer.cs +++ b/Engine.Core/Debug/LoggerContainer.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public class LoggerContainer : Behaviour, ILogger { diff --git a/Engine.Core/Debug/LoggerExtensions.cs b/Engine.Core/Debug/LoggerExtensions.cs index bc58c3d..d63421a 100644 --- a/Engine.Core/Debug/LoggerExtensions.cs +++ b/Engine.Core/Debug/LoggerExtensions.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics; -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public static class LoggerExtensions { diff --git a/Engine.Core/Debug/LoggerWrapper.cs b/Engine.Core/Debug/LoggerWrapper.cs index 15e69fb..7ac1335 100644 --- a/Engine.Core/Debug/LoggerWrapper.cs +++ b/Engine.Core/Debug/LoggerWrapper.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public class LoggerWrapper(ILogger firstLogger, ILogger secondLogger) : ILogger { diff --git a/Engine.Core/Debug/LoggerWrapperExtensions.cs b/Engine.Core/Debug/LoggerWrapperExtensions.cs index c98bece..ce5bfc6 100644 --- a/Engine.Core/Debug/LoggerWrapperExtensions.cs +++ b/Engine.Core/Debug/LoggerWrapperExtensions.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core.Debug; +namespace Engine.Core.Debug; public static class LoggerWrapperExtensions { diff --git a/Engine.Core/Engine.Core.csproj b/Engine.Core/Engine.Core.csproj index b71dec1..f777948 100644 --- a/Engine.Core/Engine.Core.csproj +++ b/Engine.Core/Engine.Core.csproj @@ -4,7 +4,8 @@ net9.0 false enable - Syntriax.Engine.Core + Engine.Core + Engine.Core diff --git a/Engine.Core/Exceptions/AssignFailedException.cs b/Engine.Core/Exceptions/AssignFailedException.cs index 2cc474c..8294f17 100644 --- a/Engine.Core/Exceptions/AssignFailedException.cs +++ b/Engine.Core/Exceptions/AssignFailedException.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Exceptions; +namespace Engine.Core.Exceptions; public class AssignFailedException(string? message) : Exception(message) { diff --git a/Engine.Core/Exceptions/BehaviourNotFoundException.cs b/Engine.Core/Exceptions/BehaviourNotFoundException.cs index 36ca458..c340f33 100644 --- a/Engine.Core/Exceptions/BehaviourNotFoundException.cs +++ b/Engine.Core/Exceptions/BehaviourNotFoundException.cs @@ -1,3 +1,3 @@ -namespace Syntriax.Engine.Core.Exceptions; +namespace Engine.Core.Exceptions; public class BehaviourNotFoundException(string? message) : NotFoundException(message); diff --git a/Engine.Core/Exceptions/NotAssignedException.cs b/Engine.Core/Exceptions/NotAssignedException.cs index bd1923a..9bdd476 100644 --- a/Engine.Core/Exceptions/NotAssignedException.cs +++ b/Engine.Core/Exceptions/NotAssignedException.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Exceptions; +namespace Engine.Core.Exceptions; public class NotAssignedException(string? message) : Exception(message) { diff --git a/Engine.Core/Exceptions/NotFoundException.cs b/Engine.Core/Exceptions/NotFoundException.cs index b6b0d69..77a9656 100644 --- a/Engine.Core/Exceptions/NotFoundException.cs +++ b/Engine.Core/Exceptions/NotFoundException.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Exceptions; +namespace Engine.Core.Exceptions; public class NotFoundException(string? message) : Exception(message) { diff --git a/Engine.Core/Exceptions/UniverseObjectNotFoundException.cs b/Engine.Core/Exceptions/UniverseObjectNotFoundException.cs index 9b68b4d..67f909e 100644 --- a/Engine.Core/Exceptions/UniverseObjectNotFoundException.cs +++ b/Engine.Core/Exceptions/UniverseObjectNotFoundException.cs @@ -1,3 +1,3 @@ -namespace Syntriax.Engine.Core.Exceptions; +namespace Engine.Core.Exceptions; public class UniverseObjectNotFoundException(string? message) : NotFoundException(message); diff --git a/Engine.Core/Extensions/BehaviourControllerExtensions.cs b/Engine.Core/Extensions/BehaviourControllerExtensions.cs index 9dbfa46..bcf0773 100644 --- a/Engine.Core/Extensions/BehaviourControllerExtensions.cs +++ b/Engine.Core/Extensions/BehaviourControllerExtensions.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using Syntriax.Engine.Core.Exceptions; +using Engine.Core.Exceptions; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public static class BehaviourControllerExtensions { diff --git a/Engine.Core/Extensions/EnumExtensions.cs b/Engine.Core/Extensions/EnumExtensions.cs index 1f7e8b1..06e4a01 100644 --- a/Engine.Core/Extensions/EnumExtensions.cs +++ b/Engine.Core/Extensions/EnumExtensions.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public static class EnumExtensions { diff --git a/Engine.Core/Extensions/FloatExtensions.cs b/Engine.Core/Extensions/FloatExtensions.cs index 019bc39..fd5b828 100644 --- a/Engine.Core/Extensions/FloatExtensions.cs +++ b/Engine.Core/Extensions/FloatExtensions.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public static class FloatExtensions { diff --git a/Engine.Core/Extensions/TransformExtensions.cs b/Engine.Core/Extensions/TransformExtensions.cs index 33e349a..8300449 100644 --- a/Engine.Core/Extensions/TransformExtensions.cs +++ b/Engine.Core/Extensions/TransformExtensions.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public static class TransformExtensions { diff --git a/Engine.Core/Extensions/UniverseExtensions.cs b/Engine.Core/Extensions/UniverseExtensions.cs index 2624712..e7379b0 100644 --- a/Engine.Core/Extensions/UniverseExtensions.cs +++ b/Engine.Core/Extensions/UniverseExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core.Exceptions; +using Engine.Core.Exceptions; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public static class UniverseExtensions { diff --git a/Engine.Core/Extensions/UniverseObjectExtensions.cs b/Engine.Core/Extensions/UniverseObjectExtensions.cs index 96d5ec3..2f843cb 100644 --- a/Engine.Core/Extensions/UniverseObjectExtensions.cs +++ b/Engine.Core/Extensions/UniverseObjectExtensions.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using Syntriax.Engine.Core.Exceptions; +using Engine.Core.Exceptions; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public static class UniverseObjectExtensions { diff --git a/Engine.Core/Factory/Abstract/IFactory.cs b/Engine.Core/Factory/Abstract/IFactory.cs index 2d61656..659f073 100644 --- a/Engine.Core/Factory/Abstract/IFactory.cs +++ b/Engine.Core/Factory/Abstract/IFactory.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core.Factory.Abstract; +namespace Engine.Core.Factory.Abstract; public interface IFactory where TInterface : class { diff --git a/Engine.Core/Factory/BehaviourControllerFactory.cs b/Engine.Core/Factory/BehaviourControllerFactory.cs index 13f8c46..fb0e6bf 100644 --- a/Engine.Core/Factory/BehaviourControllerFactory.cs +++ b/Engine.Core/Factory/BehaviourControllerFactory.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core.Exceptions; +using Engine.Core.Exceptions; -namespace Syntriax.Engine.Core.Factory; +namespace Engine.Core.Factory; public class BehaviourControllerFactory { diff --git a/Engine.Core/Factory/BehaviourFactory.cs b/Engine.Core/Factory/BehaviourFactory.cs index 0502465..4c6bff8 100644 --- a/Engine.Core/Factory/BehaviourFactory.cs +++ b/Engine.Core/Factory/BehaviourFactory.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core.Exceptions; +using Engine.Core.Exceptions; -namespace Syntriax.Engine.Core.Factory; +namespace Engine.Core.Factory; public class BehaviourFactory { diff --git a/Engine.Core/Factory/FactoryBase.cs b/Engine.Core/Factory/FactoryBase.cs index 97f8067..3e90cd8 100644 --- a/Engine.Core/Factory/FactoryBase.cs +++ b/Engine.Core/Factory/FactoryBase.cs @@ -1,7 +1,7 @@ using System; -using Syntriax.Engine.Core.Factory.Abstract; +using Engine.Core.Factory.Abstract; -namespace Syntriax.Engine.Core.Factory; +namespace Engine.Core.Factory; public abstract class FactoryBase : IFactory where TInterface : class diff --git a/Engine.Core/Factory/StateEnableFactory.cs b/Engine.Core/Factory/StateEnableFactory.cs index e7f235a..7bc950f 100644 --- a/Engine.Core/Factory/StateEnableFactory.cs +++ b/Engine.Core/Factory/StateEnableFactory.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core.Exceptions; +using Engine.Core.Exceptions; -namespace Syntriax.Engine.Core.Factory; +namespace Engine.Core.Factory; public class StateEnableFactory { diff --git a/Engine.Core/Factory/TransformFactory.cs b/Engine.Core/Factory/TransformFactory.cs index 6e22f77..182e080 100644 --- a/Engine.Core/Factory/TransformFactory.cs +++ b/Engine.Core/Factory/TransformFactory.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core.Factory; +namespace Engine.Core.Factory; public class TransformFactory { diff --git a/Engine.Core/Factory/TypeFactory.cs b/Engine.Core/Factory/TypeFactory.cs index aa770e1..5f92c68 100644 --- a/Engine.Core/Factory/TypeFactory.cs +++ b/Engine.Core/Factory/TypeFactory.cs @@ -3,7 +3,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -namespace Syntriax.Engine.Core.Factory; +namespace Engine.Core.Factory; public static class TypeFactory { diff --git a/Engine.Core/Factory/UniverseObjectFactory.cs b/Engine.Core/Factory/UniverseObjectFactory.cs index 917ee18..0d7b21f 100644 --- a/Engine.Core/Factory/UniverseObjectFactory.cs +++ b/Engine.Core/Factory/UniverseObjectFactory.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core.Exceptions; +using Engine.Core.Exceptions; -namespace Syntriax.Engine.Core.Factory; +namespace Engine.Core.Factory; public class UniverseObjectFactory { diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index c216515..13d112c 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using Syntriax.Engine.Core.Debug; +using Engine.Core.Debug; -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a simple event with no parameters. diff --git a/Engine.Core/Helpers/IPool.cs b/Engine.Core/Helpers/IPool.cs index e151ff6..09849e9 100644 --- a/Engine.Core/Helpers/IPool.cs +++ b/Engine.Core/Helpers/IPool.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface IPool { diff --git a/Engine.Core/Helpers/ListPool.cs b/Engine.Core/Helpers/ListPool.cs index 2377e79..149e015 100644 --- a/Engine.Core/Helpers/ListPool.cs +++ b/Engine.Core/Helpers/ListPool.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class ListPool : IPool> { diff --git a/Engine.Core/Helpers/Pool.cs b/Engine.Core/Helpers/Pool.cs index 1b42c77..980823f 100644 --- a/Engine.Core/Helpers/Pool.cs +++ b/Engine.Core/Helpers/Pool.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class Pool : IPool { diff --git a/Engine.Core/Helpers/Progression/IProgressionTracker.cs b/Engine.Core/Helpers/Progression/IProgressionTracker.cs index 7edd8a6..89f5653 100644 --- a/Engine.Core/Helpers/Progression/IProgressionTracker.cs +++ b/Engine.Core/Helpers/Progression/IProgressionTracker.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface IProgressionTracker : IReadOnlyProgressionTracker { diff --git a/Engine.Core/Helpers/Progression/IReadOnlyProgressionTracker.cs b/Engine.Core/Helpers/Progression/IReadOnlyProgressionTracker.cs index a92034d..e65f859 100644 --- a/Engine.Core/Helpers/Progression/IReadOnlyProgressionTracker.cs +++ b/Engine.Core/Helpers/Progression/IReadOnlyProgressionTracker.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface IReadOnlyProgressionTracker { diff --git a/Engine.Core/Helpers/Progression/ProgressionTracker.cs b/Engine.Core/Helpers/Progression/ProgressionTracker.cs index 93cf936..75fec53 100644 --- a/Engine.Core/Helpers/Progression/ProgressionTracker.cs +++ b/Engine.Core/Helpers/Progression/ProgressionTracker.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class ProgressionTracker : IProgressionTracker { diff --git a/Engine.Core/Helpers/Progression/ProgressiveTask.cs b/Engine.Core/Helpers/Progression/ProgressiveTask.cs index 701027c..05ae750 100644 --- a/Engine.Core/Helpers/Progression/ProgressiveTask.cs +++ b/Engine.Core/Helpers/Progression/ProgressiveTask.cs @@ -1,6 +1,6 @@ using System.Threading.Tasks; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public record struct ProgressiveTask(IReadOnlyProgressionTracker ProgressionTracker, Task Task) { diff --git a/Engine.Core/Math.cs b/Engine.Core/Math.cs index 456dec5..a8f939e 100644 --- a/Engine.Core/Math.cs +++ b/Engine.Core/Math.cs @@ -1,7 +1,7 @@ using System; using System.Numerics; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public static class Math { diff --git a/Engine.Core/MathExtensions.cs b/Engine.Core/MathExtensions.cs index e98df7f..63f2dcb 100644 --- a/Engine.Core/MathExtensions.cs +++ b/Engine.Core/MathExtensions.cs @@ -1,7 +1,7 @@ using System; using System.Numerics; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public static class MathExtensions { diff --git a/Engine.Core/Preserver.cs b/Engine.Core/Preserver.cs index a7f330e..1832601 100644 --- a/Engine.Core/Preserver.cs +++ b/Engine.Core/Preserver.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core +namespace Engine.Core { // This is pretty much so the assembly gets loaded automatically because // the builds include the assembly but sometimes doesn't link load it at startup. diff --git a/Engine.Core/Primitives/AABB.cs b/Engine.Core/Primitives/AABB.cs index 142e885..3789526 100644 --- a/Engine.Core/Primitives/AABB.cs +++ b/Engine.Core/Primitives/AABB.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an Axis-Aligned Bounding Box (AABB) in 2D space. diff --git a/Engine.Core/Primitives/Circle.cs b/Engine.Core/Primitives/Circle.cs index 9c3f2ae..bfd1632 100644 --- a/Engine.Core/Primitives/Circle.cs +++ b/Engine.Core/Primitives/Circle.cs @@ -1,6 +1,6 @@ using System.Diagnostics; -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a 2D circle. diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index 6fb9b2c..8cc7b42 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an HSV color. diff --git a/Engine.Core/Primitives/ColorHSVA.cs b/Engine.Core/Primitives/ColorHSVA.cs index ee49c6a..3f073c8 100644 --- a/Engine.Core/Primitives/ColorHSVA.cs +++ b/Engine.Core/Primitives/ColorHSVA.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an HSV color. diff --git a/Engine.Core/Primitives/ColorRGB.cs b/Engine.Core/Primitives/ColorRGB.cs index 67c0d99..e7628cf 100644 --- a/Engine.Core/Primitives/ColorRGB.cs +++ b/Engine.Core/Primitives/ColorRGB.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an RGB color. diff --git a/Engine.Core/Primitives/ColorRGBA.cs b/Engine.Core/Primitives/ColorRGBA.cs index ea512a4..3dcfe10 100644 --- a/Engine.Core/Primitives/ColorRGBA.cs +++ b/Engine.Core/Primitives/ColorRGBA.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an RGBA color. diff --git a/Engine.Core/Primitives/Line2D.cs b/Engine.Core/Primitives/Line2D.cs index ee4e272..171fa7c 100644 --- a/Engine.Core/Primitives/Line2D.cs +++ b/Engine.Core/Primitives/Line2D.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a 2D line segment defined by two endpoints. diff --git a/Engine.Core/Primitives/Line2DEquation.cs b/Engine.Core/Primitives/Line2DEquation.cs index 19033bf..a6544d2 100644 --- a/Engine.Core/Primitives/Line2DEquation.cs +++ b/Engine.Core/Primitives/Line2DEquation.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a in the form y = mx + b. diff --git a/Engine.Core/Primitives/Projection1D.cs b/Engine.Core/Primitives/Projection1D.cs index 599d53a..2408228 100644 --- a/Engine.Core/Primitives/Projection1D.cs +++ b/Engine.Core/Primitives/Projection1D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a range of values along a single axis. diff --git a/Engine.Core/Primitives/Quaternion.cs b/Engine.Core/Primitives/Quaternion.cs index e2e1e53..68df8dc 100644 --- a/Engine.Core/Primitives/Quaternion.cs +++ b/Engine.Core/Primitives/Quaternion.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a 3D space rotation. diff --git a/Engine.Core/Primitives/Ray2D.cs b/Engine.Core/Primitives/Ray2D.cs index f536179..ddc68c8 100644 --- a/Engine.Core/Primitives/Ray2D.cs +++ b/Engine.Core/Primitives/Ray2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents an infinite ray in 2D space. diff --git a/Engine.Core/Primitives/Shape2D.cs b/Engine.Core/Primitives/Shape2D.cs index 4a8ba84..1bd843f 100644 --- a/Engine.Core/Primitives/Shape2D.cs +++ b/Engine.Core/Primitives/Shape2D.cs @@ -1,7 +1,7 @@ using System.Collections; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a shape defined by a collection of vertices. diff --git a/Engine.Core/Primitives/Triangle.cs b/Engine.Core/Primitives/Triangle.cs index 087d977..d959a63 100644 --- a/Engine.Core/Primitives/Triangle.cs +++ b/Engine.Core/Primitives/Triangle.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; [System.Diagnostics.DebuggerDisplay("A: {A.ToString(), nq}, B: {B.ToString(), nq}, B: {C.ToString(), nq}")] public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C) diff --git a/Engine.Core/Primitives/Vector2D.cs b/Engine.Core/Primitives/Vector2D.cs index ff327e3..624b9ca 100644 --- a/Engine.Core/Primitives/Vector2D.cs +++ b/Engine.Core/Primitives/Vector2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a two-dimensional vector. diff --git a/Engine.Core/Primitives/Vector3D.cs b/Engine.Core/Primitives/Vector3D.cs index 190caf7..dedbb37 100644 --- a/Engine.Core/Primitives/Vector3D.cs +++ b/Engine.Core/Primitives/Vector3D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a three-dimensional vector. diff --git a/Engine.Core/Serialization/Attributes/IgnoreSerializationAttribute.cs b/Engine.Core/Serialization/Attributes/IgnoreSerializationAttribute.cs index f0dcb16..a8f9207 100644 --- a/Engine.Core/Serialization/Attributes/IgnoreSerializationAttribute.cs +++ b/Engine.Core/Serialization/Attributes/IgnoreSerializationAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)] public class IgnoreSerializationAttribute : Attribute; diff --git a/Engine.Core/Serialization/Attributes/SerializeAllAttribute.cs b/Engine.Core/Serialization/Attributes/SerializeAllAttribute.cs index fa6e8a1..6b142f3 100644 --- a/Engine.Core/Serialization/Attributes/SerializeAllAttribute.cs +++ b/Engine.Core/Serialization/Attributes/SerializeAllAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] public class SerializeAllAttribute : Attribute; diff --git a/Engine.Core/Serialization/Attributes/SerializeAttribute.cs b/Engine.Core/Serialization/Attributes/SerializeAttribute.cs index 6f94860..32bebe0 100644 --- a/Engine.Core/Serialization/Attributes/SerializeAttribute.cs +++ b/Engine.Core/Serialization/Attributes/SerializeAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public class SerializeAttribute : Attribute; diff --git a/Engine.Core/Serialization/EntityReference.cs b/Engine.Core/Serialization/EntityReference.cs index 8ad0bd6..07f1fc8 100644 --- a/Engine.Core/Serialization/EntityReference.cs +++ b/Engine.Core/Serialization/EntityReference.cs @@ -1,3 +1,3 @@ -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; public record class EntityReference(string? Id = null); diff --git a/Engine.Core/Serialization/EntityRegistry.cs b/Engine.Core/Serialization/EntityRegistry.cs index c02b9d2..6339ba1 100644 --- a/Engine.Core/Serialization/EntityRegistry.cs +++ b/Engine.Core/Serialization/EntityRegistry.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; public class EntityRegistry { diff --git a/Engine.Core/Serialization/ISerializer.cs b/Engine.Core/Serialization/ISerializer.cs index 0ef6962..0ada93c 100644 --- a/Engine.Core/Serialization/ISerializer.cs +++ b/Engine.Core/Serialization/ISerializer.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; public interface ISerializer { diff --git a/Engine.Core/Serialization/SerializedClass.cs b/Engine.Core/Serialization/SerializedClass.cs index 992f772..803c83b 100644 --- a/Engine.Core/Serialization/SerializedClass.cs +++ b/Engine.Core/Serialization/SerializedClass.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Generic; using System.Reflection; -using Syntriax.Engine.Core.Factory; +using Engine.Core.Factory; -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; public class SerializedClass { diff --git a/Engine.Core/Serialization/TypeContainer.cs b/Engine.Core/Serialization/TypeContainer.cs index 7179745..4b5a359 100644 --- a/Engine.Core/Serialization/TypeContainer.cs +++ b/Engine.Core/Serialization/TypeContainer.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; public class TypeContainer { diff --git a/Engine.Core/Serialization/Utils.cs b/Engine.Core/Serialization/Utils.cs index 6bf6eb1..9c5f145 100644 --- a/Engine.Core/Serialization/Utils.cs +++ b/Engine.Core/Serialization/Utils.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -namespace Syntriax.Engine.Core.Serialization; +namespace Engine.Core.Serialization; public static class Utils { diff --git a/Engine.Core/StateEnable.cs b/Engine.Core/StateEnable.cs index 2b4fc9e..fd1d89a 100644 --- a/Engine.Core/StateEnable.cs +++ b/Engine.Core/StateEnable.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class StateEnable : IStateEnable { diff --git a/Engine.Core/Static/Internal/Constants.cs b/Engine.Core/Static/Internal/Constants.cs index 535e17d..800b02b 100644 --- a/Engine.Core/Static/Internal/Constants.cs +++ b/Engine.Core/Static/Internal/Constants.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; internal static class Constants { diff --git a/Engine.Core/Systems/Abstract/IDraw.cs b/Engine.Core/Systems/Abstract/IDraw.cs index 696e551..0f1d430 100644 --- a/Engine.Core/Systems/Abstract/IDraw.cs +++ b/Engine.Core/Systems/Abstract/IDraw.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a to be notified when the draw phase of the occurs. diff --git a/Engine.Core/Systems/Abstract/IEnterUniverse.cs b/Engine.Core/Systems/Abstract/IEnterUniverse.cs index f7d67a1..63703ae 100644 --- a/Engine.Core/Systems/Abstract/IEnterUniverse.cs +++ b/Engine.Core/Systems/Abstract/IEnterUniverse.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface IEnterUniverse : IBehaviour { diff --git a/Engine.Core/Systems/Abstract/IExitUniverse.cs b/Engine.Core/Systems/Abstract/IExitUniverse.cs index b8c3db1..8bc3ba3 100644 --- a/Engine.Core/Systems/Abstract/IExitUniverse.cs +++ b/Engine.Core/Systems/Abstract/IExitUniverse.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface IExitUniverse : IBehaviour { diff --git a/Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs b/Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs index d3abd57..8a2e5b4 100644 --- a/Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs +++ b/Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface IFirstFrameUpdate : IBehaviour { diff --git a/Engine.Core/Systems/Abstract/ILastFrameUpdate.cs b/Engine.Core/Systems/Abstract/ILastFrameUpdate.cs index 9957da1..c3e5132 100644 --- a/Engine.Core/Systems/Abstract/ILastFrameUpdate.cs +++ b/Engine.Core/Systems/Abstract/ILastFrameUpdate.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; public interface ILastFrameUpdate : IBehaviour { diff --git a/Engine.Core/Systems/Abstract/IPostDraw.cs b/Engine.Core/Systems/Abstract/IPostDraw.cs index 38003b2..ce4ec03 100644 --- a/Engine.Core/Systems/Abstract/IPostDraw.cs +++ b/Engine.Core/Systems/Abstract/IPostDraw.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a to be notified after the draw phase of the occurs. diff --git a/Engine.Core/Systems/Abstract/IPostUpdate.cs b/Engine.Core/Systems/Abstract/IPostUpdate.cs index 3802437..4654dde 100644 --- a/Engine.Core/Systems/Abstract/IPostUpdate.cs +++ b/Engine.Core/Systems/Abstract/IPostUpdate.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a to be notified after the update phase of the occurs. diff --git a/Engine.Core/Systems/Abstract/IPreDraw.cs b/Engine.Core/Systems/Abstract/IPreDraw.cs index 7d43801..b13226d 100644 --- a/Engine.Core/Systems/Abstract/IPreDraw.cs +++ b/Engine.Core/Systems/Abstract/IPreDraw.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a to be notified before the draw phase of the occurs. diff --git a/Engine.Core/Systems/Abstract/IPreUpdate.cs b/Engine.Core/Systems/Abstract/IPreUpdate.cs index af3a453..f07d009 100644 --- a/Engine.Core/Systems/Abstract/IPreUpdate.cs +++ b/Engine.Core/Systems/Abstract/IPreUpdate.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a to be notified before the update phase of the occurs. diff --git a/Engine.Core/Systems/Abstract/IUpdate.cs b/Engine.Core/Systems/Abstract/IUpdate.cs index 1e34989..b574148 100644 --- a/Engine.Core/Systems/Abstract/IUpdate.cs +++ b/Engine.Core/Systems/Abstract/IUpdate.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Core; +namespace Engine.Core; /// /// Represents a to be notified when the update phase of the occurs. diff --git a/Engine.Core/Systems/DrawManager.cs b/Engine.Core/Systems/DrawManager.cs index cd7fef0..b385c68 100644 --- a/Engine.Core/Systems/DrawManager.cs +++ b/Engine.Core/Systems/DrawManager.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class DrawManager : Behaviour { diff --git a/Engine.Core/Systems/UniverseEntranceManager.cs b/Engine.Core/Systems/UniverseEntranceManager.cs index 6df3d96..4fa7651 100644 --- a/Engine.Core/Systems/UniverseEntranceManager.cs +++ b/Engine.Core/Systems/UniverseEntranceManager.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class UniverseEntranceManager : Behaviour { diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index 0777f47..5d0c0cc 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public class UpdateManager : Behaviour { diff --git a/Engine.Core/Transform2D.cs b/Engine.Core/Transform2D.cs index 7d14fa9..1c2a8bc 100644 --- a/Engine.Core/Transform2D.cs +++ b/Engine.Core/Transform2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core.Serialization; +using Engine.Core.Serialization; -namespace Syntriax.Engine.Core; +namespace Engine.Core; [System.Diagnostics.DebuggerDisplay("Name: {UniverseObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")] public class Transform2D : Behaviour, ITransform2D diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index ae5a1b3..37c1498 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -2,7 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; [System.Diagnostics.DebuggerDisplay("UniverseObject Count: {_universeObjects.Count}")] public class Universe : BaseEntity, IUniverse diff --git a/Engine.Core/UniverseObject.cs b/Engine.Core/UniverseObject.cs index ff1c57f..78307f2 100644 --- a/Engine.Core/UniverseObject.cs +++ b/Engine.Core/UniverseObject.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Syntriax.Engine.Core; +namespace Engine.Core; [System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")] public class UniverseObject : BaseEntity, IUniverseObject diff --git a/Engine.Core/UniverseTime.cs b/Engine.Core/UniverseTime.cs index ed73de7..505fa77 100644 --- a/Engine.Core/UniverseTime.cs +++ b/Engine.Core/UniverseTime.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Core; +namespace Engine.Core; public readonly struct UniverseTime(TimeSpan TimeSinceStart, TimeSpan TimeDelta) { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Engine.Integration.LiteNetLib.csproj b/Engine.Integration/Engine.Integration.LiteNetLib/Engine.Integration.LiteNetLib.csproj index 3a34cb3..f5f119a 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Engine.Integration.LiteNetLib.csproj +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Engine.Integration.LiteNetLib.csproj @@ -4,8 +4,8 @@ net9.0 enable enable - Syntriax.Engine.Systems.Network - Syntriax.Engine.Integration.LiteNetLib + Engine.Systems.Network + Engine.Integration.LiteNetLib diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs index 0967d57..55887e6 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs @@ -3,10 +3,10 @@ using System.Net.Sockets; using LiteNetLib; using LiteNetLib.Utils; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Debug; +using Engine.Core; +using Engine.Core.Debug; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public class LiteNetLibClient : LiteNetLibCommunicatorBase, INetworkCommunicatorClient { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClientConnection.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClientConnection.cs index 5e2408f..5ce46e0 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClientConnection.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClientConnection.cs @@ -1,6 +1,6 @@ using LiteNetLib; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public record class LiteNetLibClientConnection(NetPeer NetPeer) : IConnection { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs index ed14f12..7691103 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs @@ -3,10 +3,10 @@ using System.Reflection; using LiteNetLib; using LiteNetLib.Utils; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Debug; +using Engine.Core; +using Engine.Core.Debug; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicator { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs index d3fad8e..f77d1e3 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs @@ -1,10 +1,10 @@ using LiteNetLib; using LiteNetLib.Utils; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Debug; +using Engine.Core; +using Engine.Core.Debug; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public class LiteNetLibServer : LiteNetLibCommunicatorBase, INetworkCommunicatorServer { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServerConnection.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServerConnection.cs index 66f8f3b..a215b74 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServerConnection.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServerConnection.cs @@ -1,6 +1,6 @@ using LiteNetLib; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public record class LiteNetLibServerConnection(NetPeer NetPeer) : IConnection { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/AABBNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/AABBNetPacker.cs index e8ed56e..0af57aa 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/AABBNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/AABBNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class AABBNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/CircleNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/CircleNetPacker.cs index 5545dca..9cd748f 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/CircleNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/CircleNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class CircleNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorHSVNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorHSVNetPacker.cs index af868c8..a7a24be 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorHSVNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorHSVNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class ColorHSVNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBANetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBANetPacker.cs index 0b20f06..ea5f409 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBANetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBANetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class ColorRGBANetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBNetPacker.cs index 46770e1..4243143 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/ColorRGBNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class ColorRGBNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DEquationNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DEquationNetPacker.cs index 3bcfe70..e3c2228 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DEquationNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DEquationNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class Line2DEquationNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DNetPacker.cs index 899b0f7..4340670 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Line2DNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class Line2DNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Projection1DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Projection1DNetPacker.cs index 0a356ef..753f037 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Projection1DNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Projection1DNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class Projection1DNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/QuaternionNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/QuaternionNetPacker.cs index a1241be..fbda6ce 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/QuaternionNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/QuaternionNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class QuaternionNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Shape2DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Shape2DNetPacker.cs index 525185f..97ceea8 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Shape2DNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Shape2DNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class Shape2DNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/TriangleNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/TriangleNetPacker.cs index 8c22746..53b3481 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/TriangleNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/TriangleNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class TriangleNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector2DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector2DNetPacker.cs index 5f1485f..93f60e1 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector2DNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector2DNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class Vector2DNetPacker { diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector3DNetPacker.cs b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector3DNetPacker.cs index d594104..393152c 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector3DNetPacker.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/Packers/Vector3DNetPacker.cs @@ -1,8 +1,8 @@ using LiteNetLib.Utils; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; internal static class Vector3DNetPacker { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Abstract/IDrawableSprite.cs b/Engine.Integration/Engine.Integration.MonoGame/Abstract/IDrawableSprite.cs index 2e39ff7..a0e2211 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Abstract/IDrawableSprite.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Abstract/IDrawableSprite.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public interface IDrawableSprite : IBehaviour { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Abstract/IDrawableTriangle.cs b/Engine.Integration/Engine.Integration.MonoGame/Abstract/IDrawableTriangle.cs index 937d559..7d3372d 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Abstract/IDrawableTriangle.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Abstract/IDrawableTriangle.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public interface IDrawableTriangle : IBehaviour { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Abstract/ILoadContent.cs b/Engine.Integration/Engine.Integration.MonoGame/Abstract/ILoadContent.cs index 042a5b7..d838772 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Abstract/ILoadContent.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Abstract/ILoadContent.cs @@ -1,8 +1,8 @@ using Microsoft.Xna.Framework.Content; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public interface ILoadContent : IBehaviour { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Abstract/ISpriteBatch.cs b/Engine.Integration/Engine.Integration.MonoGame/Abstract/ISpriteBatch.cs index 88a4f82..0939141 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Abstract/ISpriteBatch.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Abstract/ISpriteBatch.cs @@ -3,9 +3,9 @@ using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public interface ISpriteBatch { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Abstract/ITriangleBatch.cs b/Engine.Integration/Engine.Integration.MonoGame/Abstract/ITriangleBatch.cs index 08f190a..1de8f80 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Abstract/ITriangleBatch.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Abstract/ITriangleBatch.cs @@ -1,8 +1,8 @@ using Microsoft.Xna.Framework; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public interface ITriangleBatch { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShape.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShape.cs index ba31f23..0078088 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShape.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/DrawableShape.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class DrawableShape : Behaviour2D, IDrawableTriangle, IPreDraw { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs index 350e92f..fbb8a77 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs @@ -3,10 +3,10 @@ using System.Collections.Generic; using Microsoft.Xna.Framework.Input; -using Syntriax.Engine.Core; -using Syntriax.Engine.Systems.Input; +using Engine.Core; +using Engine.Systems.Input; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class KeyboardInputs : Behaviour, IButtonInputs, IUpdate { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs index ccaf8da..a8eec5b 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class LoadContentManager : Behaviour, IFirstFrameUpdate { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs index 7357ae7..0f0dc85 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs @@ -1,9 +1,9 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class MonoGameCamera2D : BehaviourBase, ICamera2D, IFirstFrameUpdate, IPreDraw { @@ -56,7 +56,7 @@ public class MonoGameCamera2D : BehaviourBase, ICamera2D, IFirstFrameUpdate, IPr get => _zoom; set { - float newValue = Syntriax.Engine.Core.Math.Max(0.1f, value); + float newValue = Engine.Core.Math.Max(0.1f, value); if (_zoom == newValue) return; @@ -94,7 +94,7 @@ public class MonoGameCamera2D : BehaviourBase, ICamera2D, IFirstFrameUpdate, IPr { MatrixTransform = Matrix.CreateTranslation(new Vector3(-Position.X, Position.Y, 0f)) * - Matrix.CreateRotationZ(Rotation * Syntriax.Engine.Core.Math.DegreeToRadian) * + Matrix.CreateRotationZ(Rotation * Engine.Core.Math.DegreeToRadian) * Matrix.CreateScale(Transform.Scale.X.Max(Transform.Scale.Y)) * Matrix.CreateScale(Zoom) * Matrix.CreateTranslation(new Vector3(_viewport.Width * .5f, _viewport.Height * .5f, 0f)); diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatchWrapper.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatchWrapper.cs index 9fa617b..7e40376 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatchWrapper.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatchWrapper.cs @@ -3,9 +3,9 @@ using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class SpriteBatchWrapper(GraphicsDevice graphicsDevice) : ISpriteBatch { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs index f3f57ae..e2e1cd6 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class SpriteBatcher : BehaviourBase, IFirstFrameUpdate, IDraw { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs index 11bca97..1fafe41 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using Microsoft.Xna.Framework; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class TriangleBatcher : BehaviourBase, ITriangleBatch, IFirstFrameUpdate, IDraw { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Engine.Integration.MonoGame.csproj b/Engine.Integration/Engine.Integration.MonoGame/Engine.Integration.MonoGame.csproj index cd49b65..4f66f9a 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Engine.Integration.MonoGame.csproj +++ b/Engine.Integration/Engine.Integration.MonoGame/Engine.Integration.MonoGame.csproj @@ -3,7 +3,8 @@ net9.0 disable enable - Syntriax.Engine.Integration.MonoGame + Engine.Integration.MonoGame + Engine.Integration.MonoGame diff --git a/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs b/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs index cea1b55..b1c408f 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/EngineConverter.cs @@ -3,9 +3,9 @@ using System.Runtime.CompilerServices; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public static class EngineConverterExtensions { diff --git a/Engine.Integration/Engine.Integration.MonoGame/MonoGameWindow.cs b/Engine.Integration/Engine.Integration.MonoGame/MonoGameWindow.cs index 8b8740c..7decf16 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/MonoGameWindow.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/MonoGameWindow.cs @@ -1,9 +1,9 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class MonoGameWindow : Game { diff --git a/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs b/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs index a03c852..bc9ec50 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs @@ -1,9 +1,9 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; public class TriangleBatch : ITriangleBatch { diff --git a/Engine.Integration/Engine.Integration.MonoGame/UniverseObjects/MonoGameWindowContainer.cs b/Engine.Integration/Engine.Integration.MonoGame/UniverseObjects/MonoGameWindowContainer.cs index eba7e18..f4b8016 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/UniverseObjects/MonoGameWindowContainer.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/UniverseObjects/MonoGameWindowContainer.cs @@ -1,7 +1,7 @@ -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; -namespace Syntriax.Engine.Integration.MonoGame; +namespace Engine.Integration.MonoGame; [IgnoreSerialization] public class MonoGameWindowContainer(MonoGameWindow GameWindow) : BehaviourBase diff --git a/Engine.Physics2D/Abstract/ICircleCollider2D.cs b/Engine.Physics2D/Abstract/ICircleCollider2D.cs index fff33bd..3384f1c 100644 --- a/Engine.Physics2D/Abstract/ICircleCollider2D.cs +++ b/Engine.Physics2D/Abstract/ICircleCollider2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a with the shape of a . diff --git a/Engine.Physics2D/Abstract/ICollider2D.cs b/Engine.Physics2D/Abstract/ICollider2D.cs index fdc1ffd..38f0c75 100644 --- a/Engine.Physics2D/Abstract/ICollider2D.cs +++ b/Engine.Physics2D/Abstract/ICollider2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a 2D collider. diff --git a/Engine.Physics2D/Abstract/ICollisionDetector2D.cs b/Engine.Physics2D/Abstract/ICollisionDetector2D.cs index ed6e307..9f11739 100644 --- a/Engine.Physics2D/Abstract/ICollisionDetector2D.cs +++ b/Engine.Physics2D/Abstract/ICollisionDetector2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a 2D collision detector. diff --git a/Engine.Physics2D/Abstract/ICollisionResolver2D.cs b/Engine.Physics2D/Abstract/ICollisionResolver2D.cs index e5b10ff..9d7851f 100644 --- a/Engine.Physics2D/Abstract/ICollisionResolver2D.cs +++ b/Engine.Physics2D/Abstract/ICollisionResolver2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a 2D collision resolver. diff --git a/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs b/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs index 323a31e..f281349 100644 --- a/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs +++ b/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a 2D physics engine. diff --git a/Engine.Physics2D/Abstract/IPhysicsMaterial2D.cs b/Engine.Physics2D/Abstract/IPhysicsMaterial2D.cs index 4bfc716..1605eb3 100644 --- a/Engine.Physics2D/Abstract/IPhysicsMaterial2D.cs +++ b/Engine.Physics2D/Abstract/IPhysicsMaterial2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a 2D physics object's responsive attributes. diff --git a/Engine.Physics2D/Abstract/IRaycastResolver2D.cs b/Engine.Physics2D/Abstract/IRaycastResolver2D.cs index 28fc459..190d5d1 100644 --- a/Engine.Physics2D/Abstract/IRaycastResolver2D.cs +++ b/Engine.Physics2D/Abstract/IRaycastResolver2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a 2D raycast resolver. diff --git a/Engine.Physics2D/Abstract/IRigidBody2D.cs b/Engine.Physics2D/Abstract/IRigidBody2D.cs index b7292cd..871fc0e 100644 --- a/Engine.Physics2D/Abstract/IRigidBody2D.cs +++ b/Engine.Physics2D/Abstract/IRigidBody2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a 2D rigid body in the engine. diff --git a/Engine.Physics2D/Abstract/IShapeCollider2D.cs b/Engine.Physics2D/Abstract/IShapeCollider2D.cs index 925751a..99a3802 100644 --- a/Engine.Physics2D/Abstract/IShapeCollider2D.cs +++ b/Engine.Physics2D/Abstract/IShapeCollider2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a with a custom . diff --git a/Engine.Physics2D/Abstract/RaycastResult.cs b/Engine.Physics2D/Abstract/RaycastResult.cs index 55a56f2..2e6f236 100644 --- a/Engine.Physics2D/Abstract/RaycastResult.cs +++ b/Engine.Physics2D/Abstract/RaycastResult.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public readonly struct RaycastResult(Ray2D ray, ICollider2D collider2D, Vector2D position, Vector2D normal) { diff --git a/Engine.Physics2D/Abstract/Updates/IPhysicsIteration.cs b/Engine.Physics2D/Abstract/Updates/IPhysicsIteration.cs index 103837a..c1b3737 100644 --- a/Engine.Physics2D/Abstract/Updates/IPhysicsIteration.cs +++ b/Engine.Physics2D/Abstract/Updates/IPhysicsIteration.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a that listens to physics simulation update phase. diff --git a/Engine.Physics2D/Abstract/Updates/IPhysicsUpdate.cs b/Engine.Physics2D/Abstract/Updates/IPhysicsUpdate.cs index f447dfa..b596965 100644 --- a/Engine.Physics2D/Abstract/Updates/IPhysicsUpdate.cs +++ b/Engine.Physics2D/Abstract/Updates/IPhysicsUpdate.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a that listens to physics simulation update phase. diff --git a/Engine.Physics2D/Abstract/Updates/IPostPhysicsUpdate.cs b/Engine.Physics2D/Abstract/Updates/IPostPhysicsUpdate.cs index e6edb47..31e74ba 100644 --- a/Engine.Physics2D/Abstract/Updates/IPostPhysicsUpdate.cs +++ b/Engine.Physics2D/Abstract/Updates/IPostPhysicsUpdate.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a that listens to the phase after the physics simulation phase. diff --git a/Engine.Physics2D/Abstract/Updates/IPrePhysicsUpdate.cs b/Engine.Physics2D/Abstract/Updates/IPrePhysicsUpdate.cs index 4de7d66..dfd9f7c 100644 --- a/Engine.Physics2D/Abstract/Updates/IPrePhysicsUpdate.cs +++ b/Engine.Physics2D/Abstract/Updates/IPrePhysicsUpdate.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; /// /// Represents a that listens to the phase before the physics simulation phase. diff --git a/Engine.Physics2D/Collider2DBase.cs b/Engine.Physics2D/Collider2DBase.cs index bca0735..b0aef94 100644 --- a/Engine.Physics2D/Collider2DBase.cs +++ b/Engine.Physics2D/Collider2DBase.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public abstract class Collider2DBase : Behaviour2D, ICollider2D { diff --git a/Engine.Physics2D/Collider2DCircle.cs b/Engine.Physics2D/Collider2DCircle.cs index 5d2f8cb..8291b08 100644 --- a/Engine.Physics2D/Collider2DCircle.cs +++ b/Engine.Physics2D/Collider2DCircle.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class Collider2DCircle : Collider2DBase, ICircleCollider2D { diff --git a/Engine.Physics2D/Collider2DShape.cs b/Engine.Physics2D/Collider2DShape.cs index 7f2b51a..10113f4 100644 --- a/Engine.Physics2D/Collider2DShape.cs +++ b/Engine.Physics2D/Collider2DShape.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class Collider2DShape : Collider2DBase, IShapeCollider2D { diff --git a/Engine.Physics2D/CollisionDetectionInformation.cs b/Engine.Physics2D/CollisionDetectionInformation.cs index 6476df0..62e564a 100644 --- a/Engine.Physics2D/CollisionDetectionInformation.cs +++ b/Engine.Physics2D/CollisionDetectionInformation.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; [System.Diagnostics.DebuggerDisplay("Normal: {Normal.ToString(), nq}, Penetration: {Penetration}")] public readonly struct CollisionDetectionInformation diff --git a/Engine.Physics2D/CollisionDetector2D.cs b/Engine.Physics2D/CollisionDetector2D.cs index 8b1508b..760c086 100644 --- a/Engine.Physics2D/CollisionDetector2D.cs +++ b/Engine.Physics2D/CollisionDetector2D.cs @@ -1,7 +1,7 @@ -using Syntriax.Engine.Core; -using Syntriax.Engine.Physics2D; +using Engine.Core; +using Engine.Physics2D; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class CollisionDetector2D : ICollisionDetector2D { diff --git a/Engine.Physics2D/CollisionResolver2D.cs b/Engine.Physics2D/CollisionResolver2D.cs index 4918a59..90341be 100644 --- a/Engine.Physics2D/CollisionResolver2D.cs +++ b/Engine.Physics2D/CollisionResolver2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class CollisionResolver2D : ICollisionResolver2D { diff --git a/Engine.Physics2D/Engine.Physics2D.csproj b/Engine.Physics2D/Engine.Physics2D.csproj index ba7ce86..7119153 100644 --- a/Engine.Physics2D/Engine.Physics2D.csproj +++ b/Engine.Physics2D/Engine.Physics2D.csproj @@ -4,7 +4,8 @@ net9.0 disable enable - Syntriax.Engine.Physics2D + Engine.Physics2D + Engine.Physics2D diff --git a/Engine.Physics2D/Physics2D.cs b/Engine.Physics2D/Physics2D.cs index edb3335..1dd6b0b 100644 --- a/Engine.Physics2D/Physics2D.cs +++ b/Engine.Physics2D/Physics2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public static class Physics2D { diff --git a/Engine.Physics2D/PhysicsCoroutineManager.cs b/Engine.Physics2D/PhysicsCoroutineManager.cs index 47fb742..573a5d4 100644 --- a/Engine.Physics2D/PhysicsCoroutineManager.cs +++ b/Engine.Physics2D/PhysicsCoroutineManager.cs @@ -1,9 +1,9 @@ using System.Collections; using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class PhysicsCoroutineManager : Behaviour, IPhysicsUpdate { diff --git a/Engine.Physics2D/PhysicsEngine2D.cs b/Engine.Physics2D/PhysicsEngine2D.cs index 10de29b..8b75a22 100644 --- a/Engine.Physics2D/PhysicsEngine2D.cs +++ b/Engine.Physics2D/PhysicsEngine2D.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D { diff --git a/Engine.Physics2D/PhysicsEngine2DStandalone.cs b/Engine.Physics2D/PhysicsEngine2DStandalone.cs index 5de9885..11c313c 100644 --- a/Engine.Physics2D/PhysicsEngine2DStandalone.cs +++ b/Engine.Physics2D/PhysicsEngine2DStandalone.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class PhysicsEngine2DStandalone : IPhysicsEngine2D { diff --git a/Engine.Physics2D/PhysicsMaterial2D.cs b/Engine.Physics2D/PhysicsMaterial2D.cs index 616c26f..a3875ca 100644 --- a/Engine.Physics2D/PhysicsMaterial2D.cs +++ b/Engine.Physics2D/PhysicsMaterial2D.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public readonly struct PhysicsMaterial2D(float Friction, float Restitution) : IPhysicsMaterial2D { diff --git a/Engine.Physics2D/PhysicsMaterial2DDefault.cs b/Engine.Physics2D/PhysicsMaterial2DDefault.cs index faf0e31..1ed446e 100644 --- a/Engine.Physics2D/PhysicsMaterial2DDefault.cs +++ b/Engine.Physics2D/PhysicsMaterial2DDefault.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public readonly struct PhysicsMaterial2DDefault : IPhysicsMaterial2D { diff --git a/Engine.Physics2D/Preserver.cs b/Engine.Physics2D/Preserver.cs index be2dfe1..a446f3f 100644 --- a/Engine.Physics2D/Preserver.cs +++ b/Engine.Physics2D/Preserver.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Physics2D +namespace Engine.Physics2D { // This is pretty much so the assembly gets loaded automatically because // the builds include the assembly but sometimes doesn't link load it at startup. diff --git a/Engine.Physics2D/RaycastResolver2D.cs b/Engine.Physics2D/RaycastResolver2D.cs index 726a2e5..e933e66 100644 --- a/Engine.Physics2D/RaycastResolver2D.cs +++ b/Engine.Physics2D/RaycastResolver2D.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class RaycastResolver2D : IRaycastResolver2D { diff --git a/Engine.Physics2D/RigidBody2D.cs b/Engine.Physics2D/RigidBody2D.cs index c5584eb..8d9c1f9 100644 --- a/Engine.Physics2D/RigidBody2D.cs +++ b/Engine.Physics2D/RigidBody2D.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Physics2D; +namespace Engine.Physics2D; public class RigidBody2D : Behaviour2D, IRigidBody2D { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs index e9812d9..873b796 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs @@ -1,9 +1,9 @@ -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public interface IEngineTypeYamlConverter : IYamlTypeConverter { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs index 770f9f1..97ed522 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs @@ -2,14 +2,14 @@ using System; using System.Collections.Generic; using System.Linq; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class BehaviourControllerConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs index eebfdd1..abc3b97 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs @@ -1,13 +1,13 @@ using System; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class BehaviourConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs index 4e8d731..134e922 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; using YamlDotNet.Core; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public abstract class EngineTypeYamlSerializerBase : IEngineTypeYamlConverter { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs index bfc0001..d09150d 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class AABBConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs index 32ad922..d06bc53 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class CircleConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs index b5bb4ca..a03f490 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class ColorHSVConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs index 8243a0b..50ec7aa 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class ColorRGBAConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs index 809db2a..8133885 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class ColorRGBConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs index 85551c0..1d45331 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class Line2DConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs index da70ea2..ed13cc4 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class Line2DEquationConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs index 9bad9bf..b1ea9fe 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class Projection1DConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs index 66e2a0d..76317b3 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class QuaternionConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs index 239546e..cd88d96 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs @@ -1,13 +1,13 @@ using System; using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class Shape2DConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs index d98efbb..c544b37 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class TriangleConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs index 1c1b420..654416c 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class Vector2DConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs index 64f49c2..4bdca07 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs @@ -1,12 +1,12 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class Vector3DConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs index 2dd9455..aef2822 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs @@ -2,15 +2,15 @@ using System; using System.Collections.Generic; using System.Linq; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Factory; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Factory; +using Engine.Core.Serialization; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class SerializedClassConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/StateEnableConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/StateEnableConverter.cs index 1135bf5..9c317b0 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/StateEnableConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/StateEnableConverter.cs @@ -1,13 +1,13 @@ using System; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class StateEnableConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs index 0b7a665..94f045c 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs @@ -1,13 +1,13 @@ using System; -using Syntriax.Engine.Core.Serialization; -using Syntriax.Engine.Core.Factory; +using Engine.Core.Serialization; +using Engine.Core.Factory; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class TypeContainerConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs index 1fbf978..6fdf87e 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs @@ -2,14 +2,14 @@ using System; using System.Collections.Generic; using System.Linq; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class UniverseConverter : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs index 527e2b0..76268fe 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs @@ -2,14 +2,14 @@ using System; using System.Collections.Generic; using System.Linq; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class UniverseObjectSerializer : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj b/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj index c56d15f..59ce055 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj +++ b/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj @@ -4,7 +4,8 @@ net9.0 disable enable - Syntriax.Engine.Serializers.Yaml + Engine.Serializers.Yaml + Engine.Serializers.Yaml diff --git a/Engine.Serializers/Engine.Serializers.Yaml/SerializerInProgressException.cs b/Engine.Serializers/Engine.Serializers.Yaml/SerializerInProgressException.cs index 2b03c0b..7ca2cc3 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/SerializerInProgressException.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/SerializerInProgressException.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; [Serializable] public class SerializerInProgressException() : Exception("There's already a running deserialization in progress."); diff --git a/Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs index 15d5f2f..1dfadd1 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs @@ -4,13 +4,13 @@ using System.Linq; using System.Reflection; using System.Threading.Tasks; -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; -namespace Syntriax.Engine.Serializers.Yaml; +namespace Engine.Serializers.Yaml; public class YamlSerializer : Core.Serialization.ISerializer { diff --git a/Engine.Systems/Engine.Systems.csproj b/Engine.Systems/Engine.Systems.csproj index 967f31f..11a1757 100644 --- a/Engine.Systems/Engine.Systems.csproj +++ b/Engine.Systems/Engine.Systems.csproj @@ -4,7 +4,8 @@ net9.0 disable enable - Syntriax.Engine.Systems + Engine.Systems + Engine.Systems diff --git a/Engine.Systems/Input/IButtonInputs.cs b/Engine.Systems/Input/IButtonInputs.cs index 75cd678..3b54529 100644 --- a/Engine.Systems/Input/IButtonInputs.cs +++ b/Engine.Systems/Input/IButtonInputs.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Input; +namespace Engine.Systems.Input; public interface IButtonInputs : IHasStateEnable { diff --git a/Engine.Systems/Network/Abstract/IConnection.cs b/Engine.Systems/Network/Abstract/IConnection.cs index 30aeecf..f43a87c 100644 --- a/Engine.Systems/Network/Abstract/IConnection.cs +++ b/Engine.Systems/Network/Abstract/IConnection.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public interface IConnection { diff --git a/Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs b/Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs index 7d1ee2a..5f05e16 100644 --- a/Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs +++ b/Engine.Systems/Network/Abstract/IEntityNetworkPacket.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public interface IEntityNetworkPacket : INetworkPacket { diff --git a/Engine.Systems/Network/Abstract/INetworkCommunicator.cs b/Engine.Systems/Network/Abstract/INetworkCommunicator.cs index 95e28a1..6ae2cc7 100644 --- a/Engine.Systems/Network/Abstract/INetworkCommunicator.cs +++ b/Engine.Systems/Network/Abstract/INetworkCommunicator.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public interface INetworkCommunicator { diff --git a/Engine.Systems/Network/Abstract/INetworkEntity.cs b/Engine.Systems/Network/Abstract/INetworkEntity.cs index 1e6a1f6..3baa040 100644 --- a/Engine.Systems/Network/Abstract/INetworkEntity.cs +++ b/Engine.Systems/Network/Abstract/INetworkEntity.cs @@ -1,5 +1,5 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public interface INetworkEntity : IEntity; diff --git a/Engine.Systems/Network/Abstract/INetworkManager.cs b/Engine.Systems/Network/Abstract/INetworkManager.cs index 3f9c950..306f001 100644 --- a/Engine.Systems/Network/Abstract/INetworkManager.cs +++ b/Engine.Systems/Network/Abstract/INetworkManager.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public interface INetworkManager { diff --git a/Engine.Systems/Network/Abstract/INetworkPacket.cs b/Engine.Systems/Network/Abstract/INetworkPacket.cs index 042f14d..25d9438 100644 --- a/Engine.Systems/Network/Abstract/INetworkPacket.cs +++ b/Engine.Systems/Network/Abstract/INetworkPacket.cs @@ -1,3 +1,3 @@ -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public interface INetworkPacket; diff --git a/Engine.Systems/Network/Abstract/IPacketListenerClient.cs b/Engine.Systems/Network/Abstract/IPacketListenerClient.cs index bfe39d7..39576fa 100644 --- a/Engine.Systems/Network/Abstract/IPacketListenerClient.cs +++ b/Engine.Systems/Network/Abstract/IPacketListenerClient.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public interface IPacketListenerClient : INetworkEntity { diff --git a/Engine.Systems/Network/Abstract/IPacketListenerServer.cs b/Engine.Systems/Network/Abstract/IPacketListenerServer.cs index b084949..6508db4 100644 --- a/Engine.Systems/Network/Abstract/IPacketListenerServer.cs +++ b/Engine.Systems/Network/Abstract/IPacketListenerServer.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public interface IPacketListenerServer : INetworkEntity { diff --git a/Engine.Systems/Network/Abstract/PacketDelivery.cs b/Engine.Systems/Network/Abstract/PacketDelivery.cs index 2fce6d0..a35d9a2 100644 --- a/Engine.Systems/Network/Abstract/PacketDelivery.cs +++ b/Engine.Systems/Network/Abstract/PacketDelivery.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; public enum PacketDelivery { diff --git a/Engine.Systems/Network/NetworkManager.cs b/Engine.Systems/Network/NetworkManager.cs index 915782b..53d9c5c 100644 --- a/Engine.Systems/Network/NetworkManager.cs +++ b/Engine.Systems/Network/NetworkManager.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Network; +namespace Engine.Systems.Network; /// /// Intermediary manager that looks up in it's hierarchy for a to route/broadcast it's received packets to their destinations. diff --git a/Engine.Systems/Preserver.cs b/Engine.Systems/Preserver.cs index dbfab6f..92ac222 100644 --- a/Engine.Systems/Preserver.cs +++ b/Engine.Systems/Preserver.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems +namespace Engine.Systems { // This is pretty much so the assembly gets loaded automatically because // the builds include the assembly but sometimes doesn't link load it at startup. diff --git a/Engine.Systems/StateMachine/IState.cs b/Engine.Systems/StateMachine/IState.cs index f30b260..c29b0bc 100644 --- a/Engine.Systems/StateMachine/IState.cs +++ b/Engine.Systems/StateMachine/IState.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.StateMachine; +namespace Engine.Systems.StateMachine; public interface IState : IEntity, INameable { diff --git a/Engine.Systems/StateMachine/State.cs b/Engine.Systems/StateMachine/State.cs index 86b030e..0c34a56 100644 --- a/Engine.Systems/StateMachine/State.cs +++ b/Engine.Systems/StateMachine/State.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.StateMachine; +namespace Engine.Systems.StateMachine; public class State : BaseEntity, IState { diff --git a/Engine.Systems/StateMachine/StateBehaviourBase.cs b/Engine.Systems/StateMachine/StateBehaviourBase.cs index efc6c9a..1ee7790 100644 --- a/Engine.Systems/StateMachine/StateBehaviourBase.cs +++ b/Engine.Systems/StateMachine/StateBehaviourBase.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.StateMachine; +namespace Engine.Systems.StateMachine; public abstract class StateBehaviourBase : Behaviour, IState { diff --git a/Engine.Systems/StateMachine/StateMachine.cs b/Engine.Systems/StateMachine/StateMachine.cs index 28f97b3..e8f009b 100644 --- a/Engine.Systems/StateMachine/StateMachine.cs +++ b/Engine.Systems/StateMachine/StateMachine.cs @@ -1,7 +1,7 @@ -using Syntriax.Engine.Core; -using Syntriax.Engine.Core.Serialization; +using Engine.Core; +using Engine.Core.Serialization; -namespace Syntriax.Engine.Systems.StateMachine; +namespace Engine.Systems.StateMachine; public class StateMachine : Behaviour, IUpdate { diff --git a/Engine.Systems/StateMachine/StateTransition.cs b/Engine.Systems/StateMachine/StateTransition.cs index ab02331..48dff73 100644 --- a/Engine.Systems/StateMachine/StateTransition.cs +++ b/Engine.Systems/StateMachine/StateTransition.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; -namespace Syntriax.Engine.Systems.StateMachine; +namespace Engine.Systems.StateMachine; public readonly record struct StateTransition(IState State, IReadOnlyList> Conditions) { diff --git a/Engine.Systems/Time/IReadOnlyStopwatch.cs b/Engine.Systems/Time/IReadOnlyStopwatch.cs index ea28155..e702c19 100644 --- a/Engine.Systems/Time/IReadOnlyStopwatch.cs +++ b/Engine.Systems/Time/IReadOnlyStopwatch.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public interface IReadOnlyStopwatch { diff --git a/Engine.Systems/Time/IReadOnlyTicker.cs b/Engine.Systems/Time/IReadOnlyTicker.cs index 665671f..6d7d799 100644 --- a/Engine.Systems/Time/IReadOnlyTicker.cs +++ b/Engine.Systems/Time/IReadOnlyTicker.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public interface IReadOnlyTicker : IReadOnlyStopwatch { diff --git a/Engine.Systems/Time/IReadOnlyTimer.cs b/Engine.Systems/Time/IReadOnlyTimer.cs index bca3ab7..cb1ca5e 100644 --- a/Engine.Systems/Time/IReadOnlyTimer.cs +++ b/Engine.Systems/Time/IReadOnlyTimer.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public interface IReadOnlyTimer { diff --git a/Engine.Systems/Time/IStopwatch.cs b/Engine.Systems/Time/IStopwatch.cs index 46e3cbc..aca070a 100644 --- a/Engine.Systems/Time/IStopwatch.cs +++ b/Engine.Systems/Time/IStopwatch.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public interface IStopwatch : IReadOnlyStopwatch { diff --git a/Engine.Systems/Time/ITicker.cs b/Engine.Systems/Time/ITicker.cs index 17ec73d..ae18ab8 100644 --- a/Engine.Systems/Time/ITicker.cs +++ b/Engine.Systems/Time/ITicker.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public interface ITicker { diff --git a/Engine.Systems/Time/ITimer.cs b/Engine.Systems/Time/ITimer.cs index 8e313f9..31f4e2f 100644 --- a/Engine.Systems/Time/ITimer.cs +++ b/Engine.Systems/Time/ITimer.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public interface ITimer : IReadOnlyTimer { diff --git a/Engine.Systems/Time/Stopwatch.cs b/Engine.Systems/Time/Stopwatch.cs index 40593f6..90e92f8 100644 --- a/Engine.Systems/Time/Stopwatch.cs +++ b/Engine.Systems/Time/Stopwatch.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public class Stopwatch : Behaviour, IUpdate, IStopwatch { diff --git a/Engine.Systems/Time/TickerStopwatch.cs b/Engine.Systems/Time/TickerStopwatch.cs index d0ad899..c41f5b7 100644 --- a/Engine.Systems/Time/TickerStopwatch.cs +++ b/Engine.Systems/Time/TickerStopwatch.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public class TickerStopwatch : Stopwatch, ITicker { diff --git a/Engine.Systems/Time/TickerTimer.cs b/Engine.Systems/Time/TickerTimer.cs index ec011c4..4e17115 100644 --- a/Engine.Systems/Time/TickerTimer.cs +++ b/Engine.Systems/Time/TickerTimer.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public class TickerTimer : Timer, ITicker { diff --git a/Engine.Systems/Time/Timer.cs b/Engine.Systems/Time/Timer.cs index 2c8faa1..42d2e03 100644 --- a/Engine.Systems/Time/Timer.cs +++ b/Engine.Systems/Time/Timer.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public class Timer : Behaviour, IUpdate, ITimer { diff --git a/Engine.Systems/Time/TimerState.cs b/Engine.Systems/Time/TimerState.cs index 4bda41a..97b7f11 100644 --- a/Engine.Systems/Time/TimerState.cs +++ b/Engine.Systems/Time/TimerState.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Time; +namespace Engine.Systems.Time; public enum TimerState { diff --git a/Engine.Systems/Tween/Easings.cs b/Engine.Systems/Tween/Easings.cs index 5b42480..46a031d 100644 --- a/Engine.Systems/Tween/Easings.cs +++ b/Engine.Systems/Tween/Easings.cs @@ -1,8 +1,8 @@ // Reference: https://easings.net -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; internal static class EaseConstants { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenAABBExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenAABBExtensions.cs index d6c19bd..e0b6304 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenAABBExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenAABBExtensions.cs @@ -1,7 +1,7 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenAABBExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenCamera2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenCamera2DExtensions.cs index 1644789..32d923c 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenCamera2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenCamera2DExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenCamera2DExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenCircleExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenCircleExtensions.cs index c92f8fd..959ed38 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenCircleExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenCircleExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenCircleExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs index 03b0e35..ce26271 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenColorExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenLine2DEquationExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenLine2DEquationExtensions.cs index bf8d91f..52e2bdc 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenLine2DEquationExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenLine2DEquationExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenLine2DEquationExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenLine2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenLine2DExtensions.cs index eaaed71..e9f5c46 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenLine2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenLine2DExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenLine2DExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenProjection1DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenProjection1DExtensions.cs index f6755bf..b20ba7b 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenProjection1DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenProjection1DExtensions.cs @@ -1,7 +1,7 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenProjection1DExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenQuaternionExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenQuaternionExtensions.cs index a0c10fc..5397433 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenQuaternionExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenQuaternionExtensions.cs @@ -1,7 +1,7 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenQuaternionExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenShape2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenShape2DExtensions.cs index 00393dd..6c9bb97 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenShape2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenShape2DExtensions.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenShape2DExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenTransform2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenTransform2DExtensions.cs index f4ca833..c3b3e4b 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenTransform2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenTransform2DExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenTransform2DExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenTriangleExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenTriangleExtensions.cs index d91475e..236b46e 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenTriangleExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenTriangleExtensions.cs @@ -1,7 +1,7 @@ using System; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenTriangleExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenVector2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenVector2DExtensions.cs index e230349..1ef0454 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenVector2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenVector2DExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenVector2DExtensions { diff --git a/Engine.Systems/Tween/EngineExtensions/TweenVector3DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenVector3DExtensions.cs index 3ef7026..e4c53fd 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenVector3DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenVector3DExtensions.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenVector3DExtensions { diff --git a/Engine.Systems/Tween/IEasing.cs b/Engine.Systems/Tween/IEasing.cs index a81331f..acf1502 100644 --- a/Engine.Systems/Tween/IEasing.cs +++ b/Engine.Systems/Tween/IEasing.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public interface IEasing { diff --git a/Engine.Systems/Tween/ITween.cs b/Engine.Systems/Tween/ITween.cs index f4d881b..559d3ad 100644 --- a/Engine.Systems/Tween/ITween.cs +++ b/Engine.Systems/Tween/ITween.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public interface ITween { diff --git a/Engine.Systems/Tween/ITweenManager.cs b/Engine.Systems/Tween/ITweenManager.cs index 2dc52d9..f1739fc 100644 --- a/Engine.Systems/Tween/ITweenManager.cs +++ b/Engine.Systems/Tween/ITweenManager.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public interface ITweenManager { diff --git a/Engine.Systems/Tween/Tween.cs b/Engine.Systems/Tween/Tween.cs index c92aa94..a8afc42 100644 --- a/Engine.Systems/Tween/Tween.cs +++ b/Engine.Systems/Tween/Tween.cs @@ -1,6 +1,6 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; internal class Tween : ITween { diff --git a/Engine.Systems/Tween/TweenExtensions.cs b/Engine.Systems/Tween/TweenExtensions.cs index 4b02cac..e0ffc09 100644 --- a/Engine.Systems/Tween/TweenExtensions.cs +++ b/Engine.Systems/Tween/TweenExtensions.cs @@ -1,6 +1,6 @@ using System; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public static class TweenExtensions { diff --git a/Engine.Systems/Tween/TweenManager.cs b/Engine.Systems/Tween/TweenManager.cs index 4c0b599..53f830d 100644 --- a/Engine.Systems/Tween/TweenManager.cs +++ b/Engine.Systems/Tween/TweenManager.cs @@ -1,9 +1,9 @@ using System.Collections; using System.Collections.Generic; -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public class TweenManager : Behaviour, ITweenManager { diff --git a/Engine.Systems/Tween/TweenState.cs b/Engine.Systems/Tween/TweenState.cs index 166e925..df010c0 100644 --- a/Engine.Systems/Tween/TweenState.cs +++ b/Engine.Systems/Tween/TweenState.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public enum TweenState { diff --git a/Engine.Systems/Tween/Yields/WaitForTweenCompleteCoroutineYield.cs b/Engine.Systems/Tween/Yields/WaitForTweenCompleteCoroutineYield.cs index 0a8c290..b574530 100644 --- a/Engine.Systems/Tween/Yields/WaitForTweenCompleteCoroutineYield.cs +++ b/Engine.Systems/Tween/Yields/WaitForTweenCompleteCoroutineYield.cs @@ -1,5 +1,5 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public class WaitForTweenCompleteCoroutineYield(ITween tween) : CoroutineYield(() => tween.State == TweenState.Completed); diff --git a/Engine.Systems/Tween/Yields/WaitForTweenDoneCoroutineYield.cs b/Engine.Systems/Tween/Yields/WaitForTweenDoneCoroutineYield.cs index b34330b..3ab3d78 100644 --- a/Engine.Systems/Tween/Yields/WaitForTweenDoneCoroutineYield.cs +++ b/Engine.Systems/Tween/Yields/WaitForTweenDoneCoroutineYield.cs @@ -1,5 +1,5 @@ -using Syntriax.Engine.Core; +using Engine.Core; -namespace Syntriax.Engine.Systems.Tween; +namespace Engine.Systems.Tween; public class WaitWhileTweenActiveCoroutineYield(ITween tween) : CoroutineYield(() => tween.State.CheckFlag(TweenState.Completed | TweenState.Cancelled)); diff --git a/Engine/Engine.csproj b/Engine/Engine.csproj index be663c5..c3763fb 100644 --- a/Engine/Engine.csproj +++ b/Engine/Engine.csproj @@ -4,7 +4,8 @@ net9.0 disable enable - Syntriax.Engine + Engine + Engine diff --git a/Engine/Preserver.cs b/Engine/Preserver.cs index a272d7e..f26a7ac 100644 --- a/Engine/Preserver.cs +++ b/Engine/Preserver.cs @@ -1,4 +1,4 @@ -namespace Syntriax.Engine +namespace Engine { // This is pretty much so the assembly gets loaded automatically because // the builds include the assembly but sometimes doesn't link load it at startup. -- 2.49.1 From 65dcb0c5647484b02767ac9fbcdb397a820d59f6 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 5 Aug 2025 19:48:49 +0300 Subject: [PATCH 55/91] BREAKING CHANGE: moved yaml serialization from Engine.Serialization to Engine.Integration --- .gitmodules | 4 ++-- .../Converters/Abstract/IEngineTypeYamlConverter.cs | 0 .../Converters/BehaviourControllerConverter.cs | 0 .../Converters/BehaviourConverter.cs | 0 .../Converters/EngineTypeYamlConverterBase.cs | 0 .../Converters/Primitives/AABBConverter.cs | 0 .../Converters/Primitives/CircleConverter.cs | 0 .../Converters/Primitives/ColorHSVConverter.cs | 0 .../Converters/Primitives/ColorRGBAConverter.cs | 0 .../Converters/Primitives/ColorRGBConverter.cs | 0 .../Converters/Primitives/Line2DConverter.cs | 0 .../Converters/Primitives/Line2DEquationConverter.cs | 0 .../Converters/Primitives/Projection1DConverter.cs | 0 .../Converters/Primitives/QuaternionConverter.cs | 0 .../Converters/Primitives/Shape2DConverter.cs | 0 .../Converters/Primitives/TriangleConverter.cs | 0 .../Converters/Primitives/Vector2DConverter.cs | 0 .../Converters/Primitives/Vector3DConverter.cs | 0 .../Converters/SerializedClassConverter.cs | 0 .../Converters/StateEnableConverter.cs | 0 .../Converters/TypeContainerConverter.cs | 0 .../Converters/UniverseConverter.cs | 0 .../Converters/UniverseObjectConverter.cs | 0 .../Engine.Integration.Yaml.csproj | 4 ++-- .../SerializerInProgressException.cs | 0 .../Engine.Integration.Yaml}/YamlSerializer.cs | 0 Engine.Integration/YamlDotNet | 1 + Engine.Serializers/YamlDotNet | 1 - Engine.sln | 9 +++------ 29 files changed, 8 insertions(+), 11 deletions(-) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Abstract/IEngineTypeYamlConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/BehaviourControllerConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/BehaviourConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/EngineTypeYamlConverterBase.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/AABBConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/CircleConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/ColorHSVConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/ColorRGBAConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/ColorRGBConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/Line2DConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/Line2DEquationConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/Projection1DConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/QuaternionConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/Shape2DConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/TriangleConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/Vector2DConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/Primitives/Vector3DConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/SerializedClassConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/StateEnableConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/TypeContainerConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/UniverseConverter.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/Converters/UniverseObjectConverter.cs (100%) rename Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj => Engine.Integration/Engine.Integration.Yaml/Engine.Integration.Yaml.csproj (76%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/SerializerInProgressException.cs (100%) rename {Engine.Serializers/Engine.Serializers.Yaml => Engine.Integration/Engine.Integration.Yaml}/YamlSerializer.cs (100%) create mode 160000 Engine.Integration/YamlDotNet delete mode 160000 Engine.Serializers/YamlDotNet diff --git a/.gitmodules b/.gitmodules index 5b155fd..269915b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "Engine.Serializers/YamlDotNet"] - path = Engine.Serializers/YamlDotNet +[submodule "Engine.Integration/YamlDotNet"] + path = Engine.Integration/YamlDotNet url = git@github.com:Syntriax/YamlDotNet.git diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/BehaviourControllerConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/BehaviourControllerConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/BehaviourConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/BehaviourConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/EngineTypeYamlConverterBase.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/EngineTypeYamlConverterBase.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/AABBConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/AABBConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/CircleConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/CircleConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/ColorHSVConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/ColorHSVConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/ColorRGBAConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/ColorRGBAConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/ColorRGBConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/ColorRGBConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Line2DConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Line2DConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Line2DEquationConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Line2DEquationConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Projection1DConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Projection1DConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/QuaternionConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/QuaternionConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Shape2DConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Shape2DConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/TriangleConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/TriangleConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Vector2DConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Vector2DConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Vector3DConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/Primitives/Vector3DConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/SerializedClassConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/SerializedClassConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/StateEnableConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/StateEnableConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/StateEnableConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/StateEnableConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/TypeContainerConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/TypeContainerConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/UniverseConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/UniverseConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs b/Engine.Integration/Engine.Integration.Yaml/Converters/UniverseObjectConverter.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs rename to Engine.Integration/Engine.Integration.Yaml/Converters/UniverseObjectConverter.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj b/Engine.Integration/Engine.Integration.Yaml/Engine.Integration.Yaml.csproj similarity index 76% rename from Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj rename to Engine.Integration/Engine.Integration.Yaml/Engine.Integration.Yaml.csproj index 59ce055..4878b8e 100644 --- a/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj +++ b/Engine.Integration/Engine.Integration.Yaml/Engine.Integration.Yaml.csproj @@ -4,8 +4,8 @@ net9.0 disable enable - Engine.Serializers.Yaml - Engine.Serializers.Yaml + Engine.Integration.Yaml + Engine.Integration.Yaml diff --git a/Engine.Serializers/Engine.Serializers.Yaml/SerializerInProgressException.cs b/Engine.Integration/Engine.Integration.Yaml/SerializerInProgressException.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/SerializerInProgressException.cs rename to Engine.Integration/Engine.Integration.Yaml/SerializerInProgressException.cs diff --git a/Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs b/Engine.Integration/Engine.Integration.Yaml/YamlSerializer.cs similarity index 100% rename from Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs rename to Engine.Integration/Engine.Integration.Yaml/YamlSerializer.cs diff --git a/Engine.Integration/YamlDotNet b/Engine.Integration/YamlDotNet new file mode 160000 index 0000000..b8ac2a9 --- /dev/null +++ b/Engine.Integration/YamlDotNet @@ -0,0 +1 @@ +Subproject commit b8ac2a98ffcc12434eff6c6abb75b38ad1b1ab04 diff --git a/Engine.Serializers/YamlDotNet b/Engine.Serializers/YamlDotNet deleted file mode 160000 index 62048d7..0000000 --- a/Engine.Serializers/YamlDotNet +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 62048d7abe5b233570d59c7d8043c21a4def2cb6 diff --git a/Engine.sln b/Engine.sln index b81932e..59b17e5 100644 --- a/Engine.sln +++ b/Engine.sln @@ -11,18 +11,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Systems", "Engine.Sy EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine", "Engine\Engine.csproj", "{58AE79C1-9203-44AE-8022-AA180F0A71DC}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine.Serializers", "Engine.Serializers", "{F88E129A-9A47-4D27-96EE-6EC02F79594B}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine.Integration", "Engine.Integration", "{F88E129A-9A47-4D27-96EE-6EC02F79594B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Serializers.Yaml", "Engine.Serializers\Engine.Serializers.Yaml\Engine.Serializers.Yaml.csproj", "{E9D1CDC3-5BFF-4C87-AFEB-6CE372709176}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Integration.Yaml", "Engine.Integration\Engine.Integration.Yaml\Engine.Integration.Yaml.csproj", "{E9D1CDC3-5BFF-4C87-AFEB-6CE372709176}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YamlDotNet", "Engine.Serializers\YamlDotNet\YamlDotNet\YamlDotNet.csproj", "{3D852C92-BC14-4893-AEF2-50612DAFCD8F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YamlDotNet", "Engine.Integration\YamlDotNet\YamlDotNet\YamlDotNet.csproj", "{3D852C92-BC14-4893-AEF2-50612DAFCD8F}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Integration", "Integration", "{823D4020-332D-2C13-F261-6F510F11A57E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Integration.MonoGame", "Engine.Integration\Engine.Integration.MonoGame\Engine.Integration.MonoGame.csproj", "{C3438D33-0879-44E4-9DF0-D29F5621C44C}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine.Integration", "Engine.Integration", "{3122C4BF-14AF-E0C0-27A2-43B3E062692D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Integration.LiteNetLib", "Engine.Integration\Engine.Integration.LiteNetLib\Engine.Integration.LiteNetLib.csproj", "{121A7C66-1691-4DA5-B070-A681A83779AC}" EndProject Global @@ -139,6 +137,5 @@ Global {E9D1CDC3-5BFF-4C87-AFEB-6CE372709176} = {F88E129A-9A47-4D27-96EE-6EC02F79594B} {3D852C92-BC14-4893-AEF2-50612DAFCD8F} = {F88E129A-9A47-4D27-96EE-6EC02F79594B} {C3438D33-0879-44E4-9DF0-D29F5621C44C} = {823D4020-332D-2C13-F261-6F510F11A57E} - {121A7C66-1691-4DA5-B070-A681A83779AC} = {3122C4BF-14AF-E0C0-27A2-43B3E062692D} EndGlobalSection EndGlobal -- 2.49.1 From b04e0f81cd7e12541efc10dcb2686702fe530db1 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 5 Aug 2025 20:43:54 +0300 Subject: [PATCH 56/91] fix: triangle batch not drawing shapes because not setting rasterizer state properly --- .../Engine.Integration.MonoGame/TriangleBatch.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs b/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs index bc9ec50..1612526 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs @@ -14,11 +14,11 @@ public class TriangleBatch : ITriangleBatch private Matrix _view; private Matrix _projection; private readonly BasicEffect basicEffect; + private readonly RasterizerState rasterizerState = new() { CullMode = CullMode.None }; public TriangleBatch(GraphicsDevice graphicsDevice) { this.graphicsDevice = graphicsDevice; - this.graphicsDevice.RasterizerState = new RasterizerState() { CullMode = CullMode.None }; basicEffect = new(graphicsDevice); basicEffect.VertexColorEnabled = true; } @@ -58,6 +58,7 @@ public class TriangleBatch : ITriangleBatch private void Flush() { + graphicsDevice.RasterizerState = rasterizerState; basicEffect.Projection = _projection; basicEffect.View = _view; vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), 1024, BufferUsage.WriteOnly); -- 2.49.1 From d78c42a65327a5889636da1a8d99e57513e20098 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 5 Aug 2025 20:57:03 +0300 Subject: [PATCH 57/91] feat: update manager now calls last frames listeners on process exit as well --- Engine.Core/Systems/UpdateManager.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index 5d0c0cc..ac61131 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -75,9 +75,16 @@ public class UpdateManager : Behaviour args.BehaviourRemoved.LastActiveFrame(); } + private void CallLastFramesBeforeExit(object? sender, System.EventArgs e) + { + for (int i = lastFrameUpdates.Count - 1; i >= 0; i--) + lastFrameUpdates[i].LastActiveFrame(); + } + public UpdateManager() { firstFrameUpdates.OnCollected.AddListener(OnFirstFrameCollected); lastFrameUpdates.OnRemoved.AddListener(OnLastFrameRemoved); + System.AppDomain.CurrentDomain.ProcessExit += CallLastFramesBeforeExit; } } -- 2.49.1 From 3912706d2728d37d4a40655a0e82e1f5a2c00a54 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 8 Aug 2025 16:27:57 +0300 Subject: [PATCH 58/91] chore: force .log extension to log files --- Engine.Core/Debug/FileLogger.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Engine.Core/Debug/FileLogger.cs b/Engine.Core/Debug/FileLogger.cs index ff305e2..060ea6a 100644 --- a/Engine.Core/Debug/FileLogger.cs +++ b/Engine.Core/Debug/FileLogger.cs @@ -14,6 +14,9 @@ public class FileLogger : LoggerBase public FileLogger(string filePath) { + if (!filePath.EndsWith(".log")) + filePath += ".log"; + FilePath = filePath; bool isRelativePath = Path.GetFullPath(filePath).CompareTo(filePath) != 0; -- 2.49.1 From efed24de2011eb9aad6fbeac38697eb9a7c37e3f Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 8 Aug 2025 16:28:08 +0300 Subject: [PATCH 59/91] feat: rotating file logger added --- Engine.Core/Debug/RotatingFileLogger.cs | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Engine.Core/Debug/RotatingFileLogger.cs diff --git a/Engine.Core/Debug/RotatingFileLogger.cs b/Engine.Core/Debug/RotatingFileLogger.cs new file mode 100644 index 0000000..ec3e007 --- /dev/null +++ b/Engine.Core/Debug/RotatingFileLogger.cs @@ -0,0 +1,71 @@ +using System; +using System.IO; +using System.Linq; + +namespace Engine.Core.Debug; + +public class RotatingFileLogger : ILogger +{ + public readonly FileLogger FileLogger = null!; + public readonly string Directory = string.Empty; + public readonly int RotateLength = 3; + + public RotatingFileLogger(string directory, string namePrefix, string nameSuffix = "", int rotateLength = 3) + { + RotateLength = rotateLength; + + string fileName = Path.Combine(directory, namePrefix); + if (!string.IsNullOrWhiteSpace(nameSuffix)) + fileName += $"_{nameSuffix}"; + + bool isRelativePath = Path.GetFullPath(fileName).CompareTo(fileName) != 0; + + if (isRelativePath) + fileName = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName)); + + if (File.Exists($"{fileName}.log")) + RenameExistingLogs(fileName, RotateLength); + + FileLogger = new(fileName); + + Directory = Path.GetDirectoryName(fileName) ?? throw new("Unexpected error on getting directory of logger path"); + RotateLastLogs(Directory, namePrefix, RotateLength); + } + + private static void RenameExistingLogs(string filePath, int rotateLength) + { + for (int i = rotateLength - 1; i >= 0; i--) + { + string source = i == 0 + ? $"{filePath}.log" + : $"{filePath}_{i}.log"; + + string dest = $"{filePath}_{i + 1}.log"; + + if (!File.Exists(source)) + continue; + + if (File.Exists(dest)) + File.Delete(dest); + + File.Move(source, dest); + } + } + + private static void RotateLastLogs(string directory, string prefix, int rotateLength) + { + IOrderedEnumerable logs = System.IO.Directory.GetFiles(directory, $"{prefix}*.log") + .OrderBy(File.GetCreationTime); + + foreach (string file in logs.Skip(rotateLength)) + try + { + ILogger.Shared.Log($"Removing log file located at \"{file}\" during rotation."); + File.Delete(file); + } + catch (Exception e) { ILogger.Shared.LogException($"Failed to rotate log file at \"{file}\"", e); } + } + + public ILogger.Level FilterLevel { get => FileLogger.FilterLevel; set => FileLogger.FilterLevel = value; } + public void Log(string message, ILogger.Level level = ILogger.Level.Info, bool force = false) => FileLogger.Log(message, level, force); +} -- 2.49.1 From 620ef911fa2b7b70c6fdce0beb421646cd8d01c1 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 9 Aug 2025 21:01:25 +0300 Subject: [PATCH 60/91] fix: parameter name typo --- Engine.Core/UniverseObject.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Engine.Core/UniverseObject.cs b/Engine.Core/UniverseObject.cs index 78307f2..d70e995 100644 --- a/Engine.Core/UniverseObject.cs +++ b/Engine.Core/UniverseObject.cs @@ -100,14 +100,14 @@ public class UniverseObject : BaseEntity, IUniverseObject return true; } - public void AddChild(IUniverseObject parent) + public void AddChild(IUniverseObject child) { - if (_children.Contains(parent)) + if (_children.Contains(child)) return; - _children.Add(parent); - parent.Parent = this; - OnChildrenAdded?.Invoke(this, new(parent)); + _children.Add(child); + child.Parent = this; + OnChildrenAdded?.Invoke(this, new(child)); } public void RemoveChild(IUniverseObject child) -- 2.49.1 From 949dfeb3d907fb1a54aaf86c61dde164ac8e121d Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 9 Aug 2025 21:03:45 +0300 Subject: [PATCH 61/91] fix: universe reverse for loop index doesn't start with count - 1 --- Engine.Core/Universe.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index 37c1498..ff0504a 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -120,7 +120,7 @@ public class Universe : BaseEntity, IUniverse protected override void FinalizeInternal() { base.FinalizeInternal(); - for (int i = UniverseObjects.Count; i >= 0; i--) + for (int i = UniverseObjects.Count - 1; i >= 0; i--) UniverseObjects[i].Finalize(); } -- 2.49.1 From 0205354202cb312fa47b905ffd9b1de7eb45c2a0 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 9 Aug 2025 21:09:36 +0300 Subject: [PATCH 62/91] fix: universe entrance manager using the wrong reference on universe exit --- Engine.Core/Systems/UniverseEntranceManager.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Engine.Core/Systems/UniverseEntranceManager.cs b/Engine.Core/Systems/UniverseEntranceManager.cs index 4fa7651..0fa28e5 100644 --- a/Engine.Core/Systems/UniverseEntranceManager.cs +++ b/Engine.Core/Systems/UniverseEntranceManager.cs @@ -17,8 +17,8 @@ public class UniverseEntranceManager : Behaviour { enterUniverses.Assign(universe); - foreach (IUniverseObject universeObject in Universe.UniverseObjects) - OnUniverseObjectRegistered(Universe, new(universeObject)); + foreach (IUniverseObject universeObject in universe.UniverseObjects) + OnUniverseObjectRegistered(universe, new(universeObject)); universe.OnUniverseObjectRegistered.AddListener(OnUniverseObjectRegistered); universe.OnUniverseObjectUnRegistered.AddListener(OnUniverseObjectUnRegistered); @@ -28,8 +28,8 @@ public class UniverseEntranceManager : Behaviour { enterUniverses.Unassign(); - foreach (IUniverseObject universeObject in Universe.UniverseObjects) - OnUniverseObjectUnRegistered(Universe, new(universeObject)); + foreach (IUniverseObject universeObject in universe.UniverseObjects) + OnUniverseObjectUnRegistered(universe, new(universeObject)); universe.OnUniverseObjectRegistered.RemoveListener(OnUniverseObjectRegistered); universe.OnUniverseObjectUnRegistered.RemoveListener(OnUniverseObjectUnRegistered); -- 2.49.1 From a31b39fd1d28594d864af94275ca571e5d38ed12 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 9 Aug 2025 21:36:28 +0300 Subject: [PATCH 63/91] fix: universe finalize not working properly --- Engine.Core/Universe.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index ff0504a..bb00b98 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -121,7 +121,7 @@ public class Universe : BaseEntity, IUniverse { base.FinalizeInternal(); for (int i = UniverseObjects.Count - 1; i >= 0; i--) - UniverseObjects[i].Finalize(); + Remove(UniverseObjects[i]); } public void Update(UniverseTime engineTime) -- 2.49.1 From a4b83679b1c45313b57a7a2581547aacf9f3064f Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 9 Aug 2025 21:41:24 +0300 Subject: [PATCH 64/91] chore: added todo for a rare bug --- Engine.Core/Helpers/Event.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs index 13d112c..3b4a6db 100644 --- a/Engine.Core/Helpers/Event.cs +++ b/Engine.Core/Helpers/Event.cs @@ -5,6 +5,12 @@ using Engine.Core.Debug; namespace Engine.Core; +// TODO!: every reverse loop has a chance to have more than 1 unsubscription, +// for (int i = listeners.Count - 1; i >= 0; i--) +// can be replaced with +// for (int i = listeners.Count - 1; i >= 0; i = Math.Min(i - 1, listeners.Count - 1)) +// but this would causes possible double calls on already called callbacks, find a better method. + /// /// Represents a simple event with no parameters. /// Example usage: -- 2.49.1 From cf68f6ca6f244f4e1c5bc2fef2cb5275af90ad5a Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 9 Aug 2025 22:29:44 +0300 Subject: [PATCH 65/91] fix: first frame updates not calling first, they are now set to be a high priority --- Engine.Core/Systems/UpdateManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index ac61131..1ee0257 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace Engine.Core; @@ -23,6 +24,7 @@ public class UpdateManager : Behaviour updateEntities.Assign(universe); postUpdateEntities.Assign(universe); + universe.OnPreUpdate.AddListener(OnFirstUpdate, int.MaxValue); universe.OnPreUpdate.AddListener(OnPreUpdate); universe.OnUpdate.AddListener(OnUpdate); universe.OnPostUpdate.AddListener(OnPostUpdate); @@ -36,19 +38,23 @@ public class UpdateManager : Behaviour updateEntities.Unassign(); postUpdateEntities.Unassign(); + universe.OnPreUpdate.RemoveListener(OnFirstUpdate); universe.OnPreUpdate.RemoveListener(OnPreUpdate); universe.OnUpdate.RemoveListener(OnUpdate); universe.OnPostUpdate.RemoveListener(OnPostUpdate); } - private void OnPreUpdate(IUniverse sender, IUniverse.UpdateArguments args) + private void OnFirstUpdate(IUniverse sender, IUniverse.UpdateArguments args) { for (int i = toCallFirstFrameUpdates.Count - 1; i >= 0; i--) { toCallFirstFrameUpdates[i].FirstActiveFrame(); toCallFirstFrameUpdates.RemoveAt(i); } + } + private void OnPreUpdate(IUniverse sender, IUniverse.UpdateArguments args) + { for (int i = preUpdateEntities.Count - 1; i >= 0; i--) preUpdateEntities[i].PreUpdate(); } -- 2.49.1 From 746d29fb7a0f71bd01b9237f73022eee0a58e1f9 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 10 Aug 2025 14:42:47 +0300 Subject: [PATCH 66/91] refactor: shortened IButtonInputs event declaration --- .../Behaviours/KeyboardInputs.cs | 28 +++++++++---------- Engine.Systems/Input/IButtonInputs.cs | 14 ++++++---- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs index fbb8a77..5e333e6 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/KeyboardInputs.cs @@ -10,11 +10,11 @@ namespace Engine.Integration.MonoGame; public class KeyboardInputs : Behaviour, IButtonInputs, IUpdate { - public Event, IButtonInputs.ButtonCallbackArguments> OnAnyButtonPressed { get; } = new(); - public Event, IButtonInputs.ButtonCallbackArguments> OnAnyButtonReleased { get; } = new(); + public IButtonInputs.InputEvent OnAnyButtonPressed { get; } = new(); + public IButtonInputs.InputEvent OnAnyButtonReleased { get; } = new(); - private readonly Dictionary, IButtonInputs.ButtonCallbackArguments>> OnPressed = new(256); - private readonly Dictionary, IButtonInputs.ButtonCallbackArguments>> OnReleased = new(256); + private readonly Dictionary.InputEvent> OnPressed = new(256); + private readonly Dictionary.InputEvent> OnReleased = new(256); private int cachePressedCurrentlyCount = 0; private readonly Keys[] cachePressedCurrently = new Keys[256]; @@ -22,9 +22,9 @@ public class KeyboardInputs : Behaviour, IButtonInputs, IUpdate private int cachePressedPreviouslyCount = 0; private readonly Keys[] cachePressedPreviously = new Keys[256]; - public void RegisterOnPress(Keys key, Event, IButtonInputs.ButtonCallbackArguments>.EventHandler callback) + public void RegisterOnPress(Keys key, IButtonInputs.InputEvent.EventHandler callback) { - if (!OnPressed.TryGetValue(key, out Event, IButtonInputs.ButtonCallbackArguments>? delegateCallback)) + if (!OnPressed.TryGetValue(key, out IButtonInputs.InputEvent? delegateCallback)) { delegateCallback = new(); OnPressed.Add(key, delegateCallback); @@ -33,15 +33,15 @@ public class KeyboardInputs : Behaviour, IButtonInputs, IUpdate delegateCallback.AddListener(callback); } - public void UnregisterOnPress(Keys key, Event, IButtonInputs.ButtonCallbackArguments>.EventHandler callback) + public void UnregisterOnPress(Keys key, IButtonInputs.InputEvent.EventHandler callback) { - if (OnPressed.TryGetValue(key, out Event, IButtonInputs.ButtonCallbackArguments>? delegateCallback)) + if (OnPressed.TryGetValue(key, out IButtonInputs.InputEvent? delegateCallback)) delegateCallback.RemoveListener(callback); } - public void RegisterOnRelease(Keys key, Event, IButtonInputs.ButtonCallbackArguments>.EventHandler callback) + public void RegisterOnRelease(Keys key, IButtonInputs.InputEvent.EventHandler callback) { - if (!OnReleased.TryGetValue(key, out Event, IButtonInputs.ButtonCallbackArguments>? delegateCallback)) + if (!OnReleased.TryGetValue(key, out IButtonInputs.InputEvent? delegateCallback)) { delegateCallback = new(); OnReleased.Add(key, delegateCallback); @@ -50,9 +50,9 @@ public class KeyboardInputs : Behaviour, IButtonInputs, IUpdate delegateCallback.AddListener(callback); } - public void UnregisterOnRelease(Keys key, Event, IButtonInputs.ButtonCallbackArguments>.EventHandler callback) + public void UnregisterOnRelease(Keys key, IButtonInputs.InputEvent.EventHandler callback) { - if (OnReleased.TryGetValue(key, out Event, IButtonInputs.ButtonCallbackArguments>? delegateCallback)) + if (OnReleased.TryGetValue(key, out IButtonInputs.InputEvent? delegateCallback)) delegateCallback.RemoveListener(callback); } @@ -69,7 +69,7 @@ public class KeyboardInputs : Behaviour, IButtonInputs, IUpdate if (WasPressed(currentlyPressedKey)) continue; - if (OnPressed.TryGetValue(currentlyPressedKey, out Event, IButtonInputs.ButtonCallbackArguments>? callback)) + if (OnPressed.TryGetValue(currentlyPressedKey, out IButtonInputs.InputEvent? callback)) callback?.Invoke(this, new(currentlyPressedKey)); OnAnyButtonPressed?.Invoke(this, new(currentlyPressedKey)); @@ -82,7 +82,7 @@ public class KeyboardInputs : Behaviour, IButtonInputs, IUpdate if (IsPressed(previouslyPressedKey)) continue; - if (OnReleased.TryGetValue(previouslyPressedKey, out Event, IButtonInputs.ButtonCallbackArguments>? callback)) + if (OnReleased.TryGetValue(previouslyPressedKey, out IButtonInputs.InputEvent? callback)) callback?.Invoke(this, new(previouslyPressedKey)); OnAnyButtonReleased?.Invoke(this, new(previouslyPressedKey)); diff --git a/Engine.Systems/Input/IButtonInputs.cs b/Engine.Systems/Input/IButtonInputs.cs index 3b54529..da41a93 100644 --- a/Engine.Systems/Input/IButtonInputs.cs +++ b/Engine.Systems/Input/IButtonInputs.cs @@ -4,15 +4,17 @@ namespace Engine.Systems.Input; public interface IButtonInputs : IHasStateEnable { - Event, ButtonCallbackArguments> OnAnyButtonPressed { get; } - Event, ButtonCallbackArguments> OnAnyButtonReleased { get; } + InputEvent OnAnyButtonPressed { get; } + InputEvent OnAnyButtonReleased { get; } - void RegisterOnPress(T button, Event, ButtonCallbackArguments>.EventHandler callback); - void UnregisterOnPress(T button, Event, ButtonCallbackArguments>.EventHandler callback); - void RegisterOnRelease(T button, Event, ButtonCallbackArguments>.EventHandler callback); - void UnregisterOnRelease(T button, Event, ButtonCallbackArguments>.EventHandler callback); + void RegisterOnPress(T button, InputEvent.EventHandler callback); + void UnregisterOnPress(T button, InputEvent.EventHandler callback); + void RegisterOnRelease(T button, InputEvent.EventHandler callback); + void UnregisterOnRelease(T button, InputEvent.EventHandler callback); bool IsPressed(T button); readonly record struct ButtonCallbackArguments(T Button); + + class InputEvent : Event, ButtonCallbackArguments>; } -- 2.49.1 From f5a7077570a28582c5c1c2b5bf153cd0407ff41c Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 14 Aug 2025 20:31:46 +0300 Subject: [PATCH 67/91] perf: improved garbage created by tweens slightly They still do generate a lot of garbage but with boxed value pools I made the boxes reusable, it still does generate garbage through the delegate creation, gotta find a solution for them later --- .../EngineExtensions/TweenAABBExtensions.cs | 20 +++++++-- .../TweenCamera2DExtensions.cs | 16 +++++++- .../EngineExtensions/TweenCircleExtensions.cs | 21 ++++++++-- .../EngineExtensions/TweenColorExtensions.cs | 33 ++++++++++++++- .../TweenLine2DEquationExtensions.cs | 21 ++++++++-- .../EngineExtensions/TweenLine2DExtensions.cs | 21 ++++++++-- .../TweenPrimitiveExtensions.cs | 41 +++++++++++++++++++ .../TweenProjection1DExtensions.cs | 24 ++++++++--- .../TweenQuaternionExtensions.cs | 20 +++++++-- .../TweenTransform2DExtensions.cs | 31 ++++---------- .../TweenTriangleExtensions.cs | 27 ++++++++---- .../TweenVector2DExtensions.cs | 17 +++++++- .../TweenVector3DExtensions.cs | 17 +++++++- Engine.Systems/Tween/Helpers/Boxed.cs | 12 ++++++ Engine.Systems/Tween/Helpers/BoxedPool.cs | 14 +++++++ 15 files changed, 278 insertions(+), 57 deletions(-) create mode 100644 Engine.Systems/Tween/EngineExtensions/TweenPrimitiveExtensions.cs create mode 100644 Engine.Systems/Tween/Helpers/Boxed.cs create mode 100644 Engine.Systems/Tween/Helpers/BoxedPool.cs diff --git a/Engine.Systems/Tween/EngineExtensions/TweenAABBExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenAABBExtensions.cs index e0b6304..bfedd4f 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenAABBExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenAABBExtensions.cs @@ -1,10 +1,24 @@ -using System; using Engine.Core; namespace Engine.Systems.Tween; public static class TweenAABBExtensions { - public static ITween TweenAABB(this AABB initialAABB, ITweenManager tweenManager, float duration, AABB targetAABB, Action setMethod) - => tweenManager.StartTween(duration, t => setMethod?.Invoke(new AABB(initialAABB.LowerBoundary.Lerp(targetAABB.LowerBoundary, t), initialAABB.UpperBoundary.Lerp(targetAABB.UpperBoundary, t)))); + private static readonly BoxedPool boxedAABBPool = new(2); + + public static ITween TweenAABB(this AABB initialAABB, ITweenManager tweenManager, float duration, AABB targetAABB, System.Action setMethod) + { + Boxed boxedInitial = boxedAABBPool.Get(initialAABB); + Boxed boxedTarget = boxedAABBPool.Get(targetAABB); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke(new AABB(boxedInitial.Value.LowerBoundary.Lerp(boxedTarget.Value.LowerBoundary, t), boxedInitial.Value.UpperBoundary.Lerp(boxedTarget.Value.UpperBoundary, t)))); + + tween.OnComplete(() => + { + boxedAABBPool.Return(boxedInitial); + boxedAABBPool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenCamera2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenCamera2DExtensions.cs index 32d923c..d8d3059 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenCamera2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenCamera2DExtensions.cs @@ -4,9 +4,21 @@ namespace Engine.Systems.Tween; public static class TweenCamera2DExtensions { + private static readonly BoxedPool boxedFloatPool = new(2); + public static ITween TweenZoom(this ICamera2D camera2D, ITweenManager tweenManager, float duration, float targetZoom) { - float initialZoom = camera2D.Zoom; - return tweenManager.StartTween(duration, t => camera2D.Zoom = initialZoom.Lerp(targetZoom, t)); + Boxed boxedInitial = boxedFloatPool.Get(camera2D.Zoom); + Boxed boxedTarget = boxedFloatPool.Get(targetZoom); + + ITween tween = tweenManager.StartTween(duration, t => camera2D.Zoom = boxedInitial.Value.Lerp(boxedTarget.Value, t)); + + tween.OnComplete(() => + { + boxedFloatPool.Return(boxedInitial); + boxedFloatPool.Return(boxedTarget); + }); + + return tween; } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenCircleExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenCircleExtensions.cs index 959ed38..f0253b6 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenCircleExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenCircleExtensions.cs @@ -4,13 +4,28 @@ namespace Engine.Systems.Tween; public static class TweenCircleExtensions { + private static readonly BoxedPool boxedCirclePool = new(2); + public static ITween TweenCircle(this Circle initialCircle, ITweenManager tweenManager, float duration, Circle targetCircle, System.Action setMethod) - => tweenManager.StartTween(duration, + { + Boxed boxedInitial = boxedCirclePool.Get(initialCircle); + Boxed boxedTarget = boxedCirclePool.Get(targetCircle); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke( new Circle( - initialCircle.Center.Lerp(targetCircle.Center, t), - initialCircle.Diameter.Lerp(targetCircle.Diameter, t) + boxedInitial.Value.Center.Lerp(boxedTarget.Value.Center, t), + boxedInitial.Value.Diameter.Lerp(boxedTarget.Value.Diameter, t) ) ) ); + + tween.OnComplete(() => + { + boxedCirclePool.Return(boxedInitial); + boxedCirclePool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs index ce26271..3bf9216 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenColorExtensions.cs @@ -4,6 +4,9 @@ namespace Engine.Systems.Tween; public static class TweenColorExtensions { + private static readonly BoxedPool boxedColorHSVPool = new(2); + private static readonly BoxedPool boxedColorHSVAPool = new(2); + public static ITween TweenColor(this ColorRGB initialColorRGB, ITweenManager tweenManager, float duration, ColorRGB targetColorRGB, System.Action setMethod) => TweenColor((ColorHSV)initialColorRGB, tweenManager, duration, (ColorHSV)targetColorRGB, color => setMethod?.Invoke(color)); @@ -11,8 +14,34 @@ public static class TweenColorExtensions => TweenColor((ColorHSVA)initialColorRGBA, tweenManager, duration, (ColorHSVA)targetColorRGBA, color => setMethod?.Invoke(color)); public static ITween TweenColor(this ColorHSV initialColorHSV, ITweenManager tweenManager, float duration, ColorHSV targetColorHSV, System.Action setMethod) - => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorHSV.Lerp(targetColorHSV, t))); + { + Boxed boxedInitial = boxedColorHSVPool.Get(initialColorHSV); + Boxed boxedTarget = boxedColorHSVPool.Get(targetColorHSV); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke(boxedInitial.Value.Lerp(boxedTarget.Value, t))); + + tween.OnComplete(() => + { + boxedColorHSVPool.Return(boxedInitial); + boxedColorHSVPool.Return(boxedTarget); + }); + + return tween; + } public static ITween TweenColor(this ColorHSVA initialColorHSVA, ITweenManager tweenManager, float duration, ColorHSVA targetColorHSVA, System.Action setMethod) - => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorHSVA.Lerp(targetColorHSVA, t))); + { + Boxed boxedInitial = boxedColorHSVAPool.Get(initialColorHSVA); + Boxed boxedTarget = boxedColorHSVAPool.Get(targetColorHSVA); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke(boxedInitial.Value.Lerp(boxedTarget.Value, t))); + + tween.OnComplete(() => + { + boxedColorHSVAPool.Return(boxedInitial); + boxedColorHSVAPool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenLine2DEquationExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenLine2DEquationExtensions.cs index 52e2bdc..51fc9e6 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenLine2DEquationExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenLine2DEquationExtensions.cs @@ -4,13 +4,28 @@ namespace Engine.Systems.Tween; public static class TweenLine2DEquationExtensions { + private static readonly BoxedPool boxedLine2DEquationPool = new(2); + public static ITween TweenLine2DEquation(this Line2DEquation initialLine2DEquation, ITweenManager tweenManager, float duration, Line2DEquation targetLine2DEquation, System.Action setMethod) - => tweenManager.StartTween(duration, + { + Boxed boxedInitial = boxedLine2DEquationPool.Get(initialLine2DEquation); + Boxed boxedTarget = boxedLine2DEquationPool.Get(targetLine2DEquation); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke( new Line2DEquation( - initialLine2DEquation.Slope.Lerp(targetLine2DEquation.Slope, t), - initialLine2DEquation.OffsetY.Lerp(targetLine2DEquation.OffsetY, t) + boxedInitial.Value.Slope.Lerp(boxedTarget.Value.Slope, t), + boxedInitial.Value.OffsetY.Lerp(boxedTarget.Value.OffsetY, t) ) ) ); + + tween.OnComplete(() => + { + boxedLine2DEquationPool.Return(boxedInitial); + boxedLine2DEquationPool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenLine2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenLine2DExtensions.cs index e9f5c46..a34ec4d 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenLine2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenLine2DExtensions.cs @@ -4,13 +4,28 @@ namespace Engine.Systems.Tween; public static class TweenLine2DExtensions { + private static readonly BoxedPool boxedLine2DPool = new(2); + public static ITween TweenLine2D(this Line2D initialLine2D, ITweenManager tweenManager, float duration, Line2D targetLine2D, System.Action setMethod) - => tweenManager.StartTween(duration, + { + Boxed boxedInitial = boxedLine2DPool.Get(initialLine2D); + Boxed boxedTarget = boxedLine2DPool.Get(targetLine2D); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke( new Line2D( - initialLine2D.From.Lerp(targetLine2D.From, t), - initialLine2D.To.Lerp(targetLine2D.To, t) + boxedInitial.Value.From.Lerp(boxedTarget.Value.From, t), + boxedInitial.Value.To.Lerp(boxedTarget.Value.To, t) ) ) ); + + tween.OnComplete(() => + { + boxedLine2DPool.Return(boxedInitial); + boxedLine2DPool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenPrimitiveExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenPrimitiveExtensions.cs new file mode 100644 index 0000000..1dc857f --- /dev/null +++ b/Engine.Systems/Tween/EngineExtensions/TweenPrimitiveExtensions.cs @@ -0,0 +1,41 @@ +using Engine.Core; + +namespace Engine.Systems.Tween; + +public static class TweenPrimitiveExtensions +{ + private static readonly BoxedPool boxedFloatPool = new(2); + private static readonly BoxedPool boxedIntPool = new(2); + + public static ITween TweenFloat(this float initialFloat, ITweenManager tweenManager, float duration, float targetFloat, System.Action setMethod) + { + Boxed boxedInitial = boxedFloatPool.Get(initialFloat); + Boxed boxedTarget = boxedFloatPool.Get(targetFloat); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke(boxedInitial.Value.Lerp(boxedTarget.Value, t))); + + tween.OnComplete(() => + { + boxedFloatPool.Return(boxedInitial); + boxedFloatPool.Return(boxedTarget); + }); + + return tween; + } + + public static ITween TweenInt(this int initialInt, ITweenManager tweenManager, float duration, int targetInt, System.Action setMethod) + { + Boxed boxedInitial = boxedIntPool.Get(initialInt); + Boxed boxedTarget = boxedIntPool.Get(targetInt); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke(boxedInitial.Value + (boxedTarget.Value - boxedInitial.Value) * t)); + + tween.OnComplete(() => + { + boxedIntPool.Return(boxedInitial); + boxedIntPool.Return(boxedTarget); + }); + + return tween; + } +} diff --git a/Engine.Systems/Tween/EngineExtensions/TweenProjection1DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenProjection1DExtensions.cs index b20ba7b..b18399e 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenProjection1DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenProjection1DExtensions.cs @@ -1,17 +1,31 @@ -using System; using Engine.Core; namespace Engine.Systems.Tween; public static class TweenProjection1DExtensions { - public static ITween TweenProjection1D(this Projection1D initialProjection1D, ITweenManager tweenManager, float duration, Projection1D targetProjection1D, Action setMethod) - => tweenManager.StartTween(duration, + private static readonly BoxedPool boxedProjection1DPool = new(2); + + public static ITween TweenProjection1D(this Projection1D initialProjection1D, ITweenManager tweenManager, float duration, Projection1D targetProjection1D, System.Action setMethod) + { + Boxed boxedInitial = boxedProjection1DPool.Get(initialProjection1D); + Boxed boxedTarget = boxedProjection1DPool.Get(targetProjection1D); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke( new Projection1D( - initialProjection1D.Min.Lerp(targetProjection1D.Min, t), - initialProjection1D.Max.Lerp(targetProjection1D.Max, t) + boxedInitial.Value.Min.Lerp(boxedTarget.Value.Min, t), + boxedInitial.Value.Max.Lerp(boxedTarget.Value.Max, t) ) ) ); + + tween.OnComplete(() => + { + boxedProjection1DPool.Return(boxedInitial); + boxedProjection1DPool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenQuaternionExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenQuaternionExtensions.cs index 5397433..976c2d4 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenQuaternionExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenQuaternionExtensions.cs @@ -1,10 +1,24 @@ -using System; using Engine.Core; namespace Engine.Systems.Tween; public static class TweenQuaternionExtensions { - public static ITween TweenQuaternion(this Quaternion initialQuaternion, ITweenManager tweenManager, float duration, Quaternion targetQuaternion, Action setMethod) - => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialQuaternion.SLerp(targetQuaternion, t))); + private static readonly BoxedPool boxedQuaternionPool = new(2); + + public static ITween TweenQuaternion(this Quaternion initialQuaternion, ITweenManager tweenManager, float duration, Quaternion targetQuaternion, System.Action setMethod) + { + Boxed boxedInitial = boxedQuaternionPool.Get(initialQuaternion); + Boxed boxedTarget = boxedQuaternionPool.Get(targetQuaternion); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke(boxedInitial.Value.SLerp(boxedTarget.Value, t))); + + tween.OnComplete(() => + { + boxedQuaternionPool.Return(boxedInitial); + boxedQuaternionPool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenTransform2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenTransform2DExtensions.cs index c3b3e4b..62a2aac 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenTransform2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenTransform2DExtensions.cs @@ -5,40 +5,23 @@ namespace Engine.Systems.Tween; public static class TweenTransform2DExtensions { public static ITween TweenPosition(this ITransform2D transform2D, ITweenManager tweenManager, float duration, Vector2D targetPosition) - { - Vector2D initialPosition = transform2D.Position; - return tweenManager.StartTween(duration, t => transform2D.Position = initialPosition.Lerp(targetPosition, t)); - } + => transform2D.Position.TweenVector2D(tweenManager, duration, targetPosition, x => transform2D.Position = x); public static ITween TweenScale(this ITransform2D transform2D, ITweenManager tweenManager, float duration, Vector2D targetScale) - { - Vector2D initialScale = transform2D.Scale; - return tweenManager.StartTween(duration, t => transform2D.Scale = initialScale.Lerp(targetScale, t)); - } + => transform2D.Scale.TweenVector2D(tweenManager, duration, targetScale, x => transform2D.Scale = x); public static ITween TweenRotation(this ITransform2D transform2D, ITweenManager tweenManager, float duration, float targetRotation) - { - float initialRotation = transform2D.Rotation; - return tweenManager.StartTween(duration, t => transform2D.Rotation = initialRotation.Lerp(targetRotation, t)); - } + => transform2D.Rotation.TweenFloat(tweenManager, duration, targetRotation, x => transform2D.Rotation = x); public static ITween TweenLocalPosition(this ITransform2D transform2D, ITweenManager tweenManager, float duration, Vector2D targetLocalPosition) - { - Vector2D initialLocalPosition = transform2D.LocalPosition; - return tweenManager.StartTween(duration, t => transform2D.LocalPosition = initialLocalPosition.Lerp(targetLocalPosition, t)); - } + => transform2D.LocalPosition.TweenVector2D(tweenManager, duration, targetLocalPosition, x => transform2D.LocalPosition = x); public static ITween TweenLocalScale(this ITransform2D transform2D, ITweenManager tweenManager, float duration, Vector2D targetLocalScale) - { - Vector2D initialLocalScale = transform2D.LocalScale; - return tweenManager.StartTween(duration, t => transform2D.LocalScale = initialLocalScale.Lerp(targetLocalScale, t)); - } + => transform2D.LocalScale.TweenVector2D(tweenManager, duration, targetLocalScale, x => transform2D.LocalScale = x); public static ITween TweenLocalRotation(this ITransform2D transform2D, ITweenManager tweenManager, float duration, float targetLocalRotation) - { - float initialLocalRotation = transform2D.LocalRotation; - return tweenManager.StartTween(duration, t => transform2D.LocalRotation = initialLocalRotation.Lerp(targetLocalRotation, t)); - } + => transform2D.LocalRotation.TweenFloat(tweenManager, duration, targetLocalRotation, x => transform2D.LocalRotation = x); + public static ITween TweenPositionAdditive(this ITransform2D transform2D, ITweenManager tweenManager, float duration, Vector2D additivePosition) { Vector2D progressedPosition = Vector2D.Zero; diff --git a/Engine.Systems/Tween/EngineExtensions/TweenTriangleExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenTriangleExtensions.cs index 236b46e..c1dfd1e 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenTriangleExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenTriangleExtensions.cs @@ -1,18 +1,31 @@ -using System; using Engine.Core; namespace Engine.Systems.Tween; public static class TweenTriangleExtensions { - public static ITween TweenTriangle(this Triangle initialTriangle, ITweenManager tweenManager, float duration, Triangle targetTriangle, Action setMethod) - => tweenManager.StartTween(duration, - t => setMethod?.Invoke( + private static readonly BoxedPool boxedTrianglePool = new(2); + + public static ITween TweenTriangle(this Triangle initialTriangle, ITweenManager tweenManager, float duration, Triangle targetTriangle, System.Action setMethod) + { + Boxed boxedInitial = boxedTrianglePool.Get(initialTriangle); + Boxed boxedTarget = boxedTrianglePool.Get(targetTriangle); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke( new Triangle( - initialTriangle.A.Lerp(targetTriangle.A, t), - initialTriangle.B.Lerp(targetTriangle.B, t), - initialTriangle.C.Lerp(targetTriangle.C, t) + boxedInitial.Value.A.Lerp(boxedTarget.Value.A, t), + boxedInitial.Value.B.Lerp(boxedTarget.Value.B, t), + boxedInitial.Value.C.Lerp(boxedTarget.Value.C, t) ) ) ); + + tween.OnComplete(() => + { + boxedTrianglePool.Return(boxedInitial); + boxedTrianglePool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenVector2DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenVector2DExtensions.cs index 1ef0454..49d620f 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenVector2DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenVector2DExtensions.cs @@ -4,6 +4,21 @@ namespace Engine.Systems.Tween; public static class TweenVector2DExtensions { + private static readonly BoxedPool boxedVector2DPool = new(2); + public static ITween TweenVector2D(this Vector2D initialVector2D, ITweenManager tweenManager, float duration, Vector2D targetVector2D, System.Action setMethod) - => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialVector2D.Lerp(targetVector2D, t))); + { + Boxed boxedInitial = boxedVector2DPool.Get(initialVector2D); + Boxed boxedTarget = boxedVector2DPool.Get(targetVector2D); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke(boxedInitial.Value.Lerp(boxedTarget.Value, t))); + + tween.OnComplete(() => + { + boxedVector2DPool.Return(boxedInitial); + boxedVector2DPool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/EngineExtensions/TweenVector3DExtensions.cs b/Engine.Systems/Tween/EngineExtensions/TweenVector3DExtensions.cs index e4c53fd..3853634 100644 --- a/Engine.Systems/Tween/EngineExtensions/TweenVector3DExtensions.cs +++ b/Engine.Systems/Tween/EngineExtensions/TweenVector3DExtensions.cs @@ -4,6 +4,21 @@ namespace Engine.Systems.Tween; public static class TweenVector3DExtensions { + private static readonly BoxedPool boxedVector3DPool = new(2); + public static ITween TweenVector3D(this Vector3D initialVector3D, ITweenManager tweenManager, float duration, Vector3D targetVector3D, System.Action setMethod) - => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialVector3D.Lerp(targetVector3D, t))); + { + Boxed boxedInitial = boxedVector3DPool.Get(initialVector3D); + Boxed boxedTarget = boxedVector3DPool.Get(targetVector3D); + + ITween tween = tweenManager.StartTween(duration, t => setMethod?.Invoke(boxedInitial.Value.Lerp(boxedTarget.Value, t))); + + tween.OnComplete(() => + { + boxedVector3DPool.Return(boxedInitial); + boxedVector3DPool.Return(boxedTarget); + }); + + return tween; + } } diff --git a/Engine.Systems/Tween/Helpers/Boxed.cs b/Engine.Systems/Tween/Helpers/Boxed.cs new file mode 100644 index 0000000..e02242d --- /dev/null +++ b/Engine.Systems/Tween/Helpers/Boxed.cs @@ -0,0 +1,12 @@ +using Engine.Core; + +namespace Engine.Systems.Tween; + +public class Boxed where T : struct +{ + public Event, BoxedValueChangedArguments> OnValueChanged { get; } = new(); + + public T Value { get; set; } = default; + + public readonly record struct BoxedValueChangedArguments(T PreviousValue, T CurrentValue); +} diff --git a/Engine.Systems/Tween/Helpers/BoxedPool.cs b/Engine.Systems/Tween/Helpers/BoxedPool.cs new file mode 100644 index 0000000..37fd270 --- /dev/null +++ b/Engine.Systems/Tween/Helpers/BoxedPool.cs @@ -0,0 +1,14 @@ +using Engine.Core; + +namespace Engine.Systems.Tween; + +public class BoxedPool(int initialCapacity = 1) : Pool>(() => new(), initialCapacity) where T : struct; +public static class BoxedPoolExtensions +{ + public static Boxed Get(this BoxedPool boxedPool, T value) where T : struct + { + Boxed boxed = boxedPool.Get(); + boxed.Value = value; + return boxed; + } +} -- 2.49.1 From 8e314f3269d8d3b464f57dad1a6eadeb4ac02990 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 19 Aug 2025 21:17:47 +0300 Subject: [PATCH 68/91] feat: networking type hasher added --- Engine.Systems/Network/TypeHasher.cs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Engine.Systems/Network/TypeHasher.cs diff --git a/Engine.Systems/Network/TypeHasher.cs b/Engine.Systems/Network/TypeHasher.cs new file mode 100644 index 0000000..82451d4 --- /dev/null +++ b/Engine.Systems/Network/TypeHasher.cs @@ -0,0 +1,27 @@ +namespace Engine.Systems.Network; + +public static class TypeHasher +{ + private static long _fnv1a = 0; + public static long FNV1a + { + get + { + if (_fnv1a == 0) + unchecked + { + const long fnvPrime = 1099511628211; + _fnv1a = 1469598103934665603; + + string typeName = typeof(T).FullName ?? typeof(T).Name; + foreach (char c in typeName) + { + _fnv1a ^= c; + _fnv1a *= fnvPrime; + } + } + + return _fnv1a; + } + } +} -- 2.49.1 From 6d159330a1a6ce61943fa8335f9c5ebb43565228 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 31 Aug 2025 23:09:02 +0300 Subject: [PATCH 69/91] refactor: moved client and server interfaces into their files --- Engine.Serializers/YamlDotNet | 1 + .../Network/Abstract/INetworkCommunicator.cs | 19 ------------------- .../Abstract/INetworkCommunicatorClient.cs | 8 ++++++++ .../Abstract/INetworkCommunicatorServer.cs | 13 +++++++++++++ 4 files changed, 22 insertions(+), 19 deletions(-) create mode 160000 Engine.Serializers/YamlDotNet create mode 100644 Engine.Systems/Network/Abstract/INetworkCommunicatorClient.cs create mode 100644 Engine.Systems/Network/Abstract/INetworkCommunicatorServer.cs diff --git a/Engine.Serializers/YamlDotNet b/Engine.Serializers/YamlDotNet new file mode 160000 index 0000000..62048d7 --- /dev/null +++ b/Engine.Serializers/YamlDotNet @@ -0,0 +1 @@ +Subproject commit 62048d7abe5b233570d59c7d8043c21a4def2cb6 diff --git a/Engine.Systems/Network/Abstract/INetworkCommunicator.cs b/Engine.Systems/Network/Abstract/INetworkCommunicator.cs index 6ae2cc7..413eae2 100644 --- a/Engine.Systems/Network/Abstract/INetworkCommunicator.cs +++ b/Engine.Systems/Network/Abstract/INetworkCommunicator.cs @@ -16,22 +16,3 @@ public interface INetworkCommunicator INetworkCommunicator SubscribeToPackets(Event.EventHandler callback); INetworkCommunicator UnsubscribeFromPackets(Event.EventHandler callback); } - -public interface INetworkCommunicatorClient : INetworkCommunicator -{ - INetworkCommunicatorClient Connect(string address, int port, string? password = null); - - INetworkCommunicatorClient SendToServer(T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); -} - -public interface INetworkCommunicatorServer : INetworkCommunicator -{ - string Password { get; } - int MaxConnectionCount { get; } - int Port { get; } - - INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null); - - INetworkCommunicatorServer SendToClient(IConnection connection, T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); - INetworkCommunicatorServer SendToAll(T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); -} diff --git a/Engine.Systems/Network/Abstract/INetworkCommunicatorClient.cs b/Engine.Systems/Network/Abstract/INetworkCommunicatorClient.cs new file mode 100644 index 0000000..414287c --- /dev/null +++ b/Engine.Systems/Network/Abstract/INetworkCommunicatorClient.cs @@ -0,0 +1,8 @@ +namespace Engine.Systems.Network; + +public interface INetworkCommunicatorClient : INetworkCommunicator +{ + INetworkCommunicatorClient Connect(string address, int port, string? password = null); + + INetworkCommunicatorClient SendToServer(T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); +} diff --git a/Engine.Systems/Network/Abstract/INetworkCommunicatorServer.cs b/Engine.Systems/Network/Abstract/INetworkCommunicatorServer.cs new file mode 100644 index 0000000..73175d4 --- /dev/null +++ b/Engine.Systems/Network/Abstract/INetworkCommunicatorServer.cs @@ -0,0 +1,13 @@ +namespace Engine.Systems.Network; + +public interface INetworkCommunicatorServer : INetworkCommunicator +{ + string Password { get; } + int MaxConnectionCount { get; } + int Port { get; } + + INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null); + + INetworkCommunicatorServer SendToClient(IConnection connection, T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); + INetworkCommunicatorServer SendToAll(T packet, PacketDelivery packetDelivery = PacketDelivery.ReliableInOrder) where T : class, new(); +} -- 2.49.1 From f47488c6f184b676becd1f2af66991ba947a863f Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 10 Oct 2025 10:59:39 +0300 Subject: [PATCH 70/91] fix: registering/unregistering objects during universe enter/exit causing stack overflows --- Engine.Core/Systems/UniverseEntranceManager.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Engine.Core/Systems/UniverseEntranceManager.cs b/Engine.Core/Systems/UniverseEntranceManager.cs index 0fa28e5..0f32115 100644 --- a/Engine.Core/Systems/UniverseEntranceManager.cs +++ b/Engine.Core/Systems/UniverseEntranceManager.cs @@ -39,8 +39,9 @@ public class UniverseEntranceManager : Behaviour { for (int i = toCallExitUniverses.Count - 1; i >= 0; i--) { - toCallExitUniverses[i].ExitUniverse(Universe); + IExitUniverse exitUniverse = toCallExitUniverses[i]; toCallExitUniverses.RemoveAt(i); + exitUniverse.ExitUniverse(Universe); } } @@ -48,8 +49,9 @@ public class UniverseEntranceManager : Behaviour { for (int i = toCallEnterUniverses.Count - 1; i >= 0; i--) { - toCallEnterUniverses[i].EnterUniverse(Universe); + IEnterUniverse enterUniverse = toCallEnterUniverses[i]; toCallEnterUniverses.RemoveAt(i); + enterUniverse.EnterUniverse(Universe); } } -- 2.49.1 From 651b0614c4f123c463112f3b20873d57467cc240 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 10 Oct 2025 11:43:04 +0300 Subject: [PATCH 71/91] fix: index check on triangle batch flush --- .../Engine.Integration.MonoGame/TriangleBatch.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs b/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs index 1612526..e4201f2 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs @@ -58,6 +58,9 @@ public class TriangleBatch : ITriangleBatch private void Flush() { + if (verticesIndex == 0) + return; + graphicsDevice.RasterizerState = rasterizerState; basicEffect.Projection = _projection; basicEffect.View = _view; -- 2.49.1 From 28ca343b4347797019ac30a8c51df61cfb994915 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 10 Oct 2025 14:21:54 +0300 Subject: [PATCH 72/91] perf: improved pool return method by using a hashset for searching if the returning item is already queued --- Engine.Core/Helpers/Pool.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Engine.Core/Helpers/Pool.cs b/Engine.Core/Helpers/Pool.cs index 980823f..a5cfc9a 100644 --- a/Engine.Core/Helpers/Pool.cs +++ b/Engine.Core/Helpers/Pool.cs @@ -10,22 +10,25 @@ public class Pool : IPool private readonly Func generator = null!; private readonly Queue queue = new(); + private readonly HashSet queuedHashes = []; public T Get() { if (!queue.TryDequeue(out T? result)) result = generator(); + queuedHashes.Remove(result); OnRemoved?.Invoke(this, result); return result; } public void Return(T item) { - if (queue.Contains(item)) + if (queuedHashes.Contains(item)) return; queue.Enqueue(item); + queuedHashes.Add(item); OnReturned?.Invoke(this, item); } -- 2.49.1 From 4c542df401852ca49636a83d6cc2d2c8de484d56 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 10 Oct 2025 14:56:31 +0300 Subject: [PATCH 73/91] perf: implemented fast list with index mapping --- Engine.Core/ActiveBehaviourCollector.cs | 4 +- Engine.Core/BehaviourCollector.cs | 3 +- Engine.Core/BehaviourController.cs | 2 +- Engine.Core/Helpers/FastList.cs | 74 +++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 Engine.Core/Helpers/FastList.cs diff --git a/Engine.Core/ActiveBehaviourCollector.cs b/Engine.Core/ActiveBehaviourCollector.cs index f5fbd06..f6a5fc0 100644 --- a/Engine.Core/ActiveBehaviourCollector.cs +++ b/Engine.Core/ActiveBehaviourCollector.cs @@ -16,8 +16,8 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; - private readonly List monitoringBehaviours = new(32); - protected readonly List activeBehaviours = new(32); + private readonly FastList monitoringBehaviours = new(32); + protected readonly FastList activeBehaviours = new(32); protected readonly Dictionary monitoringActiveToBehaviour = new(32); public IUniverse Universe { get; private set; } = null!; diff --git a/Engine.Core/BehaviourCollector.cs b/Engine.Core/BehaviourCollector.cs index 56617c2..f43ef7b 100644 --- a/Engine.Core/BehaviourCollector.cs +++ b/Engine.Core/BehaviourCollector.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace Engine.Core; @@ -15,7 +14,7 @@ public class BehaviourCollector : IBehaviourCollector where T : class private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; - protected readonly List behaviours = new(32); + protected readonly FastList behaviours = new(32); public IUniverse Universe { get; private set; } = null!; diff --git a/Engine.Core/BehaviourController.cs b/Engine.Core/BehaviourController.cs index 45497aa..00618a8 100644 --- a/Engine.Core/BehaviourController.cs +++ b/Engine.Core/BehaviourController.cs @@ -10,7 +10,7 @@ public class BehaviourController : BaseEntity, IBehaviourController public Event OnBehaviourRemoved { get; } = new(); public Event OnUniverseObjectAssigned { get; } = new(); - private readonly List behaviours = new(Constants.BEHAVIOURS_SIZE_INITIAL); + private readonly FastList behaviours = new(Constants.BEHAVIOURS_SIZE_INITIAL); private IUniverseObject _universeObject = null!; diff --git a/Engine.Core/Helpers/FastList.cs b/Engine.Core/Helpers/FastList.cs new file mode 100644 index 0000000..fa64216 --- /dev/null +++ b/Engine.Core/Helpers/FastList.cs @@ -0,0 +1,74 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Engine.Core; + +public class FastList : IReadOnlyList, IEnumerable where T : notnull +{ + private readonly List items = []; + private readonly Dictionary indexMap = []; + + public int Count => items.Count; + + public T this[int index] => items[index]; + + public void Add(T item) + { + indexMap[item] = items.Count; + items.Add(item); + } + + public void RemoveAt(int i) => Remove(items[i], i); + public bool Remove(T item) + { + if (!indexMap.TryGetValue(item, out int index)) + return false; + + Remove(item, index); + + return true; + } + + private void Remove(T item, int index) + { + int lastIndex = items.Count - 1; + T lastItem = items[lastIndex]; + + items[index] = lastItem; + indexMap[lastItem] = index; + + items.RemoveAt(lastIndex); + indexMap.Remove(item); + } + + public void Insert(int index, T item) + { + items.Insert(index, item); + + for (int i = index; i < items.Count; i++) + indexMap[items[i]] = i; + } + + public void Clear() + { + items.Clear(); + indexMap.Clear(); + } + + public bool Contains(T item) => indexMap.ContainsKey(item); + + public int BinarySearch(T item, IComparer? comparer = null) => items.BinarySearch(item, comparer); + public void Sort(IComparer comparer) + { + items.Sort(comparer); + + for (int i = 0; i < items.Count; i++) + indexMap[items[i]] = i; + } + + public IEnumerator GetEnumerator() => items.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public FastList() { } + public FastList(int count) { items.Capacity = count; } +} -- 2.49.1 From e77772cbc2ffec986beb297a4756d301e5b7a7ef Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 11 Oct 2025 15:08:02 +0300 Subject: [PATCH 74/91] refactor: behaviour collector base added --- Engine.Core/BehaviourCollector.cs | 120 ++----------------------- Engine.Core/BehaviourCollectorBase.cs | 125 ++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 113 deletions(-) create mode 100644 Engine.Core/BehaviourCollectorBase.cs diff --git a/Engine.Core/BehaviourCollector.cs b/Engine.Core/BehaviourCollector.cs index f43ef7b..137088c 100644 --- a/Engine.Core/BehaviourCollector.cs +++ b/Engine.Core/BehaviourCollector.cs @@ -2,122 +2,16 @@ using System; namespace Engine.Core; -public class BehaviourCollector : IBehaviourCollector where T : class +public class BehaviourCollector : BehaviourCollectorBase where T : class { - public Event, IBehaviourCollector.BehaviourCollectedArguments> OnCollected { get; } = new(); - public Event, IBehaviourCollector.BehaviourRemovedArguments> OnRemoved { get; } = new(); - public Event OnUniverseAssigned { get; } = new(); - public Event? OnUnassigned { get; } = new(); - - private readonly Event.EventHandler delegateOnBehaviourAdded = null!; - private readonly Event.EventHandler delegateOnBehaviourRemoved = null!; - private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; - private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; - protected readonly FastList behaviours = new(32); - public IUniverse Universe { get; private set; } = null!; + public override T this[Index index] => behaviours[index]; + public override int Count => behaviours.Count; - private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args) - { - IUniverseObject universeObject = args.UniverseObjectRegistered; + protected override void AddBehaviour(T behaviour) => behaviours.Add(behaviour); + protected override bool RemoveBehaviour(T tBehaviour) => behaviours.Remove(tBehaviour); - universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded); - universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved); - - for (int i = 0; i < universeObject.BehaviourController.Count; i++) - OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); - } - - private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args) - { - IUniverseObject universeObject = args.UniverseObjectUnregistered; - - universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded); - universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved); - - for (int i = 0; i < universeObject.BehaviourController.Count; i++) - OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); - } - - protected virtual void AddBehaviour(T behaviour) => behaviours.Add(behaviour); - protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } - private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args) - { - if (args.BehaviourAdded is not T tBehaviour) - return; - - AddBehaviour(tBehaviour); - OnBehaviourAdd(args.BehaviourAdded); - OnCollected?.Invoke(this, new(tBehaviour)); - } - - protected virtual void OnBehaviourRemove(IBehaviour behaviour) { } - private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args) - { - if (args.BehaviourRemoved is not T tBehaviour) - return; - - if (!behaviours.Remove(tBehaviour)) - return; - - OnBehaviourRemove(args.BehaviourRemoved); - OnRemoved?.Invoke(this, new(tBehaviour)); - } - - protected virtual void OnAssign(IUniverse universe) { } - public bool Assign(IUniverse universe) - { - if (Universe is not null) - return false; - - foreach (IUniverseObject universeObject in universe.UniverseObjects) - OnUniverseObjectRegistered(universe, new(universeObject)); - - universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered); - universe.OnPreUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); - - Universe = universe; - OnAssign(universe); - OnUniverseAssigned?.Invoke(this); - - return true; - } - - public bool Unassign() - { - if (Universe is null) - return false; - - foreach (IUniverseObject universeObject in Universe.UniverseObjects) - OnUniverseObjectUnregistered(Universe, new(universeObject)); - - Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered); - Universe.OnPreUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); - - Universe = null!; - OnUnassigned?.Invoke(this); - return true; - } - - public int Count => behaviours.Count; - public T this[Index index] => behaviours[index]; - - public BehaviourCollector() - { - delegateOnBehaviourAdded = OnBehaviourAdded; - delegateOnBehaviourRemoved = OnBehaviourRemoved; - delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; - delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; - } - - public BehaviourCollector(IUniverse universe) - { - delegateOnBehaviourAdded = OnBehaviourAdded; - delegateOnBehaviourRemoved = OnBehaviourRemoved; - delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; - delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; - - Assign(universe); - } + public BehaviourCollector() { } + public BehaviourCollector(IUniverse universe) : base(universe) { } } diff --git a/Engine.Core/BehaviourCollectorBase.cs b/Engine.Core/BehaviourCollectorBase.cs new file mode 100644 index 0000000..dd2bbc5 --- /dev/null +++ b/Engine.Core/BehaviourCollectorBase.cs @@ -0,0 +1,125 @@ +using System; + +namespace Engine.Core; + +public abstract class BehaviourCollectorBase : IBehaviourCollector where T : class +{ + private readonly Event.EventHandler delegateOnBehaviourAdded = null!; + private readonly Event.EventHandler delegateOnBehaviourRemoved = null!; + private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; + private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; + + public Event, IBehaviourCollector.BehaviourCollectedArguments> OnCollected { get; } = new(); + public Event, IBehaviourCollector.BehaviourRemovedArguments> OnRemoved { get; } = new(); + public Event OnUniverseAssigned { get; } = new(); + public Event? OnUnassigned { get; } = new(); + + public IUniverse Universe { get; private set; } = null!; + + public abstract int Count { get; } + + public abstract T this[Index index] { get; } + + public bool Assign(IUniverse universe) + { + if (Universe is not null) + return false; + + foreach (IUniverseObject universeObject in universe.UniverseObjects) + OnUniverseObjectRegistered(universe, new(universeObject)); + + universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered); + universe.OnPreUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); + + Universe = universe; + OnAssign(universe); + OnUniverseAssigned?.Invoke(this); + + return true; + } + + public bool Unassign() + { + if (Universe is null) + return false; + + foreach (IUniverseObject universeObject in Universe.UniverseObjects) + OnUniverseObjectUnregistered(Universe, new(universeObject)); + + Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered); + Universe.OnPreUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); + + Universe = null!; + OnUnassigned?.Invoke(this); + return true; + } + + protected virtual void OnAssign(IUniverse universe) { } + + protected abstract void AddBehaviour(T behaviour); + protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } + private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args) + { + if (args.BehaviourAdded is not T tBehaviour) + return; + + AddBehaviour(tBehaviour); + OnBehaviourAdd(args.BehaviourAdded); + OnCollected?.Invoke(this, new(tBehaviour)); + } + + protected abstract bool RemoveBehaviour(T tBehaviour); + protected virtual void OnBehaviourRemove(IBehaviour behaviour) { } + private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args) + { + if (args.BehaviourRemoved is not T tBehaviour) + return; + + if (!RemoveBehaviour(tBehaviour)) + return; + + OnBehaviourRemove(args.BehaviourRemoved); + OnRemoved?.Invoke(this, new(tBehaviour)); + } + + + private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args) + { + IUniverseObject universeObject = args.UniverseObjectRegistered; + + universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved); + + for (int i = 0; i < universeObject.BehaviourController.Count; i++) + OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); + } + + private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args) + { + IUniverseObject universeObject = args.UniverseObjectUnregistered; + + universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved); + + for (int i = 0; i < universeObject.BehaviourController.Count; i++) + OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); + } + + public BehaviourCollectorBase() + { + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; + delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; + delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + } + + public BehaviourCollectorBase(IUniverse universe) + { + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; + delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; + delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + + Assign(universe); + } +} -- 2.49.1 From ae9d4f02ef19d6e963b60efd25d2cbcefe0f40e1 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 11 Oct 2025 15:11:35 +0300 Subject: [PATCH 75/91] chore: moved behaviour collectors into subdirectory --- Engine.Core/{ => Collectors}/ActiveBehaviourCollector.cs | 0 Engine.Core/{ => Collectors}/ActiveBehaviourCollectorSorted.cs | 0 Engine.Core/{ => Collectors}/BehaviourCollector.cs | 0 Engine.Core/{ => Collectors}/BehaviourCollectorBase.cs | 1 - Engine.Core/{ => Collectors}/BehaviourCollectorSorted.cs | 0 5 files changed, 1 deletion(-) rename Engine.Core/{ => Collectors}/ActiveBehaviourCollector.cs (100%) rename Engine.Core/{ => Collectors}/ActiveBehaviourCollectorSorted.cs (100%) rename Engine.Core/{ => Collectors}/BehaviourCollector.cs (100%) rename Engine.Core/{ => Collectors}/BehaviourCollectorBase.cs (99%) rename Engine.Core/{ => Collectors}/BehaviourCollectorSorted.cs (100%) diff --git a/Engine.Core/ActiveBehaviourCollector.cs b/Engine.Core/Collectors/ActiveBehaviourCollector.cs similarity index 100% rename from Engine.Core/ActiveBehaviourCollector.cs rename to Engine.Core/Collectors/ActiveBehaviourCollector.cs diff --git a/Engine.Core/ActiveBehaviourCollectorSorted.cs b/Engine.Core/Collectors/ActiveBehaviourCollectorSorted.cs similarity index 100% rename from Engine.Core/ActiveBehaviourCollectorSorted.cs rename to Engine.Core/Collectors/ActiveBehaviourCollectorSorted.cs diff --git a/Engine.Core/BehaviourCollector.cs b/Engine.Core/Collectors/BehaviourCollector.cs similarity index 100% rename from Engine.Core/BehaviourCollector.cs rename to Engine.Core/Collectors/BehaviourCollector.cs diff --git a/Engine.Core/BehaviourCollectorBase.cs b/Engine.Core/Collectors/BehaviourCollectorBase.cs similarity index 99% rename from Engine.Core/BehaviourCollectorBase.cs rename to Engine.Core/Collectors/BehaviourCollectorBase.cs index dd2bbc5..e531466 100644 --- a/Engine.Core/BehaviourCollectorBase.cs +++ b/Engine.Core/Collectors/BehaviourCollectorBase.cs @@ -82,7 +82,6 @@ public abstract class BehaviourCollectorBase : IBehaviourCollector where T OnRemoved?.Invoke(this, new(tBehaviour)); } - private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args) { IUniverseObject universeObject = args.UniverseObjectRegistered; diff --git a/Engine.Core/BehaviourCollectorSorted.cs b/Engine.Core/Collectors/BehaviourCollectorSorted.cs similarity index 100% rename from Engine.Core/BehaviourCollectorSorted.cs rename to Engine.Core/Collectors/BehaviourCollectorSorted.cs -- 2.49.1 From 566c16d09cd551ca7896986c413e170f18dd370d Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 11 Oct 2025 15:36:58 +0300 Subject: [PATCH 76/91] refactor: active behaviour collector base added --- .../Collectors/ActiveBehaviourCollector.cs | 146 +---------------- .../ActiveBehaviourCollectorBase.cs | 147 ++++++++++++++++++ 2 files changed, 154 insertions(+), 139 deletions(-) create mode 100644 Engine.Core/Collectors/ActiveBehaviourCollectorBase.cs diff --git a/Engine.Core/Collectors/ActiveBehaviourCollector.cs b/Engine.Core/Collectors/ActiveBehaviourCollector.cs index f6a5fc0..dfe9a2f 100644 --- a/Engine.Core/Collectors/ActiveBehaviourCollector.cs +++ b/Engine.Core/Collectors/ActiveBehaviourCollector.cs @@ -1,148 +1,16 @@ using System; -using System.Collections.Generic; namespace Engine.Core; -public class ActiveBehaviourCollector : IBehaviourCollector where T : class, IBehaviour +public class ActiveBehaviourCollector : ActiveBehaviourCollectorBase where T : class, IBehaviour { - public Event, IBehaviourCollector.BehaviourCollectedArguments> OnCollected { get; } = new(); - public Event, IBehaviourCollector.BehaviourRemovedArguments> OnRemoved { get; } = new(); - public Event OnUniverseAssigned { get; } = new(); - public Event? OnUnassigned { get; } = new(); - - private readonly Event.EventHandler delegateOnBehaviourAdded = null!; - private readonly Event.EventHandler delegateOnBehaviourRemoved = null!; - private readonly Event.EventHandler delegateOnBehaviourStateChanged = null!; - private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; - private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; - - private readonly FastList monitoringBehaviours = new(32); protected readonly FastList activeBehaviours = new(32); - protected readonly Dictionary monitoringActiveToBehaviour = new(32); + public override T this[Index index] => activeBehaviours[index]; + public override int Count => activeBehaviours.Count; - public IUniverse Universe { get; private set; } = null!; + public ActiveBehaviourCollector() { } + public ActiveBehaviourCollector(IUniverse universe) : base(universe) { } - private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args) - { - IUniverseObject universeObject = args.UniverseObjectRegistered; - - universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded); - universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved); - - for (int i = 0; i < universeObject.BehaviourController.Count; i++) - OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); - } - - private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args) - { - IUniverseObject universeObject = args.UniverseObjectUnregistered; - - universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded); - universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved); - - for (int i = 0; i < universeObject.BehaviourController.Count; i++) - OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); - } - - protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } - private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args) - { - if (args.BehaviourAdded is not T tBehaviour) - return; - - monitoringBehaviours.Add(tBehaviour); - monitoringActiveToBehaviour.Add(tBehaviour, tBehaviour); - tBehaviour.OnActiveChanged.AddListener(delegateOnBehaviourStateChanged); - OnBehaviourStateChanged(tBehaviour, new(!tBehaviour.IsActive)); - } - - protected virtual void AddBehaviour(T behaviour) => activeBehaviours.Add(behaviour); - private void OnBehaviourStateChanged(IActive sender, IActive.ActiveChangedArguments args) - { - T behaviour = monitoringActiveToBehaviour[sender]; - if (sender.IsActive) - { - AddBehaviour(behaviour); - OnBehaviourAdd(behaviour); - OnCollected?.Invoke(this, new(behaviour)); - } - else if (activeBehaviours.Remove(behaviour)) - { - OnBehaviourRemove(behaviour); - OnRemoved?.Invoke(this, new(behaviour)); - } - } - - protected virtual void OnBehaviourRemove(IBehaviour behaviour) { } - private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args) - { - if (args.BehaviourRemoved is not T tBehaviour) - return; - - if (!monitoringBehaviours.Remove(tBehaviour) || !monitoringActiveToBehaviour.Remove(tBehaviour)) - return; - - tBehaviour.OnActiveChanged.RemoveListener(delegateOnBehaviourStateChanged); - if (activeBehaviours.Remove(tBehaviour)) - { - OnBehaviourRemove(tBehaviour); - OnRemoved?.Invoke(this, new(tBehaviour)); - } - } - - public bool Assign(IUniverse universe) - { - if (Universe is not null) - return false; - - foreach (IUniverseObject universeObject in universe.UniverseObjects) - OnUniverseObjectRegistered(universe, new(universeObject)); - - universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered); - universe.OnUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); - - Universe = universe; - OnUniverseAssigned?.Invoke(this); - - return true; - } - - public bool Unassign() - { - if (Universe is null) - return false; - - foreach (IUniverseObject universeObject in Universe.UniverseObjects) - OnUniverseObjectUnregistered(Universe, new(universeObject)); - - Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered); - Universe.OnUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); - - Universe = null!; - OnUnassigned?.Invoke(this); - return true; - } - - public int Count => activeBehaviours.Count; - public T this[Index index] => activeBehaviours[index]; - - public ActiveBehaviourCollector() - { - delegateOnBehaviourAdded = OnBehaviourAdded; - delegateOnBehaviourRemoved = OnBehaviourRemoved; - delegateOnBehaviourStateChanged = OnBehaviourStateChanged; - delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; - delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; - } - - public ActiveBehaviourCollector(IUniverse universe) - { - delegateOnBehaviourAdded = OnBehaviourAdded; - delegateOnBehaviourRemoved = OnBehaviourRemoved; - delegateOnBehaviourStateChanged = OnBehaviourStateChanged; - delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; - delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; - - Assign(universe); - } + protected override void AddBehaviour(T behaviour) => activeBehaviours.Add(behaviour); + protected override bool RemoveBehaviour(T tBehaviour) => activeBehaviours.Remove(tBehaviour); } diff --git a/Engine.Core/Collectors/ActiveBehaviourCollectorBase.cs b/Engine.Core/Collectors/ActiveBehaviourCollectorBase.cs new file mode 100644 index 0000000..f389a61 --- /dev/null +++ b/Engine.Core/Collectors/ActiveBehaviourCollectorBase.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; + +namespace Engine.Core; + +public abstract class ActiveBehaviourCollectorBase : IBehaviourCollector where T : class, IBehaviour +{ + protected readonly Dictionary monitoringActiveToBehaviour = new(32); + protected readonly FastList monitoringBehaviours = new(32); + + private readonly Event.EventHandler delegateOnBehaviourAdded = null!; + private readonly Event.EventHandler delegateOnBehaviourRemoved = null!; + private readonly Event.EventHandler delegateOnBehaviourStateChanged = null!; + private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; + private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; + + public Event, IBehaviourCollector.BehaviourCollectedArguments> OnCollected { get; } = new(); + public Event, IBehaviourCollector.BehaviourRemovedArguments> OnRemoved { get; } = new(); + public Event OnUniverseAssigned { get; } = new(); + public Event? OnUnassigned { get; } = new(); + + public abstract int Count { get; } + + public abstract T this[Index index] { get; } + public IUniverse Universe { get; private set; } = null!; + + public bool Assign(IUniverse universe) + { + if (Universe is not null) + return false; + + foreach (IUniverseObject universeObject in universe.UniverseObjects) + OnUniverseObjectRegistered(universe, new(universeObject)); + + universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered); + universe.OnUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); + + Universe = universe; + OnUniverseAssigned?.Invoke(this); + + return true; + } + + public bool Unassign() + { + if (Universe is null) + return false; + + foreach (IUniverseObject universeObject in Universe.UniverseObjects) + OnUniverseObjectUnregistered(Universe, new(universeObject)); + + Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered); + Universe.OnUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); + + Universe = null!; + OnUnassigned?.Invoke(this); + return true; + } + + protected abstract void AddBehaviour(T behaviour); + protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } + private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args) + { + if (args.BehaviourAdded is not T tBehaviour) + return; + + monitoringBehaviours.Add(tBehaviour); + monitoringActiveToBehaviour.Add(tBehaviour, tBehaviour); + tBehaviour.OnActiveChanged.AddListener(delegateOnBehaviourStateChanged); + OnBehaviourStateChanged(tBehaviour, new(!tBehaviour.IsActive)); + } + + protected abstract bool RemoveBehaviour(T behaviour); + protected virtual void OnBehaviourRemove(IBehaviour behaviour) { } + private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args) + { + if (args.BehaviourRemoved is not T tBehaviour) + return; + + if (!monitoringBehaviours.Remove(tBehaviour) || !monitoringActiveToBehaviour.Remove(tBehaviour)) + return; + + tBehaviour.OnActiveChanged.RemoveListener(delegateOnBehaviourStateChanged); + if (!RemoveBehaviour(tBehaviour)) + return; + + OnBehaviourRemove(tBehaviour); + OnRemoved?.Invoke(this, new(tBehaviour)); + } + private void OnBehaviourStateChanged(IActive sender, IActive.ActiveChangedArguments args) + { + T behaviour = monitoringActiveToBehaviour[sender]; + if (sender.IsActive) + { + AddBehaviour(behaviour); + OnBehaviourAdd(behaviour); + OnCollected?.Invoke(this, new(behaviour)); + } + else if (RemoveBehaviour(behaviour)) + { + OnBehaviourRemove(behaviour); + OnRemoved?.Invoke(this, new(behaviour)); + } + } + + private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args) + { + IUniverseObject universeObject = args.UniverseObjectRegistered; + + universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved); + + for (int i = 0; i < universeObject.BehaviourController.Count; i++) + OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); + } + + private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args) + { + IUniverseObject universeObject = args.UniverseObjectUnregistered; + + universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved); + + for (int i = 0; i < universeObject.BehaviourController.Count; i++) + OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); + } + + public ActiveBehaviourCollectorBase() + { + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; + delegateOnBehaviourStateChanged = OnBehaviourStateChanged; + delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; + delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + } + + public ActiveBehaviourCollectorBase(IUniverse universe) + { + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; + delegateOnBehaviourStateChanged = OnBehaviourStateChanged; + delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; + delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + + Assign(universe); + } +} -- 2.49.1 From e3d4899112716ba476fa66e0dbc78c9f923d5e3e Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 11 Oct 2025 16:00:47 +0300 Subject: [PATCH 77/91] refactor: renamed behaviour collectors from sorted to ordered --- ...orSorted.cs => ActiveBehaviourCollectorOrdered.cs} | 11 +++-------- ...ollectorSorted.cs => BehaviourCollectorOrdered.cs} | 11 +++-------- Engine.Core/Systems/DrawManager.cs | 6 +++--- Engine.Core/Systems/UniverseEntranceManager.cs | 4 ++-- Engine.Core/Systems/UpdateManager.cs | 8 ++++---- .../Behaviours/LoadContentManager.cs | 2 +- .../Behaviours/SpriteBatcher.cs | 2 +- .../Behaviours/TriangleBatcher.cs | 2 +- Engine.Physics2D/PhysicsEngine2D.cs | 8 ++++---- 9 files changed, 22 insertions(+), 32 deletions(-) rename Engine.Core/Collectors/{ActiveBehaviourCollectorSorted.cs => ActiveBehaviourCollectorOrdered.cs} (82%) rename Engine.Core/Collectors/{BehaviourCollectorSorted.cs => BehaviourCollectorOrdered.cs} (83%) diff --git a/Engine.Core/Collectors/ActiveBehaviourCollectorSorted.cs b/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs similarity index 82% rename from Engine.Core/Collectors/ActiveBehaviourCollectorSorted.cs rename to Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs index 7db7945..5c20423 100644 --- a/Engine.Core/Collectors/ActiveBehaviourCollectorSorted.cs +++ b/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace Engine.Core; -public class ActiveBehaviourCollectorSorted : ActiveBehaviourCollector where T : class, IBehaviour +public class ActiveBehaviourCollectorOrdered : ActiveBehaviourCollector where T : class, IBehaviour { private readonly Event.EventHandler delegateOnPriorityChanged = null!; @@ -53,15 +53,10 @@ public class ActiveBehaviourCollectorSorted : ActiveBehaviourCollector whe AddBehaviour(behaviour); } - public ActiveBehaviourCollectorSorted() + public ActiveBehaviourCollectorOrdered() => delegateOnPriorityChanged = OnPriorityChanged; + public ActiveBehaviourCollectorOrdered(IUniverse universe, Comparison sortBy) : base(universe) { delegateOnPriorityChanged = OnPriorityChanged; - } - - public ActiveBehaviourCollectorSorted(IUniverse universe, Comparison sortBy) : base(universe) - { - delegateOnPriorityChanged = OnPriorityChanged; - SortBy = Comparer.Create(sortBy); } } diff --git a/Engine.Core/Collectors/BehaviourCollectorSorted.cs b/Engine.Core/Collectors/BehaviourCollectorOrdered.cs similarity index 83% rename from Engine.Core/Collectors/BehaviourCollectorSorted.cs rename to Engine.Core/Collectors/BehaviourCollectorOrdered.cs index 811bb63..bbf445b 100644 --- a/Engine.Core/Collectors/BehaviourCollectorSorted.cs +++ b/Engine.Core/Collectors/BehaviourCollectorOrdered.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace Engine.Core; -public class BehaviourCollectorSorted : BehaviourCollector where T : class +public class BehaviourCollectorOrdered : BehaviourCollector where T : class { private readonly Event.EventHandler delegateOnPriorityChanged = null!; @@ -53,15 +53,10 @@ public class BehaviourCollectorSorted : BehaviourCollector where T : class AddBehaviour(behaviour); } - public BehaviourCollectorSorted() + public BehaviourCollectorOrdered() => delegateOnPriorityChanged = OnPriorityChanged; + public BehaviourCollectorOrdered(IUniverse universe, Comparison sortBy) : base(universe) { delegateOnPriorityChanged = OnPriorityChanged; - } - - public BehaviourCollectorSorted(IUniverse universe, Comparison sortBy) : base(universe) - { - delegateOnPriorityChanged = OnPriorityChanged; - SortBy = Comparer.Create(sortBy); } } diff --git a/Engine.Core/Systems/DrawManager.cs b/Engine.Core/Systems/DrawManager.cs index b385c68..719147c 100644 --- a/Engine.Core/Systems/DrawManager.cs +++ b/Engine.Core/Systems/DrawManager.cs @@ -7,9 +7,9 @@ public class DrawManager : Behaviour // We use Descending order because draw calls are running from last to first private static Comparer SortByDescendingPriority() => Comparer.Create((x, y) => y.Priority.CompareTo(x.Priority)); - private readonly ActiveBehaviourCollectorSorted preDrawEntities = new() { SortBy = SortByDescendingPriority() }; - private readonly ActiveBehaviourCollectorSorted drawEntities = new() { SortBy = SortByDescendingPriority() }; - private readonly ActiveBehaviourCollectorSorted postDrawEntities = new() { SortBy = SortByDescendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered preDrawEntities = new() { SortBy = SortByDescendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered drawEntities = new() { SortBy = SortByDescendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered postDrawEntities = new() { SortBy = SortByDescendingPriority() }; private void OnPreDraw(IUniverse sender) { diff --git a/Engine.Core/Systems/UniverseEntranceManager.cs b/Engine.Core/Systems/UniverseEntranceManager.cs index 0f32115..a421913 100644 --- a/Engine.Core/Systems/UniverseEntranceManager.cs +++ b/Engine.Core/Systems/UniverseEntranceManager.cs @@ -7,8 +7,8 @@ public class UniverseEntranceManager : Behaviour // We use Ascending order because we are using reverse for loop to call them private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); - private readonly ActiveBehaviourCollectorSorted enterUniverses = new() { SortBy = SortByAscendingPriority() }; - private readonly ActiveBehaviourCollectorSorted exitUniverses = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered enterUniverses = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered exitUniverses = new() { SortBy = SortByAscendingPriority() }; private readonly List toCallEnterUniverses = new(32); private readonly List toCallExitUniverses = new(32); diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index 1ee0257..3712c26 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -8,11 +8,11 @@ public class UpdateManager : Behaviour // We use Ascending order because we are using reverse for loop to call them private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); - private readonly ActiveBehaviourCollectorSorted firstFrameUpdates = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered firstFrameUpdates = new() { SortBy = SortByAscendingPriority() }; private readonly ActiveBehaviourCollector lastFrameUpdates = new(); - private readonly ActiveBehaviourCollectorSorted preUpdateEntities = new() { SortBy = SortByAscendingPriority() }; - private readonly ActiveBehaviourCollectorSorted updateEntities = new() { SortBy = SortByAscendingPriority() }; - private readonly ActiveBehaviourCollectorSorted postUpdateEntities = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered preUpdateEntities = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered updateEntities = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered postUpdateEntities = new() { SortBy = SortByAscendingPriority() }; private readonly List toCallFirstFrameUpdates = new(32); diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs index a8eec5b..4377086 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs @@ -8,7 +8,7 @@ public class LoadContentManager : Behaviour, IFirstFrameUpdate // We use Ascending order because we are using reverse for loop to call them private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); - private readonly ActiveBehaviourCollectorSorted loadContents = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered loadContents = new() { SortBy = SortByAscendingPriority() }; private readonly List toCallLoadContents = new(32); private MonoGameWindowContainer monoGameWindowContainer = null!; diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs index e2e1cd6..73b2a72 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs @@ -11,7 +11,7 @@ public class SpriteBatcher : BehaviourBase, IFirstFrameUpdate, IDraw private ISpriteBatch spriteBatch = null!; private MonoGameCamera2D camera2D = null!; - private readonly ActiveBehaviourCollectorSorted drawableSprites = new() { SortBy = SortByPriority() }; + private readonly ActiveBehaviourCollectorOrdered drawableSprites = new() { SortBy = SortByPriority() }; public void FirstActiveFrame() { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs index 1fafe41..666a2a6 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs @@ -12,7 +12,7 @@ public class TriangleBatcher : BehaviourBase, ITriangleBatch, IFirstFrameUpdate, private TriangleBatch triangleBatch = null!; private MonoGameCamera2D camera2D = null!; - private readonly ActiveBehaviourCollectorSorted drawableShapes = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered drawableShapes = new() { SortBy = SortByAscendingPriority() }; public void FirstActiveFrame() { diff --git a/Engine.Physics2D/PhysicsEngine2D.cs b/Engine.Physics2D/PhysicsEngine2D.cs index 8b75a22..52c91eb 100644 --- a/Engine.Physics2D/PhysicsEngine2D.cs +++ b/Engine.Physics2D/PhysicsEngine2D.cs @@ -18,10 +18,10 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D protected readonly IRaycastResolver2D raycastResolver = null!; private static Comparer SortByPriority() => Comparer.Create((x, y) => y.Priority.CompareTo(x.Priority)); - protected ActiveBehaviourCollectorSorted physicsPreUpdateCollector = new() { SortBy = SortByPriority() }; - protected ActiveBehaviourCollectorSorted physicsUpdateCollector = new() { SortBy = SortByPriority() }; - protected ActiveBehaviourCollectorSorted physicsIterationCollector = new() { SortBy = SortByPriority() }; - protected ActiveBehaviourCollectorSorted physicsPostUpdateCollector = new() { SortBy = SortByPriority() }; + protected ActiveBehaviourCollectorOrdered physicsPreUpdateCollector = new() { SortBy = SortByPriority() }; + protected ActiveBehaviourCollectorOrdered physicsUpdateCollector = new() { SortBy = SortByPriority() }; + protected ActiveBehaviourCollectorOrdered physicsIterationCollector = new() { SortBy = SortByPriority() }; + protected ActiveBehaviourCollectorOrdered physicsPostUpdateCollector = new() { SortBy = SortByPriority() }; protected BehaviourCollector rigidBodyCollector = new(); protected BehaviourCollector colliderCollector = new(); -- 2.49.1 From 9ccf7b754d89349878c3535fd83b97f632943434 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sat, 11 Oct 2025 16:07:26 +0300 Subject: [PATCH 78/91] perf: ordered behaviour collectors now use linked lists for performance --- .../ActiveBehaviourCollectorOrdered.cs | 69 +++++++++++++++---- .../Collectors/BehaviourCollectorOrdered.cs | 68 ++++++++++++++---- 2 files changed, 109 insertions(+), 28 deletions(-) diff --git a/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs b/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs index 5c20423..fbc14e4 100644 --- a/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs +++ b/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs @@ -7,6 +7,9 @@ public class ActiveBehaviourCollectorOrdered : ActiveBehaviourCollector wh { private readonly Event.EventHandler delegateOnPriorityChanged = null!; + private readonly LinkedList behaviours = new(); + private readonly List sortList = []; + private IComparer? _sortBy = null; public IComparer? SortBy { @@ -16,43 +19,81 @@ public class ActiveBehaviourCollectorOrdered : ActiveBehaviourCollector wh _sortBy = value; if (value is not null) - activeBehaviours.Sort(value); + Sort(value); } } + public override int Count => behaviours.Count; + + public override T this[Index index] + { + get + { + int actualIndex = index.IsFromEnd + ? behaviours.Count - index.Value + : index.Value; + + if (actualIndex < 0 || actualIndex >= behaviours.Count) + throw new IndexOutOfRangeException(); + + int currentIndex = 0; + foreach (T item in behaviours) + if (currentIndex++ == actualIndex) + return item; + + throw new IndexOutOfRangeException(); + } + } + + protected override bool RemoveBehaviour(T tBehaviour) => behaviours.Remove(tBehaviour); protected override void AddBehaviour(T behaviour) { if (SortBy is null) { - activeBehaviours.Add(behaviour); + behaviours.AddLast(behaviour); return; } - int insertionIndex = activeBehaviours.BinarySearch(behaviour, SortBy); + LinkedListNode? insertionNode = FindInsertionNodeFor(behaviour, SortBy); - if (insertionIndex < 0) - insertionIndex = ~insertionIndex; - - activeBehaviours.Insert(insertionIndex, behaviour); + if (insertionNode is not null) + behaviours.AddAfter(insertionNode, behaviour); + else + behaviours.AddLast(behaviour); } - protected override void OnBehaviourAdd(IBehaviour behaviour) + private LinkedListNode? FindInsertionNodeFor(T behaviour, IComparer sortBy) { - behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged); + LinkedListNode? node = behaviours.First; + + while (node is not null) + { + int compareValue = sortBy.Compare(node.Value, behaviour); + if (compareValue < 0) + return node.Previous; + node = node.Next; + } + return null; } - protected override void OnBehaviourRemove(IBehaviour behaviour) - { - behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged); - } + protected override void OnBehaviourAdd(IBehaviour behaviour) => behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged); + protected override void OnBehaviourRemove(IBehaviour behaviour) => behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged); private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args) { T behaviour = (T)sender; - activeBehaviours.Remove(behaviour); + behaviours.Remove(behaviour); AddBehaviour(behaviour); } + private void Sort(IComparer comparer) + { + sortList.Sort(comparer); + behaviours.Clear(); + foreach (T item in sortList) + behaviours.AddLast(item); + } + public ActiveBehaviourCollectorOrdered() => delegateOnPriorityChanged = OnPriorityChanged; public ActiveBehaviourCollectorOrdered(IUniverse universe, Comparison sortBy) : base(universe) { diff --git a/Engine.Core/Collectors/BehaviourCollectorOrdered.cs b/Engine.Core/Collectors/BehaviourCollectorOrdered.cs index bbf445b..5558aa2 100644 --- a/Engine.Core/Collectors/BehaviourCollectorOrdered.cs +++ b/Engine.Core/Collectors/BehaviourCollectorOrdered.cs @@ -3,10 +3,13 @@ using System.Collections.Generic; namespace Engine.Core; -public class BehaviourCollectorOrdered : BehaviourCollector where T : class +public class BehaviourCollectorOrdered : BehaviourCollectorBase where T : class { private readonly Event.EventHandler delegateOnPriorityChanged = null!; + private readonly LinkedList behaviours = new(); + private readonly List sortList = []; + private IComparer? _sortBy = null; public IComparer? SortBy { @@ -16,35 +19,64 @@ public class BehaviourCollectorOrdered : BehaviourCollector where T : clas _sortBy = value; if (value is not null) - behaviours.Sort(value); + Sort(value); } } + public override int Count => behaviours.Count; + public override T this[Index index] + { + get + { + int actualIndex = index.IsFromEnd + ? behaviours.Count - index.Value + : index.Value; + + if (actualIndex < 0 || actualIndex >= behaviours.Count) + throw new IndexOutOfRangeException(); + + int currentIndex = 0; + foreach (T item in behaviours) + if (currentIndex++ == actualIndex) + return item; + + throw new IndexOutOfRangeException(); + } + } + + protected override bool RemoveBehaviour(T tBehaviour) => behaviours.Remove(tBehaviour); protected override void AddBehaviour(T behaviour) { if (SortBy is null) { - behaviours.Add(behaviour); + behaviours.AddLast(behaviour); return; } - int insertionIndex = behaviours.BinarySearch(behaviour, SortBy); + LinkedListNode? insertionNode = FindInsertionNodeFor(behaviour, SortBy); - if (insertionIndex < 0) - insertionIndex = ~insertionIndex; - - behaviours.Insert(insertionIndex, behaviour); + if (insertionNode is not null) + behaviours.AddAfter(insertionNode, behaviour); + else + behaviours.AddLast(behaviour); } - protected override void OnBehaviourAdd(IBehaviour behaviour) + private LinkedListNode? FindInsertionNodeFor(T behaviour, IComparer sortBy) { - behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged); + LinkedListNode? node = behaviours.First; + + while (node is not null) + { + int compareValue = sortBy.Compare(node.Value, behaviour); + if (compareValue < 0) + return node.Previous; + node = node.Next; + } + return null; } - protected override void OnBehaviourRemove(IBehaviour behaviour) - { - behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged); - } + protected override void OnBehaviourAdd(IBehaviour behaviour) => behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged); + protected override void OnBehaviourRemove(IBehaviour behaviour) => behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged); private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args) { @@ -53,6 +85,14 @@ public class BehaviourCollectorOrdered : BehaviourCollector where T : clas AddBehaviour(behaviour); } + private void Sort(IComparer comparer) + { + sortList.Sort(comparer); + behaviours.Clear(); + foreach (T item in sortList) + behaviours.AddLast(item); + } + public BehaviourCollectorOrdered() => delegateOnPriorityChanged = OnPriorityChanged; public BehaviourCollectorOrdered(IUniverse universe, Comparison sortBy) : base(universe) { -- 2.49.1 From c7d170fad90799cf5afa3599c0bef08d44053a04 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 13 Oct 2025 09:58:58 +0300 Subject: [PATCH 79/91] perf: significant performance optimizations on ordered behaviour collectors by using a sorted dictionary --- .../ActiveBehaviourCollectorOrdered.cs | 119 +++++++++--------- .../Collectors/BehaviourCollectorOrdered.cs | 118 ++++++++--------- Engine.Core/Systems/DrawManager.cs | 9 +- .../Systems/UniverseEntranceManager.cs | 7 +- Engine.Core/Systems/UpdateManager.cs | 12 +- .../Behaviours/LoadContentManager.cs | 6 +- .../Behaviours/SpriteBatcher.cs | 5 +- .../Behaviours/TriangleBatcher.cs | 6 +- Engine.Physics2D/PhysicsEngine2D.cs | 11 +- 9 files changed, 152 insertions(+), 141 deletions(-) diff --git a/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs b/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs index fbc14e4..502e45c 100644 --- a/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs +++ b/Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs @@ -3,77 +3,61 @@ using System.Collections.Generic; namespace Engine.Core; -public class ActiveBehaviourCollectorOrdered : ActiveBehaviourCollector where T : class, IBehaviour +public class ActiveBehaviourCollectorOrdered : ActiveBehaviourCollector where TItem : class, IBehaviour where TIndex : IComparable { private readonly Event.EventHandler delegateOnPriorityChanged = null!; - private readonly LinkedList behaviours = new(); - private readonly List sortList = []; + private readonly SortedDictionary> behaviours = null!; - private IComparer? _sortBy = null; - public IComparer? SortBy - { - get => _sortBy; - set - { - _sortBy = value; + private readonly Func getIndexFunc = null!; + private readonly IComparer sortBy = null!; - if (value is not null) - Sort(value); - } - } + private int count = 0; + public override int Count => count; - public override int Count => behaviours.Count; - - public override T this[Index index] + public override TItem this[Index index] { get { int actualIndex = index.IsFromEnd - ? behaviours.Count - index.Value + ? count - index.Value : index.Value; - if (actualIndex < 0 || actualIndex >= behaviours.Count) + if (actualIndex < 0 || actualIndex >= count) throw new IndexOutOfRangeException(); - int currentIndex = 0; - foreach (T item in behaviours) - if (currentIndex++ == actualIndex) - return item; - + int leftIndex = actualIndex; + foreach ((TIndex i, FastList list) in behaviours) + { + if (leftIndex < list.Count) + return list[leftIndex]; + leftIndex -= list.Count; + } throw new IndexOutOfRangeException(); } } - protected override bool RemoveBehaviour(T tBehaviour) => behaviours.Remove(tBehaviour); - protected override void AddBehaviour(T behaviour) + protected override bool RemoveBehaviour(TItem tBehaviour) { - if (SortBy is null) - { - behaviours.AddLast(behaviour); - return; - } + TIndex index = getIndexFunc(tBehaviour); + if (!behaviours.TryGetValue(index, out FastList? list)) + throw new Exceptions.NotFoundException($"Index of '{index}' is not found in the collector"); - LinkedListNode? insertionNode = FindInsertionNodeFor(behaviour, SortBy); + if (!list.Remove(tBehaviour)) + return false; - if (insertionNode is not null) - behaviours.AddAfter(insertionNode, behaviour); - else - behaviours.AddLast(behaviour); + count--; + return true; } - private LinkedListNode? FindInsertionNodeFor(T behaviour, IComparer sortBy) + protected override void AddBehaviour(TItem behaviour) { - LinkedListNode? node = behaviours.First; + TIndex key = getIndexFunc(behaviour); + if (!behaviours.TryGetValue(key, out FastList? list)) + behaviours[key] = list = []; - while (node is not null) - { - int compareValue = sortBy.Compare(node.Value, behaviour); - if (compareValue < 0) - return node.Previous; - node = node.Next; - } - return null; + count++; + list.Add(behaviour); } protected override void OnBehaviourAdd(IBehaviour behaviour) => behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged); @@ -81,23 +65,40 @@ public class ActiveBehaviourCollectorOrdered : ActiveBehaviourCollector wh private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args) { - T behaviour = (T)sender; - behaviours.Remove(behaviour); + TItem behaviour = (TItem)sender; + RemoveBehaviour(behaviour); AddBehaviour(behaviour); } - private void Sort(IComparer comparer) - { - sortList.Sort(comparer); - behaviours.Clear(); - foreach (T item in sortList) - behaviours.AddLast(item); - } - - public ActiveBehaviourCollectorOrdered() => delegateOnPriorityChanged = OnPriorityChanged; - public ActiveBehaviourCollectorOrdered(IUniverse universe, Comparison sortBy) : base(universe) + public ActiveBehaviourCollectorOrdered(Func getIndexFunc, Comparison sortBy) { delegateOnPriorityChanged = OnPriorityChanged; - SortBy = Comparer.Create(sortBy); + this.getIndexFunc = getIndexFunc; + this.sortBy = Comparer.Create(sortBy); + behaviours = new(this.sortBy); + } + + public ActiveBehaviourCollectorOrdered(IUniverse universe, Func getIndexFunc, Comparison sortBy) : base(universe) + { + delegateOnPriorityChanged = OnPriorityChanged; + this.getIndexFunc = getIndexFunc; + this.sortBy = Comparer.Create(sortBy); + behaviours = new(this.sortBy); + } + + public ActiveBehaviourCollectorOrdered(Func getIndexFunc, IComparer sortBy) + { + this.getIndexFunc = getIndexFunc; + delegateOnPriorityChanged = OnPriorityChanged; + this.sortBy = sortBy; + behaviours = new(sortBy); + } + + public ActiveBehaviourCollectorOrdered(IUniverse universe, Func getIndexFunc, IComparer sortBy) : base(universe) + { + delegateOnPriorityChanged = OnPriorityChanged; + this.getIndexFunc = getIndexFunc; + this.sortBy = sortBy; + behaviours = new(sortBy); } } diff --git a/Engine.Core/Collectors/BehaviourCollectorOrdered.cs b/Engine.Core/Collectors/BehaviourCollectorOrdered.cs index 5558aa2..6f1077a 100644 --- a/Engine.Core/Collectors/BehaviourCollectorOrdered.cs +++ b/Engine.Core/Collectors/BehaviourCollectorOrdered.cs @@ -3,76 +3,61 @@ using System.Collections.Generic; namespace Engine.Core; -public class BehaviourCollectorOrdered : BehaviourCollectorBase where T : class +public class BehaviourCollectorOrdered : BehaviourCollectorBase where TItem : class where TIndex : IComparable { private readonly Event.EventHandler delegateOnPriorityChanged = null!; - private readonly LinkedList behaviours = new(); - private readonly List sortList = []; + private readonly SortedDictionary> behaviours = null!; - private IComparer? _sortBy = null; - public IComparer? SortBy - { - get => _sortBy; - set - { - _sortBy = value; + private readonly Func getIndexFunc = null!; + private readonly IComparer sortBy = null!; - if (value is not null) - Sort(value); - } - } + private int count = 0; + public override int Count => count; - public override int Count => behaviours.Count; - public override T this[Index index] + public override TItem this[Index index] { get { int actualIndex = index.IsFromEnd - ? behaviours.Count - index.Value + ? count - index.Value : index.Value; - if (actualIndex < 0 || actualIndex >= behaviours.Count) + if (actualIndex < 0 || actualIndex >= count) throw new IndexOutOfRangeException(); - int currentIndex = 0; - foreach (T item in behaviours) - if (currentIndex++ == actualIndex) - return item; - + int leftIndex = actualIndex; + foreach ((TIndex i, FastList list) in behaviours) + { + if (leftIndex < list.Count) + return list[leftIndex]; + leftIndex -= list.Count; + } throw new IndexOutOfRangeException(); } } - protected override bool RemoveBehaviour(T tBehaviour) => behaviours.Remove(tBehaviour); - protected override void AddBehaviour(T behaviour) + protected override bool RemoveBehaviour(TItem tBehaviour) { - if (SortBy is null) - { - behaviours.AddLast(behaviour); - return; - } + TIndex index = getIndexFunc(tBehaviour); + if (!behaviours.TryGetValue(index, out FastList? list)) + throw new Exceptions.NotFoundException($"Index of '{index}' is not found in the collector"); - LinkedListNode? insertionNode = FindInsertionNodeFor(behaviour, SortBy); + if (!list.Remove(tBehaviour)) + return false; - if (insertionNode is not null) - behaviours.AddAfter(insertionNode, behaviour); - else - behaviours.AddLast(behaviour); + count--; + return true; } - private LinkedListNode? FindInsertionNodeFor(T behaviour, IComparer sortBy) + protected override void AddBehaviour(TItem behaviour) { - LinkedListNode? node = behaviours.First; + TIndex key = getIndexFunc(behaviour); + if (!behaviours.TryGetValue(key, out FastList? list)) + behaviours[key] = list = []; - while (node is not null) - { - int compareValue = sortBy.Compare(node.Value, behaviour); - if (compareValue < 0) - return node.Previous; - node = node.Next; - } - return null; + count++; + list.Add(behaviour); } protected override void OnBehaviourAdd(IBehaviour behaviour) => behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged); @@ -80,23 +65,40 @@ public class BehaviourCollectorOrdered : BehaviourCollectorBase where T : private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args) { - T behaviour = (T)sender; - behaviours.Remove(behaviour); + TItem behaviour = (TItem)sender; + RemoveBehaviour(behaviour); AddBehaviour(behaviour); } - private void Sort(IComparer comparer) - { - sortList.Sort(comparer); - behaviours.Clear(); - foreach (T item in sortList) - behaviours.AddLast(item); - } - - public BehaviourCollectorOrdered() => delegateOnPriorityChanged = OnPriorityChanged; - public BehaviourCollectorOrdered(IUniverse universe, Comparison sortBy) : base(universe) + public BehaviourCollectorOrdered(Func getIndexFunc, Comparison sortBy) { delegateOnPriorityChanged = OnPriorityChanged; - SortBy = Comparer.Create(sortBy); + this.getIndexFunc = getIndexFunc; + this.sortBy = Comparer.Create(sortBy); + behaviours = new(this.sortBy); + } + + public BehaviourCollectorOrdered(IUniverse universe, Func getIndexFunc, Comparison sortBy) : base(universe) + { + delegateOnPriorityChanged = OnPriorityChanged; + this.getIndexFunc = getIndexFunc; + this.sortBy = Comparer.Create(sortBy); + behaviours = new(this.sortBy); + } + + public BehaviourCollectorOrdered(Func getIndexFunc, IComparer sortBy) + { + this.getIndexFunc = getIndexFunc; + delegateOnPriorityChanged = OnPriorityChanged; + this.sortBy = sortBy; + behaviours = new(sortBy); + } + + public BehaviourCollectorOrdered(IUniverse universe, Func getIndexFunc, IComparer sortBy) : base(universe) + { + delegateOnPriorityChanged = OnPriorityChanged; + this.getIndexFunc = getIndexFunc; + this.sortBy = sortBy; + behaviours = new(sortBy); } } diff --git a/Engine.Core/Systems/DrawManager.cs b/Engine.Core/Systems/DrawManager.cs index 719147c..13706ae 100644 --- a/Engine.Core/Systems/DrawManager.cs +++ b/Engine.Core/Systems/DrawManager.cs @@ -5,11 +5,12 @@ namespace Engine.Core; public class DrawManager : Behaviour { // We use Descending order because draw calls are running from last to first - private static Comparer SortByDescendingPriority() => Comparer.Create((x, y) => y.Priority.CompareTo(x.Priority)); + private static Comparer SortByDescendingPriority() => Comparer.Create((x, y) => y.CompareTo(x)); + private static System.Func GetPriority() => (b) => b.Priority; - private readonly ActiveBehaviourCollectorOrdered preDrawEntities = new() { SortBy = SortByDescendingPriority() }; - private readonly ActiveBehaviourCollectorOrdered drawEntities = new() { SortBy = SortByDescendingPriority() }; - private readonly ActiveBehaviourCollectorOrdered postDrawEntities = new() { SortBy = SortByDescendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered preDrawEntities = new(GetPriority(), SortByDescendingPriority()); + private readonly ActiveBehaviourCollectorOrdered drawEntities = new(GetPriority(), SortByDescendingPriority()); + private readonly ActiveBehaviourCollectorOrdered postDrawEntities = new(GetPriority(), SortByDescendingPriority()); private void OnPreDraw(IUniverse sender) { diff --git a/Engine.Core/Systems/UniverseEntranceManager.cs b/Engine.Core/Systems/UniverseEntranceManager.cs index a421913..502c6a6 100644 --- a/Engine.Core/Systems/UniverseEntranceManager.cs +++ b/Engine.Core/Systems/UniverseEntranceManager.cs @@ -5,10 +5,11 @@ namespace Engine.Core; public class UniverseEntranceManager : Behaviour { // We use Ascending order because we are using reverse for loop to call them - private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); + private static System.Func GetPriority() => (b) => b.Priority; - private readonly ActiveBehaviourCollectorOrdered enterUniverses = new() { SortBy = SortByAscendingPriority() }; - private readonly ActiveBehaviourCollectorOrdered exitUniverses = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered enterUniverses = new(GetPriority(), SortByAscendingPriority()); + private readonly ActiveBehaviourCollectorOrdered exitUniverses = new(GetPriority(), SortByAscendingPriority()); private readonly List toCallEnterUniverses = new(32); private readonly List toCallExitUniverses = new(32); diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index 3712c26..f44076a 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace Engine.Core; @@ -6,13 +5,14 @@ namespace Engine.Core; public class UpdateManager : Behaviour { // We use Ascending order because we are using reverse for loop to call them - private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); + private static System.Func GetPriority() => (b) => b.Priority; - private readonly ActiveBehaviourCollectorOrdered firstFrameUpdates = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered firstFrameUpdates = new(GetPriority(), SortByAscendingPriority()); private readonly ActiveBehaviourCollector lastFrameUpdates = new(); - private readonly ActiveBehaviourCollectorOrdered preUpdateEntities = new() { SortBy = SortByAscendingPriority() }; - private readonly ActiveBehaviourCollectorOrdered updateEntities = new() { SortBy = SortByAscendingPriority() }; - private readonly ActiveBehaviourCollectorOrdered postUpdateEntities = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered preUpdateEntities = new(GetPriority(), SortByAscendingPriority()); + private readonly ActiveBehaviourCollectorOrdered updateEntities = new(GetPriority(), SortByAscendingPriority()); + private readonly ActiveBehaviourCollectorOrdered postUpdateEntities = new(GetPriority(), SortByAscendingPriority()); private readonly List toCallFirstFrameUpdates = new(32); diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs index 4377086..18fd80c 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; + using Engine.Core; namespace Engine.Integration.MonoGame; @@ -6,9 +7,10 @@ namespace Engine.Integration.MonoGame; public class LoadContentManager : Behaviour, IFirstFrameUpdate { // We use Ascending order because we are using reverse for loop to call them - private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); + private static System.Func GetPriority() => (b) => b.Priority; - private readonly ActiveBehaviourCollectorOrdered loadContents = new() { SortBy = SortByAscendingPriority() }; + private readonly ActiveBehaviourCollectorOrdered loadContents = new(GetPriority(), SortByAscendingPriority()); private readonly List toCallLoadContents = new(32); private MonoGameWindowContainer monoGameWindowContainer = null!; diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs index 73b2a72..9f39e1d 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs @@ -6,12 +6,13 @@ namespace Engine.Integration.MonoGame; public class SpriteBatcher : BehaviourBase, IFirstFrameUpdate, IDraw { - private static Comparer SortByPriority() => Comparer.Create((x, y) => y.Priority.CompareTo(x.Priority)); + private static Comparer SortByPriority() => Comparer.Create((x, y) => y.CompareTo(x)); + private static System.Func GetPriority() => (b) => b.Priority; private ISpriteBatch spriteBatch = null!; private MonoGameCamera2D camera2D = null!; - private readonly ActiveBehaviourCollectorOrdered drawableSprites = new() { SortBy = SortByPriority() }; + private readonly ActiveBehaviourCollectorOrdered drawableSprites = new(GetPriority(), SortByPriority()); public void FirstActiveFrame() { diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs index 666a2a6..40827a3 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs @@ -8,11 +8,13 @@ namespace Engine.Integration.MonoGame; public class TriangleBatcher : BehaviourBase, ITriangleBatch, IFirstFrameUpdate, IDraw { - private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); + private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); + private static System.Func GetPriority() => (b) => b.Priority; private TriangleBatch triangleBatch = null!; private MonoGameCamera2D camera2D = null!; - private readonly ActiveBehaviourCollectorOrdered drawableShapes = new() { SortBy = SortByAscendingPriority() }; + + private readonly ActiveBehaviourCollectorOrdered drawableShapes = new(GetPriority(), SortByAscendingPriority()); public void FirstActiveFrame() { diff --git a/Engine.Physics2D/PhysicsEngine2D.cs b/Engine.Physics2D/PhysicsEngine2D.cs index 52c91eb..d2071c3 100644 --- a/Engine.Physics2D/PhysicsEngine2D.cs +++ b/Engine.Physics2D/PhysicsEngine2D.cs @@ -17,11 +17,12 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D protected readonly ICollisionResolver2D collisionResolver = null!; protected readonly IRaycastResolver2D raycastResolver = null!; - private static Comparer SortByPriority() => Comparer.Create((x, y) => y.Priority.CompareTo(x.Priority)); - protected ActiveBehaviourCollectorOrdered physicsPreUpdateCollector = new() { SortBy = SortByPriority() }; - protected ActiveBehaviourCollectorOrdered physicsUpdateCollector = new() { SortBy = SortByPriority() }; - protected ActiveBehaviourCollectorOrdered physicsIterationCollector = new() { SortBy = SortByPriority() }; - protected ActiveBehaviourCollectorOrdered physicsPostUpdateCollector = new() { SortBy = SortByPriority() }; + private static Comparer SortByPriority() => Comparer.Create((x, y) => y.CompareTo(x)); + private static System.Func GetPriority() => (b) => b.Priority; + protected ActiveBehaviourCollectorOrdered physicsPreUpdateCollector = new(GetPriority(), SortByPriority()); + protected ActiveBehaviourCollectorOrdered physicsUpdateCollector = new(GetPriority(), SortByPriority()); + protected ActiveBehaviourCollectorOrdered physicsIterationCollector = new(GetPriority(), SortByPriority()); + protected ActiveBehaviourCollectorOrdered physicsPostUpdateCollector = new(GetPriority(), SortByPriority()); protected BehaviourCollector rigidBodyCollector = new(); protected BehaviourCollector colliderCollector = new(); -- 2.49.1 From a2e704916e9c4f5cc51071bcd325e0a50b56e2c7 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 13 Oct 2025 12:39:49 +0300 Subject: [PATCH 80/91] feat: fast list now implements IList --- Engine.Core/Helpers/FastList.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Engine.Core/Helpers/FastList.cs b/Engine.Core/Helpers/FastList.cs index fa64216..89b11b3 100644 --- a/Engine.Core/Helpers/FastList.cs +++ b/Engine.Core/Helpers/FastList.cs @@ -3,14 +3,15 @@ using System.Collections.Generic; namespace Engine.Core; -public class FastList : IReadOnlyList, IEnumerable where T : notnull +public class FastList : IList, IReadOnlyList, IEnumerable where T : notnull { private readonly List items = []; private readonly Dictionary indexMap = []; public int Count => items.Count; - public T this[int index] => items[index]; + public bool IsReadOnly { get; set; } = false; + public T this[int index] { get => items[index]; set => items[index] = value; } public void Add(T item) { @@ -66,6 +67,9 @@ public class FastList : IReadOnlyList, IEnumerable where T : notnull indexMap[items[i]] = i; } + public int IndexOf(T item) => items.IndexOf(item); + public void CopyTo(T[] array, int arrayIndex) => items.CopyTo(array, arrayIndex); + public IEnumerator GetEnumerator() => items.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); -- 2.49.1 From 8d31372c24eaea6f6a1241a6fb2733e5d02ac1ad Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 13 Oct 2025 12:40:43 +0300 Subject: [PATCH 81/91] refactor: universe and objects now use fast list --- Engine.Core/Universe.cs | 2 +- Engine.Core/UniverseObject.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index bb00b98..49cc883 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -22,7 +22,7 @@ public class Universe : BaseEntity, IUniverse private readonly Event.EventHandler delegateOnUniverseObjectFinalize = null!; private readonly Event.EventHandler delegateOnUniverseObjectExitedUniverse = null!; - private readonly List _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL); + private readonly FastList _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL); private float _timeScale = 1f; public Universe() diff --git a/Engine.Core/UniverseObject.cs b/Engine.Core/UniverseObject.cs index d70e995..e653f1c 100644 --- a/Engine.Core/UniverseObject.cs +++ b/Engine.Core/UniverseObject.cs @@ -19,7 +19,7 @@ public class UniverseObject : BaseEntity, IUniverseObject private IUniverse _universe = null!; private IBehaviourController _behaviourController = null!; private bool _isActive = false; - private readonly List _children = []; + private readonly FastList _children = []; private IUniverseObject? _parent = null; public IReadOnlyList Children => _children; -- 2.49.1 From 4bec7bce6e96d2821ea9acc5f772bd073408d696 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 14 Oct 2025 11:42:05 +0300 Subject: [PATCH 82/91] fix: fast list readonly mode not throwing exceptions --- Engine.Core/Helpers/FastList.cs | 34 ++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Engine.Core/Helpers/FastList.cs b/Engine.Core/Helpers/FastList.cs index 89b11b3..32c486b 100644 --- a/Engine.Core/Helpers/FastList.cs +++ b/Engine.Core/Helpers/FastList.cs @@ -8,13 +8,25 @@ public class FastList : IList, IReadOnlyList, IEnumerable where T : private readonly List items = []; private readonly Dictionary indexMap = []; - public int Count => items.Count; - public bool IsReadOnly { get; set; } = false; - public T this[int index] { get => items[index]; set => items[index] = value; } + public int Count => items.Count; + public T this[int index] + { + get => items[index]; + set + { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + + items[index] = value; + } + } public void Add(T item) { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + indexMap[item] = items.Count; items.Add(item); } @@ -22,6 +34,9 @@ public class FastList : IList, IReadOnlyList, IEnumerable where T : public void RemoveAt(int i) => Remove(items[i], i); public bool Remove(T item) { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + if (!indexMap.TryGetValue(item, out int index)) return false; @@ -44,6 +59,9 @@ public class FastList : IList, IReadOnlyList, IEnumerable where T : public void Insert(int index, T item) { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + items.Insert(index, item); for (int i = index; i < items.Count; i++) @@ -52,22 +70,28 @@ public class FastList : IList, IReadOnlyList, IEnumerable where T : public void Clear() { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + items.Clear(); indexMap.Clear(); } public bool Contains(T item) => indexMap.ContainsKey(item); - + public int IndexOf(T item) => items.IndexOf(item); public int BinarySearch(T item, IComparer? comparer = null) => items.BinarySearch(item, comparer); + public void Sort(IComparer comparer) { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + items.Sort(comparer); for (int i = 0; i < items.Count; i++) indexMap[items[i]] = i; } - public int IndexOf(T item) => items.IndexOf(item); public void CopyTo(T[] array, int arrayIndex) => items.CopyTo(array, arrayIndex); public IEnumerator GetEnumerator() => items.GetEnumerator(); -- 2.49.1 From 7c62440bba4f0804606676ecea67946e69eae6d6 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 14 Oct 2025 12:06:47 +0300 Subject: [PATCH 83/91] chore: added an experimental ordered fast list class --- Engine.Core/Helpers/FastListOrdered.cs | 172 +++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 Engine.Core/Helpers/FastListOrdered.cs diff --git a/Engine.Core/Helpers/FastListOrdered.cs b/Engine.Core/Helpers/FastListOrdered.cs new file mode 100644 index 0000000..d99c826 --- /dev/null +++ b/Engine.Core/Helpers/FastListOrdered.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Engine.Core; + +/// +/// TODO This is VEERY experimental, and doesn't work well with the indices access. Use with caution +/// +/// +/// +public class FastListOrdered : IList, IReadOnlyList, IEnumerable where TItem : notnull where TIndex : IComparable +{ + private readonly SortedDictionary> items = null!; + + private readonly Func getIndexFunc = null!; + private readonly IComparer sortBy = null!; + + private int count = 0; + public int Count => count; + + public bool IsReadOnly { get; set; } = false; + + public TItem this[int index] + { + get { (TIndex tIndex, int i) = GetAt(index); return items[tIndex][i]; } + set + { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + (TIndex tIndex, int i) = GetAt(index); items[tIndex][i] = value; + } + } + + private (TIndex TIndex, int i) GetAt(Index index) + { + int actualIndex = index.IsFromEnd + ? count - index.Value + : index.Value; + + if (actualIndex < 0 || actualIndex >= count) + throw new IndexOutOfRangeException(); + + int leftIndex = actualIndex; + foreach ((TIndex i, FastList list) in items) + { + if (leftIndex < list.Count) + return (i, leftIndex); + leftIndex -= list.Count; + } + throw new IndexOutOfRangeException(); + } + + public int IndexOf(TItem item) + { + int indexCounter = 0; + foreach ((TIndex index, FastList list) in items) + { + int i = list.IndexOf(item); + if (i != -1) + return indexCounter + i; + indexCounter += list.Count; + } + + return -1; + } + + public void Add(TItem item) + { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + + TIndex key = getIndexFunc(item); + if (!items.TryGetValue(key, out FastList? list)) + items[key] = list = []; + + list.Add(item); + count++; + } + + public void Insert(int index, TItem item) + { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + + TIndex tIndex = getIndexFunc(item); + if (!items.TryGetValue(tIndex, out FastList? list)) + items[tIndex] = list = []; + + list.Insert(index, item); + count++; + } + + public bool Remove(TItem item) + { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + + TIndex index = getIndexFunc(item); + if (!items.TryGetValue(index, out FastList? list)) + throw new Exceptions.NotFoundException($"Index of '{index}' is not found in the collector"); + + if (!list.Remove(item)) + return false; + + count--; + return true; + } + + public void RemoveAt(int index) + { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + + (TIndex tIndex, int i) = GetAt(index); + items[tIndex].RemoveAt(i); + count--; + } + + public void Clear() + { + if (IsReadOnly) + throw new System.Data.ReadOnlyException(); + + foreach ((TIndex index, FastList list) in items) + list.Clear(); + + count = 0; + } + + public bool Contains(TItem item) + { + foreach ((TIndex index, FastList list) in items) + if (list.Contains(item)) + return true; + return false; + } + + public void CopyTo(TItem[] array, int arrayIndex) + { + int indexCounter = 0; + + foreach ((TIndex index, FastList list) in items) + { + list.CopyTo(array, indexCounter); + indexCounter += list.Count; + } + } + + public IEnumerator GetEnumerator() + { + foreach ((TIndex index, FastList list) in items) + foreach (TItem item in list) + yield return item; + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public FastListOrdered(Func getIndexFunc, Comparison sortBy) + { + this.getIndexFunc = getIndexFunc; + this.sortBy = Comparer.Create(sortBy); + items = new(this.sortBy); + } + + public FastListOrdered(Func getIndexFunc, IComparer sortBy) + { + this.getIndexFunc = getIndexFunc; + this.sortBy = sortBy; + items = new(sortBy); + } +} -- 2.49.1 From 25db60e4367b48fb1f351341e568f9ee2e41bbad Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 16 Oct 2025 08:25:02 +0300 Subject: [PATCH 84/91] perf: memory allocations reduced on universe update --- Engine.Core/Universe.cs | 7 ++++--- Engine.Core/UniverseTime.cs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index 49cc883..8e3c28f 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -131,9 +131,10 @@ public class Universe : BaseEntity, IUniverse UnscaledTime = engineTime; Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale))); - OnPreUpdate?.Invoke(this, new(Time)); - OnUpdate?.Invoke(this, new(Time)); - OnPostUpdate?.Invoke(this, new(Time)); + IUniverse.UpdateArguments args = new(Time); + OnPreUpdate?.Invoke(this, args); + OnUpdate?.Invoke(this, args); + OnPostUpdate?.Invoke(this, args); } public void Draw() diff --git a/Engine.Core/UniverseTime.cs b/Engine.Core/UniverseTime.cs index 505fa77..460ed8a 100644 --- a/Engine.Core/UniverseTime.cs +++ b/Engine.Core/UniverseTime.cs @@ -2,7 +2,7 @@ using System; namespace Engine.Core; -public readonly struct UniverseTime(TimeSpan TimeSinceStart, TimeSpan TimeDelta) +public readonly record struct UniverseTime(TimeSpan TimeSinceStart, TimeSpan TimeDelta) { public readonly TimeSpan TimeSinceStart = TimeSinceStart; public readonly TimeSpan DeltaSpan = TimeDelta; -- 2.49.1 From 28bc02258769ec3ae94ffed401ce507255ab0060 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 16 Oct 2025 08:43:40 +0300 Subject: [PATCH 85/91] perf: forgotten memory allocation on triangle batch --- Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs b/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs index e4201f2..fd98064 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/TriangleBatch.cs @@ -21,6 +21,7 @@ public class TriangleBatch : ITriangleBatch this.graphicsDevice = graphicsDevice; basicEffect = new(graphicsDevice); basicEffect.VertexColorEnabled = true; + vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), 1024, BufferUsage.WriteOnly); } public void Draw(Triangle triangle, ColorRGBA colorRGBA) @@ -64,7 +65,6 @@ public class TriangleBatch : ITriangleBatch graphicsDevice.RasterizerState = rasterizerState; basicEffect.Projection = _projection; basicEffect.View = _view; - vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), 1024, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); graphicsDevice.SetVertexBuffer(vertexBuffer); -- 2.49.1 From 69bc6573d1ee62fd0028163335a55e2952543ed0 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 16 Oct 2025 13:59:49 +0300 Subject: [PATCH 86/91] feat: added IEquatable interfaces to primitives --- Engine.Core/Primitives/AABB.cs | 4 +++- Engine.Core/Primitives/Circle.cs | 4 +++- Engine.Core/Primitives/ColorHSV.cs | 5 ++++- Engine.Core/Primitives/ColorHSVA.cs | 5 ++++- Engine.Core/Primitives/ColorRGB.cs | 5 ++++- Engine.Core/Primitives/ColorRGBA.cs | 5 ++++- Engine.Core/Primitives/Line2D.cs | 4 +++- Engine.Core/Primitives/Line2DEquation.cs | 5 ++++- Engine.Core/Primitives/Projection1D.cs | 5 ++++- Engine.Core/Primitives/Quaternion.cs | 5 ++++- Engine.Core/Primitives/Ray2D.cs | 5 ++++- Engine.Core/Primitives/Triangle.cs | 5 ++++- Engine.Core/Primitives/Vector2D.cs | 5 ++++- Engine.Core/Primitives/Vector3D.cs | 5 ++++- 14 files changed, 53 insertions(+), 14 deletions(-) diff --git a/Engine.Core/Primitives/AABB.cs b/Engine.Core/Primitives/AABB.cs index 3789526..15a2767 100644 --- a/Engine.Core/Primitives/AABB.cs +++ b/Engine.Core/Primitives/AABB.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace Engine.Core; @@ -11,7 +12,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified lower and upper boundaries. /// [System.Diagnostics.DebuggerDisplay("LowerBoundary: {LowerBoundary.ToString(), nq}, UpperBoundary: {UpperBoundary.ToString(), nq}")] -public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary) +public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary) : IEquatable { /// /// The lower boundary of the . @@ -82,6 +83,7 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is AABB aabb && this == aabb; + public bool Equals(AABB other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Circle.cs b/Engine.Core/Primitives/Circle.cs index bfd1632..2f516ef 100644 --- a/Engine.Core/Primitives/Circle.cs +++ b/Engine.Core/Primitives/Circle.cs @@ -1,3 +1,4 @@ +using System; using System.Diagnostics; namespace Engine.Core; @@ -11,7 +12,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified center and radius. /// [DebuggerDisplay("Center: {Center.ToString(),nq}, Radius: {Radius}")] -public readonly struct Circle(Vector2D center, float radius) +public readonly struct Circle(Vector2D center, float radius) : IEquatable { /// /// The center of the circle. @@ -87,6 +88,7 @@ public readonly struct Circle(Vector2D center, float radius) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Circle circle && this == circle; + public bool Equals(Circle other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs index 8cc7b42..9090694 100644 --- a/Engine.Core/Primitives/ColorHSV.cs +++ b/Engine.Core/Primitives/ColorHSV.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -10,7 +12,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified values. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public readonly struct ColorHSV(float hue, float saturation, float value) +public readonly struct ColorHSV(float hue, float saturation, float value) : IEquatable { /// /// The Hue value of the . @@ -112,6 +114,7 @@ public readonly struct ColorHSV(float hue, float saturation, float value) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is ColorHSV colorHSV && this == colorHSV; + public bool Equals(ColorHSV other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/ColorHSVA.cs b/Engine.Core/Primitives/ColorHSVA.cs index 3f073c8..cb3ffa9 100644 --- a/Engine.Core/Primitives/ColorHSVA.cs +++ b/Engine.Core/Primitives/ColorHSVA.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -11,7 +13,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified values. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public readonly struct ColorHSVA(float hue, float saturation, float value, float alpha = 1) +public readonly struct ColorHSVA(float hue, float saturation, float value, float alpha = 1) : IEquatable { /// /// The Hue value of the . @@ -150,6 +152,7 @@ public readonly struct ColorHSVA(float hue, float saturation, float value, float /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is ColorHSVA colorHSVA && this == colorHSVA; + public bool Equals(ColorHSVA other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/ColorRGB.cs b/Engine.Core/Primitives/ColorRGB.cs index e7628cf..1fada67 100644 --- a/Engine.Core/Primitives/ColorRGB.cs +++ b/Engine.Core/Primitives/ColorRGB.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -10,7 +12,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified values. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public readonly struct ColorRGB(byte r, byte g, byte b) +public readonly struct ColorRGB(byte r, byte g, byte b) : IEquatable { /// /// The Red value of the . @@ -102,6 +104,7 @@ public readonly struct ColorRGB(byte r, byte g, byte b) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is ColorRGB colorRGB && this == colorRGB; + public bool Equals(ColorRGB other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/ColorRGBA.cs b/Engine.Core/Primitives/ColorRGBA.cs index 3dcfe10..8163840 100644 --- a/Engine.Core/Primitives/ColorRGBA.cs +++ b/Engine.Core/Primitives/ColorRGBA.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -11,7 +13,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified values. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) +public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) : IEquatable { /// /// The Red value of the . @@ -132,6 +134,7 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is ColorRGBA colorRGBA && this == colorRGBA; + public bool Equals(ColorRGBA other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Line2D.cs b/Engine.Core/Primitives/Line2D.cs index 171fa7c..753027b 100644 --- a/Engine.Core/Primitives/Line2D.cs +++ b/Engine.Core/Primitives/Line2D.cs @@ -1,3 +1,4 @@ +using System; using System.Diagnostics.CodeAnalysis; namespace Engine.Core; @@ -11,7 +12,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified endpoints. /// [System.Diagnostics.DebuggerDisplay("From: {From.ToString(),nq}, To: {To.ToString(),nq}, Direction: {Direction.ToString(),nq}, Length: {Length}")] -public readonly struct Line2D(Vector2D from, Vector2D to) +public readonly struct Line2D(Vector2D from, Vector2D to) : IEquatable { /// /// The starting point of the segment. @@ -196,6 +197,7 @@ public readonly struct Line2D(Vector2D from, Vector2D to) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Line2D line2D && this == line2D; + public bool Equals(Line2D other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Line2DEquation.cs b/Engine.Core/Primitives/Line2DEquation.cs index a6544d2..fc06e2a 100644 --- a/Engine.Core/Primitives/Line2DEquation.cs +++ b/Engine.Core/Primitives/Line2DEquation.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -9,7 +11,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified slope and Y intercept. /// [System.Diagnostics.DebuggerDisplay("y = {Slope}x + {OffsetY}")] -public readonly struct Line2DEquation(float slope, float offsetY) +public readonly struct Line2DEquation(float slope, float offsetY) : IEquatable { /// /// The slope of the . @@ -48,6 +50,7 @@ public readonly struct Line2DEquation(float slope, float offsetY) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Line2DEquation lineEquation && this == lineEquation; + public bool Equals(Line2DEquation other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Projection1D.cs b/Engine.Core/Primitives/Projection1D.cs index 2408228..e57eb33 100644 --- a/Engine.Core/Primitives/Projection1D.cs +++ b/Engine.Core/Primitives/Projection1D.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -9,7 +11,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified minimum and maximum values. /// [System.Diagnostics.DebuggerDisplay("Min: {Min}, Max: {Max}")] -public readonly struct Projection1D(float min, float max) +public readonly struct Projection1D(float min, float max) : IEquatable { /// /// Gets the minimum value of the projection. @@ -90,6 +92,7 @@ public readonly struct Projection1D(float min, float max) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Projection1D projection1D && this == projection1D; + public bool Equals(Projection1D other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Quaternion.cs b/Engine.Core/Primitives/Quaternion.cs index 68df8dc..0a4b957 100644 --- a/Engine.Core/Primitives/Quaternion.cs +++ b/Engine.Core/Primitives/Quaternion.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -11,7 +13,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified positions. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")] -public readonly struct Quaternion(float x, float y, float z, float w) +public readonly struct Quaternion(float x, float y, float z, float w) : IEquatable { /// /// The X(i) imaginary of the . @@ -288,6 +290,7 @@ public readonly struct Quaternion(float x, float y, float z, float w) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Quaternion quaternion && this == quaternion; + public bool Equals(Quaternion other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Ray2D.cs b/Engine.Core/Primitives/Ray2D.cs index ddc68c8..29884b7 100644 --- a/Engine.Core/Primitives/Ray2D.cs +++ b/Engine.Core/Primitives/Ray2D.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -5,7 +7,7 @@ namespace Engine.Core; /// /// The in 2D space where the ray starts from. /// Normalized indicating the ray's is direction. -public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) +public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) : IEquatable { /// /// The starting point of the . @@ -72,6 +74,7 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Ray2D ray2D && this == ray2D; + public bool Equals(Ray2D other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Triangle.cs b/Engine.Core/Primitives/Triangle.cs index d959a63..96477cb 100644 --- a/Engine.Core/Primitives/Triangle.cs +++ b/Engine.Core/Primitives/Triangle.cs @@ -1,7 +1,9 @@ +using System; + namespace Engine.Core; [System.Diagnostics.DebuggerDisplay("A: {A.ToString(), nq}, B: {B.ToString(), nq}, B: {C.ToString(), nq}")] -public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C) +public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C) : IEquatable { public readonly Vector2D A { get; init; } = A; public readonly Vector2D B { get; init; } = B; @@ -54,6 +56,7 @@ public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Triangle triangle && this == triangle; + public bool Equals(Triangle other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Vector2D.cs b/Engine.Core/Primitives/Vector2D.cs index 624b9ca..751e1c1 100644 --- a/Engine.Core/Primitives/Vector2D.cs +++ b/Engine.Core/Primitives/Vector2D.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -9,7 +11,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified positions. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")] -public readonly struct Vector2D(float x, float y) +public readonly struct Vector2D(float x, float y) : IEquatable { /// /// The X coordinate of the . @@ -308,6 +310,7 @@ public readonly struct Vector2D(float x, float y) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Vector2D vector2D && this == vector2D; + public bool Equals(Vector2D other) => this == other; /// /// Generates a hash code for the . diff --git a/Engine.Core/Primitives/Vector3D.cs b/Engine.Core/Primitives/Vector3D.cs index dedbb37..b7d8c3f 100644 --- a/Engine.Core/Primitives/Vector3D.cs +++ b/Engine.Core/Primitives/Vector3D.cs @@ -1,3 +1,5 @@ +using System; + namespace Engine.Core; /// @@ -10,7 +12,7 @@ namespace Engine.Core; /// Initializes a new instance of the struct with the specified positions. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")] -public readonly struct Vector3D(float x, float y, float z) +public readonly struct Vector3D(float x, float y, float z) : IEquatable { /// /// The X coordinate of the . @@ -277,6 +279,7 @@ public readonly struct Vector3D(float x, float y, float z) /// The object to compare with the current . /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Vector3D vector3D && this == vector3D; + public bool Equals(Vector3D other) => this == other; /// /// Generates a hash code for the . -- 2.49.1 From 92a5c276a4a3fc4a7b21fd1999e459e9b5017d05 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 16 Oct 2025 14:12:24 +0300 Subject: [PATCH 87/91] feat: integer vector 2d & 3d added --- Engine.Core/Primitives/Vector2DInt.cs | 305 +++++++++++++++++++++++++ Engine.Core/Primitives/Vector3DInt.cs | 313 ++++++++++++++++++++++++++ 2 files changed, 618 insertions(+) create mode 100644 Engine.Core/Primitives/Vector2DInt.cs create mode 100644 Engine.Core/Primitives/Vector3DInt.cs diff --git a/Engine.Core/Primitives/Vector2DInt.cs b/Engine.Core/Primitives/Vector2DInt.cs new file mode 100644 index 0000000..b060953 --- /dev/null +++ b/Engine.Core/Primitives/Vector2DInt.cs @@ -0,0 +1,305 @@ +using System; + +namespace Engine.Core; + +/// +/// Represents a two-dimensional integer vector. +/// +/// X position of the . +/// Y position of the . +/// +/// Initializes a new instance of the struct with the specified positions. +/// +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly struct Vector2DInt(int x, int y) : IEquatable +{ + /// + /// The X coordinate of the . + /// + public readonly int X = x; + + /// + /// The Y coordinate of the . + /// + public readonly int Y = y; + + /// + /// The magnitude (length) of the . + /// + public float Magnitude => Length(this); + + /// + /// The squared magnitude (length) of the . + /// + public float MagnitudeSquared => LengthSquared(this); + + /// + /// Gets a with the direction reversed. + /// + public readonly Vector2DInt Reversed => -this; + + /// + /// Represents the unit pointing upwards. + /// + public readonly static Vector2DInt Up = new(0, 1); + + /// + /// Represents the unit pointing downwards. + /// + public readonly static Vector2DInt Down = new(0, -1); + + /// + /// Represents the unit pointing leftwards. + /// + public readonly static Vector2DInt Left = new(-1, 0); + + /// + /// Represents the unit pointing rightwards. + /// + public readonly static Vector2DInt Right = new(1, 0); + + /// + /// Represents the zero . + /// + public readonly static Vector2DInt Zero = new(0, 0); + + /// + /// Represents the with both components equal to 1. + /// + public readonly static Vector2DInt One = new(1, 1); + + public static Vector2DInt operator -(Vector2DInt vector) => new(0 - vector.X, 0 - vector.Y); + public static Vector2DInt operator +(Vector2DInt left, Vector2DInt right) => new(left.X + right.X, left.Y + right.Y); + public static Vector2DInt operator -(Vector2DInt left, Vector2DInt right) => new(left.X - right.X, left.Y - right.Y); + public static Vector2DInt operator *(Vector2DInt vector, int value) => new(vector.X * value, vector.Y * value); + public static Vector2DInt operator *(int value, Vector2DInt vector) => new(vector.X * value, vector.Y * value); + public static Vector2DInt operator /(Vector2DInt vector, int value) => new(vector.X / value, vector.Y / value); + public static bool operator ==(Vector2DInt left, Vector2DInt right) => left.X == right.X && left.Y == right.Y; + public static bool operator !=(Vector2DInt left, Vector2DInt right) => left.X != right.X || left.Y != right.Y; + + public static implicit operator Vector2DInt(Vector3DInt vector) => new(vector.X, vector.Y); + + /// + /// Calculates the length of the . + /// + /// The . + /// The length of the . + public static float Length(Vector2DInt vector) => Engine.Core.Math.Sqrt(LengthSquared(vector)); + + /// + /// Calculates the squared length of the . + /// + /// The . + /// The squared length of the . + public static float LengthSquared(Vector2DInt vector) => vector.X * vector.X + vector.Y * vector.Y; + + /// + /// Calculates the distance between two s. + /// + /// The start . + /// The end . + /// The distance between the two s. + public static float Distance(Vector2DInt from, Vector2DInt to) => Length(FromTo(from, to)); + + /// + /// Inverts the direction of the . + /// + /// The . + /// The inverted . + public static Vector2DInt Invert(Vector2DInt vector) => -vector; + + /// + /// Adds two s. + /// + /// The first . + /// The second . + /// The sum of the two s. + public static Vector2DInt Add(Vector2DInt left, Vector2DInt right) => left + right; + + /// + /// Subtracts one from another. + /// + /// The to subtract from. + /// The to subtract. + /// The result of subtracting the second from the first. + public static Vector2DInt Subtract(Vector2DInt left, Vector2DInt right) => left - right; + + /// + /// Multiplies a by a scalar value. + /// + /// The . + /// The scalar value. + /// The result of multiplying the by the scalar value. + public static Vector2DInt Multiply(Vector2DInt vector, int value) => vector * value; + + /// + /// Divides a by a scalar value. + /// + /// The . + /// The scalar value. + /// The result of dividing the by the scalar value. + public static Vector2DInt Divide(Vector2DInt vector, int value) => vector / value; + + /// + /// Calculates the absolute value of each component of the vector. + /// + /// The . + /// The with each component's absolute value. + public static Vector2DInt Abs(Vector2DInt vector) => new(Engine.Core.Math.Abs(vector.X), Engine.Core.Math.Abs(vector.Y)); + + /// + /// Calculates the from one point to another. + /// + /// The starting point. + /// The ending point. + /// The from the starting point to the ending point. + public static Vector2DInt FromTo(Vector2DInt from, Vector2DInt to) => to - from; + + /// + /// Scales a by another component-wise. + /// + /// The to scale. + /// The containing the scaling factors for each component. + /// The scaled . + public static Vector2DInt Scale(Vector2DInt vector, Vector2DInt scale) => new(vector.X * scale.X, vector.Y * scale.Y); + + /// + /// Calculates a perpendicular to the given . + /// + /// The input . + /// A perpendicular to the input . + public static Vector2DInt Perpendicular(Vector2DInt vector) => new(-vector.Y, vector.X); + + /// + /// Returns the component-wise minimum of two s. + /// + /// The first . + /// The second . + /// The containing the minimum components from both input s. + public static Vector2DInt Min(Vector2DInt left, Vector2DInt right) => new((left.X < right.X) ? left.X : right.X, (left.Y < right.Y) ? left.Y : right.Y); + + /// + /// Returns the component-wise maximum of two s. + /// + /// The first . + /// The second . + /// The containing the maximum components from both input s. + public static Vector2DInt Max(Vector2DInt left, Vector2DInt right) => new((left.X > right.X) ? left.X : right.X, (left.Y > right.Y) ? left.Y : right.Y); + + /// + /// Clamps each component of a between the corresponding component of two other s. + /// + /// The to clamp. + /// The representing the minimum values for each component. + /// The representing the maximum values for each component. + /// A with each component clamped between the corresponding components of the min and max s. + public static Vector2DInt Clamp(Vector2DInt vector, Vector2DInt min, Vector2DInt max) => new(Engine.Core.Math.Clamp(vector.X, min.X, max.X), Engine.Core.Math.Clamp(vector.Y, min.Y, max.Y)); + + /// + /// Performs linear interpolation between two s. + /// + /// The starting (t = 0). + /// The ending (t = 1). + /// The interpolation parameter. + /// The interpolated . + public static Vector2DInt Lerp(Vector2DInt from, Vector2DInt to, int t) => from + FromTo(from, to) * t; + + /// + /// Calculates the cross product of two s. + /// + /// The first . + /// The second . + /// The cross product of the two s. + public static int Cross(Vector2DInt left, Vector2DInt right) => left.X * right.Y - left.Y * right.X; + + /// + /// Calculates the dot product of two s. + /// + /// The first . + /// The second . + /// The dot product of the two s. + public static int Dot(Vector2DInt left, Vector2DInt right) => left.X * right.X + left.Y * right.Y; + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Vector2DInt vector2DInt && this == vector2DInt; + public bool Equals(Vector2DInt other) => this == other; + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(X, Y); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Vector2DInt)}({X}, {Y})"; +} + +/// +/// Provides extension methods for type. +/// +public static class Vector2DIntExtensions +{ + /// + public static float Length(this Vector2DInt vector) => Vector2DInt.Length(vector); + + /// + public static float Distance(this Vector2DInt from, Vector2DInt to) => Vector2DInt.Distance(from, to); + + /// + public static Vector2DInt Add(this Vector2DInt vector, Vector2DInt vectorToAdd) => Vector2DInt.Add(vector, vectorToAdd); + + /// + public static Vector2DInt Subtract(this Vector2DInt vector, Vector2DInt vectorToSubtract) => Vector2DInt.Subtract(vector, vectorToSubtract); + + /// + public static Vector2DInt Multiply(this Vector2DInt vector, int value) => Vector2DInt.Multiply(vector, value); + + /// + public static Vector2DInt Divide(this Vector2DInt vector, int value) => Vector2DInt.Divide(vector, value); + + /// + public static Vector2DInt Abs(this Vector2DInt vector) => Vector2DInt.Abs(vector); + + /// + public static Vector2DInt FromTo(this Vector2DInt from, Vector2DInt to) => Vector2DInt.FromTo(from, to); + + /// + public static Vector2DInt Scale(this Vector2DInt vector, Vector2DInt scale) => Vector2DInt.Scale(vector, scale); + + /// + public static Vector2DInt Perpendicular(this Vector2DInt vector) => Vector2DInt.Perpendicular(vector); + + /// + public static Vector2DInt Min(this Vector2DInt left, Vector2DInt right) => Vector2DInt.Min(left, right); + + /// + public static Vector2DInt Max(this Vector2DInt left, Vector2DInt right) => Vector2DInt.Max(left, right); + + /// + public static Vector2DInt Clamp(this Vector2DInt vector, Vector2DInt min, Vector2DInt max) => Vector2DInt.Clamp(vector, min, max); + + /// + public static Vector2DInt Lerp(this Vector2DInt from, Vector2DInt to, int t) => Vector2DInt.Lerp(from, to, t); + + /// + public static int Cross(this Vector2DInt left, Vector2DInt right) => Vector2DInt.Cross(left, right); + + /// + public static float AngleBetween(this Vector2D left, Vector2D right) => Vector2D.Angle(left, right); + + /// + public static int Dot(this Vector2DInt left, Vector2DInt right) => Vector2DInt.Dot(left, right); +} diff --git a/Engine.Core/Primitives/Vector3DInt.cs b/Engine.Core/Primitives/Vector3DInt.cs new file mode 100644 index 0000000..1dbe037 --- /dev/null +++ b/Engine.Core/Primitives/Vector3DInt.cs @@ -0,0 +1,313 @@ +using System; + +namespace Engine.Core; + +/// +/// Represents a three-dimensional integer vector. +/// +/// X position of the . +/// Y position of the . +/// Z position of the . +/// +/// Initializes a new instance of the struct with the specified positions. +/// +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly struct Vector3DInt(int x, int y, int z) : IEquatable +{ + /// + /// The X coordinate of the . + /// + public readonly int X = x; + + /// + /// The Y coordinate of the . + /// + public readonly int Y = y; + + /// + /// The Z coordinate of the . + /// + public readonly int Z = z; + + /// + /// The magnitude (length) of the . + /// + public float Magnitude => Length(this); + + /// + /// The squared magnitude (length) of the . + /// + public float MagnitudeSquared => LengthSquared(this); + + /// + /// Represents the unit pointing upwards. + /// + public readonly static Vector3DInt Up = new(0, 1, 0); + + /// + /// Represents the unit pointing downwards. + /// + public readonly static Vector3DInt Down = new(0, -1, 0); + + /// + /// Represents the unit pointing leftwards. + /// + public readonly static Vector3DInt Left = new(-1, 0, 0); + + /// + /// Represents the unit pointing rightwards. + /// + public readonly static Vector3DInt Right = new(1, 0, 0); + + /// + /// Represents the unit pointing forwards. + /// + public readonly static Vector3DInt Forward = new(0, 0, 1); + + /// + /// Represents the unit pointing backwards. + public readonly static Vector3DInt Backward = new(0, 0, -1); + + /// + /// Represents the zero . + /// + public readonly static Vector3DInt Zero = new(0, 0, 0); + + /// + /// Represents the with both components equal to 1. + /// + public readonly static Vector3DInt One = new(1, 1, 1); + + public static Vector3DInt operator -(Vector3DInt vector) => new(0 - vector.X, 0 - vector.Y, 0 - vector.Z); + public static Vector3DInt operator +(Vector3DInt left, Vector3DInt right) => new(left.X + right.X, left.Y + right.Y, left.Z + right.Z); + public static Vector3DInt operator -(Vector3DInt left, Vector3DInt right) => new(left.X - right.X, left.Y - right.Y, left.Z - right.Z); + public static Vector3DInt operator *(Vector3DInt vector, int value) => new(vector.X * value, vector.Y * value, vector.Z * value); + public static Vector3DInt operator *(int value, Vector3DInt vector) => new(vector.X * value, vector.Y * value, vector.Z * value); + public static Vector3DInt operator /(Vector3DInt vector, int value) => new(vector.X / value, vector.Y / value, vector.Z / value); + public static bool operator ==(Vector3DInt left, Vector3DInt right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z; + public static bool operator !=(Vector3DInt left, Vector3DInt right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z; + + public static implicit operator Vector3DInt(Vector2DInt vector) => new(vector.X, vector.Y, 0); + + /// + /// Calculates the length of the . + /// + /// The . + /// The length of the . + public static float Length(Vector3DInt vector) => Math.Sqrt(LengthSquared(vector)); + + /// + /// Calculates the squared length of the . + /// + /// The . + /// The squared length of the . + public static float LengthSquared(Vector3DInt vector) => vector.X * vector.X + vector.Y * vector.Y + vector.Z * vector.Z; + + /// + /// Calculates the distance between two s. + /// + /// The start . + /// The end . + /// The distance between the two s. + public static float Distance(Vector3DInt from, Vector3DInt to) => Length(FromTo(from, to)); + + /// + /// Inverts the direction of the . + /// + /// The . + /// The inverted . + public static Vector3DInt Invert(Vector3DInt vector) => -vector; + + /// + /// Adds two s. + /// + /// The first . + /// The second . + /// The sum of the two s. + public static Vector3DInt Add(Vector3DInt left, Vector3DInt right) => left + right; + + /// + /// Subtracts one from another. + /// + /// The to subtract from. + /// The to subtract. + /// The result of subtracting the second from the first. + public static Vector3DInt Subtract(Vector3DInt left, Vector3DInt right) => left - right; + + /// + /// Multiplies a by a scalar value. + /// + /// The . + /// The scalar value. + /// The result of multiplying the by the scalar value. + public static Vector3DInt Multiply(Vector3DInt vector, int value) => vector * value; + + /// + /// Divides a by a scalar value. + /// + /// The . + /// The scalar value. + /// The result of dividing the by the scalar value. + public static Vector3DInt Divide(Vector3DInt vector, int value) => vector / value; + + /// + /// Calculates the absolute value of each component of the vector. + /// + /// The . + /// The with each component's absolute value. + public static Vector3DInt Abs(Vector3DInt vector) => new(Math.Abs(vector.X), Math.Abs(vector.Y), Math.Abs(vector.Z)); + + /// + /// Calculates the from one point to another. + /// + /// The starting point. + /// The ending point. + /// The from the starting point to the ending point. + public static Vector3DInt FromTo(Vector3DInt from, Vector3DInt to) => to - from; + + /// + /// Scales a by another component-wise. + /// + /// The to scale. + /// The containing the scaling factors for each component. + /// The scaled . + public static Vector3DInt Scale(Vector3DInt vector, Vector3DInt scale) => new(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z); + + /// + /// Returns the component-wise minimum of two s. + /// + /// The first . + /// The second . + /// The containing the minimum components from both input s. + public static Vector3DInt Min(Vector3DInt left, Vector3DInt right) => new((left.X < right.X) ? left.X : right.X, (left.Y < right.Y) ? left.Y : right.Y, (left.Z < right.Z) ? left.Z : right.Z); + + /// + /// Returns the component-wise maximum of two s. + /// + /// The first . + /// The second . + /// The containing the maximum components from both input s. + public static Vector3DInt Max(Vector3DInt left, Vector3DInt right) => new((left.X > right.X) ? left.X : right.X, (left.Y > right.Y) ? left.Y : right.Y, (left.Z > right.Z) ? left.Z : right.Z); + + /// + /// Clamps each component of a between the corresponding component of two other s. + /// + /// The to clamp. + /// The representing the minimum values for each component. + /// The representing the maximum values for each component. + /// A with each component clamped between the corresponding components of the min and max s. + public static Vector3DInt Clamp(Vector3DInt vector, Vector3DInt min, Vector3DInt max) => new(Math.Clamp(vector.X, min.X, max.X), Math.Clamp(vector.Y, min.Y, max.Y), Math.Clamp(vector.Z, min.Z, max.Z)); + + /// + /// Performs linear interpolation between two s. + /// + /// The starting (t = 0). + /// The ending (t = 1). + /// The interpolation parameter. + /// The interpolated . + public static Vector3DInt Lerp(Vector3DInt from, Vector3DInt to, int t) => from + FromTo(from, to) * t; + + /// + /// Calculates the cross product of two s. + /// + /// The first . + /// The second . + /// The cross product of the two s. + public static Vector3DInt Cross(Vector3DInt left, Vector3DInt right) => new(left.Y * right.Z - left.Z * right.Y, left.Z * right.X - left.X * right.Z, left.X * right.Y - left.Y * right.X); + + /// + /// Calculates the angle between two s. + /// + /// The first . + /// The second . + /// The angle between the two s in radians. + public static float Angle(Vector3DInt left, Vector3DInt right) => Math.Acos(Dot(left, right) / (Length(left) * Length(right))); + + /// + /// Calculates the dot product of two s. + /// + /// The first . + /// The second . + /// The dot product of the two s. + public static int Dot(Vector3DInt left, Vector3DInt right) => left.X * right.X + left.Y * right.Y + left.Z * right.Z; + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . + public override bool Equals(object? obj) => obj is Vector3DInt vector3D && this == vector3D; + public bool Equals(Vector3DInt other) => this == other; + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . + public override int GetHashCode() => System.HashCode.Combine(X, Y, Z); + + /// + /// Converts the to its string representation. + /// + /// A string representation of the . + public override string ToString() => $"{nameof(Vector3DInt)}({X}, {Y}, {Z})"; +} + +/// +/// Provides extension methods for type. +/// +public static class Vector3DIntExtensions +{ + /// + public static float Length(this Vector3DInt vector) => Vector3DInt.Length(vector); + + /// + public static float LengthSquared(this Vector3DInt vector) => Vector3DInt.LengthSquared(vector); + + /// + public static float Distance(this Vector3DInt from, Vector3DInt to) => Vector3DInt.Distance(from, to); + + /// + public static Vector3DInt Invert(this Vector3DInt vector) => Vector3DInt.Invert(vector); + + /// + public static Vector3DInt Add(this Vector3DInt vector, Vector3DInt vectorToAdd) => Vector3DInt.Add(vector, vectorToAdd); + + /// + public static Vector3DInt Subtract(this Vector3DInt vector, Vector3DInt vectorToSubtract) => Vector3DInt.Subtract(vector, vectorToSubtract); + + /// + public static Vector3DInt Multiply(this Vector3DInt vector, int value) => Vector3DInt.Multiply(vector, value); + + /// + public static Vector3DInt Divide(this Vector3DInt vector, int value) => Vector3DInt.Divide(vector, value); + + /// + public static Vector3DInt Abs(this Vector3DInt vector) => Vector3DInt.Abs(vector); + + /// + public static Vector3DInt FromTo(this Vector3DInt from, Vector3DInt to) => Vector3DInt.FromTo(from, to); + + /// + public static Vector3DInt Scale(this Vector3DInt vector, Vector3DInt scale) => Vector3DInt.Scale(vector, scale); + + /// + public static Vector3DInt Min(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Min(left, right); + + /// + public static Vector3DInt Max(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Max(left, right); + + /// + public static Vector3DInt Clamp(this Vector3DInt vector, Vector3DInt min, Vector3DInt max) => Vector3DInt.Clamp(vector, min, max); + + /// + public static Vector3DInt Lerp(this Vector3DInt from, Vector3DInt to, int t) => Vector3DInt.Lerp(from, to, t); + + /// + public static Vector3DInt Cross(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Cross(left, right); + + /// + public static float AngleBetween(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Angle(left, right); + + /// + public static int Dot(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Dot(left, right); +} -- 2.49.1 From 6f1f30bd53c6b739649077bfef3d47134c502d04 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 16 Oct 2025 14:38:27 +0300 Subject: [PATCH 88/91] feat: intervectoral implicit conversions added --- Engine.Core/Primitives/Vector2D.cs | 1 + Engine.Core/Primitives/Vector2DInt.cs | 1 + Engine.Core/Primitives/Vector3D.cs | 1 + Engine.Core/Primitives/Vector3DInt.cs | 1 + 4 files changed, 4 insertions(+) diff --git a/Engine.Core/Primitives/Vector2D.cs b/Engine.Core/Primitives/Vector2D.cs index 751e1c1..6009875 100644 --- a/Engine.Core/Primitives/Vector2D.cs +++ b/Engine.Core/Primitives/Vector2D.cs @@ -84,6 +84,7 @@ public readonly struct Vector2D(float x, float y) : IEquatable public static implicit operator System.Numerics.Vector2(Vector2D vector) => new(vector.X, vector.Y); public static implicit operator Vector2D(System.Numerics.Vector2 vector) => new(vector.X, vector.Y); + public static implicit operator Vector2D(Vector2DInt vector) => new(vector.X, vector.Y); public static implicit operator Vector2D(Vector3D vector) => new(vector.X, vector.Y); public static implicit operator Vector2D(System.Numerics.Vector3 vector) => new(vector.X, vector.Y); diff --git a/Engine.Core/Primitives/Vector2DInt.cs b/Engine.Core/Primitives/Vector2DInt.cs index b060953..7dd5d4c 100644 --- a/Engine.Core/Primitives/Vector2DInt.cs +++ b/Engine.Core/Primitives/Vector2DInt.cs @@ -77,6 +77,7 @@ public readonly struct Vector2DInt(int x, int y) : IEquatable public static bool operator ==(Vector2DInt left, Vector2DInt right) => left.X == right.X && left.Y == right.Y; public static bool operator !=(Vector2DInt left, Vector2DInt right) => left.X != right.X || left.Y != right.Y; + public static implicit operator Vector2DInt(Vector2D vector) => new((int)vector.X, (int)vector.Y); public static implicit operator Vector2DInt(Vector3DInt vector) => new(vector.X, vector.Y); /// diff --git a/Engine.Core/Primitives/Vector3D.cs b/Engine.Core/Primitives/Vector3D.cs index b7d8c3f..71e6152 100644 --- a/Engine.Core/Primitives/Vector3D.cs +++ b/Engine.Core/Primitives/Vector3D.cs @@ -94,6 +94,7 @@ public readonly struct Vector3D(float x, float y, float z) : IEquatable new(vector.X, vector.Y, vector.Z); public static implicit operator Vector3D(System.Numerics.Vector3 vector) => new(vector.X, vector.Y, vector.Z); + public static implicit operator Vector3D(Vector3DInt vector) => new(vector.X, vector.Y, vector.Z); public static implicit operator Vector3D(Vector2D vector) => new(vector.X, vector.Y, 0f); public static implicit operator Vector3D(System.Numerics.Vector2 vector) => new(vector.X, vector.Y, 0f); diff --git a/Engine.Core/Primitives/Vector3DInt.cs b/Engine.Core/Primitives/Vector3DInt.cs index 1dbe037..319f81a 100644 --- a/Engine.Core/Primitives/Vector3DInt.cs +++ b/Engine.Core/Primitives/Vector3DInt.cs @@ -87,6 +87,7 @@ public readonly struct Vector3DInt(int x, int y, int z) : IEquatable left.X == right.X && left.Y == right.Y && left.Z == right.Z; public static bool operator !=(Vector3DInt left, Vector3DInt right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z; + public static implicit operator Vector3DInt(Vector3D vector) => new((int)vector.X, (int)vector.Y, (int)vector.Z); public static implicit operator Vector3DInt(Vector2DInt vector) => new(vector.X, vector.Y, 0); /// -- 2.49.1 From b75f30f864921bb16f4221f66bb97356eafb9a36 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 16 Oct 2025 15:37:03 +0300 Subject: [PATCH 89/91] fix: math round methods not working properly --- Engine.Core/Math.cs | 28 ++++++++++++++++++++-------- Engine.Core/MathExtensions.cs | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Engine.Core/Math.cs b/Engine.Core/Math.cs index a8f939e..b65cc5e 100644 --- a/Engine.Core/Math.cs +++ b/Engine.Core/Math.cs @@ -240,21 +240,33 @@ public static class Math public static T Lerp(T x, T y, T t) where T : IFloatingPoint => x + (y - x) * t; /// - /// Rounds a number to a specified number of fractional digits. + /// Rounds a number to the closest integer. /// /// The number to round. - /// The number of fractional digits in the return value. - /// Specification for how to round if it is midway between two other numbers. - /// The number rounded to fractional digits. - public static float Round(float x, int digits, MidpointRounding mode) => MathF.Round(x, digits, mode); + /// Specification for how to round if it is midway between two other numbers. + /// The number rounded to the closest integer. + public static float Round(float x, RoundMode roundMode) => RoundToInt(x, roundMode); /// - /// Rounds a number to an integer. + /// Rounds a number to the closest integer. /// /// The number to round. /// Specification for how to round if it's midway between two numbers - /// - public static int RoundToInt(float x, RoundMode roundMode = RoundMode.Ceil) => (int)MathF.Round(x, 0, roundMode == RoundMode.Ceil ? MidpointRounding.ToPositiveInfinity : MidpointRounding.ToNegativeInfinity); + /// The number rounded to the closest integer. + public static int RoundToInt(float x, RoundMode roundMode = RoundMode.Ceil) + { + float remainder = x.Mod(1f); + + if (remainder == .5f) + if (roundMode == RoundMode.Floor) + return (int)x; + else + return (int)(x + .5f); + + if (x < 0f) + return (int)(x - .5f); + return (int)(x + .5f); + } public enum RoundMode { Ceil, Floor }; /// diff --git a/Engine.Core/MathExtensions.cs b/Engine.Core/MathExtensions.cs index 63f2dcb..d1fd4aa 100644 --- a/Engine.Core/MathExtensions.cs +++ b/Engine.Core/MathExtensions.cs @@ -81,7 +81,7 @@ public static class MathExtensions public static T Lerp(this T x, T y, T t) where T : IFloatingPoint => Math.Lerp(x, y, t); /// - public static float Round(this float x, int digits, MidpointRounding mode) => Math.Round(x, digits, mode); + public static float Round(this float x, Math.RoundMode mode) => Math.Round(x, mode); /// public static int RoundToInt(this float x, Math.RoundMode roundMode = Math.RoundMode.Ceil) => Math.RoundToInt(x, roundMode); -- 2.49.1 From f55ba499b6cb52343c351645af969f005084a11e Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 16 Oct 2025 15:37:31 +0300 Subject: [PATCH 90/91] fix: int vectors not rounding float values on regular vector conversions --- Engine.Core/Primitives/Vector2DInt.cs | 2 +- Engine.Core/Primitives/Vector3DInt.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine.Core/Primitives/Vector2DInt.cs b/Engine.Core/Primitives/Vector2DInt.cs index 7dd5d4c..2968723 100644 --- a/Engine.Core/Primitives/Vector2DInt.cs +++ b/Engine.Core/Primitives/Vector2DInt.cs @@ -77,7 +77,7 @@ public readonly struct Vector2DInt(int x, int y) : IEquatable public static bool operator ==(Vector2DInt left, Vector2DInt right) => left.X == right.X && left.Y == right.Y; public static bool operator !=(Vector2DInt left, Vector2DInt right) => left.X != right.X || left.Y != right.Y; - public static implicit operator Vector2DInt(Vector2D vector) => new((int)vector.X, (int)vector.Y); + public static implicit operator Vector2DInt(Vector2D vector) => new(vector.X.RoundToInt(), vector.Y.RoundToInt()); public static implicit operator Vector2DInt(Vector3DInt vector) => new(vector.X, vector.Y); /// diff --git a/Engine.Core/Primitives/Vector3DInt.cs b/Engine.Core/Primitives/Vector3DInt.cs index 319f81a..5e2a427 100644 --- a/Engine.Core/Primitives/Vector3DInt.cs +++ b/Engine.Core/Primitives/Vector3DInt.cs @@ -87,7 +87,7 @@ public readonly struct Vector3DInt(int x, int y, int z) : IEquatable left.X == right.X && left.Y == right.Y && left.Z == right.Z; public static bool operator !=(Vector3DInt left, Vector3DInt right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z; - public static implicit operator Vector3DInt(Vector3D vector) => new((int)vector.X, (int)vector.Y, (int)vector.Z); + public static implicit operator Vector3DInt(Vector3D vector) => new(vector.X.RoundToInt(), vector.Y.RoundToInt(), vector.Z.RoundToInt()); public static implicit operator Vector3DInt(Vector2DInt vector) => new(vector.X, vector.Y, 0); /// -- 2.49.1 From e70b7f112f9acef637a1a0ae2f37ee4fe2bb1bf1 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 17 Oct 2025 21:27:49 +0300 Subject: [PATCH 91/91] chore: coroutine manager moved to correct directory --- Engine.Core/{ => Systems}/CoroutineManager.cs | 0 Engine.Core/{ => Systems}/CoroutineYield.cs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Engine.Core/{ => Systems}/CoroutineManager.cs (100%) rename Engine.Core/{ => Systems}/CoroutineYield.cs (100%) diff --git a/Engine.Core/CoroutineManager.cs b/Engine.Core/Systems/CoroutineManager.cs similarity index 100% rename from Engine.Core/CoroutineManager.cs rename to Engine.Core/Systems/CoroutineManager.cs diff --git a/Engine.Core/CoroutineYield.cs b/Engine.Core/Systems/CoroutineYield.cs similarity index 100% rename from Engine.Core/CoroutineYield.cs rename to Engine.Core/Systems/CoroutineYield.cs -- 2.49.1