4 Commits

8 changed files with 116 additions and 2 deletions

View File

@@ -37,11 +37,21 @@ public interface IUniverse : IEntity, IEnumerable<IUniverseObject>
/// </summary>
Event<IUniverse> OnPostDraw { get; }
/// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is about to be registered to the <see cref="IUniverse"/>.
/// </summary>
Event<IUniverse, UniverseObjectRegisteredArguments> OnPreUniverseObjectRegistered { get; }
/// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is registered to the <see cref="IUniverse"/>.
/// </summary>
Event<IUniverse, UniverseObjectRegisteredArguments> OnUniverseObjectRegistered { get; }
/// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is about to be unregistered from the <see cref="IUniverse"/>.
/// </summary>
Event<IUniverse, UniverseObjectUnRegisteredArguments> OnPreUniverseObjectUnRegistered { get; }
/// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is unregistered from the <see cref="IUniverse"/>.
/// </summary>

View File

@@ -76,7 +76,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
OnUniverseObjectRegistered(universe, new(universeObject));
universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered);
universe.OnUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered);
universe.OnPreUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered);
Universe = universe;
OnAssign(universe);
@@ -94,7 +94,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
OnUniverseObjectUnregistered(Universe, new(universeObject));
Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered);
Universe.OnUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered);
Universe.OnPreUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered);
Universe = null!;
OnUnassigned?.Invoke(this);

View File

@@ -0,0 +1,6 @@
namespace Syntriax.Engine.Core;
public interface IEnterUniverse : IBehaviour
{
void EnterUniverse(IUniverse universe);
}

View File

@@ -0,0 +1,6 @@
namespace Syntriax.Engine.Core;
public interface IExitUniverse : IBehaviour
{
void ExitUniverse(IUniverse universe);
}

View File

@@ -0,0 +1,6 @@
namespace Syntriax.Engine.Core;
public interface ILastFrameUpdate : IBehaviour
{
void LastActiveFrame();
}

View File

@@ -0,0 +1,71 @@
using System.Collections.Generic;
namespace Syntriax.Engine.Core;
public class UniverseEntranceManager : Behaviour
{
// We use Ascending order because we are using reverse for loop to call them
private static Comparer<IBehaviour> SortByAscendingPriority() => Comparer<IBehaviour>.Create((x, y) => x.Priority.CompareTo(y.Priority));
private readonly ActiveBehaviourCollectorSorted<IEnterUniverse> enterUniverses = new() { SortBy = SortByAscendingPriority() };
private readonly ActiveBehaviourCollectorSorted<IExitUniverse> exitUniverses = new() { SortBy = SortByAscendingPriority() };
private readonly List<IEnterUniverse> toCallEnterUniverses = new(32);
private readonly List<IExitUniverse> toCallExitUniverses = new(32);
protected override void OnEnteredUniverse(IUniverse universe)
{
enterUniverses.Assign(universe);
foreach (IUniverseObject universeObject in Universe.UniverseObjects)
OnUniverseObjectRegistered(Universe, new(universeObject));
universe.OnUniverseObjectRegistered.AddListener(OnUniverseObjectRegistered);
universe.OnUniverseObjectUnRegistered.AddListener(OnUniverseObjectUnRegistered);
}
protected override void OnExitedUniverse(IUniverse universe)
{
enterUniverses.Unassign();
foreach (IUniverseObject universeObject in Universe.UniverseObjects)
OnUniverseObjectUnRegistered(Universe, new(universeObject));
universe.OnUniverseObjectRegistered.RemoveListener(OnUniverseObjectRegistered);
universe.OnUniverseObjectUnRegistered.RemoveListener(OnUniverseObjectUnRegistered);
}
private void OnUniverseObjectUnRegistered(IUniverse sender, IUniverse.UniverseObjectUnRegisteredArguments args)
{
for (int i = toCallExitUniverses.Count - 1; i >= 0; i--)
{
toCallExitUniverses[i].ExitUniverse(Universe);
toCallExitUniverses.RemoveAt(i);
}
}
private void OnUniverseObjectRegistered(IUniverse sender, IUniverse.UniverseObjectRegisteredArguments args)
{
for (int i = toCallEnterUniverses.Count - 1; i >= 0; i--)
{
toCallEnterUniverses[i].EnterUniverse(Universe);
toCallEnterUniverses.RemoveAt(i);
}
}
private void OnEnterUniverseCollected(IBehaviourCollector<IEnterUniverse> sender, IBehaviourCollector<IEnterUniverse>.BehaviourCollectedArguments args)
{
toCallEnterUniverses.Add(args.BehaviourCollected);
}
private void OnExitUniverseCollected(IBehaviourCollector<IExitUniverse> sender, IBehaviourCollector<IExitUniverse>.BehaviourCollectedArguments args)
{
toCallExitUniverses.Add(args.BehaviourCollected);
}
public UniverseEntranceManager()
{
enterUniverses.OnCollected.AddListener(OnEnterUniverseCollected);
exitUniverses.OnCollected.AddListener(OnExitUniverseCollected);
}
}

