7 Commits

56 changed files with 876 additions and 854 deletions

View File

@@ -1,26 +0,0 @@
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="ITransform2D"/> field.
/// </summary>
public interface IHasGameManager : IAssignable
{
/// <summary>
/// Event triggered when the <see cref="IGameManager"/> value has has been assigned a new value.
/// </summary>
event GameManagerAssignedEventHandler? OnGameManagerAssigned;
/// <inheritdoc cref="IGameManager" />
IGameManager GameManager { get; }
/// <summary>
/// Assign a value to the <see cref="IGameManager"/> field of this object.
/// </summary>
/// <param name="gameManager">New <see cref="IGameManager"/> to assign.</param>
/// <returns>
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
/// </returns>
bool Assign(IGameManager gameManager);
delegate void GameManagerAssignedEventHandler(IHasGameManager sender);
}

View File

@@ -1,26 +0,0 @@
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IHierarchyObject"/> field.
/// </summary>
public interface IHasHierarchyObject : IAssignable
{
/// <summary>
/// Event triggered when the <see cref="IHierarchyObject"/> value has has been assigned a new value.
/// </summary>
event HierarchyObjectAssignedEventHandler? OnHierarchyObjectAssigned;
/// <inheritdoc cref="IHierarchyObject" />
IHierarchyObject HierarchyObject { get; }
/// <summary>
/// Assign a value to the <see cref="IHierarchyObject"/> field of this object.
/// </summary>
/// <param name="hierarchyObject">New <see cref="IHierarchyObject"/> to assign.</param>
/// <returns>
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
/// </returns>
bool Assign(IHierarchyObject hierarchyObject);
delegate void HierarchyObjectAssignedEventHandler(IHasHierarchyObject sender);
}

View File

@@ -0,0 +1,26 @@
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverse"/> field.
/// </summary>
public interface IHasUniverse : IAssignable
{
/// <summary>
/// Event triggered when the <see cref="IUniverse"/> value has has been assigned a new value.
/// </summary>
event UniverseAssignedEventHandler? OnUniverseAssigned;
/// <inheritdoc cref="IUniverse" />
IUniverse Universe { get; }
/// <summary>
/// Assign a value to the <see cref="IUniverse"/> field of this object.
/// </summary>
/// <param name="universe">New <see cref="IUniverse"/> to assign.</param>
/// <returns>
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
/// </returns>
bool Assign(IUniverse universe);
delegate void UniverseAssignedEventHandler(IHasUniverse sender);
}

View File

@@ -0,0 +1,26 @@
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverseObject"/> field.
/// </summary>
public interface IHasUniverseObject : IAssignable
{
/// <summary>
/// Event triggered when the <see cref="IUniverseObject"/> value has has been assigned a new value.
/// </summary>
event UniverseObjectAssignedEventHandler? OnUniverseObjectAssigned;
/// <inheritdoc cref="IUniverseObject" />
IUniverseObject UniverseObject { get; }
/// <summary>
/// Assign a value to the <see cref="IUniverseObject"/> field of this object.
/// </summary>
/// <param name="universeObject">New <see cref="IUniverseObject"/> to assign.</param>
/// <returns>
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
/// </returns>
bool Assign(IUniverseObject universeObject);
delegate void UniverseObjectAssignedEventHandler(IHasUniverseObject sender);
}

View File

