feat: safe delegate invocation helper added

This commit is contained in:
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);
OnBehaviourAdd(behaviour);
OnCollected?.Invoke(this, behaviour);
OnCollected?.InvokeSafe(this, behaviour);
}
else if (activeBehaviours.Remove(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))
{
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 = gameManager;
OnGameManagerAssigned?.Invoke(this);
OnGameManagerAssigned?.InvokeSafe(this);
return true;
}
@@ -118,7 +118,7 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
GameManager.OnHierarchyObjectUnRegistered -= OnHierarchyObjectUnregistered;
GameManager = null!;
OnUnassigned?.Invoke(this);
OnUnassigned?.InvokeSafe(this);
return true;
}

View File

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

View File

@@ -25,7 +25,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
int previousPriority = _priority;
_priority = value;
OnPriorityChanged?.Invoke(this, previousPriority);
OnPriorityChanged?.InvokeSafe(this, previousPriority);
}
}
@@ -43,7 +43,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
behaviourController.OnHierarchyObjectAssigned += OnHierarchyObjectAssigned;
if (behaviourController.HierarchyObject is not null)
OnHierarchyObjectAssigned(behaviourController);
OnBehaviourControllerAssigned?.Invoke(this);
OnBehaviourControllerAssigned?.InvokeSafe(this);
return true;
}
@@ -83,6 +83,6 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
_isActive = StateEnable.Enabled && _behaviourController.HierarchyObject.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);
OnBehaviourAdd(behaviour);
OnCollected?.Invoke(this, tBehaviour);
OnCollected?.InvokeSafe(this, tBehaviour);
}
protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
@@ -63,7 +63,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
return;
OnBehaviourRemove(behaviour);
OnRemoved?.Invoke(this, tBehaviour);
OnRemoved?.InvokeSafe(this, tBehaviour);
}
protected virtual void OnAssign(IGameManager gameManager) { }
@@ -80,7 +80,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
GameManager = gameManager;
OnAssign(gameManager);
OnGameManagerAssigned?.Invoke(this);
OnGameManagerAssigned?.InvokeSafe(this);
return true;
}
@@ -97,7 +97,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
GameManager.OnHierarchyObjectUnRegistered -= OnHierarchyObjectUnregistered;
GameManager = null!;
OnUnassigned?.Invoke(this);
OnUnassigned?.InvokeSafe(this);
return true;
}

View File

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

View File

@@ -49,7 +49,7 @@ public class GameManager : BaseEntity, IGameManager
if (!hierarchyObject.EnterHierarchy(this))
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
@@ -84,7 +84,7 @@ public class GameManager : BaseEntity, IGameManager
if (!hierarchyObject.Finalize())
throw new Exception($"{hierarchyObject.Name} can't be finalized");
OnHierarchyObjectUnRegistered?.Invoke(this, hierarchyObject);
OnHierarchyObjectUnRegistered?.InvokeSafe(this, hierarchyObject);
}
protected override void InitializeInternal()
@@ -107,12 +107,12 @@ public class GameManager : BaseEntity, IGameManager
UnscaledTime = engineTime;
Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale)));
OnPreUpdate?.Invoke(this, Time);
OnPreUpdate?.InvokeSafe(this, Time);
for (int i = 0; i < HierarchyObjects.Count; i++)
HierarchyObjects[i].BehaviourController.Update();
OnUpdate?.Invoke(this, Time);
OnUpdate?.InvokeSafe(this, Time);
}
public void PreDraw()
@@ -122,7 +122,7 @@ public class GameManager : BaseEntity, IGameManager
for (int i = 0; i < HierarchyObjects.Count; i++)
HierarchyObjects[i].BehaviourController.UpdatePreDraw();
OnPreDraw?.Invoke(this);
OnPreDraw?.InvokeSafe(this);
}
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;
_name = value;
OnNameChanged?.Invoke(this, previousName);
OnNameChanged?.InvokeSafe(this, previousName);
}
}
@@ -52,7 +52,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_gameManager = gameManager;
UpdateActive();
OnEnteringHierarchy(gameManager);
OnEnteredHierarchy?.Invoke(this, gameManager);
OnEnteredHierarchy?.InvokeSafe(this, gameManager);
return true;
}
@@ -64,7 +64,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
OnExitingHierarchy(gameManager);
_gameManager = null!;
OnExitedHierarchy?.Invoke(this, gameManager);
OnExitedHierarchy?.InvokeSafe(this, gameManager);
return true;
}
@@ -95,7 +95,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
}
UpdateActive();
OnParentChanged?.Invoke(this, previousParent, parent);
OnParentChanged?.InvokeSafe(this, previousParent, parent);
}
public void AddChild(IHierarchyObject parent)
@@ -105,7 +105,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_children.Add(parent);
parent.SetParent(this);
OnChildrenAdded?.Invoke(this, parent);
OnChildrenAdded?.InvokeSafe(this, parent);
}
public void RemoveChild(IHierarchyObject child)
@@ -114,7 +114,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
return;
child.SetParent(null);
OnChildrenRemoved?.Invoke(this, child);
OnChildrenRemoved?.InvokeSafe(this, child);
}
protected virtual void OnAssign(IBehaviourController behaviourController) { }
@@ -125,7 +125,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_behaviourController = behaviourController;
OnAssign(behaviourController);
OnBehaviourControllerAssigned?.Invoke(this);
OnBehaviourControllerAssigned?.InvokeSafe(this);
return true;
}
@@ -145,7 +145,7 @@ public class HierarchyObject : BaseEntity, IHierarchyObject
_isActive = StateEnable.Enabled && (Parent?.IsActive ?? true);
if (previousActive != IsActive)
OnActiveChanged?.Invoke(this, previousActive);
OnActiveChanged?.InvokeSafe(this, previousActive);
}
protected override void UnassignInternal()

View File

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

View File

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