View File

@@ -8,6 +8,7 @@ public class UpdateManager : Behaviour
private static Comparer<IBehaviour> SortByAscendingPriority() => Comparer<IBehaviour>.Create((x, y) => x.Priority.CompareTo(y.Priority));
private readonly ActiveBehaviourCollectorSorted<IFirstFrameUpdate> firstFrameUpdates = new() { SortBy = SortByAscendingPriority() };
private readonly ActiveBehaviourCollector<ILastFrameUpdate> lastFrameUpdates = new();
private readonly ActiveBehaviourCollectorSorted<IPreUpdate> preUpdateEntities = new() { SortBy = SortByAscendingPriority() };
private readonly ActiveBehaviourCollectorSorted<IUpdate> updateEntities = new() { SortBy = SortByAscendingPriority() };
private readonly ActiveBehaviourCollectorSorted<IPostUpdate> postUpdateEntities = new() { SortBy = SortByAscendingPriority() };
@@ -17,6 +18,7 @@ public class UpdateManager : Behaviour
protected override void OnEnteredUniverse(IUniverse universe)
{
firstFrameUpdates.Assign(universe);
lastFrameUpdates.Assign(universe);
preUpdateEntities.Assign(universe);
updateEntities.Assign(universe);
postUpdateEntities.Assign(universe);
@@ -29,6 +31,7 @@ public class UpdateManager : Behaviour
protected override void OnExitedUniverse(IUniverse universe)
{
firstFrameUpdates.Unassign();
lastFrameUpdates.Unassign();
preUpdateEntities.Unassign();
updateEntities.Unassign();
postUpdateEntities.Unassign();
@@ -67,8 +70,14 @@ public class UpdateManager : Behaviour
toCallFirstFrameUpdates.Add(args.BehaviourCollected);
}
private void OnLastFrameRemoved(IBehaviourCollector<ILastFrameUpdate> sender, IBehaviourCollector<ILastFrameUpdate>.BehaviourRemovedArguments args)
{
args.BehaviourRemoved.LastActiveFrame();
}
public UpdateManager()
{
firstFrameUpdates.OnCollected.AddListener(OnFirstFrameCollected);
lastFrameUpdates.OnRemoved.AddListener(OnLastFrameRemoved);
}
}

View File

@@ -13,7 +13,9 @@ public class Universe : BaseEntity, IUniverse
public Event<IUniverse> OnPreDraw { get; } = new();
public Event<IUniverse> OnDraw { get; } = new();
public Event<IUniverse> OnPostDraw { get; } = new();
public Event<IUniverse, IUniverse.UniverseObjectRegisteredArguments> OnPreUniverseObjectRegistered { get; } = new();
public Event<IUniverse, IUniverse.UniverseObjectRegisteredArguments> OnUniverseObjectRegistered { get; } = new();
public Event<IUniverse, IUniverse.UniverseObjectUnRegisteredArguments> OnPreUniverseObjectUnRegistered { get; } = new();
public Event<IUniverse, IUniverse.UniverseObjectUnRegisteredArguments> OnUniverseObjectUnRegistered { get; } = new();
public Event<IUniverse, IUniverse.TimeScaleChangedArguments> OnTimeScaleChanged { get; } = new();
@@ -53,6 +55,8 @@ public class Universe : BaseEntity, IUniverse
if (_universeObjects.Contains(universeObject))
throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is already registered to the {nameof(Universe)}.");
OnPreUniverseObjectRegistered?.Invoke(this, new(universeObject));
universeObject.OnFinalized.AddListener(delegateOnUniverseObjectFinalize);
universeObject.OnExitedUniverse.AddListener(delegateOnUniverseObjectExitedUniverse);
@@ -88,6 +92,8 @@ public class Universe : BaseEntity, IUniverse
if (!_universeObjects.Contains(universeObject))
throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is not registered to the {nameof(Universe)}.");
OnPreUniverseObjectUnRegistered?.Invoke(this, new(universeObject));
universeObject.OnFinalized.RemoveListener(delegateOnUniverseObjectFinalize);
universeObject.OnExitedUniverse.RemoveListener(delegateOnUniverseObjectExitedUniverse);