@@ -1,7 +1,7 @@
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 engine that might use to interact with itself or other objects.
/// </summary> /// </summary>
public interface IBehaviour : IEntity, IActive, IHasBehaviourController, IHasStateEnable public interface IBehaviour : IEntity, IActive, IHasBehaviourController, IHasStateEnable
{ {

View File

@@ -4,10 +4,10 @@ namespace Syntriax.Engine.Core.Abstract;
/// <summary> /// <summary>
/// Represents a collector for the class type of <typeparamref name="T"/>. /// 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"/>. /// Provides mechanisms for tracking additions and removals, and notifies subscribers when such events occur on the assigned <see cref="IUniverse"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The type of objects tracked by the collector.</typeparam> /// <typeparam name="T">The type of objects tracked by the collector.</typeparam>
public interface IBehaviourCollector<T> : IHasGameManager, IEnumerable<T> where T : class public interface IBehaviourCollector<T> : IHasUniverse, IEnumerable<T> where T : class
{ {
/// <summary> /// <summary>
/// Event triggered when an object of type <typeparamref name="T"/> is added to the collector. /// Event triggered when an object of type <typeparamref name="T"/> is added to the collector.

View File

@@ -3,9 +3,9 @@ using System.Collections.Generic;
namespace Syntriax.Engine.Core.Abstract; 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="IHierarchyObject"/>. /// Represents a controller for managing <see cref="IBehaviour"/>s and notify them accordingly about the engine's updates. Connected to an <see cref="IUniverseObject"/>.
/// </summary> /// </summary>
public interface IBehaviourController : IInitializable, IHasHierarchyObject, IEnumerable<IBehaviour> public interface IBehaviourController : IInitializable, IHasUniverseObject, IEnumerable<IBehaviour>
{ {
/// <summary> /// <summary>
/// Event triggered before the update of <see cref="IBehaviour"/>s. /// Event triggered before the update of <see cref="IBehaviour"/>s.

View File

@@ -1,91 +0,0 @@
using System.Collections.Generic;
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Represents a game world responsible for managing <see cref="IHierarchyObject"/>s.
/// </summary>
public interface IGameManager : IEntity, IEnumerable<IHierarchyObject>
{
/// <summary>
/// Event triggered when <see cref="Update(EngineTime)"/> is about to be called called on the <see cref="IGameManager"/>.
/// </summary>
event UpdateEventHandler? OnPreUpdate;
/// <summary>
/// Event triggered when <see cref="Update(EngineTime)"/> is called on the <see cref="IGameManager"/>.
/// </summary>
event UpdateEventHandler? OnUpdate;
/// <summary>
/// Event triggered when <see cref="PreDraw"/> is called on the <see cref="IGameManager"/>.
/// </summary>
event PreDrawEventHandler? OnPreDraw;
/// <summary>
/// Event triggered when a <see cref="IHierarchyObject"/> is registered to the <see cref="IGameManager"/>.
/// </summary>
event HierarchyObjectRegisteredEventHandler? OnHierarchyObjectRegistered;
/// <summary>
/// Event triggered when a <see cref="IHierarchyObject"/> is unregistered from the <see cref="IGameManager"/>.
/// </summary>
event HierarchyObjectUnRegisteredEventHandler? OnHierarchyObjectUnRegistered;
/// <summary>
/// Current time scale the <see cref="IGameManager"/> operates on.
/// </summary>
float TimeScale { get; set; }
/// <summary>
/// Contains time data related to this <see cref="IGameManager"/>.
/// </summary>
EngineTime Time { get; }
/// <summary>
/// Contains unscaled time data related to this <see cref="IGameManager"/>.
/// </summary>
EngineTime UnscaledTime { get; }
/// <summary>
/// Gets a read-only list of <see cref="IHierarchyObject"/>s managed by the <see cref="IGameManager"/>.
/// </summary>
IReadOnlyList<IHierarchyObject> HierarchyObjects { get; }
/// <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>
/// Instantiates a <see cref="IHierarchyObject"/> of type T with the given arguments and registers it to the <see cref="IGameManager"/>.
/// </summary>
/// <typeparam name="T">The type of <see cref="IHierarchyObject"/> to instantiate.</typeparam>
/// <param name="args">Constructor parameters for the given type of <see cref="IHierarchyObject"/>.</param>
/// <returns>The instantiated <see cref="IHierarchyObject"/>.</returns>
T InstantiateHierarchyObject<T>(params object?[]? args) where T : class, IHierarchyObject;
/// <summary>
/// Removes an <see cref="IHierarchyObject"/> from the <see cref="IGameManager"/>.
/// </summary>
/// <param name="hierarchyObject">The <see cref="IHierarchyObject"/> to remove.</param>
void Remove(IHierarchyObject hierarchyObject);
/// <summary>
/// Updates the <see cref="IGameManager"/> with the given delta time.
/// </summary>
/// <param name="engineTime">Delta time.</param>
void Update(EngineTime engineTime);
/// <summary>
/// Performs operations that should be done before the draw calls.
/// </summary>
void PreDraw();
delegate void UpdateEventHandler(IGameManager sender, EngineTime engineTime);
delegate void PreDrawEventHandler(IGameManager sender);
delegate void HierarchyObjectRegisteredEventHandler(IGameManager sender, IHierarchyObject hierarchyObjectRegistered);
delegate void HierarchyObjectUnRegisteredEventHandler(IGameManager sender, IHierarchyObject hierarchyObjectUnregistered);
}

View File

@@ -1,131 +0,0 @@
using System.Collections.Generic;
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, IActive, INameable, IHasBehaviourController, IEnumerable<IHierarchyObject>
{
/// <summary>
/// Event triggered when the <see cref="IHierarchyObject"/> enters the hierarchy.
/// </summary>
event EnteredHierarchyEventHandler? OnEnteredHierarchy;
/// <summary>
/// Event triggered when the <see cref="IHierarchyObject"/> exits the hierarchy.
/// </summary>
event ExitedHierarchyEventHandler? OnExitedHierarchy;
/// <summary>
/// Event triggered when the <see cref="Parent"/> of the <see cref="IHierarchyObject"/> changes. The second parameter is the old <see cref="IHierarchyObject"/>.
/// </summary>
event ParentChangedEventHandler? OnParentChanged;
/// <summary>
/// Event triggered when a new <see cref="IHierarchyObject"/> is added to the <see cref="Children"/>.
/// </summary>
event ChildrenAddedEventHandler? OnChildrenAdded;
/// <summary>
/// Event triggered when an <see cref="IHierarchyObject"/> is removed from the <see cref="Children"/>.
/// </summary>
event ChildrenRemovedEventHandler? OnChildrenRemoved;
/// <summary>
/// Gets the <see cref="IGameManager"/> this <see cref="IHierarchyObject"/> is connected to, if any.
/// </summary>
IGameManager GameManager { get; }
/// <summary>
/// Indicates whether the <see cref="IHierarchyObject"/> is currently in the hierarchy.
/// </summary>
bool IsInHierarchy { get; }
/// <summary>
/// The parent <see cref="IHierarchyObject"/> of the <see cref="IHierarchyObject"/>.
/// </summary>
IHierarchyObject? Parent { get; }
/// <summary>
/// The <see cref="IHierarchyObject"/>s that have this <see cref="IHierarchyObject"/> as their <see cref="Parent"/>.
/// </summary>
IReadOnlyList<IHierarchyObject> Children { 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 <see cref="IGameManager"/> that is managing this hierarchy.</param>
/// <returns>
/// <see cref="true"/> if the <see cref="IHierarchyObject"/> 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="IHierarchyObject"/> successfully exited the hierarchy;
/// <see cref="false"/> if it failed to do so.
/// </returns>
internal bool ExitHierarchy();
/// <summary>
/// Sets the parent <see cref="IHierarchyObject"/> of this <see cref="IHierarchyObject"/>.
/// </summary>
/// <param name="hierarchyObject">The parent <see cref="IHierarchyObject"/> to set.</param>
void SetParent(IHierarchyObject? hierarchyObject);
/// <summary>
/// Adds a child <see cref="IHierarchyObject"/> to this <see cref="IHierarchyObject"/>.
/// </summary>
/// <param name="hierarchyObject">The child <see cref="IHierarchyObject"/> to add.</param>
void AddChild(IHierarchyObject hierarchyObject);
/// <summary>
/// Removes a child <see cref="IHierarchyObject"/> from this <see cref="IHierarchyObject"/>.
/// </summary>
/// <param name="hierarchyObject">The child <see cref="IHierarchyObject"/> to remove.</param>
void RemoveChild(IHierarchyObject hierarchyObject);
/// <summary>
/// EventHandler delegate for the event triggered when the <see cref="IHierarchyObject"/> enters the hierarchy of a <see cref="IGameManager">.
/// </summary>
/// <param name="sender">The <see cref="IHierarchyObject"/> that entered the hierarchy.</param>
/// <param name="gameManager">The <see cref="IGameManager"/> that the <see cref="IHierarchyObject"/> has entered it's hierarchy.</param>
delegate void EnteredHierarchyEventHandler(IHierarchyObject sender, IGameManager gameManager);
/// <summary>
/// EventHandler delegate for the event triggered when the <see cref="IHierarchyObject"/> exits the hierarchy of a <see cref="IGameManager">.
/// </summary>
/// <param name="sender">The <see cref="IHierarchyObject"/> that exited the hierarchy.</param>
/// <param name="gameManager">The <see cref="IGameManager"/> that the <see cref="IHierarchyObject"/> has exited it's hierarchy.</param>
delegate void ExitedHierarchyEventHandler(IHierarchyObject sender, IGameManager gameManager);
/// <summary>
/// Delegate for the event triggered when the <see cref="IHierarchyObject"/>'s parent changes.
/// </summary>
/// <param name="sender">The <see cref="IHierarchyObject"/> that the parent has changed.</param>
/// <param name="previousParent">The previous <see cref="IHierarchyObject"/> the sender was a child of.</param>
/// <param name="newParent">The new and current <see cref="IHierarchyObject"/> the sender is a child of.</param>
delegate void ParentChangedEventHandler(IHierarchyObject sender, IHierarchyObject? previousParent, IHierarchyObject? newParent);
/// <summary>
/// Delegate for the event triggered when a new <see cref="IHierarchyObject"/> added as a child.
/// </summary>
/// <param name="sender">The parent <see cref="IHierarchyObject"/> this event is being called from.</param>
/// <param name="childrenAdded">The <see cref="IHierarchyObject"/> that got removed as a children of the sender <see cref="IHierarchyObject"/>.</param>
delegate void ChildrenAddedEventHandler(IHierarchyObject sender, IHierarchyObject childrenAdded);
/// <summary>
/// Delegate for the event triggered when a new <see cref="IHierarchyObject"/> removed from being a child.
/// </summary>
/// <param name="sender">The parent <see cref="IHierarchyObject"/> this event is being called from.</param>
/// <param name="childrenAdded">The <see cref="IHierarchyObject"/> that got removed as a children of the sender <see cref="IHierarchyObject"/>.</param>
delegate void ChildrenRemovedEventHandler(IHierarchyObject sender, IHierarchyObject childrenRemoved);
}

View File

@@ -0,0 +1,91 @@
using System.Collections.Generic;
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Represents a universe responsible for managing <see cref="IUniverseObject"/>s.
/// </summary>
public interface IUniverse : IEntity, IEnumerable<IUniverseObject>
{
/// <summary>
/// Event triggered when <see cref="Update(UniverseTime)"/> is about to be called called on the <see cref="IUniverse"/>.
/// </summary>
event UpdateEventHandler? OnPreUpdate;
/// <summary>
/// Event triggered when <see cref="Update(UniverseTime)"/> is called on the <see cref="IUniverse"/>.
/// </summary>
event UpdateEventHandler? OnUpdate;
/// <summary>
/// Event triggered when <see cref="PreDraw"/> is called on the <see cref="IUniverse"/>.
/// </summary>
event PreDrawEventHandler? OnPreDraw;
/// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is registered to the <see cref="IUniverse"/>.
/// </summary>
event UniverseObjectRegisteredEventHandler? OnUniverseObjectRegistered;
/// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is unregistered from the <see cref="IUniverse"/>.
/// </summary>
event UniverseObjectUnRegisteredEventHandler? OnUniverseObjectUnRegistered;
/// <summary>
/// Current time scale the <see cref="IUniverse"/> operates on.
/// </summary>
float TimeScale { get; set; }
/// <summary>
/// Contains time data related to this <see cref="IUniverse"/>.
/// </summary>
UniverseTime Time { get; }
/// <summary>
/// Contains unscaled time data related to this <see cref="IUniverse"/>.
/// </summary>
UniverseTime UnscaledTime { get; }
/// <summary>
/// Gets a read-only list of <see cref="IUniverseObject"/>s managed by the <see cref="IUniverse"/>.
/// </summary>
IReadOnlyList<IUniverseObject> UniverseObjects { get; }
/// <summary>
/// Registers an <see cref="IUniverseObject"/> to the <see cref="IUniverse"/>.
/// </summary>
/// <param name="universeObject">The <see cref="IUniverseObject"/> to register.</param>
void Register(IUniverseObject universeObject);
/// <summary>
/// Instantiates a <see cref="IUniverseObject"/> of type T with the given arguments and registers it to the <see cref="IUniverse"/>.
/// </summary>
/// <typeparam name="T">The type of <see cref="IUniverseObject"/> to instantiate.</typeparam>
/// <param name="args">Constructor parameters for the given type of <see cref="IUniverseObject"/>.</param>
/// <returns>The instantiated <see cref="IUniverseObject"/>.</returns>
T InstantiateUniverseObject<T>(params object?[]? args) where T : class, IUniverseObject;
/// <summary>
/// Removes an <see cref="IUniverseObject"/> from the <see cref="IUniverse"/>.
/// </summary>
/// <param name="universeObject">The <see cref="IUniverseObject"/> to remove.</param>
void Remove(IUniverseObject universeObject);
/// <summary>
/// Updates the <see cref="IUniverse"/> with the given delta time.
/// </summary>
/// <param name="universeTime">Delta time.</param>
void Update(UniverseTime universeTime);
/// <summary>
/// Performs operations that should be done before the draw calls.
/// </summary>
void PreDraw();
delegate void UpdateEventHandler(IUniverse sender, UniverseTime engineTime);
delegate void PreDrawEventHandler(IUniverse sender);
delegate void UniverseObjectRegisteredEventHandler(IUniverse sender, IUniverseObject universeObjectRegistered);
delegate void UniverseObjectUnRegisteredEventHandler(IUniverse sender, IUniverseObject universeObjectUnregistered);
}

View File

@@ -0,0 +1,131 @@
using System.Collections.Generic;
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Represents an <see cref="IEntity"/> that can enter and exit a universe within the <see cref="IUniverse"/> system.
/// This interface allows for tracking the object's presence in the universe and provides events
/// for notifying when the see enters or exits the universe.
/// </summary>
public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourController, IEnumerable<IUniverseObject>
{
/// <summary>
/// Event triggered when the <see cref="IUniverseObject"/> enters the universe.
/// </summary>
event EnteredUniverseEventHandler? OnEnteredUniverse;
/// <summary>
/// Event triggered when the <see cref="IUniverseObject"/> exits the universe.
/// </summary>
event ExitedUniverseEventHandler? OnExitedUniverse;
/// <summary>
/// Event triggered when the <see cref="Parent"/> of the <see cref="IUniverseObject"/> changes. The second parameter is the old <see cref="IUniverseObject"/>.
/// </summary>
event ParentChangedEventHandler? OnParentChanged;
/// <summary>
/// Event triggered when a new <see cref="IUniverseObject"/> is added to the <see cref="Children"/>.
/// </summary>
event ChildrenAddedEventHandler? OnChildrenAdded;
/// <summary>
/// Event triggered when an <see cref="IUniverseObject"/> is removed from the <see cref="Children"/>.
/// </summary>
event ChildrenRemovedEventHandler? OnChildrenRemoved;
/// <summary>
/// Gets the <see cref="IUniverse"/> this <see cref="IUniverseObject"/> is connected to, if any.
/// </summary>
IUniverse Universe { get; }
/// <summary>
/// Indicates whether the <see cref="IUniverseObject"/> is currently in the universe.
/// </summary>
bool IsInUniverse { get; }
/// <summary>
/// The parent <see cref="IUniverseObject"/> of the <see cref="IUniverseObject"/>.
/// </summary>
IUniverseObject? Parent { get; }
/// <summary>
/// The <see cref="IUniverseObject"/>s that have this <see cref="IUniverseObject"/> as their <see cref="Parent"/>.
/// </summary>
IReadOnlyList<IUniverseObject> Children { get; }
/// <summary>
/// Internal method to handle entering the universe.
/// This should be called by the system to properly manage universe states.
/// </summary>
/// <param name="universe">The <see cref="IUniverse"/> that is managing this universe.</param>
/// <returns>
/// <see cref="true"/> if the <see cref="IUniverseObject"/> successfully entered the universe;
/// <see cref="false"/> if it failed to do so.
/// </returns>
internal bool EnterUniverse(IUniverse universe);
/// <summary>
/// Internal method to handle exiting the universe.
/// This should be called by the system to properly manage universe states.
/// </summary>
/// <returns>
/// <see cref="true"/> if the <see cref="IUniverseObject"/> successfully exited the universe;
/// <see cref="false"/> if it failed to do so.
/// </returns>
internal bool ExitUniverse();
/// <summary>
/// Sets the parent <see cref="IUniverseObject"/> of this <see cref="IUniverseObject"/>.
/// </summary>
/// <param name="universeObject">The parent <see cref="IUniverseObject"/> to set.</param>
void SetParent(IUniverseObject? universeObject);
/// <summary>
/// Adds a child <see cref="IUniverseObject"/> to this <see cref="IUniverseObject"/>.
/// </summary>
/// <param name="universeObject">The child <see cref="IUniverseObject"/> to add.</param>
void AddChild(IUniverseObject universeObject);
/// <summary>
/// Removes a child <see cref="IUniverseObject"/> from this <see cref="IUniverseObject"/>.
/// </summary>
/// <param name="universeObject">The child <see cref="IUniverseObject"/> to remove.</param>
void RemoveChild(IUniverseObject universeObject);
/// <summary>
/// EventHandler delegate for the event triggered when the <see cref="IUniverseObject"/> enters the universe of a <see cref="IUniverse">.
/// </summary>
/// <param name="sender">The <see cref="IUniverseObject"/> that entered the universe.</param>
/// <param name="universe">The <see cref="IUniverse"/> that the <see cref="IUniverseObject"/> has entered it's universe.</param>
delegate void EnteredUniverseEventHandler(IUniverseObject sender, IUniverse universe);
/// <summary>
/// EventHandler delegate for the event triggered when the <see cref="IUniverseObject"/> exits the universe of a <see cref="IUniverse">.
/// </summary>
/// <param name="sender">The <see cref="IUniverseObject"/> that exited the universe.</param>
/// <param name="universe">The <see cref="IUniverse"/> that the <see cref="IUniverseObject"/> has exited it's universe.</param>
delegate void ExitedUniverseEventHandler(IUniverseObject sender, IUniverse universe);
/// <summary>
/// Delegate for the event triggered when the <see cref="IUniverseObject"/>'s parent changes.
/// </summary>
/// <param name="sender">The <see cref="IUniverseObject"/> that the parent has changed.</param>
/// <param name="previousParent">The previous <see cref="IUniverseObject"/> the sender was a child of.</param>
/// <param name="newParent">The new and current <see cref="IUniverseObject"/> the sender is a child of.</param>
delegate void ParentChangedEventHandler(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent);
/// <summary>
/// Delegate for the event triggered when a new <see cref="IUniverseObject"/> added as a child.
/// </summary>
/// <param name="sender">The parent <see cref="IUniverseObject"/> this event is being called from.</param>
/// <param name="childrenAdded">The <see cref="IUniverseObject"/> that got removed as a children of the sender <see cref="IUniverseObject"/>.</param>
delegate void ChildrenAddedEventHandler(IUniverseObject sender, IUniverseObject childrenAdded);
/// <summary>
/// Delegate for the event triggered when a new <see cref="IUniverseObject"/> removed from being a child.
/// </summary>
/// <param name="sender">The parent <see cref="IUniverseObject"/> this event is being called from.</param>
/// <param name="childrenAdded">The <see cref="IUniverseObject"/> that got removed as a children of the sender <see cref="IUniverseObject"/>.</param>
delegate void ChildrenRemovedEventHandler(IUniverseObject sender, IUniverseObject childrenRemoved);
}

View File

@@ -9,7 +9,7 @@ namespace Syntriax.Engine.Core;
public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : class, IBehaviour public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : class, IBehaviour
{ {
public event IAssignable.UnassignEventHandler? OnUnassigned = null; public event IAssignable.UnassignEventHandler? OnUnassigned = null;
public event IHasGameManager.GameManagerAssignedEventHandler? OnGameManagerAssigned = null; public event IHasUniverse.UniverseAssignedEventHandler? OnUniverseAssigned = null;
public event IBehaviourCollector<T>.CollectedEventHandler? OnCollected = null; public event IBehaviourCollector<T>.CollectedEventHandler? OnCollected = null;
public event IBehaviourCollector<T>.RemovedEventHandler? OnRemoved = null; public event IBehaviourCollector<T>.RemovedEventHandler? OnRemoved = null;
@@ -19,29 +19,29 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
protected readonly Dictionary<IActive, T> monitoringActiveToBehaviour = new(32); protected readonly Dictionary<IActive, T> monitoringActiveToBehaviour = new(32);
public IReadOnlyList<T> Behaviours => activeBehaviours; public IReadOnlyList<T> Behaviours => activeBehaviours;
public IGameManager GameManager { get; private set; } = null!; public IUniverse Universe { get; private set; } = null!;
public T this[Index index] => activeBehaviours[index]; public T this[Index index] => activeBehaviours[index];
public ActiveBehaviourCollector() { } public ActiveBehaviourCollector() { }
public ActiveBehaviourCollector(IGameManager gameManager) => Assign(gameManager); public ActiveBehaviourCollector(IUniverse universe) => Assign(universe);
private void OnHierarchyObjectRegistered(IGameManager manager, IHierarchyObject hierarchyObject) private void OnUniverseObjectRegistered(IUniverse manager, IUniverseObject universeObject)
{ {
hierarchyObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; universeObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
hierarchyObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; universeObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved;
foreach (IBehaviour item in hierarchyObject.BehaviourController) foreach (IBehaviour item in universeObject.BehaviourController)
OnBehaviourAdded(hierarchyObject.BehaviourController, item); OnBehaviourAdded(universeObject.BehaviourController, item);
} }
private void OnHierarchyObjectUnregistered(IGameManager manager, IHierarchyObject hierarchyObject) private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject)
{ {
hierarchyObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded; universeObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded;
hierarchyObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved; universeObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved;
foreach (IBehaviour item in hierarchyObject.BehaviourController) foreach (IBehaviour item in universeObject.BehaviourController)
OnBehaviourRemoved(hierarchyObject.BehaviourController, item); OnBehaviourRemoved(universeObject.BehaviourController, item);
} }
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
@@ -63,12 +63,12 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
{ {
activeBehaviours.Add(behaviour); activeBehaviours.Add(behaviour);
OnBehaviourAdd(behaviour); OnBehaviourAdd(behaviour);
OnCollected?.Invoke(this, behaviour); OnCollected?.InvokeSafe(this, behaviour);
} }
else if (activeBehaviours.Remove(behaviour)) else if (activeBehaviours.Remove(behaviour))
{ {
OnBehaviourRemove(behaviour); OnBehaviourRemove(behaviour);
OnRemoved?.Invoke(this, behaviour); OnRemoved?.InvokeSafe(this, behaviour);
} }
} }
@@ -85,40 +85,40 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
if (activeBehaviours.Remove(tBehaviour)) if (activeBehaviours.Remove(tBehaviour))
{ {
OnBehaviourRemove(tBehaviour); OnBehaviourRemove(tBehaviour);
OnRemoved?.Invoke(this, tBehaviour); OnRemoved?.InvokeSafe(this, tBehaviour);
} }
} }
public bool Assign(IGameManager gameManager) public bool Assign(IUniverse universe)
{ {
if (GameManager is not null) if (Universe is not null)
return false; return false;
foreach (IHierarchyObject hierarchyObject in gameManager.HierarchyObjects) foreach (IUniverseObject universeObject in universe.UniverseObjects)
OnHierarchyObjectRegistered(gameManager, hierarchyObject); OnUniverseObjectRegistered(universe, universeObject);
gameManager.OnHierarchyObjectRegistered += OnHierarchyObjectRegistered; universe.OnUniverseObjectRegistered += OnUniverseObjectRegistered;
gameManager.OnHierarchyObjectUnRegistered += OnHierarchyObjectUnregistered; universe.OnUniverseObjectUnRegistered += OnUniverseObjectUnregistered;
GameManager = gameManager; Universe = universe;
OnGameManagerAssigned?.Invoke(this); OnUniverseAssigned?.InvokeSafe(this);
return true; return true;
} }
public bool Unassign() public bool Unassign()
{ {
if (GameManager is null) if (Universe is null)
return false; return false;
foreach (IHierarchyObject hierarchyObject in GameManager.HierarchyObjects) foreach (IUniverseObject universeObject in Universe.UniverseObjects)
OnHierarchyObjectUnregistered(GameManager, hierarchyObject); OnUniverseObjectUnregistered(Universe, universeObject);
GameManager.OnHierarchyObjectRegistered -= OnHierarchyObjectRegistered; Universe.OnUniverseObjectRegistered -= OnUniverseObjectRegistered;
GameManager.OnHierarchyObjectUnRegistered -= OnHierarchyObjectUnregistered; Universe.OnUniverseObjectUnRegistered -= OnUniverseObjectUnregistered;
GameManager = null!; Universe = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.InvokeSafe(this);
return true; return true;
} }

View File

@@ -26,5 +26,5 @@ public class ActiveBehaviourCollectorSorted<T> : ActiveBehaviourCollector<T> whe
} }
public ActiveBehaviourCollectorSorted() { } public ActiveBehaviourCollectorSorted() { }
public ActiveBehaviourCollectorSorted(IGameManager gameManager, Comparison<T> sortBy) : base(gameManager) => SortBy = sortBy; public ActiveBehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe) => SortBy = sortBy;
} }

View File

@@ -33,7 +33,7 @@ public abstract class BaseEntity : IEntity
string previousId = _id; string previousId = _id;
_id = value; _id = value;
OnIdChanged?.Invoke(this, previousId); OnIdChanged?.InvokeSafe(this, previousId);
} }
} }
@@ -47,9 +47,9 @@ public abstract class BaseEntity : IEntity
_initialized = value; _initialized = value;
if (value) if (value)
OnInitialized?.Invoke(this); OnInitialized?.InvokeSafe(this);
else else
OnFinalized?.Invoke(this); OnFinalized?.InvokeSafe(this);
} }
} }
@@ -62,7 +62,7 @@ public abstract class BaseEntity : IEntity
_stateEnable = stateEnable; _stateEnable = stateEnable;
_stateEnable.Assign(this); _stateEnable.Assign(this);
OnAssign(stateEnable); OnAssign(stateEnable);
OnStateEnableAssigned?.Invoke(this); OnStateEnableAssigned?.InvokeSafe(this);
return true; return true;
} }
@@ -76,7 +76,7 @@ public abstract class BaseEntity : IEntity
_stateEnable = null!; _stateEnable = null!;
_stateEnable.Unassign(); _stateEnable.Unassign();
OnUnassigned?.Invoke(this); OnUnassigned?.InvokeSafe(this);
return true; return true;
} }

View File

