Compare commits
6 Commits
developmen
...
tests
Author | SHA1 | Date | |
---|---|---|---|
22b3a342a8 | |||
d0aee7fe16 | |||
be15cba9e1 | |||
ac0eac3fbb | |||
3c23ac7f1e | |||
57807c2a62 |
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
|||||||
[submodule "Engine.Integration/YamlDotNet"]
|
[submodule "Engine.Serializers/YamlDotNet"]
|
||||||
path = Engine.Integration/YamlDotNet
|
path = Engine.Serializers/YamlDotNet
|
||||||
url = git@github.com:Syntriax/YamlDotNet.git
|
url = git@github.com:Syntriax/YamlDotNet.git
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates the class implementing it has Assignable fields that are necessary for the engine to work properly.
|
/// Indicates the class implementing it has Assignable fields that are necessary for the engine to work properly.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IBehaviourController"/> field.
|
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IBehaviourController"/> field.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IEntity"/> field.
|
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IEntity"/> field.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IStateEnable"/> field.
|
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IStateEnable"/> field.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverse"/> field.
|
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverse"/> field.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverseObject"/> field.
|
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="IUniverseObject"/> field.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an entity which can be active or not.
|
/// Represents an entity which can be active or not.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a behaviour that any object in the engine that might use to interact with itself or other objects.
|
/// Represents a behaviour that any object in the engine that might use to interact with itself or other objects.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public interface IBehaviour2D : IBehaviour
|
public interface IBehaviour2D : IBehaviour
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a collector for the class type of <typeparamref name="T"/>.
|
/// Represents a collector for the class type of <typeparamref name="T"/>.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a controller for managing <see cref="IBehaviour"/>s. Connected to an <see cref="IUniverseObject"/>.
|
/// Represents a controller for managing <see cref="IBehaviour"/>s. Connected to an <see cref="IUniverseObject"/>.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a 2D camera in the engine.
|
/// Represents a 2D camera in the engine.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public interface ICoroutineYield
|
public interface ICoroutineYield
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a basic entity in the engine.
|
/// Represents a basic entity in the engine.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an entity that can be initialized and finalized. This information is useful for objects we know that are not in use and can be either recycled or dropped for garbage collection.
|
/// Represents an entity that can be initialized and finalized. This information is useful for objects we know that are not in use and can be either recycled or dropped for garbage collection.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an entity with a name.
|
/// Represents an entity with a name.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an entity with an enable state that can be toggled.
|
/// Represents an entity with an enable state that can be toggled.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the transformation properties of an object such as position, scale, and rotation in 2D space.
|
/// Represents the transformation properties of an object such as position, scale, and rotation in 2D space.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a universe responsible for managing <see cref="IUniverseObject"/>s.
|
/// Represents a universe responsible for managing <see cref="IUniverseObject"/>s.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an <see cref="IEntity"/> that can enter and exit a universe within the <see cref="IUniverse"/> system.
|
/// Represents an <see cref="IEntity"/> that can enter and exit a universe within the <see cref="IUniverse"/> system.
|
||||||
|
@@ -1,12 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public abstract class ActiveBehaviourCollectorBase<T> : IBehaviourCollector<T> where T : class, IBehaviour
|
public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : class, IBehaviour
|
||||||
{
|
{
|
||||||
protected readonly Dictionary<IActive, T> monitoringActiveToBehaviour = new(32);
|
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
|
||||||
protected readonly FastList<T> monitoringBehaviours = new(32);
|
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourRemovedArguments> OnRemoved { get; } = new();
|
||||||
|
public Event<IHasUniverse> OnUniverseAssigned { get; } = new();
|
||||||
|
public Event<IAssignable>? OnUnassigned { get; } = new();
|
||||||
|
|
||||||
private readonly Event<IBehaviourController, IBehaviourController.BehaviourAddedArguments>.EventHandler delegateOnBehaviourAdded = null!;
|
private readonly Event<IBehaviourController, IBehaviourController.BehaviourAddedArguments>.EventHandler delegateOnBehaviourAdded = null!;
|
||||||
private readonly Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments>.EventHandler delegateOnBehaviourRemoved = null!;
|
private readonly Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments>.EventHandler delegateOnBehaviourRemoved = null!;
|
||||||
@@ -14,16 +16,80 @@ public abstract class ActiveBehaviourCollectorBase<T> : IBehaviourCollector<T> w
|
|||||||
private readonly Event<IUniverse, IUniverse.UniverseObjectRegisteredArguments>.EventHandler delegateOnUniverseObjectRegistered = null!;
|
private readonly Event<IUniverse, IUniverse.UniverseObjectRegisteredArguments>.EventHandler delegateOnUniverseObjectRegistered = null!;
|
||||||
private readonly Event<IUniverse, IUniverse.UniverseObjectUnRegisteredArguments>.EventHandler delegateOnUniverseObjectUnregistered = null!;
|
private readonly Event<IUniverse, IUniverse.UniverseObjectUnRegisteredArguments>.EventHandler delegateOnUniverseObjectUnregistered = null!;
|
||||||
|
|
||||||
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
|
private readonly List<T> monitoringBehaviours = new(32);
|
||||||
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourRemovedArguments> OnRemoved { get; } = new();
|
protected readonly List<T> activeBehaviours = new(32);
|
||||||
public Event<IHasUniverse> OnUniverseAssigned { get; } = new();
|
protected readonly Dictionary<IActive, T> monitoringActiveToBehaviour = new(32);
|
||||||
public Event<IAssignable>? OnUnassigned { get; } = new();
|
|
||||||
|
|
||||||
public abstract int Count { get; }
|
|
||||||
|
|
||||||
public abstract T this[Index index] { get; }
|
|
||||||
public IUniverse Universe { get; private set; } = null!;
|
public IUniverse Universe { get; private set; } = null!;
|
||||||
|
|
||||||
|
private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args)
|
||||||
|
{
|
||||||
|
IUniverseObject universeObject = args.UniverseObjectRegistered;
|
||||||
|
|
||||||
|
universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded);
|
||||||
|
universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved);
|
||||||
|
|
||||||
|
for (int i = 0; i < universeObject.BehaviourController.Count; i++)
|
||||||
|
OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args)
|
||||||
|
{
|
||||||
|
IUniverseObject universeObject = args.UniverseObjectUnregistered;
|
||||||
|
|
||||||
|
universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded);
|
||||||
|
universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved);
|
||||||
|
|
||||||
|
for (int i = 0; i < universeObject.BehaviourController.Count; i++)
|
||||||
|
OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
|
||||||
|
private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args)
|
||||||
|
{
|
||||||
|
if (args.BehaviourAdded is not T tBehaviour)
|
||||||
|
return;
|
||||||
|
|
||||||
|
monitoringBehaviours.Add(tBehaviour);
|
||||||
|
monitoringActiveToBehaviour.Add(tBehaviour, tBehaviour);
|
||||||
|
tBehaviour.OnActiveChanged.AddListener(delegateOnBehaviourStateChanged);
|
||||||
|
OnBehaviourStateChanged(tBehaviour, new(!tBehaviour.IsActive));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void AddBehaviour(T behaviour) => activeBehaviours.Add(behaviour);
|
||||||
|
private void OnBehaviourStateChanged(IActive sender, IActive.ActiveChangedArguments args)
|
||||||
|
{
|
||||||
|
T behaviour = monitoringActiveToBehaviour[sender];
|
||||||
|
if (sender.IsActive)
|
||||||
|
{
|
||||||
|
AddBehaviour(behaviour);
|
||||||
|
OnBehaviourAdd(behaviour);
|
||||||
|
OnCollected?.Invoke(this, new(behaviour));
|
||||||
|
}
|
||||||
|
else if (activeBehaviours.Remove(behaviour))
|
||||||
|
{
|
||||||
|
OnBehaviourRemove(behaviour);
|
||||||
|
OnRemoved?.Invoke(this, new(behaviour));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
|
||||||
|
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args)
|
||||||
|
{
|
||||||
|
if (args.BehaviourRemoved is not T tBehaviour)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!monitoringBehaviours.Remove(tBehaviour) || !monitoringActiveToBehaviour.Remove(tBehaviour))
|
||||||
|
return;
|
||||||
|
|
||||||
|
tBehaviour.OnActiveChanged.RemoveListener(delegateOnBehaviourStateChanged);
|
||||||
|
if (activeBehaviours.Remove(tBehaviour))
|
||||||
|
{
|
||||||
|
OnBehaviourRemove(tBehaviour);
|
||||||
|
OnRemoved?.Invoke(this, new(tBehaviour));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool Assign(IUniverse universe)
|
public bool Assign(IUniverse universe)
|
||||||
{
|
{
|
||||||
if (Universe is not null)
|
if (Universe is not null)
|
||||||
@@ -57,75 +123,10 @@ public abstract class ActiveBehaviourCollectorBase<T> : IBehaviourCollector<T> w
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void AddBehaviour(T behaviour);
|
public int Count => activeBehaviours.Count;
|
||||||
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
|
public T this[Index index] => activeBehaviours[index];
|
||||||
private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args)
|
|
||||||
{
|
|
||||||
if (args.BehaviourAdded is not T tBehaviour)
|
|
||||||
return;
|
|
||||||
|
|
||||||
monitoringBehaviours.Add(tBehaviour);
|
public ActiveBehaviourCollector()
|
||||||
monitoringActiveToBehaviour.Add(tBehaviour, tBehaviour);
|
|
||||||
tBehaviour.OnActiveChanged.AddListener(delegateOnBehaviourStateChanged);
|
|
||||||
OnBehaviourStateChanged(tBehaviour, new(!tBehaviour.IsActive));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract bool RemoveBehaviour(T behaviour);
|
|
||||||
protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
|
|
||||||
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args)
|
|
||||||
{
|
|
||||||
if (args.BehaviourRemoved is not T tBehaviour)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!monitoringBehaviours.Remove(tBehaviour) || !monitoringActiveToBehaviour.Remove(tBehaviour))
|
|
||||||
return;
|
|
||||||
|
|
||||||
tBehaviour.OnActiveChanged.RemoveListener(delegateOnBehaviourStateChanged);
|
|
||||||
if (!RemoveBehaviour(tBehaviour))
|
|
||||||
return;
|
|
||||||
|
|
||||||
OnBehaviourRemove(tBehaviour);
|
|
||||||
OnRemoved?.Invoke(this, new(tBehaviour));
|
|
||||||
}
|
|
||||||
private void OnBehaviourStateChanged(IActive sender, IActive.ActiveChangedArguments args)
|
|
||||||
{
|
|
||||||
T behaviour = monitoringActiveToBehaviour[sender];
|
|
||||||
if (sender.IsActive)
|
|
||||||
{
|
|
||||||
AddBehaviour(behaviour);
|
|
||||||
OnBehaviourAdd(behaviour);
|
|
||||||
OnCollected?.Invoke(this, new(behaviour));
|
|
||||||
}
|
|
||||||
else if (RemoveBehaviour(behaviour))
|
|
||||||
{
|
|
||||||
OnBehaviourRemove(behaviour);
|
|
||||||
OnRemoved?.Invoke(this, new(behaviour));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args)
|
|
||||||
{
|
|
||||||
IUniverseObject universeObject = args.UniverseObjectRegistered;
|
|
||||||
|
|
||||||
universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded);
|
|
||||||
universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved);
|
|
||||||
|
|
||||||
for (int i = 0; i < universeObject.BehaviourController.Count; i++)
|
|
||||||
OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args)
|
|
||||||
{
|
|
||||||
IUniverseObject universeObject = args.UniverseObjectUnregistered;
|
|
||||||
|
|
||||||
universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded);
|
|
||||||
universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved);
|
|
||||||
|
|
||||||
for (int i = 0; i < universeObject.BehaviourController.Count; i++)
|
|
||||||
OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActiveBehaviourCollectorBase()
|
|
||||||
{
|
{
|
||||||
delegateOnBehaviourAdded = OnBehaviourAdded;
|
delegateOnBehaviourAdded = OnBehaviourAdded;
|
||||||
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
||||||
@@ -134,7 +135,7 @@ public abstract class ActiveBehaviourCollectorBase<T> : IBehaviourCollector<T> w
|
|||||||
delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
|
delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActiveBehaviourCollectorBase(IUniverse universe)
|
public ActiveBehaviourCollector(IUniverse universe)
|
||||||
{
|
{
|
||||||
delegateOnBehaviourAdded = OnBehaviourAdded;
|
delegateOnBehaviourAdded = OnBehaviourAdded;
|
||||||
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
67
Engine.Core/ActiveBehaviourCollectorSorted.cs
Normal file
67
Engine.Core/ActiveBehaviourCollectorSorted.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
public class ActiveBehaviourCollectorSorted<T> : ActiveBehaviourCollector<T> where T : class, IBehaviour
|
||||||
|
{
|
||||||
|
private readonly Event<IBehaviour, IBehaviour.PriorityChangedArguments>.EventHandler delegateOnPriorityChanged = null!;
|
||||||
|
|
||||||
|
private IComparer<T>? _sortBy = null;
|
||||||
|
public IComparer<T>? SortBy
|
||||||
|
{
|
||||||
|
get => _sortBy;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_sortBy = value;
|
||||||
|
|
||||||
|
if (value is not null)
|
||||||
|
activeBehaviours.Sort(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AddBehaviour(T behaviour)
|
||||||
|
{
|
||||||
|
if (SortBy is null)
|
||||||
|
{
|
||||||
|
activeBehaviours.Add(behaviour);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int insertionIndex = activeBehaviours.BinarySearch(behaviour, SortBy);
|
||||||
|
|
||||||
|
if (insertionIndex < 0)
|
||||||
|
insertionIndex = ~insertionIndex;
|
||||||
|
|
||||||
|
activeBehaviours.Insert(insertionIndex, behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnBehaviourAdd(IBehaviour behaviour)
|
||||||
|
{
|
||||||
|
behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnBehaviourRemove(IBehaviour behaviour)
|
||||||
|
{
|
||||||
|
behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args)
|
||||||
|
{
|
||||||
|
T behaviour = (T)sender;
|
||||||
|
activeBehaviours.Remove(behaviour);
|
||||||
|
AddBehaviour(behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActiveBehaviourCollectorSorted()
|
||||||
|
{
|
||||||
|
delegateOnPriorityChanged = OnPriorityChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActiveBehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe)
|
||||||
|
{
|
||||||
|
delegateOnPriorityChanged = OnPriorityChanged;
|
||||||
|
|
||||||
|
SortBy = Comparer<T>.Create(sortBy);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public abstract class BaseEntity : IEntity
|
public abstract class BaseEntity : IEntity
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public abstract class Behaviour : BehaviourBase
|
public abstract class Behaviour : BehaviourBase
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public abstract class Behaviour2D : Behaviour, IBehaviour2D
|
public abstract class Behaviour2D : Behaviour, IBehaviour2D
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace 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 BehaviourBase : BaseEntity, IBehaviour
|
public abstract class BehaviourBase : BaseEntity, IBehaviour
|
||||||
|
@@ -1,25 +1,72 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public abstract class BehaviourCollectorBase<T> : IBehaviourCollector<T> where T : class
|
public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
|
||||||
{
|
{
|
||||||
private readonly Event<IBehaviourController, IBehaviourController.BehaviourAddedArguments>.EventHandler delegateOnBehaviourAdded = null!;
|
|
||||||
private readonly Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments>.EventHandler delegateOnBehaviourRemoved = null!;
|
|
||||||
private readonly Event<IUniverse, IUniverse.UniverseObjectRegisteredArguments>.EventHandler delegateOnUniverseObjectRegistered = null!;
|
|
||||||
private readonly Event<IUniverse, IUniverse.UniverseObjectUnRegisteredArguments>.EventHandler delegateOnUniverseObjectUnregistered = null!;
|
|
||||||
|
|
||||||
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
|
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
|
||||||
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourRemovedArguments> OnRemoved { get; } = new();
|
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourRemovedArguments> OnRemoved { get; } = new();
|
||||||
public Event<IHasUniverse> OnUniverseAssigned { get; } = new();
|
public Event<IHasUniverse> OnUniverseAssigned { get; } = new();
|
||||||
public Event<IAssignable>? OnUnassigned { get; } = new();
|
public Event<IAssignable>? OnUnassigned { get; } = new();
|
||||||
|
|
||||||
|
private readonly Event<IBehaviourController, IBehaviourController.BehaviourAddedArguments>.EventHandler delegateOnBehaviourAdded = null!;
|
||||||
|
private readonly Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments>.EventHandler delegateOnBehaviourRemoved = null!;
|
||||||
|
private readonly Event<IUniverse, IUniverse.UniverseObjectRegisteredArguments>.EventHandler delegateOnUniverseObjectRegistered = null!;
|
||||||
|
private readonly Event<IUniverse, IUniverse.UniverseObjectUnRegisteredArguments>.EventHandler delegateOnUniverseObjectUnregistered = null!;
|
||||||
|
|
||||||
|
protected readonly List<T> behaviours = new(32);
|
||||||
|
|
||||||
public IUniverse Universe { get; private set; } = null!;
|
public IUniverse Universe { get; private set; } = null!;
|
||||||
|
|
||||||
public abstract int Count { get; }
|
private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args)
|
||||||
|
{
|
||||||
|
IUniverseObject universeObject = args.UniverseObjectRegistered;
|
||||||
|
|
||||||
public abstract T this[Index index] { get; }
|
universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded);
|
||||||
|
universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved);
|
||||||
|
|
||||||
|
for (int i = 0; i < universeObject.BehaviourController.Count; i++)
|
||||||
|
OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args)
|
||||||
|
{
|
||||||
|
IUniverseObject universeObject = args.UniverseObjectUnregistered;
|
||||||
|
|
||||||
|
universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded);
|
||||||
|
universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved);
|
||||||
|
|
||||||
|
for (int i = 0; i < universeObject.BehaviourController.Count; i++)
|
||||||
|
OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void AddBehaviour(T behaviour) => behaviours.Add(behaviour);
|
||||||
|
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
|
||||||
|
private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args)
|
||||||
|
{
|
||||||
|
if (args.BehaviourAdded is not T tBehaviour)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AddBehaviour(tBehaviour);
|
||||||
|
OnBehaviourAdd(args.BehaviourAdded);
|
||||||
|
OnCollected?.Invoke(this, new(tBehaviour));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
|
||||||
|
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args)
|
||||||
|
{
|
||||||
|
if (args.BehaviourRemoved is not T tBehaviour)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!behaviours.Remove(tBehaviour))
|
||||||
|
return;
|
||||||
|
|
||||||
|
OnBehaviourRemove(args.BehaviourRemoved);
|
||||||
|
OnRemoved?.Invoke(this, new(tBehaviour));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnAssign(IUniverse universe) { }
|
||||||
public bool Assign(IUniverse universe)
|
public bool Assign(IUniverse universe)
|
||||||
{
|
{
|
||||||
if (Universe is not null)
|
if (Universe is not null)
|
||||||
@@ -54,57 +101,10 @@ public abstract class BehaviourCollectorBase<T> : IBehaviourCollector<T> where T
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnAssign(IUniverse universe) { }
|
public int Count => behaviours.Count;
|
||||||
|
public T this[Index index] => behaviours[index];
|
||||||
|
|
||||||
protected abstract void AddBehaviour(T behaviour);
|
public BehaviourCollector()
|
||||||
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
|
|
||||||
private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args)
|
|
||||||
{
|
|
||||||
if (args.BehaviourAdded is not T tBehaviour)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AddBehaviour(tBehaviour);
|
|
||||||
OnBehaviourAdd(args.BehaviourAdded);
|
|
||||||
OnCollected?.Invoke(this, new(tBehaviour));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract bool RemoveBehaviour(T tBehaviour);
|
|
||||||
protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
|
|
||||||
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args)
|
|
||||||
{
|
|
||||||
if (args.BehaviourRemoved is not T tBehaviour)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!RemoveBehaviour(tBehaviour))
|
|
||||||
return;
|
|
||||||
|
|
||||||
OnBehaviourRemove(args.BehaviourRemoved);
|
|
||||||
OnRemoved?.Invoke(this, new(tBehaviour));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args)
|
|
||||||
{
|
|
||||||
IUniverseObject universeObject = args.UniverseObjectRegistered;
|
|
||||||
|
|
||||||
universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded);
|
|
||||||
universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved);
|
|
||||||
|
|
||||||
for (int i = 0; i < universeObject.BehaviourController.Count; i++)
|
|
||||||
OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args)
|
|
||||||
{
|
|
||||||
IUniverseObject universeObject = args.UniverseObjectUnregistered;
|
|
||||||
|
|
||||||
universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded);
|
|
||||||
universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved);
|
|
||||||
|
|
||||||
for (int i = 0; i < universeObject.BehaviourController.Count; i++)
|
|
||||||
OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
public BehaviourCollectorBase()
|
|
||||||
{
|
{
|
||||||
delegateOnBehaviourAdded = OnBehaviourAdded;
|
delegateOnBehaviourAdded = OnBehaviourAdded;
|
||||||
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
||||||
@@ -112,7 +112,7 @@ public abstract class BehaviourCollectorBase<T> : IBehaviourCollector<T> where T
|
|||||||
delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
|
delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BehaviourCollectorBase(IUniverse universe)
|
public BehaviourCollector(IUniverse universe)
|
||||||
{
|
{
|
||||||
delegateOnBehaviourAdded = OnBehaviourAdded;
|
delegateOnBehaviourAdded = OnBehaviourAdded;
|
||||||
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
67
Engine.Core/BehaviourCollectorSorted.cs
Normal file
67
Engine.Core/BehaviourCollectorSorted.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class
|
||||||
|
{
|
||||||
|
private readonly Event<IBehaviour, IBehaviour.PriorityChangedArguments>.EventHandler delegateOnPriorityChanged = null!;
|
||||||
|
|
||||||
|
private IComparer<T>? _sortBy = null;
|
||||||
|
public IComparer<T>? SortBy
|
||||||
|
{
|
||||||
|
get => _sortBy;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_sortBy = value;
|
||||||
|
|
||||||
|
if (value is not null)
|
||||||
|
behaviours.Sort(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AddBehaviour(T behaviour)
|
||||||
|
{
|
||||||
|
if (SortBy is null)
|
||||||
|
{
|
||||||
|
behaviours.Add(behaviour);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int insertionIndex = behaviours.BinarySearch(behaviour, SortBy);
|
||||||
|
|
||||||
|
if (insertionIndex < 0)
|
||||||
|
insertionIndex = ~insertionIndex;
|
||||||
|
|
||||||
|
behaviours.Insert(insertionIndex, behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnBehaviourAdd(IBehaviour behaviour)
|
||||||
|
{
|
||||||
|
behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnBehaviourRemove(IBehaviour behaviour)
|
||||||
|
{
|
||||||
|
behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args)
|
||||||
|
{
|
||||||
|
T behaviour = (T)sender;
|
||||||
|
behaviours.Remove(behaviour);
|
||||||
|
AddBehaviour(behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BehaviourCollectorSorted()
|
||||||
|
{
|
||||||
|
delegateOnPriorityChanged = OnPriorityChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe)
|
||||||
|
{
|
||||||
|
delegateOnPriorityChanged = OnPriorityChanged;
|
||||||
|
|
||||||
|
SortBy = Comparer<T>.Create(sortBy);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")]
|
[System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")]
|
||||||
public class BehaviourController : BaseEntity, IBehaviourController
|
public class BehaviourController : BaseEntity, IBehaviourController
|
||||||
@@ -10,7 +10,7 @@ public class BehaviourController : BaseEntity, IBehaviourController
|
|||||||
public Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments> OnBehaviourRemoved { get; } = new();
|
public Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments> OnBehaviourRemoved { get; } = new();
|
||||||
public Event<IHasUniverseObject> OnUniverseObjectAssigned { get; } = new();
|
public Event<IHasUniverseObject> OnUniverseObjectAssigned { get; } = new();
|
||||||
|
|
||||||
private readonly FastList<IBehaviour> behaviours = new(Constants.BEHAVIOURS_SIZE_INITIAL);
|
private readonly List<IBehaviour> behaviours = new(Constants.BEHAVIOURS_SIZE_INITIAL);
|
||||||
|
|
||||||
private IUniverseObject _universeObject = null!;
|
private IUniverseObject _universeObject = null!;
|
||||||
|
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Engine.Core;
|
|
||||||
|
|
||||||
public class ActiveBehaviourCollector<T> : ActiveBehaviourCollectorBase<T> where T : class, IBehaviour
|
|
||||||
{
|
|
||||||
protected readonly FastList<T> activeBehaviours = new(32);
|
|
||||||
public override T this[Index index] => activeBehaviours[index];
|
|
||||||
public override int Count => activeBehaviours.Count;
|
|
||||||
|
|
||||||
public ActiveBehaviourCollector() { }
|
|
||||||
public ActiveBehaviourCollector(IUniverse universe) : base(universe) { }
|
|
||||||
|
|
||||||
protected override void AddBehaviour(T behaviour) => activeBehaviours.Add(behaviour);
|
|
||||||
protected override bool RemoveBehaviour(T tBehaviour) => activeBehaviours.Remove(tBehaviour);
|
|
||||||
}
|
|
@@ -1,104 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Engine.Core;
|
|
||||||
|
|
||||||
public class ActiveBehaviourCollectorOrdered<TIndex, TItem> : ActiveBehaviourCollector<TItem> where TItem : class, IBehaviour where TIndex : IComparable
|
|
||||||
{
|
|
||||||
private readonly Event<IBehaviour, IBehaviour.PriorityChangedArguments>.EventHandler delegateOnPriorityChanged = null!;
|
|
||||||
|
|
||||||
private readonly SortedDictionary<TIndex, FastList<TItem>> behaviours = null!;
|
|
||||||
|
|
||||||
private readonly Func<TItem, TIndex> getIndexFunc = null!;
|
|
||||||
private readonly IComparer<TIndex> sortBy = null!;
|
|
||||||
|
|
||||||
private int count = 0;
|
|
||||||
public override int Count => count;
|
|
||||||
|
|
||||||
public override TItem this[Index index]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
int actualIndex = index.IsFromEnd
|
|
||||||
? count - index.Value
|
|
||||||
: index.Value;
|
|
||||||
|
|
||||||
if (actualIndex < 0 || actualIndex >= count)
|
|
||||||
throw new IndexOutOfRangeException();
|
|
||||||
|
|
||||||
int leftIndex = actualIndex;
|
|
||||||
foreach ((TIndex i, FastList<TItem> list) in behaviours)
|
|
||||||
{
|
|
||||||
if (leftIndex < list.Count)
|
|
||||||
return list[leftIndex];
|
|
||||||
leftIndex -= list.Count;
|
|
||||||
}
|
|
||||||
throw new IndexOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool RemoveBehaviour(TItem tBehaviour)
|
|
||||||
{
|
|
||||||
TIndex index = getIndexFunc(tBehaviour);
|
|
||||||
if (!behaviours.TryGetValue(index, out FastList<TItem>? list))
|
|
||||||
throw new Exceptions.NotFoundException($"Index of '{index}' is not found in the collector");
|
|
||||||
|
|
||||||
if (!list.Remove(tBehaviour))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
count--;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void AddBehaviour(TItem behaviour)
|
|
||||||
{
|
|
||||||
TIndex key = getIndexFunc(behaviour);
|
|
||||||
if (!behaviours.TryGetValue(key, out FastList<TItem>? list))
|
|
||||||
behaviours[key] = list = [];
|
|
||||||
|
|
||||||
count++;
|
|
||||||
list.Add(behaviour);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnBehaviourAdd(IBehaviour behaviour) => behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged);
|
|
||||||
protected override void OnBehaviourRemove(IBehaviour behaviour) => behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged);
|
|
||||||
|
|
||||||
private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args)
|
|
||||||
{
|
|
||||||
TItem behaviour = (TItem)sender;
|
|
||||||
RemoveBehaviour(behaviour);
|
|
||||||
AddBehaviour(behaviour);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActiveBehaviourCollectorOrdered(Func<TItem, TIndex> getIndexFunc, Comparison<TIndex> sortBy)
|
|
||||||
{
|
|
||||||
delegateOnPriorityChanged = OnPriorityChanged;
|
|
||||||
this.getIndexFunc = getIndexFunc;
|
|
||||||
this.sortBy = Comparer<TIndex>.Create(sortBy);
|
|
||||||
behaviours = new(this.sortBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActiveBehaviourCollectorOrdered(IUniverse universe, Func<TItem, TIndex> getIndexFunc, Comparison<TIndex> sortBy) : base(universe)
|
|
||||||
{
|
|
||||||
delegateOnPriorityChanged = OnPriorityChanged;
|
|
||||||
this.getIndexFunc = getIndexFunc;
|
|
||||||
this.sortBy = Comparer<TIndex>.Create(sortBy);
|
|
||||||
behaviours = new(this.sortBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActiveBehaviourCollectorOrdered(Func<TItem, TIndex> getIndexFunc, IComparer<TIndex> sortBy)
|
|
||||||
{
|
|
||||||
this.getIndexFunc = getIndexFunc;
|
|
||||||
delegateOnPriorityChanged = OnPriorityChanged;
|
|
||||||
this.sortBy = sortBy;
|
|
||||||
behaviours = new(sortBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActiveBehaviourCollectorOrdered(IUniverse universe, Func<TItem, TIndex> getIndexFunc, IComparer<TIndex> sortBy) : base(universe)
|
|
||||||
{
|
|
||||||
delegateOnPriorityChanged = OnPriorityChanged;
|
|
||||||
this.getIndexFunc = getIndexFunc;
|
|
||||||
this.sortBy = sortBy;
|
|
||||||
behaviours = new(sortBy);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Engine.Core;
|
|
||||||
|
|
||||||
public class BehaviourCollector<T> : BehaviourCollectorBase<T> where T : class
|
|
||||||
{
|
|
||||||
protected readonly FastList<T> behaviours = new(32);
|
|
||||||
|
|
||||||
public override T this[Index index] => behaviours[index];
|
|
||||||
public override int Count => behaviours.Count;
|
|
||||||
|
|
||||||
protected override void AddBehaviour(T behaviour) => behaviours.Add(behaviour);
|
|
||||||
protected override bool RemoveBehaviour(T tBehaviour) => behaviours.Remove(tBehaviour);
|
|
||||||
|
|
||||||
public BehaviourCollector() { }
|
|
||||||
public BehaviourCollector(IUniverse universe) : base(universe) { }
|
|
||||||
}
|
|
@@ -1,104 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Engine.Core;
|
|
||||||
|
|
||||||
public class BehaviourCollectorOrdered<TIndex, TItem> : BehaviourCollectorBase<TItem> where TItem : class where TIndex : IComparable
|
|
||||||
{
|
|
||||||
private readonly Event<IBehaviour, IBehaviour.PriorityChangedArguments>.EventHandler delegateOnPriorityChanged = null!;
|
|
||||||
|
|
||||||
private readonly SortedDictionary<TIndex, FastList<TItem>> behaviours = null!;
|
|
||||||
|
|
||||||
private readonly Func<TItem, TIndex> getIndexFunc = null!;
|
|
||||||
private readonly IComparer<TIndex> sortBy = null!;
|
|
||||||
|
|
||||||
private int count = 0;
|
|
||||||
public override int Count => count;
|
|
||||||
|
|
||||||
public override TItem this[Index index]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
int actualIndex = index.IsFromEnd
|
|
||||||
? count - index.Value
|
|
||||||
: index.Value;
|
|
||||||
|
|
||||||
if (actualIndex < 0 || actualIndex >= count)
|
|
||||||
throw new IndexOutOfRangeException();
|
|
||||||
|
|
||||||
int leftIndex = actualIndex;
|
|
||||||
foreach ((TIndex i, FastList<TItem> list) in behaviours)
|
|
||||||
{
|
|
||||||
if (leftIndex < list.Count)
|
|
||||||
return list[leftIndex];
|
|
||||||
leftIndex -= list.Count;
|
|
||||||
}
|
|
||||||
throw new IndexOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool RemoveBehaviour(TItem tBehaviour)
|
|
||||||
{
|
|
||||||
TIndex index = getIndexFunc(tBehaviour);
|
|
||||||
if (!behaviours.TryGetValue(index, out FastList<TItem>? list))
|
|
||||||
throw new Exceptions.NotFoundException($"Index of '{index}' is not found in the collector");
|
|
||||||
|
|
||||||
if (!list.Remove(tBehaviour))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
count--;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void AddBehaviour(TItem behaviour)
|
|
||||||
{
|
|
||||||
TIndex key = getIndexFunc(behaviour);
|
|
||||||
if (!behaviours.TryGetValue(key, out FastList<TItem>? list))
|
|
||||||
behaviours[key] = list = [];
|
|
||||||
|
|
||||||
count++;
|
|
||||||
list.Add(behaviour);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnBehaviourAdd(IBehaviour behaviour) => behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged);
|
|
||||||
protected override void OnBehaviourRemove(IBehaviour behaviour) => behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged);
|
|
||||||
|
|
||||||
private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args)
|
|
||||||
{
|
|
||||||
TItem behaviour = (TItem)sender;
|
|
||||||
RemoveBehaviour(behaviour);
|
|
||||||
AddBehaviour(behaviour);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BehaviourCollectorOrdered(Func<TItem, TIndex> getIndexFunc, Comparison<TIndex> sortBy)
|
|
||||||
{
|
|
||||||
delegateOnPriorityChanged = OnPriorityChanged;
|
|
||||||
this.getIndexFunc = getIndexFunc;
|
|
||||||
this.sortBy = Comparer<TIndex>.Create(sortBy);
|
|
||||||
behaviours = new(this.sortBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BehaviourCollectorOrdered(IUniverse universe, Func<TItem, TIndex> getIndexFunc, Comparison<TIndex> sortBy) : base(universe)
|
|
||||||
{
|
|
||||||
delegateOnPriorityChanged = OnPriorityChanged;
|
|
||||||
this.getIndexFunc = getIndexFunc;
|
|
||||||
this.sortBy = Comparer<TIndex>.Create(sortBy);
|
|
||||||
behaviours = new(this.sortBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BehaviourCollectorOrdered(Func<TItem, TIndex> getIndexFunc, IComparer<TIndex> sortBy)
|
|
||||||
{
|
|
||||||
this.getIndexFunc = getIndexFunc;
|
|
||||||
delegateOnPriorityChanged = OnPriorityChanged;
|
|
||||||
this.sortBy = sortBy;
|
|
||||||
behaviours = new(sortBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BehaviourCollectorOrdered(IUniverse universe, Func<TItem, TIndex> getIndexFunc, IComparer<TIndex> sortBy) : base(universe)
|
|
||||||
{
|
|
||||||
delegateOnPriorityChanged = OnPriorityChanged;
|
|
||||||
this.getIndexFunc = getIndexFunc;
|
|
||||||
this.sortBy = sortBy;
|
|
||||||
behaviours = new(sortBy);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,7 +1,7 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class CoroutineManager : Behaviour, IUpdate
|
public class CoroutineManager : Behaviour, IUpdate
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class CoroutineYield(Func<bool> condition) : ICoroutineYield
|
public class CoroutineYield(Func<bool> condition) : ICoroutineYield
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public static class Assert
|
public static class Assert
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public class ConsoleLogger : LoggerBase
|
public class ConsoleLogger : LoggerBase
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public class FileLogger : LoggerBase
|
public class FileLogger : LoggerBase
|
||||||
{
|
{
|
||||||
@@ -14,9 +14,6 @@ public class FileLogger : LoggerBase
|
|||||||
|
|
||||||
public FileLogger(string filePath)
|
public FileLogger(string filePath)
|
||||||
{
|
{
|
||||||
if (!filePath.EndsWith(".log"))
|
|
||||||
filePath += ".log";
|
|
||||||
|
|
||||||
FilePath = filePath;
|
FilePath = filePath;
|
||||||
|
|
||||||
bool isRelativePath = Path.GetFullPath(filePath).CompareTo(filePath) != 0;
|
bool isRelativePath = Path.GetFullPath(filePath).CompareTo(filePath) != 0;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public interface ILogger
|
public interface ILogger
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public abstract class LoggerBase : ILogger
|
public abstract class LoggerBase : ILogger
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public class LoggerContainer : Behaviour, ILogger
|
public class LoggerContainer : Behaviour, ILogger
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public static class LoggerExtensions
|
public static class LoggerExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public class LoggerWrapper(ILogger firstLogger, ILogger secondLogger) : ILogger
|
public class LoggerWrapper(ILogger firstLogger, ILogger secondLogger) : ILogger
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core.Debug;
|
namespace Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
public static class LoggerWrapperExtensions
|
public static class LoggerWrapperExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,71 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Engine.Core.Debug;
|
|
||||||
|
|
||||||
public class RotatingFileLogger : ILogger
|
|
||||||
{
|
|
||||||
public readonly FileLogger FileLogger = null!;
|
|
||||||
public readonly string Directory = string.Empty;
|
|
||||||
public readonly int RotateLength = 3;
|
|
||||||
|
|
||||||
public RotatingFileLogger(string directory, string namePrefix, string nameSuffix = "", int rotateLength = 3)
|
|
||||||
{
|
|
||||||
RotateLength = rotateLength;
|
|
||||||
|
|
||||||
string fileName = Path.Combine(directory, namePrefix);
|
|
||||||
if (!string.IsNullOrWhiteSpace(nameSuffix))
|
|
||||||
fileName += $"_{nameSuffix}";
|
|
||||||
|
|
||||||
bool isRelativePath = Path.GetFullPath(fileName).CompareTo(fileName) != 0;
|
|
||||||
|
|
||||||
if (isRelativePath)
|
|
||||||
fileName = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName));
|
|
||||||
|
|
||||||
if (File.Exists($"{fileName}.log"))
|
|
||||||
RenameExistingLogs(fileName, RotateLength);
|
|
||||||
|
|
||||||
FileLogger = new(fileName);
|
|
||||||
|
|
||||||
Directory = Path.GetDirectoryName(fileName) ?? throw new("Unexpected error on getting directory of logger path");
|
|
||||||
RotateLastLogs(Directory, namePrefix, RotateLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RenameExistingLogs(string filePath, int rotateLength)
|
|
||||||
{
|
|
||||||
for (int i = rotateLength - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
string source = i == 0
|
|
||||||
? $"{filePath}.log"
|
|
||||||
: $"{filePath}_{i}.log";
|
|
||||||
|
|
||||||
string dest = $"{filePath}_{i + 1}.log";
|
|
||||||
|
|
||||||
if (!File.Exists(source))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (File.Exists(dest))
|
|
||||||
File.Delete(dest);
|
|
||||||
|
|
||||||
File.Move(source, dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RotateLastLogs(string directory, string prefix, int rotateLength)
|
|
||||||
{
|
|
||||||
IOrderedEnumerable<string> logs = System.IO.Directory.GetFiles(directory, $"{prefix}*.log")
|
|
||||||
.OrderBy(File.GetCreationTime);
|
|
||||||
|
|
||||||
foreach (string file in logs.Skip(rotateLength))
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ILogger.Shared.Log($"Removing log file located at \"{file}\" during rotation.");
|
|
||||||
File.Delete(file);
|
|
||||||
}
|
|
||||||
catch (Exception e) { ILogger.Shared.LogException($"Failed to rotate log file at \"{file}\"", e); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public ILogger.Level FilterLevel { get => FileLogger.FilterLevel; set => FileLogger.FilterLevel = value; }
|
|
||||||
public void Log(string message, ILogger.Level level = ILogger.Level.Info, bool force = false) => FileLogger.Log(message, level, force);
|
|
||||||
}
|
|
@@ -4,8 +4,7 @@
|
|||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<ImplicitUsings>false</ImplicitUsings>
|
<ImplicitUsings>false</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<RootNamespace>Engine.Core</RootNamespace>
|
<RootNamespace>Syntriax.Engine.Core</RootNamespace>
|
||||||
<AssemblyName>Engine.Core</AssemblyName>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Exceptions;
|
namespace Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
public class AssignFailedException(string? message) : Exception(message)
|
public class AssignFailedException(string? message) : Exception(message)
|
||||||
{
|
{
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
namespace Engine.Core.Exceptions;
|
namespace Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
public class BehaviourNotFoundException(string? message) : NotFoundException(message);
|
public class BehaviourNotFoundException(string? message) : NotFoundException(message);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Exceptions;
|
namespace Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
public class NotAssignedException(string? message) : Exception(message)
|
public class NotAssignedException(string? message) : Exception(message)
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Exceptions;
|
namespace Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
public class NotFoundException(string? message) : Exception(message)
|
public class NotFoundException(string? message) : Exception(message)
|
||||||
{
|
{
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
namespace Engine.Core.Exceptions;
|
namespace Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
public class UniverseObjectNotFoundException(string? message) : NotFoundException(message);
|
public class UniverseObjectNotFoundException(string? message) : NotFoundException(message);
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
using Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class BehaviourControllerExtensions
|
public static class BehaviourControllerExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class EnumExtensions
|
public static class EnumExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class FloatExtensions
|
public static class FloatExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class TransformExtensions
|
public static class TransformExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class UniverseExtensions
|
public static class UniverseExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
using Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class UniverseObjectExtensions
|
public static class UniverseObjectExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core.Factory.Abstract;
|
namespace Syntriax.Engine.Core.Factory.Abstract;
|
||||||
|
|
||||||
public interface IFactory<TInterface> where TInterface : class
|
public interface IFactory<TInterface> where TInterface : class
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Engine.Core.Factory;
|
namespace Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
public class BehaviourControllerFactory
|
public class BehaviourControllerFactory
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Engine.Core.Factory;
|
namespace Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
public class BehaviourFactory
|
public class BehaviourFactory
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Engine.Core.Factory.Abstract;
|
using Syntriax.Engine.Core.Factory.Abstract;
|
||||||
|
|
||||||
namespace Engine.Core.Factory;
|
namespace Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
public abstract class FactoryBase<TInterface> : IFactory<TInterface>
|
public abstract class FactoryBase<TInterface> : IFactory<TInterface>
|
||||||
where TInterface : class
|
where TInterface : class
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Engine.Core.Factory;
|
namespace Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
public class StateEnableFactory
|
public class StateEnableFactory
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core.Factory;
|
namespace Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
public class TransformFactory
|
public class TransformFactory
|
||||||
{
|
{
|
||||||
|
@@ -3,7 +3,7 @@ using System.Collections.Concurrent;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Engine.Core.Factory;
|
namespace Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
public static class TypeFactory
|
public static class TypeFactory
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using Engine.Core.Exceptions;
|
using Syntriax.Engine.Core.Exceptions;
|
||||||
|
|
||||||
namespace Engine.Core.Factory;
|
namespace Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
public class UniverseObjectFactory
|
public class UniverseObjectFactory
|
||||||
{
|
{
|
||||||
|
@@ -1,15 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Engine.Core.Debug;
|
using Syntriax.Engine.Core.Debug;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
// TODO!: every reverse loop has a chance to have more than 1 unsubscription,
|
|
||||||
// for (int i = listeners.Count - 1; i >= 0; i--)
|
|
||||||
// can be replaced with
|
|
||||||
// for (int i = listeners.Count - 1; i >= 0; i = Math.Min(i - 1, listeners.Count - 1))
|
|
||||||
// but this would causes possible double calls on already called callbacks, find a better method.
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a simple event with no parameters.
|
/// Represents a simple event with no parameters.
|
||||||
|
@@ -1,78 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Engine.Core;
|
|
||||||
|
|
||||||
public class FastList<T> : IList<T>, IReadOnlyList<T>, IEnumerable<T> where T : notnull
|
|
||||||
{
|
|
||||||
private readonly List<T> items = [];
|
|
||||||
private readonly Dictionary<T, int> indexMap = [];
|
|
||||||
|
|
||||||
public int Count => items.Count;
|
|
||||||
|
|
||||||
public bool IsReadOnly { get; set; } = false;
|
|
||||||
public T this[int index] { get => items[index]; set => items[index] = value; }
|
|
||||||
|
|
||||||
public void Add(T item)
|
|
||||||
{
|
|
||||||
indexMap[item] = items.Count;
|
|
||||||
items.Add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAt(int i) => Remove(items[i], i);
|
|
||||||
public bool Remove(T item)
|
|
||||||
{
|
|
||||||
if (!indexMap.TryGetValue(item, out int index))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Remove(item, index);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Remove(T item, int index)
|
|
||||||
{
|
|
||||||
int lastIndex = items.Count - 1;
|
|
||||||
T lastItem = items[lastIndex];
|
|
||||||
|
|
||||||
items[index] = lastItem;
|
|
||||||
indexMap[lastItem] = index;
|
|
||||||
|
|
||||||
items.RemoveAt(lastIndex);
|
|
||||||
indexMap.Remove(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Insert(int index, T item)
|
|
||||||
{
|
|
||||||
items.Insert(index, item);
|
|
||||||
|
|
||||||
for (int i = index; i < items.Count; i++)
|
|
||||||
indexMap[items[i]] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
items.Clear();
|
|
||||||
indexMap.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Contains(T item) => indexMap.ContainsKey(item);
|
|
||||||
|
|
||||||
public int BinarySearch(T item, IComparer<T>? comparer = null) => items.BinarySearch(item, comparer);
|
|
||||||
public void Sort(IComparer<T> comparer)
|
|
||||||
{
|
|
||||||
items.Sort(comparer);
|
|
||||||
|
|
||||||
for (int i = 0; i < items.Count; i++)
|
|
||||||
indexMap[items[i]] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int IndexOf(T item) => items.IndexOf(item);
|
|
||||||
public void CopyTo(T[] array, int arrayIndex) => items.CopyTo(array, arrayIndex);
|
|
||||||
|
|
||||||
public IEnumerator<T> GetEnumerator() => items.GetEnumerator();
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
||||||
|
|
||||||
public FastList() { }
|
|
||||||
public FastList(int count) { items.Capacity = count; }
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public interface IPool<T>
|
public interface IPool<T>
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class ListPool<T> : IPool<List<T>>
|
public class ListPool<T> : IPool<List<T>>
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class Pool<T> : IPool<T>
|
public class Pool<T> : IPool<T>
|
||||||
{
|
{
|
||||||
@@ -10,25 +10,22 @@ public class Pool<T> : IPool<T>
|
|||||||
|
|
||||||
private readonly Func<T> generator = null!;
|
private readonly Func<T> generator = null!;
|
||||||
private readonly Queue<T> queue = new();
|
private readonly Queue<T> queue = new();
|
||||||
private readonly HashSet<T> queuedHashes = [];
|
|
||||||
|
|
||||||
public T Get()
|
public T Get()
|
||||||
{
|
{
|
||||||
if (!queue.TryDequeue(out T? result))
|
if (!queue.TryDequeue(out T? result))
|
||||||
result = generator();
|
result = generator();
|
||||||
|
|
||||||
queuedHashes.Remove(result);
|
|
||||||
OnRemoved?.Invoke(this, result);
|
OnRemoved?.Invoke(this, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Return(T item)
|
public void Return(T item)
|
||||||
{
|
{
|
||||||
if (queuedHashes.Contains(item))
|
if (queue.Contains(item))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
queue.Enqueue(item);
|
queue.Enqueue(item);
|
||||||
queuedHashes.Add(item);
|
|
||||||
OnReturned?.Invoke(this, item);
|
OnReturned?.Invoke(this, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public interface IProgressionTracker : IReadOnlyProgressionTracker
|
public interface IProgressionTracker : IReadOnlyProgressionTracker
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public interface IReadOnlyProgressionTracker
|
public interface IReadOnlyProgressionTracker
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class ProgressionTracker : IProgressionTracker
|
public class ProgressionTracker : IProgressionTracker
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public record struct ProgressiveTask<T>(IReadOnlyProgressionTracker ProgressionTracker, Task<T> Task)
|
public record struct ProgressiveTask<T>(IReadOnlyProgressionTracker ProgressionTracker, Task<T> Task)
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class Math
|
public static class Math
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class MathExtensions
|
public static class MathExtensions
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core
|
namespace Syntriax.Engine.Core
|
||||||
{
|
{
|
||||||
// This is pretty much so the assembly gets loaded automatically because
|
// This is pretty much so the assembly gets loaded automatically because
|
||||||
// the builds include the assembly but sometimes doesn't link load it at startup.
|
// the builds include the assembly but sometimes doesn't link load it at startup.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an Axis-Aligned Bounding Box (AABB) in 2D space.
|
/// Represents an Axis-Aligned Bounding Box (AABB) in 2D space.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a 2D circle.
|
/// Represents a 2D circle.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an HSV color.
|
/// Represents an HSV color.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an HSV color.
|
/// Represents an HSV color.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an RGB color.
|
/// Represents an RGB color.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an RGBA color.
|
/// Represents an RGBA color.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a 2D line segment defined by two endpoints.
|
/// Represents a 2D line segment defined by two endpoints.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a <see cref="Line2DEquation"/> in the form y = mx + b.
|
/// Represents a <see cref="Line2DEquation"/> in the form y = mx + b.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a range of values along a single axis.
|
/// Represents a range of values along a single axis.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a 3D space rotation.
|
/// Represents a 3D space rotation.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an infinite ray in 2D space.
|
/// Represents an infinite ray in 2D space.
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a shape defined by a collection of vertices.
|
/// Represents a shape defined by a collection of vertices.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("A: {A.ToString(), nq}, B: {B.ToString(), nq}, B: {C.ToString(), nq}")]
|
[System.Diagnostics.DebuggerDisplay("A: {A.ToString(), nq}, B: {B.ToString(), nq}, B: {C.ToString(), nq}")]
|
||||||
public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C)
|
public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a two-dimensional vector.
|
/// Represents a two-dimensional vector.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a three-dimensional vector.
|
/// Represents a three-dimensional vector.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Serialization;
|
namespace Syntriax.Engine.Core.Serialization;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)]
|
||||||
public class IgnoreSerializationAttribute : Attribute;
|
public class IgnoreSerializationAttribute : Attribute;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Serialization;
|
namespace Syntriax.Engine.Core.Serialization;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
||||||
public class SerializeAllAttribute : Attribute;
|
public class SerializeAllAttribute : Attribute;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Serialization;
|
namespace Syntriax.Engine.Core.Serialization;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||||
public class SerializeAttribute : Attribute;
|
public class SerializeAttribute : Attribute;
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
namespace Engine.Core.Serialization;
|
namespace Syntriax.Engine.Core.Serialization;
|
||||||
|
|
||||||
public record class EntityReference(string? Id = null);
|
public record class EntityReference(string? Id = null);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core.Serialization;
|
namespace Syntriax.Engine.Core.Serialization;
|
||||||
|
|
||||||
public class EntityRegistry
|
public class EntityRegistry
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core.Serialization;
|
namespace Syntriax.Engine.Core.Serialization;
|
||||||
|
|
||||||
public interface ISerializer
|
public interface ISerializer
|
||||||
{
|
{
|
||||||
|
@@ -2,9 +2,9 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using Engine.Core.Factory;
|
using Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
namespace Engine.Core.Serialization;
|
namespace Syntriax.Engine.Core.Serialization;
|
||||||
|
|
||||||
public class SerializedClass
|
public class SerializedClass
|
||||||
{
|
{
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user