Compare commits

..

No commits in common. "development" and "main" have entirely different histories.

269 changed files with 810 additions and 3361 deletions

4
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "Engine.Integration/YamlDotNet"] [submodule "Engine.Serializers/YamlDotNet"]
path = Engine.Integration/YamlDotNet path = Engine.Serializers/YamlDotNet
url = git@github.com:Syntriax/YamlDotNet.git url = git@github.com:Syntriax/YamlDotNet.git

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Indicates the class implementing it has Assignable fields that are necessary for the engine to work properly. /// Indicates the class implementing it has Assignable fields that are necessary for the engine to work properly.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IBehaviourController"/> field. /// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IBehaviourController"/> field.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IEntity"/> field. /// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IEntity"/> field.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IStateEnable"/> field. /// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IStateEnable"/> field.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverse"/> field. /// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverse"/> field.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverseObject"/> field. /// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverseObject"/> field.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents an entity which can be active or not. /// Represents an entity which can be active or not.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a behaviour that any object in the engine that might use to interact with itself or other objects. /// Represents a behaviour that any object in the engine that might use to interact with itself or other objects.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public interface IBehaviour2D : IBehaviour public interface IBehaviour2D : IBehaviour
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a collector for the class type of <typeparamref name="T"/>. /// Represents a collector for the class type of <typeparamref name="T"/>.

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a controller for managing <see cref="IBehaviour"/>s. Connected to an <see cref="IUniverseObject"/>. /// Represents a controller for managing <see cref="IBehaviour"/>s. Connected to an <see cref="IUniverseObject"/>.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a 2D camera in the engine. /// Represents a 2D camera in the engine.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public interface ICoroutineYield public interface ICoroutineYield
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a basic entity in the engine. /// Represents a basic entity in the engine.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// 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. /// 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.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents an entity with a name. /// Represents an entity with a name.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents an entity with an enable state that can be toggled. /// Represents an entity with an enable state that can be toggled.

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents the transformation properties of an object such as position, scale, and rotation in 2D space. /// Represents the transformation properties of an object such as position, scale, and rotation in 2D space.

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a universe responsible for managing <see cref="IUniverseObject"/>s. /// Represents a universe responsible for managing <see cref="IUniverseObject"/>s.
@ -37,21 +37,11 @@ public interface IUniverse : IEntity, IEnumerable<IUniverseObject>
/// </summary> /// </summary>
Event<IUniverse> OnPostDraw { get; } Event<IUniverse> OnPostDraw { get; }
/// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is about to be registered to the <see cref="IUniverse"/>.
/// </summary>
Event<IUniverse, UniverseObjectRegisteredArguments> OnPreUniverseObjectRegistered { get; }
/// <summary> /// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is registered to the <see cref="IUniverse"/>. /// Event triggered when a <see cref="IUniverseObject"/> is registered to the <see cref="IUniverse"/>.
/// </summary> /// </summary>
Event<IUniverse, UniverseObjectRegisteredArguments> OnUniverseObjectRegistered { get; } Event<IUniverse, UniverseObjectRegisteredArguments> OnUniverseObjectRegistered { get; }
/// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is about to be unregistered from the <see cref="IUniverse"/>.
/// </summary>
Event<IUniverse, UniverseObjectUnRegisteredArguments> OnPreUniverseObjectUnRegistered { get; }
/// <summary> /// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is unregistered from the <see cref="IUniverse"/>. /// Event triggered when a <see cref="IUniverseObject"/> is unregistered from the <see cref="IUniverse"/>.
/// </summary> /// </summary>

View File