@@ -1,5 +1,4 @@
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Helpers;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
@@ -7,8 +6,8 @@ public abstract class Behaviour : BehaviourBase
{ {
private bool isInitializedThisFrame = false; private bool isInitializedThisFrame = false;
protected IGameManager GameManager => BehaviourController.HierarchyObject.GameManager; protected IUniverse Universe => BehaviourController.UniverseObject.Universe;
protected IHierarchyObject HierarchyObject => BehaviourController.HierarchyObject; protected IUniverseObject UniverseObject => BehaviourController.UniverseObject;
public Behaviour() public Behaviour()
{ {
@@ -28,13 +27,13 @@ public abstract class Behaviour : BehaviourBase
BehaviourController.OnPreUpdate += PreUpdate; BehaviourController.OnPreUpdate += PreUpdate;
BehaviourController.OnPreDraw += PreDraw; BehaviourController.OnPreDraw += PreDraw;
BehaviourController.OnUpdate += Update; BehaviourController.OnUpdate += Update;
BehaviourController.HierarchyObject.OnEnteredHierarchy += EnteredHierarchy; BehaviourController.UniverseObject.OnEnteredUniverse += EnteredUniverse;
BehaviourController.HierarchyObject.OnExitedHierarchy += ExitedHierarchy; BehaviourController.UniverseObject.OnExitedUniverse += ExitedUniverse;
OnInitialize(); OnInitialize();
if (HierarchyObject.IsInHierarchy) if (UniverseObject.IsInUniverse)
EnteredHierarchy(HierarchyObject, GameManager); EnteredUniverse(UniverseObject, Universe);
} }
protected virtual void OnFinalize() { } protected virtual void OnFinalize() { }
@@ -43,20 +42,20 @@ public abstract class Behaviour : BehaviourBase
BehaviourController.OnPreUpdate -= PreUpdate; BehaviourController.OnPreUpdate -= PreUpdate;
BehaviourController.OnPreDraw -= PreDraw; BehaviourController.OnPreDraw -= PreDraw;
BehaviourController.OnUpdate -= Update; BehaviourController.OnUpdate -= Update;
BehaviourController.HierarchyObject.OnEnteredHierarchy -= EnteredHierarchy; BehaviourController.UniverseObject.OnEnteredUniverse -= EnteredUniverse;
BehaviourController.HierarchyObject.OnExitedHierarchy -= ExitedHierarchy; BehaviourController.UniverseObject.OnExitedUniverse -= ExitedUniverse;
OnFinalize(); OnFinalize();
if (HierarchyObject.IsInHierarchy) if (UniverseObject.IsInUniverse)
ExitedHierarchy(HierarchyObject, GameManager); ExitedUniverse(UniverseObject, Universe);
} }
protected virtual void OnPreUpdatePreActiveCheck() { } protected virtual void OnPreUpdatePreActiveCheck() { }
protected virtual void OnPreUpdate() { } protected virtual void OnPreUpdate() { }
protected virtual void PreUpdate(IBehaviourController _) protected virtual void PreUpdate(IBehaviourController _)
{ {
AssertHelpers.AssertInitialized(this); Debug.AssertHelpers.AssertInitialized(this);
OnPreUpdatePreActiveCheck(); OnPreUpdatePreActiveCheck();
@@ -80,7 +79,7 @@ public abstract class Behaviour : BehaviourBase
protected virtual void OnUpdate() { } protected virtual void OnUpdate() { }
protected virtual void Update(IBehaviourController _) protected virtual void Update(IBehaviourController _)
{ {
AssertHelpers.AssertInitialized(this); Debug.AssertHelpers.AssertInitialized(this);
OnUpdatePreActiveCheck(); OnUpdatePreActiveCheck();
@@ -94,7 +93,7 @@ public abstract class Behaviour : BehaviourBase
protected virtual void OnPreDraw() { } protected virtual void OnPreDraw() { }
protected virtual void PreDraw(IBehaviourController _) protected virtual void PreDraw(IBehaviourController _)
{ {
AssertHelpers.AssertInitialized(this); Debug.AssertHelpers.AssertInitialized(this);
OnPreDrawPreActiveCheck(); OnPreDrawPreActiveCheck();
@@ -104,9 +103,9 @@ public abstract class Behaviour : BehaviourBase
OnPreDraw(); OnPreDraw();
} }
protected virtual void OnEnteredHierarchy(IGameManager gameManager) { } protected virtual void OnEnteredUniverse(IUniverse universe) { }
protected virtual void EnteredHierarchy(IHierarchyObject sender, IGameManager gameManager) => OnEnteredHierarchy(gameManager); protected virtual void EnteredUniverse(IUniverseObject sender, IUniverse universe) => OnEnteredUniverse(universe);
protected virtual void OnExitedHierarchy(IGameManager gameManager) { } protected virtual void OnExitedUniverse(IUniverse universe) { }
protected virtual void ExitedHierarchy(IHierarchyObject sender, IGameManager gameManager) => OnExitedHierarchy(gameManager); protected virtual void ExitedUniverse(IUniverseObject sender, IUniverse universe) => OnExitedUniverse(universe);
} }

View File

@@ -23,6 +23,6 @@ public abstract class Behaviour2D : Behaviour, IBehaviour2D
protected sealed override void FirstActiveFrame() => base.FirstActiveFrame(); protected sealed override void FirstActiveFrame() => base.FirstActiveFrame();
protected sealed override void Update(IBehaviourController behaviourController) => base.Update(behaviourController); protected sealed override void Update(IBehaviourController behaviourController) => base.Update(behaviourController);
protected sealed override void PreDraw(IBehaviourController behaviourController) => base.PreDraw(behaviourController); protected sealed override void PreDraw(IBehaviourController behaviourController) => base.PreDraw(behaviourController);
protected sealed override void EnteredHierarchy(IHierarchyObject sender, IGameManager gameManager) => base.EnteredHierarchy(sender, gameManager); protected sealed override void EnteredUniverse(IUniverseObject sender, IUniverse universe) => base.EnteredUniverse(sender, universe);
protected sealed override void ExitedHierarchy(IHierarchyObject sender, IGameManager gameManager) => base.ExitedHierarchy(sender, gameManager); protected sealed override void ExitedUniverse(IUniverseObject sender, IUniverse universe) => base.ExitedUniverse(sender, universe);
} }

View File

@@ -1,6 +1,4 @@
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Exceptions;
using Syntriax.Engine.Core.Helpers;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
@@ -25,7 +23,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
int previousPriority = _priority; int previousPriority = _priority;
_priority = value; _priority = value;
OnPriorityChanged?.Invoke(this, previousPriority); OnPriorityChanged?.InvokeSafe(this, previousPriority);
} }
} }
@@ -40,16 +38,16 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
_behaviourController = behaviourController; _behaviourController = behaviourController;
OnAssign(behaviourController); OnAssign(behaviourController);
behaviourController.OnHierarchyObjectAssigned += OnHierarchyObjectAssigned; behaviourController.OnUniverseObjectAssigned += OnUniverseObjectAssigned;
if (behaviourController.HierarchyObject is not null) if (behaviourController.UniverseObject is not null)
OnHierarchyObjectAssigned(behaviourController); OnUniverseObjectAssigned(behaviourController);
OnBehaviourControllerAssigned?.Invoke(this); OnBehaviourControllerAssigned?.InvokeSafe(this);
return true; return true;
} }
private void OnHierarchyObjectAssigned(IHasHierarchyObject sender) private void OnUniverseObjectAssigned(IHasUniverseObject sender)
{ {
sender.HierarchyObject.OnActiveChanged += OnHierarchyObjectActiveChanged; sender.UniverseObject.OnActiveChanged += OnUniverseObjectActiveChanged;
UpdateActive(); UpdateActive();
} }
@@ -63,26 +61,26 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
protected override void UnassignInternal() protected override void UnassignInternal()
{ {
StateEnable.OnEnabledChanged -= OnStateEnabledChanged; StateEnable.OnEnabledChanged -= OnStateEnabledChanged;
BehaviourController.OnHierarchyObjectAssigned -= OnHierarchyObjectAssigned; BehaviourController.OnUniverseObjectAssigned -= OnUniverseObjectAssigned;
base.UnassignInternal(); base.UnassignInternal();
_behaviourController = null!; _behaviourController = null!;
} }
protected override void InitializeInternal() protected override void InitializeInternal()
{ {
AssertHelpers.AssertBehaviourControllerAssigned(this); Debug.AssertHelpers.AssertBehaviourControllerAssigned(this);
AssertHelpers.AssertStateEnableAssigned(this); Debug.AssertHelpers.AssertStateEnableAssigned(this);
} }
private void OnStateEnabledChanged(IStateEnable sender, bool previousState) => UpdateActive(); private void OnStateEnabledChanged(IStateEnable sender, bool previousState) => UpdateActive();
private void OnHierarchyObjectActiveChanged(IActive sender, bool previousState) => UpdateActive(); private void OnUniverseObjectActiveChanged(IActive sender, bool previousState) => UpdateActive();
private void UpdateActive() private void UpdateActive()
{ {
bool previousActive = IsActive; bool previousActive = IsActive;
_isActive = StateEnable.Enabled && _behaviourController.HierarchyObject.IsActive; _isActive = StateEnable.Enabled && _behaviourController.UniverseObject.IsActive;
if (previousActive != IsActive) if (previousActive != IsActive)
OnActiveChanged?.Invoke(this, previousActive); OnActiveChanged?.InvokeSafe(this, previousActive);
} }
} }

View File

@@ -9,7 +9,7 @@ namespace Syntriax.Engine.Core;
public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
{ {
public event IAssignable.UnassignEventHandler? OnUnassigned = null; public event IAssignable.UnassignEventHandler? OnUnassigned = null;
public event IHasGameManager.GameManagerAssignedEventHandler? OnGameManagerAssigned = null; public event IHasUniverse.UniverseAssignedEventHandler? OnUniverseAssigned = null;
public event IBehaviourCollector<T>.CollectedEventHandler? OnCollected = null; public event IBehaviourCollector<T>.CollectedEventHandler? OnCollected = null;
public event IBehaviourCollector<T>.RemovedEventHandler? OnRemoved = null; public event IBehaviourCollector<T>.RemovedEventHandler? OnRemoved = null;
@@ -17,29 +17,29 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
protected readonly List<T> behaviours = new(32); protected readonly List<T> behaviours = new(32);
public IReadOnlyList<T> Behaviours => behaviours; public IReadOnlyList<T> Behaviours => behaviours;
public IGameManager GameManager { get; private set; } = null!; public IUniverse Universe { get; private set; } = null!;
public T this[Index index] => behaviours[index]; public T this[Index index] => behaviours[index];
public BehaviourCollector() { } public BehaviourCollector() { }
public BehaviourCollector(IGameManager gameManager) => Assign(gameManager); public BehaviourCollector(IUniverse universe) => Assign(universe);
private void OnHierarchyObjectRegistered(IGameManager manager, IHierarchyObject hierarchyObject) private void OnUniverseObjectRegistered(IUniverse manager, IUniverseObject universeObject)
{ {
hierarchyObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; universeObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
hierarchyObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; universeObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved;
foreach (IBehaviour item in hierarchyObject.BehaviourController) foreach (IBehaviour item in universeObject.BehaviourController)
OnBehaviourAdded(hierarchyObject.BehaviourController, item); OnBehaviourAdded(universeObject.BehaviourController, item);
} }
private void OnHierarchyObjectUnregistered(IGameManager manager, IHierarchyObject hierarchyObject) private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject)
{ {
hierarchyObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded; universeObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded;
hierarchyObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved; universeObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved;
foreach (IBehaviour item in hierarchyObject.BehaviourController) foreach (IBehaviour item in universeObject.BehaviourController)
OnBehaviourRemoved(hierarchyObject.BehaviourController, item); OnBehaviourRemoved(universeObject.BehaviourController, item);
} }
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
@@ -50,7 +50,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
behaviours.Add(tBehaviour); behaviours.Add(tBehaviour);
OnBehaviourAdd(behaviour); OnBehaviourAdd(behaviour);
OnCollected?.Invoke(this, tBehaviour); OnCollected?.InvokeSafe(this, tBehaviour);
} }
protected virtual void OnBehaviourRemove(IBehaviour behaviour) { } protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
@@ -63,41 +63,41 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
return; return;
OnBehaviourRemove(behaviour); OnBehaviourRemove(behaviour);
OnRemoved?.Invoke(this, tBehaviour); OnRemoved?.InvokeSafe(this, tBehaviour);
} }
protected virtual void OnAssign(IGameManager gameManager) { } protected virtual void OnAssign(IUniverse universe) { }
public bool Assign(IGameManager gameManager) public bool Assign(IUniverse universe)
{ {
if (GameManager is not null) if (Universe is not null)
return false; return false;
foreach (IHierarchyObject hierarchyObject in gameManager.HierarchyObjects) foreach (IUniverseObject universeObject in universe.UniverseObjects)
OnHierarchyObjectRegistered(gameManager, hierarchyObject); OnUniverseObjectRegistered(universe, universeObject);
gameManager.OnHierarchyObjectRegistered += OnHierarchyObjectRegistered; universe.OnUniverseObjectRegistered += OnUniverseObjectRegistered;
gameManager.OnHierarchyObjectUnRegistered += OnHierarchyObjectUnregistered; universe.OnUniverseObjectUnRegistered += OnUniverseObjectUnregistered;
GameManager = gameManager; Universe = universe;
OnAssign(gameManager); OnAssign(universe);
OnGameManagerAssigned?.Invoke(this); OnUniverseAssigned?.InvokeSafe(this);
return true; return true;
} }
public bool Unassign() public bool Unassign()
{ {
if (GameManager is null) if (Universe is null)
return false; return false;
foreach (IHierarchyObject hierarchyObject in GameManager.HierarchyObjects) foreach (IUniverseObject universeObject in Universe.UniverseObjects)
OnHierarchyObjectUnregistered(GameManager, hierarchyObject); OnUniverseObjectUnregistered(Universe, universeObject);
GameManager.OnHierarchyObjectRegistered -= OnHierarchyObjectRegistered; Universe.OnUniverseObjectRegistered -= OnUniverseObjectRegistered;
GameManager.OnHierarchyObjectUnRegistered -= OnHierarchyObjectUnregistered; Universe.OnUniverseObjectUnRegistered -= OnUniverseObjectUnregistered;
GameManager = null!; Universe = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.InvokeSafe(this);
return true; return true;
} }

View File

@@ -26,5 +26,5 @@ public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class
} }
public BehaviourCollectorSorted() { } public BehaviourCollectorSorted() { }
public BehaviourCollectorSorted(IGameManager gameManager, Comparison<T> sortBy) : base(gameManager) => SortBy = sortBy; public BehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe) => SortBy = sortBy;
} }

View File

