Compare commits
No commits in common. "development" and "main" have entirely different histories.
developmen
...
main
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,7 +10,7 @@ public interface IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IAssignable"/>'s fields are unassigned and completely ready to recycle.
|
/// Event triggered when the <see cref="IAssignable"/>'s fields are unassigned and completely ready to recycle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnUnassignedEventHandler? OnUnassigned;
|
Action<IAssignable>? OnUnassigned { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unassign <see cref="IAssignable"/>'s all fields and make it ready to recycle.
|
/// Unassign <see cref="IAssignable"/>'s all fields and make it ready to recycle.
|
||||||
@ -17,6 +19,4 @@ public interface IAssignable
|
|||||||
/// <see cref="true"/>, if the fields are unsigned successfully, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the fields are unsigned successfully, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Unassign();
|
bool Unassign();
|
||||||
|
|
||||||
delegate void OnUnassignedEventHandler(IAssignable sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,7 +10,7 @@ public interface IAssignableBehaviourController : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IBehaviourController"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IBehaviourController"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnBehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned;
|
Action<IAssignableBehaviourController>? OnBehaviourControllerAssigned { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IBehaviourController" />
|
/// <inheritdoc cref="IBehaviourController" />
|
||||||
IBehaviourController BehaviourController { get; }
|
IBehaviourController BehaviourController { get; }
|
||||||
@ -21,6 +23,4 @@ public interface IAssignableBehaviourController : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IBehaviourController behaviourController);
|
bool Assign(IBehaviourController behaviourController);
|
||||||
|
|
||||||
delegate void OnBehaviourControllerAssignedEventHandler(IAssignableBehaviourController sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,7 +10,7 @@ public interface IAssignableEntity : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IEntity"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IEntity"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnEntityAssignedEventHandler? OnEntityAssigned;
|
Action<IAssignableEntity>? OnEntityAssigned { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IEntity" />
|
/// <inheritdoc cref="IEntity" />
|
||||||
IEntity Entity { get; }
|
IEntity Entity { get; }
|
||||||
@ -21,6 +23,4 @@ public interface IAssignableEntity : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IEntity entity);
|
bool Assign(IEntity entity);
|
||||||
|
|
||||||
delegate void OnEntityAssignedEventHandler(IAssignableEntity sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,7 +10,7 @@ public interface IAssignableGameManager : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IGameManager"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IGameManager"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnGameManagerAssignedEventHandler? OnGameManagerAssigned;
|
Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IGameManager" />
|
/// <inheritdoc cref="IGameManager" />
|
||||||
IGameManager GameManager { get; }
|
IGameManager GameManager { get; }
|
||||||
@ -21,6 +23,4 @@ public interface IAssignableGameManager : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IGameManager gameManager);
|
bool Assign(IGameManager gameManager);
|
||||||
|
|
||||||
delegate void OnGameManagerAssignedEventHandler(IAssignableGameManager sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,7 +10,7 @@ public interface IAssignableGameObject : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IGameObject"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IGameObject"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnGameObjectAssignedEventHandler? OnGameObjectAssigned;
|
Action<IAssignableGameObject>? OnGameObjectAssigned { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IGameObject" />
|
/// <inheritdoc cref="IGameObject" />
|
||||||
IGameObject GameObject { get; }
|
IGameObject GameObject { get; }
|
||||||
@ -21,6 +23,4 @@ public interface IAssignableGameObject : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IGameObject gameObject);
|
bool Assign(IGameObject gameObject);
|
||||||
|
|
||||||
delegate void OnGameObjectAssignedEventHandler(IAssignableGameObject sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,7 +10,7 @@ public interface IAssignableStateEnable : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IStateEnable"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IStateEnable"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnStateEnableAssignedEventHandler? OnStateEnableAssigned;
|
Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IStateEnable" />
|
/// <inheritdoc cref="IStateEnable" />
|
||||||
IStateEnable StateEnable { get; }
|
IStateEnable StateEnable { get; }
|
||||||
@ -21,6 +23,4 @@ public interface IAssignableStateEnable : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IStateEnable stateEnable);
|
bool Assign(IStateEnable stateEnable);
|
||||||
|
|
||||||
delegate void OnStateEnableAssignedEventHandler(IAssignableStateEnable sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,7 +10,7 @@ public interface IAssignableTransform : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="ITransform"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="ITransform"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnTransformAssignedEventHandler? OnTransformAssigned;
|
Action<IAssignableTransform>? OnTransformAssigned { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="ITransform" />
|
/// <inheritdoc cref="ITransform" />
|
||||||
ITransform Transform { get; }
|
ITransform Transform { get; }
|
||||||
@ -21,6 +23,4 @@ public interface IAssignableTransform : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(ITransform transform);
|
bool Assign(ITransform transform);
|
||||||
|
|
||||||
delegate void OnTransformAssignedEventHandler(IAssignableTransform sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
namespace Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents an <see cref="IEntity"/> that can enter and exit a hierarchy within the <see cref="IGameManager"/> system.
|
|
||||||
/// This interface allows for tracking the object's presence in the hierarchy and provides events
|
|
||||||
/// for notifying when the see enters or exits the hierarchy.
|
|
||||||
/// </summary>
|
|
||||||
public interface IHierarchyObject : IEntity, INameable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when the <see cref="IEntity"/> enters the hierarchy.
|
|
||||||
/// </summary>
|
|
||||||
event OnEnteredHierarchyEventHandler? OnEnteredHierarchy;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when the <see cref="IEntity"/> exits the hierarchy.
|
|
||||||
/// </summary>
|
|
||||||
event OnExitedHierarchyEventHandler? OnExitedHierarchy;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="IGameManager"/> associated with this <see cref="IEntity"/> , if any.
|
|
||||||
/// </summary>
|
|
||||||
IGameManager GameManager { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates whether the <see cref="IEntity"/> is currently in the hierarchy.
|
|
||||||
/// </summary>
|
|
||||||
bool IsInHierarchy { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Internal method to handle entering the hierarchy.
|
|
||||||
/// This should be called by the system to properly manage hierarchy states.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="gameManager">The game manager that is managing this hierarchy.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <see cref="true"/> if the <see cref="IEntity"/> successfully entered the hierarchy;
|
|
||||||
/// <see cref="false"/> if it failed to do so.
|
|
||||||
/// </returns>
|
|
||||||
internal bool EnterHierarchy(IGameManager gameManager);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Internal method to handle exiting the hierarchy.
|
|
||||||
/// This should be called by the system to properly manage hierarchy states.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// <see cref="true"/> if the <see cref="IEntity"/> successfully exited the hierarchy;
|
|
||||||
/// <see cref="false"/> if it failed to do so.
|
|
||||||
/// </returns>
|
|
||||||
internal bool ExitHierarchy();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EventHandler delegate for the event triggered when the <see cref="IEntity"/> enters the hierarchy of a <see cref="IGameManager">.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">The <see cref="IEntity"/> that entered the hierarchy.</param>
|
|
||||||
/// <param name="gameManager">The <see cref="IGameManager"/> that the <see cref="IEntity"/> has entered it's hierarchy.</param>
|
|
||||||
delegate void OnEnteredHierarchyEventHandler(IHierarchyObject sender, IGameManager gameManager);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EventHandler delegate for the event triggered when the <see cref="IEntity"/> exits the hierarchy of a <see cref="IGameManager">.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">The <see cref="IEntity"/> that exited the hierarchy.</param>
|
|
||||||
/// <param name="gameManager">The <see cref="IGameManager"/> that the <see cref="IEntity"/> has exited it's hierarchy.</param>
|
|
||||||
delegate void OnExitedHierarchyEventHandler(IHierarchyObject sender, IGameManager gameManager);
|
|
||||||
}
|
|
@ -1,18 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Exceptions;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
public abstract class BaseEntity : IEntity
|
public abstract class BaseEntity : IEntity
|
||||||
{
|
{
|
||||||
public event IEntity.OnIdChangedEventHandler? OnIdChanged = null;
|
public Action<IEntity, string>? OnIdChanged { get; set; } = null;
|
||||||
|
|
||||||
public event IInitialize.OnInitializedEventHandler? OnInitialized = null;
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
||||||
public event IInitialize.OnFinalizedEventHandler? OnFinalized = null;
|
public Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; } = null;
|
||||||
|
|
||||||
public event IAssignableStateEnable.OnStateEnableAssignedEventHandler? OnStateEnableAssigned = null;
|
public Action<IInitialize>? OnInitialized { get; set; } = null;
|
||||||
public event IAssignable.OnUnassignedEventHandler? OnUnassigned = null;
|
public Action<IInitialize>? OnFinalized { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
private IStateEnable _stateEnable = null!;
|
private IStateEnable _stateEnable = null!;
|
||||||
@ -39,7 +37,7 @@ public abstract class BaseEntity : IEntity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsInitialized
|
public bool Initialized
|
||||||
{
|
{
|
||||||
get => _initialized;
|
get => _initialized;
|
||||||
private set
|
private set
|
||||||
@ -57,7 +55,7 @@ public abstract class BaseEntity : IEntity
|
|||||||
|
|
||||||
public bool Assign(IStateEnable stateEnable)
|
public bool Assign(IStateEnable stateEnable)
|
||||||
{
|
{
|
||||||
if (IsInitialized)
|
if (Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_stateEnable = stateEnable;
|
_stateEnable = stateEnable;
|
||||||
@ -69,13 +67,11 @@ public abstract class BaseEntity : IEntity
|
|||||||
protected virtual void UnassignInternal() { }
|
protected virtual void UnassignInternal() { }
|
||||||
public bool Unassign()
|
public bool Unassign()
|
||||||
{
|
{
|
||||||
if (IsInitialized)
|
if (Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
UnassignInternal();
|
UnassignInternal();
|
||||||
|
|
||||||
_stateEnable = null!;
|
|
||||||
_stateEnable.Unassign();
|
|
||||||
OnUnassigned?.Invoke(this);
|
OnUnassigned?.Invoke(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -83,26 +79,24 @@ public abstract class BaseEntity : IEntity
|
|||||||
protected virtual void InitializeInternal() { }
|
protected virtual void InitializeInternal() { }
|
||||||
public bool Initialize()
|
public bool Initialize()
|
||||||
{
|
{
|
||||||
if (IsInitialized)
|
if (Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NotAssignedException.Check(this, _stateEnable);
|
|
||||||
|
|
||||||
InitializeInternal();
|
InitializeInternal();
|
||||||
|
|
||||||
IsInitialized = true;
|
Initialized = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void FinalizeInternal() { }
|
protected virtual void FinalizeInternal() { }
|
||||||
public bool Finalize()
|
public bool Finalize()
|
||||||
{
|
{
|
||||||
if (!IsInitialized)
|
if (!Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FinalizeInternal();
|
FinalizeInternal();
|
||||||
|
|
||||||
IsInitialized = false;
|
Initialized = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a behaviour that any object in the game might use to interact with itself or other objects.
|
/// Represents a behaviour that any object in the game might use to interact with itself or other objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBehaviour : IEntity, IAssignableBehaviourController, IAssignableStateEnable
|
public interface IBehaviour : IEntity, IAssignableBehaviourController, IAssignableStateEnable, IInitialize
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the priority of the <see cref="IBehaviour"/> changes.
|
/// Event triggered when the priority of the <see cref="IBehaviour"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnPriorityChangedEventHandler? OnPriorityChanged;
|
Action<IBehaviour>? OnPriorityChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The priority of the <see cref="IBehaviour"/>.
|
/// The priority of the <see cref="IBehaviour"/>.
|
||||||
@ -19,6 +21,4 @@ public interface IBehaviour : IEntity, IAssignableBehaviourController, IAssignab
|
|||||||
/// The value indicating whether the <see cref="IBehaviour"/> is active.
|
/// The value indicating whether the <see cref="IBehaviour"/> is active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsActive { get; }
|
bool IsActive { get; }
|
||||||
|
|
||||||
delegate void OnPriorityChangedEventHandler(IBehaviour sender, int previousPriority);
|
|
||||||
}
|
}
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a collector for the class type of <typeparamref name="T"/>.
|
|
||||||
/// Provides mechanisms for tracking additions and removals, and notifies subscribers when such events occur on the assigned <see cref="IGameManager"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of objects tracked by the collector.</typeparam>
|
|
||||||
public interface IBehaviourCollector<T> : IAssignableGameManager, IEnumerable<T> where T : class
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when an object of type <typeparamref name="T"/> is added to the collector.
|
|
||||||
/// </summary>
|
|
||||||
event OnCollectedEventHandler? OnCollected;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when an object of type <typeparamref name="T"/> is removed from the collector.
|
|
||||||
/// </summary>
|
|
||||||
event OnRemovedEventHandler? OnRemoved;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delegate for handling the <see cref="OnCollected"/> event.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">The instance of the <see cref="BehaviourCollector{T}"/> that triggered the event.</param>
|
|
||||||
/// <param name="behaviourCollected">The object of type <typeparamref name="T"/> that was added to the collector.</param>
|
|
||||||
public delegate void OnCollectedEventHandler(BehaviourCollector<T> sender, T behaviourCollected);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delegate for handling the <see cref="OnRemoved"/> event.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">The instance of the <see cref="BehaviourCollector{T}"/> that triggered the event.</param>
|
|
||||||
/// <param name="behaviourRemoved">The object of type <typeparamref name="T"/> that was removed from the collector.</param>
|
|
||||||
public delegate void OnRemovedEventHandler(BehaviourCollector<T> sender, T behaviourRemoved);
|
|
||||||
}
|
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
@ -6,32 +7,32 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a controller for managing <see cref="IBehaviour"/>s and notify them accordingly about the engine's updates. Connected to an <see cref="IGameObject"/>.
|
/// Represents a controller for managing <see cref="IBehaviour"/>s and notify them accordingly about the engine's updates. Connected to an <see cref="IGameObject"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBehaviourController : IInitialize, IAssignableGameObject, IEnumerable<IBehaviour>
|
public interface IBehaviourController : IAssignableGameObject, IEnumerable<IBehaviour>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered before the update of <see cref="IBehaviour"/>s.
|
/// Event triggered before the update of <see cref="IBehaviour"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnPreUpdateEventHandler? OnPreUpdate;
|
Action<IBehaviourController>? OnPreUpdate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered during the update of <see cref="IBehaviour"/>s.
|
/// Event triggered during the update of <see cref="IBehaviour"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnUpdateEventHandler? OnUpdate;
|
Action<IBehaviourController>? OnUpdate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered before the drawing phase.
|
/// Event triggered before the drawing phase.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnPreDrawEventHandler? OnPreDraw;
|
Action<IBehaviourController>? OnPreDraw { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a <see cref="IBehaviour"/> is added to the <see cref="IBehaviourController"/>.
|
/// Event triggered when a <see cref="IBehaviour"/> is added to the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnBehaviourAddedEventHandler? OnBehaviourAdded;
|
Action<IBehaviourController, IBehaviour>? OnBehaviourAdded { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a <see cref="IBehaviour"/> is removed from the <see cref="IBehaviourController"/>.
|
/// Event triggered when a <see cref="IBehaviour"/> is removed from the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnBehaviourRemovedEventHandler? OnBehaviourRemoved;
|
Action<IBehaviourController, IBehaviour>? OnBehaviourRemoved { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="IBehaviour"/> to the <see cref="IBehaviourController"/>.
|
/// Adds a <see cref="IBehaviour"/> to the <see cref="IBehaviourController"/>.
|
||||||
@ -56,6 +57,14 @@ public interface IBehaviourController : IInitialize, IAssignableGameObject, IEnu
|
|||||||
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, <see cref="null"/>.</returns>
|
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, <see cref="null"/>.</returns>
|
||||||
T? GetBehaviour<T>();
|
T? GetBehaviour<T>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to get a <see cref="IBehaviour"/> of the specified type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
|
||||||
|
/// <param name="behaviour">When this method returns, contains the <see cref="IBehaviour"/> of the specified type, if found; otherwise, see.</param>
|
||||||
|
/// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found; otherwise, <see cref="false"/>.</returns>
|
||||||
|
bool TryGetBehaviour<T>([NotNullWhen(returnValue: true)] out T? behaviour);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all <see cref="IBehaviour"/>s of the specified type.
|
/// Gets all <see cref="IBehaviour"/>s of the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -67,8 +76,8 @@ public interface IBehaviourController : IInitialize, IAssignableGameObject, IEnu
|
|||||||
/// Gets all <see cref="IBehaviour"/>s of the specified type and stores them in the provided list.
|
/// Gets all <see cref="IBehaviour"/>s of the specified type and stores them in the provided list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of <see cref="IBehaviour"/>s to get.</typeparam>
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/>s to get.</typeparam>
|
||||||
/// <param name="results">The list to store the <see cref="IBehaviour"/>s.</param>
|
/// <param name="behaviours">The list to store the <see cref="IBehaviour"/>s.</param>
|
||||||
void GetBehaviours<T>(IList<T> results);
|
void GetBehaviours<T>(List<T> behaviours);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes <see cref="IBehaviour"/>s of the specified type from the <see cref="IBehaviourController"/>.
|
/// Removes <see cref="IBehaviour"/>s of the specified type from the <see cref="IBehaviourController"/>.
|
||||||
@ -93,11 +102,4 @@ public interface IBehaviourController : IInitialize, IAssignableGameObject, IEnu
|
|||||||
/// Performs pre-draw operations.
|
/// Performs pre-draw operations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void UpdatePreDraw();
|
void UpdatePreDraw();
|
||||||
|
|
||||||
delegate void OnPreUpdateEventHandler(IBehaviourController sender);
|
|
||||||
delegate void OnUpdateEventHandler(IBehaviourController sender);
|
|
||||||
delegate void OnPreDrawEventHandler(IBehaviourController sender);
|
|
||||||
delegate void OnBehaviourAddedEventHandler(IBehaviourController sender, IBehaviour behaviourAdded);
|
|
||||||
delegate void OnBehaviourRemovedEventHandler(IBehaviourController sender, IBehaviour behaviourRemoved);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
public interface ICoroutineYield
|
|
||||||
{
|
|
||||||
bool Yield();
|
|
||||||
}
|
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -9,12 +11,10 @@ public interface IEntity : IInitialize, IAssignableStateEnable
|
|||||||
/// Event triggered when the <see cref="Id"/> of the <see cref="IEntity"/> changes.
|
/// Event triggered when the <see cref="Id"/> of the <see cref="IEntity"/> changes.
|
||||||
/// The string action parameter is the previous <see cref="Id"/> of the <see cref="IEntity"/>.
|
/// The string action parameter is the previous <see cref="Id"/> of the <see cref="IEntity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnIdChangedEventHandler? OnIdChanged;
|
Action<IEntity, string>? OnIdChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ID of the <see cref="IEntity"/>.
|
/// The ID of the <see cref="IEntity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Id { get; set; }
|
string Id { get; set; }
|
||||||
|
|
||||||
delegate void OnIdChangedEventHandler(IEntity sender, string previousId);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
@ -5,37 +6,17 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a game world responsible for managing <see cref="IGameObject"/>s.
|
/// Represents a game world responsible for managing <see cref="IGameObject"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IGameManager : IEntity
|
public interface IGameManager : IEntity, IEnumerable<IGameObject>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when <see cref="Update(EngineTime)"/> is called on the <see cref="IGameManager"/>.
|
|
||||||
/// </summary>
|
|
||||||
event OnUpdateEventHandler? OnUpdate;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when <see cref="PreDraw"/> is called on the <see cref="IGameManager"/>.
|
|
||||||
/// </summary>
|
|
||||||
event OnPreDawEventHandler? OnPreDraw;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a <see cref="IGameObject"/> is registered to the <see cref="IGameManager"/>.
|
/// Event triggered when a <see cref="IGameObject"/> is registered to the <see cref="IGameManager"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnGameObjectRegisteredEventHandler? OnGameObjectRegistered;
|
Action<IGameManager, IGameObject>? OnGameObjectRegistered { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a <see cref="IGameObject"/> is unregistered from the <see cref="IGameManager"/>.
|
/// Event triggered when a <see cref="IGameObject"/> is unregistered from the <see cref="IGameManager"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnGameObjectUnRegisteredEventHandler? OnGameObjectUnRegistered;
|
Action<IGameManager, IGameObject>? OnGameObjectUnRegistered { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when a <see cref="IHierarchyObject"/> is registered to the <see cref="IGameManager"/>.
|
|
||||||
/// </summary>
|
|
||||||
event OnHierarchyObjectRegisteredEventHandler? OnHierarchyObjectRegistered;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when a <see cref="IHierarchyObject"/> is unregistered from the <see cref="IGameManager"/>.
|
|
||||||
/// </summary>
|
|
||||||
event OnHierarchyObjectUnRegisteredEventHandler? OnHierarchyObjectUnRegistered;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only list of <see cref="IGameObject"/>s managed by the <see cref="IGameManager"/>.
|
/// Gets a read-only list of <see cref="IGameObject"/>s managed by the <see cref="IGameManager"/>.
|
||||||
@ -43,15 +24,10 @@ public interface IGameManager : IEntity
|
|||||||
IReadOnlyList<IGameObject> GameObjects { get; }
|
IReadOnlyList<IGameObject> GameObjects { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only list of <see cref="IHierarchyObject"/>s managed by the <see cref="IGameManager"/>.
|
/// Registers a <see cref="IGameObject"/> to the <see cref="IGameManager"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IReadOnlyList<IHierarchyObject> HierarchyObjects { get; }
|
/// <param name="gameObject">The <see cref="IGameObject"/> to register.</param>
|
||||||
|
void RegisterGameObject(IGameObject gameObject);
|
||||||
/// <summary>
|
|
||||||
/// Registers an <see cref="IHierarchyObject"/> to the <see cref="IGameManager"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hierarchyObject">The <see cref="IHierarchyObject"/> to register.</param>
|
|
||||||
void Register(IHierarchyObject hierarchyObject);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiates a <see cref="IGameObject"/> of type T with the given arguments and registers it to the <see cref="IGameManager"/>.
|
/// Instantiates a <see cref="IGameObject"/> of type T with the given arguments and registers it to the <see cref="IGameManager"/>.
|
||||||
@ -62,10 +38,11 @@ public interface IGameManager : IEntity
|
|||||||
T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject;
|
T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes an <see cref="IHierarchyObject"/> from the <see cref="IGameManager"/>.
|
/// Removes a <see cref="IGameObject"/> from the <see cref="IGameManager"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hierarchyObject">The <see cref="IHierarchyObject"/> to remove.</param>
|
/// <param name="gameObject">The <see cref="IGameObject"/> to remove.</param>
|
||||||
void Remove(IHierarchyObject hierarchyObject);
|
/// <returns>The removed <see cref="IGameObject"/>.</returns>
|
||||||
|
IGameObject RemoveGameObject(IGameObject gameObject);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the <see cref="IGameManager"/> with the given engine time data.
|
/// Updates the <see cref="IGameManager"/> with the given engine time data.
|
||||||
@ -77,12 +54,4 @@ public interface IGameManager : IEntity
|
|||||||
/// Performs operations that should be done before the draw calls.
|
/// Performs operations that should be done before the draw calls.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void PreDraw();
|
void PreDraw();
|
||||||
|
|
||||||
delegate void OnUpdateEventHandler(IGameManager sender, EngineTime time);
|
|
||||||
delegate void OnPreDawEventHandler(IGameManager sender);
|
|
||||||
|
|
||||||
delegate void OnGameObjectRegisteredEventHandler(IGameManager sender, IGameObject gameObjectRegistered);
|
|
||||||
delegate void OnGameObjectUnRegisteredEventHandler(IGameManager sender, IGameObject gameObjectUnregistered);
|
|
||||||
delegate void OnHierarchyObjectRegisteredEventHandler(IGameManager sender, IHierarchyObject hierarchyObjectRegistered);
|
|
||||||
delegate void OnHierarchyObjectUnRegisteredEventHandler(IGameManager sender, IHierarchyObject hierarchyObjectUnregistered);
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a game object with various properties and functionalities.
|
/// Represents a game object with various properties and functionalities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IGameObject : IEntity, IHierarchyObject, IAssignableTransform, IAssignableBehaviourController, INameable, IInitialize
|
public interface IGameObject : IEntity, IAssignableGameManager, IAssignableTransform, IAssignableBehaviourController, INameable, IInitialize
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Update"/> method is called.
|
/// Event triggered when the <see cref="Update"/> method is called.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnUpdatedEventHandler? OnUpdated;
|
Action<IGameObject>? OnUpdated { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the game object.
|
/// Updates the game object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
delegate void OnUpdatedEventHandler(IGameObject sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,17 +10,17 @@ public interface IInitialize
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Initialize"/> method is called successfully.
|
/// Event triggered when the <see cref="Initialize"/> method is called successfully.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnInitializedEventHandler? OnInitialized;
|
Action<IInitialize>? OnInitialized { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Finalize"/> method is called successfully.
|
/// Event triggered when the <see cref="Finalize"/> method is called successfully.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnFinalizedEventHandler? OnFinalized;
|
Action<IInitialize>? OnFinalized { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value indicating whether the entity has been initialized.
|
/// The value indicating whether the entity has been initialized.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsInitialized { get; }
|
bool Initialized { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the entity.
|
/// Initializes the entity.
|
||||||
@ -31,7 +33,4 @@ public interface IInitialize
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns><see cref="true"/> if finalization is successful, otherwise <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if finalization is successful, otherwise <see cref="false"/>.</returns>
|
||||||
bool Finalize();
|
bool Finalize();
|
||||||
|
|
||||||
delegate void OnInitializedEventHandler(IInitialize sender);
|
|
||||||
delegate void OnFinalizedEventHandler(IInitialize sender);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,12 +10,10 @@ public interface INameable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the name of the entity changes.
|
/// Event triggered when the name of the entity changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnNameChangedEventHandler? OnNameChanged;
|
Action<IEntity>? OnNameChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the entity.
|
/// The name of the entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
|
|
||||||
delegate void OnNameChangedEventHandler(INameable sender, string previousName);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,12 +10,10 @@ public interface IStateEnable : IAssignableEntity
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Enabled"/> state of the <see cref="IStateEnable"/> changes.
|
/// Event triggered when the <see cref="Enabled"/> state of the <see cref="IStateEnable"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnNameChangedEventHandler? OnEnabledChanged;
|
Action<IStateEnable>? OnEnabledChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value indicating whether the <see cref="IStateEnable"/> is enabled.
|
/// The value indicating whether the <see cref="IStateEnable"/> is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool Enabled { get; set; }
|
bool Enabled { get; set; }
|
||||||
|
|
||||||
delegate void OnNameChangedEventHandler(IStateEnable sender, bool previousState);
|
|
||||||
}
|
}
|
||||||
|
@ -1,105 +1,39 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the transformation properties of an object such as position, scale, and rotation.
|
/// Represents the transformation properties of an object such as position, scale, and rotation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ITransform : IAssignableGameObject, IEnumerable<ITransform>
|
public interface ITransform
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform"/> changes.
|
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnPositionChangedEventHandler? OnPositionChanged;
|
Action<ITransform>? OnPositionChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Scale"/> of the <see cref="ITransform"/> changes.
|
/// Event triggered when the <see cref="Scale"/> of the <see cref="ITransform"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnScaleChangedEventHandler? OnScaleChanged;
|
Action<ITransform>? OnScaleChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Rotation"/> of the <see cref="ITransform"/> changes.
|
/// Event triggered when the <see cref="Rotation"/> of the <see cref="ITransform"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnRotationChangedEventHandler? OnRotationChanged;
|
Action<ITransform>? OnRotationChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Parent"/> of the <see cref="ITransform"/> changes. The second parameter is the old <see cref="ITransform"/>.
|
/// The position of the <see cref="ITransform"/> in 2D space.
|
||||||
/// </summary>
|
|
||||||
event OnParentChangedEventHandler? OnParentChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when a new <see cref="ITransform"/> is added to the <see cref="Children"/>.
|
|
||||||
/// </summary>
|
|
||||||
event OnChildrenAddedEventHandler? OnChildrenAdded;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when an <see cref="ITransform"/> is removed from the <see cref="Children"/>.
|
|
||||||
/// </summary>
|
|
||||||
event OnChildrenRemovedEventHandler? OnChildrenRemoved;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The world position of the <see cref="ITransform"/> in 2D space.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Vector2D Position { get; set; }
|
Vector2D Position { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The world scale of the <see cref="ITransform"/>.
|
/// The scale of the <see cref="ITransform"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Vector2D Scale { get; set; }
|
Vector2D Scale { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The world rotation of the <see cref="ITransform"/> in degrees.
|
/// The rotation of the <see cref="ITransform"/> in degrees.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
float Rotation { get; set; }
|
float Rotation { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The local position of the <see cref="ITransform"/> in 2D space.
|
|
||||||
/// </summary>
|
|
||||||
Vector2D LocalPosition { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The local scale of the <see cref="ITransform"/>.
|
|
||||||
/// </summary>
|
|
||||||
Vector2D LocalScale { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The local rotation of the <see cref="ITransform"/> in degrees.
|
|
||||||
/// </summary>
|
|
||||||
float LocalRotation { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The parent <see cref="ITransform"/> of the <see cref="ITransform"/>.
|
|
||||||
/// </summary>
|
|
||||||
ITransform? Parent { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The <see cref="ITransform"/>s that have this <see cref="ITransform"/> as their <see cref="Parent"/>.
|
|
||||||
/// </summary>
|
|
||||||
IReadOnlyList<ITransform> Children { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the parent <see cref="ITransform"/> of this <see cref="ITransform"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="transform">The parent <see cref="ITransform"/> to set.</param>
|
|
||||||
void SetParent(ITransform? transform);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a child <see cref="ITransform"/> to this <see cref="ITransform"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="transform">The child <see cref="ITransform"/> to add.</param>
|
|
||||||
void AddChild(ITransform transform);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a child <see cref="ITransform"/> from this <see cref="ITransform"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="transform">The child <see cref="ITransform"/> to remove.</param>
|
|
||||||
void RemoveChild(ITransform transform);
|
|
||||||
|
|
||||||
delegate void OnPositionChangedEventHandler(ITransform sender);
|
|
||||||
delegate void OnScaleChangedEventHandler(ITransform sender);
|
|
||||||
delegate void OnRotationChangedEventHandler(ITransform sender);
|
|
||||||
delegate void OnParentChangedEventHandler(ITransform sender, ITransform? previousParent, ITransform? newParent);
|
|
||||||
delegate void OnChildrenAddedEventHandler(ITransform sender, ITransform childrenAdded);
|
|
||||||
delegate void OnChildrenRemovedEventHandler(ITransform sender, ITransform childrenRemoved);
|
|
||||||
}
|
}
|
||||||
|
@ -1,106 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public abstract class Behaviour : BehaviourBase
|
[System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")]
|
||||||
|
public abstract class Behaviour : BaseEntity, IBehaviour
|
||||||
{
|
{
|
||||||
private bool isInitializedThisFrame = false;
|
public Action<IAssignableBehaviourController>? OnBehaviourControllerAssigned { get; set; } = null;
|
||||||
|
|
||||||
protected IGameManager GameManager => BehaviourController.GameObject.GameManager;
|
public Action<IBehaviour>? OnPriorityChanged { get; set; } = null;
|
||||||
protected IGameObject GameObject => BehaviourController.GameObject;
|
|
||||||
protected ITransform Transform => BehaviourController.GameObject.Transform;
|
|
||||||
|
|
||||||
public Behaviour()
|
|
||||||
|
private IBehaviourController _behaviourController = null!;
|
||||||
|
|
||||||
|
private int _priority = 0;
|
||||||
|
|
||||||
|
public IBehaviourController BehaviourController => _behaviourController;
|
||||||
|
|
||||||
|
public override bool IsActive => base.IsActive && BehaviourController.GameObject.StateEnable.Enabled;
|
||||||
|
|
||||||
|
public int Priority
|
||||||
{
|
{
|
||||||
OnInitialized += OnInitialize;
|
get => _priority;
|
||||||
OnFinalized += OnFinalize;
|
set
|
||||||
OnUnassigned += OnUnassign;
|
{
|
||||||
|
if (value == _priority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_priority = value;
|
||||||
|
OnPriorityChanged?.Invoke(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnUnassign() { }
|
public bool Assign(IBehaviourController behaviourController)
|
||||||
private void OnUnassign(IAssignable assignable) => OnUnassign();
|
|
||||||
|
|
||||||
protected virtual void OnInitialize() { }
|
|
||||||
private void OnInitialize(IInitialize _)
|
|
||||||
{
|
{
|
||||||
isInitializedThisFrame = true;
|
if (Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
BehaviourController.OnPreUpdate += PreUpdate;
|
_behaviourController = behaviourController;
|
||||||
BehaviourController.OnPreDraw += PreDraw;
|
OnBehaviourControllerAssigned?.Invoke(this);
|
||||||
BehaviourController.OnUpdate += Update;
|
return true;
|
||||||
BehaviourController.GameObject.OnEnteredHierarchy += EnteredHierarchy;
|
|
||||||
BehaviourController.GameObject.OnExitedHierarchy += ExitedHierarchy;
|
|
||||||
|
|
||||||
OnInitialize();
|
|
||||||
|
|
||||||
if (GameObject.IsInHierarchy)
|
|
||||||
EnteredHierarchy(GameObject, GameManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnFinalize() { }
|
protected override void UnassignInternal()
|
||||||
private void OnFinalize(IInitialize _)
|
|
||||||
{
|
{
|
||||||
BehaviourController.OnPreUpdate -= PreUpdate;
|
base.UnassignInternal();
|
||||||
BehaviourController.OnPreDraw -= PreDraw;
|
_behaviourController = null!;
|
||||||
BehaviourController.OnUpdate -= Update;
|
|
||||||
BehaviourController.GameObject.OnEnteredHierarchy -= EnteredHierarchy;
|
|
||||||
BehaviourController.GameObject.OnExitedHierarchy -= ExitedHierarchy;
|
|
||||||
|
|
||||||
OnFinalize();
|
|
||||||
|
|
||||||
if (GameObject.IsInHierarchy)
|
|
||||||
ExitedHierarchy(GameObject, GameManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnPreUpdatePreActiveCheck() { }
|
protected override void InitializeInternal()
|
||||||
protected virtual void OnPreUpdate() { }
|
|
||||||
private void PreUpdate(IBehaviourController _)
|
|
||||||
{
|
{
|
||||||
OnPreUpdatePreActiveCheck();
|
base.InitializeInternal();
|
||||||
|
NotAssignedException.Check(this, _behaviourController);
|
||||||
if (!IsActive)
|
NotAssignedException.Check(this, StateEnable);
|
||||||
return;
|
|
||||||
|
|
||||||
if (isInitializedThisFrame)
|
|
||||||
FirstActiveFrame();
|
|
||||||
|
|
||||||
OnPreUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnFirstActiveFrame() { }
|
|
||||||
private void FirstActiveFrame()
|
|
||||||
{
|
|
||||||
OnFirstActiveFrame();
|
|
||||||
isInitializedThisFrame = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnUpdatePreActiveCheck() { }
|
|
||||||
protected virtual void OnUpdate() { }
|
|
||||||
private void Update(IBehaviourController _)
|
|
||||||
{
|
|
||||||
OnUpdatePreActiveCheck();
|
|
||||||
|
|
||||||
if (!IsActive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
OnUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnPreDrawPreActiveCheck() { }
|
|
||||||
protected virtual void OnPreDraw() { }
|
|
||||||
private void PreDraw(IBehaviourController _)
|
|
||||||
{
|
|
||||||
OnPreDrawPreActiveCheck();
|
|
||||||
|
|
||||||
if (!StateEnable.Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
OnPreDraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnEnteredHierarchy(IGameManager gameManager) { }
|
|
||||||
private void EnteredHierarchy(IHierarchyObject sender, IGameManager gameManager) => OnEnteredHierarchy(gameManager);
|
|
||||||
|
|
||||||
protected virtual void OnExitedHierarchy(IGameManager gameManager) { }
|
|
||||||
private void ExitedHierarchy(IHierarchyObject sender, IGameManager gameManager) => OnExitedHierarchy(gameManager);
|
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
using Syntriax.Engine.Core.Exceptions;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")]
|
|
||||||
public abstract class BehaviourBase : BaseEntity, IBehaviour
|
|
||||||
{
|
|
||||||
public event IAssignableBehaviourController.OnBehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null;
|
|
||||||
|
|
||||||
public event IBehaviour.OnPriorityChangedEventHandler? OnPriorityChanged = null;
|
|
||||||
|
|
||||||
|
|
||||||
private IBehaviourController _behaviourController = null!;
|
|
||||||
|
|
||||||
private int _priority = 0;
|
|
||||||
|
|
||||||
|
|
||||||
public IBehaviourController BehaviourController => _behaviourController;
|
|
||||||
|
|
||||||
public override bool IsActive => base.IsActive && BehaviourController.GameObject.StateEnable.Enabled;
|
|
||||||
|
|
||||||
public int Priority
|
|
||||||
{
|
|
||||||
get => _priority;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _priority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int previousPriority = _priority;
|
|
||||||
_priority = value;
|
|
||||||
OnPriorityChanged?.Invoke(this, previousPriority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Assign(IBehaviourController behaviourController)
|
|
||||||
{
|
|
||||||
if (IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_behaviourController = behaviourController;
|
|
||||||
OnBehaviourControllerAssigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UnassignInternal()
|
|
||||||
{
|
|
||||||
base.UnassignInternal();
|
|
||||||
_behaviourController = null!;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void InitializeInternal()
|
|
||||||
{
|
|
||||||
base.InitializeInternal();
|
|
||||||
NotAssignedException.Check(this, _behaviourController);
|
|
||||||
NotAssignedException.Check(this, StateEnable);
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,54 +6,45 @@ using Syntriax.Engine.Core.Abstract;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
|
public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
||||||
{
|
{
|
||||||
public event IAssignable.OnUnassignedEventHandler? OnUnassigned = null;
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
||||||
public event IAssignableGameManager.OnGameManagerAssignedEventHandler? OnGameManagerAssigned = null;
|
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
||||||
|
|
||||||
public event IBehaviourCollector<T>.OnCollectedEventHandler? OnCollected = null;
|
public Action<BehaviourCacher<T>, T>? OnCached { get; set; } = null;
|
||||||
public event IBehaviourCollector<T>.OnRemovedEventHandler? OnRemoved = null;
|
public Action<BehaviourCacher<T>, T>? OnUncached { get; set; } = null;
|
||||||
|
|
||||||
protected readonly List<T> _behaviours = new(32);
|
private readonly List<T> _behaviours = new(32);
|
||||||
|
|
||||||
public IReadOnlyList<T> Behaviours => _behaviours;
|
public IReadOnlyList<T> Behaviours => _behaviours;
|
||||||
public IGameManager GameManager { get; private set; } = null!;
|
public IGameManager GameManager { get; private set; } = null!;
|
||||||
|
|
||||||
public T this[Index index] => _behaviours[index];
|
public T this[Index index] => _behaviours[index];
|
||||||
|
|
||||||
public BehaviourCollector() { }
|
public BehaviourCacher() { }
|
||||||
public BehaviourCollector(IGameManager gameManager) => Assign(gameManager);
|
public BehaviourCacher(IGameManager gameManager) => Assign(gameManager);
|
||||||
|
|
||||||
private void OnGameObjectRegistered(IGameManager manager, IGameObject gameObject)
|
private void OnGameObjectRegistered(IGameManager manager, IGameObject gameObject)
|
||||||
{
|
{
|
||||||
gameObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
|
gameObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
|
||||||
gameObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved;
|
gameObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved;
|
||||||
|
|
||||||
foreach (IBehaviour item in gameObject.BehaviourController)
|
|
||||||
OnBehaviourAdded(gameObject.BehaviourController, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGameObjectUnregistered(IGameManager manager, IGameObject gameObject)
|
private void OnGameObjectUnregistered(IGameManager manager, IGameObject gameObject)
|
||||||
{
|
{
|
||||||
gameObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded;
|
gameObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded;
|
||||||
gameObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved;
|
gameObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved;
|
||||||
|
|
||||||
foreach (IBehaviour item in gameObject.BehaviourController)
|
|
||||||
OnBehaviourRemoved(gameObject.BehaviourController, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
|
|
||||||
private void OnBehaviourAdded(IBehaviourController controller, IBehaviour behaviour)
|
private void OnBehaviourAdded(IBehaviourController controller, IBehaviour behaviour)
|
||||||
{
|
{
|
||||||
if (behaviour is not T tBehaviour)
|
if (behaviour is not T tBehaviour)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_behaviours.Add(tBehaviour);
|
_behaviours.Add(tBehaviour);
|
||||||
OnBehaviourAdd(behaviour);
|
OnCached?.Invoke(this, tBehaviour);
|
||||||
OnCollected?.Invoke(this, tBehaviour);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
|
|
||||||
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour)
|
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour)
|
||||||
{
|
{
|
||||||
if (behaviour is not T tBehaviour)
|
if (behaviour is not T tBehaviour)
|
||||||
@ -62,8 +53,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
|
|||||||
if (!_behaviours.Remove(tBehaviour))
|
if (!_behaviours.Remove(tBehaviour))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OnBehaviourRemove(behaviour);
|
OnUncached?.Invoke(this, tBehaviour);
|
||||||
OnRemoved?.Invoke(this, tBehaviour);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Assign(IGameManager gameManager)
|
public bool Assign(IGameManager gameManager)
|
||||||
@ -71,8 +61,12 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
|
|||||||
if (GameManager is not null)
|
if (GameManager is not null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (IGameObject gameObject in gameManager.GameObjects)
|
foreach (IGameObject gameObject in gameManager)
|
||||||
|
{
|
||||||
OnGameObjectRegistered(gameManager, gameObject);
|
OnGameObjectRegistered(gameManager, gameObject);
|
||||||
|
foreach (IBehaviour behaviour in gameObject.BehaviourController)
|
||||||
|
OnBehaviourAdded(gameObject.BehaviourController, behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
gameManager.OnGameObjectRegistered += OnGameObjectRegistered;
|
gameManager.OnGameObjectRegistered += OnGameObjectRegistered;
|
||||||
gameManager.OnGameObjectUnRegistered += OnGameObjectUnregistered;
|
gameManager.OnGameObjectUnRegistered += OnGameObjectUnregistered;
|
||||||
@ -88,8 +82,12 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
|
|||||||
if (GameManager is null)
|
if (GameManager is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (IGameObject gameObject in GameManager.GameObjects)
|
foreach (IGameObject gameObject in GameManager)
|
||||||
|
{
|
||||||
OnGameObjectUnregistered(GameManager, gameObject);
|
OnGameObjectUnregistered(GameManager, gameObject);
|
||||||
|
foreach (IBehaviour behaviour in gameObject.BehaviourController)
|
||||||
|
OnBehaviourRemoved(gameObject.BehaviourController, behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
GameManager.OnGameObjectRegistered -= OnGameObjectRegistered;
|
GameManager.OnGameObjectRegistered -= OnGameObjectRegistered;
|
||||||
GameManager.OnGameObjectUnRegistered -= OnGameObjectUnregistered;
|
GameManager.OnGameObjectUnRegistered -= OnGameObjectUnregistered;
|
@ -1,19 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class
|
|
||||||
{
|
|
||||||
public Comparison<T>? SortBy { get; set; } = null;
|
|
||||||
|
|
||||||
protected override void OnBehaviourAdd(IBehaviour behaviour)
|
|
||||||
{
|
|
||||||
if (SortBy is not null)
|
|
||||||
_behaviours.Sort(SortBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BehaviourCollectorSorted() { }
|
|
||||||
public BehaviourCollectorSorted(IGameManager gameManager) : base(gameManager) { }
|
|
||||||
}
|
|
@ -5,57 +5,33 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Core.Exceptions;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")]
|
[System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")]
|
||||||
public class BehaviourController : IBehaviourController
|
public class BehaviourController : IBehaviourController
|
||||||
{
|
{
|
||||||
public event IBehaviourController.OnPreUpdateEventHandler? OnPreUpdate = null;
|
public Action<IBehaviourController>? OnPreUpdate { get; set; }
|
||||||
public event IBehaviourController.OnUpdateEventHandler? OnUpdate = null;
|
public Action<IBehaviourController>? OnUpdate { get; set; } = null;
|
||||||
public event IBehaviourController.OnPreDrawEventHandler? OnPreDraw = null;
|
public Action<IBehaviourController>? OnPreDraw { get; set; } = null;
|
||||||
|
|
||||||
public event IBehaviourController.OnBehaviourAddedEventHandler? OnBehaviourAdded = null;
|
public Action<IBehaviourController, IBehaviour>? OnBehaviourAdded { get; set; } = null;
|
||||||
public event IBehaviourController.OnBehaviourRemovedEventHandler? OnBehaviourRemoved = null;
|
public Action<IBehaviourController, IBehaviour>? OnBehaviourRemoved { get; set; } = null;
|
||||||
public event IAssignableGameObject.OnGameObjectAssignedEventHandler? OnGameObjectAssigned = null;
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
||||||
|
public Action<IAssignableGameObject>? OnGameObjectAssigned { get; set; } = null;
|
||||||
|
|
||||||
public event IInitialize.OnInitializedEventHandler? OnInitialized = null;
|
|
||||||
public event IInitialize.OnFinalizedEventHandler? OnFinalized = null;
|
|
||||||
|
|
||||||
public event IAssignable.OnUnassignedEventHandler? OnUnassigned = null;
|
|
||||||
|
|
||||||
private readonly IList<IBehaviour> behaviours = new List<IBehaviour>(Constants.BEHAVIOURS_SIZE_INITIAL);
|
private readonly IList<IBehaviour> behaviours = new List<IBehaviour>(Constants.BEHAVIOURS_SIZE_INITIAL);
|
||||||
|
|
||||||
private IGameObject _gameObject = null!;
|
private IGameObject _gameObject = null!;
|
||||||
private bool _initialized = false;
|
|
||||||
|
|
||||||
public IGameObject GameObject => _gameObject;
|
public IGameObject GameObject => _gameObject;
|
||||||
|
|
||||||
|
|
||||||
public bool IsInitialized
|
|
||||||
{
|
|
||||||
get => _initialized;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
if (value == _initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_initialized = value;
|
|
||||||
if (value)
|
|
||||||
OnInitialized?.Invoke(this);
|
|
||||||
else
|
|
||||||
OnFinalized?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T AddBehaviour<T>(T behaviour) where T : class, IBehaviour
|
public T AddBehaviour<T>(T behaviour) where T : class, IBehaviour
|
||||||
{
|
{
|
||||||
InsertBehaviourByPriority(behaviour);
|
InsertBehaviourByPriority(behaviour);
|
||||||
|
|
||||||
behaviour.Assign(this);
|
|
||||||
behaviour.Assign(GameObject.StateEnable);
|
|
||||||
|
|
||||||
behaviour.Initialize();
|
behaviour.Initialize();
|
||||||
behaviour.OnPriorityChanged += OnPriorityChange;
|
behaviour.OnPriorityChanged += OnPriorityChange;
|
||||||
OnBehaviourAdded?.Invoke(this, behaviour);
|
OnBehaviourAdded?.Invoke(this, behaviour);
|
||||||
@ -74,6 +50,12 @@ public class BehaviourController : IBehaviourController
|
|||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryGetBehaviour<T>([NotNullWhen(returnValue: true)] out T? behaviour)
|
||||||
|
{
|
||||||
|
behaviour = GetBehaviour<T>();
|
||||||
|
return behaviour is not null;
|
||||||
|
}
|
||||||
|
|
||||||
public IList<T> GetBehaviours<T>()
|
public IList<T> GetBehaviours<T>()
|
||||||
{
|
{
|
||||||
List<T>? behaviours = null;
|
List<T>? behaviours = null;
|
||||||
@ -89,15 +71,15 @@ public class BehaviourController : IBehaviourController
|
|||||||
return behaviours ?? Enumerable.Empty<T>().ToList();
|
return behaviours ?? Enumerable.Empty<T>().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetBehaviours<T>(IList<T> results)
|
public void GetBehaviours<T>(List<T> behaviors)
|
||||||
{
|
{
|
||||||
results.Clear();
|
behaviors.Clear();
|
||||||
foreach (var behaviourItem in behaviours)
|
foreach (var behaviourItem in behaviours)
|
||||||
{
|
{
|
||||||
if (behaviourItem is not T behaviour)
|
if (behaviourItem is not T _)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
results.Add(behaviour);
|
behaviours.Add(behaviourItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +110,7 @@ public class BehaviourController : IBehaviourController
|
|||||||
|
|
||||||
public bool Assign(IGameObject gameObject)
|
public bool Assign(IGameObject gameObject)
|
||||||
{
|
{
|
||||||
if (GameObject is not null && GameObject.IsInitialized)
|
if (GameObject is not null && GameObject.Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_gameObject = gameObject;
|
_gameObject = gameObject;
|
||||||
@ -136,36 +118,9 @@ public class BehaviourController : IBehaviourController
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool Initialize()
|
|
||||||
{
|
|
||||||
if (IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
NotAssignedException.Check(this, _gameObject);
|
|
||||||
|
|
||||||
foreach (IBehaviour behaviour in behaviours)
|
|
||||||
behaviour.Initialize();
|
|
||||||
|
|
||||||
IsInitialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Finalize()
|
|
||||||
{
|
|
||||||
if (!IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
foreach (IBehaviour behaviour in behaviours)
|
|
||||||
behaviour.Finalize();
|
|
||||||
|
|
||||||
IsInitialized = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Unassign()
|
public bool Unassign()
|
||||||
{
|
{
|
||||||
if (IsInitialized)
|
if (GameObject is not null && GameObject.Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_gameObject = null!;
|
_gameObject = null!;
|
||||||
@ -210,11 +165,10 @@ public class BehaviourController : IBehaviourController
|
|||||||
behaviours.Add(behaviour);
|
behaviours.Add(behaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnPriorityChange(IBehaviour behaviour)
|
||||||
private void OnPriorityChange(IBehaviour sender, int previousPriority)
|
|
||||||
{
|
{
|
||||||
behaviours.Remove(sender);
|
behaviours.Remove(behaviour);
|
||||||
InsertBehaviourByPriority(sender);
|
InsertBehaviourByPriority(behaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<IBehaviour> GetEnumerator() => behaviours.GetEnumerator();
|
public IEnumerator<IBehaviour> GetEnumerator() => behaviours.GetEnumerator();
|
||||||
|
87
Engine.Core/BehaviourOverride.cs
Normal file
87
Engine.Core/BehaviourOverride.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
public abstract class BehaviourOverride : Behaviour
|
||||||
|
{
|
||||||
|
private bool isInitializedThisFrame = false;
|
||||||
|
|
||||||
|
protected IGameObject GameObject => BehaviourController.GameObject;
|
||||||
|
protected ITransform Transform => BehaviourController.GameObject.Transform;
|
||||||
|
|
||||||
|
public BehaviourOverride()
|
||||||
|
{
|
||||||
|
OnInitialized += OnInitialize;
|
||||||
|
OnFinalized += OnFinalize;
|
||||||
|
OnUnassigned += OnUnassign;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnUnassign() { }
|
||||||
|
private void OnUnassign(IAssignable assignable) => OnUnassign();
|
||||||
|
|
||||||
|
protected virtual void OnInitialize() { }
|
||||||
|
private void OnInitialize(IInitialize _)
|
||||||
|
{
|
||||||
|
isInitializedThisFrame = true;
|
||||||
|
|
||||||
|
BehaviourController.OnPreUpdate += PreUpdate;
|
||||||
|
BehaviourController.OnPreDraw += PreDraw;
|
||||||
|
BehaviourController.OnUpdate += Update;
|
||||||
|
OnInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnFinalize() { }
|
||||||
|
private void OnFinalize(IInitialize _)
|
||||||
|
{
|
||||||
|
BehaviourController.OnPreUpdate -= PreUpdate;
|
||||||
|
BehaviourController.OnPreDraw -= PreDraw;
|
||||||
|
BehaviourController.OnUpdate -= Update;
|
||||||
|
OnFinalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPreUpdatePreActiveCheck() { }
|
||||||
|
protected virtual void OnPreUpdate() { }
|
||||||
|
private void PreUpdate(IBehaviourController _)
|
||||||
|
{
|
||||||
|
OnPreUpdatePreActiveCheck();
|
||||||
|
|
||||||
|
if (!IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isInitializedThisFrame)
|
||||||
|
FirstActiveFrame();
|
||||||
|
|
||||||
|
OnPreUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnFirstActiveFrame() { }
|
||||||
|
private void FirstActiveFrame()
|
||||||
|
{
|
||||||
|
OnFirstActiveFrame();
|
||||||
|
isInitializedThisFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnUpdatePreActiveCheck() { }
|
||||||
|
protected virtual void OnUpdate() { }
|
||||||
|
private void Update(IBehaviourController _)
|
||||||
|
{
|
||||||
|
OnUpdatePreActiveCheck();
|
||||||
|
|
||||||
|
if (!IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OnUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPreDrawPreActiveCheck() { }
|
||||||
|
protected virtual void OnPreDraw() { }
|
||||||
|
private void PreDraw(IBehaviourController _)
|
||||||
|
{
|
||||||
|
OnPreDrawPreActiveCheck();
|
||||||
|
|
||||||
|
if (!StateEnable.Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OnPreDraw();
|
||||||
|
}
|
||||||
|
}
|
@ -1,44 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
public class CoroutineManager : HierarchyObjectBase
|
|
||||||
{
|
|
||||||
private readonly List<IEnumerator> enumerators = [];
|
|
||||||
|
|
||||||
public IEnumerator StartCoroutine(IEnumerator enumerator)
|
|
||||||
{
|
|
||||||
enumerators.Add(enumerator);
|
|
||||||
return enumerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopCoroutine(IEnumerator enumerator)
|
|
||||||
{
|
|
||||||
enumerators.Remove(enumerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnEnteringHierarchy(IGameManager gameManager)
|
|
||||||
{
|
|
||||||
gameManager.OnUpdate += OnUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnExitingHierarchy(IGameManager gameManager)
|
|
||||||
{
|
|
||||||
gameManager.OnUpdate -= OnUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUpdate(IGameManager sender, EngineTime time)
|
|
||||||
{
|
|
||||||
for (int i = enumerators.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (enumerators[i].Current is ICoroutineYield coroutineYield && coroutineYield.Yield())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!enumerators[i].MoveNext())
|
|
||||||
enumerators.RemoveAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
public class CoroutineYield(Func<bool> condition) : ICoroutineYield
|
|
||||||
{
|
|
||||||
private readonly Func<bool> condition = condition;
|
|
||||||
|
|
||||||
public bool Yield() => condition.Invoke();
|
|
||||||
}
|
|
@ -7,5 +7,5 @@ public readonly struct EngineTime(TimeSpan Total, TimeSpan Elapsed)
|
|||||||
public readonly TimeSpan Total = Total;
|
public readonly TimeSpan Total = Total;
|
||||||
public readonly TimeSpan Elapsed = Elapsed;
|
public readonly TimeSpan Elapsed = Elapsed;
|
||||||
|
|
||||||
public readonly float DeltaTimeFrame = (float)Elapsed.TotalMilliseconds * .001f;
|
public readonly float DeltaTimeFrame = (float)Elapsed.TotalMilliseconds;
|
||||||
}
|
}
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
public static class BehaviourControllerExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to get a <see cref="IBehaviour"/> of the specified type.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
|
|
||||||
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to search in.</param>
|
|
||||||
/// <param name="behaviour">When this method returns, contains the <see cref="IBehaviour"/> of the specified type, if found; otherwise, null.</param>
|
|
||||||
/// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found; otherwise, <see cref="false"/>.</returns>
|
|
||||||
public static bool TryGetBehaviour<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour)
|
|
||||||
{
|
|
||||||
behaviour = behaviourController.GetBehaviour<T>();
|
|
||||||
return behaviour is not null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets an existing <see cref="IBehaviour"/> of the specified type, or adds and returns a new one if it doesn't exist.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get or add.</typeparam>
|
|
||||||
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to search in.</param>
|
|
||||||
/// <param name="args">Optional arguments to pass to the constructor of the <see cref="IBehaviour"/> if a new one is added.</param>
|
|
||||||
/// <returns>The existing or newly added <see cref="IBehaviour"/> of the specified type.</returns>
|
|
||||||
public static T GetOrAddBehaviour<T>(this IBehaviourController behaviourController, params object?[]? args) where T : class, IBehaviour
|
|
||||||
=> behaviourController.GetBehaviour<T>() ?? behaviourController.AddBehaviour<T>(args);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to get a <see cref="IBehaviour"/> of the specified type in the parent hierarchy.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
|
|
||||||
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
|
|
||||||
/// <param name="behaviour">When this method returns, contains the <see cref="IBehaviour"/> of the specified type, if found; otherwise, null.</param>
|
|
||||||
/// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found in the parent hierarchy; otherwise, <see cref="false"/>.</returns>
|
|
||||||
public static bool TryGetBehaviourInParent<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
|
||||||
{
|
|
||||||
behaviour = GetBehaviourInParent<T>(behaviourController);
|
|
||||||
return behaviour is not null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a <see cref="IBehaviour"/> of the specified type in the parent hierarchy.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
|
|
||||||
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
|
|
||||||
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, null.</returns>
|
|
||||||
public static T? GetBehaviourInParent<T>(this IBehaviourController behaviourController) where T : class
|
|
||||||
{
|
|
||||||
IBehaviourController? controller = behaviourController;
|
|
||||||
|
|
||||||
while (controller is not null)
|
|
||||||
{
|
|
||||||
if (behaviourController.GetBehaviour<T>() is T behaviour)
|
|
||||||
return behaviour;
|
|
||||||
|
|
||||||
controller = controller.GameObject.Transform.Parent?.GameObject.BehaviourController;
|
|
||||||
}
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to get a <see cref="IBehaviour"/> of the specified type in the child hierarchy.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
|
|
||||||
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
|
|
||||||
/// <param name="behaviour">When this method returns, contains the <see cref="IBehaviour"/> of the specified type, if found; otherwise, null.</param>
|
|
||||||
/// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found in the child hierarchy; otherwise, <see cref="false"/>.</returns>
|
|
||||||
public static bool TryGetBehaviourInChildren<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
|
||||||
{
|
|
||||||
behaviour = GetBehaviourInChildren<T>(behaviourController);
|
|
||||||
return behaviour is not null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a <see cref="IBehaviour"/> of the specified type in the child hierarchy.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
|
|
||||||
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
|
|
||||||
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, null.</returns>
|
|
||||||
public static T? GetBehaviourInChildren<T>(this IBehaviourController behaviourController) where T : class
|
|
||||||
{
|
|
||||||
if (behaviourController.GetBehaviour<T>() is T localBehaviour)
|
|
||||||
return localBehaviour;
|
|
||||||
|
|
||||||
foreach (ITransform transform in behaviourController.GameObject.Transform)
|
|
||||||
if (GetBehaviourInChildren<T>(transform.GameObject.BehaviourController) is T behaviour)
|
|
||||||
return behaviour;
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,22 +7,18 @@ namespace Syntriax.Engine.Core;
|
|||||||
|
|
||||||
public static class BehaviourExtensions
|
public static class BehaviourExtensions
|
||||||
{
|
{
|
||||||
public static T? FindBehaviour<T>(this IEnumerable<IGameObject> gameObjects) where T : class
|
public static bool TryFindBehaviour<T>(this IEnumerable<IGameObject> gameObjects, [NotNullWhen(returnValue: true)] out T? behaviour)
|
||||||
{
|
{
|
||||||
|
behaviour = default;
|
||||||
|
|
||||||
foreach (IGameObject gameObject in gameObjects)
|
foreach (IGameObject gameObject in gameObjects)
|
||||||
if (gameObject.BehaviourController.GetBehaviour<T>() is T behaviour)
|
if (gameObject.BehaviourController.TryGetBehaviour(out behaviour))
|
||||||
return behaviour;
|
return true;
|
||||||
|
|
||||||
return default;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryFindBehaviour<T>(this IEnumerable<IGameObject> gameObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
public static void FindBehaviours<T>(this IEnumerable<IGameObject> gameObjects, List<T> behaviours)
|
||||||
{
|
|
||||||
behaviour = FindBehaviour<T>(gameObjects);
|
|
||||||
return behaviour is not null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void FindBehaviours<T>(this IEnumerable<IGameObject> gameObjects, List<T> behaviours) where T : class
|
|
||||||
{
|
{
|
||||||
behaviours.Clear();
|
behaviours.Clear();
|
||||||
List<T> cache = [];
|
List<T> cache = [];
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
public static class HierarchyObjectExtensions
|
|
||||||
{
|
|
||||||
public static T? FindObject<T>(this IEnumerable<IHierarchyObject> hierarchyObjects) where T : class
|
|
||||||
{
|
|
||||||
foreach (IHierarchyObject hierarchyObject in hierarchyObjects)
|
|
||||||
if (hierarchyObject is T @object)
|
|
||||||
return @object;
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryFindObject<T>(this IEnumerable<IHierarchyObject> hierarchyObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
|
||||||
{
|
|
||||||
behaviour = FindObject<T>(hierarchyObjects);
|
|
||||||
return behaviour is not null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void FindObjects<T>(this IEnumerable<IHierarchyObject> hierarchyObjects, List<T> behaviours) where T : class
|
|
||||||
{
|
|
||||||
behaviours.Clear();
|
|
||||||
foreach (IHierarchyObject hierarchyObject in hierarchyObjects)
|
|
||||||
if (hierarchyObject is T @object)
|
|
||||||
behaviours.Add(@object);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,16 +4,11 @@ namespace Syntriax.Engine.Core;
|
|||||||
|
|
||||||
public static class TransformExtensions
|
public static class TransformExtensions
|
||||||
{
|
{
|
||||||
public static ITransform SetTransform(this ITransform transform,
|
public static ITransform SetTransform(this ITransform transform, Vector2D? position = null, float? rotation = null, Vector2D? scale = null)
|
||||||
Vector2D? position = null, float? rotation = null, Vector2D? scale = null,
|
|
||||||
Vector2D? localPosition = null, float? localRotation = null, Vector2D? localScale = null)
|
|
||||||
{
|
{
|
||||||
if (position.HasValue) transform.Position = position.Value;
|
if (position.HasValue) transform.Position = position.Value;
|
||||||
if (rotation.HasValue) transform.Rotation = rotation.Value;
|
if (rotation.HasValue) transform.Rotation = rotation.Value;
|
||||||
if (scale.HasValue) transform.Scale = scale.Value;
|
if (scale.HasValue) transform.Scale = scale.Value;
|
||||||
if (localPosition.HasValue) transform.LocalPosition = localPosition.Value;
|
|
||||||
if (localRotation.HasValue) transform.LocalRotation = localRotation.Value;
|
|
||||||
if (localScale.HasValue) transform.LocalScale = localScale.Value;
|
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,6 @@ public class GameObjectFactory
|
|||||||
behaviourController ??= TypeFactory.Get<BehaviourController>();
|
behaviourController ??= TypeFactory.Get<BehaviourController>();
|
||||||
stateEnable ??= TypeFactory.Get<StateEnable>();
|
stateEnable ??= TypeFactory.Get<StateEnable>();
|
||||||
|
|
||||||
if (!transform.Assign(gameObject))
|
|
||||||
throw AssignException.From(transform, gameObject);
|
|
||||||
|
|
||||||
if (!behaviourController.Assign(gameObject))
|
if (!behaviourController.Assign(gameObject))
|
||||||
throw AssignException.From(behaviourController, gameObject);
|
throw AssignException.From(behaviourController, gameObject);
|
||||||
if (!stateEnable.Assign(gameObject))
|
if (!stateEnable.Assign(gameObject))
|
||||||
|
@ -11,16 +11,11 @@ namespace Syntriax.Engine.Core;
|
|||||||
[System.Diagnostics.DebuggerDisplay("GameObject Count: {_gameObjects.Count}")]
|
[System.Diagnostics.DebuggerDisplay("GameObject Count: {_gameObjects.Count}")]
|
||||||
public class GameManager : BaseEntity, IGameManager
|
public class GameManager : BaseEntity, IGameManager
|
||||||
{
|
{
|
||||||
public event IGameManager.OnUpdateEventHandler? OnUpdate = null;
|
public Action<IGameManager, IGameObject>? OnGameObjectRegistered { get; set; } = null;
|
||||||
public event IGameManager.OnPreDawEventHandler? OnPreDraw = null;
|
public Action<IGameManager, IGameObject>? OnGameObjectUnRegistered { get; set; } = null;
|
||||||
|
|
||||||
public event IGameManager.OnGameObjectRegisteredEventHandler? OnGameObjectRegistered = null;
|
|
||||||
public event IGameManager.OnGameObjectUnRegisteredEventHandler? OnGameObjectUnRegistered = null;
|
|
||||||
public event IGameManager.OnHierarchyObjectRegisteredEventHandler? OnHierarchyObjectRegistered = null;
|
|
||||||
public event IGameManager.OnHierarchyObjectUnRegisteredEventHandler? OnHierarchyObjectUnRegistered = null;
|
|
||||||
|
|
||||||
private readonly List<IGameObject> _gameObjects = new(Constants.GAME_OBJECTS_SIZE_INITIAL);
|
private readonly List<IGameObject> _gameObjects = new(Constants.GAME_OBJECTS_SIZE_INITIAL);
|
||||||
private readonly List<IHierarchyObject> _hierarchyObjects = new(Constants.GAME_OBJECTS_SIZE_INITIAL);
|
|
||||||
|
|
||||||
private GameObjectFactory _gameObjectFactory = null!;
|
private GameObjectFactory _gameObjectFactory = null!;
|
||||||
|
|
||||||
@ -35,7 +30,6 @@ public class GameManager : BaseEntity, IGameManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<IGameObject> GameObjects => _gameObjects;
|
public IReadOnlyList<IGameObject> GameObjects => _gameObjects;
|
||||||
public IReadOnlyList<IHierarchyObject> HierarchyObjects => _hierarchyObjects;
|
|
||||||
|
|
||||||
public override IStateEnable StateEnable
|
public override IStateEnable StateEnable
|
||||||
{
|
{
|
||||||
@ -52,23 +46,12 @@ public class GameManager : BaseEntity, IGameManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Register(IHierarchyObject hierarchyObject)
|
public void RegisterGameObject(IGameObject gameObject)
|
||||||
{
|
{
|
||||||
if (_hierarchyObjects.Contains(hierarchyObject))
|
if (_gameObjects.Contains(gameObject))
|
||||||
throw new Exception($"{nameof(IHierarchyObject)} named {hierarchyObject.Name} is already registered to the {nameof(GameManager)}.");
|
throw new Exception($"{nameof(IGameObject)} named {gameObject.Name} is already registered to the {nameof(GameManager)}.");
|
||||||
|
|
||||||
if (hierarchyObject is IGameObject gameObject)
|
Register(gameObject);
|
||||||
Register(gameObject);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!hierarchyObject.Initialize())
|
|
||||||
throw new Exception($"{nameof(hierarchyObject)} can't be initialized");
|
|
||||||
|
|
||||||
_hierarchyObjects.Add(hierarchyObject);
|
|
||||||
hierarchyObject.EnterHierarchy(this);
|
|
||||||
|
|
||||||
OnHierarchyObjectRegistered?.Invoke(this, hierarchyObject);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject
|
public T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject
|
||||||
@ -78,23 +61,13 @@ public class GameManager : BaseEntity, IGameManager
|
|||||||
return gameObject;
|
return gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(IHierarchyObject hierarchyObject)
|
public IGameObject RemoveGameObject(IGameObject gameObject)
|
||||||
{
|
{
|
||||||
if (!_hierarchyObjects.Contains(hierarchyObject))
|
if (!_gameObjects.Contains(gameObject))
|
||||||
throw new Exception($"{nameof(IHierarchyObject)} named {hierarchyObject.Name} is not registered to the {nameof(GameManager)}.");
|
throw new Exception($"{nameof(IGameObject)} named {gameObject.Name} is not registered to the {nameof(GameManager)}.");
|
||||||
|
|
||||||
if (hierarchyObject is IGameObject gameObject)
|
Unregister(gameObject);
|
||||||
Unregister(gameObject);
|
return gameObject;
|
||||||
else
|
|
||||||
{
|
|
||||||
_hierarchyObjects.Remove(hierarchyObject);
|
|
||||||
hierarchyObject.ExitHierarchy();
|
|
||||||
|
|
||||||
if (!hierarchyObject.Finalize())
|
|
||||||
throw new Exception($"{nameof(hierarchyObject)} can't be finalized");
|
|
||||||
|
|
||||||
OnHierarchyObjectUnRegistered?.Invoke(this, hierarchyObject);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void InitializeInternal()
|
protected override void InitializeInternal()
|
||||||
@ -116,67 +89,33 @@ public class GameManager : BaseEntity, IGameManager
|
|||||||
public void Update(EngineTime time)
|
public void Update(EngineTime time)
|
||||||
{
|
{
|
||||||
Time.SetTime(time);
|
Time.SetTime(time);
|
||||||
for (int i = 0; i < GameObjects.Count; i++)
|
foreach (var gameObject in GameObjects)
|
||||||
GameObjects[i].BehaviourController.Update();
|
gameObject.BehaviourController.Update();
|
||||||
|
|
||||||
OnUpdate?.Invoke(this, time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PreDraw()
|
public void PreDraw()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < GameObjects.Count; i++)
|
foreach (var gameObject in GameObjects)
|
||||||
GameObjects[i].BehaviourController.UpdatePreDraw();
|
gameObject.BehaviourController.UpdatePreDraw();
|
||||||
|
|
||||||
OnPreDraw?.Invoke(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void Register(IGameObject gameObject)
|
private void Register(IGameObject gameObject)
|
||||||
{
|
{
|
||||||
if (_gameObjects.Contains(gameObject))
|
gameObject.Assign(this);
|
||||||
throw new Exception($"{nameof(IGameObject)} named {gameObject.Name} is already registered to the {nameof(GameManager)}.");
|
|
||||||
|
|
||||||
gameObject.OnFinalized += OnGameObjectFinalize;
|
gameObject.OnFinalized += OnGameObjectFinalize;
|
||||||
gameObject.OnExitedHierarchy += OnGameObjectExitedHierarchy;
|
|
||||||
|
|
||||||
if (!gameObject.Initialize())
|
|
||||||
throw new Exception($"{nameof(gameObject)} can't be initialized");
|
|
||||||
|
|
||||||
foreach (ITransform child in gameObject.Transform.Children)
|
|
||||||
Register(child.GameObject);
|
|
||||||
|
|
||||||
_gameObjects.Add(gameObject);
|
_gameObjects.Add(gameObject);
|
||||||
_hierarchyObjects.Add(gameObject);
|
|
||||||
|
|
||||||
if (!gameObject.EnterHierarchy(this))
|
|
||||||
throw new Exception($"{nameof(gameObject)} can't enter the hierarchy");
|
|
||||||
|
|
||||||
OnHierarchyObjectRegistered?.Invoke(this, gameObject);
|
|
||||||
OnGameObjectRegistered?.Invoke(this, gameObject);
|
OnGameObjectRegistered?.Invoke(this, gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Unregister(IGameObject gameObject)
|
private void Unregister(IGameObject gameObject)
|
||||||
{
|
{
|
||||||
if (!_gameObjects.Contains(gameObject))
|
|
||||||
throw new Exception($"{nameof(IGameObject)} named {gameObject.Name} is not registered to the {nameof(GameManager)}.");
|
|
||||||
|
|
||||||
gameObject.OnFinalized -= OnGameObjectFinalize;
|
gameObject.OnFinalized -= OnGameObjectFinalize;
|
||||||
gameObject.OnExitedHierarchy -= OnGameObjectExitedHierarchy;
|
|
||||||
|
|
||||||
foreach (ITransform child in gameObject.Transform.Children)
|
|
||||||
Unregister(child.GameObject);
|
|
||||||
|
|
||||||
_gameObjects.Remove(gameObject);
|
_gameObjects.Remove(gameObject);
|
||||||
_hierarchyObjects.Remove(gameObject);
|
|
||||||
|
|
||||||
if (!gameObject.ExitHierarchy())
|
|
||||||
throw new Exception($"{nameof(gameObject)} can't exit the hierarchy");
|
|
||||||
|
|
||||||
if (!gameObject.Finalize())
|
|
||||||
throw new Exception($"{nameof(gameObject)} can't be finalized");
|
|
||||||
|
|
||||||
OnHierarchyObjectUnRegistered?.Invoke(this, gameObject);
|
|
||||||
OnGameObjectUnRegistered?.Invoke(this, gameObject);
|
OnGameObjectUnRegistered?.Invoke(this, gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,9 +125,8 @@ public class GameManager : BaseEntity, IGameManager
|
|||||||
Unregister(gameObject);
|
Unregister(gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGameObjectExitedHierarchy(IHierarchyObject sender, IGameManager gameManager)
|
/////////////////////////////////////////////////////////////////
|
||||||
{
|
|
||||||
if (sender is IGameObject gameObject)
|
public IEnumerator<IGameObject> GetEnumerator() => _gameObjects.GetEnumerator();
|
||||||
Unregister(gameObject);
|
IEnumerator IEnumerable.GetEnumerator() => _gameObjects.GetEnumerator();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
@ -6,18 +8,18 @@ namespace Syntriax.Engine.Core;
|
|||||||
[System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")]
|
[System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")]
|
||||||
public class GameObject : BaseEntity, IGameObject
|
public class GameObject : BaseEntity, IGameObject
|
||||||
{
|
{
|
||||||
public event IHierarchyObject.OnEnteredHierarchyEventHandler? OnEnteredHierarchy = null;
|
public Action<IAssignableTransform>? OnTransformAssigned { get; set; } = null;
|
||||||
public event IHierarchyObject.OnExitedHierarchyEventHandler? OnExitedHierarchy = null;
|
public Action<IAssignableBehaviourController>? OnBehaviourControllerAssigned { get; set; } = null;
|
||||||
|
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
||||||
|
|
||||||
public event IAssignableTransform.OnTransformAssignedEventHandler? OnTransformAssigned = null;
|
public Action<IEntity>? OnNameChanged { get; set; } = null;
|
||||||
public event IAssignableBehaviourController.OnBehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null;
|
|
||||||
|
|
||||||
public event INameable.OnNameChangedEventHandler? OnNameChanged = null;
|
public Action<IGameObject>? OnUpdated { get; set; } = null;
|
||||||
|
|
||||||
public event IGameObject.OnUpdatedEventHandler? OnUpdated = null;
|
|
||||||
|
|
||||||
private ITransform _transform = null!;
|
private ITransform _transform = null!;
|
||||||
private IBehaviourController _behaviourController = null!;
|
private IBehaviourController _behaviourController = null!;
|
||||||
|
private IStateEnable _stateEnable = null!;
|
||||||
private IGameManager _gameManager = null!;
|
private IGameManager _gameManager = null!;
|
||||||
|
|
||||||
private string _name = nameof(GameObject);
|
private string _name = nameof(GameObject);
|
||||||
@ -25,7 +27,6 @@ public class GameObject : BaseEntity, IGameObject
|
|||||||
public ITransform Transform => _transform;
|
public ITransform Transform => _transform;
|
||||||
public IBehaviourController BehaviourController => _behaviourController;
|
public IBehaviourController BehaviourController => _behaviourController;
|
||||||
public IGameManager GameManager => _gameManager;
|
public IGameManager GameManager => _gameManager;
|
||||||
public bool IsInHierarchy => GameManager is not null;
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
@ -34,9 +35,8 @@ public class GameObject : BaseEntity, IGameObject
|
|||||||
{
|
{
|
||||||
if (value == _name) return;
|
if (value == _name) return;
|
||||||
|
|
||||||
string previousName = _name;
|
|
||||||
_name = value;
|
_name = value;
|
||||||
OnNameChanged?.Invoke(this, previousName);
|
OnNameChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,14 +46,13 @@ public class GameObject : BaseEntity, IGameObject
|
|||||||
|
|
||||||
NotAssignedException.Check(this, _transform);
|
NotAssignedException.Check(this, _transform);
|
||||||
NotAssignedException.Check(this, _behaviourController);
|
NotAssignedException.Check(this, _behaviourController);
|
||||||
|
NotAssignedException.Check(this, _stateEnable);
|
||||||
if (!_behaviourController.Initialize())
|
NotAssignedException.Check(this, _gameManager);
|
||||||
throw new System.Exception($"Failed to Initialize {BehaviourController.GetType().Name} on {Transform.GameObject.Name}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
if (!StateEnable.Enabled)
|
if (!_stateEnable.Enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OnUpdated?.Invoke(this);
|
OnUpdated?.Invoke(this);
|
||||||
@ -63,25 +62,23 @@ public class GameObject : BaseEntity, IGameObject
|
|||||||
{
|
{
|
||||||
base.FinalizeInternal();
|
base.FinalizeInternal();
|
||||||
|
|
||||||
if (!_behaviourController.Finalize())
|
foreach (IBehaviour behaviour in _behaviourController.GetBehaviours<IBehaviour>())
|
||||||
throw new System.Exception($"Failed to Finalize {BehaviourController.GetType().Name} on {Transform.GameObject.Name}");
|
behaviour.Finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Assign(ITransform transform)
|
public bool Assign(ITransform transform)
|
||||||
{
|
{
|
||||||
if (IsInitialized)
|
if (Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_transform = transform;
|
_transform = transform;
|
||||||
OnTransformAssigned?.Invoke(this);
|
OnTransformAssigned?.Invoke(this);
|
||||||
transform.OnParentChanged += OnParentChangedInternal;
|
|
||||||
OnParentChangedInternal(transform, null, transform.Parent);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Assign(IBehaviourController behaviourController)
|
public bool Assign(IBehaviourController behaviourController)
|
||||||
{
|
{
|
||||||
if (IsInitialized)
|
if (Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_behaviourController = behaviourController;
|
_behaviourController = behaviourController;
|
||||||
@ -89,63 +86,32 @@ public class GameObject : BaseEntity, IGameObject
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Assign(IGameManager gameManager)
|
||||||
|
{
|
||||||
|
if (Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_gameManager = gameManager;
|
||||||
|
OnGameManagerAssigned?.Invoke(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void UnassignInternal()
|
protected override void UnassignInternal()
|
||||||
{
|
{
|
||||||
base.UnassignInternal();
|
base.UnassignInternal();
|
||||||
|
|
||||||
_transform.OnParentChanged -= OnParentChangedInternal;
|
_stateEnable = null!;
|
||||||
OnParentChangedInternal(_transform, _transform.Parent, null);
|
|
||||||
_transform = null!;
|
_transform = null!;
|
||||||
_behaviourController = null!;
|
_behaviourController = null!;
|
||||||
_gameManager = null!;
|
_gameManager = null!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameObject() { OnBehaviourControllerAssigned += ConnectBehaviourController; }
|
public GameObject() { OnBehaviourControllerAssigned += ConnectBehaviourController; }
|
||||||
|
|
||||||
private void ConnectBehaviourController(IAssignableBehaviourController controller)
|
private void ConnectBehaviourController(IAssignableBehaviourController controller)
|
||||||
{
|
{
|
||||||
controller.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
|
controller.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
|
||||||
controller.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved;
|
controller.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved;
|
||||||
}
|
}
|
||||||
private void OnBehaviourRemoved(IBehaviourController _, IBehaviour behaviour) { if (IsInitialized) behaviour.Finalize(); }
|
private void OnBehaviourRemoved(IBehaviourController _, IBehaviour behaviour) { if (Initialized) behaviour.Initialize(); }
|
||||||
private void OnBehaviourAdded(IBehaviourController _, IBehaviour behaviour) { if (!IsInitialized) behaviour.Initialize(); }
|
private void OnBehaviourAdded(IBehaviourController _, IBehaviour behaviour) { if (Initialized) behaviour.Finalize(); }
|
||||||
|
|
||||||
private void OnParentChangedInternal(ITransform sender, ITransform? previousParent, ITransform? newParent)
|
|
||||||
{
|
|
||||||
if (previousParent is not null)
|
|
||||||
{
|
|
||||||
previousParent.OnParentChanged -= OnParentChangedInternal;
|
|
||||||
previousParent.GameObject.OnEnteredHierarchy -= EnterHierarchyInternal;
|
|
||||||
previousParent.GameObject.OnExitedHierarchy -= ExitHierarchyInternal;
|
|
||||||
}
|
|
||||||
if (newParent is not null)
|
|
||||||
{
|
|
||||||
newParent.OnParentChanged += OnParentChangedInternal;
|
|
||||||
newParent.GameObject.OnEnteredHierarchy += EnterHierarchyInternal;
|
|
||||||
newParent.GameObject.OnExitedHierarchy += ExitHierarchyInternal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnterHierarchyInternal(IHierarchyObject sender, IGameManager gameManager) => ((IHierarchyObject)this).EnterHierarchy(gameManager);
|
|
||||||
private void ExitHierarchyInternal(IHierarchyObject sender, IGameManager gameManager) => ((IHierarchyObject)this).ExitHierarchy();
|
|
||||||
|
|
||||||
bool IHierarchyObject.EnterHierarchy(IGameManager gameManager)
|
|
||||||
{
|
|
||||||
if (IsInHierarchy)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_gameManager = gameManager;
|
|
||||||
OnEnteredHierarchy?.Invoke(this, gameManager);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IHierarchyObject.ExitHierarchy()
|
|
||||||
{
|
|
||||||
if (!IsInHierarchy || _gameManager is not IGameManager gameManager)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_gameManager = null!;
|
|
||||||
OnExitedHierarchy?.Invoke(this, gameManager);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,142 +0,0 @@
|
|||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
public abstract class HierarchyObjectBase : IHierarchyObject
|
|
||||||
{
|
|
||||||
public event IHierarchyObject.OnEnteredHierarchyEventHandler? OnEnteredHierarchy = null;
|
|
||||||
public event IHierarchyObject.OnExitedHierarchyEventHandler? OnExitedHierarchy = null;
|
|
||||||
public event IEntity.OnIdChangedEventHandler? OnIdChanged = null;
|
|
||||||
public event IInitialize.OnInitializedEventHandler? OnInitialized = null;
|
|
||||||
public event IInitialize.OnFinalizedEventHandler? OnFinalized = null;
|
|
||||||
public event IAssignableStateEnable.OnStateEnableAssignedEventHandler? OnStateEnableAssigned = null;
|
|
||||||
public event IAssignable.OnUnassignedEventHandler? OnUnassigned = null;
|
|
||||||
public event INameable.OnNameChangedEventHandler? OnNameChanged = null;
|
|
||||||
|
|
||||||
private string _id = string.Empty;
|
|
||||||
private string _name = nameof(HierarchyObjectBase);
|
|
||||||
private bool _initialized = false;
|
|
||||||
private IStateEnable _stateEnable = null!;
|
|
||||||
private IGameManager _gameManager = null!;
|
|
||||||
|
|
||||||
public IGameManager GameManager => _gameManager;
|
|
||||||
|
|
||||||
public bool IsInHierarchy => _gameManager is not null;
|
|
||||||
|
|
||||||
public bool IsInitialized
|
|
||||||
{
|
|
||||||
get => _initialized;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
if (value == _initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_initialized = value;
|
|
||||||
if (value)
|
|
||||||
OnInitialized?.Invoke(this);
|
|
||||||
else
|
|
||||||
OnFinalized?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual IStateEnable StateEnable => _stateEnable;
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get => _name;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _name) return;
|
|
||||||
|
|
||||||
string previousName = _name;
|
|
||||||
_name = value;
|
|
||||||
OnNameChanged?.Invoke(this, previousName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Id
|
|
||||||
{
|
|
||||||
get => _id;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _id)
|
|
||||||
return;
|
|
||||||
|
|
||||||
string previousId = _id;
|
|
||||||
|
|
||||||
_id = value;
|
|
||||||
OnIdChanged?.Invoke(this, previousId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Assign(IStateEnable stateEnable)
|
|
||||||
{
|
|
||||||
if (IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_stateEnable = stateEnable;
|
|
||||||
_stateEnable.Assign(this);
|
|
||||||
OnStateEnableAssigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void UnassignInternal() { }
|
|
||||||
public bool Unassign()
|
|
||||||
{
|
|
||||||
if (IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
UnassignInternal();
|
|
||||||
|
|
||||||
OnUnassigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void InitializeInternal() { }
|
|
||||||
public bool Initialize()
|
|
||||||
{
|
|
||||||
if (IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
InitializeInternal();
|
|
||||||
|
|
||||||
IsInitialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void FinalizeInternal() { }
|
|
||||||
public bool Finalize()
|
|
||||||
{
|
|
||||||
if (!IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
FinalizeInternal();
|
|
||||||
|
|
||||||
IsInitialized = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnEnteringHierarchy(IGameManager gameManager) { }
|
|
||||||
bool IHierarchyObject.EnterHierarchy(IGameManager gameManager)
|
|
||||||
{
|
|
||||||
if (IsInHierarchy)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_gameManager = gameManager;
|
|
||||||
OnEnteringHierarchy(gameManager);
|
|
||||||
OnEnteredHierarchy?.Invoke(this, gameManager);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnExitingHierarchy(IGameManager gameManager) { }
|
|
||||||
bool IHierarchyObject.ExitHierarchy()
|
|
||||||
{
|
|
||||||
if (!IsInHierarchy || _gameManager is not IGameManager gameManager)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_gameManager = null!;
|
|
||||||
OnExitingHierarchy(gameManager);
|
|
||||||
OnExitedHierarchy?.Invoke(this, gameManager);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,10 +4,9 @@ using System.Numerics;
|
|||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class Math
|
public static class Math
|
||||||
{
|
{/// <summary>
|
||||||
/// <summary>
|
/// The value of Pi (π), a mathematical constant approximately equal to 3.14159.
|
||||||
/// 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>
|
||||||
@ -38,20 +37,6 @@ public static class Math
|
|||||||
/// <returns>The absolute value of <paramref name="x"/>.</returns>
|
/// <returns>The absolute value of <paramref name="x"/>.</returns>
|
||||||
public static T Abs<T>(T x) where T : INumber<T> => x > T.Zero ? x : -x;
|
public static T Abs<T>(T x) where T : INumber<T> => x > T.Zero ? x : -x;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the cosine of a number.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="x">The number.</param>
|
|
||||||
/// <returns>The cosine of <paramref name="x"/>.</returns>
|
|
||||||
public static float Cos(float x) => MathF.Cos(x);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the sine of a number.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="x">The number.</param>
|
|
||||||
/// <returns>The sine of <paramref name="x"/>.</returns>
|
|
||||||
public static float Sin(float x) => MathF.Sin(x);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the arccosine of a number.
|
/// Returns the arccosine of a number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -89,7 +74,7 @@ public static class Math
|
|||||||
/// <param name="min">The minimum value.</param>
|
/// <param name="min">The minimum value.</param>
|
||||||
/// <param name="max">The maximum value.</param>
|
/// <param name="max">The maximum value.</param>
|
||||||
/// <returns>The clamped value.</returns>
|
/// <returns>The clamped value.</returns>
|
||||||
public static T Clamp<T>(T x, T min, T max) where T : INumber<T> => (x < min) ? min : (x > max) ? max : x;
|
public static T Clamp<T>(this T x, T min, T max) where T : INumber<T> => (x < min) ? min : (x > max) ? max : x;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the smallest integral value that is greater than or equal to the specified number.
|
/// Returns the smallest integral value that is greater than or equal to the specified number.
|
||||||
@ -171,16 +156,6 @@ public static class Math
|
|||||||
/// <returns>The number <paramref name="x"/> raised to the power <paramref name="y"/>.</returns>
|
/// <returns>The number <paramref name="x"/> raised to the power <paramref name="y"/>.</returns>
|
||||||
public static float Pow(float x, float y) => MathF.Pow(x, y);
|
public static float Pow(float x, float y) => MathF.Pow(x, y);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Performs linear interpolation between two specified values.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of the values, which must implement <see cref="IFloatingPoint{T}"/>.</typeparam>
|
|
||||||
/// <param name="x">The starting value of the interpolation.</param>
|
|
||||||
/// <param name="y">The ending value of the interpolation.</param>
|
|
||||||
/// <param name="t">The interpolation factor, typically in the range [0, 1].</param>
|
|
||||||
/// <returns>A value that represents the linear interpolation between <paramref name="x"/> and <paramref name="y"/>.</returns>
|
|
||||||
public static T Lerp<T>(T x, T y, T t) where T : IFloatingPoint<T> => x + (y - x) * t;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rounds a number to a specified number of fractional digits.
|
/// Rounds a number to a specified number of fractional digits.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -211,4 +186,5 @@ public static class Math
|
|||||||
/// <param name="x">The number.</param>
|
/// <param name="x">The number.</param>
|
||||||
/// <returns>The integral part of <paramref name="x"/>.</returns>
|
/// <returns>The integral part of <paramref name="x"/>.</returns>
|
||||||
public static float Truncate(float x) => MathF.Truncate(x);
|
public static float Truncate(float x) => MathF.Truncate(x);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
public static class MathExtensions
|
|
||||||
{
|
|
||||||
/// <inheritdoc cref="Math.Abs{T}(T)" />
|
|
||||||
public static T Abs<T>(this T x) where T : INumber<T> => Math.Abs(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Cos(float)" />
|
|
||||||
public static float Cos(this float x) => Math.Cos(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Sin(float)" />
|
|
||||||
public static float Sin(this float x) => Math.Sin(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Acos(float)" />
|
|
||||||
public static float Acos(this float x) => Math.Acos(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Asin(float)" />
|
|
||||||
public static float Asin(this float x) => Math.Asin(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Atan2(float, float)" />
|
|
||||||
public static float Atan2(this float y, float x) => Math.Atan2(y, x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Atanh(float)" />
|
|
||||||
public static float Atanh(this float x) => Math.Atanh(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Clamp{T}(T, T, T)" />
|
|
||||||
public static T Clamp<T>(this T x, T min, T max) where T : INumber<T> => Math.Clamp(x, min, max);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Ceiling(float)" />
|
|
||||||
public static float Ceiling(this float x) => Math.Ceiling(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.CopySign(float, float)" />
|
|
||||||
public static float CopySign(this float x, float y) => Math.CopySign(x, y);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Floor(float)" />
|
|
||||||
public static float Floor(this float x) => Math.Floor(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.IEEERemainder(float, float)" />
|
|
||||||
public static float IEEERemainder(this float x, float y) => Math.IEEERemainder(x, y);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Log(float, float)" />
|
|
||||||
public static float Log(this float x, float y) => Math.Log(x, y);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Max{T}(T, T)" />
|
|
||||||
public static T Max<T>(this T x, T y) where T : INumber<T> => Math.Max(x, y);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.AbsMax{T}(T, T)" />
|
|
||||||
public static T AbsMax<T>(this T x, T y) where T : INumber<T> => Math.AbsMax(x, y);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Min{T}(T, T)" />
|
|
||||||
public static T Min<T>(this T x, T y) where T : INumber<T> => Math.Min(x, y);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.AbsMin{T}(T, T)" />
|
|
||||||
public static T AbsMin<T>(this T x, T y) where T : INumber<T> => Math.AbsMin(x, y);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Pow(float, float)" />
|
|
||||||
public static float Pow(this float x, float y) => Math.Pow(x, y);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Lerp{T}(T, T, T)" />
|
|
||||||
public static T Lerp<T>(this T x, T y, T t) where T : IFloatingPoint<T> => Math.Lerp(x, y, t);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Round(float, int, MidpointRounding)" />
|
|
||||||
public static float Round(this float x, int digits, MidpointRounding mode) => Math.Round(x, digits, mode);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Sqr{T}(T)" />
|
|
||||||
public static T Sqr<T>(this T x) where T : INumber<T> => Math.Sqr(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Sqrt(float)" />
|
|
||||||
public static float Sqrt(this float x) => Math.Sqrt(x);
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Truncate(float)" />
|
|
||||||
public static float Truncate(this float x) => Math.Truncate(x);
|
|
||||||
}
|
|
@ -1,12 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class StateEnable : IStateEnable
|
public class StateEnable : IStateEnable
|
||||||
{
|
{
|
||||||
public event IAssignable.OnUnassignedEventHandler? OnUnassigned = null;
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
||||||
public event IAssignableEntity.OnEntityAssignedEventHandler? OnEntityAssigned = null;
|
public Action<IAssignableEntity>? OnEntityAssigned { get; set; } = null;
|
||||||
public event IStateEnable.OnNameChangedEventHandler? OnEnabledChanged = null;
|
public Action<IStateEnable>? OnEnabledChanged { get; set; } = null;
|
||||||
|
|
||||||
private bool _enabled = true;
|
private bool _enabled = true;
|
||||||
private IEntity _entity = null!;
|
private IEntity _entity = null!;
|
||||||
@ -21,15 +23,14 @@ public class StateEnable : IStateEnable
|
|||||||
if (value == _enabled)
|
if (value == _enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool previousState = _enabled;
|
|
||||||
_enabled = value;
|
_enabled = value;
|
||||||
OnEnabledChanged?.Invoke(this, previousState);
|
OnEnabledChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Assign(IEntity entity)
|
public bool Assign(IEntity entity)
|
||||||
{
|
{
|
||||||
if (_entity is not null && _entity.IsInitialized)
|
if (_entity is not null && _entity.Initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_entity = entity;
|
_entity = entity;
|
||||||
|
@ -1,41 +1,20 @@
|
|||||||
using System.Collections;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("Name: {GameObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
|
[System.Diagnostics.DebuggerDisplay("Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
|
||||||
public class Transform : ITransform
|
public class Transform : ITransform
|
||||||
{
|
{
|
||||||
public event IAssignableGameObject.OnGameObjectAssignedEventHandler? OnGameObjectAssigned = null;
|
public Action<ITransform>? OnPositionChanged { get; set; } = null;
|
||||||
|
public Action<ITransform>? OnScaleChanged { get; set; } = null;
|
||||||
public event IAssignable.OnUnassignedEventHandler? OnUnassigned = null;
|
public Action<ITransform>? OnRotationChanged { get; set; } = null;
|
||||||
|
|
||||||
public event ITransform.OnPositionChangedEventHandler? OnPositionChanged = null;
|
|
||||||
public event ITransform.OnScaleChangedEventHandler? OnScaleChanged = null;
|
|
||||||
public event ITransform.OnRotationChangedEventHandler? OnRotationChanged = null;
|
|
||||||
|
|
||||||
public event ITransform.OnParentChangedEventHandler? OnParentChanged = null;
|
|
||||||
public event ITransform.OnChildrenAddedEventHandler? OnChildrenAdded = null;
|
|
||||||
public event ITransform.OnChildrenRemovedEventHandler? OnChildrenRemoved = null;
|
|
||||||
|
|
||||||
|
|
||||||
private Vector2D _position = Vector2D.Zero;
|
private Vector2D _position = Vector2D.Zero;
|
||||||
private Vector2D _scale = Vector2D.One;
|
private Vector2D _scale = Vector2D.One;
|
||||||
private float _rotation = 0f;
|
private float _rotation = 0f;
|
||||||
|
|
||||||
private Vector2D _localPosition = Vector2D.Zero;
|
|
||||||
private Vector2D _localScale = Vector2D.One;
|
|
||||||
private float _localRotation = 0f;
|
|
||||||
|
|
||||||
private readonly List<ITransform> _children = [];
|
|
||||||
|
|
||||||
public IGameObject GameObject { get; private set; } = null!;
|
|
||||||
public ITransform? Parent { get; private set; } = null;
|
|
||||||
|
|
||||||
public IReadOnlyList<ITransform> Children => _children;
|
|
||||||
|
|
||||||
public Vector2D Position
|
public Vector2D Position
|
||||||
{
|
{
|
||||||
get => _position;
|
get => _position;
|
||||||
@ -45,238 +24,33 @@ public class Transform : ITransform
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_position = value;
|
_position = value;
|
||||||
UpdateLocalPosition();
|
|
||||||
OnPositionChanged?.Invoke(this);
|
OnPositionChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2D Scale
|
public Vector2D Scale
|
||||||
{
|
{
|
||||||
get => _localScale.Scale(Parent?.Scale ?? Vector2D.One);
|
get => _scale;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == _scale)
|
if (value == _scale)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_scale = value;
|
_scale = value;
|
||||||
UpdateLocalScale();
|
|
||||||
OnScaleChanged?.Invoke(this);
|
OnScaleChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Rotation
|
public float Rotation
|
||||||
{
|
{
|
||||||
get => _localRotation + (Parent?.Rotation ?? 0f);
|
get => _rotation;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == _rotation)
|
if (value == _rotation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_rotation = value;
|
_rotation = value;
|
||||||
UpdateLocalPosition();
|
|
||||||
OnRotationChanged?.Invoke(this);
|
OnRotationChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2D LocalPosition
|
|
||||||
{
|
|
||||||
get => _localPosition;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _localPosition)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_localPosition = value;
|
|
||||||
UpdatePosition();
|
|
||||||
OnPositionChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2D LocalScale
|
|
||||||
{
|
|
||||||
get => _localScale;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _localScale)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_localScale = value;
|
|
||||||
UpdateScale();
|
|
||||||
OnScaleChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float LocalRotation
|
|
||||||
{
|
|
||||||
get => _localRotation;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _localRotation)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_localRotation = value;
|
|
||||||
UpdateRotation();
|
|
||||||
OnRotationChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetParent(ITransform? transform)
|
|
||||||
{
|
|
||||||
if (transform == this || Parent == transform)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ITransform? previousParent = Parent;
|
|
||||||
if (previousParent is not null)
|
|
||||||
{
|
|
||||||
previousParent.RemoveChild(this);
|
|
||||||
previousParent.OnPositionChanged -= RecalculatePosition;
|
|
||||||
previousParent.OnScaleChanged -= RecalculateScale;
|
|
||||||
previousParent.OnRotationChanged -= RecalculateRotation;
|
|
||||||
previousParent.OnParentChanged -= NotifyChildrenOnParentChange;
|
|
||||||
}
|
|
||||||
|
|
||||||
Parent = transform;
|
|
||||||
|
|
||||||
if (transform is not null)
|
|
||||||
{
|
|
||||||
transform.AddChild(this);
|
|
||||||
transform.OnPositionChanged += RecalculatePosition;
|
|
||||||
transform.OnScaleChanged += RecalculateScale;
|
|
||||||
transform.OnRotationChanged += RecalculateRotation;
|
|
||||||
transform.OnParentChanged += NotifyChildrenOnParentChange;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateLocalPosition();
|
|
||||||
UpdateLocalScale();
|
|
||||||
UpdateLocalRotation();
|
|
||||||
|
|
||||||
OnParentChanged?.Invoke(this, previousParent, transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddChild(ITransform transform)
|
|
||||||
{
|
|
||||||
if (_children.Contains(transform))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_children.Add(transform);
|
|
||||||
transform.SetParent(this);
|
|
||||||
OnChildrenAdded?.Invoke(this, transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveChild(ITransform transform)
|
|
||||||
{
|
|
||||||
if (!_children.Remove(transform))
|
|
||||||
return;
|
|
||||||
|
|
||||||
transform.SetParent(null);
|
|
||||||
OnChildrenRemoved?.Invoke(this, transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<ITransform> GetEnumerator() => _children.GetEnumerator();
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => _children.GetEnumerator();
|
|
||||||
|
|
||||||
private void NotifyChildrenOnParentChange(ITransform transform, ITransform? previousParent, ITransform? newParent)
|
|
||||||
{
|
|
||||||
// TODO No idea how logical this is to propagate this to the children the way I'm doing right now.
|
|
||||||
// I was originally gonna just call `child.OnParentChanged?.Invoke(child, child.Parent);` but seems an unnecessary call too?
|
|
||||||
foreach (var child in Children) // TODO CHECK ERRORS
|
|
||||||
child.SetParent(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RecalculatePosition(ITransform _)
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
UpdatePosition();
|
|
||||||
OnPositionChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RecalculateScale(ITransform _)
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
UpdateScale();
|
|
||||||
OnScaleChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RecalculateRotation(ITransform _)
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
UpdatePosition();
|
|
||||||
UpdateRotation();
|
|
||||||
OnPositionChanged?.Invoke(this);
|
|
||||||
OnRotationChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateLocalPosition()
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
_localPosition = Position;
|
|
||||||
else
|
|
||||||
_localPosition = Parent.Position.FromTo(Position).Scale(Parent.Scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateLocalScale()
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
_localScale = Scale;
|
|
||||||
else
|
|
||||||
_localScale = Scale.Scale(new(1f / Parent.Scale.X, 1f / Parent.Scale.Y));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateLocalRotation()
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
_localRotation = Rotation;
|
|
||||||
else
|
|
||||||
_localRotation = Rotation - Parent.Rotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdatePosition()
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
_position = LocalPosition.Rotate(0f * Math.DegreeToRadian);
|
|
||||||
else
|
|
||||||
_position = Parent.Position + LocalPosition.Scale(new(Parent.Scale.X, Parent.Scale.Y)).Rotate(Parent.Rotation * Math.DegreeToRadian);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateScale()
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
_scale = LocalScale;
|
|
||||||
else
|
|
||||||
_scale = Vector2D.Scale(Parent.Scale, LocalScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateRotation()
|
|
||||||
{
|
|
||||||
if (Parent is null)
|
|
||||||
_rotation = LocalRotation;
|
|
||||||
else
|
|
||||||
_rotation = Parent.Rotation + LocalRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Assign(IGameObject gameObject)
|
|
||||||
{
|
|
||||||
if (GameObject is not null && GameObject.IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
GameObject = gameObject;
|
|
||||||
OnGameObjectAssigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Unassign()
|
|
||||||
{
|
|
||||||
if (GameObject is not null && GameObject.IsInitialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
GameObject = null!;
|
|
||||||
OnUnassigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,11 @@ namespace Syntriax.Engine.Input;
|
|||||||
|
|
||||||
public interface IButtonInputs<T> : IAssignableStateEnable
|
public interface IButtonInputs<T> : IAssignableStateEnable
|
||||||
{
|
{
|
||||||
event ButtonCallbackEventHandler? OnAnyButtonPressed;
|
void RegisterOnPress(T button, Action<IButtonInputs<T>, T> callback);
|
||||||
event ButtonCallbackEventHandler? OnAnyButtonReleased;
|
void UnregisterOnPress(T button, Action<IButtonInputs<T>, T> callback);
|
||||||
|
void RegisterOnRelease(T button, Action<IButtonInputs<T>, T> callback);
|
||||||
void RegisterOnPress(T button, ButtonCallbackEventHandler callback);
|
void UnregisterOnRelease(T button, Action<IButtonInputs<T>, T> callback);
|
||||||
void UnregisterOnPress(T button, ButtonCallbackEventHandler callback);
|
|
||||||
void RegisterOnRelease(T button, ButtonCallbackEventHandler callback);
|
|
||||||
void UnregisterOnRelease(T button, ButtonCallbackEventHandler callback);
|
|
||||||
|
|
||||||
bool IsPressed(T button);
|
bool IsPressed(T button);
|
||||||
|
bool WasPressed(T button);
|
||||||
delegate void ButtonCallbackEventHandler(IButtonInputs<T> buttonInputs, T button);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
@ -10,17 +12,17 @@ public interface ICollider2D : IBehaviour, IAssignableTransform
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a collision is detected.
|
/// Event triggered when a collision is detected.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnCollisionDetectedEventHandler? OnCollisionDetected;
|
Action<ICollider2D, CollisionDetectionInformation>? OnCollisionDetected { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a collision is resolved.
|
/// Event triggered when a collision is resolved.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnCollisionResolvedEventHandler? OnCollisionResolved;
|
Action<ICollider2D, CollisionDetectionInformation>? OnCollisionResolved { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when another <see cref="ICollider2D"/> triggers this <see cref="ICollider2D"/>.
|
/// Event triggered when another <see cref="ICollider2D"/> triggers this <see cref="ICollider2D"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event OnTriggeredEventHandler? OnTriggered;
|
Action<ICollider2D, ICollider2D>? OnTriggered { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="IRigidBody2D"/> associated with the <see cref="ICollider2D"/>.
|
/// The <see cref="IRigidBody2D"/> associated with the <see cref="ICollider2D"/>.
|
||||||
@ -36,12 +38,4 @@ public interface ICollider2D : IBehaviour, IAssignableTransform
|
|||||||
/// Recalculates <see cref="ICollider2D"/> properties.
|
/// Recalculates <see cref="ICollider2D"/> properties.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Recalculate();
|
void Recalculate();
|
||||||
|
|
||||||
void Detect(CollisionDetectionInformation collisionDetectionInformation);
|
|
||||||
void Resolve(CollisionDetectionInformation collisionDetectionInformation);
|
|
||||||
void Trigger(ICollider2D initiator);
|
|
||||||
|
|
||||||
delegate void OnCollisionDetectedEventHandler(ICollider2D sender, CollisionDetectionInformation collisionDetectionInformation);
|
|
||||||
delegate void OnCollisionResolvedEventHandler(ICollider2D sender, CollisionDetectionInformation collisionDetectionInformation);
|
|
||||||
delegate void OnTriggeredEventHandler(ICollider2D sender, ICollider2D initiatorCollider);
|
|
||||||
}
|
}
|
||||||
|
@ -5,16 +5,6 @@ namespace Syntriax.Engine.Physics2D.Abstract;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPhysicsEngine2D
|
public interface IPhysicsEngine2D
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when the <see cref="IPhysicsEngine2D"/> has done a single physics iteration.
|
|
||||||
/// </summary>
|
|
||||||
event OnPhysicsIterationEventHandler? OnPhysicsIteration;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event triggered when the <see cref="IPhysicsEngine2D"/> has done a full physics step/>.
|
|
||||||
/// </summary>
|
|
||||||
event OnPhysicsStepEventHandler? OnPhysicsStep;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of iterations the <see cref="IPhysicsEngine2D"/> performs per step.
|
/// The number of iterations the <see cref="IPhysicsEngine2D"/> performs per step.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -25,7 +15,4 @@ public interface IPhysicsEngine2D
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="deltaTime">The time step.</param>
|
/// <param name="deltaTime">The time step.</param>
|
||||||
void Step(float deltaTime);
|
void Step(float deltaTime);
|
||||||
|
|
||||||
delegate void OnPhysicsIterationEventHandler(IPhysicsEngine2D sender, float iterationDeltaTime);
|
|
||||||
delegate void OnPhysicsStepEventHandler(IPhysicsEngine2D sender, float stepDeltaTime);
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a <see cref="IBehaviour"/> that listens to physics simulation update phase.
|
|
||||||
/// </summary>
|
|
||||||
public interface IPhysicsUpdate : IBehaviour
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the physics state of the object based on the elapsed time since the last update.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="delta">The time elapsed since the last physics update, typically in seconds.</param>
|
|
||||||
void PhysicsUpdate(float delta);
|
|
||||||
}
|
|
@ -1,14 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
namespace Syntriax.Engine.Physics2D;
|
||||||
|
|
||||||
public abstract class Collider2DBehaviourBase : Behaviour, ICollider2D
|
public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
||||||
{
|
{
|
||||||
public event ICollider2D.OnCollisionDetectedEventHandler? OnCollisionDetected = null;
|
public Action<ICollider2D, CollisionDetectionInformation>? OnCollisionDetected { get; set; } = null;
|
||||||
public event ICollider2D.OnCollisionResolvedEventHandler? OnCollisionResolved = null;
|
public Action<ICollider2D, CollisionDetectionInformation>? OnCollisionResolved { get; set; } = null;
|
||||||
public event ICollider2D.OnTriggeredEventHandler? OnTriggered = null;
|
public Action<ICollider2D, ICollider2D>? OnTriggered { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
protected bool NeedsRecalculation { get; private set; } = true;
|
protected bool NeedsRecalculation { get; private set; } = true;
|
||||||
@ -18,7 +20,7 @@ public abstract class Collider2DBehaviourBase : Behaviour, ICollider2D
|
|||||||
public bool IsTrigger { get; set; } = false;
|
public bool IsTrigger { get; set; } = false;
|
||||||
|
|
||||||
ITransform IAssignableTransform.Transform => Transform;
|
ITransform IAssignableTransform.Transform => Transform;
|
||||||
public event IAssignableTransform.OnTransformAssignedEventHandler? OnTransformAssigned { add => GameObject.OnTransformAssigned += value; remove => GameObject.OnTransformAssigned -= value; }
|
Action<IAssignableTransform>? IAssignableTransform.OnTransformAssigned { get => GameObject.OnTransformAssigned; set => GameObject.OnTransformAssigned = value; }
|
||||||
|
|
||||||
bool IAssignableTransform.Assign(ITransform transform) => GameObject.Assign(transform);
|
bool IAssignableTransform.Assign(ITransform transform) => GameObject.Assign(transform);
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ public abstract class Collider2DBehaviourBase : Behaviour, ICollider2D
|
|||||||
|
|
||||||
protected override void OnInitialize()
|
protected override void OnInitialize()
|
||||||
{
|
{
|
||||||
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
|
BehaviourController.TryGetBehaviour(out _rigidBody2D);
|
||||||
|
|
||||||
BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController;
|
BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController;
|
||||||
BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController;
|
BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController;
|
||||||
@ -43,12 +45,6 @@ public abstract class Collider2DBehaviourBase : Behaviour, ICollider2D
|
|||||||
Transform.OnPositionChanged += SetNeedsRecalculation;
|
Transform.OnPositionChanged += SetNeedsRecalculation;
|
||||||
Transform.OnRotationChanged += SetNeedsRecalculation;
|
Transform.OnRotationChanged += SetNeedsRecalculation;
|
||||||
Transform.OnScaleChanged += SetNeedsRecalculation;
|
Transform.OnScaleChanged += SetNeedsRecalculation;
|
||||||
Transform.OnParentChanged += UpdateRigidBody2D;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateRigidBody2D(ITransform sender, ITransform? previousParent, ITransform? newParent)
|
|
||||||
{
|
|
||||||
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour)
|
private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour)
|
||||||
@ -74,8 +70,4 @@ public abstract class Collider2DBehaviourBase : Behaviour, ICollider2D
|
|||||||
Transform.OnPositionChanged -= SetNeedsRecalculation;
|
Transform.OnPositionChanged -= SetNeedsRecalculation;
|
||||||
Transform.OnRotationChanged -= SetNeedsRecalculation;
|
Transform.OnRotationChanged -= SetNeedsRecalculation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation);
|
|
||||||
public void Resolve(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionResolved?.Invoke(this, collisionDetectionInformation);
|
|
||||||
public void Trigger(ICollider2D initiator) => OnTriggered?.Invoke(this, initiator);
|
|
||||||
}
|
}
|
||||||
|
@ -6,16 +6,14 @@ namespace Syntriax.Engine.Physics2D;
|
|||||||
[System.Diagnostics.DebuggerDisplay("Normal: {Normal.ToString(), nq}, Penetration: {Penetration}")]
|
[System.Diagnostics.DebuggerDisplay("Normal: {Normal.ToString(), nq}, Penetration: {Penetration}")]
|
||||||
public readonly struct CollisionDetectionInformation
|
public readonly struct CollisionDetectionInformation
|
||||||
(
|
(
|
||||||
ICollider2D Detector,
|
ICollider2D Left,
|
||||||
ICollider2D Detected,
|
ICollider2D Right,
|
||||||
Vector2D Normal,
|
Vector2D Normal,
|
||||||
float Penetration
|
float Penetration
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
public ICollider2D Detector { get; init; } = Detector;
|
public ICollider2D Left { get; init; } = Left;
|
||||||
public ICollider2D Detected { get; init; } = Detected;
|
public ICollider2D Right { get; init; } = Right;
|
||||||
public Vector2D Normal { get; init; } = Normal;
|
public Vector2D Normal { get; init; } = Normal;
|
||||||
public float Penetration { get; init; } = Penetration;
|
public float Penetration { get; init; } = Penetration;
|
||||||
|
|
||||||
public CollisionDetectionInformation Reverse() => new(Detected, Detector, -Normal, Penetration);
|
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public class CollisionDetector2D : ICollisionDetector2D
|
|||||||
if (!leftProjection.Overlaps(rightProjection, out float depth))
|
if (!leftProjection.Overlaps(rightProjection, out float depth))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (collisionInformation.Detector is null || Math.Abs(collisionInformation.Penetration) > Math.Abs(depth))
|
if (collisionInformation.Left is null || Math.Abs(collisionInformation.Penetration) > Math.Abs(depth))
|
||||||
collisionInformation = new(left, right, projectionVector, depth);
|
collisionInformation = new(left, right, projectionVector, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ public class CollisionDetector2D : ICollisionDetector2D
|
|||||||
if (!shapeProjection.Overlaps(circleProjection, out float depth))
|
if (!shapeProjection.Overlaps(circleProjection, out float depth))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (collisionInformation.Detector is null || Math.Abs(collisionInformation.Penetration) > Math.Abs(depth))
|
if (collisionInformation.Left is null || Math.Abs(collisionInformation.Penetration) > Math.Abs(depth))
|
||||||
collisionInformation = new(shapeCollider, circleCollider, projectionVector, depth);
|
collisionInformation = new(shapeCollider, circleCollider, projectionVector, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ public class CollisionDetector2D : ICollisionDetector2D
|
|||||||
if (!shapeProjection.Overlaps(circleProjection, out float depth))
|
if (!shapeProjection.Overlaps(circleProjection, out float depth))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (collisionInformation.Detector is null || Math.Abs(collisionInformation.Penetration) > Math.Abs(depth))
|
if (collisionInformation.Left is null || Math.Abs(collisionInformation.Penetration) > Math.Abs(depth))
|
||||||
collisionInformation = new(shapeCollider, circleCollider, shapeToCircleProjectionVector, depth);
|
collisionInformation = new(shapeCollider, circleCollider, shapeToCircleProjectionVector, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ public class CollisionResolver2D : ICollisionResolver2D
|
|||||||
{
|
{
|
||||||
Vector2D displacementVector = collisionInformation.Normal * collisionInformation.Penetration;
|
Vector2D displacementVector = collisionInformation.Normal * collisionInformation.Penetration;
|
||||||
|
|
||||||
ICollider2D left = collisionInformation.Detector;
|
ICollider2D left = collisionInformation.Left;
|
||||||
ICollider2D right = collisionInformation.Detected;
|
ICollider2D right = collisionInformation.Right;
|
||||||
|
|
||||||
bool isLeftStatic = left.RigidBody2D?.IsStatic ?? true;
|
bool isLeftStatic = left.RigidBody2D?.IsStatic ?? true;
|
||||||
bool isRightStatic = right.RigidBody2D?.IsStatic ?? true;
|
bool isRightStatic = right.RigidBody2D?.IsStatic ?? true;
|
||||||
@ -38,7 +38,7 @@ public class CollisionResolver2D : ICollisionResolver2D
|
|||||||
left.Recalculate();
|
left.Recalculate();
|
||||||
right.Recalculate();
|
right.Recalculate();
|
||||||
|
|
||||||
left.Resolve(collisionInformation);
|
left.OnCollisionResolved?.Invoke(collisionInformation.Left, collisionInformation);
|
||||||
right.Resolve(collisionInformation);
|
right.OnCollisionResolved?.Invoke(right, collisionInformation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Physics2D;
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
using Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
namespace Engine.Physics2D;
|
||||||
|
|
||||||
public static partial class Physics2D
|
public static partial class Physics2D
|
||||||
{
|
{
|
||||||
public static bool Overlaps(this Shape shape, Vector2D point) => Overlaps(shape, point, out var _);
|
|
||||||
public static bool Overlaps(this Shape shape, Vector2D point, out float depth)
|
|
||||||
{
|
|
||||||
depth = float.MaxValue;
|
|
||||||
var vertices = shape.Vertices;
|
|
||||||
int count = vertices.Count;
|
|
||||||
|
|
||||||
for (int indexProjection = 0; indexProjection < count; indexProjection++)
|
|
||||||
{
|
|
||||||
Vector2D projectionVector = vertices[indexProjection].FromTo(vertices[(indexProjection + 1) % count]).Perpendicular().Normalized;
|
|
||||||
|
|
||||||
Projection shapeProjection = shape.ToProjection(projectionVector);
|
|
||||||
float projectedPoint = point.Dot(projectionVector);
|
|
||||||
|
|
||||||
if (shapeProjection.Max < projectedPoint || shapeProjection.Min > projectedPoint)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
depth = Math.Min(depth, Math.Abs(Math.AbsMin(shapeProjection.Max - projectedPoint, shapeProjection.Min - projectedPoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool Overlaps(this Circle left, Circle right)
|
public static bool Overlaps(this Circle left, Circle right)
|
||||||
{
|
{
|
||||||
float distanceSquared = left.Center.FromTo(right.Center).LengthSquared();
|
float distanceSquared = left.Center.FromTo(right.Center).LengthSquared();
|
||||||
@ -47,7 +27,7 @@ public static partial class Physics2D
|
|||||||
normal = distanceVector.Normalized;
|
normal = distanceVector.Normalized;
|
||||||
|
|
||||||
if (isOverlapping)
|
if (isOverlapping)
|
||||||
depth = Math.Sqrt(radiusSumSquared - distanceSquared);
|
depth = MathF.Sqrt(radiusSumSquared - distanceSquared);
|
||||||
|
|
||||||
return isOverlapping;
|
return isOverlapping;
|
||||||
}
|
}
|
||||||
@ -64,7 +44,7 @@ public static partial class Physics2D
|
|||||||
normal = distanceVector.Normalized;
|
normal = distanceVector.Normalized;
|
||||||
|
|
||||||
if (isOverlapping)
|
if (isOverlapping)
|
||||||
depth = Math.Sqrt(radiusSquared - distanceSquared);
|
depth = MathF.Sqrt(radiusSquared - distanceSquared);
|
||||||
|
|
||||||
return isOverlapping;
|
return isOverlapping;
|
||||||
}
|
}
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
|
||||||
|
|
||||||
public class PhysicsCoroutineManager : HierarchyObjectBase
|
|
||||||
{
|
|
||||||
private readonly List<IEnumerator> enumerators = [];
|
|
||||||
private IPhysicsEngine2D? physicsEngine = null;
|
|
||||||
|
|
||||||
public IEnumerator CreateCoroutine(IEnumerator enumerator)
|
|
||||||
{
|
|
||||||
enumerators.Add(enumerator);
|
|
||||||
return enumerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopCoroutine(IEnumerator enumerator)
|
|
||||||
{
|
|
||||||
enumerators.Remove(enumerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnEnteringHierarchy(IGameManager gameManager)
|
|
||||||
{
|
|
||||||
physicsEngine = gameManager.HierarchyObjects.FindObject<IPhysicsEngine2D>();
|
|
||||||
if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine)
|
|
||||||
foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep;
|
|
||||||
else
|
|
||||||
gameManager.OnUpdate += OnUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPhysicsStep(IPhysicsEngine2D sender, float stepDeltaTime)
|
|
||||||
{
|
|
||||||
for (int i = enumerators.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (enumerators[i].Current is ICoroutineYield coroutineYield && coroutineYield.Yield())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!enumerators[i].MoveNext())
|
|
||||||
enumerators.RemoveAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnExitingHierarchy(IGameManager gameManager)
|
|
||||||
{
|
|
||||||
if (physicsEngine is IPhysicsEngine2D existingPhysicsEngine)
|
|
||||||
existingPhysicsEngine.OnPhysicsStep -= OnPhysicsStep;
|
|
||||||
gameManager.OnUpdate -= OnUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUpdate(IGameManager sender, EngineTime time)
|
|
||||||
{
|
|
||||||
if (GameManager is not IGameManager gameManager)
|
|
||||||
return;
|
|
||||||
|
|
||||||
physicsEngine = gameManager.HierarchyObjects.FindObject<IPhysicsEngine2D>();
|
|
||||||
if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine)
|
|
||||||
{
|
|
||||||
foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep;
|
|
||||||
gameManager.OnUpdate -= OnUpdate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
@ -7,9 +8,6 @@ namespace Syntriax.Engine.Physics2D;
|
|||||||
|
|
||||||
public class PhysicsEngine2D : IPhysicsEngine2D
|
public class PhysicsEngine2D : IPhysicsEngine2D
|
||||||
{
|
{
|
||||||
public event IPhysicsEngine2D.OnPhysicsIterationEventHandler? OnPhysicsIteration = null;
|
|
||||||
public event IPhysicsEngine2D.OnPhysicsStepEventHandler? OnPhysicsStep = null;
|
|
||||||
|
|
||||||
private readonly List<IRigidBody2D> rigidBodies = new(32);
|
private readonly List<IRigidBody2D> rigidBodies = new(32);
|
||||||
private readonly List<ICollider2D> colliders = new(64);
|
private readonly List<ICollider2D> colliders = new(64);
|
||||||
|
|
||||||
@ -74,7 +72,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
|||||||
if (bothCollidersAreTriggers)
|
if (bothCollidersAreTriggers)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool bothCollidersAreStatic = (colliderX.RigidBody2D?.IsStatic ?? true) && (colliderY.RigidBody2D?.IsStatic ?? true);
|
bool bothCollidersAreStatic = colliderX.RigidBody2D?.IsStatic ?? true && colliderX.RigidBody2D?.IsStatic == colliderY.RigidBody2D?.IsStatic;
|
||||||
if (bothCollidersAreStatic)
|
if (bothCollidersAreStatic)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -82,33 +80,23 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
|||||||
{
|
{
|
||||||
if (colliderX.IsTrigger)
|
if (colliderX.IsTrigger)
|
||||||
{
|
{
|
||||||
colliderX.Trigger(colliderY);
|
colliderX.OnTriggered?.Invoke(colliderX, colliderY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (colliderY.IsTrigger)
|
else if (colliderY.IsTrigger)
|
||||||
{
|
{
|
||||||
colliderY.Trigger(colliderY);
|
colliderY.OnTriggered?.Invoke(colliderY, colliderY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (information.Detector == colliderX)
|
colliderX.OnCollisionDetected?.Invoke(colliderX, information);
|
||||||
{
|
colliderY.OnCollisionDetected?.Invoke(colliderY, information);
|
||||||
colliderX.Detect(information);
|
|
||||||
colliderY.Detect(information.Reverse());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
colliderX.Detect(information.Reverse());
|
|
||||||
colliderY.Detect(information);
|
|
||||||
}
|
|
||||||
|
|
||||||
collisionResolver?.Resolve(information);
|
collisionResolver?.Resolve(information);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OnPhysicsIteration?.Invoke(this, intervalDeltaTime);
|
|
||||||
}
|
}
|
||||||
OnPhysicsStep?.Invoke(this, deltaTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)
|
private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)
|
||||||
|
@ -1,25 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
namespace Syntriax.Engine.Physics2D;
|
||||||
|
|
||||||
public class PhysicsEngine2DCollector : HierarchyObjectBase, IPhysicsEngine2D
|
public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
||||||
{
|
{
|
||||||
public event IPhysicsEngine2D.OnPhysicsIterationEventHandler? OnPhysicsIteration = null;
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
||||||
public event IPhysicsEngine2D.OnPhysicsStepEventHandler? OnPhysicsStep = null;
|
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
private int _iterationPerStep = 1;
|
private int _iterationPerStep = 1;
|
||||||
|
|
||||||
protected readonly ICollisionDetector2D collisionDetector = null!;
|
protected readonly ICollisionDetector2D collisionDetector = null!;
|
||||||
protected readonly ICollisionResolver2D collisionResolver = null!;
|
protected readonly ICollisionResolver2D collisionResolver = null!;
|
||||||
|
|
||||||
protected BehaviourCollector<IRigidBody2D> rigidBodyCollector = new();
|
protected BehaviourCacher<IRigidBody2D> rigidBodyCacher = new();
|
||||||
protected BehaviourCollector<ICollider2D> colliderCollector = new();
|
protected BehaviourCacher<ICollider2D> colliderCacher = new();
|
||||||
protected BehaviourCollector<IPhysicsUpdate> physicsUpdateCollector = new();
|
|
||||||
|
|
||||||
|
|
||||||
public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; }
|
public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; }
|
||||||
|
public IGameManager GameManager { get; private set; } = null!;
|
||||||
|
|
||||||
public void Step(float deltaTime)
|
public void Step(float deltaTime)
|
||||||
{
|
{
|
||||||
@ -28,23 +31,23 @@ public class PhysicsEngine2DCollector : HierarchyObjectBase, IPhysicsEngine2D
|
|||||||
for (int iterationIndex = 0; iterationIndex < IterationPerStep; iterationIndex++)
|
for (int iterationIndex = 0; iterationIndex < IterationPerStep; iterationIndex++)
|
||||||
{
|
{
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
foreach (var rigidBody in rigidBodyCollector)
|
foreach (var rigidBody in rigidBodyCacher)
|
||||||
StepRigidBody(rigidBody, intervalDeltaTime);
|
StepRigidBody(rigidBody, intervalDeltaTime);
|
||||||
|
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
foreach (var collider in colliderCollector)
|
foreach (var collider in colliderCacher)
|
||||||
collider.Recalculate();
|
collider.Recalculate();
|
||||||
|
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
for (int x = 0; x < colliderCollector.Behaviours.Count; x++)
|
for (int x = 0; x < colliderCacher.Behaviours.Count; x++)
|
||||||
{
|
{
|
||||||
ICollider2D? colliderX = colliderCollector.Behaviours[x];
|
ICollider2D? colliderX = colliderCacher.Behaviours[x];
|
||||||
if (!colliderX.IsActive)
|
if (!colliderX.IsActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int y = x + 1; y < colliderCollector.Behaviours.Count; y++)
|
for (int y = x + 1; y < colliderCacher.Behaviours.Count; y++)
|
||||||
{
|
{
|
||||||
ICollider2D? colliderY = colliderCollector.Behaviours[y];
|
ICollider2D? colliderY = colliderCacher.Behaviours[y];
|
||||||
|
|
||||||
if (!colliderY.IsActive)
|
if (!colliderY.IsActive)
|
||||||
return;
|
return;
|
||||||
@ -56,7 +59,7 @@ public class PhysicsEngine2DCollector : HierarchyObjectBase, IPhysicsEngine2D
|
|||||||
if (bothCollidersAreTriggers)
|
if (bothCollidersAreTriggers)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool bothCollidersAreStatic = (colliderX.RigidBody2D?.IsStatic ?? true) && (colliderY.RigidBody2D?.IsStatic ?? true);
|
bool bothCollidersAreStatic = colliderX.RigidBody2D?.IsStatic ?? true && colliderX.RigidBody2D?.IsStatic == colliderY.RigidBody2D?.IsStatic;
|
||||||
if (bothCollidersAreStatic)
|
if (bothCollidersAreStatic)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -64,38 +67,23 @@ public class PhysicsEngine2DCollector : HierarchyObjectBase, IPhysicsEngine2D
|
|||||||
{
|
{
|
||||||
if (colliderX.IsTrigger)
|
if (colliderX.IsTrigger)
|
||||||
{
|
{
|
||||||
colliderX.Trigger(colliderY);
|
colliderX.OnTriggered?.Invoke(colliderX, colliderY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (colliderY.IsTrigger)
|
else if (colliderY.IsTrigger)
|
||||||
{
|
{
|
||||||
colliderY.Trigger(colliderY);
|
colliderY.OnTriggered?.Invoke(colliderY, colliderY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (information.Detector == colliderX)
|
colliderX.OnCollisionDetected?.Invoke(colliderX, information);
|
||||||
{
|
colliderY.OnCollisionDetected?.Invoke(colliderY, information);
|
||||||
colliderX.Detect(information);
|
|
||||||
colliderY.Detect(information.Reverse());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
colliderX.Detect(information.Reverse());
|
|
||||||
colliderY.Detect(information);
|
|
||||||
}
|
|
||||||
|
|
||||||
collisionResolver?.Resolve(information);
|
collisionResolver?.Resolve(information);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnPhysicsIteration?.Invoke(this, intervalDeltaTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (IPhysicsUpdate physicsUpdate in physicsUpdateCollector)
|
|
||||||
physicsUpdate.PhysicsUpdate(deltaTime);
|
|
||||||
|
|
||||||
OnPhysicsStep?.Invoke(this, deltaTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)
|
private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)
|
||||||
@ -106,27 +94,55 @@ public class PhysicsEngine2DCollector : HierarchyObjectBase, IPhysicsEngine2D
|
|||||||
rigidBody.Transform.Position += rigidBody.Velocity * intervalDeltaTime;
|
rigidBody.Transform.Position += rigidBody.Velocity * intervalDeltaTime;
|
||||||
rigidBody.Transform.Rotation += rigidBody.AngularVelocity * intervalDeltaTime;
|
rigidBody.Transform.Rotation += rigidBody.AngularVelocity * intervalDeltaTime;
|
||||||
}
|
}
|
||||||
protected override void OnEnteringHierarchy(IGameManager gameManager)
|
|
||||||
|
public bool Assign(IGameManager gameManager)
|
||||||
{
|
{
|
||||||
physicsUpdateCollector.Assign(gameManager);
|
if (GameManager is not null)
|
||||||
colliderCollector.Assign(gameManager);
|
return false;
|
||||||
rigidBodyCollector.Assign(gameManager);
|
|
||||||
|
colliderCacher.Assign(gameManager);
|
||||||
|
rigidBodyCacher.Assign(gameManager);
|
||||||
|
|
||||||
|
GameManager = gameManager;
|
||||||
|
OnGameManagerAssigned?.Invoke(this);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnExitingHierarchy(IGameManager gameManager)
|
public bool Unassign()
|
||||||
{
|
{
|
||||||
physicsUpdateCollector.Unassign();
|
if (GameManager is null)
|
||||||
colliderCollector.Unassign();
|
return false;
|
||||||
rigidBodyCollector.Unassign();
|
|
||||||
|
colliderCacher.Unassign();
|
||||||
|
rigidBodyCacher.Unassign();
|
||||||
|
|
||||||
|
GameManager = null!;
|
||||||
|
OnUnassigned?.Invoke(this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCollector()
|
public PhysicsEngine2DCacher()
|
||||||
{
|
{
|
||||||
collisionDetector = new CollisionDetector2D();
|
collisionDetector = new CollisionDetector2D();
|
||||||
collisionResolver = new CollisionResolver2D();
|
collisionResolver = new CollisionResolver2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCollector(ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
public PhysicsEngine2DCacher(IGameManager gameManager)
|
||||||
|
{
|
||||||
|
Assign(gameManager);
|
||||||
|
collisionDetector = new CollisionDetector2D();
|
||||||
|
collisionResolver = new CollisionResolver2D();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhysicsEngine2DCacher(IGameManager gameManager, ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
||||||
|
{
|
||||||
|
Assign(gameManager);
|
||||||
|
this.collisionDetector = collisionDetector;
|
||||||
|
this.collisionResolver = collisionResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhysicsEngine2DCacher(ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
||||||
{
|
{
|
||||||
this.collisionDetector = collisionDetector;
|
this.collisionDetector = collisionDetector;
|
||||||
this.collisionResolver = collisionResolver;
|
this.collisionResolver = collisionResolver;
|
@ -65,12 +65,6 @@ 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>
|
||||||
|
@ -69,7 +69,7 @@ public readonly struct Circle(Vector2D center, float radius)
|
|||||||
/// Transforms the <see cref="Circle"/> by the specified <see cref="ITransform"/>.
|
/// Transforms the <see cref="Circle"/> by the specified <see cref="ITransform"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Circle TransformCircle(ITransform transform, Circle circle)
|
public static Circle TransformCircle(ITransform transform, Circle circle)
|
||||||
=> new(transform.TransformVector2D(circle.Center), circle.Radius * (transform.Scale.Magnitude / Vector2D.One.Magnitude));
|
=> new(transform.TransformVector2D(circle.Center), circle.Radius * transform.Scale.Magnitude);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if two <see cref="Circle"/>s are approximately equal.
|
/// Checks if two <see cref="Circle"/>s are approximately equal.
|
||||||
|
@ -202,40 +202,6 @@ public readonly struct Line(Vector2D from, Vector2D to)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class LineExtensions
|
public static class LineExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Linearly interpolates between the two endpoints of the <see cref="Line"/> segment using parameter 't'.
|
|
||||||
/// </summary>
|
|
||||||
public static Vector2D Lerp(this Line line, float t) => Line.Lerp(line, t);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The equation of the <see cref="Line"/> defined by this <see cref="Line"/> segment.
|
|
||||||
/// </summary>
|
|
||||||
public static LineEquation ToLineEquation(this Line line) => Line.GetLineEquation(line);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether the specified <see cref="Vector2D"/> lies on the <see cref="Line"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static bool Intersects(this Line line, Vector2D point) => Line.Intersects(line, point);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Calculates the parameter 't' representing the point's position on the <see cref="Line"/> segment.
|
|
||||||
/// </summary>
|
|
||||||
public static float GetT(this Line line, Vector2D point) => Line.GetT(line, point);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if the <see cref="Line"/> segment intersects with another <see cref="Line"/> segment.
|
|
||||||
/// </summary>
|
|
||||||
public static bool Intersects(this Line left, Line right) => Line.Intersects(left, right);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether two <see cref="Line"/> segments intersect.
|
|
||||||
/// </summary>
|
|
||||||
public static bool Intersects(this Line left, Line right, [NotNullWhen(returnValue: true)] out Vector2D? point) => Line.Intersects(left, right, out point);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if two <see cref="Line"/>s are approximately equal.
|
/// Checks if two <see cref="Line"/>s are approximately equal.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
namespace Syntriax.Engine.Physics2D;
|
||||||
|
|
||||||
public class RigidBody2D : Behaviour, IRigidBody2D
|
public class RigidBody2D : BehaviourOverride, IRigidBody2D
|
||||||
{
|
{
|
||||||
event IAssignableTransform.OnTransformAssignedEventHandler? IAssignableTransform.OnTransformAssigned { add => GameObject.OnTransformAssigned += value; remove => GameObject.OnTransformAssigned -= value; }
|
public Action<IAssignableTransform>? OnTransformAssigned { get => GameObject.OnTransformAssigned; set => GameObject.OnTransformAssigned = value; }
|
||||||
|
|
||||||
private const float LOWEST_ALLOWED_MASS = 0.00001f;
|
private const float LOWEST_ALLOWED_MASS = 0.00001f;
|
||||||
private float _mass = 1f;
|
private float _mass = 1f;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user