@ -1,13 +1,13 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents an <see cref="IEntity"/> that can enter and exit a universe within the <see cref="IUniverse"/> system. /// Represents an <see cref="IEntity"/> that can enter and exit a universe within the <see cref="IUniverse"/> system.
/// This interface allows for tracking the object's presence in the universe and provides events /// 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. /// for notifying when the see enters or exits the universe.
/// </summary> /// </summary>
public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourController public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourController, IEnumerable<IUniverseObject>
{ {
/// <summary> /// <summary>
/// Event triggered when the <see cref="IUniverseObject"/> enters the universe. /// Event triggered when the <see cref="IUniverseObject"/> enters the universe.
@ -47,7 +47,7 @@ public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourCon
/// <summary> /// <summary>
/// The parent <see cref="IUniverseObject"/> of the <see cref="IUniverseObject"/>. /// The parent <see cref="IUniverseObject"/> of the <see cref="IUniverseObject"/>.
/// </summary> /// </summary>
IUniverseObject? Parent { get; set; } IUniverseObject? Parent { get; }
/// <summary> /// <summary>
/// The <see cref="IUniverseObject"/>s that have this <see cref="IUniverseObject"/> as their <see cref="Parent"/>. /// The <see cref="IUniverseObject"/>s that have this <see cref="IUniverseObject"/> as their <see cref="Parent"/>.
@ -75,6 +75,12 @@ public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourCon
/// </returns> /// </returns>
internal bool ExitUniverse(); internal bool ExitUniverse();
/// <summary>
/// Sets the parent <see cref="IUniverseObject"/> of this <see cref="IUniverseObject"/>.
/// </summary>
/// <param name="universeObject">The parent <see cref="IUniverseObject"/> to set.</param>
void SetParent(IUniverseObject? universeObject);
/// <summary> /// <summary>
/// Adds a child <see cref="IUniverseObject"/> to this <see cref="IUniverseObject"/>. /// Adds a child <see cref="IUniverseObject"/> to this <see cref="IUniverseObject"/>.
/// </summary> /// </summary>

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : class, IBehaviour public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : class, IBehaviour
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class ActiveBehaviourCollectorSorted<T> : ActiveBehaviourCollector<T> where T : class, IBehaviour public class ActiveBehaviourCollectorSorted<T> : ActiveBehaviourCollector<T> where T : class, IBehaviour
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public abstract class BaseEntity : IEntity public abstract class BaseEntity : IEntity
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public abstract class Behaviour : BehaviourBase public abstract class Behaviour : BehaviourBase
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public abstract class Behaviour2D : Behaviour, IBehaviour2D public abstract class Behaviour2D : Behaviour, IBehaviour2D
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")] [System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")]
public abstract class BehaviourBase : BaseEntity, IBehaviour public abstract class BehaviourBase : BaseEntity, IBehaviour
@ -44,7 +44,6 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
_behaviourController = behaviourController; _behaviourController = behaviourController;
OnAssign(behaviourController); OnAssign(behaviourController);
behaviourController.OnUniverseObjectAssigned.AddListener(delegateOnUniverseObjectAssigned); behaviourController.OnUniverseObjectAssigned.AddListener(delegateOnUniverseObjectAssigned);
behaviourController.StateEnable.OnEnabledChanged.AddListener(delegateOnStateEnabledChanged);
if (behaviourController.UniverseObject is not null) if (behaviourController.UniverseObject is not null)
OnUniverseObjectAssigned(behaviourController); OnUniverseObjectAssigned(behaviourController);
OnBehaviourControllerAssigned?.Invoke(this); OnBehaviourControllerAssigned?.Invoke(this);
@ -69,7 +68,6 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
BehaviourController.UniverseObject.OnActiveChanged.RemoveListener(delegateOnUniverseObjectActiveChanged); BehaviourController.UniverseObject.OnActiveChanged.RemoveListener(delegateOnUniverseObjectActiveChanged);
StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged); StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged);
BehaviourController.OnUniverseObjectAssigned.RemoveListener(delegateOnUniverseObjectAssigned); BehaviourController.OnUniverseObjectAssigned.RemoveListener(delegateOnUniverseObjectAssigned);
BehaviourController.StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged);
base.UnassignInternal(); base.UnassignInternal();
_behaviourController = null!; _behaviourController = null!;
} }
@ -78,8 +76,6 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
{ {
Debug.Assert.AssertBehaviourControllerAssigned(this); Debug.Assert.AssertBehaviourControllerAssigned(this);
Debug.Assert.AssertStateEnableAssigned(this); Debug.Assert.AssertStateEnableAssigned(this);
UpdateActive();
} }
private void OnStateEnabledChanged(IStateEnable sender, IStateEnable.EnabledChangedArguments args) => UpdateActive(); private void OnStateEnabledChanged(IStateEnable sender, IStateEnable.EnabledChangedArguments args) => UpdateActive();
@ -88,7 +84,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
private void UpdateActive() private void UpdateActive()
{ {
bool previousActive = IsActive; bool previousActive = IsActive;
_isActive = StateEnable.Enabled && _behaviourController.StateEnable.Enabled && _behaviourController.UniverseObject.IsActive; _isActive = StateEnable.Enabled && _behaviourController.UniverseObject.IsActive;
if (previousActive != IsActive) if (previousActive != IsActive)
OnActiveChanged?.Invoke(this, new(previousActive)); OnActiveChanged?.Invoke(this, new(previousActive));

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
{ {
@ -76,7 +76,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
OnUniverseObjectRegistered(universe, new(universeObject)); OnUniverseObjectRegistered(universe, new(universeObject));
universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered); universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered);
universe.OnPreUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); universe.OnUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered);
Universe = universe; Universe = universe;
OnAssign(universe); OnAssign(universe);
@ -94,7 +94,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
OnUniverseObjectUnregistered(Universe, new(universeObject)); OnUniverseObjectUnregistered(Universe, new(universeObject));
Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered); Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered);
Universe.OnPreUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); Universe.OnUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered);
Universe = null!; Universe = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.Invoke(this);

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class
{ {

View File

@ -1,7 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Engine.Core; namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")] [System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")]
public class BehaviourController : BaseEntity, IBehaviourController public class BehaviourController : BaseEntity, IBehaviourController
@ -49,13 +50,17 @@ public class BehaviourController : BaseEntity, IBehaviourController
public IReadOnlyList<T> GetBehaviours<T>() public IReadOnlyList<T> GetBehaviours<T>()
{ {
List<T> behaviours = []; List<T>? behaviours = null;
foreach (IBehaviour behaviourItem in this.behaviours) foreach (IBehaviour behaviourItem in this.behaviours)
if (behaviourItem is T behaviour) {
behaviours.Add(behaviour); if (behaviourItem is not T behaviour)
continue;
return behaviours; behaviours ??= [];
behaviours.Add(behaviour);
}
return behaviours ?? Enumerable.Empty<T>().ToList();
} }
public void GetBehaviours<T>(IList<T> results) public void GetBehaviours<T>(IList<T> results)
@ -72,7 +77,7 @@ public class BehaviourController : BaseEntity, IBehaviourController
public void RemoveBehaviour<T>(bool removeAll = false) where T : class, IBehaviour public void RemoveBehaviour<T>(bool removeAll = false) where T : class, IBehaviour
{ {
for (int i = behaviours.Count - 1; i >= 0; i--) for (int i = behaviours.Count; i >= 0; i--)
{ {
if (behaviours[i] is not T behaviour) if (behaviours[i] is not T behaviour)
continue; continue;

View File

@ -1,7 +1,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class CoroutineManager : Behaviour, IUpdate public class CoroutineManager : Behaviour, IUpdate
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class CoroutineYield(Func<bool> condition) : ICoroutineYield public class CoroutineYield(Func<bool> condition) : ICoroutineYield
{ {

View File

@ -1,6 +1,6 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Engine.Core.Debug; namespace Syntriax.Engine.Core.Debug;
public static class Assert public static class Assert
{ {
@ -10,21 +10,21 @@ public static class Assert
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertBehaviourControllerAssigned(IHasBehaviourController assignable) public static void AssertBehaviourControllerAssigned(IHasBehaviourController assignable)
=> System.Diagnostics.Debug.Assert(assignable.BehaviourController is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IBehaviourController)}"); => System.Diagnostics.Debug.Assert(assignable.BehaviourController is not null, $"{assignable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertEntityAssigned(IHasEntity assignable) public static void AssertEntityAssigned(IHasEntity assignable)
=> System.Diagnostics.Debug.Assert(assignable.Entity is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IEntity)}"); => System.Diagnostics.Debug.Assert(assignable.Entity is not null, $"{assignable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertUniverseAssigned(IHasUniverse assignable) public static void AssertUniverseAssigned(IHasUniverse assignable)
=> System.Diagnostics.Debug.Assert(assignable.Universe is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IUniverse)}"); => System.Diagnostics.Debug.Assert(assignable.Universe is not null, $"{assignable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertUniverseObjectAssigned(IHasUniverseObject assignable) public static void AssertUniverseObjectAssigned(IHasUniverseObject assignable)
=> System.Diagnostics.Debug.Assert(assignable.UniverseObject is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IUniverseObject)}"); => System.Diagnostics.Debug.Assert(assignable.UniverseObject is not null, $"{assignable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertStateEnableAssigned(IHasStateEnable assignable) public static void AssertStateEnableAssigned(IHasStateEnable assignable)
=> System.Diagnostics.Debug.Assert(assignable.StateEnable is not null, $"{assignable.GetType().Name} must be assigned an {nameof(IStateEnable)}"); => System.Diagnostics.Debug.Assert(assignable.StateEnable is not null, $"{assignable.GetType().Name} must be initialized");
} }

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Debug; namespace Syntriax.Engine.Core.Debug;
public class ConsoleLogger : LoggerBase public class ConsoleLogger : LoggerBase
{ {

View File

@ -1,32 +1,20 @@
using System; using System;
using System.IO; using System.IO;
namespace Engine.Core.Debug; namespace Syntriax.Engine.Core.Debug;
public class FileLogger : LoggerBase public class FileLogger : LoggerBase
{ {
public readonly string FilePath; public readonly string FilePath;
public FileLogger(string filePath)
{
FilePath = filePath;
File.Open(filePath, FileMode.Create).Close();
}
protected override void Write(string message) protected override void Write(string message)
{ {
File.AppendAllTextAsync(FilePath, $"{message}{Environment.NewLine}"); File.AppendAllTextAsync(FilePath, $"{message}{Environment.NewLine}");
} }
public FileLogger(string filePath)
{
if (!filePath.EndsWith(".log"))
filePath += ".log";
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();
}
} }

View File

@ -1,16 +1,13 @@
namespace Engine.Core.Debug; namespace Syntriax.Engine.Core.Debug;
public interface ILogger public interface ILogger
{ {
static ILogger Shared { get; set; } = new ConsoleLogger();
Level FilterLevel { get; set; } Level FilterLevel { get; set; }
void Log(string message, Level level = Level.Info, bool force = false); void Log(string message, Level level = Level.Info, bool force = false);
enum Level enum Level
{ {
Trace,
Info, Info,
Warning, Warning,
Error, Error,

View File

@ -1,10 +1,10 @@
using System; using System;
namespace Engine.Core.Debug; namespace Syntriax.Engine.Core.Debug;
public abstract class LoggerBase : ILogger public abstract class LoggerBase : ILogger
{ {
public ILogger.Level FilterLevel { get; set; } = ILogger.Level.Trace; public ILogger.Level FilterLevel { get; set; } = ILogger.Level.Info;
public void Log(string message, ILogger.Level level = ILogger.Level.Info, bool force = false) public void Log(string message, ILogger.Level level = ILogger.Level.Info, bool force = false)
{ {

View File

@ -1,9 +0,0 @@
namespace Engine.Core.Debug;
public class LoggerContainer : Behaviour, ILogger
{
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);
}

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
namespace Engine.Core.Debug; namespace Syntriax.Engine.Core.Debug;
public static class LoggerExtensions public static class LoggerExtensions
{ {
@ -16,21 +16,13 @@ public static class LoggerExtensions
public static void LogError<T>(this ILogger logger, T caller, string message, bool force = false) public static void LogError<T>(this ILogger logger, T caller, string message, bool force = false)
{ {
Log(logger, caller, message, ILogger.Level.Error, force); Log(logger, caller, message, ILogger.Level.Error, force);
LogTrace(logger, caller, new StackTrace(), force); Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{new StackTrace()}");
} }
public static void LogException<T>(this ILogger logger, T caller, Exception exception, bool force = false) public static void LogException<T>(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, $"Message: {exception.Message}", ILogger.Level.Error, force);
Log(logger, caller, $"InnerException: {exception.InnerException}", 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<T>(this ILogger logger, T caller, StackTrace? stackTrace = null, bool force = false)
{
Log(logger, caller, $"{nameof(StackTrace)}:{Environment.NewLine}{stackTrace ?? new()}", ILogger.Level.Trace, force);
} }
} }

View File

@ -1,23 +0,0 @@
namespace 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);
}
}

View File

@ -1,6 +0,0 @@
namespace Engine.Core.Debug;
public static class LoggerWrapperExtensions
{
public static ILogger WrapWith(this ILogger thisLogger, ILogger logger) => new LoggerWrapper(thisLogger, logger);
}

View File

@ -1,71 +0,0 @@
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<string> 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);
}

View File

@ -4,8 +4,7 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>false</ImplicitUsings> <ImplicitUsings>false</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<RootNamespace>Engine.Core</RootNamespace> <RootNamespace>Syntriax.Engine.Core</RootNamespace>
<AssemblyName>Engine.Core</AssemblyName>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Exceptions; namespace Syntriax.Engine.Core.Exceptions;
public class AssignFailedException(string? message) : Exception(message) public class AssignFailedException(string? message) : Exception(message)
{ {

View File

@ -1,3 +1,3 @@
namespace Engine.Core.Exceptions; namespace Syntriax.Engine.Core.Exceptions;
public class BehaviourNotFoundException(string? message) : NotFoundException(message); public class BehaviourNotFoundException(string? message) : NotFoundException(message);

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Exceptions; namespace Syntriax.Engine.Core.Exceptions;
public class NotAssignedException(string? message) : Exception(message) public class NotAssignedException(string? message) : Exception(message)
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Exceptions; namespace Syntriax.Engine.Core.Exceptions;
public class NotFoundException(string? message) : Exception(message) public class NotFoundException(string? message) : Exception(message)
{ {

View File

@ -1,3 +1,3 @@
namespace Engine.Core.Exceptions; namespace Syntriax.Engine.Core.Exceptions;
public class UniverseObjectNotFoundException(string? message) : NotFoundException(message); public class UniverseObjectNotFoundException(string? message) : NotFoundException(message);

View File

@ -1,9 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Engine.Core.Exceptions; using Syntriax.Engine.Core.Exceptions;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public static class BehaviourControllerExtensions public static class BehaviourControllerExtensions
{ {
@ -27,7 +27,7 @@ public static class BehaviourControllerExtensions
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param> /// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns> /// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns>
public static T GetRequiredBehaviour<T>(this IBehaviourController behaviourController) where T : class public static T GetRequiredBehaviour<T>(this IBehaviourController behaviourController) where T : class
=> behaviourController.GetBehaviour<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject?.Name ?? "NULL"}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName}"); => behaviourController.GetBehaviour<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName}");
/// <summary> /// <summary>
/// Gets an existing <see cref="IBehaviour"/> of the specified type, or adds and returns a new one if it doesn't exist. /// Gets an existing <see cref="IBehaviour"/> of the specified type, or adds and returns a new one if it doesn't exist.
@ -93,7 +93,7 @@ public static class BehaviourControllerExtensions
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param> /// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns> /// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns>
public static T GetRequiredBehaviourInParent<T>(this IBehaviourController behaviourController) where T : class public static T GetRequiredBehaviourInParent<T>(this IBehaviourController behaviourController) where T : class
=> behaviourController.GetBehaviourInParent<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject?.Name ?? "NULL"}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any parent"); => behaviourController.GetBehaviourInParent<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any parent");
/// <summary> /// <summary>
/// Gets all <see cref="IBehaviour"/>s of the specified type in it's <see cref="IUniverseObject"/>'s parents recursively and stores them in the provided list. /// Gets all <see cref="IBehaviour"/>s of the specified type in it's <see cref="IUniverseObject"/>'s parents recursively and stores them in the provided list.
@ -140,7 +140,7 @@ public static class BehaviourControllerExtensions
if (behaviourController.GetBehaviour<T>() is T localBehaviour) if (behaviourController.GetBehaviour<T>() is T localBehaviour)
return localBehaviour; return localBehaviour;
foreach (IUniverseObject child in behaviourController.UniverseObject.Children) foreach (IUniverseObject child in behaviourController.UniverseObject)
if (GetBehaviourInChildren<T>(child.BehaviourController) is T behaviour) if (GetBehaviourInChildren<T>(child.BehaviourController) is T behaviour)
return behaviour; return behaviour;
@ -154,7 +154,7 @@ public static class BehaviourControllerExtensions
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param> /// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns> /// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns>
public static T GetRequiredBehaviourInChildren<T>(this IBehaviourController behaviourController) where T : class public static T GetRequiredBehaviourInChildren<T>(this IBehaviourController behaviourController) where T : class
=> behaviourController.GetBehaviourInChildren<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject?.Name ?? "NULL"}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any children "); => behaviourController.GetBehaviourInChildren<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any children ");
/// <summary> /// <summary>
/// Gets all <see cref="IBehaviour"/>s of the specified type in it's <see cref="IUniverseObject"/>'s children recursively and stores them in the provided list. /// Gets all <see cref="IBehaviour"/>s of the specified type in it's <see cref="IUniverseObject"/>'s children recursively and stores them in the provided list.
@ -176,7 +176,7 @@ public static class BehaviourControllerExtensions
foreach (T behaviour in cache) foreach (T behaviour in cache)
behaviours.Add(behaviour); behaviours.Add(behaviour);
foreach (IUniverseObject child in universeObject.Children) foreach (IUniverseObject child in universeObject)
TraverseChildrenForBehaviour(child, behaviours, cache); TraverseChildrenForBehaviour(child, behaviours, cache);
} }
} }

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public static class EnumExtensions public static class EnumExtensions
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public static class FloatExtensions public static class FloatExtensions
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public static class TransformExtensions public static class TransformExtensions
{ {

View File

@ -1,6 +1,6 @@
using Engine.Core.Exceptions; using Syntriax.Engine.Core.Exceptions;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public static class UniverseExtensions public static class UniverseExtensions
{ {

View File

@ -1,9 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Engine.Core.Exceptions; using Syntriax.Engine.Core.Exceptions;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public static class UniverseObjectExtensions public static class UniverseObjectExtensions
{ {
@ -12,7 +12,7 @@ public static class UniverseObjectExtensions
if (!string.IsNullOrWhiteSpace(name)) if (!string.IsNullOrWhiteSpace(name))
universeObject.Name = name; universeObject.Name = name;
if (parent is not null) if (parent is not null)
universeObject.Parent = parent; universeObject.SetParent(parent);
return universeObject; return universeObject;
} }
@ -81,7 +81,7 @@ public static class UniverseObjectExtensions
/// <returns>The <see cref="IUniverseObject"/> of the specified type if found; otherwise, null.</returns> /// <returns>The <see cref="IUniverseObject"/> of the specified type if found; otherwise, null.</returns>
public static T? GetUniverseObjectInParent<T>(this IUniverseObject universeObject) where T : class public static T? GetUniverseObjectInParent<T>(this IUniverseObject universeObject) where T : class
{ {
if (universeObject.Children.GetUniverseObject<T>() is T localUniverseObject) if (universeObject.GetUniverseObject<T>() is T localUniverseObject)
return localUniverseObject; return localUniverseObject;
IUniverseObject? parent = universeObject; IUniverseObject? parent = universeObject;
@ -129,10 +129,10 @@ public static class UniverseObjectExtensions
/// <returns>The <see cref="IUniverseObject"/> of the specified type if found; otherwise, null.</returns> /// <returns>The <see cref="IUniverseObject"/> of the specified type if found; otherwise, null.</returns>
public static T? GetUniverseObjectInChildren<T>(this IUniverseObject universeObject) where T : class public static T? GetUniverseObjectInChildren<T>(this IUniverseObject universeObject) where T : class
{ {
if (universeObject.Children.GetUniverseObject<T>() is T localUniverseObject) if (universeObject.GetUniverseObject<T>() is T localUniverseObject)
return localUniverseObject; return localUniverseObject;
foreach (IUniverseObject child in universeObject.Children) foreach (IUniverseObject child in universeObject)
if (GetUniverseObjectInChildren<T>(child) is T behaviour) if (GetUniverseObjectInChildren<T>(child) is T behaviour)
return behaviour; return behaviour;
@ -246,7 +246,7 @@ public static class UniverseObjectExtensions
foreach (IUniverseObject universeObject in universeObjects) foreach (IUniverseObject universeObject in universeObjects)
{ {
universeObject.Children.Find(cache); universeObject.Find(cache);
foreach (T behaviour in cache) foreach (T behaviour in cache)
instances.Add(behaviour); instances.Add(behaviour);
} }

View File

@ -1,4 +1,4 @@
namespace Engine.Core.Factory.Abstract; namespace Syntriax.Engine.Core.Factory.Abstract;
public interface IFactory<TInterface> where TInterface : class public interface IFactory<TInterface> where TInterface : class
{ {

View File

@ -1,13 +1,13 @@
using Engine.Core.Exceptions; using Syntriax.Engine.Core.Exceptions;
namespace Engine.Core.Factory; namespace Syntriax.Engine.Core.Factory;
public class BehaviourControllerFactory public class BehaviourControllerFactory
{ {
public static IBehaviourController Instantiate(IUniverseObject universeObject, IStateEnable? stateEnable = null) public static IBehaviourController Instantiate(IUniverseObject universeObject)
=> Instantiate<BehaviourController>(universeObject, stateEnable); => Instantiate<BehaviourController>(universeObject);
public static T Instantiate<T>(IUniverseObject universeObject, IStateEnable? stateEnable = null, params object?[]? args) public static T Instantiate<T>(IUniverseObject universeObject, params object?[]? args)
where T : class, IBehaviourController where T : class, IBehaviourController
{ {
T behaviourController = TypeFactory.Get<T>(args); T behaviourController = TypeFactory.Get<T>(args);
@ -18,17 +18,6 @@ public class BehaviourControllerFactory
if (!behaviourController.Assign(universeObject)) if (!behaviourController.Assign(universeObject))
throw AssignFailedException.From(behaviourController, 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; return behaviourController;
} }
} }

View File

@ -1,6 +1,6 @@
using Engine.Core.Exceptions; using Syntriax.Engine.Core.Exceptions;
namespace Engine.Core.Factory; namespace Syntriax.Engine.Core.Factory;
public class BehaviourFactory public class BehaviourFactory
{ {
@ -12,15 +12,12 @@ public class BehaviourFactory
{ {
T behaviour = TypeFactory.Get<T>(args); T behaviour = TypeFactory.Get<T>(args);
if (stateEnable is not null) stateEnable ??= TypeFactory.Get<StateEnable>();
{ if (!stateEnable.Assign(behaviour))
if (!stateEnable.Assign(behaviour)) throw AssignFailedException.From(stateEnable, behaviour);
throw AssignFailedException.From(stateEnable, behaviour);
if (!behaviour.Assign(stateEnable)) if (!behaviour.Assign(stateEnable))
throw AssignFailedException.From(behaviour, stateEnable); throw AssignFailedException.From(behaviour, stateEnable);
}
else
StateEnableFactory.Instantiate(behaviour);
return behaviour; return behaviour;
} }

View File

@ -1,7 +1,7 @@
using System; using System;
using Engine.Core.Factory.Abstract; using Syntriax.Engine.Core.Factory.Abstract;
namespace Engine.Core.Factory; namespace Syntriax.Engine.Core.Factory;
public abstract class FactoryBase<TInterface> : IFactory<TInterface> public abstract class FactoryBase<TInterface> : IFactory<TInterface>
where TInterface : class where TInterface : class

View File

@ -1,6 +1,6 @@
using Engine.Core.Exceptions; using Syntriax.Engine.Core.Exceptions;
namespace Engine.Core.Factory; namespace Syntriax.Engine.Core.Factory;
public class StateEnableFactory public class StateEnableFactory
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core.Factory; namespace Syntriax.Engine.Core.Factory;
public class TransformFactory public class TransformFactory
{ {

View File

@ -3,7 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Engine.Core.Factory; namespace Syntriax.Engine.Core.Factory;
public static class TypeFactory public static class TypeFactory
{ {

View File

@ -1,6 +1,6 @@
using Engine.Core.Exceptions; using Syntriax.Engine.Core.Exceptions;
namespace Engine.Core.Factory; namespace Syntriax.Engine.Core.Factory;
public class UniverseObjectFactory public class UniverseObjectFactory
{ {
@ -18,25 +18,18 @@ public class UniverseObjectFactory
{ {
T universeObject = TypeFactory.Get<T>(args); T universeObject = TypeFactory.Get<T>(args);
if (behaviourController is not null) behaviourController ??= TypeFactory.Get<BehaviourController>();
{ stateEnable ??= TypeFactory.Get<StateEnable>();
if (!behaviourController.Assign(universeObject))
throw AssignFailedException.From(behaviourController, universeObject);
if (!universeObject.Assign(behaviourController))
throw AssignFailedException.From(universeObject, behaviourController);
}
else
BehaviourControllerFactory.Instantiate(universeObject);
if (stateEnable is not null) if (!behaviourController.Assign(universeObject))
{ throw AssignFailedException.From(behaviourController, universeObject);
if (!stateEnable.Assign(universeObject)) if (!stateEnable.Assign(universeObject))
throw AssignFailedException.From(stateEnable, universeObject); throw AssignFailedException.From(stateEnable, universeObject);
if (!universeObject.Assign(stateEnable))
throw AssignFailedException.From(universeObject, stateEnable); if (!universeObject.Assign(behaviourController))
} throw AssignFailedException.From(universeObject, behaviourController);
else if (!universeObject.Assign(stateEnable))
StateEnableFactory.Instantiate(universeObject); throw AssignFailedException.From(universeObject, stateEnable);
return universeObject; return universeObject;
} }

View File

@ -1,152 +1,35 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Engine.Core.Debug; namespace Syntriax.Engine.Core;
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.
/// <summary>
/// Represents a simple event with no parameters.
/// <para>Example usage:</para>
/// <code>
/// 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!");
/// }
/// }
/// </code>
/// The output of the example code above would be:
/// <code>
/// Event occurred!
/// Event called once!
/// Event occurred!
/// Event occurred!
/// Event occurred!
/// ...
/// </code>
/// </summary>
public class Event public class Event
{ {
// We use Ascending order because draw calls are running from last to first private readonly List<EventHandler> listeners = null!;
private static readonly Comparer<ListenerData> SortByAscendingPriority = Comparer<ListenerData>.Create((x, y) => x.Priority.CompareTo(y.Priority)); private readonly List<EventHandler> onceListeners = null!;
private ILogger _logger = ILogger.Shared; public void AddListener(EventHandler listener) => listeners.Add(listener);
public ILogger Logger { get => _logger; set => _logger = value ?? ILogger.Shared; } public void AddOnceListener(EventHandler listener) => onceListeners.Add(listener);
public void RemoveListener(EventHandler listener) => listeners.Remove(listener);
private readonly List<ListenerData> listeners = null!; public void RemoveOnceListener(EventHandler listener) => onceListeners.Remove(listener);
private readonly List<ListenerData> onceListeners = null!;
/// <summary>
/// Subscribes the callback to be invoked whenever the event is triggered.
/// </summary>
/// <param name="listener">The callback to be called when the event is triggered.</param>
/// <param name="priority">Priority of the callback.</param>
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);
}
/// <summary>
/// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once.
/// </summary>
/// <param name="listener">The callback to be called the next time the event is triggered.</param>
/// <param name="priority">Priority of the callback.</param>
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);
}
/// <summary>
/// Unsubscribes the callback that was previously registered by <see cref="AddListener(EventHandler)"/>.
/// </summary>
/// <param name="listener">The callback that was previously registered by <see cref="AddListener(EventHandler)"/></param>
public void RemoveListener(EventHandler listener)
{
for (int i = listeners.Count - 1; i >= 0; i--)
if (listeners[i].Callback == listener)
{
listeners.RemoveAt(i);
return;
}
}
/// <summary>
/// Unsubscribes the callback that was previously registered by <see cref="AddOneTimeListener(EventHandler)"/>.
/// </summary>
/// <param name="listener">The callback that was previously registered by <see cref="AddOneTimeListener(EventHandler)"/></param>
public void RemoveOneTimeListener(EventHandler listener)
{
for (int i = 0; i < onceListeners.Count; i++)
if (onceListeners[i].Callback == listener)
{
onceListeners.RemoveAt(i);
return;
}
}
/// <summary>
/// Unsubscribes all listeners that was previously registered by either <see cref="AddListener(EventHandler)"/> or <see cref="AddOneTimeListener(EventHandler)"/>.
/// </summary>
public void Clear() { listeners.Clear(); onceListeners.Clear(); } public void Clear() { listeners.Clear(); onceListeners.Clear(); }
/// <summary>
/// Triggers the event.
/// </summary>
public void Invoke() public void Invoke()
{ {
for (int i = listeners.Count - 1; i >= 0; i--) for (int i = 0; i < listeners.Count; i++)
try { listeners[i].Callback.Invoke(); } try { listeners[i].Invoke(); }
catch (Exception exception) catch (Exception exception)
{ {
string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}()"; string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}()";
EventHelpers.LogInvocationException(listeners[i].Callback.Target ?? this, Logger, exception, methodCallRepresentation); Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
} }
for (int i = onceListeners.Count - 1; i >= 0; i--) for (int i = onceListeners.Count - 1; i >= 0; i--)
{ {
try { onceListeners[i].Callback.Invoke(); } try { onceListeners[i].Invoke(); }
catch (Exception exception) catch (Exception exception)
{ {
string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}()"; string methodCallRepresentation = $"{onceListeners[i].Method.DeclaringType?.FullName}.{onceListeners[i].Method.Name}()";
EventHelpers.LogInvocationException(onceListeners[i].Callback.Target ?? this, Logger, exception, methodCallRepresentation); Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
} }
onceListeners.RemoveAt(i); onceListeners.RemoveAt(i);
} }
@ -165,148 +48,35 @@ public class Event
} }
public delegate void EventHandler(); public delegate void EventHandler();
private record struct ListenerData(EventHandler Callback, int Priority);
} }
/// <summary> public class Event<TSender>
/// Represents an event with only sender parameters.
/// <para>Example usage:</para>
/// <code>
/// public class MyBehaviour : Behaviour, IUpdate
/// {
/// public readonly Event&lt;MyBehaviour&gt; 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!");
/// }
/// }
/// </code>
/// The output of the example code above would be:
/// <code>
/// [Id]'s event occurred!
/// [Id]'s event called once!
/// [Id]'s event occurred!
/// [Id]'s event occurred!
/// [Id]'s event occurred!
/// ...
/// </code>
///
/// </summary>
/// <typeparam name="TSender">Sender type</typeparam>
public class Event<TSender> where TSender : class
{ {
// We use Ascending order because draw calls are running from last to first private readonly List<EventHandler> listeners = null!;
private static readonly Comparer<ListenerData> SortByAscendingPriority = Comparer<ListenerData>.Create((x, y) => x.Priority.CompareTo(y.Priority)); private readonly List<EventHandler> onceListeners = null!;
private ILogger _logger = ILogger.Shared; public void AddListener(EventHandler listener) => listeners.Add(listener);
public ILogger Logger { get => _logger; set => _logger = value ?? ILogger.Shared; } public void AddOnceListener(EventHandler listener) => onceListeners.Add(listener);
public void RemoveListener(EventHandler listener) => listeners.Remove(listener);
private readonly List<ListenerData> listeners = null!; public void RemoveOnceListener(EventHandler listener) => onceListeners.Remove(listener);
private readonly List<ListenerData> onceListeners = null!;
/// <summary>
/// Subscribes the callback to be invoked whenever the event is triggered.
/// </summary>
/// <param name="listener">The callback to be called when the event is triggered.</param>
/// <param name="priority">Priority of the callback.</param>
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);
}
/// <summary>
/// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once.
/// </summary>
/// <param name="listener">The callback to be called the next time the event is triggered.</param>
/// <param name="priority">Priority of the callback.</param>
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);
}
/// <summary>
/// Unsubscribes the callback that was previously registered by <see cref="AddListener(EventHandler)"/>.
/// </summary>
/// <param name="listener">The callback that was previously registered by <see cref="AddListener(EventHandler)"/></param>
public void RemoveListener(EventHandler listener)
{
for (int i = listeners.Count - 1; i >= 0; i--)
if (listeners[i].Callback == listener)
{
listeners.RemoveAt(i);
return;
}
}
/// <summary>
/// Unsubscribes the callback that was previously registered by <see cref="AddOneTimeListener(EventHandler)"/>.
/// </summary>
/// <param name="listener">The callback that was previously registered by <see cref="AddOneTimeListener(EventHandler)"/></param>
public void RemoveOneTimeListener(EventHandler listener)
{
for (int i = 0; i < onceListeners.Count; i++)
if (onceListeners[i].Callback == listener)
{
onceListeners.RemoveAt(i);
return;
}
}
/// <summary>
/// Unsubscribes all listeners that was previously registered by either <see cref="AddListener(EventHandler)"/> or <see cref="AddOneTimeListener(EventHandler)"/>.
/// </summary>
public void Clear() { listeners.Clear(); onceListeners.Clear(); } public void Clear() { listeners.Clear(); onceListeners.Clear(); }
/// <summary>
/// Triggers the event.
/// </summary>
/// <param name="sender">The caller that's triggering this event.</param>
public void Invoke(TSender sender) public void Invoke(TSender sender)
{ {
for (int i = listeners.Count - 1; i >= 0; i--) for (int i = 0; i < listeners.Count; i++)
try { listeners[i].Callback.Invoke(sender); } try { listeners[i].Invoke(sender); }
catch (Exception exception) catch (Exception exception)
{ {
string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({sender})"; string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({sender})";
EventHelpers.LogInvocationException(listeners[i].Callback.Target ?? sender, Logger, exception, methodCallRepresentation); Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
} }
for (int i = onceListeners.Count - 1; i >= 0; i--) for (int i = onceListeners.Count - 1; i >= 0; i--)
{ {
try { onceListeners[i].Callback.Invoke(sender); } try { onceListeners[i].Invoke(sender); }
catch (Exception exception) catch (Exception exception)
{ {
string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({sender})"; string methodCallRepresentation = $"{onceListeners[i].Method.DeclaringType?.FullName}.{onceListeners[i].Method.Name}({sender})";
EventHelpers.LogInvocationException(onceListeners[i].Callback.Target ?? sender, Logger, exception, methodCallRepresentation); Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
} }
onceListeners.RemoveAt(i); onceListeners.RemoveAt(i);
} }
@ -325,156 +95,35 @@ public class Event<TSender> where TSender : class
} }
public delegate void EventHandler(TSender sender); public delegate void EventHandler(TSender sender);
private record struct ListenerData(EventHandler Callback, int Priority);
} }
/// <summary> public class Event<TSender, TArguments>
/// Represents an event with sender and argument parameters.
/// <para>Example usage:</para>
/// <code>
/// public class MyBehaviour : Behaviour, IUpdate
/// {
/// public readonly Event&lt;MyBehaviour, MyArguments&gt; 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);
/// }
/// </code>
/// The output of the example code above would be:
/// <code>
/// [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!
/// ...
/// </code>
///
/// </summary>
/// <typeparam name="TSender">Sender type</typeparam>
public class Event<TSender, TArguments> where TSender : class
{ {
// We use Ascending order because draw calls are running from last to first private readonly List<EventHandler> listeners = null!;
private static readonly Comparer<ListenerData> SortByAscendingPriority = Comparer<ListenerData>.Create((x, y) => x.Priority.CompareTo(y.Priority)); private readonly List<EventHandler> onceListeners = null!;
private ILogger _logger = ILogger.Shared; public void AddListener(EventHandler listener) => listeners.Add(listener);
public ILogger Logger { get => _logger; set => _logger = value ?? ILogger.Shared; } public void AddOnceListener(EventHandler listener) => onceListeners.Add(listener);
public void RemoveListener(EventHandler listener) => listeners.Remove(listener);
private readonly List<ListenerData> listeners = null!; public void RemoveOnceListener(EventHandler listener) => onceListeners.Remove(listener);
private readonly List<ListenerData> onceListeners = null!;
/// <summary>
/// Subscribes the callback to be invoked whenever the event is triggered.
/// </summary>
/// <param name="listener">The callback to be called when the event is triggered.</param>
/// <param name="priority">Priority of the callback.</param>
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);
}
/// <summary>
/// Subscribes the callback to be invoked the next time the event is triggered. The callback will be called only once.
/// </summary>
/// <param name="listener">The callback to be called the next time the event is triggered.</param>
/// <param name="priority">Priority of the callback.</param>
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);
}
/// <summary>
/// Unsubscribes the callback that was previously registered by <see cref="AddListener(EventHandler)"/>.
/// </summary>
/// <param name="listener">The callback that was previously registered by <see cref="AddListener(EventHandler)"/></param>
public void RemoveListener(EventHandler listener)
{
for (int i = listeners.Count - 1; i >= 0; i--)
if (listeners[i].Callback == listener)
{
listeners.RemoveAt(i);
return;
}
}
/// <summary>
/// Unsubscribes the callback that was previously registered by <see cref="AddOneTimeListener(EventHandler)"/>.
/// </summary>
/// <param name="listener">The callback that was previously registered by <see cref="AddOneTimeListener(EventHandler)"/></param>
public void RemoveOneTimeListener(EventHandler listener)
{
for (int i = 0; i < onceListeners.Count; i++)
if (onceListeners[i].Callback == listener)
{
onceListeners.RemoveAt(i);
return;
}
}
/// <summary>
/// Unsubscribes all listeners that was previously registered by either <see cref="AddListener(EventHandler)"/> or <see cref="AddOneTimeListener(EventHandler)"/>.
/// </summary>
public void Clear() { listeners.Clear(); onceListeners.Clear(); } public void Clear() { listeners.Clear(); onceListeners.Clear(); }
/// <summary>
/// Triggers the event.
/// </summary>
/// <param name="sender">The caller that's triggering this event.</param>
/// <param name="args">The arguments provided for this event.</param>
public void Invoke(TSender sender, TArguments args) public void Invoke(TSender sender, TArguments args)
{ {
for (int i = listeners.Count - 1; i >= 0; i--) for (int i = 0; i < listeners.Count; i++)
try { listeners[i].Callback.Invoke(sender, args); } try { listeners[i].Invoke(sender, args); }
catch (Exception exception) catch (Exception exception)
{ {
string methodCallRepresentation = $"{listeners[i].Callback.Method.DeclaringType?.FullName}.{listeners[i].Callback.Method.Name}({sender}, {args})"; string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", sender, args)})";
EventHelpers.LogInvocationException(listeners[i].Callback.Target ?? sender, Logger, exception, methodCallRepresentation); Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
} }
for (int i = onceListeners.Count - 1; i >= 0; i--) for (int i = onceListeners.Count - 1; i >= 0; i--)
{ {
try { onceListeners[i].Callback.Invoke(sender, args); } try { onceListeners[i].Invoke(sender, args); }
catch (Exception exception) catch (Exception exception)
{ {
string methodCallRepresentation = $"{onceListeners[i].Callback.Method.DeclaringType?.FullName}.{onceListeners[i].Callback.Method.Name}({sender}, {args})"; string methodCallRepresentation = $"{onceListeners[i].Method.DeclaringType?.FullName}.{onceListeners[i].Method.Name}({string.Join(", ", sender, args)})";
EventHelpers.LogInvocationException(onceListeners[i].Callback.Target ?? sender, Logger, exception, methodCallRepresentation); Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
} }
onceListeners.RemoveAt(i); onceListeners.RemoveAt(i);
} }
@ -493,14 +142,4 @@ public class Event<TSender, TArguments> where TSender : class
} }
public delegate void EventHandler(TSender sender, TArguments args); 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}");
}
} }

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public interface IPool<T> public interface IPool<T>
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class ListPool<T> : IPool<List<T>> public class ListPool<T> : IPool<List<T>>
{ {
@ -31,10 +31,10 @@ public class ListPool<T> : IPool<List<T>>
OnReturned?.Invoke(this, list); OnReturned?.Invoke(this, list);
} }
public ListPool(int initialListCount = 1, int initialListCapacity = 32) public ListPool(Func<List<T>> generator, int initialCapacity = 1)
{ {
generator = () => new(initialListCapacity); this.generator = generator;
for (int i = 0; i < initialListCount; i++) for (int i = 0; i < initialCapacity; i++)
queue.Enqueue(generator()); queue.Enqueue(generator());
} }
} }

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class Pool<T> : IPool<T> public class Pool<T> : IPool<T>
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public interface IProgressionTracker : IReadOnlyProgressionTracker public interface IProgressionTracker : IReadOnlyProgressionTracker
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public interface IReadOnlyProgressionTracker public interface IReadOnlyProgressionTracker
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class ProgressionTracker : IProgressionTracker public class ProgressionTracker : IProgressionTracker
{ {

View File

@ -1,6 +1,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public record struct ProgressiveTask<T>(IReadOnlyProgressionTracker ProgressionTracker, Task<T> Task) public record struct ProgressiveTask<T>(IReadOnlyProgressionTracker ProgressionTracker, Task<T> Task)
{ {

View File

@ -1,34 +1,34 @@
using System; using System;
using System.Numerics; using System.Numerics;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public static class Math public static class Math
{ {
/// <summary> /// <summary>
/// The value of Pi (π). /// The value of Pi (π), a mathematical constant approximately equal to 3.14159.
/// </summary> /// </summary>
public const float Pi = 3.1415926535897932f; public const float PI = 3.1415926535897932f;
/// <summary> /// <summary>
/// The value of Tau (τ), mathematical constant equal to 2π. /// The value of Tau (τ), a mathematical constant equal to 2π, approximately equal to 6.28319.
/// </summary> /// </summary>
public const float Tau = 2f * Pi; public const float Tau = 2f * PI;
/// <summary> /// <summary>
/// The base of the natural logarithm. /// The base of the natural logarithm, approximately equal to 2.71828.
/// </summary> /// </summary>
public const float E = 2.718281828459045f; public const float E = 2.718281828459045f;
/// <summary> /// <summary>
/// The conversion factor from radians to degrees. /// The conversion factor from radians to degrees.
/// </summary> /// </summary>
public const float RadianToDegree = 180f / Pi; public const float RadianToDegree = 180f / PI;
/// <summary> /// <summary>
/// The conversion factor from degrees to radians. /// The conversion factor from degrees to radians.
/// </summary> /// </summary>
public const float DegreeToRadian = Pi / 180f; public const float DegreeToRadian = PI / 180f;
/// <summary> /// <summary>
/// Gets one minus of given <see cref="T"/>. /// Gets one minus of given <see cref="T"/>.

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Numerics; using System.Numerics;
namespace Engine.Core; namespace Syntriax.Engine.Core;
public static class MathExtensions public static class MathExtensions
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core namespace Syntriax.Engine.Core
{ {
// This is pretty much so the assembly gets loaded automatically because // 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. // the builds include the assembly but sometimes doesn't link load it at startup.

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents an Axis-Aligned Bounding Box (AABB) in 2D space. /// Represents an Axis-Aligned Bounding Box (AABB) in 2D space.
@ -38,9 +38,6 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary)
/// </summary> /// </summary>
public readonly Vector2D SizeHalf => Size * .5f; 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;
/// <summary> /// <summary>
/// Creates an <see cref="AABB"/> from a collection of <see cref="Vector2D"/>s. /// Creates an <see cref="AABB"/> from a collection of <see cref="Vector2D"/>s.
/// </summary> /// </summary>
@ -66,6 +63,12 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary)
return new(lowerBoundary, upperBoundary); return new(lowerBoundary, upperBoundary);
} }
/// <summary>
/// Converts the <see cref="AABB"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="AABB"/>.</returns>
public override string ToString() => $"{nameof(AABB)}({LowerBoundary}, {UpperBoundary})";
/// <summary> /// <summary>
/// Checks if two <see cref="AABB"/>s are approximately equal. /// Checks if two <see cref="AABB"/>s are approximately equal.
/// </summary> /// </summary>
@ -75,25 +78,6 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary)
/// <returns><see cref="true"/> if the <see cref="AABB"/>s are approximately equal; otherwise, <see cref="false"/>.</returns> /// <returns><see cref="true"/> if the <see cref="AABB"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
public static bool ApproximatelyEquals(AABB left, AABB right, float epsilon = float.Epsilon) public static bool ApproximatelyEquals(AABB left, AABB right, float epsilon = float.Epsilon)
=> left.LowerBoundary.ApproximatelyEquals(right.LowerBoundary, epsilon) && left.UpperBoundary.ApproximatelyEquals(right.UpperBoundary, epsilon); => left.LowerBoundary.ApproximatelyEquals(right.LowerBoundary, epsilon) && left.UpperBoundary.ApproximatelyEquals(right.UpperBoundary, epsilon);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="AABB"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="AABB"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="AABB"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is AABB aabb && this == aabb;
/// <summary>
/// Generates a hash code for the <see cref="AABB"/>.
/// </summary>
/// <returns>A hash code for the <see cref="AABB"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(LowerBoundary, UpperBoundary);
/// <summary>
/// Converts the <see cref="AABB"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="AABB"/>.</returns>
public override string ToString() => $"{nameof(AABB)}({LowerBoundary}, {UpperBoundary})";
} }
/// <summary> /// <summary>

View File

@ -1,6 +1,6 @@
using System.Diagnostics; using System.Diagnostics;
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a 2D circle. /// Represents a 2D circle.
@ -38,9 +38,6 @@ public readonly struct Circle(Vector2D center, float radius)
/// </summary> /// </summary>
public static readonly Circle UnitCircle = new(Vector2D.Zero, 1f); 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;
/// <summary> /// <summary>
/// Sets the center of the <see cref="Circle"/>. /// Sets the center of the <see cref="Circle"/>.
/// </summary> /// </summary>
@ -80,25 +77,6 @@ public readonly struct Circle(Vector2D center, float radius)
/// <returns><see cref="true"/> if the <see cref="Circle"/>s are approximately equal; otherwise, <see cref="false"/>.</returns> /// <returns><see cref="true"/> if the <see cref="Circle"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
public static bool ApproximatelyEquals(Circle left, Circle right, float epsilon = float.Epsilon) public static bool ApproximatelyEquals(Circle left, Circle right, float epsilon = float.Epsilon)
=> left.Center.ApproximatelyEquals(right.Center, epsilon) && left.Radius.ApproximatelyEquals(right.Radius, epsilon); => left.Center.ApproximatelyEquals(right.Center, epsilon) && left.Radius.ApproximatelyEquals(right.Radius, epsilon);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="Circle"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="Circle"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Circle"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Circle circle && this == circle;
/// <summary>
/// Generates a hash code for the <see cref="Circle"/>.
/// </summary>
/// <returns>A hash code for the <see cref="Circle"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(Center, Radius);
/// <summary>
/// Converts the <see cref="Circle"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Circle"/>.</returns>
public override string ToString() => $"{nameof(Circle)}({Center}, {Radius})";
} }
/// <summary> /// <summary>

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents an HSV color. /// Represents an HSV color.
@ -27,19 +27,49 @@ public readonly struct ColorHSV(float hue, float saturation, float value)
/// </summary> /// </summary>
public readonly float Value = value.Clamp(0f, 1f); public readonly float 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 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, left.Saturation + right.Saturation, left.Value + right.Value); 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, left.Saturation - right.Saturation, left.Value - right.Value); 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, left.Saturation * right.Saturation, left.Value * right.Value); 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, color.Saturation * value, color.Value * 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, color.Saturation * value, color.Value * value); 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, color.Saturation / value, color.Value / 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 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.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.ApproximatelyEquals(right.Hue) || !left.Saturation.ApproximatelyEquals(right.Saturation) || !left.Value.ApproximatelyEquals(right.Value);
public static implicit operator ColorHSV(ColorHSVA hsva) => new(hsva.Hue, hsva.Saturation, hsva.Value); public static implicit operator ColorHSV(ColorRGBA rgba) => (ColorRGB)rgba;
public static implicit operator ColorHSV(ColorRGBA rgba) => (ColorHSVA)rgba; public static implicit operator ColorHSV(ColorRGB rgb)
public static implicit operator ColorHSV(ColorRGB rgb) => (ColorHSVA)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);
}
/// <summary> /// <summary>
/// Inverts the given <see cref="ColorHSV"/>. /// Inverts the given <see cref="ColorHSV"/>.
@ -80,6 +110,14 @@ public readonly struct ColorHSV(float hue, float saturation, float value)
/// <returns>The result of dividing the <see cref="ColorHSV"/> by the scalar value.</returns> /// <returns>The result of dividing the <see cref="ColorHSV"/> by the scalar value.</returns>
public static ColorHSV Divide(ColorHSV color, float value) => color / value; public static ColorHSV Divide(ColorHSV color, float value) => color / value;
/// <summary>
/// Calculates the <see cref="ColorHSV"/> from one point to another.
/// </summary>
/// <param name="from">The starting point.</param>
/// <param name="to">The ending point.</param>
/// <returns>The <see cref="ColorHSV"/> from the starting point to the ending point.</returns>
public static ColorHSV FromTo(ColorHSV from, ColorHSV to) => to - from;
/// <summary> /// <summary>
/// Performs linear interpolation between two <see cref="ColorHSV"/>s. /// Performs linear interpolation between two <see cref="ColorHSV"/>s.
/// </summary> /// </summary>
@ -87,14 +125,13 @@ public readonly struct ColorHSV(float hue, float saturation, float value)
/// <param name="to">The ending <see cref="ColorHSV"/> (t = 1).</param> /// <param name="to">The ending <see cref="ColorHSV"/> (t = 1).</param>
/// <param name="t">The interpolation parameter.</param> /// <param name="t">The interpolation parameter.</param>
/// <returns>The interpolated <see cref="ColorHSV"/>.</returns> /// <returns>The interpolated <see cref="ColorHSV"/>.</returns>
public static ColorHSV Lerp(ColorHSV from, ColorHSV to, float t) public static ColorHSV Lerp(ColorHSV from, ColorHSV to, float t) => from + FromTo(from, to) * 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); /// <summary>
} /// Converts the <see cref="ColorHSV"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="ColorHSV"/>.</returns>
public override string ToString() => $"{nameof(ColorHSV)}({Hue}, {Saturation}, {Value})";
/// <summary> /// <summary>
/// Checks if two <see cref="ColorHSV"/>s are approximately equal within a specified epsilon range. /// Checks if two <see cref="ColorHSV"/>s are approximately equal within a specified epsilon range.
@ -111,19 +148,13 @@ public readonly struct ColorHSV(float hue, float saturation, float value)
/// </summary> /// </summary>
/// <param name="obj">The object to compare with the current <see cref="ColorHSV"/>.</param> /// <param name="obj">The object to compare with the current <see cref="ColorHSV"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorHSV"/>; otherwise, <see cref="false"/>.</returns> /// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorHSV"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is ColorHSV colorHSV && this == colorHSV; public override bool Equals(object? obj) => obj is ColorHSV objVec && Hue.Equals(objVec.Hue) && Saturation.Equals(objVec.Saturation) && Value.Equals(objVec.Value);
/// <summary> /// <summary>
/// Generates a hash code for the <see cref="ColorHSV"/>. /// Generates a hash code for the <see cref="ColorHSV"/>.
/// </summary> /// </summary>
/// <returns>A hash code for the <see cref="ColorHSV"/>.</returns> /// <returns>A hash code for the <see cref="ColorHSV"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(Hue, Saturation, Value); public override int GetHashCode() => System.HashCode.Combine(Hue, Saturation, Value);
/// <summary>
/// Converts the <see cref="ColorHSV"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="ColorHSV"/>.</returns>
public override string ToString() => $"{nameof(ColorHSV)}({Hue}, {Saturation}, {Value})";
} }
/// <summary> /// <summary>
@ -143,6 +174,9 @@ public static class ColorHSVExtensions
/// <inheritdoc cref="ColorHSV.Divide(ColorHSV, ColorHSV)" /> /// <inheritdoc cref="ColorHSV.Divide(ColorHSV, ColorHSV)" />
public static ColorHSV Divide(this ColorHSV color, float value) => ColorHSV.Divide(color, value); public static ColorHSV Divide(this ColorHSV color, float value) => ColorHSV.Divide(color, value);
/// <inheritdoc cref="ColorHSV.FromTo(ColorHSV, ColorHSV)" />
public static ColorHSV FromTo(this ColorHSV from, ColorHSV to) => ColorHSV.FromTo(from, to);
/// <inheritdoc cref="ColorHSV.Lerp(ColorHSV, ColorHSV, float)" /> /// <inheritdoc cref="ColorHSV.Lerp(ColorHSV, ColorHSV, float)" />
public static ColorHSV Lerp(this ColorHSV from, ColorHSV to, float t) => ColorHSV.Lerp(from, to, t); public static ColorHSV Lerp(this ColorHSV from, ColorHSV to, float t) => ColorHSV.Lerp(from, to, t);

