feat: safe delegate invocation helper added

This commit is contained in:
Syntriax 2025-04-13 19:08:47 +03:00
parent 00f7b1aaab
commit 58eb373c79
21 changed files with 116 additions and 91 deletions

View File

@ -63,12 +63,12 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
{ {
activeBehaviours.Add(behaviour); activeBehaviours.Add(behaviour);
OnBehaviourAdd(behaviour); OnBehaviourAdd(behaviour);
OnCollected?.Invoke(this, behaviour); OnCollected?.InvokeSafe(this, behaviour);
} }
else if (activeBehaviours.Remove(behaviour)) else if (activeBehaviours.Remove(behaviour))
{ {
OnBehaviourRemove(behaviour); OnBehaviourRemove(behaviour);
OnRemoved?.Invoke(this, behaviour); OnRemoved?.InvokeSafe(this, behaviour);
} }
} }
@ -85,7 +85,7 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
if (activeBehaviours.Remove(tBehaviour)) if (activeBehaviours.Remove(tBehaviour))
{ {
OnBehaviourRemove(tBehaviour); OnBehaviourRemove(tBehaviour);
OnRemoved?.Invoke(this, tBehaviour); OnRemoved?.InvokeSafe(this, tBehaviour);
} }
} }
@ -101,7 +101,7 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
gameManager.OnHierarchyObjectUnRegistered += OnHierarchyObjectUnregistered; gameManager.OnHierarchyObjectUnRegistered += OnHierarchyObjectUnregistered;
GameManager = gameManager; GameManager = gameManager;
OnGameManagerAssigned?.Invoke(this); OnGameManagerAssigned?.InvokeSafe(this);
return true; return true;
} }
@ -118,7 +118,7 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
GameManager.OnHierarchyObjectUnRegistered -= OnHierarchyObjectUnregistered; GameManager.OnHierarchyObjectUnRegistered -= OnHierarchyObjectUnregistered;
GameManager = null!; GameManager = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.InvokeSafe(this);
return true; return true;
} }

View File

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

View File

@ -25,7 +25,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
int previousPriority = _priority; int previousPriority = _priority;
_priority = value; _priority = value;
OnPriorityChanged?.Invoke(this, previousPriority); OnPriorityChanged?.InvokeSafe(this, previousPriority);
} }
} }
@ -43,7 +43,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
behaviourController.OnHierarchyObjectAssigned += OnHierarchyObjectAssigned; behaviourController.OnHierarchyObjectAssigned += OnHierarchyObjectAssigned;
if (behaviourController.HierarchyObject is not null) if (behaviourController.HierarchyObject is not null)
OnHierarchyObjectAssigned(behaviourController); OnHierarchyObjectAssigned(behaviourController);
OnBehaviourControllerAssigned?.Invoke(this); OnBehaviourControllerAssigned?.InvokeSafe(this);
return true; return true;
} }
@ -83,6 +83,6 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
_isActive = StateEnable.Enabled && _behaviourController.HierarchyObject.IsActive; _isActive = StateEnable.Enabled && _behaviourController.HierarchyObject.IsActive;
if (previousActive != IsActive) if (previousActive != IsActive)
OnActiveChanged?.Invoke(this, previousActive); OnActiveChanged?.InvokeSafe(this, previousActive);
} }
} }

View File

@ -50,7 +50,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
behaviours.Add(tBehaviour); behaviours.Add(tBehaviour);
OnBehaviourAdd(behaviour); OnBehaviourAdd(behaviour);
OnCollected?.Invoke(this, tBehaviour); OnCollected?.InvokeSafe(this, tBehaviour);
} }
protected virtual void OnBehaviourRemove(IBehaviour behaviour) { } protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
@ -63,7 +63,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
return; return;
OnBehaviourRemove(behaviour); OnBehaviourRemove(behaviour);
OnRemoved?.Invoke(this, tBehaviour); OnRemoved?.InvokeSafe(this, tBehaviour);
} }
protected virtual void OnAssign(IGameManager gameManager) { } protected virtual void OnAssign(IGameManager gameManager) { }
@ -80,7 +80,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
GameManager = gameManager; GameManager = gameManager;
OnAssign(gameManager); OnAssign(gameManager);
OnGameManagerAssigned?.Invoke(this); OnGameManagerAssigned?.InvokeSafe(this);
return true; return true;
} }
@ -97,7 +97,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
GameManager.OnHierarchyObjectUnRegistered -= OnHierarchyObjectUnregistered; GameManager.OnHierarchyObjectUnRegistered -= OnHierarchyObjectUnregistered;
GameManager = null!; GameManager = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.InvokeSafe(this);
return true; return true;
} }