@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Helpers;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
@@ -17,7 +16,7 @@ public class BehaviourController : IBehaviourController
public event IBehaviourController.BehaviourAddedEventHandler? OnBehaviourAdded = null; public event IBehaviourController.BehaviourAddedEventHandler? OnBehaviourAdded = null;
public event IBehaviourController.BehaviourRemovedEventHandler? OnBehaviourRemoved = null; public event IBehaviourController.BehaviourRemovedEventHandler? OnBehaviourRemoved = null;
public event IHasHierarchyObject.HierarchyObjectAssignedEventHandler? OnHierarchyObjectAssigned = null; public event IHasUniverseObject.UniverseObjectAssignedEventHandler? OnUniverseObjectAssigned = null;
public event IInitializable.InitializedEventHandler? OnInitialized = null; public event IInitializable.InitializedEventHandler? OnInitialized = null;
public event IInitializable.FinalizedEventHandler? OnFinalized = null; public event IInitializable.FinalizedEventHandler? OnFinalized = null;
@@ -26,10 +25,10 @@ public class BehaviourController : IBehaviourController
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 IHierarchyObject _hierarchyObject = null!; private IUniverseObject _universeObject = null!;
private bool _initialized = false; private bool _initialized = false;
public IHierarchyObject HierarchyObject => _hierarchyObject; public IUniverseObject UniverseObject => _universeObject;
public bool IsInitialized public bool IsInitialized
{ {
@@ -41,9 +40,9 @@ public class BehaviourController : IBehaviourController
_initialized = value; _initialized = value;
if (value) if (value)
OnInitialized?.Invoke(this); OnInitialized?.InvokeSafe(this);
else else
OnFinalized?.Invoke(this); OnFinalized?.InvokeSafe(this);
} }
} }
@@ -56,12 +55,12 @@ public class BehaviourController : IBehaviourController
behaviour.Initialize(); behaviour.Initialize();
behaviour.OnPriorityChanged += OnPriorityChange; behaviour.OnPriorityChanged += OnPriorityChange;
OnBehaviourAdded?.Invoke(this, behaviour); OnBehaviourAdded?.InvokeSafe(this, behaviour);
return behaviour; return behaviour;
} }
public T AddBehaviour<T>(params object?[]? args) where T : class, IBehaviour public T AddBehaviour<T>(params object?[]? args) where T : class, IBehaviour
=> AddBehaviour(Factory.BehaviourFactory.Instantiate<T>(_hierarchyObject, args)); => AddBehaviour(Factory.BehaviourFactory.Instantiate<T>(_universeObject, args));
public T? GetBehaviour<T>() public T? GetBehaviour<T>()
{ {
@@ -116,23 +115,23 @@ public class BehaviourController : IBehaviourController
public void RemoveBehaviour<T>(T behaviour) where T : class, IBehaviour public void RemoveBehaviour<T>(T behaviour) where T : class, IBehaviour
{ {
if (!behaviours.Contains(behaviour)) if (!behaviours.Contains(behaviour))
throw new Exception($"{behaviour.GetType().Name} does not exist in {HierarchyObject.Name}'s {nameof(IBehaviourController)}."); throw new Exception($"{behaviour.GetType().Name} does not exist in {UniverseObject.Name}'s {nameof(IBehaviourController)}.");
behaviour.OnPriorityChanged -= OnPriorityChange; behaviour.OnPriorityChanged -= OnPriorityChange;
behaviour.Finalize(); behaviour.Finalize();
behaviours.Remove(behaviour); behaviours.Remove(behaviour);
OnBehaviourRemoved?.Invoke(this, behaviour); OnBehaviourRemoved?.InvokeSafe(this, behaviour);
} }
protected virtual void OnAssign(IHierarchyObject hierarchyObject) { } protected virtual void OnAssign(IUniverseObject universeObject) { }
public bool Assign(IHierarchyObject hierarchyObject) public bool Assign(IUniverseObject universeObject)
{ {
if (HierarchyObject is not null && HierarchyObject.IsInitialized) if (UniverseObject is not null && UniverseObject.IsInitialized)
return false; return false;
_hierarchyObject = hierarchyObject; _universeObject = universeObject;
OnAssign(hierarchyObject); OnAssign(universeObject);
OnHierarchyObjectAssigned?.Invoke(this); OnUniverseObjectAssigned?.InvokeSafe(this);
return true; return true;
} }
@@ -141,7 +140,7 @@ public class BehaviourController : IBehaviourController
if (IsInitialized) if (IsInitialized)
return false; return false;
AssertHelpers.AssertHierarchyObjectAssigned(this); Debug.AssertHelpers.AssertUniverseObjectAssigned(this);
foreach (IBehaviour behaviour in behaviours) foreach (IBehaviour behaviour in behaviours)
behaviour.Initialize(); behaviour.Initialize();
@@ -167,30 +166,30 @@ public class BehaviourController : IBehaviourController
if (IsInitialized) if (IsInitialized)
return false; return false;
_hierarchyObject = null!; _universeObject = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.InvokeSafe(this);
return true; return true;
} }
public void Update() public void Update()
{ {
if (!HierarchyObject.StateEnable.Enabled) if (!UniverseObject.StateEnable.Enabled)
return; return;
OnPreUpdate?.Invoke(this); OnPreUpdate?.InvokeSafe(this);
OnUpdate?.Invoke(this); OnUpdate?.InvokeSafe(this);
} }
public void UpdatePreDraw() public void UpdatePreDraw()
{ {
if (!HierarchyObject.StateEnable.Enabled) if (!UniverseObject.StateEnable.Enabled)
return; return;
OnPreDraw?.Invoke(this); OnPreDraw?.InvokeSafe(this);
} }
public BehaviourController() { } public BehaviourController() { }
public BehaviourController(IHierarchyObject hierarchyObject) => Assign(hierarchyObject); public BehaviourController(IUniverseObject universeObject) => Assign(universeObject);
private void InsertBehaviourByPriority<T>(T behaviour) where T : class, IBehaviour private void InsertBehaviourByPriority<T>(T behaviour) where T : class, IBehaviour
{ {

View File

@@ -5,7 +5,7 @@ using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public class CoroutineManager : HierarchyObject public class CoroutineManager : UniverseObject
{ {
private readonly List<IEnumerator> enumerators = []; private readonly List<IEnumerator> enumerators = [];
@@ -20,17 +20,17 @@ public class CoroutineManager : HierarchyObject
enumerators.Remove(enumerator); enumerators.Remove(enumerator);
} }
protected override void OnEnteringHierarchy(IGameManager gameManager) protected override void OnEnteringUniverse(IUniverse universe)
{ {
gameManager.OnUpdate += OnUpdate; universe.OnUpdate += OnUpdate;
} }
protected override void OnExitingHierarchy(IGameManager gameManager) protected override void OnExitingUniverse(IUniverse universe)
{ {
gameManager.OnUpdate -= OnUpdate; universe.OnUpdate -= OnUpdate;
} }
private void OnUpdate(IGameManager sender, EngineTime time) private void OnUpdate(IUniverse sender, UniverseTime time)
{ {
for (int i = enumerators.Count - 1; i >= 0; i--) for (int i = enumerators.Count - 1; i >= 0; i--)
{ {

View File

@@ -7,11 +7,11 @@ skinparam nodesep 100
title Core Engine Relations title Core Engine Relations
interface Engine.Core.Abstract.IEntity extends Engine.Core.Abstract.IInitializable {} interface Engine.Core.Abstract.IEntity extends Engine.Core.Abstract.IInitializable {}
interface Engine.Core.Abstract.IHierarchyObject extends Engine.Core.Abstract.IEntity, Engine.Core.Abstract.INameable {} interface Engine.Core.Abstract.IUniverseObject extends Engine.Core.Abstract.IEntity, Engine.Core.Abstract.INameable {}
interface Engine.Core.Abstract.INameable {} interface Engine.Core.Abstract.INameable {}
Engine.Core.Abstract.IHierarchyObject --> Engine.Core.Abstract.IBehaviourController: has Engine.Core.Abstract.IUniverseObject --> Engine.Core.Abstract.IBehaviourController: has
Engine.Core.Abstract.IBehaviourController "1" --> "0..*" Engine.Core.Abstract.IBehaviour: has Engine.Core.Abstract.IBehaviourController "1" --> "0..*" Engine.Core.Abstract.IBehaviour: has
interface Engine.Core.Abstract.IBehaviourController {} interface Engine.Core.Abstract.IBehaviourController {}
@@ -19,18 +19,18 @@ interface Engine.Core.Abstract.IBehaviour {}
interface Engine.Core.Abstract.IBehaviour2D extends Engine.Core.Abstract.IBehaviour {} interface Engine.Core.Abstract.IBehaviour2D extends Engine.Core.Abstract.IBehaviour {}
interface Engine.Core.Abstract.IBehaviour3D extends Engine.Core.Abstract.IBehaviour {} interface Engine.Core.Abstract.IBehaviour3D extends Engine.Core.Abstract.IBehaviour {}
interface Engine.Core.Abstract.IGameManager {} interface Engine.Core.Abstract.IUniverse {}
Engine.Core.Abstract.IGameManager "1" -r-> "0..*" Engine.Core.Abstract.IHierarchyObject: has Engine.Core.Abstract.IUniverse "1" -r-> "0..*" Engine.Core.Abstract.IUniverseObject: has
' together { ' together {
' interface Engine.Core.Abstract.IAssignable {} ' interface Engine.Core.Abstract.IAssignable {}
' interface Engine.Core.Abstract.IHasStateEnable extends Engine.Core.Abstract.IAssignable {} ' interface Engine.Core.Abstract.IHasStateEnable extends Engine.Core.Abstract.IAssignable {}
' interface Engine.Core.Abstract.IHasGameManager extends Engine.Core.Abstract.IAssignable {} ' interface Engine.Core.Abstract.IHasUniverse extends Engine.Core.Abstract.IAssignable {}
' interface Engine.Core.Abstract.IHasHierarchyObject extends Engine.Core.Abstract.IAssignable {} ' interface Engine.Core.Abstract.IHasUniverseObject extends Engine.Core.Abstract.IAssignable {}
' interface Engine.Core.Abstract.IHasBehaviourController extends Engine.Core.Abstract.IAssignable {} ' interface Engine.Core.Abstract.IHasBehaviourController extends Engine.Core.Abstract.IAssignable {}
' ' Engine.Core.Abstract.IHasStateEnable --> Engine.Core.Abstract.IStateEnable: has ' ' Engine.Core.Abstract.IHasStateEnable --> Engine.Core.Abstract.IStateEnable: has
' ' Engine.Core.Abstract.IHasGameManager --> Engine.Core.Abstract.IGameManager: has ' ' Engine.Core.Abstract.IHasUniverse --> Engine.Core.Abstract.IUniverse: has
' ' Engine.Core.Abstract.IHasHierarchyObject --> Engine.Core.Abstract.IHierarchyObject: has ' ' Engine.Core.Abstract.IHasUniverseObject --> Engine.Core.Abstract.IUniverseObject: has
' ' Engine.Core.Abstract.IHasBehaviourController --> Engine.Core.Abstract.IBehaviourController: has ' ' Engine.Core.Abstract.IHasBehaviourController --> Engine.Core.Abstract.IBehaviourController: has
' } ' }

View File

@@ -1,9 +0,0 @@
using System;
namespace Syntriax.Engine.Core.Exceptions;
public class HierarchyObjectNotFoundException(string? message) : Exception(message)
{
public static NotAssignedException FromType<THierarchyObject>()
=> new($"{typeof(THierarchyObject).FullName} was not found");
}

View File

@@ -0,0 +1,9 @@
using System;
namespace Syntriax.Engine.Core.Exceptions;
public class UniverseObjectNotFoundException(string? message) : Exception(message)
{
public static NotAssignedException FromType<TUniverseObject>()
=> new($"{typeof(TUniverseObject).FullName} was not found");
}

View File

@@ -27,7 +27,7 @@ public static class BehaviourControllerExtensions
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param> /// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns> /// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns>
public static T GetRequiredBehaviour<T>(this IBehaviourController behaviourController) where T : class public static T GetRequiredBehaviour<T>(this IBehaviourController behaviourController) where T : class
=> behaviourController.GetBehaviour<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.HierarchyObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName}"); => behaviourController.GetBehaviour<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName}");
/// <summary> /// <summary>
/// Gets an existing <see cref="IBehaviour"/> of the specified type, or adds and returns a new one if it doesn't exist. /// Gets an existing <see cref="IBehaviour"/> of the specified type, or adds and returns a new one if it doesn't exist.
@@ -40,12 +40,12 @@ public static class BehaviourControllerExtensions
=> behaviourController.GetBehaviour<T>() ?? behaviourController.AddBehaviour<T>(args); => behaviourController.GetBehaviour<T>() ?? behaviourController.AddBehaviour<T>(args);
/// <summary> /// <summary>
/// Tries to get a <see cref="IBehaviour"/> of the specified type in it's <see cref="IHierarchyObject"/>'s parents recursively. /// Tries to get a <see cref="IBehaviour"/> of the specified type in it's <see cref="IUniverseObject"/>'s parents recursively.
/// </summary> /// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam> /// <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="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> /// <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> /// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found in the parent universe; otherwise, <see cref="false"/>.</returns>
public static bool TryGetBehaviourInParent<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class public static bool TryGetBehaviourInParent<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
{ {
behaviour = GetBehaviourInParent<T>(behaviourController); behaviour = GetBehaviourInParent<T>(behaviourController);
@@ -53,7 +53,7 @@ public static class BehaviourControllerExtensions
} }
/// <summary> /// <summary>
/// Gets a <see cref="IBehaviour"/> of the specified type in it's <see cref="IHierarchyObject"/>'s parents recursively. /// Gets a <see cref="IBehaviour"/> of the specified type in it's <see cref="IUniverseObject"/>'s parents recursively.
/// </summary> /// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam> /// <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="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
@@ -67,28 +67,28 @@ public static class BehaviourControllerExtensions
if (controller.GetBehaviour<T>() is T behaviour) if (controller.GetBehaviour<T>() is T behaviour)
return behaviour; return behaviour;
controller = controller.HierarchyObject.Parent?.BehaviourController; controller = controller.UniverseObject.Parent?.BehaviourController;
} }
return default; return default;
} }
/// <summary> /// <summary>
/// Gets a <see cref="IBehaviour"/> of the specified type in it's <see cref="IHierarchyObject"/>'s parents recursively. Throws an error if not found. /// Gets a <see cref="IBehaviour"/> of the specified type in it's <see cref="IUniverseObject"/>'s parents recursively. Throws an error if not found.
/// </summary> /// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam> /// <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="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns> /// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns>
public static T GetRequiredBehaviourInParent<T>(this IBehaviourController behaviourController) where T : class public static T GetRequiredBehaviourInParent<T>(this IBehaviourController behaviourController) where T : class
=> behaviourController.GetBehaviourInParent<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.HierarchyObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any parent"); => behaviourController.GetBehaviourInParent<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any parent");
/// <summary> /// <summary>
/// Tries to get a <see cref="IBehaviour"/> of the specified type in it's <see cref="IHierarchyObject"/>'s children recursively. /// Tries to get a <see cref="IBehaviour"/> of the specified type in it's <see cref="IUniverseObject"/>'s children recursively.
/// </summary> /// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam> /// <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="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> /// <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> /// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found in the child universe; otherwise, <see cref="false"/>.</returns>
public static bool TryGetBehaviourInChildren<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class public static bool TryGetBehaviourInChildren<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
{ {
behaviour = GetBehaviourInChildren<T>(behaviourController); behaviour = GetBehaviourInChildren<T>(behaviourController);
@@ -96,7 +96,7 @@ public static class BehaviourControllerExtensions
} }
/// <summary> /// <summary>
/// Gets a <see cref="IBehaviour"/> of the specified type in it's <see cref="IHierarchyObject"/>'s children recursively. /// Gets a <see cref="IBehaviour"/> of the specified type in it's <see cref="IUniverseObject"/>'s children recursively.
/// </summary> /// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam> /// <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="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
@@ -106,7 +106,7 @@ public static class BehaviourControllerExtensions
if (behaviourController.GetBehaviour<T>() is T localBehaviour) if (behaviourController.GetBehaviour<T>() is T localBehaviour)
return localBehaviour; return localBehaviour;
foreach (IHierarchyObject child in behaviourController.HierarchyObject) foreach (IUniverseObject child in behaviourController.UniverseObject)
if (GetBehaviourInChildren<T>(child.BehaviourController) is T behaviour) if (GetBehaviourInChildren<T>(child.BehaviourController) is T behaviour)
return behaviour; return behaviour;
@@ -120,5 +120,5 @@ public static class BehaviourControllerExtensions
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param> /// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns> /// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, throws <see cref="BehaviourNotFoundException"/>.</returns>
public static T GetRequiredBehaviourInChildren<T>(this IBehaviourController behaviourController) where T : class public static T GetRequiredBehaviourInChildren<T>(this IBehaviourController behaviourController) where T : class
=> behaviourController.GetBehaviourInChildren<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.HierarchyObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any children "); => behaviourController.GetBehaviourInChildren<T>() ?? throw new BehaviourNotFoundException($"{behaviourController.UniverseObject.Name}'s {nameof(IBehaviourController)} does not contain any {typeof(T).FullName} on any children ");
} }

