All delegate events are refactored to use the Event<TSender> and Event<TSender, TArgument> for performance issues regarding delegate events creating garbage, also this gives us better control on event invocation since C# Delegates did also create unnecessary garbage during Delegate.DynamicInvoke
93 lines
4.8 KiB
C#
93 lines
4.8 KiB
C#
using Syntriax.Engine.Core;
|
|
|
|
namespace Syntriax.Engine.Physics2D;
|
|
|
|
public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D
|
|
{
|
|
public Event<ICollider2D, CollisionDetectionInformation> OnCollisionDetected { get; } = new();
|
|
public Event<ICollider2D, CollisionDetectionInformation> OnCollisionResolved { get; } = new();
|
|
public Event<ICollider2D, ICollider2D> OnTriggered { get; } = new();
|
|
|
|
private readonly Event<IBehaviourController, IBehaviourController.BehaviourAddedArguments>.EventHandler delegateOnBehaviourAddedToController = null!;
|
|
private readonly Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments>.EventHandler delegateOnBehaviourRemovedFromController = null!;
|
|
private readonly Event<ITransform2D, ITransform2D.PositionChangedArguments>.EventHandler delegateSetNeedsRecalculationFromPosition = null!;
|
|
private readonly Event<ITransform2D, ITransform2D.RotationChangedArguments>.EventHandler delegateSetNeedsRecalculationFromRotation = null!;
|
|
private readonly Event<ITransform2D, ITransform2D.ScaleChangedArguments>.EventHandler delegateSetNeedsRecalculationFromScale = null!;
|
|
private readonly Event<IUniverseObject, IUniverseObject.ParentChangedArguments>.EventHandler delegateUpdateRigidBody2D = null!;
|
|
|
|
protected bool NeedsRecalculation { get; set; } = true;
|
|
protected IRigidBody2D? _rigidBody2D = null;
|
|
|
|
protected Collider2DBehaviourBase()
|
|
{
|
|
delegateOnBehaviourAddedToController = OnBehaviourAddedToController;
|
|
delegateOnBehaviourRemovedFromController = OnBehaviourRemovedFromController;
|
|
delegateSetNeedsRecalculationFromPosition = SetNeedsRecalculationFromPosition;
|
|
delegateSetNeedsRecalculationFromRotation = SetNeedsRecalculationFromRotation;
|
|
delegateSetNeedsRecalculationFromScale = SetNeedsRecalculationFromScale;
|
|
delegateUpdateRigidBody2D = UpdateRigidBody2D;
|
|
}
|
|
|
|
public IRigidBody2D? RigidBody2D => _rigidBody2D;
|
|
public bool IsTrigger { get; set; } = false;
|
|
|
|
public void Recalculate()
|
|
{
|
|
if (!NeedsRecalculation)
|
|
return;
|
|
|
|
CalculateCollider();
|
|
NeedsRecalculation = false;
|
|
}
|
|
|
|
public abstract void CalculateCollider();
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
|
|
|
|
BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAddedToController);
|
|
BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemovedFromController);
|
|
|
|
Transform.OnPositionChanged.AddListener(delegateSetNeedsRecalculationFromPosition);
|
|
Transform.OnRotationChanged.AddListener(delegateSetNeedsRecalculationFromRotation);
|
|
Transform.OnScaleChanged.AddListener(delegateSetNeedsRecalculationFromScale);
|
|
UniverseObject.OnParentChanged.AddListener(delegateUpdateRigidBody2D);
|
|
}
|
|
|
|
private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject.ParentChangedArguments args)
|
|
{
|
|
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
|
|
}
|
|
|
|
private void OnBehaviourAddedToController(IBehaviourController sender, IBehaviourController.BehaviourAddedArguments args)
|
|
{
|
|
if (args.BehaviourAdded is IRigidBody2D rigidBody)
|
|
_rigidBody2D = rigidBody;
|
|
}
|
|
|
|
private void OnBehaviourRemovedFromController(IBehaviourController sender, IBehaviourController.BehaviourRemovedArguments args)
|
|
{
|
|
if (args.BehaviourRemoved is IRigidBody2D)
|
|
_rigidBody2D = null;
|
|
}
|
|
|
|
private void SetNeedsRecalculationFromPosition(ITransform2D sender, ITransform2D.PositionChangedArguments args) => NeedsRecalculation = true;
|
|
private void SetNeedsRecalculationFromScale(ITransform2D sender, ITransform2D.ScaleChangedArguments args) => NeedsRecalculation = true;
|
|
private void SetNeedsRecalculationFromRotation(ITransform2D sender, ITransform2D.RotationChangedArguments args) => NeedsRecalculation = true;
|
|
|
|
protected override void OnFinalize()
|
|
{
|
|
BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAddedToController);
|
|
BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemovedFromController);
|
|
Transform.OnScaleChanged.RemoveListener(delegateSetNeedsRecalculationFromScale);
|
|
|
|
Transform.OnPositionChanged.RemoveListener(delegateSetNeedsRecalculationFromPosition);
|
|
Transform.OnRotationChanged.RemoveListener(delegateSetNeedsRecalculationFromRotation);
|
|
}
|
|
|
|
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);
|
|
}
|