View File

@ -41,9 +41,9 @@ public class BehaviourController : IBehaviourController
_initialized = value; _initialized = value;
if (value) if (value)
OnInitialized?.Invoke(this); OnInitialized?.InvokeSafe(this);
else else
OnFinalized?.Invoke(this); OnFinalized?.InvokeSafe(this);
} }
} }
@ -56,7 +56,7 @@ public class BehaviourController : IBehaviourController
behaviour.Initialize(); behaviour.Initialize();
behaviour.OnPriorityChanged += OnPriorityChange; behaviour.OnPriorityChanged += OnPriorityChange;
OnBehaviourAdded?.Invoke(this, behaviour); OnBehaviourAdded?.InvokeSafe(this, behaviour);
return behaviour; return behaviour;
} }
@ -121,7 +121,7 @@ public class BehaviourController : IBehaviourController
behaviour.OnPriorityChanged -= OnPriorityChange; behaviour.OnPriorityChanged -= OnPriorityChange;
behaviour.Finalize(); behaviour.Finalize();
behaviours.Remove(behaviour); behaviours.Remove(behaviour);
OnBehaviourRemoved?.Invoke(this, behaviour); OnBehaviourRemoved?.InvokeSafe(this, behaviour);
} }
protected virtual void OnAssign(IHierarchyObject hierarchyObject) { } protected virtual void OnAssign(IHierarchyObject hierarchyObject) { }
@ -132,7 +132,7 @@ public class BehaviourController : IBehaviourController
_hierarchyObject = hierarchyObject; _hierarchyObject = hierarchyObject;
OnAssign(hierarchyObject); OnAssign(hierarchyObject);
OnHierarchyObjectAssigned?.Invoke(this); OnHierarchyObjectAssigned?.InvokeSafe(this);
return true; return true;
} }
@ -168,7 +168,7 @@ public class BehaviourController : IBehaviourController
return false; return false;
_hierarchyObject = null!; _hierarchyObject = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.InvokeSafe(this);
return true; return true;
} }
@ -177,8 +177,8 @@ public class BehaviourController : IBehaviourController
if (!HierarchyObject.StateEnable.Enabled) if (!HierarchyObject.StateEnable.Enabled)
return; return;
OnPreUpdate?.Invoke(this); OnPreUpdate?.InvokeSafe(this);
OnUpdate?.Invoke(this); OnUpdate?.InvokeSafe(this);
} }
public void UpdatePreDraw() public void UpdatePreDraw()
@ -186,7 +186,7 @@ public class BehaviourController : IBehaviourController
if (!HierarchyObject.StateEnable.Enabled) if (!HierarchyObject.StateEnable.Enabled)
return; return;
OnPreDraw?.Invoke(this); OnPreDraw?.InvokeSafe(this);
} }
public BehaviourController() { } public BehaviourController() { }

View File

@ -49,7 +49,7 @@ public class GameManager : BaseEntity, IGameManager
if (!hierarchyObject.EnterHierarchy(this)) if (!hierarchyObject.EnterHierarchy(this))
throw new Exception($"{hierarchyObject.Name} can't enter the hierarchy"); throw new Exception($"{hierarchyObject.Name} can't enter the hierarchy");
OnHierarchyObjectRegistered?.Invoke(this, hierarchyObject); OnHierarchyObjectRegistered?.InvokeSafe(this, hierarchyObject);
} }
public T InstantiateHierarchyObject<T>(params object?[]? args) where T : class, IHierarchyObject public T InstantiateHierarchyObject<T>(params object?[]? args) where T : class, IHierarchyObject
@ -84,7 +84,7 @@ public class GameManager : BaseEntity, IGameManager
if (!hierarchyObject.Finalize()) if (!hierarchyObject.Finalize())
throw new Exception($"{hierarchyObject.Name} can't be finalized"); throw new Exception($"{hierarchyObject.Name} can't be finalized");
OnHierarchyObjectUnRegistered?.Invoke(this, hierarchyObject); OnHierarchyObjectUnRegistered?.InvokeSafe(this, hierarchyObject);
} }
protected override void InitializeInternal() protected override void InitializeInternal()
@ -107,12 +107,12 @@ public class GameManager : BaseEntity, IGameManager
UnscaledTime = engineTime; UnscaledTime = engineTime;
Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale))); Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale)));
OnPreUpdate?.Invoke(this, Time); OnPreUpdate?.InvokeSafe(this, Time);
for (int i = 0; i < HierarchyObjects.Count; i++) for (int i = 0; i < HierarchyObjects.Count; i++)
HierarchyObjects[i].BehaviourController.Update(); HierarchyObjects[i].BehaviourController.Update();
OnUpdate?.Invoke(this, Time); OnUpdate?.InvokeSafe(this, Time);
} }
public void PreDraw() public void PreDraw()
@ -122,7 +122,7 @@ public class GameManager : BaseEntity, IGameManager
for (int i = 0; i < HierarchyObjects.Count; i++) for (int i = 0; i < HierarchyObjects.Count; i++)
HierarchyObjects[i].BehaviourController.UpdatePreDraw(); HierarchyObjects[i].BehaviourController.UpdatePreDraw();
OnPreDraw?.Invoke(this); OnPreDraw?.InvokeSafe(this);
} }
private void OnHierarchyObjectFinalize(IInitializable initializable) private void OnHierarchyObjectFinalize(IInitializable initializable)

