Compare commits
16 Commits
5d897f2f56
...
ef21cdf213
Author | SHA1 | Date | |
---|---|---|---|
ef21cdf213 | |||
2cf6135063 | |||
be06575f91 | |||
ed6975bf24 | |||
d9660c08b1 | |||
3902f1caca | |||
14e3337daa | |||
f729cdc0a8 | |||
c767e1e856 | |||
f96c58cbd4 | |||
fed288859f | |||
6e4c9b0ef8 | |||
b931abb735 | |||
72492a9f5a | |||
2f043c19a6 | |||
dbb263ebed |
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +8,7 @@ public interface IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IAssignable"/>'s fields are unassigned and completely ready to recycle.
|
/// Event triggered when the <see cref="IAssignable"/>'s fields are unassigned and completely ready to recycle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignable>? OnUnassigned { get; set; }
|
event OnUnassignedDelegate? OnUnassigned;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unassign <see cref="IAssignable"/>'s all fields and make it ready to recycle.
|
/// Unassign <see cref="IAssignable"/>'s all fields and make it ready to recycle.
|
||||||
@@ -19,4 +17,6 @@ public interface IAssignable
|
|||||||
/// <see cref="true"/>, if the fields are unsigned successfully, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the fields are unsigned successfully, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Unassign();
|
bool Unassign();
|
||||||
|
|
||||||
|
delegate void OnUnassignedDelegate(IAssignable sender);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +8,7 @@ public interface IAssignableBehaviourController : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IBehaviourController"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IBehaviourController"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableBehaviourController>? OnBehaviourControllerAssigned { get; set; }
|
event OnBehaviourControllerAssignedDelegate? OnBehaviourControllerAssigned;
|
||||||
|
|
||||||
/// <inheritdoc cref="IBehaviourController" />
|
/// <inheritdoc cref="IBehaviourController" />
|
||||||
IBehaviourController BehaviourController { get; }
|
IBehaviourController BehaviourController { get; }
|
||||||
@@ -23,4 +21,6 @@ public interface IAssignableBehaviourController : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IBehaviourController behaviourController);
|
bool Assign(IBehaviourController behaviourController);
|
||||||
|
|
||||||
|
delegate void OnBehaviourControllerAssignedDelegate(IAssignableBehaviourController sender);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +8,7 @@ public interface IAssignableEntity : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IEntity"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IEntity"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableEntity>? OnEntityAssigned { get; set; }
|
event OnEntityAssignedDelegate? OnEntityAssigned;
|
||||||
|
|
||||||
/// <inheritdoc cref="IEntity" />
|
/// <inheritdoc cref="IEntity" />
|
||||||
IEntity Entity { get; }
|
IEntity Entity { get; }
|
||||||
@@ -23,4 +21,6 @@ public interface IAssignableEntity : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IEntity entity);
|
bool Assign(IEntity entity);
|
||||||
|
|
||||||
|
delegate void OnEntityAssignedDelegate(IAssignableEntity sender);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +8,7 @@ public interface IAssignableGameManager : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IGameManager"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IGameManager"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; }
|
event OnGameManagerAssignedDelegate? OnGameManagerAssigned;
|
||||||
|
|
||||||
/// <inheritdoc cref="IGameManager" />
|
/// <inheritdoc cref="IGameManager" />
|
||||||
IGameManager GameManager { get; }
|
IGameManager GameManager { get; }
|
||||||
@@ -23,4 +21,6 @@ public interface IAssignableGameManager : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IGameManager gameManager);
|
bool Assign(IGameManager gameManager);
|
||||||
|
|
||||||
|
delegate void OnGameManagerAssignedDelegate(IAssignableGameManager sender);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +8,7 @@ public interface IAssignableGameObject : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IGameObject"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IGameObject"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableGameObject>? OnGameObjectAssigned { get; set; }
|
event OnGameObjectAssignedDelegate? OnGameObjectAssigned;
|
||||||
|
|
||||||
/// <inheritdoc cref="IGameObject" />
|
/// <inheritdoc cref="IGameObject" />
|
||||||
IGameObject GameObject { get; }
|
IGameObject GameObject { get; }
|
||||||
@@ -23,4 +21,6 @@ public interface IAssignableGameObject : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IGameObject gameObject);
|
bool Assign(IGameObject gameObject);
|
||||||
|
|
||||||
|
delegate void OnGameObjectAssignedDelegate(IAssignableGameObject sender);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +8,7 @@ public interface IAssignableStateEnable : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="IStateEnable"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IStateEnable"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; }
|
event OnStateEnableAssignedDelegate? OnStateEnableAssigned;
|
||||||
|
|
||||||
/// <inheritdoc cref="IStateEnable" />
|
/// <inheritdoc cref="IStateEnable" />
|
||||||
IStateEnable StateEnable { get; }
|
IStateEnable StateEnable { get; }
|
||||||
@@ -23,4 +21,6 @@ public interface IAssignableStateEnable : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(IStateEnable stateEnable);
|
bool Assign(IStateEnable stateEnable);
|
||||||
|
|
||||||
|
delegate void OnStateEnableAssignedDelegate(IAssignableStateEnable sender);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +8,7 @@ public interface IAssignableTransform : IAssignable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="ITransform"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="ITransform"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableTransform>? OnTransformAssigned { get; set; }
|
event OnTransformAssignedDelegate? OnTransformAssigned;
|
||||||
|
|
||||||
/// <inheritdoc cref="ITransform" />
|
/// <inheritdoc cref="ITransform" />
|
||||||
ITransform Transform { get; }
|
ITransform Transform { get; }
|
||||||
@@ -23,4 +21,6 @@ public interface IAssignableTransform : IAssignable
|
|||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool Assign(ITransform transform);
|
bool Assign(ITransform transform);
|
||||||
|
|
||||||
|
delegate void OnTransformAssignedDelegate(IAssignableTransform sender);
|
||||||
}
|
}
|
||||||
|
105
Engine.Core/Abstract/BaseEntity.cs
Normal file
105
Engine.Core/Abstract/BaseEntity.cs
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
public abstract class BaseEntity : IEntity
|
||||||
|
{
|
||||||
|
public event IEntity.OnIdChangedDelegate? OnIdChanged = null;
|
||||||
|
|
||||||
|
public event IInitialize.OnInitializedDelegate? OnInitialized = null;
|
||||||
|
public event IInitialize.OnFinalizedDelegate? OnFinalized = null;
|
||||||
|
|
||||||
|
public event IAssignableStateEnable.OnStateEnableAssignedDelegate? OnStateEnableAssigned = null;
|
||||||
|
public event IAssignable.OnUnassignedDelegate? OnUnassigned = null;
|
||||||
|
|
||||||
|
|
||||||
|
private IStateEnable _stateEnable = null!;
|
||||||
|
|
||||||
|
private bool _initialized = false;
|
||||||
|
private string _id = string.Empty;
|
||||||
|
|
||||||
|
public virtual IStateEnable StateEnable => _stateEnable;
|
||||||
|
|
||||||
|
public virtual bool IsActive => StateEnable.Enabled;
|
||||||
|
|
||||||
|
public string Id
|
||||||
|
{
|
||||||
|
get => _id;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string previousId = _id;
|
||||||
|
|
||||||
|
_id = value;
|
||||||
|
OnIdChanged?.Invoke(this, previousId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Initialized
|
||||||
|
{
|
||||||
|
get => _initialized;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_initialized = value;
|
||||||
|
if (value)
|
||||||
|
OnInitialized?.Invoke(this);
|
||||||
|
else
|
||||||
|
OnFinalized?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Assign(IStateEnable stateEnable)
|
||||||
|
{
|
||||||
|
if (Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_stateEnable = stateEnable;
|
||||||
|
_stateEnable.Assign(this);
|
||||||
|
OnStateEnableAssigned?.Invoke(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void UnassignInternal() { }
|
||||||
|
public bool Unassign()
|
||||||
|
{
|
||||||
|
if (Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UnassignInternal();
|
||||||
|
|
||||||
|
OnUnassigned?.Invoke(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void InitializeInternal() { }
|
||||||
|
public bool Initialize()
|
||||||
|
{
|
||||||
|
if (Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
InitializeInternal();
|
||||||
|
|
||||||
|
Initialized = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void FinalizeInternal() { }
|
||||||
|
public bool Finalize()
|
||||||
|
{
|
||||||
|
if (!Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FinalizeInternal();
|
||||||
|
|
||||||
|
Initialized = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BaseEntity() => _id = Guid.NewGuid().ToString("D");
|
||||||
|
protected BaseEntity(string id) => _id = id;
|
||||||
|
}
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +8,7 @@ public interface IBehaviour : IEntity, IAssignableBehaviourController, IAssignab
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the priority of the <see cref="IBehaviour"/> changes.
|
/// Event triggered when the priority of the <see cref="IBehaviour"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviour>? OnPriorityChanged { get; set; }
|
event OnPriorityChangedDelegate? OnPriorityChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The priority of the <see cref="IBehaviour"/>.
|
/// The priority of the <see cref="IBehaviour"/>.
|
||||||
@@ -21,4 +19,6 @@ public interface IBehaviour : IEntity, IAssignableBehaviourController, IAssignab
|
|||||||
/// The value indicating whether the <see cref="IBehaviour"/> is active.
|
/// The value indicating whether the <see cref="IBehaviour"/> is active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsActive { get; }
|
bool IsActive { get; }
|
||||||
|
|
||||||
|
delegate void OnPriorityChangedDelegate(IBehaviour sender, int previousPriority);
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
@@ -12,27 +11,27 @@ public interface IBehaviourController : IAssignableGameObject, IEnumerable<IBeha
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered before the update of <see cref="IBehaviour"/>s.
|
/// Event triggered before the update of <see cref="IBehaviour"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController>? OnPreUpdate { get; set; }
|
event OnPreUpdateDelegate? OnPreUpdate;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered during the update of <see cref="IBehaviour"/>s.
|
/// Event triggered during the update of <see cref="IBehaviour"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController>? OnUpdate { get; set; }
|
event OnUpdateDelegate? OnUpdate;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered before the drawing phase.
|
/// Event triggered before the drawing phase.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController>? OnPreDraw { get; set; }
|
event OnPreDrawDelegate? OnPreDraw;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a <see cref="IBehaviour"/> is added to the <see cref="IBehaviourController"/>.
|
/// Event triggered when a <see cref="IBehaviour"/> is added to the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController, IBehaviour>? OnBehaviourAdded { get; set; }
|
event OnBehaviourAddedDelegate? OnBehaviourAdded;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a <see cref="IBehaviour"/> is removed from the <see cref="IBehaviourController"/>.
|
/// Event triggered when a <see cref="IBehaviour"/> is removed from the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController, IBehaviour>? OnBehaviourRemoved { get; set; }
|
event OnBehaviourRemovedDelegate? OnBehaviourRemoved;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="IBehaviour"/> to the <see cref="IBehaviourController"/>.
|
/// Adds a <see cref="IBehaviour"/> to the <see cref="IBehaviourController"/>.
|
||||||
@@ -102,4 +101,11 @@ public interface IBehaviourController : IAssignableGameObject, IEnumerable<IBeha
|
|||||||
/// Performs pre-draw operations.
|
/// Performs pre-draw operations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void UpdatePreDraw();
|
void UpdatePreDraw();
|
||||||
|
|
||||||
|
delegate void OnPreUpdateDelegate(IBehaviourController sender);
|
||||||
|
delegate void OnUpdateDelegate(IBehaviourController sender);
|
||||||
|
delegate void OnPreDrawDelegate(IBehaviourController sender);
|
||||||
|
delegate void OnBehaviourAddedDelegate(IBehaviourController sender, IBehaviour behaviourAdded);
|
||||||
|
delegate void OnBehaviourRemovedDelegate(IBehaviourController sender, IBehaviour behaviourRemoved);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -5,4 +5,16 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IEntity : IInitialize, IAssignableStateEnable
|
public interface IEntity : IInitialize, IAssignableStateEnable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the <see cref="Id"/> of the <see cref="IEntity"/> changes.
|
||||||
|
/// The string action parameter is the previous <see cref="Id"/> of the <see cref="IEntity"/>.
|
||||||
|
/// </summary>
|
||||||
|
event OnIdChangedDelegate? OnIdChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the <see cref="IEntity"/>.
|
||||||
|
/// </summary>
|
||||||
|
string Id { get; set; }
|
||||||
|
|
||||||
|
delegate void OnIdChangedDelegate(IEntity sender, string previousId);
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
@@ -11,12 +10,12 @@ public interface IGameManager : IEntity, IEnumerable<IGameObject>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a <see cref="IGameObject"/> is registered to the <see cref="IGameManager"/>.
|
/// Event triggered when a <see cref="IGameObject"/> is registered to the <see cref="IGameManager"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IGameManager, IGameObject>? OnGameObjectRegistered { get; set; }
|
event OnGameObjectRegisteredDelegate? OnGameObjectRegistered;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a <see cref="IGameObject"/> is unregistered from the <see cref="IGameManager"/>.
|
/// Event triggered when a <see cref="IGameObject"/> is unregistered from the <see cref="IGameManager"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IGameManager, IGameObject>? OnGameObjectUnRegistered { get; set; }
|
event OnGameObjectUnRegisteredDelegate? OnGameObjectUnRegistered;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only list of <see cref="IGameObject"/>s managed by the <see cref="IGameManager"/>.
|
/// Gets a read-only list of <see cref="IGameObject"/>s managed by the <see cref="IGameManager"/>.
|
||||||
@@ -54,4 +53,7 @@ public interface IGameManager : IEntity, IEnumerable<IGameObject>
|
|||||||
/// Performs operations that should be done before the draw calls.
|
/// Performs operations that should be done before the draw calls.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void PreDraw();
|
void PreDraw();
|
||||||
|
|
||||||
|
delegate void OnGameObjectRegisteredDelegate(IGameManager sender, IGameObject gameObjectRegistered);
|
||||||
|
delegate void OnGameObjectUnRegisteredDelegate(IGameManager sender, IGameObject gameObjectUnregistered);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,10 +8,12 @@ public interface IGameObject : IEntity, IAssignableGameManager, IAssignableTrans
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Update"/> method is called.
|
/// Event triggered when the <see cref="Update"/> method is called.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IGameObject>? OnUpdated { get; set; }
|
event OnUpdatedDelegate? OnUpdated;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the game object.
|
/// Updates the game object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
delegate void OnUpdatedDelegate(IGameObject sender);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,12 +8,12 @@ public interface IInitialize
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Initialize"/> method is called successfully.
|
/// Event triggered when the <see cref="Initialize"/> method is called successfully.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IInitialize>? OnInitialized { get; set; }
|
event OnInitializedDelegate? OnInitialized;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Finalize"/> method is called successfully.
|
/// Event triggered when the <see cref="Finalize"/> method is called successfully.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IInitialize>? OnFinalized { get; set; }
|
event OnFinalizedDelegate? OnFinalized;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value indicating whether the entity has been initialized.
|
/// The value indicating whether the entity has been initialized.
|
||||||
@@ -33,4 +31,7 @@ public interface IInitialize
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns><see cref="true"/> if finalization is successful, otherwise <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if finalization is successful, otherwise <see cref="false"/>.</returns>
|
||||||
bool Finalize();
|
bool Finalize();
|
||||||
|
|
||||||
|
delegate void OnInitializedDelegate(IInitialize sender);
|
||||||
|
delegate void OnFinalizedDelegate(IInitialize sender);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,10 +8,12 @@ public interface INameable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the name of the entity changes.
|
/// Event triggered when the name of the entity changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IEntity>? OnNameChanged { get; set; }
|
event OnNameChangedDelegate? OnNameChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the entity.
|
/// The name of the entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
|
|
||||||
|
delegate void OnNameChangedDelegate(INameable sender, string previousName);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,10 +8,12 @@ public interface IStateEnable : IAssignableEntity
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Enabled"/> state of the <see cref="IStateEnable"/> changes.
|
/// Event triggered when the <see cref="Enabled"/> state of the <see cref="IStateEnable"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IStateEnable>? OnEnabledChanged { get; set; }
|
event OnNameChangedDelegate? OnEnabledChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value indicating whether the <see cref="IStateEnable"/> is enabled.
|
/// The value indicating whether the <see cref="IStateEnable"/> is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool Enabled { get; set; }
|
bool Enabled { get; set; }
|
||||||
|
|
||||||
|
delegate void OnNameChangedDelegate(IStateEnable sender, bool previousState);
|
||||||
}
|
}
|
||||||
|
@@ -1,39 +1,105 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the transformation properties of an object such as position, scale, and rotation.
|
/// Represents the transformation properties of an object such as position, scale, and rotation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ITransform
|
public interface ITransform : IAssignableGameObject, IEnumerable<ITransform>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform"/> changes.
|
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<ITransform>? OnPositionChanged { get; set; }
|
event OnPositionChangedDelegate? OnPositionChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Scale"/> of the <see cref="ITransform"/> changes.
|
/// Event triggered when the <see cref="Scale"/> of the <see cref="ITransform"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<ITransform>? OnScaleChanged { get; set; }
|
event OnScaleChangedDelegate? OnScaleChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Rotation"/> of the <see cref="ITransform"/> changes.
|
/// Event triggered when the <see cref="Rotation"/> of the <see cref="ITransform"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<ITransform>? OnRotationChanged { get; set; }
|
event OnRotationChangedDelegate? OnRotationChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The position of the <see cref="ITransform"/> in 2D space.
|
/// Event triggered when the <see cref="Parent"/> of the <see cref="ITransform"/> changes. The second parameter is the old <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
event OnParentChangedDelegate? OnParentChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when a new <see cref="ITransform"/> is added to the <see cref="Children"/>.
|
||||||
|
/// </summary>
|
||||||
|
event OnChildrenAddedDelegate? OnChildrenAdded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when an <see cref="ITransform"/> is removed from the <see cref="Children"/>.
|
||||||
|
/// </summary>
|
||||||
|
event OnChildrenRemovedDelegate? OnChildrenRemoved;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The world position of the <see cref="ITransform"/> in 2D space.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Vector2D Position { get; set; }
|
Vector2D Position { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The scale of the <see cref="ITransform"/>.
|
/// The world scale of the <see cref="ITransform"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Vector2D Scale { get; set; }
|
Vector2D Scale { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The rotation of the <see cref="ITransform"/> in degrees.
|
/// The world rotation of the <see cref="ITransform"/> in degrees.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
float Rotation { get; set; }
|
float Rotation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The local position of the <see cref="ITransform"/> in 2D space.
|
||||||
|
/// </summary>
|
||||||
|
Vector2D LocalPosition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The local scale of the <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
Vector2D LocalScale { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The local rotation of the <see cref="ITransform"/> in degrees.
|
||||||
|
/// </summary>
|
||||||
|
float LocalRotation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The parent <see cref="ITransform"/> of the <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
ITransform? Parent { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ITransform"/>s that have this <see cref="ITransform"/> as their <see cref="Parent"/>.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyList<ITransform> Children { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the parent <see cref="ITransform"/> of this <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transform">The parent <see cref="ITransform"/> to set.</param>
|
||||||
|
void SetParent(ITransform? transform);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a child <see cref="ITransform"/> to this <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transform">The child <see cref="ITransform"/> to add.</param>
|
||||||
|
void AddChild(ITransform transform);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a child <see cref="ITransform"/> from this <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transform">The child <see cref="ITransform"/> to remove.</param>
|
||||||
|
void RemoveChild(ITransform transform);
|
||||||
|
|
||||||
|
delegate void OnPositionChangedDelegate(ITransform sender);
|
||||||
|
delegate void OnScaleChangedDelegate(ITransform sender);
|
||||||
|
delegate void OnRotationChangedDelegate(ITransform sender);
|
||||||
|
delegate void OnParentChangedDelegate(ITransform sender, ITransform? newParent);
|
||||||
|
delegate void OnChildrenAddedDelegate(ITransform sender, ITransform childrenAdded);
|
||||||
|
delegate void OnChildrenRemovedDelegate(ITransform sender, ITransform childrenRemoved);
|
||||||
}
|
}
|
||||||
|
@@ -1,48 +1,24 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")]
|
[System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")]
|
||||||
public abstract class Behaviour : IBehaviour
|
public abstract class Behaviour : BaseEntity, IBehaviour
|
||||||
{
|
{
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
public event IAssignableBehaviourController.OnBehaviourControllerAssignedDelegate? OnBehaviourControllerAssigned = null;
|
||||||
public Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; } = null;
|
|
||||||
public Action<IAssignableBehaviourController>? OnBehaviourControllerAssigned { get; set; } = null;
|
|
||||||
|
|
||||||
public Action<IInitialize>? OnInitialized { get; set; } = null;
|
public event IBehaviour.OnPriorityChangedDelegate? OnPriorityChanged = null;
|
||||||
public Action<IInitialize>? OnFinalized { get; set; } = null;
|
|
||||||
public Action<IBehaviour>? OnPriorityChanged { get; set; } = null;
|
|
||||||
|
|
||||||
|
|
||||||
private IBehaviourController _behaviourController = null!;
|
private IBehaviourController _behaviourController = null!;
|
||||||
private IStateEnable _stateEnable = null!;
|
|
||||||
|
|
||||||
private bool _initialized = false;
|
|
||||||
private int _priority = 0;
|
private int _priority = 0;
|
||||||
|
|
||||||
public IStateEnable StateEnable => _stateEnable;
|
|
||||||
public IBehaviourController BehaviourController => _behaviourController;
|
public IBehaviourController BehaviourController => _behaviourController;
|
||||||
|
|
||||||
public bool IsActive => StateEnable.Enabled && BehaviourController.GameObject.StateEnable.Enabled;
|
public override bool IsActive => base.IsActive && BehaviourController.GameObject.StateEnable.Enabled;
|
||||||
|
|
||||||
public bool Initialized
|
|
||||||
{
|
|
||||||
get => _initialized;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
if (value == _initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_initialized = value;
|
|
||||||
if (value)
|
|
||||||
OnInitialized?.Invoke(this);
|
|
||||||
else
|
|
||||||
OnFinalized?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Priority
|
public int Priority
|
||||||
{
|
{
|
||||||
@@ -52,22 +28,12 @@ public abstract class Behaviour : IBehaviour
|
|||||||
if (value == _priority)
|
if (value == _priority)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int previousPriority = _priority;
|
||||||
_priority = value;
|
_priority = value;
|
||||||
OnPriorityChanged?.Invoke(this);
|
OnPriorityChanged?.Invoke(this, previousPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Assign(IStateEnable stateEnable)
|
|
||||||
{
|
|
||||||
if (Initialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_stateEnable = stateEnable;
|
|
||||||
_stateEnable.Assign(this);
|
|
||||||
OnStateEnableAssigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Assign(IBehaviourController behaviourController)
|
public bool Assign(IBehaviourController behaviourController)
|
||||||
{
|
{
|
||||||
if (Initialized)
|
if (Initialized)
|
||||||
@@ -78,36 +44,16 @@ public abstract class Behaviour : IBehaviour
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Unassign()
|
protected override void UnassignInternal()
|
||||||
{
|
{
|
||||||
if (Initialized)
|
base.UnassignInternal();
|
||||||
return false;
|
|
||||||
|
|
||||||
_stateEnable = null!;
|
|
||||||
_behaviourController = null!;
|
_behaviourController = null!;
|
||||||
|
|
||||||
OnUnassigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Initialize()
|
protected override void InitializeInternal()
|
||||||
{
|
{
|
||||||
if (Initialized)
|
base.InitializeInternal();
|
||||||
return false;
|
|
||||||
|
|
||||||
NotAssignedException.Check(this, _behaviourController);
|
NotAssignedException.Check(this, _behaviourController);
|
||||||
NotAssignedException.Check(this, _stateEnable);
|
NotAssignedException.Check(this, StateEnable);
|
||||||
|
|
||||||
Initialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Finalize()
|
|
||||||
{
|
|
||||||
if (!Initialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Initialized = false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,13 +6,13 @@ using Syntriax.Engine.Core.Abstract;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
public class BehaviourCollector<T> : IAssignableGameManager, IEnumerable<T>
|
||||||
{
|
{
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
public event IAssignable.OnUnassignedDelegate? OnUnassigned = null;
|
||||||
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
public event IAssignableGameManager.OnGameManagerAssignedDelegate? OnGameManagerAssigned = null;
|
||||||
|
|
||||||
public Action<BehaviourCacher<T>, T>? OnCached { get; set; } = null;
|
public event OnCollectedDelegate? OnCollected = null;
|
||||||
public Action<BehaviourCacher<T>, T>? OnUncached { get; set; } = null;
|
public event OnRemovedDelegate? OnRemoved = null;
|
||||||
|
|
||||||
private readonly List<T> _behaviours = new(32);
|
private readonly List<T> _behaviours = new(32);
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@ public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
|||||||
|
|
||||||
public T this[Index index] => _behaviours[index];
|
public T this[Index index] => _behaviours[index];
|
||||||
|
|
||||||
public BehaviourCacher() { }
|
public BehaviourCollector() { }
|
||||||
public BehaviourCacher(IGameManager gameManager) => Assign(gameManager);
|
public BehaviourCollector(IGameManager gameManager) => Assign(gameManager);
|
||||||
|
|
||||||
private void OnGameObjectRegistered(IGameManager manager, IGameObject gameObject)
|
private void OnGameObjectRegistered(IGameManager manager, IGameObject gameObject)
|
||||||
{
|
{
|
||||||
@@ -42,7 +42,7 @@ public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_behaviours.Add(tBehaviour);
|
_behaviours.Add(tBehaviour);
|
||||||
OnCached?.Invoke(this, tBehaviour);
|
OnCollected?.Invoke(this, tBehaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour)
|
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour)
|
||||||
@@ -53,7 +53,7 @@ public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
|||||||
if (!_behaviours.Remove(tBehaviour))
|
if (!_behaviours.Remove(tBehaviour))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OnUncached?.Invoke(this, tBehaviour);
|
OnRemoved?.Invoke(this, tBehaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Assign(IGameManager gameManager)
|
public bool Assign(IGameManager gameManager)
|
||||||
@@ -99,4 +99,8 @@ public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
|||||||
|
|
||||||
public IEnumerator<T> GetEnumerator() => _behaviours.GetEnumerator();
|
public IEnumerator<T> GetEnumerator() => _behaviours.GetEnumerator();
|
||||||
IEnumerator IEnumerable.GetEnumerator() => _behaviours.GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => _behaviours.GetEnumerator();
|
||||||
|
|
||||||
|
|
||||||
|
public delegate void OnCollectedDelegate(BehaviourCollector<T> sender, T behaviourCollected);
|
||||||
|
public delegate void OnRemovedDelegate(BehaviourCollector<T> sender, T behaviourRemoved);
|
||||||
}
|
}
|
@@ -11,14 +11,14 @@ namespace Syntriax.Engine.Core;
|
|||||||
[System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")]
|
[System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")]
|
||||||
public class BehaviourController : IBehaviourController
|
public class BehaviourController : IBehaviourController
|
||||||
{
|
{
|
||||||
public Action<IBehaviourController>? OnPreUpdate { get; set; }
|
public event IBehaviourController.OnPreUpdateDelegate? OnPreUpdate = null;
|
||||||
public Action<IBehaviourController>? OnUpdate { get; set; } = null;
|
public event IBehaviourController.OnUpdateDelegate? OnUpdate = null;
|
||||||
public Action<IBehaviourController>? OnPreDraw { get; set; } = null;
|
public event IBehaviourController.OnPreDrawDelegate? OnPreDraw = null;
|
||||||
|
|
||||||
public Action<IBehaviourController, IBehaviour>? OnBehaviourAdded { get; set; } = null;
|
public event IBehaviourController.OnBehaviourAddedDelegate? OnBehaviourAdded = null;
|
||||||
public Action<IBehaviourController, IBehaviour>? OnBehaviourRemoved { get; set; } = null;
|
public event IBehaviourController.OnBehaviourRemovedDelegate? OnBehaviourRemoved = null;
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
public event IAssignable.OnUnassignedDelegate? OnUnassigned;
|
||||||
public Action<IAssignableGameObject>? OnGameObjectAssigned { get; set; } = null;
|
public event IAssignableGameObject.OnGameObjectAssignedDelegate? OnGameObjectAssigned = null;
|
||||||
|
|
||||||
|
|
||||||
private readonly IList<IBehaviour> behaviours = new List<IBehaviour>(Constants.BEHAVIOURS_SIZE_INITIAL);
|
private readonly IList<IBehaviour> behaviours = new List<IBehaviour>(Constants.BEHAVIOURS_SIZE_INITIAL);
|
||||||
@@ -165,10 +165,11 @@ public class BehaviourController : IBehaviourController
|
|||||||
behaviours.Add(behaviour);
|
behaviours.Add(behaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPriorityChange(IBehaviour behaviour)
|
|
||||||
|
private void OnPriorityChange(IBehaviour sender, int previousPriority)
|
||||||
{
|
{
|
||||||
behaviours.Remove(behaviour);
|
behaviours.Remove(sender);
|
||||||
InsertBehaviourByPriority(behaviour);
|
InsertBehaviourByPriority(sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<IBehaviour> GetEnumerator() => behaviours.GetEnumerator();
|
public IEnumerator<IBehaviour> GetEnumerator() => behaviours.GetEnumerator();
|
||||||
|
47
Engine.Core/Extensions/BehaviourControllerExtensions.cs
Normal file
47
Engine.Core/Extensions/BehaviourControllerExtensions.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
public static class BehaviourControllerExtensions
|
||||||
|
{
|
||||||
|
public static bool TryGetBehaviourInParent<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
||||||
|
{
|
||||||
|
behaviour = GetBehaviourInParent<T>(behaviourController);
|
||||||
|
return behaviour is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T? GetBehaviourInParent<T>(this IBehaviourController behaviourController) where T : class
|
||||||
|
{
|
||||||
|
IBehaviourController? controller = behaviourController;
|
||||||
|
|
||||||
|
while (controller is not null)
|
||||||
|
{
|
||||||
|
if (behaviourController.GetBehaviour<T>() is T behaviour)
|
||||||
|
return behaviour;
|
||||||
|
|
||||||
|
controller = controller.GameObject.Transform.Parent?.GameObject.BehaviourController;
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetBehaviourInChildren<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
||||||
|
{
|
||||||
|
behaviour = GetBehaviourInChildren<T>(behaviourController);
|
||||||
|
return behaviour is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T? GetBehaviourInChildren<T>(this IBehaviourController behaviourController) where T : class
|
||||||
|
{
|
||||||
|
if (behaviourController.GetBehaviour<T>() is T localBehaviour)
|
||||||
|
return localBehaviour;
|
||||||
|
|
||||||
|
foreach (ITransform transform in behaviourController.GameObject.Transform)
|
||||||
|
if (GetBehaviourInChildren<T>(transform.GameObject.BehaviourController) is T behaviour)
|
||||||
|
return behaviour;
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
@@ -7,18 +7,22 @@ namespace Syntriax.Engine.Core;
|
|||||||
|
|
||||||
public static class BehaviourExtensions
|
public static class BehaviourExtensions
|
||||||
{
|
{
|
||||||
public static bool TryFindBehaviour<T>(this IEnumerable<IGameObject> gameObjects, [NotNullWhen(returnValue: true)] out T? behaviour)
|
public static T? FindBehaviour<T>(this IEnumerable<IGameObject> gameObjects) where T : class
|
||||||
{
|
{
|
||||||
behaviour = default;
|
|
||||||
|
|
||||||
foreach (IGameObject gameObject in gameObjects)
|
foreach (IGameObject gameObject in gameObjects)
|
||||||
if (gameObject.BehaviourController.TryGetBehaviour(out behaviour))
|
if (gameObject.BehaviourController.TryGetBehaviour(out T? behaviour))
|
||||||
return true;
|
return behaviour;
|
||||||
|
|
||||||
return false;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FindBehaviours<T>(this IEnumerable<IGameObject> gameObjects, List<T> behaviours)
|
public static bool TryFindBehaviour<T>(this IEnumerable<IGameObject> gameObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
||||||
|
{
|
||||||
|
behaviour = FindBehaviour<T>(gameObjects);
|
||||||
|
return behaviour is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FindBehaviours<T>(this IEnumerable<IGameObject> gameObjects, List<T> behaviours) where T : class
|
||||||
{
|
{
|
||||||
behaviours.Clear();
|
behaviours.Clear();
|
||||||
List<T> cache = [];
|
List<T> cache = [];
|
||||||
|
9
Engine.Core/Extensions/GameManagerExtensions.cs
Normal file
9
Engine.Core/Extensions/GameManagerExtensions.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
public static class GameManagerExtensions
|
||||||
|
{
|
||||||
|
public static IGameObject InstantiateGameObject(this IGameManager gameManager, params object?[]? args)
|
||||||
|
=> gameManager.InstantiateGameObject<GameObject>(args);
|
||||||
|
}
|
@@ -4,11 +4,16 @@ namespace Syntriax.Engine.Core;
|
|||||||
|
|
||||||
public static class TransformExtensions
|
public static class TransformExtensions
|
||||||
{
|
{
|
||||||
public static ITransform SetTransform(this ITransform transform, Vector2D? position = null, float? rotation = null, Vector2D? scale = null)
|
public static ITransform SetTransform(this ITransform transform,
|
||||||
|
Vector2D? position = null, float? rotation = null, Vector2D? scale = null,
|
||||||
|
Vector2D? localPosition = null, float? localRotation = null, Vector2D? localScale = null)
|
||||||
{
|
{
|
||||||
if (position.HasValue) transform.Position = position.Value;
|
if (position.HasValue) transform.Position = position.Value;
|
||||||
if (rotation.HasValue) transform.Rotation = rotation.Value;
|
if (rotation.HasValue) transform.Rotation = rotation.Value;
|
||||||
if (scale.HasValue) transform.Scale = scale.Value;
|
if (scale.HasValue) transform.Scale = scale.Value;
|
||||||
|
if (localPosition.HasValue) transform.LocalPosition = localPosition.Value;
|
||||||
|
if (localRotation.HasValue) transform.LocalRotation = localRotation.Value;
|
||||||
|
if (localScale.HasValue) transform.LocalScale = localScale.Value;
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,9 @@ public class GameObjectFactory
|
|||||||
behaviourController ??= TypeFactory.Get<BehaviourController>();
|
behaviourController ??= TypeFactory.Get<BehaviourController>();
|
||||||
stateEnable ??= TypeFactory.Get<StateEnable>();
|
stateEnable ??= TypeFactory.Get<StateEnable>();
|
||||||
|
|
||||||
|
if (!transform.Assign(gameObject))
|
||||||
|
throw AssignException.From(transform, gameObject);
|
||||||
|
|
||||||
if (!behaviourController.Assign(gameObject))
|
if (!behaviourController.Assign(gameObject))
|
||||||
throw AssignException.From(behaviourController, gameObject);
|
throw AssignException.From(behaviourController, gameObject);
|
||||||
if (!stateEnable.Assign(gameObject))
|
if (!stateEnable.Assign(gameObject))
|
||||||
|
@@ -9,22 +9,15 @@ using Syntriax.Engine.Core.Factory;
|
|||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("GameObject Count: {_gameObjects.Count}")]
|
[System.Diagnostics.DebuggerDisplay("GameObject Count: {_gameObjects.Count}")]
|
||||||
public class GameManager : IGameManager
|
public class GameManager : BaseEntity, IGameManager
|
||||||
{
|
{
|
||||||
public Action<IGameManager, IGameObject>? OnGameObjectRegistered { get; set; } = null;
|
public event IGameManager.OnGameObjectRegisteredDelegate? OnGameObjectRegistered = null;
|
||||||
public Action<IGameManager, IGameObject>? OnGameObjectUnRegistered { get; set; } = null;
|
public event IGameManager.OnGameObjectUnRegisteredDelegate? OnGameObjectUnRegistered = null;
|
||||||
|
|
||||||
public Action<IInitialize>? OnInitialized { get; set; } = null;
|
|
||||||
public Action<IInitialize>? OnFinalized { get; set; } = null;
|
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
|
||||||
public Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; } = null;
|
|
||||||
|
|
||||||
|
|
||||||
private readonly List<IGameObject> _gameObjects = new(Constants.GAME_OBJECTS_SIZE_INITIAL);
|
private readonly List<IGameObject> _gameObjects = new(Constants.GAME_OBJECTS_SIZE_INITIAL);
|
||||||
|
|
||||||
private IStateEnable _stateEnable = null!;
|
|
||||||
private GameObjectFactory _gameObjectFactory = null!;
|
private GameObjectFactory _gameObjectFactory = null!;
|
||||||
private bool _initialized = false;
|
|
||||||
|
|
||||||
private GameObjectFactory GameObjectFactory
|
private GameObjectFactory GameObjectFactory
|
||||||
{
|
{
|
||||||
@@ -36,21 +29,20 @@ public class GameManager : IGameManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Initialized => _initialized;
|
|
||||||
public IReadOnlyList<IGameObject> GameObjects => _gameObjects;
|
public IReadOnlyList<IGameObject> GameObjects => _gameObjects;
|
||||||
|
|
||||||
public IStateEnable StateEnable
|
public override IStateEnable StateEnable
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_stateEnable is null)
|
if (base.StateEnable is null)
|
||||||
{
|
{
|
||||||
Assign(new StateEnableFactory().Instantiate(this));
|
Assign(new StateEnableFactory().Instantiate(this));
|
||||||
if (_stateEnable is null)
|
if (base.StateEnable is null)
|
||||||
throw NotAssignedException.From(this, _stateEnable);
|
throw NotAssignedException.From(this, base.StateEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _stateEnable;
|
return base.StateEnable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,52 +70,20 @@ public class GameManager : IGameManager
|
|||||||
return gameObject;
|
return gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Initialize()
|
protected override void InitializeInternal()
|
||||||
{
|
{
|
||||||
if (Initialized)
|
base.InitializeInternal();
|
||||||
return false;
|
|
||||||
|
|
||||||
NotAssignedException.Check(this, StateEnable);
|
NotAssignedException.Check(this, StateEnable);
|
||||||
|
|
||||||
foreach (var gameObject in GameObjects)
|
foreach (var gameObject in GameObjects)
|
||||||
gameObject.Initialize();
|
gameObject.Initialize();
|
||||||
|
|
||||||
_initialized = true;
|
|
||||||
OnInitialized?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Finalize()
|
protected override void FinalizeInternal()
|
||||||
{
|
{
|
||||||
if (!Initialized)
|
base.FinalizeInternal();
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = GameObjects.Count; i >= 0; i--)
|
for (int i = GameObjects.Count; i >= 0; i--)
|
||||||
GameObjects[i].Finalize();
|
GameObjects[i].Finalize();
|
||||||
|
|
||||||
OnFinalized?.Invoke(this);
|
|
||||||
_initialized = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Assign(IStateEnable stateEnable)
|
|
||||||
{
|
|
||||||
if (Initialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_stateEnable = stateEnable;
|
|
||||||
OnStateEnableAssigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Unassign()
|
|
||||||
{
|
|
||||||
if (Initialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_stateEnable = null!;
|
|
||||||
OnUnassigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(EngineTime time)
|
public void Update(EngineTime time)
|
||||||
|
@@ -1,25 +1,18 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")]
|
[System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")]
|
||||||
public class GameObject : IGameObject
|
public class GameObject : BaseEntity, IGameObject
|
||||||
{
|
{
|
||||||
public Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; } = null;
|
public event IAssignableTransform.OnTransformAssignedDelegate? OnTransformAssigned = null;
|
||||||
public Action<IAssignableTransform>? OnTransformAssigned { get; set; } = null;
|
public event IAssignableGameManager.OnGameManagerAssignedDelegate? OnGameManagerAssigned = null;
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
public event IAssignableBehaviourController.OnBehaviourControllerAssignedDelegate? OnBehaviourControllerAssigned = null;
|
||||||
public Action<IAssignableBehaviourController>? OnBehaviourControllerAssigned { get; set; } = null;
|
|
||||||
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
|
||||||
|
|
||||||
public Action<IEntity>? OnNameChanged { get; set; } = null;
|
public event INameable.OnNameChangedDelegate? OnNameChanged = null;
|
||||||
|
|
||||||
public Action<IInitialize>? OnInitialized { get; set; } = null;
|
public event IGameObject.OnUpdatedDelegate? OnUpdated = null;
|
||||||
public Action<IInitialize>? OnFinalized { get; set; } = null;
|
|
||||||
|
|
||||||
public Action<IGameObject>? OnUpdated { get; set; } = null;
|
|
||||||
|
|
||||||
|
|
||||||
private ITransform _transform = null!;
|
private ITransform _transform = null!;
|
||||||
@@ -28,29 +21,11 @@ public class GameObject : IGameObject
|
|||||||
private IGameManager _gameManager = null!;
|
private IGameManager _gameManager = null!;
|
||||||
|
|
||||||
private string _name = nameof(GameObject);
|
private string _name = nameof(GameObject);
|
||||||
private bool _initialized = false;
|
|
||||||
|
|
||||||
public ITransform Transform => _transform;
|
public ITransform Transform => _transform;
|
||||||
public IBehaviourController BehaviourController => _behaviourController;
|
public IBehaviourController BehaviourController => _behaviourController;
|
||||||
public IStateEnable StateEnable => _stateEnable;
|
|
||||||
public IGameManager GameManager => _gameManager;
|
public IGameManager GameManager => _gameManager;
|
||||||
|
|
||||||
public bool Initialized
|
|
||||||
{
|
|
||||||
get => _initialized;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
if (value == _initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_initialized = value;
|
|
||||||
if (value)
|
|
||||||
OnInitialized?.Invoke(this);
|
|
||||||
else
|
|
||||||
OnFinalized?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get => _name;
|
get => _name;
|
||||||
@@ -58,23 +33,20 @@ public class GameObject : IGameObject
|
|||||||
{
|
{
|
||||||
if (value == _name) return;
|
if (value == _name) return;
|
||||||
|
|
||||||
|
string previousName = _name;
|
||||||
_name = value;
|
_name = value;
|
||||||
OnNameChanged?.Invoke(this);
|
OnNameChanged?.Invoke(this, previousName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Initialize()
|
protected override void InitializeInternal()
|
||||||
{
|
{
|
||||||
if (Initialized)
|
base.InitializeInternal();
|
||||||
return false;
|
|
||||||
|
|
||||||
NotAssignedException.Check(this, _transform);
|
NotAssignedException.Check(this, _transform);
|
||||||
NotAssignedException.Check(this, _behaviourController);
|
NotAssignedException.Check(this, _behaviourController);
|
||||||
NotAssignedException.Check(this, _stateEnable);
|
NotAssignedException.Check(this, _stateEnable);
|
||||||
NotAssignedException.Check(this, _gameManager);
|
NotAssignedException.Check(this, _gameManager);
|
||||||
|
|
||||||
Initialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -85,29 +57,12 @@ public class GameObject : IGameObject
|
|||||||
OnUpdated?.Invoke(this);
|
OnUpdated?.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Finalize()
|
protected override void FinalizeInternal()
|
||||||
{
|
{
|
||||||
if (!Initialized)
|
base.FinalizeInternal();
|
||||||
return false;
|
|
||||||
|
|
||||||
|
foreach (IBehaviour behaviour in _behaviourController.GetBehaviours<IBehaviour>())
|
||||||
System.Threading.Tasks.Parallel.ForEach(
|
behaviour.Finalize();
|
||||||
_behaviourController.GetBehaviours<IBehaviour>(),
|
|
||||||
behaviour => behaviour.Finalize()
|
|
||||||
);
|
|
||||||
|
|
||||||
Initialized = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Assign(IStateEnable stateEnable)
|
|
||||||
{
|
|
||||||
if (Initialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_stateEnable = stateEnable;
|
|
||||||
OnStateEnableAssigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Assign(ITransform transform)
|
public bool Assign(ITransform transform)
|
||||||
@@ -140,21 +95,18 @@ public class GameObject : IGameObject
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Unassign()
|
protected override void UnassignInternal()
|
||||||
{
|
{
|
||||||
if (Initialized)
|
base.UnassignInternal();
|
||||||
return false;
|
|
||||||
|
|
||||||
_stateEnable = null!;
|
_stateEnable = null!;
|
||||||
_transform = null!;
|
_transform = null!;
|
||||||
_behaviourController = null!;
|
_behaviourController = null!;
|
||||||
_gameManager = null!;
|
_gameManager = null!;
|
||||||
|
|
||||||
OnUnassigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameObject() { OnBehaviourControllerAssigned += ConnectBehaviourController; }
|
public GameObject() { OnBehaviourControllerAssigned += ConnectBehaviourController; }
|
||||||
|
|
||||||
private void ConnectBehaviourController(IAssignableBehaviourController controller)
|
private void ConnectBehaviourController(IAssignableBehaviourController controller)
|
||||||
{
|
{
|
||||||
controller.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
|
controller.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
|
||||||
|
@@ -1,14 +1,12 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class StateEnable : IStateEnable
|
public class StateEnable : IStateEnable
|
||||||
{
|
{
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
public event IAssignable.OnUnassignedDelegate? OnUnassigned = null;
|
||||||
public Action<IAssignableEntity>? OnEntityAssigned { get; set; } = null;
|
public event IAssignableEntity.OnEntityAssignedDelegate? OnEntityAssigned = null;
|
||||||
public Action<IStateEnable>? OnEnabledChanged { get; set; } = null;
|
public event IStateEnable.OnNameChangedDelegate? OnEnabledChanged = null;
|
||||||
|
|
||||||
private bool _enabled = true;
|
private bool _enabled = true;
|
||||||
private IEntity _entity = null!;
|
private IEntity _entity = null!;
|
||||||
@@ -23,8 +21,9 @@ public class StateEnable : IStateEnable
|
|||||||
if (value == _enabled)
|
if (value == _enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool previousState = _enabled;
|
||||||
_enabled = value;
|
_enabled = value;
|
||||||
OnEnabledChanged?.Invoke(this);
|
OnEnabledChanged?.Invoke(this, previousState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,20 +1,41 @@
|
|||||||
using System;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
|
[System.Diagnostics.DebuggerDisplay("Name: {GameObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
|
||||||
public class Transform : ITransform
|
public class Transform : ITransform
|
||||||
{
|
{
|
||||||
public Action<ITransform>? OnPositionChanged { get; set; } = null;
|
public event IAssignableGameObject.OnGameObjectAssignedDelegate? OnGameObjectAssigned = null;
|
||||||
public Action<ITransform>? OnScaleChanged { get; set; } = null;
|
|
||||||
public Action<ITransform>? OnRotationChanged { get; set; } = null;
|
public event IAssignable.OnUnassignedDelegate? OnUnassigned = null;
|
||||||
|
|
||||||
|
public event ITransform.OnPositionChangedDelegate? OnPositionChanged = null;
|
||||||
|
public event ITransform.OnScaleChangedDelegate? OnScaleChanged = null;
|
||||||
|
public event ITransform.OnRotationChangedDelegate? OnRotationChanged = null;
|
||||||
|
|
||||||
|
public event ITransform.OnParentChangedDelegate? OnParentChanged = null;
|
||||||
|
public event ITransform.OnChildrenAddedDelegate? OnChildrenAdded = null;
|
||||||
|
public event ITransform.OnChildrenRemovedDelegate? OnChildrenRemoved = null;
|
||||||
|
|
||||||
|
|
||||||
private Vector2D _position = Vector2D.Zero;
|
private Vector2D _position = Vector2D.Zero;
|
||||||
private Vector2D _scale = Vector2D.One;
|
private Vector2D _scale = Vector2D.One;
|
||||||
private float _rotation = 0f;
|
private float _rotation = 0f;
|
||||||
|
|
||||||
|
private Vector2D _localPosition = Vector2D.Zero;
|
||||||
|
private Vector2D _localScale = Vector2D.One;
|
||||||
|
private float _localRotation = 0f;
|
||||||
|
|
||||||
|
private readonly List<ITransform> _children = [];
|
||||||
|
|
||||||
|
public IGameObject GameObject { get; private set; } = null!;
|
||||||
|
public ITransform? Parent { get; private set; } = null;
|
||||||
|
|
||||||
|
public IReadOnlyList<ITransform> Children => _children;
|
||||||
|
|
||||||
public Vector2D Position
|
public Vector2D Position
|
||||||
{
|
{
|
||||||
get => _position;
|
get => _position;
|
||||||
@@ -24,6 +45,7 @@ public class Transform : ITransform
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_position = value;
|
_position = value;
|
||||||
|
UpdateLocalPosition();
|
||||||
OnPositionChanged?.Invoke(this);
|
OnPositionChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,6 +59,7 @@ public class Transform : ITransform
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_scale = value;
|
_scale = value;
|
||||||
|
UpdateLocalScale();
|
||||||
OnScaleChanged?.Invoke(this);
|
OnScaleChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +73,210 @@ public class Transform : ITransform
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_rotation = value;
|
_rotation = value;
|
||||||
|
UpdateLocalPosition();
|
||||||
OnRotationChanged?.Invoke(this);
|
OnRotationChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2D LocalPosition
|
||||||
|
{
|
||||||
|
get => _localPosition;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _localPosition)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_localPosition = value;
|
||||||
|
UpdatePosition();
|
||||||
|
OnPositionChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2D LocalScale
|
||||||
|
{
|
||||||
|
get => _localScale;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _localScale)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_localScale = value;
|
||||||
|
UpdateScale();
|
||||||
|
OnScaleChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float LocalRotation
|
||||||
|
{
|
||||||
|
get => _localRotation;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _localRotation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_localRotation = value;
|
||||||
|
UpdateRotation();
|
||||||
|
OnRotationChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetParent(ITransform? transform)
|
||||||
|
{
|
||||||
|
if (transform == this || Parent == transform)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ITransform? previousParent = Parent;
|
||||||
|
if (previousParent is not null)
|
||||||
|
{
|
||||||
|
previousParent.RemoveChild(this);
|
||||||
|
previousParent.OnPositionChanged -= RecalculatePosition;
|
||||||
|
previousParent.OnScaleChanged -= RecalculateScale;
|
||||||
|
previousParent.OnRotationChanged -= RecalculateRotation;
|
||||||
|
previousParent.OnParentChanged -= NotifyChildrenOnParentChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parent = transform;
|
||||||
|
|
||||||
|
if (transform is not null)
|
||||||
|
{
|
||||||
|
transform.AddChild(this);
|
||||||
|
transform.OnPositionChanged += RecalculatePosition;
|
||||||
|
transform.OnScaleChanged += RecalculateScale;
|
||||||
|
transform.OnRotationChanged += RecalculateRotation;
|
||||||
|
transform.OnParentChanged += NotifyChildrenOnParentChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateLocalPosition();
|
||||||
|
UpdateLocalScale();
|
||||||
|
UpdateLocalRotation();
|
||||||
|
|
||||||
|
OnParentChanged?.Invoke(this, previousParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddChild(ITransform transform)
|
||||||
|
{
|
||||||
|
if (_children.Contains(transform))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_children.Add(transform);
|
||||||
|
transform.SetParent(this);
|
||||||
|
OnChildrenAdded?.Invoke(this, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveChild(ITransform transform)
|
||||||
|
{
|
||||||
|
if (!_children.Remove(transform))
|
||||||
|
return;
|
||||||
|
|
||||||
|
transform.SetParent(null);
|
||||||
|
OnChildrenRemoved?.Invoke(this, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<ITransform> GetEnumerator() => _children.GetEnumerator();
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => _children.GetEnumerator();
|
||||||
|
|
||||||
|
private void NotifyChildrenOnParentChange(ITransform transform, ITransform? previousParent)
|
||||||
|
{
|
||||||
|
// TODO No idea how logical this is to propagate this to the children the way I'm doing right now.
|
||||||
|
// I was originally gonna just call `child.OnParentChanged?.Invoke(child, child.Parent);` but seems an unnecessary call too?
|
||||||
|
foreach (var child in Children) // TODO CHECK ERRORS
|
||||||
|
child.SetParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecalculatePosition(ITransform _)
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdatePosition();
|
||||||
|
OnPositionChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecalculateScale(ITransform _)
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdateScale();
|
||||||
|
OnScaleChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecalculateRotation(ITransform _)
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdatePosition();
|
||||||
|
UpdateRotation();
|
||||||
|
OnPositionChanged?.Invoke(this);
|
||||||
|
OnRotationChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLocalPosition()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_localPosition = Position;
|
||||||
|
else
|
||||||
|
_localPosition = Parent.Position.FromTo(Position).Scale(Parent.Scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLocalScale()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_localScale = Scale;
|
||||||
|
else
|
||||||
|
_localScale = Scale.Scale(new(1f / Parent.Scale.X, 1f / Parent.Scale.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLocalRotation()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_localRotation = Rotation;
|
||||||
|
else
|
||||||
|
_localRotation = Rotation - Parent.Rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePosition()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_position = LocalPosition.Scale(Vector2D.One).Rotate(0f * Math.DegreeToRadian);
|
||||||
|
else
|
||||||
|
_position = Parent.Position + LocalPosition.Scale(new(1f / Parent.Scale.X, 1f / Parent.Scale.Y)).Rotate(Parent.Rotation * Math.DegreeToRadian);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateScale()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_scale = LocalScale;
|
||||||
|
else
|
||||||
|
_scale = Vector2D.Scale(Parent.Scale, LocalScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotation()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_rotation = LocalRotation;
|
||||||
|
else
|
||||||
|
_rotation = Parent.Rotation + LocalRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Assign(IGameObject gameObject)
|
||||||
|
{
|
||||||
|
if (GameObject is not null && GameObject.Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GameObject = gameObject;
|
||||||
|
OnGameObjectAssigned?.Invoke(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Unassign()
|
||||||
|
{
|
||||||
|
if (GameObject is not null && GameObject.Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GameObject = null!;
|
||||||
|
OnUnassigned?.Invoke(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
@@ -12,17 +10,17 @@ public interface ICollider2D : IBehaviour, IAssignableTransform
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a collision is detected.
|
/// Event triggered when a collision is detected.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<ICollider2D, CollisionDetectionInformation>? OnCollisionDetected { get; set; }
|
event OnCollisionDetectedDelegate? OnCollisionDetected;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when a collision is resolved.
|
/// Event triggered when a collision is resolved.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<ICollider2D, CollisionDetectionInformation>? OnCollisionResolved { get; set; }
|
event OnCollisionResolvedDelegate? OnCollisionResolved;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when another <see cref="ICollider2D"/> triggers this <see cref="ICollider2D"/>.
|
/// Event triggered when another <see cref="ICollider2D"/> triggers this <see cref="ICollider2D"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<ICollider2D, ICollider2D>? OnTriggered { get; set; }
|
event OnTriggeredDelegate? OnTriggered;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="IRigidBody2D"/> associated with the <see cref="ICollider2D"/>.
|
/// The <see cref="IRigidBody2D"/> associated with the <see cref="ICollider2D"/>.
|
||||||
@@ -38,4 +36,12 @@ public interface ICollider2D : IBehaviour, IAssignableTransform
|
|||||||
/// Recalculates <see cref="ICollider2D"/> properties.
|
/// Recalculates <see cref="ICollider2D"/> properties.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Recalculate();
|
void Recalculate();
|
||||||
|
|
||||||
|
void Detect(CollisionDetectionInformation collisionDetectionInformation);
|
||||||
|
void Resolve(CollisionDetectionInformation collisionDetectionInformation);
|
||||||
|
void Trigger(ICollider2D initiator);
|
||||||
|
|
||||||
|
delegate void OnCollisionDetectedDelegate(ICollider2D sender, CollisionDetectionInformation collisionDetectionInformation);
|
||||||
|
delegate void OnCollisionResolvedDelegate(ICollider2D sender, CollisionDetectionInformation collisionDetectionInformation);
|
||||||
|
delegate void OnTriggeredDelegate(ICollider2D sender, ICollider2D initiatorCollider);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
@@ -8,9 +6,9 @@ namespace Syntriax.Engine.Physics2D;
|
|||||||
|
|
||||||
public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
||||||
{
|
{
|
||||||
public Action<ICollider2D, CollisionDetectionInformation>? OnCollisionDetected { get; set; } = null;
|
public event ICollider2D.OnCollisionDetectedDelegate? OnCollisionDetected = null;
|
||||||
public Action<ICollider2D, CollisionDetectionInformation>? OnCollisionResolved { get; set; } = null;
|
public event ICollider2D.OnCollisionResolvedDelegate? OnCollisionResolved = null;
|
||||||
public Action<ICollider2D, ICollider2D>? OnTriggered { get; set; } = null;
|
public event ICollider2D.OnTriggeredDelegate? OnTriggered = null;
|
||||||
|
|
||||||
|
|
||||||
protected bool NeedsRecalculation { get; private set; } = true;
|
protected bool NeedsRecalculation { get; private set; } = true;
|
||||||
@@ -20,7 +18,7 @@ public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
|||||||
public bool IsTrigger { get; set; } = false;
|
public bool IsTrigger { get; set; } = false;
|
||||||
|
|
||||||
ITransform IAssignableTransform.Transform => Transform;
|
ITransform IAssignableTransform.Transform => Transform;
|
||||||
Action<IAssignableTransform>? IAssignableTransform.OnTransformAssigned { get => GameObject.OnTransformAssigned; set => GameObject.OnTransformAssigned = value; }
|
public event IAssignableTransform.OnTransformAssignedDelegate? OnTransformAssigned { add => GameObject.OnTransformAssigned += value; remove => GameObject.OnTransformAssigned -= value; }
|
||||||
|
|
||||||
bool IAssignableTransform.Assign(ITransform transform) => GameObject.Assign(transform);
|
bool IAssignableTransform.Assign(ITransform transform) => GameObject.Assign(transform);
|
||||||
|
|
||||||
@@ -37,7 +35,7 @@ public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
|||||||
|
|
||||||
protected override void OnInitialize()
|
protected override void OnInitialize()
|
||||||
{
|
{
|
||||||
BehaviourController.TryGetBehaviour(out _rigidBody2D);
|
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
|
||||||
|
|
||||||
BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController;
|
BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController;
|
||||||
BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController;
|
BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController;
|
||||||
@@ -45,6 +43,12 @@ public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
|||||||
Transform.OnPositionChanged += SetNeedsRecalculation;
|
Transform.OnPositionChanged += SetNeedsRecalculation;
|
||||||
Transform.OnRotationChanged += SetNeedsRecalculation;
|
Transform.OnRotationChanged += SetNeedsRecalculation;
|
||||||
Transform.OnScaleChanged += SetNeedsRecalculation;
|
Transform.OnScaleChanged += SetNeedsRecalculation;
|
||||||
|
Transform.OnParentChanged += UpdateRigidBody2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRigidBody2D(ITransform _1, ITransform? _2)
|
||||||
|
{
|
||||||
|
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour)
|
private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour)
|
||||||
@@ -70,4 +74,8 @@ public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
|||||||
Transform.OnPositionChanged -= SetNeedsRecalculation;
|
Transform.OnPositionChanged -= SetNeedsRecalculation;
|
||||||
Transform.OnRotationChanged -= SetNeedsRecalculation;
|
Transform.OnRotationChanged -= SetNeedsRecalculation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation);
|
||||||
|
public void Resolve(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionResolved?.Invoke(this, collisionDetectionInformation);
|
||||||
|
public void Trigger(ICollider2D initiator) => OnTriggered?.Invoke(this, initiator);
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,7 @@ public class CollisionResolver2D : ICollisionResolver2D
|
|||||||
left.Recalculate();
|
left.Recalculate();
|
||||||
right.Recalculate();
|
right.Recalculate();
|
||||||
|
|
||||||
left.OnCollisionResolved?.Invoke(collisionInformation.Left, collisionInformation);
|
left.Resolve(collisionInformation);
|
||||||
right.OnCollisionResolved?.Invoke(right, collisionInformation);
|
right.Resolve(collisionInformation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,33 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Physics2D;
|
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
using Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
namespace Engine.Physics2D;
|
namespace Engine.Physics2D;
|
||||||
|
|
||||||
public static partial class Physics2D
|
public static partial class Physics2D
|
||||||
{
|
{
|
||||||
|
public static bool Overlaps(this Shape shape, Vector2D point) => Overlaps(shape, point, out var _);
|
||||||
|
public static bool Overlaps(this Shape shape, Vector2D point, out float depth)
|
||||||
|
{
|
||||||
|
depth = float.MaxValue;
|
||||||
|
var vertices = shape.Vertices;
|
||||||
|
int count = vertices.Count;
|
||||||
|
|
||||||
|
for (int indexProjection = 0; indexProjection < count; indexProjection++)
|
||||||
|
{
|
||||||
|
Vector2D projectionVector = vertices[indexProjection].FromTo(vertices[(indexProjection + 1) % count]).Perpendicular().Normalized;
|
||||||
|
|
||||||
|
Projection shapeProjection = shape.ToProjection(projectionVector);
|
||||||
|
float projectedPoint = point.Dot(projectionVector);
|
||||||
|
|
||||||
|
if (shapeProjection.Max < projectedPoint || shapeProjection.Min > projectedPoint)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
depth = Math.Min(depth, Math.Abs(Math.AbsMin(shapeProjection.Max - projectedPoint, shapeProjection.Min - projectedPoint)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool Overlaps(this Circle left, Circle right)
|
public static bool Overlaps(this Circle left, Circle right)
|
||||||
{
|
{
|
||||||
float distanceSquared = left.Center.FromTo(right.Center).LengthSquared();
|
float distanceSquared = left.Center.FromTo(right.Center).LengthSquared();
|
||||||
@@ -27,7 +47,7 @@ public static partial class Physics2D
|
|||||||
normal = distanceVector.Normalized;
|
normal = distanceVector.Normalized;
|
||||||
|
|
||||||
if (isOverlapping)
|
if (isOverlapping)
|
||||||
depth = MathF.Sqrt(radiusSumSquared - distanceSquared);
|
depth = Math.Sqrt(radiusSumSquared - distanceSquared);
|
||||||
|
|
||||||
return isOverlapping;
|
return isOverlapping;
|
||||||
}
|
}
|
||||||
@@ -44,7 +64,7 @@ public static partial class Physics2D
|
|||||||
normal = distanceVector.Normalized;
|
normal = distanceVector.Normalized;
|
||||||
|
|
||||||
if (isOverlapping)
|
if (isOverlapping)
|
||||||
depth = MathF.Sqrt(radiusSquared - distanceSquared);
|
depth = Math.Sqrt(radiusSquared - distanceSquared);
|
||||||
|
|
||||||
return isOverlapping;
|
return isOverlapping;
|
||||||
}
|
}
|
||||||
|
@@ -80,17 +80,17 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
|||||||
{
|
{
|
||||||
if (colliderX.IsTrigger)
|
if (colliderX.IsTrigger)
|
||||||
{
|
{
|
||||||
colliderX.OnTriggered?.Invoke(colliderX, colliderY);
|
colliderX.Trigger(colliderY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (colliderY.IsTrigger)
|
else if (colliderY.IsTrigger)
|
||||||
{
|
{
|
||||||
colliderY.OnTriggered?.Invoke(colliderY, colliderY);
|
colliderY.Trigger(colliderY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
colliderX.OnCollisionDetected?.Invoke(colliderX, information);
|
colliderX.Detect(information);
|
||||||
colliderY.OnCollisionDetected?.Invoke(colliderY, information);
|
colliderY.Detect(information);
|
||||||
|
|
||||||
collisionResolver?.Resolve(information);
|
collisionResolver?.Resolve(information);
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
namespace Syntriax.Engine.Physics2D;
|
||||||
|
|
||||||
public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
public class PhysicsEngine2DCollector : IPhysicsEngine2D, IAssignableGameManager
|
||||||
{
|
{
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
public event IAssignable.OnUnassignedDelegate? OnUnassigned = null;
|
||||||
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
public event IAssignableGameManager.OnGameManagerAssignedDelegate? OnGameManagerAssigned = null;
|
||||||
|
|
||||||
|
|
||||||
private int _iterationPerStep = 1;
|
private int _iterationPerStep = 1;
|
||||||
@@ -17,8 +15,8 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
|||||||
protected readonly ICollisionDetector2D collisionDetector = null!;
|
protected readonly ICollisionDetector2D collisionDetector = null!;
|
||||||
protected readonly ICollisionResolver2D collisionResolver = null!;
|
protected readonly ICollisionResolver2D collisionResolver = null!;
|
||||||
|
|
||||||
protected BehaviourCacher<IRigidBody2D> rigidBodyCacher = new();
|
protected BehaviourCollector<IRigidBody2D> rigidBodyCollector = new();
|
||||||
protected BehaviourCacher<ICollider2D> colliderCacher = new();
|
protected BehaviourCollector<ICollider2D> colliderCollector = new();
|
||||||
|
|
||||||
|
|
||||||
public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; }
|
public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; }
|
||||||
@@ -31,23 +29,23 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
|||||||
for (int iterationIndex = 0; iterationIndex < IterationPerStep; iterationIndex++)
|
for (int iterationIndex = 0; iterationIndex < IterationPerStep; iterationIndex++)
|
||||||
{
|
{
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
foreach (var rigidBody in rigidBodyCacher)
|
foreach (var rigidBody in rigidBodyCollector)
|
||||||
StepRigidBody(rigidBody, intervalDeltaTime);
|
StepRigidBody(rigidBody, intervalDeltaTime);
|
||||||
|
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
foreach (var collider in colliderCacher)
|
foreach (var collider in colliderCollector)
|
||||||
collider.Recalculate();
|
collider.Recalculate();
|
||||||
|
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
for (int x = 0; x < colliderCacher.Behaviours.Count; x++)
|
for (int x = 0; x < colliderCollector.Behaviours.Count; x++)
|
||||||
{
|
{
|
||||||
ICollider2D? colliderX = colliderCacher.Behaviours[x];
|
ICollider2D? colliderX = colliderCollector.Behaviours[x];
|
||||||
if (!colliderX.IsActive)
|
if (!colliderX.IsActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int y = x + 1; y < colliderCacher.Behaviours.Count; y++)
|
for (int y = x + 1; y < colliderCollector.Behaviours.Count; y++)
|
||||||
{
|
{
|
||||||
ICollider2D? colliderY = colliderCacher.Behaviours[y];
|
ICollider2D? colliderY = colliderCollector.Behaviours[y];
|
||||||
|
|
||||||
if (!colliderY.IsActive)
|
if (!colliderY.IsActive)
|
||||||
return;
|
return;
|
||||||
@@ -67,17 +65,17 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
|||||||
{
|
{
|
||||||
if (colliderX.IsTrigger)
|
if (colliderX.IsTrigger)
|
||||||
{
|
{
|
||||||
colliderX.OnTriggered?.Invoke(colliderX, colliderY);
|
colliderX.Trigger(colliderY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (colliderY.IsTrigger)
|
else if (colliderY.IsTrigger)
|
||||||
{
|
{
|
||||||
colliderY.OnTriggered?.Invoke(colliderY, colliderY);
|
colliderY.Trigger(colliderY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
colliderX.OnCollisionDetected?.Invoke(colliderX, information);
|
colliderX.Detect(information);
|
||||||
colliderY.OnCollisionDetected?.Invoke(colliderY, information);
|
colliderY.Detect(information);
|
||||||
|
|
||||||
collisionResolver?.Resolve(information);
|
collisionResolver?.Resolve(information);
|
||||||
}
|
}
|
||||||
@@ -100,8 +98,8 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
|||||||
if (GameManager is not null)
|
if (GameManager is not null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
colliderCacher.Assign(gameManager);
|
colliderCollector.Assign(gameManager);
|
||||||
rigidBodyCacher.Assign(gameManager);
|
rigidBodyCollector.Assign(gameManager);
|
||||||
|
|
||||||
GameManager = gameManager;
|
GameManager = gameManager;
|
||||||
OnGameManagerAssigned?.Invoke(this);
|
OnGameManagerAssigned?.Invoke(this);
|
||||||
@@ -114,35 +112,35 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
|||||||
if (GameManager is null)
|
if (GameManager is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
colliderCacher.Unassign();
|
colliderCollector.Unassign();
|
||||||
rigidBodyCacher.Unassign();
|
rigidBodyCollector.Unassign();
|
||||||
|
|
||||||
GameManager = null!;
|
GameManager = null!;
|
||||||
OnUnassigned?.Invoke(this);
|
OnUnassigned?.Invoke(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCacher()
|
public PhysicsEngine2DCollector()
|
||||||
{
|
{
|
||||||
collisionDetector = new CollisionDetector2D();
|
collisionDetector = new CollisionDetector2D();
|
||||||
collisionResolver = new CollisionResolver2D();
|
collisionResolver = new CollisionResolver2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCacher(IGameManager gameManager)
|
public PhysicsEngine2DCollector(IGameManager gameManager)
|
||||||
{
|
{
|
||||||
Assign(gameManager);
|
Assign(gameManager);
|
||||||
collisionDetector = new CollisionDetector2D();
|
collisionDetector = new CollisionDetector2D();
|
||||||
collisionResolver = new CollisionResolver2D();
|
collisionResolver = new CollisionResolver2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCacher(IGameManager gameManager, ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
public PhysicsEngine2DCollector(IGameManager gameManager, ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
||||||
{
|
{
|
||||||
Assign(gameManager);
|
Assign(gameManager);
|
||||||
this.collisionDetector = collisionDetector;
|
this.collisionDetector = collisionDetector;
|
||||||
this.collisionResolver = collisionResolver;
|
this.collisionResolver = collisionResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCacher(ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
public PhysicsEngine2DCollector(ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
||||||
{
|
{
|
||||||
this.collisionDetector = collisionDetector;
|
this.collisionDetector = collisionDetector;
|
||||||
this.collisionResolver = collisionResolver;
|
this.collisionResolver = collisionResolver;
|
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
@@ -8,7 +6,7 @@ namespace Syntriax.Engine.Physics2D;
|
|||||||
|
|
||||||
public class RigidBody2D : BehaviourOverride, IRigidBody2D
|
public class RigidBody2D : BehaviourOverride, IRigidBody2D
|
||||||
{
|
{
|
||||||
public Action<IAssignableTransform>? OnTransformAssigned { get => GameObject.OnTransformAssigned; set => GameObject.OnTransformAssigned = value; }
|
event IAssignableTransform.OnTransformAssignedDelegate? IAssignableTransform.OnTransformAssigned { add => GameObject.OnTransformAssigned += value; remove => GameObject.OnTransformAssigned -= value; }
|
||||||
|
|
||||||
private const float LOWEST_ALLOWED_MASS = 0.00001f;
|
private const float LOWEST_ALLOWED_MASS = 0.00001f;
|
||||||
private float _mass = 1f;
|
private float _mass = 1f;
|
||||||
|
17
README.md
Normal file
17
README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Work In Progress
|
||||||
|
|
||||||
|
This engine is still in development but the implemented features include:
|
||||||
|
- Modular Systems
|
||||||
|
- Behaviour System
|
||||||
|
- 2D Physics Engine(**Not Fully Completed, but usable**)
|
||||||
|
- Rigid Body Simulations
|
||||||
|
- Collision Detection (Convex Shape & Circle)
|
||||||
|
- Collision Resolution (**Not Fully Completed**)
|
||||||
|
- Vector2D, AABB, Circle, Line, LineEquation, Projection & Shape Data Types
|
||||||
|
- General Math
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**A detailed README file will be written in the future. If you want to check out how to use this, please checkout this example Pong game made using this engine on top of [MonoGame](https://monogame.net/) from the link bellow.**
|
||||||
|
|
||||||
|
[Pong Source Code](https://git.syntriax.com/Syntriax/Engine-Pong)
|
Reference in New Issue
Block a user