View File

@ -1,189 +0,0 @@
namespace Engine.Core;
/// <summary>
/// Represents an HSV color.
/// </summary>
/// <param name="hue">Hue of the <see cref="ColorHSVA"/>.</param>
/// <param name="saturation">Saturation of the <see cref="ColorHSVA"/>.</param>
/// <param name="value">Value of the <see cref="ColorHSVA"/>.</param>
/// <param name="alpha">Alpha of the <see cref="ColorHSVA"/>.</param>
/// <remarks>
/// Initializes a new instance of the <see cref="ColorHSVA"/> struct with the specified values.
/// </remarks>
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
public readonly struct ColorHSVA(float hue, float saturation, float value, float alpha = 1)
{
/// <summary>
/// The Hue value of the <see cref="ColorHSVA"/>.
/// </summary>
public readonly float Hue = hue.Clamp(0f, 1f);
/// <summary>
/// The Saturation value of the <see cref="ColorHSVA"/>.
/// </summary>
public readonly float Saturation = saturation.Clamp(0f, 1f);
/// <summary>
/// The Value value of the <see cref="ColorHSVA"/>.
/// </summary>
public readonly float Value = value.Clamp(0f, 1f);
/// <summary>
/// The Alpha value of the <see cref="ColorHSVA"/>.
/// </summary>
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);
}
/// <summary>
/// Inverts the given <see cref="ColorHSVA"/>.
/// </summary>
/// <param name="color">The <see cref="ColorHSVA"/>.</param>
/// <returns>The inverted <see cref="ColorHSVA"/>.</returns>
public static ColorHSVA Invert(ColorHSVA color) => -color;
/// <summary>
/// Adds two <see cref="ColorHSVA"/>s.
/// </summary>
/// <param name="left">The first <see cref="ColorHSVA"/>.</param>
/// <param name="right">The second <see cref="ColorHSVA"/>.</param>
/// <returns>The sum of the two <see cref="ColorHSVA"/>s.</returns>
public static ColorHSVA Add(ColorHSVA left, ColorHSVA right) => left + right;
/// <summary>
/// Subtracts one <see cref="ColorHSVA"/> from another.
/// </summary>
/// <param name="left">The <see cref="ColorHSVA"/> to subtract from.</param>
/// <param name="right">The <see cref="ColorHSVA"/> to subtract.</param>
/// <returns>The result of subtracting the second <see cref="ColorHSVA"/> from the first.</returns>
public static ColorHSVA Subtract(ColorHSVA left, ColorHSVA right) => left - right;
/// <summary>
/// Multiplies a <see cref="ColorHSVA"/> by a scalar value.
/// </summary>
/// <param name="color">The <see cref="ColorHSVA"/>.</param>
/// <param name="value">The scalar value.</param>
/// <returns>The result of multiplying the <see cref="ColorHSVA"/> by the scalar value.</returns>
public static ColorHSVA Multiply(ColorHSVA color, float value) => color * value;
/// <summary>
/// Divides a <see cref="ColorHSVA"/> by a scalar value.
/// </summary>
/// <param name="color">The <see cref="ColorHSVA"/>.</param>
/// <param name="value">The scalar value.</param>
/// <returns>The result of dividing the <see cref="ColorHSVA"/> by the scalar value.</returns>
public static ColorHSVA Divide(ColorHSVA color, float value) => color / value;
/// <summary>
/// Performs linear interpolation between two <see cref="ColorHSVA"/>s.
/// </summary>
/// <param name="from">The starting <see cref="ColorHSVA"/> (t = 0).</param>
/// <param name="to">The ending <see cref="ColorHSVA"/> (t = 1).</param>
/// <param name="t">The interpolation parameter.</param>
/// <returns>The interpolated <see cref="ColorHSVA"/>.</returns>
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);
}
/// <summary>
/// Checks if two <see cref="ColorHSVA"/>s are approximately equal within a specified epsilon range.
/// </summary>
/// <param name="left">The first <see cref="ColorHSVA"/>.</param>
/// <param name="right">The second <see cref="ColorHSVA"/>.</param>
/// <param name="epsilon">The epsilon range.</param>
/// <returns><see cref="true"/> if the <see cref="ColorHSVA"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
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);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="ColorHSVA"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="ColorHSVA"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorHSVA"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is ColorHSVA colorHSVA && this == colorHSVA;
/// <summary>
/// Generates a hash code for the <see cref="ColorHSVA"/>.
/// </summary>
/// <returns>A hash code for the <see cref="ColorHSVA"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(Hue, Saturation, Value);
/// <summary>
/// Converts the <see cref="ColorHSVA"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="ColorHSVA"/>.</returns>
public override string ToString() => $"{nameof(ColorHSVA)}({Hue}, {Saturation}, {Value})";
}
/// <summary>
/// Provides extension methods for <see cref="ColorHSVA"/> type.
/// </summary>
public static class ColorHSVAExtensions
{
/// <inheritdoc cref="ColorHSVA.Add(ColorHSVA, ColorHSVA)" />
public static ColorHSVA Add(this ColorHSVA color, ColorHSVA value) => ColorHSVA.Add(color, value);
/// <inheritdoc cref="ColorHSVA.Subtract(ColorHSVA, ColorHSVA)" />
public static ColorHSVA Subtract(this ColorHSVA color, ColorHSVA value) => ColorHSVA.Subtract(color, value);
/// <inheritdoc cref="ColorHSVA.Multiply(ColorHSVA, ColorHSVA)" />
public static ColorHSVA Multiply(this ColorHSVA color, float value) => ColorHSVA.Multiply(color, value);
/// <inheritdoc cref="ColorHSVA.Divide(ColorHSVA, ColorHSVA)" />
public static ColorHSVA Divide(this ColorHSVA color, float value) => ColorHSVA.Divide(color, value);
/// <inheritdoc cref="ColorHSVA.Lerp(ColorHSVA, ColorHSVA, float)" />
public static ColorHSVA Lerp(this ColorHSVA from, ColorHSVA to, float t) => ColorHSVA.Lerp(from, to, t);
/// <inheritdoc cref="ColorHSVA.ApproximatelyEquals(ColorHSVA, ColorHSVA, float) " />
public static bool ApproximatelyEquals(this ColorHSVA left, ColorHSVA right, float epsilon = float.Epsilon) => ColorHSVA.ApproximatelyEquals(left, right, epsilon);
}

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents an RGB color. /// Represents an RGB color.
@ -38,8 +38,30 @@ 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 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(ColorRGBA rgba) => new(rgba.R, rgba.G, rgba.B);
public static implicit operator ColorRGB(ColorHSVA hsva) => (ColorRGBA)hsva; public static implicit operator ColorRGB(ColorHSV hsv)
public static implicit operator ColorRGB(ColorHSV hsv) => (ColorRGBA)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);
}
/// <summary> /// <summary>
/// Inverts the given <see cref="ColorRGB"/>. /// Inverts the given <see cref="ColorRGB"/>.
@ -80,6 +102,14 @@ public readonly struct ColorRGB(byte r, byte g, byte b)
/// <returns>The result of dividing the <see cref="ColorRGB"/> by the scalar value.</returns> /// <returns>The result of dividing the <see cref="ColorRGB"/> by the scalar value.</returns>
public static ColorRGB Divide(ColorRGB color, float value) => color / value; public static ColorRGB Divide(ColorRGB color, float value) => color / value;
/// <summary>
/// Calculates the <see cref="ColorRGB"/> from one point to another.
/// </summary>
/// <param name="from">The starting point.</param>
/// <param name="to">The ending point.</param>
/// <returns>The <see cref="ColorRGB"/> from the starting point to the ending point.</returns>
public static ColorRGB FromTo(ColorRGB from, ColorRGB to) => to - from;
/// <summary> /// <summary>
/// Performs linear interpolation between two <see cref="ColorRGB"/>s. /// Performs linear interpolation between two <see cref="ColorRGB"/>s.
/// </summary> /// </summary>
@ -87,33 +117,26 @@ public readonly struct ColorRGB(byte r, byte g, byte b)
/// <param name="to">The ending <see cref="ColorRGB"/> (t = 1).</param> /// <param name="to">The ending <see cref="ColorRGB"/> (t = 1).</param>
/// <param name="t">The interpolation parameter.</param> /// <param name="t">The interpolation parameter.</param>
/// <returns>The interpolated <see cref="ColorRGB"/>.</returns> /// <returns>The interpolated <see cref="ColorRGB"/>.</returns>
public static ColorRGB Lerp(ColorRGB from, ColorRGB to, float t) public static ColorRGB Lerp(ColorRGB from, ColorRGB to, float t) => from + FromTo(from, to) * 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));
}
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="ColorRGB"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="ColorRGB"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorRGB"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is ColorRGB colorRGB && this == colorRGB;
/// <summary>
/// Generates a hash code for the <see cref="ColorRGB"/>.
/// </summary>
/// <returns>A hash code for the <see cref="ColorRGB"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(R, G, B);
/// <summary> /// <summary>
/// Converts the <see cref="ColorRGB"/> to its string representation. /// Converts the <see cref="ColorRGB"/> to its string representation.
/// </summary> /// </summary>
/// <returns>A string representation of the <see cref="ColorRGB"/>.</returns> /// <returns>A string representation of the <see cref="ColorRGB"/>.</returns>
public override string ToString() => $"{nameof(ColorRGB)}({R}, {G}, {B})"; public override string ToString() => $"{nameof(ColorRGB)}({R}, {G}, {B})";
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="ColorRGB"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="ColorRGB"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorRGB"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is ColorRGB objVec && R.Equals(objVec.R) && G.Equals(objVec.G) && B.Equals(objVec.B);
/// <summary>
/// Generates a hash code for the <see cref="ColorRGB"/>.
/// </summary>
/// <returns>A hash code for the <see cref="ColorRGB"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(R, G, B);
} }
/// <summary> /// <summary>
@ -133,6 +156,9 @@ public static class ColorRGBExtensions
/// <inheritdoc cref="ColorRGB.Divide(ColorRGB, ColorRGB)" /> /// <inheritdoc cref="ColorRGB.Divide(ColorRGB, ColorRGB)" />
public static ColorRGB Divide(this ColorRGB color, float value) => ColorRGB.Divide(color, value); public static ColorRGB Divide(this ColorRGB color, float value) => ColorRGB.Divide(color, value);
/// <inheritdoc cref="ColorRGB.FromTo(ColorRGB, ColorRGB)" />
public static ColorRGB FromTo(this ColorRGB from, ColorRGB to) => ColorRGB.FromTo(from, to);
/// <inheritdoc cref="ColorRGB.Lerp(ColorRGB, ColorRGB, float)" /> /// <inheritdoc cref="ColorRGB.Lerp(ColorRGB, ColorRGB, float)" />
public static ColorRGB Lerp(this ColorRGB from, ColorRGB to, float t) => ColorRGB.Lerp(from, to, t); public static ColorRGB Lerp(this ColorRGB from, ColorRGB to, float t) => ColorRGB.Lerp(from, to, t);
} }

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents an RGBA color. /// Represents an RGBA color.
@ -44,31 +44,7 @@ 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 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(ColorRGB rgb) => new(rgb.R, rgb.G, rgb.B, 255);
public static implicit operator ColorRGBA(ColorHSV hsv) => (ColorHSVA)hsv; public static implicit operator ColorRGBA(ColorHSV hsv) => (ColorRGB)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));
}
/// <summary> /// <summary>
/// Inverts the given <see cref="ColorRGBA"/>. /// Inverts the given <see cref="ColorRGBA"/>.
@ -109,6 +85,14 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255)
/// <returns>The result of dividing the <see cref="ColorRGBA"/> by the scalar value.</returns> /// <returns>The result of dividing the <see cref="ColorRGBA"/> by the scalar value.</returns>
public static ColorRGBA Divide(ColorRGBA color, float value) => color / value; public static ColorRGBA Divide(ColorRGBA color, float value) => color / value;
/// <summary>
/// Calculates the <see cref="ColorRGBA"/> from one point to another.
/// </summary>
/// <param name="from">The starting point.</param>
/// <param name="to">The ending point.</param>
/// <returns>The <see cref="ColorRGBA"/> from the starting point to the ending point.</returns>
public static ColorRGBA FromTo(ColorRGBA from, ColorRGBA to) => to - from;
/// <summary> /// <summary>
/// Performs linear interpolation between two <see cref="ColorRGBA"/>s. /// Performs linear interpolation between two <see cref="ColorRGBA"/>s.
/// </summary> /// </summary>
@ -116,34 +100,26 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255)
/// <param name="to">The ending <see cref="ColorRGBA"/> (t = 1).</param> /// <param name="to">The ending <see cref="ColorRGBA"/> (t = 1).</param>
/// <param name="t">The interpolation parameter.</param> /// <param name="t">The interpolation parameter.</param>
/// <returns>The interpolated <see cref="ColorRGBA"/>.</returns> /// <returns>The interpolated <see cref="ColorRGBA"/>.</returns>
public static ColorRGBA Lerp(ColorRGBA from, ColorRGBA to, float t) public static ColorRGBA Lerp(ColorRGBA from, ColorRGBA to, float t) => from + FromTo(from, to) * 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));
}
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="ColorRGBA"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="ColorRGBA"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorRGBA"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is ColorRGBA colorRGBA && this == colorRGBA;
/// <summary>
/// Generates a hash code for the <see cref="ColorRGBA"/>.
/// </summary>
/// <returns>A hash code for the <see cref="ColorRGBA"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(R, G, B, A);
/// <summary> /// <summary>
/// Converts the <see cref="ColorRGBA"/> to its string representation. /// Converts the <see cref="ColorRGBA"/> to its string representation.
/// </summary> /// </summary>
/// <returns>A string representation of the <see cref="ColorRGBA"/>.</returns> /// <returns>A string representation of the <see cref="ColorRGBA"/>.</returns>
public override string ToString() => $"{nameof(ColorRGBA)}({R}, {G}, {B}, {A})"; public override string ToString() => $"{nameof(ColorRGBA)}({R}, {G}, {B}, {A})";
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="ColorRGBA"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="ColorRGBA"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorRGBA"/>; otherwise, <see cref="false"/>.</returns>
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);
/// <summary>
/// Generates a hash code for the <see cref="ColorRGBA"/>.
/// </summary>
/// <returns>A hash code for the <see cref="ColorRGBA"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(R, G, B, A);
} }
/// <summary> /// <summary>
@ -163,6 +139,9 @@ public static class ColorRGBAExtensions
/// <inheritdoc cref="ColorRGBA.Divide(ColorRGBA, ColorRGBA)" /> /// <inheritdoc cref="ColorRGBA.Divide(ColorRGBA, ColorRGBA)" />
public static ColorRGBA Divide(this ColorRGBA color, float value) => ColorRGBA.Divide(color, value); public static ColorRGBA Divide(this ColorRGBA color, float value) => ColorRGBA.Divide(color, value);
/// <inheritdoc cref="ColorRGBA.FromTo(ColorRGBA, ColorRGBA)" />
public static ColorRGBA FromTo(this ColorRGBA from, ColorRGBA to) => ColorRGBA.FromTo(from, to);
/// <inheritdoc cref="ColorRGBA.Lerp(ColorRGBA, ColorRGBA, float)" /> /// <inheritdoc cref="ColorRGBA.Lerp(ColorRGBA, ColorRGBA, float)" />
public static ColorRGBA Lerp(this ColorRGBA from, ColorRGBA to, float t) => ColorRGBA.Lerp(from, to, t); public static ColorRGBA Lerp(this ColorRGBA from, ColorRGBA to, float t) => ColorRGBA.Lerp(from, to, t);
} }