View File

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

View File

@ -39,7 +39,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
string previousName = _name; string previousName = _name;
_name = value; _name = value;
OnNameChanged?.Invoke(this, previousName); OnNameChanged?.InvokeSafe(this, previousName);
} }
} }
@ -52,7 +52,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_gameManager = gameManager; _gameManager = gameManager;
UpdateActive(); UpdateActive();
OnEnteringHierarchy(gameManager); OnEnteringHierarchy(gameManager);
OnEnteredHierarchy?.Invoke(this, gameManager); OnEnteredHierarchy?.InvokeSafe(this, gameManager);
return true; return true;
} }
@ -64,7 +64,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
OnExitingHierarchy(gameManager); OnExitingHierarchy(gameManager);
_gameManager = null!; _gameManager = null!;
OnExitedHierarchy?.Invoke(this, gameManager); OnExitedHierarchy?.InvokeSafe(this, gameManager);
return true; return true;
} }
@ -95,7 +95,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
} }
UpdateActive(); UpdateActive();
OnParentChanged?.Invoke(this, previousParent, parent); OnParentChanged?.InvokeSafe(this, previousParent, parent);
} }
public void AddChild(IHierarchyObject parent) public void AddChild(IHierarchyObject parent)
@ -105,7 +105,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_children.Add(parent); _children.Add(parent);
parent.SetParent(this); parent.SetParent(this);
OnChildrenAdded?.Invoke(this, parent); OnChildrenAdded?.InvokeSafe(this, parent);
} }
public void RemoveChild(IHierarchyObject child) public void RemoveChild(IHierarchyObject child)
@ -114,7 +114,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
return; return;
child.SetParent(null); child.SetParent(null);
OnChildrenRemoved?.Invoke(this, child); OnChildrenRemoved?.InvokeSafe(this, child);
} }
protected virtual void OnAssign(IBehaviourController behaviourController) { } protected virtual void OnAssign(IBehaviourController behaviourController) { }
@ -125,7 +125,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_behaviourController = behaviourController; _behaviourController = behaviourController;
OnAssign(behaviourController); OnAssign(behaviourController);
OnBehaviourControllerAssigned?.Invoke(this); OnBehaviourControllerAssigned?.InvokeSafe(this);
return true; return true;
} }
@ -145,7 +145,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_isActive = StateEnable.Enabled && (Parent?.IsActive ?? true); _isActive = StateEnable.Enabled && (Parent?.IsActive ?? true);
if (previousActive != IsActive) if (previousActive != IsActive)
OnActiveChanged?.Invoke(this, previousActive); OnActiveChanged?.InvokeSafe(this, previousActive);
} }
protected override void UnassignInternal() protected override void UnassignInternal()

View File

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

View File