View File

@@ -7,29 +7,29 @@ namespace Syntriax.Engine.Core;
public static class BehaviourExtensions public static class BehaviourExtensions
{ {
public static T? FindBehaviour<T>(this IEnumerable<IHierarchyObject> hierarchyObjects) where T : class public static T? FindBehaviour<T>(this IEnumerable<IUniverseObject> universeObjects) where T : class
{ {
foreach (IHierarchyObject hierarchyObject in hierarchyObjects) foreach (IUniverseObject universeObject in universeObjects)
if (hierarchyObject.BehaviourController.GetBehaviour<T>() is T behaviour) if (universeObject.BehaviourController.GetBehaviour<T>() is T behaviour)
return behaviour; return behaviour;
return default; return default;
} }
public static bool TryFindBehaviour<T>(this IEnumerable<IHierarchyObject> hierarchyObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class public static bool TryFindBehaviour<T>(this IEnumerable<IUniverseObject> universeObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
{ {
behaviour = FindBehaviour<T>(hierarchyObjects); behaviour = FindBehaviour<T>(universeObjects);
return behaviour is not null; return behaviour is not null;
} }
public static void FindBehaviours<T>(this IEnumerable<IHierarchyObject> hierarchyObjects, List<T> behaviours) where T : class public static void FindBehaviours<T>(this IEnumerable<IUniverseObject> universeObjects, List<T> behaviours) where T : class
{ {
behaviours.Clear(); behaviours.Clear();
List<T> cache = []; List<T> cache = [];
foreach (IHierarchyObject hierarchyObject in hierarchyObjects) foreach (IUniverseObject universeObject in universeObjects)
{ {
hierarchyObject.BehaviourController.GetBehaviours(cache); universeObject.BehaviourController.GetBehaviours(cache);
behaviours.AddRange(cache); behaviours.AddRange(cache);
} }
} }

View File

@@ -1,16 +0,0 @@
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Exceptions;
namespace Syntriax.Engine.Core;
public static class GameManagerExtensions
{
public static IHierarchyObject InstantiateHierarchyObject(this IGameManager gameManager, params object?[]? args)
=> gameManager.InstantiateHierarchyObject<HierarchyObject>(args);
public static T GetRequiredHierarchyObject<T>(this IGameManager gameManager) where T : class
=> gameManager.GetHierarchyObject<T>() ?? throw new HierarchyObjectNotFoundException($"{gameManager.GetType().FullName}({gameManager.Id}) does not contain any {nameof(IHierarchyObject)} object of type {typeof(T).FullName}");
public static T FindRequiredBehaviour<T>(this IGameManager gameManager) where T : class
=> gameManager.FindBehaviour<T>() ?? throw new BehaviourNotFoundException($"{gameManager.GetType().FullName}({gameManager.Id}) does not contain any {nameof(IHierarchyObject)} with {nameof(IBehaviour)} of type {typeof(T).FullName}");
}

View File

@@ -1,41 +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 SetHierarchyObject<T>(this T hierarchyObject, string? name = "", IHierarchyObject? parent = null) where T : IHierarchyObject
{
if (!string.IsNullOrWhiteSpace(name))
hierarchyObject.Name = name;
if (parent is not null)
hierarchyObject.SetParent(parent);
return hierarchyObject;
}
public static T? GetHierarchyObject<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 TryGetHierarchyObject<T>(this IEnumerable<IHierarchyObject> hierarchyObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
{
behaviour = GetHierarchyObject<T>(hierarchyObjects);
return behaviour is not null;
}
public static void GetHierarchyObjects<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);
}
}

View File

@@ -0,0 +1,16 @@
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Exceptions;
namespace Syntriax.Engine.Core;
public static class UniverseExtensions
{
public static IUniverseObject InstantiateUniverseObject(this IUniverse universe, params object?[]? args)
=> universe.InstantiateUniverseObject<UniverseObject>(args);
public static T GetRequiredUniverseObject<T>(this IUniverse universe) where T : class
=> universe.GetUniverseObject<T>() ?? throw new UniverseObjectNotFoundException($"{universe.GetType().FullName}({universe.Id}) does not contain any {nameof(IUniverseObject)} object of type {typeof(T).FullName}");
public static T FindRequiredBehaviour<T>(this IUniverse universe) where T : class
=> universe.FindBehaviour<T>() ?? throw new BehaviourNotFoundException($"{universe.GetType().FullName}({universe.Id}) does not contain any {nameof(IUniverseObject)} with {nameof(IBehaviour)} of type {typeof(T).FullName}");
}

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core;
public static class UniverseObjectExtensions
{
public static T SetUniverseObject<T>(this T universeObject, string? name = "", IUniverseObject? parent = null) where T : IUniverseObject
{
if (!string.IsNullOrWhiteSpace(name))
universeObject.Name = name;
if (parent is not null)
universeObject.SetParent(parent);
return universeObject;
}
public static T? GetUniverseObject<T>(this IEnumerable<IUniverseObject> universeObjects) where T : class
{
foreach (IUniverseObject universeObject in universeObjects)
if (universeObject is T @object)
return @object;
return default;
}
public static bool TryGetUniverseObject<T>(this IEnumerable<IUniverseObject> universeObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
{
behaviour = GetUniverseObject<T>(universeObjects);
return behaviour is not null;
}
public static void GetUniverseObjects<T>(this IEnumerable<IUniverseObject> universeObjects, List<T> behaviours) where T : class
{
behaviours.Clear();
foreach (IUniverseObject universeObject in universeObjects)
if (universeObject is T @object)
behaviours.Add(@object);
}
}

View File

@@ -5,19 +5,19 @@ namespace Syntriax.Engine.Core.Factory;
public class BehaviourControllerFactory public class BehaviourControllerFactory
{ {
public static IBehaviourController Instantiate(IHierarchyObject hierarchyObject) public static IBehaviourController Instantiate(IUniverseObject universeObject)
=> Instantiate<BehaviourController>(hierarchyObject); => Instantiate<BehaviourController>(universeObject);
public static T Instantiate<T>(IHierarchyObject hierarchyObject, params object?[]? args) public static T Instantiate<T>(IUniverseObject universeObject, params object?[]? args)
where T : class, IBehaviourController where T : class, IBehaviourController
{ {
T behaviourController = TypeFactory.Get<T>(args); T behaviourController = TypeFactory.Get<T>(args);
if (!hierarchyObject.Assign(behaviourController)) if (!universeObject.Assign(behaviourController))
throw AssignFailedException.From(hierarchyObject, behaviourController); throw AssignFailedException.From(universeObject, behaviourController);
if (!behaviourController.Assign(hierarchyObject)) if (!behaviourController.Assign(universeObject))
throw AssignFailedException.From(behaviourController, hierarchyObject); throw AssignFailedException.From(behaviourController, universeObject);
return behaviourController; return behaviourController;
} }

View File

@@ -5,10 +5,10 @@ namespace Syntriax.Engine.Core.Factory;
public class BehaviourFactory public class BehaviourFactory
{ {
public static T Instantiate<T>(IHierarchyObject hierarchyObject, params object?[]? args) where T : class, IBehaviour public static T Instantiate<T>(IUniverseObject universeObject, params object?[]? args) where T : class, IBehaviour
=> Instantiate<T>(hierarchyObject, stateEnable: null, args); => Instantiate<T>(universeObject, stateEnable: null, args);
public static T Instantiate<T>(IHierarchyObject hierarchyObject, IStateEnable? stateEnable, params object?[]? args) public static T Instantiate<T>(IUniverseObject universeObject, IStateEnable? stateEnable, params object?[]? args)
where T : class, IBehaviour where T : class, IBehaviour
{ {
T behaviour = TypeFactory.Get<T>(args); T behaviour = TypeFactory.Get<T>(args);
@@ -19,8 +19,8 @@ public class BehaviourFactory
if (!behaviour.Assign(stateEnable)) if (!behaviour.Assign(stateEnable))
throw AssignFailedException.From(behaviour, stateEnable); throw AssignFailedException.From(behaviour, stateEnable);
if (!behaviour.Assign(hierarchyObject.BehaviourController)) if (!behaviour.Assign(universeObject.BehaviourController))
throw AssignFailedException.From(behaviour, hierarchyObject.BehaviourController); throw AssignFailedException.From(behaviour, universeObject.BehaviourController);
return behaviour; return behaviour;
} }

View File

@@ -1,37 +0,0 @@
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Exceptions;
namespace Syntriax.Engine.Core.Factory;
public class HierarchyObjectFactory
{
public static IHierarchyObject Instantiate() => Instantiate<HierarchyObject>();
public static T Instantiate<T>(params object?[]? args) where T : class, IHierarchyObject
=> Instantiate<T>(behaviourController: null, stateEnable: null, args);
public static IHierarchyObject Instantiate(IBehaviourController? behaviourController = null, IStateEnable? stateEnable = null) => Instantiate<HierarchyObject>(behaviourController, stateEnable);
public static T Instantiate<T>(
IBehaviourController? behaviourController = null,
IStateEnable? stateEnable = null,
params object?[]? args
)
where T : class, IHierarchyObject
{
T hierarchyObject = TypeFactory.Get<T>(args);
behaviourController ??= TypeFactory.Get<BehaviourController>();
stateEnable ??= TypeFactory.Get<StateEnable>();
if (!behaviourController.Assign(hierarchyObject))
throw AssignFailedException.From(behaviourController, hierarchyObject);
if (!stateEnable.Assign(hierarchyObject))
throw AssignFailedException.From(stateEnable, hierarchyObject);
if (!hierarchyObject.Assign(behaviourController))
throw AssignFailedException.From(hierarchyObject, behaviourController);
if (!hierarchyObject.Assign(stateEnable))
throw AssignFailedException.From(hierarchyObject, stateEnable);
return hierarchyObject;
}
}

View File

@@ -0,0 +1,37 @@
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Exceptions;
namespace Syntriax.Engine.Core.Factory;
public class UniverseObjectFactory
{
public static IUniverseObject Instantiate() => Instantiate<UniverseObject>();
public static T Instantiate<T>(params object?[]? args) where T : class, IUniverseObject
=> Instantiate<T>(behaviourController: null, stateEnable: null, args);
public static IUniverseObject Instantiate(IBehaviourController? behaviourController = null, IStateEnable? stateEnable = null) => Instantiate<UniverseObject>(behaviourController, stateEnable);
public static T Instantiate<T>(
IBehaviourController? behaviourController = null,
IStateEnable? stateEnable = null,
params object?[]? args
)
where T : class, IUniverseObject
{
T universeObject = TypeFactory.Get<T>(args);
behaviourController ??= TypeFactory.Get<BehaviourController>();
stateEnable ??= TypeFactory.Get<StateEnable>();
if (!behaviourController.Assign(universeObject))
throw AssignFailedException.From(behaviourController, universeObject);
if (!stateEnable.Assign(universeObject))
throw AssignFailedException.From(stateEnable, universeObject);
if (!universeObject.Assign(behaviourController))
throw AssignFailedException.From(universeObject, behaviourController);
if (!universeObject.Assign(stateEnable))
throw AssignFailedException.From(universeObject, stateEnable);
return universeObject;
}
}

View File

@@ -1,142 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Helpers;
namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("HierarchyObject Count: {_hierarchyObjects.Count}")]
public class GameManager : BaseEntity, IGameManager
{
public event IGameManager.UpdateEventHandler? OnPreUpdate = null;
public event IGameManager.UpdateEventHandler? OnUpdate = null;
public event IGameManager.PreDrawEventHandler? OnPreDraw = null;
public event IGameManager.HierarchyObjectRegisteredEventHandler? OnHierarchyObjectRegistered = null;
public event IGameManager.HierarchyObjectUnRegisteredEventHandler? OnHierarchyObjectUnRegistered = null;
private readonly List<IHierarchyObject> _hierarchyObjects = new(Constants.GAME_OBJECTS_SIZE_INITIAL);
private float _timeScale = 1f;
public IReadOnlyList<IHierarchyObject> HierarchyObjects => _hierarchyObjects;
public EngineTime Time { get; private set; } = new();
public EngineTime UnscaledTime { get; private set; } = new();
public float TimeScale
{
get => _timeScale;
set => _timeScale = value.Max(0f);
}
public void Register(IHierarchyObject hierarchyObject)
{
if (_hierarchyObjects.Contains(hierarchyObject))
throw new Exception($"{nameof(IHierarchyObject)} named {hierarchyObject.Name} is already registered to the {nameof(GameManager)}.");
hierarchyObject.OnFinalized += OnHierarchyObjectFinalize;
hierarchyObject.OnExitedHierarchy += OnHierarchyObjectExitedHierarchy;
if (!hierarchyObject.Initialize())
throw new Exception($"{hierarchyObject.Name} can't be initialized");
for (int i = 0; i < hierarchyObject.Children.Count; i++)
Register(hierarchyObject.Children[i]);
_hierarchyObjects.Add(hierarchyObject);
if (!hierarchyObject.EnterHierarchy(this))
throw new Exception($"{hierarchyObject.Name} can't enter the hierarchy");
OnHierarchyObjectRegistered?.Invoke(this, hierarchyObject);
}
public T InstantiateHierarchyObject<T>(params object?[]? args) where T : class, IHierarchyObject
{
T hierarchyObject = Factory.HierarchyObjectFactory.Instantiate<T>(args);
Register(hierarchyObject);
return hierarchyObject;
}
public void Remove(IHierarchyObject hierarchyObject)
{
hierarchyObject.SetParent(null);
RemoveIncursive(hierarchyObject);
}
private void RemoveIncursive(IHierarchyObject hierarchyObject)
{
if (!_hierarchyObjects.Contains(hierarchyObject))
throw new Exception($"{nameof(IHierarchyObject)} named {hierarchyObject.Name} is not registered to the {nameof(GameManager)}.");
hierarchyObject.OnFinalized -= OnHierarchyObjectFinalize;
hierarchyObject.OnExitedHierarchy -= OnHierarchyObjectExitedHierarchy;
for (int i = hierarchyObject.Children.Count - 1; i >= 0; i--)
Remove(hierarchyObject.Children[i]);
_hierarchyObjects.Remove(hierarchyObject);
if (!hierarchyObject.ExitHierarchy())
throw new Exception($"{hierarchyObject.Name} can't exit the hierarchy");
if (!hierarchyObject.Finalize())
throw new Exception($"{hierarchyObject.Name} can't be finalized");
OnHierarchyObjectUnRegistered?.Invoke(this, hierarchyObject);
}
protected override void InitializeInternal()
{
foreach (IHierarchyObject hierarchyObject in HierarchyObjects)
hierarchyObject.Initialize();
}
protected override void FinalizeInternal()
{
base.FinalizeInternal();
for (int i = HierarchyObjects.Count; i >= 0; i--)
HierarchyObjects[i].Finalize();
}
public void Update(EngineTime engineTime)
{
AssertHelpers.AssertInitialized(this);
UnscaledTime = engineTime;
Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale)));
OnPreUpdate?.Invoke(this, Time);
for (int i = 0; i < HierarchyObjects.Count; i++)
HierarchyObjects[i].BehaviourController.Update();
OnUpdate?.Invoke(this, Time);
}
public void PreDraw()
{
AssertHelpers.AssertInitialized(this);
for (int i = 0; i < HierarchyObjects.Count; i++)
HierarchyObjects[i].BehaviourController.UpdatePreDraw();
OnPreDraw?.Invoke(this);
}
private void OnHierarchyObjectFinalize(IInitializable initializable)
{
if (initializable is IHierarchyObject hierarchyObject)
Remove(hierarchyObject);
}
private void OnHierarchyObjectExitedHierarchy(IHierarchyObject sender, IGameManager gameManager)
{
if (sender is IHierarchyObject hierarchyObject)
Remove(hierarchyObject);
}
public IEnumerator<IHierarchyObject> GetEnumerator() => _hierarchyObjects.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _hierarchyObjects.GetEnumerator();
}

View File

@@ -1,33 +1,32 @@
using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core.Helpers; namespace Syntriax.Engine.Core.Debug;
public class AssertHelpers public class AssertHelpers
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertInitialized(IInitializable initializable) public static void AssertInitialized(IInitializable initializable)
=> Debug.Assert(initializable.IsInitialized, $"{initializable.GetType().Name} must be initialized"); => System.Diagnostics.Debug.Assert(initializable.IsInitialized, $"{initializable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertBehaviourControllerAssigned(IHasBehaviourController assignable) public static void AssertBehaviourControllerAssigned(IHasBehaviourController assignable)
=> Debug.Assert(assignable.BehaviourController is not null, $"{assignable.GetType().Name} must be initialized"); => System.Diagnostics.Debug.Assert(assignable.BehaviourController is not null, $"{assignable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertEntityAssigned(IHasEntity assignable) public static void AssertEntityAssigned(IHasEntity assignable)
=> Debug.Assert(assignable.Entity is not null, $"{assignable.GetType().Name} must be initialized"); => System.Diagnostics.Debug.Assert(assignable.Entity is not null, $"{assignable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertGameManagerAssigned(IHasGameManager assignable) public static void AssertUniverseAssigned(IHasUniverse assignable)
=> Debug.Assert(assignable.GameManager is not null, $"{assignable.GetType().Name} must be initialized"); => System.Diagnostics.Debug.Assert(assignable.Universe is not null, $"{assignable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertHierarchyObjectAssigned(IHasHierarchyObject assignable) public static void AssertUniverseObjectAssigned(IHasUniverseObject assignable)
=> Debug.Assert(assignable.HierarchyObject is not null, $"{assignable.GetType().Name} must be initialized"); => System.Diagnostics.Debug.Assert(assignable.UniverseObject is not null, $"{assignable.GetType().Name} must be initialized");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertStateEnableAssigned(IHasStateEnable assignable) public static void AssertStateEnableAssigned(IHasStateEnable assignable)
=> Debug.Assert(assignable.StateEnable is not null, $"{assignable.GetType().Name} must be initialized"); => System.Diagnostics.Debug.Assert(assignable.StateEnable is not null, $"{assignable.GetType().Name} must be initialized");
} }

View File

@@ -0,0 +1,17 @@
using System;
namespace Syntriax.Engine.Core;
public static class DelegateHelpers
{
public static void InvokeSafe(this Delegate @delegate, params object?[] args)
{
foreach (Delegate invocation in @delegate.GetInvocationList())
try { invocation.DynamicInvoke(args); }
catch (Exception exception)
{
string methodCallRepresentation = $"{invocation.Method.DeclaringType?.FullName}.{invocation.Method.Name}({string.Join(", ", args)})";
Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
}
}
}

View File

@@ -23,7 +23,7 @@ public class StateEnable : IStateEnable
bool previousState = _enabled; bool previousState = _enabled;
_enabled = value; _enabled = value;
OnEnabledChanged?.Invoke(this, previousState); OnEnabledChanged?.InvokeSafe(this, previousState);
} }
} }
@@ -35,7 +35,7 @@ public class StateEnable : IStateEnable
_entity = entity; _entity = entity;
OnAssign(entity); OnAssign(entity);
OnEntityAssigned?.Invoke(this); OnEntityAssigned?.InvokeSafe(this);
return true; return true;
} }
@@ -45,7 +45,7 @@ public class StateEnable : IStateEnable
return false; return false;
_entity = null!; _entity = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.InvokeSafe(this);
return true; return true;
} }
} }