View File

@ -1,6 +1,6 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a 2D line segment defined by two endpoints. /// Represents a 2D line segment defined by two endpoints.
@ -43,9 +43,6 @@ public readonly struct Line2D(Vector2D from, Vector2D to)
/// </summary> /// </summary>
public readonly float LengthSquared => From.FromTo(To).LengthSquared(); 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;
/// <summary> /// <summary>
/// The equation of the <see cref="Line2D"/> defined by this <see cref="Line2D"/> segment. /// The equation of the <see cref="Line2D"/> defined by this <see cref="Line2D"/> segment.
/// </summary> /// </summary>
@ -189,25 +186,6 @@ public readonly struct Line2D(Vector2D from, Vector2D to)
/// <returns><see cref="true"/> if the <see cref="Line2D"/>s are approximately equal; otherwise, <see cref="false"/>.</returns> /// <returns><see cref="true"/> if the <see cref="Line2D"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
public static bool ApproximatelyEquals(Line2D left, Line2D right, float epsilon = float.Epsilon) public static bool ApproximatelyEquals(Line2D left, Line2D right, float epsilon = float.Epsilon)
=> left.From.ApproximatelyEquals(right.From, epsilon) && left.To.ApproximatelyEquals(right.To, epsilon); => left.From.ApproximatelyEquals(right.From, epsilon) && left.To.ApproximatelyEquals(right.To, epsilon);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="Line2D"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="Line2D"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Line2D"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Line2D line2D && this == line2D;
/// <summary>
/// Generates a hash code for the <see cref="Line2D"/>.
/// </summary>
/// <returns>A hash code for the <see cref="Line2D"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(From, To);
/// <summary>
/// Converts the <see cref="Line2D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Line2D"/>.</returns>
public override string ToString() => $"{nameof(Line2D)}({From}, {To})";
} }
/// <summary> /// <summary>