@ -31,7 +31,7 @@ public class Transform2D : Behaviour, ITransform2D
_position = value; _position = value;
UpdateLocalPosition(); UpdateLocalPosition();
OnPositionChanged?.Invoke(this, _position); OnPositionChanged?.InvokeSafe(this, _position);
} }
} }
@ -47,7 +47,7 @@ public class Transform2D : Behaviour, ITransform2D
_scale = value; _scale = value;
UpdateLocalScale(); UpdateLocalScale();
OnScaleChanged?.Invoke(this, previousScale); OnScaleChanged?.InvokeSafe(this, previousScale);
} }
} }
@ -63,7 +63,7 @@ public class Transform2D : Behaviour, ITransform2D
_rotation = value; _rotation = value;
UpdateLocalRotation(); UpdateLocalRotation();
OnRotationChanged?.Invoke(this, previousRotation); OnRotationChanged?.InvokeSafe(this, previousRotation);
} }
} }
@ -79,7 +79,7 @@ public class Transform2D : Behaviour, ITransform2D
_localPosition = value; _localPosition = value;
UpdatePosition(); UpdatePosition();
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
} }
@ -97,8 +97,8 @@ public class Transform2D : Behaviour, ITransform2D
UpdateScale(); UpdateScale();
UpdatePosition(); UpdatePosition();
OnScaleChanged?.Invoke(this, previousScale); OnScaleChanged?.InvokeSafe(this, previousScale);
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
} }
@ -114,7 +114,7 @@ public class Transform2D : Behaviour, ITransform2D
_localRotation = value; _localRotation = value;
UpdateRotation(); UpdateRotation();
OnRotationChanged?.Invoke(this, previousRotation); OnRotationChanged?.InvokeSafe(this, previousRotation);
} }
} }
@ -125,7 +125,7 @@ public class Transform2D : Behaviour, ITransform2D
UpdatePosition(); UpdatePosition();
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
private void RecalculateScale(ITransform2D _, Vector2D previousScale) private void RecalculateScale(ITransform2D _, Vector2D previousScale)
@ -138,8 +138,8 @@ public class Transform2D : Behaviour, ITransform2D
UpdateScale(); UpdateScale();
UpdatePosition(); UpdatePosition();
OnScaleChanged?.Invoke(this, previousScale); OnScaleChanged?.InvokeSafe(this, previousScale);
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
private void RecalculateRotation(ITransform2D _, float previousRotation) private void RecalculateRotation(ITransform2D _, float previousRotation)
@ -152,8 +152,8 @@ public class Transform2D : Behaviour, ITransform2D
UpdateRotation(); UpdateRotation();
UpdatePosition(); UpdatePosition();
OnRotationChanged?.Invoke(this, previousRotation); OnRotationChanged?.InvokeSafe(this, previousRotation);
OnPositionChanged?.Invoke(this, previousPosition); OnPositionChanged?.InvokeSafe(this, previousPosition);
} }
private void UpdateLocalPosition() private void UpdateLocalPosition()
@ -247,9 +247,9 @@ public class Transform2D : Behaviour, ITransform2D
UpdateLocalScale(); UpdateLocalScale();
UpdateLocalRotation(); UpdateLocalRotation();
OnPositionChanged?.Invoke(this, Position); OnPositionChanged?.InvokeSafe(this, Position);
OnScaleChanged?.Invoke(this, Scale); OnScaleChanged?.InvokeSafe(this, Scale);
OnRotationChanged?.Invoke(this, Rotation); OnRotationChanged?.InvokeSafe(this, Rotation);
} }
private void LookForTransform2D(IBehaviourController sender, IBehaviour behaviourAdded) private void LookForTransform2D(IBehaviourController sender, IBehaviour behaviourAdded)

View File

@ -71,7 +71,7 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D
Transform.OnRotationChanged -= SetNeedsRecalculationFromRotation; Transform.OnRotationChanged -= SetNeedsRecalculationFromRotation;
} }
public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation); public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.InvokeSafe(this, collisionDetectionInformation);
public void Resolve(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionResolved?.Invoke(this, collisionDetectionInformation); public void Resolve(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionResolved?.InvokeSafe(this, collisionDetectionInformation);
public void Trigger(ICollider2D initiator) => OnTriggered?.Invoke(this, initiator); public void Trigger(ICollider2D initiator) => OnTriggered?.InvokeSafe(this, initiator);
} }

View File

@ -91,13 +91,13 @@ public class PhysicsEngine2D : HierarchyObject, IPhysicsEngine2D
} }
} }
OnPhysicsIteration?.Invoke(this, intervalDeltaTime); OnPhysicsIteration?.InvokeSafe(this, intervalDeltaTime);
} }
foreach (IPhysicsUpdate physicsUpdate in physicsUpdateCollector) foreach (IPhysicsUpdate physicsUpdate in physicsUpdateCollector)
physicsUpdate.PhysicsUpdate(deltaTime); physicsUpdate.PhysicsUpdate(deltaTime);
OnPhysicsStep?.Invoke(this, deltaTime); OnPhysicsStep?.InvokeSafe(this, deltaTime);
} }
private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime) private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Physics2D.Abstract; using Syntriax.Engine.Physics2D.Abstract;
@ -106,9 +107,9 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D
} }
} }
} }
OnPhysicsIteration?.Invoke(this, intervalDeltaTime); OnPhysicsIteration?.InvokeSafe(this, intervalDeltaTime);
} }
OnPhysicsStep?.Invoke(this, deltaTime); OnPhysicsStep?.InvokeSafe(this, deltaTime);
} }
private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime) private static void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)