View File

@@ -3,6 +3,5 @@ namespace Syntriax.Engine.Core;
internal static class Constants internal static class Constants
{ {
internal static int BEHAVIOURS_SIZE_INITIAL = 16; internal static int BEHAVIOURS_SIZE_INITIAL = 16;
internal static int GAME_OBJECTS_SIZE_INITIAL = 256; internal static int UNIVERSE_OBJECTS_SIZE_INITIAL = 256;
internal static int DRAWABLE_OBJECTS_SIZE_INITIAL = 256;
} }

View File

@@ -2,7 +2,7 @@ using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("Name: {HierarchyObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")] [System.Diagnostics.DebuggerDisplay("Name: {UniverseObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
public class Transform2D : Behaviour, ITransform2D public class Transform2D : Behaviour, ITransform2D
{ {
public event ITransform2D.PositionChangedEventHandler? OnPositionChanged = null; public event ITransform2D.PositionChangedEventHandler? OnPositionChanged = null;
@@ -31,7 +31,7 @@ public class Transform2D : Behaviour, ITransform2D
_position = value; _position = value;
UpdateLocalPosition(); UpdateLocalPosition();
OnPositionChanged?.Invoke(this, _position); OnPositionChanged?.InvokeSafe(this, _position);
} }
} }
@@ -47,7 +47,7 @@ public class Transform2D : Behaviour, ITransform2D
_scale = value; _scale = value;
UpdateLocalScale(); UpdateLocalScale();
OnScaleChanged?.Invoke(this, previousScale); OnScaleChanged?.InvokeSafe(this, previousScale);
} }
} }
@@ -63,7 +63,7 @@ public class Transform2D : Behaviour, ITransform2D
_rotation = value; _rotation = value;
UpdateLocalRotation(); UpdateLocalRotation();
OnRotationChanged?.Invoke(this, previousRotation); OnRotationChanged?.InvokeSafe(this, previousRotation);
} }
} }
@@ -79,7 +79,7 @@ public class Transform2D : Behaviour, ITransform2D
_localPosition = value; _localPosition = value;
UpdatePosition(); UpdatePosition();
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
} }
@@ -97,8 +97,8 @@ public class Transform2D : Behaviour, ITransform2D
UpdateScale(); UpdateScale();
UpdatePosition(); UpdatePosition();
OnScaleChanged?.Invoke(this, previousScale); OnScaleChanged?.InvokeSafe(this, previousScale);
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
} }
@@ -114,7 +114,7 @@ public class Transform2D : Behaviour, ITransform2D
_localRotation = value; _localRotation = value;
UpdateRotation(); UpdateRotation();
OnRotationChanged?.Invoke(this, previousRotation); OnRotationChanged?.InvokeSafe(this, previousRotation);
} }
} }
@@ -125,7 +125,7 @@ public class Transform2D : Behaviour, ITransform2D
UpdatePosition(); UpdatePosition();
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
private void RecalculateScale(ITransform2D _, Vector2D previousScale) private void RecalculateScale(ITransform2D _, Vector2D previousScale)
@@ -138,8 +138,8 @@ public class Transform2D : Behaviour, ITransform2D
UpdateScale(); UpdateScale();
UpdatePosition(); UpdatePosition();
OnScaleChanged?.Invoke(this, previousScale); OnScaleChanged?.InvokeSafe(this, previousScale);
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
private void RecalculateRotation(ITransform2D _, float previousRotation) private void RecalculateRotation(ITransform2D _, float previousRotation)
@@ -152,8 +152,8 @@ public class Transform2D : Behaviour, ITransform2D
UpdateRotation(); UpdateRotation();
UpdatePosition(); UpdatePosition();
OnRotationChanged?.Invoke(this, previousRotation); OnRotationChanged?.InvokeSafe(this, previousRotation);
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
private void UpdateLocalPosition() private void UpdateLocalPosition()
@@ -206,16 +206,16 @@ public class Transform2D : Behaviour, ITransform2D
protected override void InitializeInternal() protected override void InitializeInternal()
{ {
UpdateReferences(HierarchyObject.Parent); UpdateReferences(UniverseObject.Parent);
HierarchyObject.OnParentChanged += OnParentChanged; UniverseObject.OnParentChanged += OnParentChanged;
} }
protected override void FinalizeInternal() protected override void FinalizeInternal()
{ {
HierarchyObject.OnParentChanged -= OnParentChanged; UniverseObject.OnParentChanged -= OnParentChanged;
} }
private void UpdateReferences(IHierarchyObject? parent) private void UpdateReferences(IUniverseObject? parent)
{ {
ITransform2D? previousParent = parentTransform; ITransform2D? previousParent = parentTransform;
if (previousParent is not null) if (previousParent is not null)
@@ -223,7 +223,7 @@ public class Transform2D : Behaviour, ITransform2D
previousParent.OnPositionChanged -= RecalculatePosition; previousParent.OnPositionChanged -= RecalculatePosition;
previousParent.OnScaleChanged -= RecalculateScale; previousParent.OnScaleChanged -= RecalculateScale;
previousParent.OnRotationChanged -= RecalculateRotation; previousParent.OnRotationChanged -= RecalculateRotation;
previousParent.BehaviourController.HierarchyObject.OnParentChanged -= OnParentChanged; previousParent.BehaviourController.UniverseObject.OnParentChanged -= OnParentChanged;
previousParent.BehaviourController.OnBehaviourAdded -= LookForTransform2D; previousParent.BehaviourController.OnBehaviourAdded -= LookForTransform2D;
} }
@@ -234,22 +234,22 @@ public class Transform2D : Behaviour, ITransform2D
parentTransform.OnPositionChanged += RecalculatePosition; parentTransform.OnPositionChanged += RecalculatePosition;
parentTransform.OnScaleChanged += RecalculateScale; parentTransform.OnScaleChanged += RecalculateScale;
parentTransform.OnRotationChanged += RecalculateRotation; parentTransform.OnRotationChanged += RecalculateRotation;
parentTransform.BehaviourController.HierarchyObject.OnParentChanged += OnParentChanged; parentTransform.BehaviourController.UniverseObject.OnParentChanged += OnParentChanged;
UpdatePosition(); UpdatePosition();
UpdateScale(); UpdateScale();
UpdateRotation(); UpdateRotation();
} }
else if (HierarchyObject.Parent is not null) else if (UniverseObject.Parent is not null)
HierarchyObject.Parent.BehaviourController.OnBehaviourAdded += LookForTransform2D; UniverseObject.Parent.BehaviourController.OnBehaviourAdded += LookForTransform2D;
UpdateLocalPosition(); UpdateLocalPosition();
UpdateLocalScale(); UpdateLocalScale();
UpdateLocalRotation(); UpdateLocalRotation();
OnPositionChanged?.Invoke(this, Position); OnPositionChanged?.InvokeSafe(this, Position);
OnScaleChanged?.Invoke(this, Scale); OnScaleChanged?.InvokeSafe(this, Scale);
OnRotationChanged?.Invoke(this, Rotation); OnRotationChanged?.InvokeSafe(this, Rotation);
} }
private void LookForTransform2D(IBehaviourController sender, IBehaviour behaviourAdded) private void LookForTransform2D(IBehaviourController sender, IBehaviour behaviourAdded)
@@ -257,10 +257,10 @@ public class Transform2D : Behaviour, ITransform2D
if (behaviourAdded is not ITransform2D transform2D) if (behaviourAdded is not ITransform2D transform2D)
return; return;
UpdateReferences(HierarchyObject.Parent); UpdateReferences(UniverseObject.Parent);
} }
private void OnParentChanged(IHierarchyObject sender, IHierarchyObject? previousParent, IHierarchyObject? newParent) private void OnParentChanged(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent)
{ {
UpdateReferences(newParent); UpdateReferences(newParent);
} }

141
Engine.Core/Universe.cs Normal file
View File

@@ -0,0 +1,141 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("UniverseObject Count: {_universeObjects.Count}")]
public class Universe : BaseEntity, IUniverse
{
public event IUniverse.UpdateEventHandler? OnPreUpdate = null;
public event IUniverse.UpdateEventHandler? OnUpdate = null;
public event IUniverse.PreDrawEventHandler? OnPreDraw = null;
public event IUniverse.UniverseObjectRegisteredEventHandler? OnUniverseObjectRegistered = null;
public event IUniverse.UniverseObjectUnRegisteredEventHandler? OnUniverseObjectUnRegistered = null;
private readonly List<IUniverseObject> _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL);
private float _timeScale = 1f;
public IReadOnlyList<IUniverseObject> UniverseObjects => _universeObjects;
public UniverseTime Time { get; private set; } = new();
public UniverseTime UnscaledTime { get; private set; } = new();
public float TimeScale
{
get => _timeScale;
set => _timeScale = value.Max(0f);
}
public void Register(IUniverseObject universeObject)
{
if (_universeObjects.Contains(universeObject))
throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is already registered to the {nameof(Universe)}.");
universeObject.OnFinalized += OnUniverseObjectFinalize;
universeObject.OnExitedUniverse += OnUniverseObjectExitedUniverse;
if (!universeObject.Initialize())
throw new Exception($"{universeObject.Name} can't be initialized");
for (int i = 0; i < universeObject.Children.Count; i++)
Register(universeObject.Children[i]);
_universeObjects.Add(universeObject);
if (!universeObject.EnterUniverse(this))
throw new Exception($"{universeObject.Name} can't enter the universe");
OnUniverseObjectRegistered?.InvokeSafe(this, universeObject);
}
public T InstantiateUniverseObject<T>(params object?[]? args) where T : class, IUniverseObject
{
T universeObject = Factory.UniverseObjectFactory.Instantiate<T>(args);
Register(universeObject);
return universeObject;
}
public void Remove(IUniverseObject universeObject)
{
universeObject.SetParent(null);
RemoveIncursive(universeObject);
}
private void RemoveIncursive(IUniverseObject universeObject)
{
if (!_universeObjects.Contains(universeObject))
throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is not registered to the {nameof(Universe)}.");
universeObject.OnFinalized -= OnUniverseObjectFinalize;
universeObject.OnExitedUniverse -= OnUniverseObjectExitedUniverse;
for (int i = universeObject.Children.Count - 1; i >= 0; i--)
Remove(universeObject.Children[i]);
_universeObjects.Remove(universeObject);
if (!universeObject.ExitUniverse())
throw new Exception($"{universeObject.Name} can't exit the universe");
if (!universeObject.Finalize())
throw new Exception($"{universeObject.Name} can't be finalized");
OnUniverseObjectUnRegistered?.InvokeSafe(this, universeObject);
}
protected override void InitializeInternal()
{
foreach (IUniverseObject universeObject in UniverseObjects)
universeObject.Initialize();
}
protected override void FinalizeInternal()
{
base.FinalizeInternal();
for (int i = UniverseObjects.Count; i >= 0; i--)
UniverseObjects[i].Finalize();
}
public void Update(UniverseTime engineTime)
{
Debug.AssertHelpers.AssertInitialized(this);
UnscaledTime = engineTime;
Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale)));
OnPreUpdate?.InvokeSafe(this, Time);
for (int i = 0; i < UniverseObjects.Count; i++)
UniverseObjects[i].BehaviourController.Update();
OnUpdate?.InvokeSafe(this, Time);
}
public void PreDraw()
{
Debug.AssertHelpers.AssertInitialized(this);
for (int i = 0; i < UniverseObjects.Count; i++)
UniverseObjects[i].BehaviourController.UpdatePreDraw();
OnPreDraw?.InvokeSafe(this);
}
private void OnUniverseObjectFinalize(IInitializable initializable)
{
if (initializable is IUniverseObject universeObject)
Remove(universeObject);
}
private void OnUniverseObjectExitedUniverse(IUniverseObject sender, IUniverse universe)
{
if (sender is IUniverseObject universeObject)
Remove(universeObject);
}
public IEnumerator<IUniverseObject> GetEnumerator() => _universeObjects.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _universeObjects.GetEnumerator();
}