View File

@ -1,69 +1,47 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a <see cref="Line2DEquation"/> in the form y = mx + b. /// Represents a line equation in the form y = mx + b.
/// </summary> /// </summary>
/// <param name="slope">The slope of the line.</param> /// <param name="slope">The slope of the line.</param>
/// <param name="offsetY">The Y intercept of the line.</param> /// <param name="offsetY">The y-intercept of the line.</param>
/// <remarks> /// <remarks>
/// Initializes a new instance of the <see cref="Line2DEquation"/> struct with the specified slope and Y intercept. /// Initializes a new instance of the <see cref="Line2DEquation"/> struct with the specified slope and y-intercept.
/// </remarks> /// </remarks>
[System.Diagnostics.DebuggerDisplay("y = {Slope}x + {OffsetY}")] [System.Diagnostics.DebuggerDisplay("y = {Slope}x + {OffsetY}")]
public readonly struct Line2DEquation(float slope, float offsetY) public readonly struct Line2DEquation(float slope, float offsetY)
{ {
/// <summary> /// <summary>
/// The slope of the <see cref="Line2DEquation"/>. /// The slope of the line equation.
/// </summary> /// </summary>
public readonly float Slope = slope; public readonly float Slope = slope;
/// <summary> /// <summary>
/// The Y intercept of the <see cref="Line2DEquation"/>. /// The y-intercept of the line equation.
/// </summary> /// </summary>
public readonly float OffsetY = 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;
/// <summary> /// <summary>
/// Resolves the Y coordinate for a given X coordinate using the <see cref="Line2DEquation"/>. /// Resolves the y-coordinate for a given x-coordinate using the line equation.
/// </summary> /// </summary>
/// <param name="lineEquation">The <see cref="Line2DEquation"/> to resolve.</param> /// <param name="lineEquation">The line equation to resolve.</param>
/// <param name="x">The X coordinate for which to resolve the Y coordinate.</param> /// <param name="x">The x-coordinate for which to resolve the y-coordinate.</param>
/// <returns>The Y coordinate resolved using the <see cref="Line2DEquation"/>.</returns> /// <returns>The y-coordinate resolved using the line equation.</returns>
public static float Resolve(Line2DEquation lineEquation, float x) => lineEquation.Slope * x + lineEquation.OffsetY; // y = mx + b public static float Resolve(Line2DEquation lineEquation, float x) => lineEquation.Slope * x + lineEquation.OffsetY; // y = mx + b
/// <summary> /// <summary>
/// Checks if two <see cref="Line2DEquation"/> are approximately equal. /// Checks if two line equations are approximately equal.
/// </summary> /// </summary>
/// <param name="left">The first <see cref="Line2DEquation"/> to compare.</param> /// <param name="left">The first line equation to compare.</param>
/// <param name="right">The second <see cref="Line2DEquation"/> to compare.</param> /// <param name="right">The second line equation to compare.</param>
/// <param name="epsilon">The epsilon range.</param> /// <param name="epsilon">The epsilon range.</param>
/// <returns>True if the <see cref="Line2DEquation"/> are approximately equal; otherwise, false.</returns> /// <returns>True if the line equations are approximately equal; otherwise, false.</returns>
public static bool ApproximatelyEquals(Line2DEquation left, Line2DEquation right, float epsilon = float.Epsilon) public static bool ApproximatelyEquals(Line2DEquation left, Line2DEquation right, float epsilon = float.Epsilon)
=> left.Slope.ApproximatelyEquals(right.Slope, epsilon) && left.OffsetY.ApproximatelyEquals(right.OffsetY, epsilon); => left.Slope.ApproximatelyEquals(right.Slope, epsilon) && left.OffsetY.ApproximatelyEquals(right.OffsetY, epsilon);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="Line2DEquation"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="Line2DEquation"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Line2DEquation"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Line2DEquation lineEquation && this == lineEquation;
/// <summary>
/// Generates a hash code for the <see cref="Line2DEquation"/>.
/// </summary>
/// <returns>A hash code for the <see cref="Line2DEquation"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(Slope, OffsetY);
/// <summary>
/// Converts the <see cref="Line2DEquation"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Line2DEquation"/>.</returns>
public override string ToString() => $"{nameof(Line2DEquation)}({Slope}, {OffsetY})";
} }
/// <summary> /// <summary>
/// Provides extension methods for the <see cref="Line2DEquation"/> struct. /// Provides extension methods for the LineEquation struct.
/// </summary> /// </summary>
public static class Line2DEquationExtensions public static class Line2DEquationExtensions
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a range of values along a single axis. /// Represents a range of values along a single axis.
@ -21,9 +21,6 @@ public readonly struct Projection1D(float min, float max)
/// </summary> /// </summary>
public readonly float Max = 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;
/// <summary> /// <summary>
/// Checks if two projections overlap. /// Checks if two projections overlap.
/// </summary> /// </summary>
@ -73,35 +70,6 @@ public readonly struct Projection1D(float min, float max)
depth = 0f; depth = 0f;
return false; return false;
} }
/// <summary>
/// Checks if two <see cref="Projection1D"/>s are approximately equal within a specified epsilon range.
/// </summary>
/// <param name="left">The first <see cref="Projection1D"/>.</param>
/// <param name="right">The second <see cref="Projection1D"/>.</param>
/// <param name="epsilon">The epsilon range.</param>
/// <returns><see cref="true"/> if the <see cref="Projection1D"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
public static bool ApproximatelyEquals(Projection1D left, Projection1D right, float epsilon = float.Epsilon)
=> left.Min.ApproximatelyEquals(right.Min, epsilon) && left.Max.ApproximatelyEquals(right.Max, epsilon);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="Projection1D"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="Projection1D"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Projection1D"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Projection1D projection1D && this == projection1D;
/// <summary>
/// Generates a hash code for the <see cref="Projection1D"/>.
/// </summary>
/// <returns>A hash code for the <see cref="Projection1D"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(Min, Max);
/// <summary>
/// Converts the <see cref="Projection1D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Projection1D"/>.</returns>
public override string ToString() => $"{nameof(Projection1D)}({Min}, {Max})";
} }
/// <summary> /// <summary>
@ -114,7 +82,4 @@ public static class Projection1DExtensions
/// <inheritdoc cref="Projection1D.Overlaps(Projection1D, Projection1D, out float)" /> /// <inheritdoc cref="Projection1D.Overlaps(Projection1D, Projection1D, out float)" />
public static bool Overlaps(this Projection1D left, Projection1D right, out float depth) => Projection1D.Overlaps(left, right, out depth); public static bool Overlaps(this Projection1D left, Projection1D right, out float depth) => Projection1D.Overlaps(left, right, out depth);
/// <inheritdoc cref="Projection1D.ApproximatelyEquals(Projection1D, Projection1D, float)" />
public static bool ApproximatelyEquals(this Projection1D left, Projection1D right, float epsilon = float.Epsilon) => Projection1D.ApproximatelyEquals(left, right, epsilon);
} }

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a 3D space rotation. /// Represents a 3D space rotation.
@ -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) 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); => left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon) && left.Z.ApproximatelyEquals(right.Z, epsilon) && left.W.ApproximatelyEquals(right.W, epsilon);
/// <summary>
/// Converts the <see cref="Quaternion"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Quaternion"/>.</returns>
public override string ToString() => $"{nameof(Quaternion)}({W}, {X}, {Y}, {Z})";
/// <summary> /// <summary>
/// Determines whether the specified object is equal to the current <see cref="Quaternion"/>. /// Determines whether the specified object is equal to the current <see cref="Quaternion"/>.
/// </summary> /// </summary>
/// <param name="obj">The object to compare with the current <see cref="Quaternion"/>.</param> /// <param name="obj">The object to compare with the current <see cref="Quaternion"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Quaternion"/>; otherwise, <see cref="false"/>.</returns> /// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Quaternion"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Quaternion quaternion && this == quaternion; 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);
/// <summary> /// <summary>
/// Generates a hash code for the <see cref="Quaternion"/>. /// Generates a hash code for the <see cref="Quaternion"/>.
/// </summary> /// </summary>
/// <returns>A hash code for the <see cref="Quaternion"/>.</returns> /// <returns>A hash code for the <see cref="Quaternion"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(W, X, Y, Z); public override int GetHashCode() => System.HashCode.Combine(X, Y, Z);
/// <summary>
/// Converts the <see cref="Quaternion"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Quaternion"/>.</returns>
public override string ToString() => $"{nameof(Quaternion)}({W}, {X}, {Y}, {Z})";
} }
/// <summary> /// <summary>