View File

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

View File

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

View File

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

View File

@ -36,7 +36,7 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
shouldBeTicking = false; shouldBeTicking = false;
State = TimerState.Stopped; State = TimerState.Stopped;
OnStopped?.Invoke(this); OnStopped?.InvokeSafe(this);
} }
protected override void OnUpdate() protected override void OnUpdate()
@ -47,7 +47,7 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
double delta = GameManager.Time.DeltaSpan.TotalSeconds; double delta = GameManager.Time.DeltaSpan.TotalSeconds;
Time += delta; Time += delta;
OnDelta?.Invoke(this, delta); OnDelta?.InvokeSafe(this, delta);
} }
protected override void OnEnteredHierarchy(IGameManager gameManager) protected override void OnEnteredHierarchy(IGameManager gameManager)
@ -72,13 +72,13 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
public virtual void Pause() public virtual void Pause()
{ {
State = TimerState.Paused; State = TimerState.Paused;
OnPaused?.Invoke(this); OnPaused?.InvokeSafe(this);
} }
public virtual void Resume() public virtual void Resume()
{ {
State = TimerState.Ticking; State = TimerState.Ticking;
OnResumed?.Invoke(this); OnResumed?.InvokeSafe(this);
} }
private void StartStopwatch() private void StartStopwatch()
@ -86,7 +86,7 @@ public class StopwatchBehaviour : Behaviour, IStopwatch
hasStartedTickingBefore = true; hasStartedTickingBefore = true;
State = TimerState.Ticking; State = TimerState.Ticking;
OnStarted?.Invoke(this); OnStarted?.InvokeSafe(this);
} }
protected override void OnFinalize() protected override void OnFinalize()

View File

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

View File

@ -51,7 +51,7 @@ public class TimerBehaviour : Behaviour, ITimer
shouldBeTicking = false; shouldBeTicking = false;
State = TimerState.Stopped; State = TimerState.Stopped;
OnStopped?.Invoke(this); OnStopped?.InvokeSafe(this);
} }
protected override void OnUpdate() protected override void OnUpdate()
@ -62,7 +62,7 @@ public class TimerBehaviour : Behaviour, ITimer
double delta = GameManager.Time.DeltaSpan.TotalSeconds; double delta = GameManager.Time.DeltaSpan.TotalSeconds;
Remaining -= delta; Remaining -= delta;
OnDelta?.Invoke(this, delta); OnDelta?.InvokeSafe(this, delta);
if (Remaining <= .0f) if (Remaining <= .0f)
Stop(); Stop();
@ -90,13 +90,13 @@ public class TimerBehaviour : Behaviour, ITimer
public virtual void Pause() public virtual void Pause()
{ {
State = TimerState.Paused; State = TimerState.Paused;
OnPaused?.Invoke(this); OnPaused?.InvokeSafe(this);
} }
public virtual void Resume() public virtual void Resume()
{ {
State = TimerState.Ticking; State = TimerState.Ticking;
OnResumed?.Invoke(this); OnResumed?.InvokeSafe(this);
} }
private void StartTimer() private void StartTimer()
@ -104,7 +104,7 @@ public class TimerBehaviour : Behaviour, ITimer
hasStartedTickingBefore = true; hasStartedTickingBefore = true;
State = TimerState.Ticking; State = TimerState.Ticking;
OnStarted?.Invoke(this); OnStarted?.InvokeSafe(this);
} }
protected override void OnFinalize() protected override void OnFinalize()

View File

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

View File

@ -14,7 +14,7 @@ public class TweenManager : HierarchyObject
public ITween StartTween(float duration, TweenSetCallback? setCallback = null) public ITween StartTween(float duration, TweenSetCallback? setCallback = null)
{ {
Tween tween = new(duration); Tween tween = new(duration);
tween.OnUpdated += tween => setCallback?.Invoke(tween.Value); tween.OnUpdated += tween => setCallback?.InvokeSafe(tween.Value);
runningCoroutines.Add(tween, coroutineManager.StartCoroutine(RunTween(tween))); runningCoroutines.Add(tween, coroutineManager.StartCoroutine(RunTween(tween)));
return tween; return tween;
} }