View File

@@ -6,28 +6,28 @@ using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")] [System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")]
public class HierarchyObject : BaseEntity, IHierarchyObject public class UniverseObject : BaseEntity, IUniverseObject
{ {
public event IHierarchyObject.EnteredHierarchyEventHandler? OnEnteredHierarchy = null; public event IUniverseObject.EnteredUniverseEventHandler? OnEnteredUniverse = null;
public event IHierarchyObject.ExitedHierarchyEventHandler? OnExitedHierarchy = null; public event IUniverseObject.ExitedUniverseEventHandler? OnExitedUniverse = null;
public event IHierarchyObject.ParentChangedEventHandler? OnParentChanged = null; public event IUniverseObject.ParentChangedEventHandler? OnParentChanged = null;
public event IHierarchyObject.ChildrenAddedEventHandler? OnChildrenAdded = null; public event IUniverseObject.ChildrenAddedEventHandler? OnChildrenAdded = null;
public event IHierarchyObject.ChildrenRemovedEventHandler? OnChildrenRemoved = null; public event IUniverseObject.ChildrenRemovedEventHandler? OnChildrenRemoved = null;
public event IHasBehaviourController.BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null; public event IHasBehaviourController.BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null;
public event INameable.NameChangedEventHandler? OnNameChanged = null; public event INameable.NameChangedEventHandler? OnNameChanged = null;
public event IActive.ActiveChangedEventHandler? OnActiveChanged = null; public event IActive.ActiveChangedEventHandler? OnActiveChanged = null;
private string _name = nameof(HierarchyObject); private string _name = nameof(UniverseObject);
private IGameManager _gameManager = null!; private IUniverse _universe = null!;
private IBehaviourController _behaviourController = null!; private IBehaviourController _behaviourController = null!;
private bool _isActive = false; private bool _isActive = false;
private readonly List<IHierarchyObject> _children = []; private readonly List<IUniverseObject> _children = [];
public IHierarchyObject? Parent { get; private set; } = null; public IUniverseObject? Parent { get; private set; } = null;
public IReadOnlyList<IHierarchyObject> Children => _children; public IReadOnlyList<IUniverseObject> Children => _children;
public IBehaviourController BehaviourController => _behaviourController; public IBehaviourController BehaviourController => _behaviourController;
public IGameManager GameManager => _gameManager; public IUniverse Universe => _universe;
public bool IsInHierarchy => _gameManager is not null; public bool IsInUniverse => _universe is not null;
public bool IsActive => _isActive; public bool IsActive => _isActive;
public string Name public string Name
@@ -39,36 +39,36 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
string previousName = _name; string previousName = _name;
_name = value; _name = value;
OnNameChanged?.Invoke(this, previousName); OnNameChanged?.InvokeSafe(this, previousName);
} }
} }
protected virtual void OnEnteringHierarchy(IGameManager gameManager) { } protected virtual void OnEnteringUniverse(IUniverse universe) { }
bool IHierarchyObject.EnterHierarchy(IGameManager gameManager) bool IUniverseObject.EnterUniverse(IUniverse universe)
{ {
if (IsInHierarchy) if (IsInUniverse)
return false; return false;
_gameManager = gameManager; _universe = universe;
UpdateActive(); UpdateActive();
OnEnteringHierarchy(gameManager); OnEnteringUniverse(universe);
OnEnteredHierarchy?.Invoke(this, gameManager); OnEnteredUniverse?.InvokeSafe(this, universe);
return true; return true;
} }
protected virtual void OnExitingHierarchy(IGameManager gameManager) { } protected virtual void OnExitingUniverse(IUniverse universe) { }
bool IHierarchyObject.ExitHierarchy() bool IUniverseObject.ExitUniverse()
{ {
if (!IsInHierarchy || _gameManager is not IGameManager gameManager) if (!IsInUniverse || _universe is not IUniverse universe)
return false; return false;
OnExitingHierarchy(gameManager); OnExitingUniverse(universe);
_gameManager = null!; _universe = null!;
OnExitedHierarchy?.Invoke(this, gameManager); OnExitedUniverse?.InvokeSafe(this, universe);
return true; return true;
} }
public void SetParent(IHierarchyObject? parent) public void SetParent(IUniverseObject? parent)
{ {
if (parent == this) if (parent == this)
throw new Exceptions.AssignFailedException($"{Name} can not parent itself"); throw new Exceptions.AssignFailedException($"{Name} can not parent itself");
@@ -76,7 +76,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
if (Parent == parent) if (Parent == parent)
return; return;
IHierarchyObject? previousParent = Parent; IUniverseObject? previousParent = Parent;
if (previousParent is not null) if (previousParent is not null)
{ {
previousParent.RemoveChild(this); previousParent.RemoveChild(this);
@@ -87,34 +87,34 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
if (parent is not null) if (parent is not null)
{ {
if (parent.IsInHierarchy && !IsInHierarchy) if (parent.IsInUniverse && !IsInUniverse)
parent.GameManager.Register(this); parent.Universe.Register(this);
parent.AddChild(this); parent.AddChild(this);
parent.OnActiveChanged += OnParentActiveChanged; parent.OnActiveChanged += OnParentActiveChanged;
} }
UpdateActive(); UpdateActive();
OnParentChanged?.Invoke(this, previousParent, parent); OnParentChanged?.InvokeSafe(this, previousParent, parent);
} }
public void AddChild(IHierarchyObject parent) public void AddChild(IUniverseObject parent)
{ {
if (_children.Contains(parent)) if (_children.Contains(parent))
return; return;
_children.Add(parent); _children.Add(parent);
parent.SetParent(this); parent.SetParent(this);
OnChildrenAdded?.Invoke(this, parent); OnChildrenAdded?.InvokeSafe(this, parent);
} }
public void RemoveChild(IHierarchyObject child) public void RemoveChild(IUniverseObject child)
{ {
if (!_children.Remove(child)) if (!_children.Remove(child))
return; return;
child.SetParent(null); child.SetParent(null);
OnChildrenRemoved?.Invoke(this, child); OnChildrenRemoved?.InvokeSafe(this, child);
} }
protected virtual void OnAssign(IBehaviourController behaviourController) { } protected virtual void OnAssign(IBehaviourController behaviourController) { }
@@ -125,7 +125,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_behaviourController = behaviourController; _behaviourController = behaviourController;
OnAssign(behaviourController); OnAssign(behaviourController);
OnBehaviourControllerAssigned?.Invoke(this); OnBehaviourControllerAssigned?.InvokeSafe(this);
return true; return true;
} }
@@ -145,7 +145,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_isActive = StateEnable.Enabled && (Parent?.IsActive ?? true); _isActive = StateEnable.Enabled && (Parent?.IsActive ?? true);
if (previousActive != IsActive) if (previousActive != IsActive)
OnActiveChanged?.Invoke(this, previousActive); OnActiveChanged?.InvokeSafe(this, previousActive);
} }
protected override void UnassignInternal() protected override void UnassignInternal()
@@ -160,6 +160,11 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_behaviourController ??= Factory.BehaviourControllerFactory.Instantiate(this); _behaviourController ??= Factory.BehaviourControllerFactory.Instantiate(this);
} }
public IEnumerator<IHierarchyObject> GetEnumerator() => _children.GetEnumerator(); public UniverseObject()
{
_name = GetType().Name;
}
public IEnumerator<IUniverseObject> GetEnumerator() => _children.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _children.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => _children.GetEnumerator();
} }

View File

@@ -2,7 +2,7 @@ using System;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public readonly struct EngineTime(TimeSpan TimeSinceStart, TimeSpan TimeDelta) public readonly struct UniverseTime(TimeSpan TimeSinceStart, TimeSpan TimeDelta)
{ {
public readonly TimeSpan TimeSinceStart = TimeSinceStart; public readonly TimeSpan TimeSinceStart = TimeSinceStart;
public readonly TimeSpan DeltaSpan = TimeDelta; public readonly TimeSpan DeltaSpan = TimeDelta;

View File

@@ -37,10 +37,10 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D
Transform.OnPositionChanged += SetNeedsRecalculationFromPosition; Transform.OnPositionChanged += SetNeedsRecalculationFromPosition;
Transform.OnRotationChanged += SetNeedsRecalculationFromRotation; Transform.OnRotationChanged += SetNeedsRecalculationFromRotation;
Transform.OnScaleChanged += SetNeedsRecalculationFromScale; Transform.OnScaleChanged += SetNeedsRecalculationFromScale;
HierarchyObject.OnParentChanged += UpdateRigidBody2D; UniverseObject.OnParentChanged += UpdateRigidBody2D;
} }
private void UpdateRigidBody2D(IHierarchyObject sender, IHierarchyObject? previousParent, IHierarchyObject? newParent) private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent)
{ {
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D); BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
} }
@@ -71,7 +71,7 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D
Transform.OnRotationChanged -= SetNeedsRecalculationFromRotation; Transform.OnRotationChanged -= SetNeedsRecalculationFromRotation;
} }
public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation); public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.InvokeSafe(this, collisionDetectionInformation);
public void Resolve(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionResolved?.Invoke(this, collisionDetectionInformation); public void Resolve(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionResolved?.InvokeSafe(this, collisionDetectionInformation);
public void Trigger(ICollider2D initiator) => OnTriggered?.Invoke(this, initiator); public void Trigger(ICollider2D initiator) => OnTriggered?.InvokeSafe(this, initiator);
} }

View File

@@ -7,7 +7,7 @@ using Syntriax.Engine.Physics2D.Abstract;
namespace Syntriax.Engine.Physics2D; namespace Syntriax.Engine.Physics2D;
public class PhysicsCoroutineManager : HierarchyObject public class PhysicsCoroutineManager : UniverseObject
{ {
private readonly List<IEnumerator> enumerators = []; private readonly List<IEnumerator> enumerators = [];
private IPhysicsEngine2D? physicsEngine = null; private IPhysicsEngine2D? physicsEngine = null;
@@ -23,13 +23,13 @@ public class PhysicsCoroutineManager : HierarchyObject
enumerators.Remove(enumerator); enumerators.Remove(enumerator);
} }
protected override void OnEnteringHierarchy(IGameManager gameManager) protected override void OnEnteringUniverse(IUniverse universe)
{ {
physicsEngine = gameManager.GetHierarchyObject<IPhysicsEngine2D>(); physicsEngine = universe.GetUniverseObject<IPhysicsEngine2D>();
if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine) if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine)
foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep; foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep;
else else
gameManager.OnUpdate += OnUpdate; universe.OnUpdate += OnUpdate;
} }
private void OnPhysicsStep(IPhysicsEngine2D sender, float stepDeltaTime) private void OnPhysicsStep(IPhysicsEngine2D sender, float stepDeltaTime)
@@ -44,23 +44,23 @@ public class PhysicsCoroutineManager : HierarchyObject
} }
} }
protected override void OnExitingHierarchy(IGameManager gameManager) protected override void OnExitingUniverse(IUniverse universe)
{ {
if (physicsEngine is IPhysicsEngine2D existingPhysicsEngine) if (physicsEngine is IPhysicsEngine2D existingPhysicsEngine)
existingPhysicsEngine.OnPhysicsStep -= OnPhysicsStep; existingPhysicsEngine.OnPhysicsStep -= OnPhysicsStep;
gameManager.OnUpdate -= OnUpdate; universe.OnUpdate -= OnUpdate;
} }
private void OnUpdate(IGameManager sender, EngineTime engineTime) private void OnUpdate(IUniverse sender, UniverseTime engineTime)
{ {
if (GameManager is not IGameManager gameManager) if (Universe is not IUniverse universe)
return; return;
physicsEngine = gameManager.GetHierarchyObject<IPhysicsEngine2D>(); physicsEngine = universe.GetUniverseObject<IPhysicsEngine2D>();
if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine) if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine)
{ {
foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep; foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep;
gameManager.OnUpdate -= OnUpdate; universe.OnUpdate -= OnUpdate;
} }
} }
} }

View File

@@ -4,7 +4,7 @@ using Syntriax.Engine.Physics2D.Abstract;
namespace Syntriax.Engine.Physics2D; namespace Syntriax.Engine.Physics2D;
public class PhysicsEngine2D : HierarchyObject, IPhysicsEngine2D public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D
{ {
public event IPhysicsEngine2D.PhysicsIterationEventHandler? OnPhysicsIteration = null; public event IPhysicsEngine2D.PhysicsIterationEventHandler? OnPhysicsIteration = null;
public event IPhysicsEngine2D.PhysicsStepEventHandler? OnPhysicsStep = null; public event IPhysicsEngine2D.PhysicsStepEventHandler? OnPhysicsStep = null;
@@ -91,13 +91,13 @@ public class PhysicsEngine2D : HierarchyObject, IPhysicsEngine2D
} }
} }
OnPhysicsIteration?.Invoke(this, intervalDeltaTime); OnPhysicsIteration?.InvokeSafe(this, intervalDeltaTime);
} }
foreach (IPhysicsUpdate physicsUpdate in physicsUpdateCollector) foreach (IPhysicsUpdate physicsUpdate in physicsUpdateCollector)
physicsUpdate.PhysicsUpdate(deltaTime); physicsUpdate.PhysicsUpdate(deltaTime);
OnPhysicsStep?.Invoke(this, deltaTime); OnPhysicsStep?.InvokeSafe(this, deltaTime);
} }
private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime) private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)
@@ -109,25 +109,25 @@ public class PhysicsEngine2D : HierarchyObject, IPhysicsEngine2D
rigidBody.Transform.Rotation += rigidBody.AngularVelocity * intervalDeltaTime; rigidBody.Transform.Rotation += rigidBody.AngularVelocity * intervalDeltaTime;
} }
protected override void OnEnteringHierarchy(IGameManager gameManager) protected override void OnEnteringUniverse(IUniverse universe)
{ {
physicsUpdateCollector.Assign(gameManager); physicsUpdateCollector.Assign(universe);
colliderCollector.Assign(gameManager); colliderCollector.Assign(universe);
rigidBodyCollector.Assign(gameManager); rigidBodyCollector.Assign(universe);
gameManager.OnPreUpdate += OnEnginePreUpdate; universe.OnPreUpdate += OnEnginePreUpdate;
} }
protected override void OnExitingHierarchy(IGameManager gameManager) protected override void OnExitingUniverse(IUniverse universe)
{ {
physicsUpdateCollector.Unassign(); physicsUpdateCollector.Unassign();
colliderCollector.Unassign(); colliderCollector.Unassign();
rigidBodyCollector.Unassign(); rigidBodyCollector.Unassign();
gameManager.OnPreUpdate -= OnEnginePreUpdate; universe.OnPreUpdate -= OnEnginePreUpdate;
} }
private void OnEnginePreUpdate(IGameManager sender, EngineTime engineTime) private void OnEnginePreUpdate(IUniverse sender, UniverseTime engineTime)
{ {
physicsTicker += engineTime.DeltaTime; physicsTicker += engineTime.DeltaTime;

View File

@@ -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;
@@ -106,9 +107,9 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D
} }
} }
} }
OnPhysicsIteration?.Invoke(this, intervalDeltaTime); OnPhysicsIteration?.InvokeSafe(this, intervalDeltaTime);
} }
OnPhysicsStep?.Invoke(this, deltaTime); OnPhysicsStep?.InvokeSafe(this, deltaTime);
} }
private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime) private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)