View File

@ -1,10 +1,5 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary>
/// Represents an infinite ray in 2D space.
/// </summary>
/// <param name="Origin">The <see cref="Vector2D"/> in 2D space where the ray starts from.</param>
/// <param name="Direction">Normalized <see cref="Vector2D"/> indicating the ray's is direction.</param>
public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) public readonly struct Ray2D(Vector2D Origin, Vector2D Direction)
{ {
/// <summary> /// <summary>
@ -22,8 +17,6 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction)
/// </summary> /// </summary>
public readonly Ray2D Reversed => new(Origin, -Direction); public readonly Ray2D Reversed => new(Origin, -Direction);
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); public static implicit operator Ray2D(Line2D line) => new(line.From, line.From.FromTo(line.To).Normalized);
/// <summary> /// <summary>
@ -55,35 +48,6 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction)
return ray.Origin + ray.Direction * dot; return ray.Origin + ray.Direction * dot;
} }
/// <summary>
/// Checks if two <see cref="Ray2D"/>s are approximately equal within a specified epsilon range.
/// </summary>
/// <param name="left">The first <see cref="Ray2D"/>.</param>
/// <param name="right">The second <see cref="Ray2D"/>.</param>
/// <param name="epsilon">The epsilon range.</param>
/// <returns><see cref="true"/> if the <see cref="Ray2D"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
public static bool ApproximatelyEquals(Ray2D left, Ray2D right, float epsilon = float.Epsilon)
=> left.Origin.ApproximatelyEquals(right.Origin, epsilon) && left.Direction.ApproximatelyEquals(right.Direction, epsilon);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="Ray2D"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="Ray2D"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Ray2D"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Ray2D ray2D && this == ray2D;
/// <summary>
/// Generates a hash code for the <see cref="Ray2D"/>.
/// </summary>
/// <returns>A hash code for the <see cref="Ray2D"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(Origin, Direction);
/// <summary>
/// Converts the <see cref="Ray2D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Ray2D"/>.</returns>
public override string ToString() => $"{nameof(Ray2D)}({Origin}, {Direction})";
} }
/// <summary> /// <summary>
@ -99,7 +63,4 @@ public static class Ray2DExtensions
/// <inheritdoc cref="Ray2D.ClosestPointTo(Ray2D, Vector2D) /> /// <inheritdoc cref="Ray2D.ClosestPointTo(Ray2D, Vector2D) />
public static Vector2D ClosestPointTo(this Ray2D ray, Vector2D point) => Ray2D.ClosestPointTo(ray, point); public static Vector2D ClosestPointTo(this Ray2D ray, Vector2D point) => Ray2D.ClosestPointTo(ray, point);
/// <inheritdoc cref="Ray2D.ApproximatelyEquals(Ray2D, Ray2D, float)" />
public static bool ApproximatelyEquals(this Ray2D left, Ray2D right, float epsilon = float.Epsilon) => Ray2D.ApproximatelyEquals(left, right, epsilon);
} }