View File

@@ -1,3 +1,5 @@
using Syntriax.Engine.Core;
namespace Syntriax.Engine.StateMachine; namespace Syntriax.Engine.StateMachine;
public class State : IState public class State : IState
@@ -35,12 +37,12 @@ public class State : IState
public void Update() public void Update()
{ {
if (GetNextState() is IState transitionState) if (GetNextState() is IState transitionState)
OnStateTransitionReady?.Invoke(this, transitionState); OnStateTransitionReady?.InvokeSafe(this, transitionState);
OnStateUpdate?.Invoke(this); OnStateUpdate?.InvokeSafe(this);
} }
public void TransitionTo(IState from) => OnStateTransitionedTo?.Invoke(this, from); public void TransitionTo(IState from) => OnStateTransitionedTo?.InvokeSafe(this, from);
public void TransitionFrom(IState to) => OnStateTransitionedFrom?.Invoke(this, to); public void TransitionFrom(IState to) => OnStateTransitionedFrom?.InvokeSafe(this, to);
public IState? GetNextState() public IState? GetNextState()
{ {

View File

@@ -16,21 +16,21 @@ public abstract class StateBehaviourBase : Behaviour, IState
public void Update() public void Update()
{ {
OnUpdateState(); OnUpdateState();
OnStateUpdate?.Invoke(this); OnStateUpdate?.InvokeSafe(this);
} }
protected virtual void OnTransitionedToState(IState from) { } protected virtual void OnTransitionedToState(IState from) { }
public void TransitionTo(IState from) public void TransitionTo(IState from)
{ {
OnTransitionedToState(from); OnTransitionedToState(from);
OnStateTransitionedTo?.Invoke(this, from); OnStateTransitionedTo?.InvokeSafe(this, from);
} }
protected virtual void OnTransitionedFromState(IState to) { } protected virtual void OnTransitionedFromState(IState to) { }
public void TransitionFrom(IState to) public void TransitionFrom(IState to)
{ {
OnTransitionedFromState(to); OnTransitionedFromState(to);
OnStateTransitionedFrom?.Invoke(this, to); OnStateTransitionedFrom?.InvokeSafe(this, to);
} }
public abstract IState? GetNextState(); public abstract IState? GetNextState();

View File

@@ -21,7 +21,7 @@ public class StateMachine : Behaviour
_state = value; _state = value;
previousState.TransitionFrom(value); previousState.TransitionFrom(value);
value.TransitionTo(_state); value.TransitionTo(_state);
OnStateChanged?.Invoke(this, previousState, value); OnStateChanged?.InvokeSafe(this, previousState, value);
value.OnStateTransitionReady += OnStateTransitionReady; value.OnStateTransitionReady += OnStateTransitionReady;
} }

View File

@@ -36,7 +36,7 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
shouldBeTicking = false; shouldBeTicking = false;
State = TimerState.Stopped; State = TimerState.Stopped;
OnStopped?.Invoke(this); OnStopped?.InvokeSafe(this);
} }
protected override void OnUpdate() protected override void OnUpdate()
@@ -44,13 +44,13 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
if (State is not TimerState.Ticking) if (State is not TimerState.Ticking)
return; return;
double delta = GameManager.Time.DeltaSpan.TotalSeconds; double delta = Universe.Time.DeltaSpan.TotalSeconds;
Time += delta; Time += delta;
OnDelta?.Invoke(this, delta); OnDelta?.InvokeSafe(this, delta);
} }
protected override void OnEnteredHierarchy(IGameManager gameManager) protected override void OnEnteredUniverse(IUniverse universe)
{ {
if (!shouldBeTicking || State is TimerState.Ticking) if (!shouldBeTicking || State is TimerState.Ticking)
return; return;
@@ -61,7 +61,7 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
StartStopwatch(); StartStopwatch();
} }
protected override void OnExitedHierarchy(IGameManager gameManager) protected override void OnExitedUniverse(IUniverse universe)
{ {
if (!shouldBeTicking || State is not TimerState.Ticking) if (!shouldBeTicking || State is not TimerState.Ticking)
return; return;
@@ -72,13 +72,13 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
public virtual void Pause() public virtual void Pause()
{ {
State = TimerState.Paused; State = TimerState.Paused;
OnPaused?.Invoke(this); OnPaused?.InvokeSafe(this);
} }
public virtual void Resume() public virtual void Resume()
{ {
State = TimerState.Ticking; State = TimerState.Ticking;
OnResumed?.Invoke(this); OnResumed?.InvokeSafe(this);
} }
private void StartStopwatch() private void StartStopwatch()
@@ -86,7 +86,7 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
hasStartedTickingBefore = true; hasStartedTickingBefore = true;
State = TimerState.Ticking; State = TimerState.Ticking;
OnStarted?.Invoke(this); OnStarted?.InvokeSafe(this);
} }
protected override void OnFinalize() protected override void OnFinalize()

View File

@@ -1,3 +1,5 @@
using Syntriax.Engine.Core;
namespace Syntriax.Engine.Systems.Time; namespace Syntriax.Engine.Systems.Time;
public class TickerBehaviour : StopwatchBehaviour, ITicker public class TickerBehaviour : StopwatchBehaviour, ITicker
@@ -24,7 +26,7 @@ public class TickerBehaviour : StopwatchBehaviour, ITicker
{ {
nextTick += Period; nextTick += Period;
TickCounter++; TickCounter++;
OnTick?.Invoke(this); OnTick?.InvokeSafe(this);
} }
} }

View File

@@ -51,7 +51,7 @@ public class TimerBehaviour : Behaviour, ITimer
shouldBeTicking = false; shouldBeTicking = false;
State = TimerState.Stopped; State = TimerState.Stopped;
OnStopped?.Invoke(this); OnStopped?.InvokeSafe(this);
} }
protected override void OnUpdate() protected override void OnUpdate()
@@ -59,16 +59,16 @@ public class TimerBehaviour : Behaviour, ITimer
if (State is not TimerState.Ticking) if (State is not TimerState.Ticking)
return; return;
double delta = GameManager.Time.DeltaSpan.TotalSeconds; double delta = Universe.Time.DeltaSpan.TotalSeconds;
Remaining -= delta; Remaining -= delta;
OnDelta?.Invoke(this, delta); OnDelta?.InvokeSafe(this, delta);
if (Remaining <= .0f) if (Remaining <= .0f)
Stop(); Stop();
} }
protected override void OnEnteredHierarchy(IGameManager gameManager) protected override void OnEnteredUniverse(IUniverse universe)
{ {
if (!shouldBeTicking || State is TimerState.Ticking) if (!shouldBeTicking || State is TimerState.Ticking)
return; return;
@@ -79,7 +79,7 @@ public class TimerBehaviour : Behaviour, ITimer
StartTimer(); StartTimer();
} }
protected override void OnExitedHierarchy(IGameManager gameManager) protected override void OnExitedUniverse(IUniverse universe)
{ {
if (!shouldBeTicking || State is not TimerState.Ticking) if (!shouldBeTicking || State is not TimerState.Ticking)
return; return;
@@ -90,13 +90,13 @@ public class TimerBehaviour : Behaviour, ITimer
public virtual void Pause() public virtual void Pause()
{ {
State = TimerState.Paused; State = TimerState.Paused;
OnPaused?.Invoke(this); OnPaused?.InvokeSafe(this);
} }
public virtual void Resume() public virtual void Resume()
{ {
State = TimerState.Ticking; State = TimerState.Ticking;
OnResumed?.Invoke(this); OnResumed?.InvokeSafe(this);
} }
private void StartTimer() private void StartTimer()
@@ -104,7 +104,7 @@ public class TimerBehaviour : Behaviour, ITimer
hasStartedTickingBefore = true; hasStartedTickingBefore = true;
State = TimerState.Ticking; State = TimerState.Ticking;
OnStarted?.Invoke(this); OnStarted?.InvokeSafe(this);
} }
protected override void OnFinalize() protected override void OnFinalize()

View File

@@ -26,14 +26,14 @@ internal class Tween : ITween
_state = value; _state = value;
switch (value) switch (value)
{ {
case TweenState.Completed: OnCompleted?.Invoke(this); OnEnded?.Invoke(this); break; case TweenState.Completed: OnCompleted?.InvokeSafe(this); OnEnded?.InvokeSafe(this); break;
case TweenState.Cancelled: OnCancelled?.Invoke(this); OnEnded?.Invoke(this); break; case TweenState.Cancelled: OnCancelled?.InvokeSafe(this); OnEnded?.InvokeSafe(this); break;
case TweenState.Paused: OnPaused?.Invoke(this); break; case TweenState.Paused: OnPaused?.InvokeSafe(this); break;
case TweenState.Playing: case TweenState.Playing:
if (previousState == TweenState.Idle) if (previousState == TweenState.Idle)
OnStarted?.Invoke(this); OnStarted?.InvokeSafe(this);
else else
OnResumed?.Invoke(this); OnResumed?.InvokeSafe(this);
break; break;
} }
} }
@@ -58,9 +58,9 @@ internal class Tween : ITween
_counter = value.Min(Duration).Max(0f); _counter = value.Min(Duration).Max(0f);
Progress = Counter / Duration; Progress = Counter / Duration;
OnUpdated?.Invoke(this); OnUpdated?.InvokeSafe(this);
OnDeltaUpdated?.Invoke(this, Easing.Evaluate(Progress) - Easing.Evaluate(previousProgress)); OnDeltaUpdated?.InvokeSafe(this, Easing.Evaluate(Progress) - Easing.Evaluate(previousProgress));
if (_counter >= Duration) if (_counter >= Duration)
State = TweenState.Completed; State = TweenState.Completed;

View File

@@ -1,3 +1,5 @@
using Syntriax.Engine.Core;
namespace Syntriax.Engine.Systems.Tween; namespace Syntriax.Engine.Systems.Tween;
public static class TweenExtensions public static class TweenExtensions
@@ -42,49 +44,49 @@ public static class TweenExtensions
public static ITween OnStart(this ITween tween, Action callback) public static ITween OnStart(this ITween tween, Action callback)
{ {
Tween tweenConcrete = (Tween)tween; Tween tweenConcrete = (Tween)tween;
tweenConcrete.OnStarted += _ => callback.Invoke(); tweenConcrete.OnStarted += _ => callback.InvokeSafe();
return tween; return tween;
} }
public static ITween OnPause(this ITween tween, Action callback) public static ITween OnPause(this ITween tween, Action callback)
{ {
Tween tweenConcrete = (Tween)tween; Tween tweenConcrete = (Tween)tween;
tweenConcrete.OnPaused += _ => callback.Invoke(); tweenConcrete.OnPaused += _ => callback.InvokeSafe();
return tween; return tween;
} }
public static ITween OnResume(this ITween tween, Action callback) public static ITween OnResume(this ITween tween, Action callback)
{ {
Tween tweenConcrete = (Tween)tween; Tween tweenConcrete = (Tween)tween;
tweenConcrete.OnResumed += _ => callback.Invoke(); tweenConcrete.OnResumed += _ => callback.InvokeSafe();
return tween; return tween;
} }
public static ITween OnCancel(this ITween tween, Action callback) public static ITween OnCancel(this ITween tween, Action callback)
{ {
Tween tweenConcrete = (Tween)tween; Tween tweenConcrete = (Tween)tween;
tweenConcrete.OnCancelled += _ => callback.Invoke(); tweenConcrete.OnCancelled += _ => callback.InvokeSafe();
return tween; return tween;
} }
public static ITween OnComplete(this ITween tween, Action callback) public static ITween OnComplete(this ITween tween, Action callback)
{ {
Tween tweenConcrete = (Tween)tween; Tween tweenConcrete = (Tween)tween;
tweenConcrete.OnCompleted += _ => callback.Invoke(); tweenConcrete.OnCompleted += _ => callback.InvokeSafe();
return tween; return tween;
} }
public static ITween OnEnd(this ITween tween, Action callback) public static ITween OnEnd(this ITween tween, Action callback)
{ {
Tween tweenConcrete = (Tween)tween; Tween tweenConcrete = (Tween)tween;
tweenConcrete.OnEnded += _ => callback.Invoke(); tweenConcrete.OnEnded += _ => callback.InvokeSafe();
return tween; return tween;
} }
public static ITween OnUpdate(this ITween tween, Action callback) public static ITween OnUpdate(this ITween tween, Action callback)
{ {
Tween tweenConcrete = (Tween)tween; Tween tweenConcrete = (Tween)tween;
tweenConcrete.OnUpdated += _ => callback.Invoke(); tweenConcrete.OnUpdated += _ => callback.InvokeSafe();
return tween; return tween;
} }
public static ITween OnDeltaUpdate(this ITween tween, Action<float> callback) public static ITween OnDeltaUpdate(this ITween tween, Action<float> callback)
{ {
Tween tweenConcrete = (Tween)tween; Tween tweenConcrete = (Tween)tween;
tweenConcrete.OnDeltaUpdated += (_, delta) => callback.Invoke(delta); tweenConcrete.OnDeltaUpdated += (_, delta) => callback.InvokeSafe(delta);
return tween; return tween;
} }
} }

View File

@@ -5,7 +5,7 @@ using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Systems.Tween; namespace Syntriax.Engine.Systems.Tween;
public class TweenManager : HierarchyObject public class TweenManager : UniverseObject
{ {
private CoroutineManager coroutineManager = null!; private CoroutineManager coroutineManager = null!;
@@ -14,7 +14,7 @@ public class TweenManager : HierarchyObject
public ITween StartTween(float duration, TweenSetCallback? setCallback = null) public ITween StartTween(float duration, TweenSetCallback? setCallback = null)
{ {
Tween tween = new(duration); Tween tween = new(duration);
tween.OnUpdated += tween => setCallback?.Invoke(tween.Value); tween.OnUpdated += tween => setCallback?.InvokeSafe(tween.Value);
runningCoroutines.Add(tween, coroutineManager.StartCoroutine(RunTween(tween))); runningCoroutines.Add(tween, coroutineManager.StartCoroutine(RunTween(tween)));
return tween; return tween;
} }
@@ -35,7 +35,7 @@ public class TweenManager : HierarchyObject
continue; continue;
} }
tween.Counter += GameManager.Time.DeltaTime; tween.Counter += Universe.Time.DeltaTime;
yield return null; yield return null;
} }
@@ -52,12 +52,12 @@ public class TweenManager : HierarchyObject
runningCoroutines.Remove(tween); runningCoroutines.Remove(tween);
} }
protected override void OnEnteringHierarchy(IGameManager gameManager) protected override void OnEnteringUniverse(IUniverse universe)
{ {
coroutineManager = gameManager.GetRequiredHierarchyObject<CoroutineManager>(); coroutineManager = universe.GetRequiredUniverseObject<CoroutineManager>();
} }
protected override void OnExitingHierarchy(IGameManager gameManager) protected override void OnExitingUniverse(IUniverse universe)
{ {
coroutineManager = null!; coroutineManager = null!;
} }