View File

@ -1,7 +1,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a shape defined by a collection of vertices. /// Represents a shape defined by a collection of vertices.
@ -122,7 +122,7 @@ public class Shape2D(List<Vector2D> vertices) : IEnumerable<Vector2D>
triangles.Clear(); triangles.Clear();
for (int i = 2; i < shape.Vertices.Count; i++) for (int i = 2; i < shape.Vertices.Count; i++)
triangles.Add(new Triangle(shape[0], shape[i], shape[i - 1])); triangles.Add(new Triangle(shape[0], shape[i - 1], shape[i]));
} }
/// <summary> /// <summary>
@ -251,34 +251,6 @@ public class Shape2D(List<Vector2D> vertices) : IEnumerable<Vector2D>
return true; return true;
} }
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="Shape2D"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="Shape2D"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Shape2D"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Shape2D shape2D && _vertices.Equals(shape2D._vertices);
/// <summary>
/// Generates a hash code for the <see cref="Shape2D"/>.
/// </summary>
/// <returns>A hash code for the <see cref="Shape2D"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(Vertices);
/// <summary>
/// Converts the <see cref="Shape2D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Shape2D"/>.</returns>
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})";
}
/// <inheritdoc/> /// <inheritdoc/>
public IEnumerator<Vector2D> GetEnumerator() => Vertices.GetEnumerator(); public IEnumerator<Vector2D> GetEnumerator() => Vertices.GetEnumerator();
@ -298,7 +270,7 @@ public static class Shape2DExtensions
public static Triangle ToSuperTriangle(this Shape2D shape) => Shape2D.GetSuperTriangle(shape); public static Triangle ToSuperTriangle(this Shape2D shape) => Shape2D.GetSuperTriangle(shape);
/// <inheritdoc cref="Shape2D.TriangulateConvex(Shape2D, IList{Triangle})" /> /// <inheritdoc cref="Shape2D.TriangulateConvex(Shape2D, IList{Triangle})" />
public static void ToTrianglesConvex(this Shape2D shape, IList<Triangle> triangles) => Shape2D.TriangulateConvex(shape, triangles); public static void ToTrianglesConvex(this Shape2D shape, IList<Triangle> lines) => Shape2D.TriangulateConvex(shape, lines);
/// <inheritdoc cref="Shape2D.TriangulateConvex(Shape2D)" /> /// <inheritdoc cref="Shape2D.TriangulateConvex(Shape2D)" />
public static List<Triangle> ToTrianglesConvex(this Shape2D shape) => Shape2D.TriangulateConvex(shape); public static List<Triangle> ToTrianglesConvex(this Shape2D shape) => Shape2D.TriangulateConvex(shape);

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("A: {A.ToString(), nq}, B: {B.ToString(), nq}, B: {C.ToString(), nq}")] [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)
@ -7,9 +7,6 @@ public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C)
public readonly Vector2D B { get; init; } = B; public readonly Vector2D B { get; init; } = B;
public readonly Vector2D C { get; init; } = C; 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 public readonly float Area
=> .5f * Math.Abs( => .5f * Math.Abs(
A.X * (B.Y - C.Y) + A.X * (B.Y - C.Y) +
@ -47,25 +44,6 @@ public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C)
/// <returns><c>true</c> if the <see cref="Triangle"/>s are approximately equal; otherwise, <c>false</c>.</returns> /// <returns><c>true</c> if the <see cref="Triangle"/>s are approximately equal; otherwise, <c>false</c>.</returns>
public static bool ApproximatelyEquals(Triangle left, Triangle right, float epsilon = float.Epsilon) 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); => left.A.ApproximatelyEquals(right.A, epsilon) && left.B.ApproximatelyEquals(right.B, epsilon) && left.C.ApproximatelyEquals(right.C, epsilon);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="Triangle"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="Triangle"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Triangle"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Triangle triangle && this == triangle;
/// <summary>
/// Generates a hash code for the <see cref="Triangle"/>.
/// </summary>
/// <returns>A hash code for the <see cref="Triangle"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(A, B, C);
/// <summary>
/// Converts the <see cref="Triangle"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Triangle"/>.</returns>
public override string ToString() => $"{nameof(Triangle)}({A}, {B}, {C})";
} }
public static class TriangleExtensions public static class TriangleExtensions

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a two-dimensional vector. /// Represents a two-dimensional vector.
@ -302,24 +302,24 @@ public readonly struct Vector2D(float x, float y)
public static bool ApproximatelyEquals(Vector2D left, Vector2D right, float epsilon = float.Epsilon) public static bool ApproximatelyEquals(Vector2D left, Vector2D right, float epsilon = float.Epsilon)
=> left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon); => left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon);
/// <summary>
/// Converts the <see cref="Vector2D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Vector2D"/>.</returns>
public override string ToString() => $"{nameof(Vector2D)}({X}, {Y})";
/// <summary> /// <summary>
/// Determines whether the specified object is equal to the current <see cref="Vector2D"/>. /// Determines whether the specified object is equal to the current <see cref="Vector2D"/>.
/// </summary> /// </summary>
/// <param name="obj">The object to compare with the current <see cref="Vector2D"/>.</param> /// <param name="obj">The object to compare with the current <see cref="Vector2D"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector2D"/>; otherwise, <see cref="false"/>.</returns> /// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector2D"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Vector2D vector2D && this == vector2D; public override bool Equals(object? obj) => obj is Vector2D objVec && X.Equals(objVec.X) && Y.Equals(objVec.Y);
/// <summary> /// <summary>
/// Generates a hash code for the <see cref="Vector2D"/>. /// Generates a hash code for the <see cref="Vector2D"/>.
/// </summary> /// </summary>
/// <returns>A hash code for the <see cref="Vector2D"/>.</returns> /// <returns>A hash code for the <see cref="Vector2D"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(X, Y); public override int GetHashCode() => System.HashCode.Combine(X, Y);
/// <summary>
/// Converts the <see cref="Vector2D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Vector2D"/>.</returns>
public override string ToString() => $"{nameof(Vector2D)}({X}, {Y})";
} }
/// <summary> /// <summary>

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a three-dimensional vector. /// Represents a three-dimensional vector.
@ -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) 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); => left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon) && left.Z.ApproximatelyEquals(right.Z, epsilon);
/// <summary>
/// Converts the <see cref="Vector3D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Vector3D"/>.</returns>
public override string ToString() => $"{nameof(Vector3D)}({X}, {Y}, {Z})";
/// <summary> /// <summary>
/// Determines whether the specified object is equal to the current <see cref="Vector3D"/>. /// Determines whether the specified object is equal to the current <see cref="Vector3D"/>.
/// </summary> /// </summary>
/// <param name="obj">The object to compare with the current <see cref="Vector3D"/>.</param> /// <param name="obj">The object to compare with the current <see cref="Vector3D"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector3D"/>; otherwise, <see cref="false"/>.</returns> /// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector3D"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Vector3D vector3D && this == vector3D; public override bool Equals(object? obj) => obj is Vector3D objVec && X.Equals(objVec.X) && Y.Equals(objVec.Y) && Z.Equals(objVec.Z);
/// <summary> /// <summary>
/// Generates a hash code for the <see cref="Vector3D"/>. /// Generates a hash code for the <see cref="Vector3D"/>.
/// </summary> /// </summary>
/// <returns>A hash code for the <see cref="Vector3D"/>.</returns> /// <returns>A hash code for the <see cref="Vector3D"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(X, Y, Z); public override int GetHashCode() => System.HashCode.Combine(X, Y, Z);
/// <summary>
/// Converts the <see cref="Vector3D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Vector3D"/>.</returns>
public override string ToString() => $"{nameof(Vector3D)}({X}, {Y}, {Z})";
} }
/// <summary> /// <summary>

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)]
public class IgnoreSerializationAttribute : Attribute; public class IgnoreSerializationAttribute : Attribute;

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class SerializeAllAttribute : Attribute; public class SerializeAllAttribute : Attribute;

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class SerializeAttribute : Attribute; public class SerializeAttribute : Attribute;

View File

@ -1,3 +1,3 @@
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
public record class EntityReference(string? Id = null); public record class EntityReference(string? Id = null);

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
public class EntityRegistry public class EntityRegistry
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
public interface ISerializer public interface ISerializer
{ {

View File

@ -2,9 +2,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using Engine.Core.Factory; using Syntriax.Engine.Core.Factory;
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
public class SerializedClass public class SerializedClass
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
public class TypeContainer public class TypeContainer
{ {

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
namespace Engine.Core.Serialization; namespace Syntriax.Engine.Core.Serialization;
public static class Utils public static class Utils
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
public class StateEnable : IStateEnable public class StateEnable : IStateEnable
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
internal static class Constants internal static class Constants
{ {

View File

@ -1,4 +1,4 @@
namespace Engine.Core; namespace Syntriax.Engine.Core;
/// <summary> /// <summary>
/// Represents a <see cref="IBehaviour"/> to be notified when the draw phase of the <see cref="IUniverse"/> occurs. /// Represents a <see cref="IBehaviour"/> to be notified when the draw phase of the <see cref="IUniverse"/> occurs.

Some files were not shown because too many files have changed in this diff Show More