Compare commits
20 Commits
4c542df401
...
dbd15cbbc2
| Author | SHA1 | Date | |
|---|---|---|---|
| dbd15cbbc2 | |||
| e051f5cfb4 | |||
| e70b7f112f | |||
| f55ba499b6 | |||
| b75f30f864 | |||
| 6f1f30bd53 | |||
| 92a5c276a4 | |||
| 69bc6573d1 | |||
| 28bc022587 | |||
| 25db60e436 | |||
| 7c62440bba | |||
| 4bec7bce6e | |||
| 8d31372c24 | |||
| a2e704916e | |||
| c7d170fad9 | |||
| 9ccf7b754d | |||
| e3d4899112 | |||
| 566c16d09c | |||
| ae9d4f02ef | |||
| e77772cbc2 |
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
|||||||
[submodule "Engine.Integration/YamlDotNet"]
|
[submodule "Engine.Integration/YamlDotNet"]
|
||||||
path = Engine.Integration/YamlDotNet
|
path = Engine.Integration/YamlDotNet
|
||||||
url = git@github.com:Syntriax/YamlDotNet.git
|
url = https://github.com/Syntriax/YamlDotNet.git
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace 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,67 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
16
Engine.Core/Collectors/ActiveBehaviourCollector.cs
Normal file
16
Engine.Core/Collectors/ActiveBehaviourCollector.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
@@ -3,12 +3,10 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : class, IBehaviour
|
public abstract class ActiveBehaviourCollectorBase<T> : IBehaviourCollector<T> where T : class, IBehaviour
|
||||||
{
|
{
|
||||||
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
|
protected readonly Dictionary<IActive, T> monitoringActiveToBehaviour = new(32);
|
||||||
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourRemovedArguments> OnRemoved { get; } = new();
|
protected readonly FastList<T> monitoringBehaviours = new(32);
|
||||||
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!;
|
||||||
@@ -16,80 +14,16 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
|
|||||||
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!;
|
||||||
|
|
||||||
private readonly FastList<T> monitoringBehaviours = new(32);
|
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
|
||||||
protected readonly FastList<T> activeBehaviours = new(32);
|
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourRemovedArguments> OnRemoved { get; } = new();
|
||||||
protected readonly Dictionary<IActive, T> monitoringActiveToBehaviour = new(32);
|
public Event<IHasUniverse> OnUniverseAssigned { get; } = new();
|
||||||
|
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)
|
||||||
@@ -123,10 +57,75 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count => activeBehaviours.Count;
|
protected abstract void AddBehaviour(T behaviour);
|
||||||
public T this[Index index] => activeBehaviours[index];
|
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
|
||||||
|
private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args)
|
||||||
|
{
|
||||||
|
if (args.BehaviourAdded is not T tBehaviour)
|
||||||
|
return;
|
||||||
|
|
||||||
public ActiveBehaviourCollector()
|
monitoringBehaviours.Add(tBehaviour);
|
||||||
|
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;
|
||||||
@@ -135,7 +134,7 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
|
|||||||
delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
|
delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActiveBehaviourCollector(IUniverse universe)
|
public ActiveBehaviourCollectorBase(IUniverse universe)
|
||||||
{
|
{
|
||||||
delegateOnBehaviourAdded = OnBehaviourAdded;
|
delegateOnBehaviourAdded = OnBehaviourAdded;
|
||||||
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
||||||
104
Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs
Normal file
104
Engine.Core/Collectors/ActiveBehaviourCollectorOrdered.cs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
Engine.Core/Collectors/BehaviourCollector.cs
Normal file
17
Engine.Core/Collectors/BehaviourCollector.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
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) { }
|
||||||
|
}
|
||||||
@@ -2,70 +2,24 @@ using System;
|
|||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
|
public abstract class BehaviourCollectorBase<T> : IBehaviourCollector<T> where T : class
|
||||||
{
|
{
|
||||||
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
|
|
||||||
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!;
|
||||||
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!;
|
||||||
|
|
||||||
protected readonly FastList<T> behaviours = new(32);
|
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
|
||||||
|
public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourRemovedArguments> OnRemoved { get; } = new();
|
||||||
|
public Event<IHasUniverse> OnUniverseAssigned { get; } = new();
|
||||||
|
public Event<IAssignable>? OnUnassigned { get; } = new();
|
||||||
|
|
||||||
public IUniverse Universe { get; private set; } = null!;
|
public IUniverse Universe { get; private set; } = null!;
|
||||||
|
|
||||||
private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args)
|
public abstract int Count { get; }
|
||||||
{
|
|
||||||
IUniverseObject universeObject = args.UniverseObjectRegistered;
|
|
||||||
|
|
||||||
universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded);
|
public abstract T this[Index index] { get; }
|
||||||
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)
|
||||||
@@ -100,10 +54,57 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count => behaviours.Count;
|
protected virtual void OnAssign(IUniverse universe) { }
|
||||||
public T this[Index index] => behaviours[index];
|
|
||||||
|
|
||||||
public BehaviourCollector()
|
protected abstract void AddBehaviour(T 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 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;
|
||||||
@@ -111,7 +112,7 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
|
|||||||
delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
|
delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BehaviourCollector(IUniverse universe)
|
public BehaviourCollectorBase(IUniverse universe)
|
||||||
{
|
{
|
||||||
delegateOnBehaviourAdded = OnBehaviourAdded;
|
delegateOnBehaviourAdded = OnBehaviourAdded;
|
||||||
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
delegateOnBehaviourRemoved = OnBehaviourRemoved;
|
||||||
104
Engine.Core/Collectors/BehaviourCollectorOrdered.cs
Normal file
104
Engine.Core/Collectors/BehaviourCollectorOrdered.cs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,17 +3,30 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
public class FastList<T> : IReadOnlyList<T>, IEnumerable<T> where T : notnull
|
public class FastList<T> : IList<T>, IReadOnlyList<T>, IEnumerable<T> where T : notnull
|
||||||
{
|
{
|
||||||
private readonly List<T> items = [];
|
private readonly List<T> items = [];
|
||||||
private readonly Dictionary<T, int> indexMap = [];
|
private readonly Dictionary<T, int> indexMap = [];
|
||||||
|
|
||||||
|
public bool IsReadOnly { get; set; } = false;
|
||||||
public int Count => items.Count;
|
public int Count => items.Count;
|
||||||
|
public T this[int index]
|
||||||
|
{
|
||||||
|
get => items[index];
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
public T this[int index] => items[index];
|
items[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Add(T item)
|
public void Add(T item)
|
||||||
{
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
indexMap[item] = items.Count;
|
indexMap[item] = items.Count;
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
}
|
}
|
||||||
@@ -21,6 +34,9 @@ public class FastList<T> : IReadOnlyList<T>, IEnumerable<T> where T : notnull
|
|||||||
public void RemoveAt(int i) => Remove(items[i], i);
|
public void RemoveAt(int i) => Remove(items[i], i);
|
||||||
public bool Remove(T item)
|
public bool Remove(T item)
|
||||||
{
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
if (!indexMap.TryGetValue(item, out int index))
|
if (!indexMap.TryGetValue(item, out int index))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -43,6 +59,9 @@ public class FastList<T> : IReadOnlyList<T>, IEnumerable<T> where T : notnull
|
|||||||
|
|
||||||
public void Insert(int index, T item)
|
public void Insert(int index, T item)
|
||||||
{
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
items.Insert(index, item);
|
items.Insert(index, item);
|
||||||
|
|
||||||
for (int i = index; i < items.Count; i++)
|
for (int i = index; i < items.Count; i++)
|
||||||
@@ -51,21 +70,30 @@ public class FastList<T> : IReadOnlyList<T>, IEnumerable<T> where T : notnull
|
|||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
items.Clear();
|
items.Clear();
|
||||||
indexMap.Clear();
|
indexMap.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains(T item) => indexMap.ContainsKey(item);
|
public bool Contains(T item) => indexMap.ContainsKey(item);
|
||||||
|
public int IndexOf(T item) => items.IndexOf(item);
|
||||||
public int BinarySearch(T item, IComparer<T>? comparer = null) => items.BinarySearch(item, comparer);
|
public int BinarySearch(T item, IComparer<T>? comparer = null) => items.BinarySearch(item, comparer);
|
||||||
|
|
||||||
public void Sort(IComparer<T> comparer)
|
public void Sort(IComparer<T> comparer)
|
||||||
{
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
items.Sort(comparer);
|
items.Sort(comparer);
|
||||||
|
|
||||||
for (int i = 0; i < items.Count; i++)
|
for (int i = 0; i < items.Count; i++)
|
||||||
indexMap[items[i]] = i;
|
indexMap[items[i]] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CopyTo(T[] array, int arrayIndex) => items.CopyTo(array, arrayIndex);
|
||||||
|
|
||||||
public IEnumerator<T> GetEnumerator() => items.GetEnumerator();
|
public IEnumerator<T> GetEnumerator() => items.GetEnumerator();
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
|
|||||||
172
Engine.Core/Helpers/FastListOrdered.cs
Normal file
172
Engine.Core/Helpers/FastListOrdered.cs
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Engine.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TODO This is VEERY experimental, and doesn't work well with the indices access. Use with caution
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TIndex"></typeparam>
|
||||||
|
/// <typeparam name="TItem"></typeparam>
|
||||||
|
public class FastListOrdered<TIndex, TItem> : IList<TItem>, IReadOnlyList<TItem>, IEnumerable<TItem> where TItem : notnull where TIndex : IComparable
|
||||||
|
{
|
||||||
|
private readonly SortedDictionary<TIndex, FastList<TItem>> items = null!;
|
||||||
|
|
||||||
|
private readonly Func<TItem, TIndex> getIndexFunc = null!;
|
||||||
|
private readonly IComparer<TIndex> sortBy = null!;
|
||||||
|
|
||||||
|
private int count = 0;
|
||||||
|
public int Count => count;
|
||||||
|
|
||||||
|
public bool IsReadOnly { get; set; } = false;
|
||||||
|
|
||||||
|
public TItem this[int index]
|
||||||
|
{
|
||||||
|
get { (TIndex tIndex, int i) = GetAt(index); return items[tIndex][i]; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
(TIndex tIndex, int i) = GetAt(index); items[tIndex][i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private (TIndex TIndex, int i) GetAt(Index index)
|
||||||
|
{
|
||||||
|
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 items)
|
||||||
|
{
|
||||||
|
if (leftIndex < list.Count)
|
||||||
|
return (i, leftIndex);
|
||||||
|
leftIndex -= list.Count;
|
||||||
|
}
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOf(TItem item)
|
||||||
|
{
|
||||||
|
int indexCounter = 0;
|
||||||
|
foreach ((TIndex index, FastList<TItem> list) in items)
|
||||||
|
{
|
||||||
|
int i = list.IndexOf(item);
|
||||||
|
if (i != -1)
|
||||||
|
return indexCounter + i;
|
||||||
|
indexCounter += list.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(TItem item)
|
||||||
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
|
TIndex key = getIndexFunc(item);
|
||||||
|
if (!items.TryGetValue(key, out FastList<TItem>? list))
|
||||||
|
items[key] = list = [];
|
||||||
|
|
||||||
|
list.Add(item);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(int index, TItem item)
|
||||||
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
|
TIndex tIndex = getIndexFunc(item);
|
||||||
|
if (!items.TryGetValue(tIndex, out FastList<TItem>? list))
|
||||||
|
items[tIndex] = list = [];
|
||||||
|
|
||||||
|
list.Insert(index, item);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Remove(TItem item)
|
||||||
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
|
TIndex index = getIndexFunc(item);
|
||||||
|
if (!items.TryGetValue(index, out FastList<TItem>? list))
|
||||||
|
throw new Exceptions.NotFoundException($"Index of '{index}' is not found in the collector");
|
||||||
|
|
||||||
|
if (!list.Remove(item))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
count--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveAt(int index)
|
||||||
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
|
(TIndex tIndex, int i) = GetAt(index);
|
||||||
|
items[tIndex].RemoveAt(i);
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
if (IsReadOnly)
|
||||||
|
throw new System.Data.ReadOnlyException();
|
||||||
|
|
||||||
|
foreach ((TIndex index, FastList<TItem> list) in items)
|
||||||
|
list.Clear();
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(TItem item)
|
||||||
|
{
|
||||||
|
foreach ((TIndex index, FastList<TItem> list) in items)
|
||||||
|
if (list.Contains(item))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo(TItem[] array, int arrayIndex)
|
||||||
|
{
|
||||||
|
int indexCounter = 0;
|
||||||
|
|
||||||
|
foreach ((TIndex index, FastList<TItem> list) in items)
|
||||||
|
{
|
||||||
|
list.CopyTo(array, indexCounter);
|
||||||
|
indexCounter += list.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<TItem> GetEnumerator()
|
||||||
|
{
|
||||||
|
foreach ((TIndex index, FastList<TItem> list) in items)
|
||||||
|
foreach (TItem item in list)
|
||||||
|
yield return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
|
public FastListOrdered(Func<TItem, TIndex> getIndexFunc, Comparison<TIndex> sortBy)
|
||||||
|
{
|
||||||
|
this.getIndexFunc = getIndexFunc;
|
||||||
|
this.sortBy = Comparer<TIndex>.Create(sortBy);
|
||||||
|
items = new(this.sortBy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FastListOrdered(Func<TItem, TIndex> getIndexFunc, IComparer<TIndex> sortBy)
|
||||||
|
{
|
||||||
|
this.getIndexFunc = getIndexFunc;
|
||||||
|
this.sortBy = sortBy;
|
||||||
|
items = new(sortBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -240,21 +240,33 @@ public static class Math
|
|||||||
public static T Lerp<T>(T x, T y, T t) where T : IFloatingPoint<T> => x + (y - x) * t;
|
public static T Lerp<T>(T x, T y, T t) where T : IFloatingPoint<T> => x + (y - x) * t;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rounds a number to a specified number of fractional digits.
|
/// Rounds a number to the closest integer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="x">The number to round.</param>
|
/// <param name="x">The number to round.</param>
|
||||||
/// <param name="digits">The number of fractional digits in the return value.</param>
|
/// <param name="roundMode">Specification for how to round <paramref name="x"/> if it is midway between two other numbers.</param>
|
||||||
/// <param name="mode">Specification for how to round <paramref name="x"/> if it is midway between two other numbers.</param>
|
/// <returns>The number <paramref name="x"/> rounded to the closest integer.</returns>
|
||||||
/// <returns>The number <paramref name="x"/> rounded to <paramref name="digits"/> fractional digits.</returns>
|
public static float Round(float x, RoundMode roundMode) => RoundToInt(x, roundMode);
|
||||||
public static float Round(float x, int digits, MidpointRounding mode) => MathF.Round(x, digits, mode);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rounds a number to an integer.
|
/// Rounds a number to the closest integer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="x">The number to round.</param>
|
/// <param name="x">The number to round.</param>
|
||||||
/// <param name="roundMode">Specification for how to round <paramref name="x"/> if it's midway between two numbers</param>
|
/// <param name="roundMode">Specification for how to round <paramref name="x"/> if it's midway between two numbers</param>
|
||||||
/// <returns></returns>
|
/// <returns>The number <paramref name="x"/> rounded to the closest integer.</returns>
|
||||||
public static int RoundToInt(float x, RoundMode roundMode = RoundMode.Ceil) => (int)MathF.Round(x, 0, roundMode == RoundMode.Ceil ? MidpointRounding.ToPositiveInfinity : MidpointRounding.ToNegativeInfinity);
|
public static int RoundToInt(float x, RoundMode roundMode = RoundMode.Ceil)
|
||||||
|
{
|
||||||
|
float remainder = x.Mod(1f);
|
||||||
|
|
||||||
|
if (remainder == .5f)
|
||||||
|
if (roundMode == RoundMode.Floor)
|
||||||
|
return (int)x;
|
||||||
|
else
|
||||||
|
return (int)(x + .5f);
|
||||||
|
|
||||||
|
if (x < 0f)
|
||||||
|
return (int)(x - .5f);
|
||||||
|
return (int)(x + .5f);
|
||||||
|
}
|
||||||
public enum RoundMode { Ceil, Floor };
|
public enum RoundMode { Ceil, Floor };
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public static class MathExtensions
|
|||||||
public static T Lerp<T>(this T x, T y, T t) where T : IFloatingPoint<T> => Math.Lerp(x, y, t);
|
public static T Lerp<T>(this T x, T y, T t) where T : IFloatingPoint<T> => Math.Lerp(x, y, t);
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.Round(float, int, MidpointRounding)" />
|
/// <inheritdoc cref="Math.Round(float, int, MidpointRounding)" />
|
||||||
public static float Round(this float x, int digits, MidpointRounding mode) => Math.Round(x, digits, mode);
|
public static float Round(this float x, Math.RoundMode mode) => Math.Round(x, mode);
|
||||||
|
|
||||||
/// <inheritdoc cref="Math.RoundToInt(float, Math.RoundMode)" />
|
/// <inheritdoc cref="Math.RoundToInt(float, Math.RoundMode)" />
|
||||||
public static int RoundToInt(this float x, Math.RoundMode roundMode = Math.RoundMode.Ceil) => Math.RoundToInt(x, roundMode);
|
public static int RoundToInt(this float x, Math.RoundMode roundMode = Math.RoundMode.Ceil) => Math.RoundToInt(x, roundMode);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
@@ -11,7 +12,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="AABB"/> struct with the specified lower and upper boundaries.
|
/// Initializes a new instance of the <see cref="AABB"/> struct with the specified lower and upper boundaries.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("LowerBoundary: {LowerBoundary.ToString(), nq}, UpperBoundary: {UpperBoundary.ToString(), nq}")]
|
[System.Diagnostics.DebuggerDisplay("LowerBoundary: {LowerBoundary.ToString(), nq}, UpperBoundary: {UpperBoundary.ToString(), nq}")]
|
||||||
public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary)
|
public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary) : IEquatable<AABB>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The lower boundary of the <see cref="AABB"/>.
|
/// The lower boundary of the <see cref="AABB"/>.
|
||||||
@@ -82,6 +83,7 @@ public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="AABB"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="AABB"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="AABB"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="AABB"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is AABB aabb && this == aabb;
|
public override bool Equals(object? obj) => obj is AABB aabb && this == aabb;
|
||||||
|
public bool Equals(AABB other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="AABB"/>.
|
/// Generates a hash code for the <see cref="AABB"/>.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
@@ -11,7 +12,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="Circle"/> struct with the specified center and radius.
|
/// Initializes a new instance of the <see cref="Circle"/> struct with the specified center and radius.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[DebuggerDisplay("Center: {Center.ToString(),nq}, Radius: {Radius}")]
|
[DebuggerDisplay("Center: {Center.ToString(),nq}, Radius: {Radius}")]
|
||||||
public readonly struct Circle(Vector2D center, float radius)
|
public readonly struct Circle(Vector2D center, float radius) : IEquatable<Circle>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The center of the circle.
|
/// The center of the circle.
|
||||||
@@ -87,6 +88,7 @@ public readonly struct Circle(Vector2D center, float radius)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Circle"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Circle"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Circle"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Circle"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Circle circle && this == circle;
|
public override bool Equals(object? obj) => obj is Circle circle && this == circle;
|
||||||
|
public bool Equals(Circle other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Circle"/>.
|
/// Generates a hash code for the <see cref="Circle"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +12,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="ColorHSV"/> struct with the specified values.
|
/// Initializes a new instance of the <see cref="ColorHSV"/> struct with the specified values.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
||||||
public readonly struct ColorHSV(float hue, float saturation, float value)
|
public readonly struct ColorHSV(float hue, float saturation, float value) : IEquatable<ColorHSV>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Hue value of the <see cref="ColorHSV"/>.
|
/// The Hue value of the <see cref="ColorHSV"/>.
|
||||||
@@ -112,6 +114,7 @@ public readonly struct ColorHSV(float hue, float saturation, float value)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="ColorHSV"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="ColorHSV"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorHSV"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorHSV"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is ColorHSV colorHSV && this == colorHSV;
|
public override bool Equals(object? obj) => obj is ColorHSV colorHSV && this == colorHSV;
|
||||||
|
public bool Equals(ColorHSV other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="ColorHSV"/>.
|
/// Generates a hash code for the <see cref="ColorHSV"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -11,7 +13,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="ColorHSVA"/> struct with the specified values.
|
/// Initializes a new instance of the <see cref="ColorHSVA"/> struct with the specified values.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
||||||
public readonly struct ColorHSVA(float hue, float saturation, float value, float alpha = 1)
|
public readonly struct ColorHSVA(float hue, float saturation, float value, float alpha = 1) : IEquatable<ColorHSVA>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Hue value of the <see cref="ColorHSVA"/>.
|
/// The Hue value of the <see cref="ColorHSVA"/>.
|
||||||
@@ -150,6 +152,7 @@ public readonly struct ColorHSVA(float hue, float saturation, float value, float
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="ColorHSVA"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="ColorHSVA"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorHSVA"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorHSVA"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is ColorHSVA colorHSVA && this == colorHSVA;
|
public override bool Equals(object? obj) => obj is ColorHSVA colorHSVA && this == colorHSVA;
|
||||||
|
public bool Equals(ColorHSVA other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="ColorHSVA"/>.
|
/// Generates a hash code for the <see cref="ColorHSVA"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +12,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="ColorRGB"/> struct with the specified values.
|
/// Initializes a new instance of the <see cref="ColorRGB"/> struct with the specified values.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
||||||
public readonly struct ColorRGB(byte r, byte g, byte b)
|
public readonly struct ColorRGB(byte r, byte g, byte b) : IEquatable<ColorRGB>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Red value of the <see cref="ColorRGB"/>.
|
/// The Red value of the <see cref="ColorRGB"/>.
|
||||||
@@ -102,6 +104,7 @@ public readonly struct ColorRGB(byte r, byte g, byte b)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="ColorRGB"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="ColorRGB"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorRGB"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorRGB"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is ColorRGB colorRGB && this == colorRGB;
|
public override bool Equals(object? obj) => obj is ColorRGB colorRGB && this == colorRGB;
|
||||||
|
public bool Equals(ColorRGB other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="ColorRGB"/>.
|
/// Generates a hash code for the <see cref="ColorRGB"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -11,7 +13,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="ColorRGBA"/> struct with the specified values.
|
/// Initializes a new instance of the <see cref="ColorRGBA"/> struct with the specified values.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
||||||
public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255)
|
public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255) : IEquatable<ColorRGBA>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Red value of the <see cref="ColorRGBA"/>.
|
/// The Red value of the <see cref="ColorRGBA"/>.
|
||||||
@@ -132,6 +134,7 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="ColorRGBA"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="ColorRGBA"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorRGBA"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorRGBA"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is ColorRGBA colorRGBA && this == colorRGBA;
|
public override bool Equals(object? obj) => obj is ColorRGBA colorRGBA && this == colorRGBA;
|
||||||
|
public bool Equals(ColorRGBA other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="ColorRGBA"/>.
|
/// Generates a hash code for the <see cref="ColorRGBA"/>.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
@@ -11,7 +12,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="Line2D"/> struct with the specified endpoints.
|
/// Initializes a new instance of the <see cref="Line2D"/> struct with the specified endpoints.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("From: {From.ToString(),nq}, To: {To.ToString(),nq}, Direction: {Direction.ToString(),nq}, Length: {Length}")]
|
[System.Diagnostics.DebuggerDisplay("From: {From.ToString(),nq}, To: {To.ToString(),nq}, Direction: {Direction.ToString(),nq}, Length: {Length}")]
|
||||||
public readonly struct Line2D(Vector2D from, Vector2D to)
|
public readonly struct Line2D(Vector2D from, Vector2D to) : IEquatable<Line2D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The starting point of the <see cref="Line2D"/> segment.
|
/// The starting point of the <see cref="Line2D"/> segment.
|
||||||
@@ -196,6 +197,7 @@ public readonly struct Line2D(Vector2D from, Vector2D to)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Line2D"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Line2D"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Line2D"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Line2D"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Line2D line2D && this == line2D;
|
public override bool Equals(object? obj) => obj is Line2D line2D && this == line2D;
|
||||||
|
public bool Equals(Line2D other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Line2D"/>.
|
/// Generates a hash code for the <see cref="Line2D"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -9,7 +11,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="Line2DEquation"/> struct with the specified slope and Y intercept.
|
/// Initializes a new instance of the <see cref="Line2DEquation"/> struct with the specified slope and Y intercept.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("y = {Slope}x + {OffsetY}")]
|
[System.Diagnostics.DebuggerDisplay("y = {Slope}x + {OffsetY}")]
|
||||||
public readonly struct Line2DEquation(float slope, float offsetY)
|
public readonly struct Line2DEquation(float slope, float offsetY) : IEquatable<Line2DEquation>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The slope of the <see cref="Line2DEquation"/>.
|
/// The slope of the <see cref="Line2DEquation"/>.
|
||||||
@@ -48,6 +50,7 @@ public readonly struct Line2DEquation(float slope, float offsetY)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Line2DEquation"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Line2DEquation"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Line2DEquation"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Line2DEquation"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Line2DEquation lineEquation && this == lineEquation;
|
public override bool Equals(object? obj) => obj is Line2DEquation lineEquation && this == lineEquation;
|
||||||
|
public bool Equals(Line2DEquation other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Line2DEquation"/>.
|
/// Generates a hash code for the <see cref="Line2DEquation"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -9,7 +11,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="Projection1D"/> struct with the specified minimum and maximum values.
|
/// Initializes a new instance of the <see cref="Projection1D"/> struct with the specified minimum and maximum values.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("Min: {Min}, Max: {Max}")]
|
[System.Diagnostics.DebuggerDisplay("Min: {Min}, Max: {Max}")]
|
||||||
public readonly struct Projection1D(float min, float max)
|
public readonly struct Projection1D(float min, float max) : IEquatable<Projection1D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the minimum value of the projection.
|
/// Gets the minimum value of the projection.
|
||||||
@@ -90,6 +92,7 @@ public readonly struct Projection1D(float min, float max)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Projection1D"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Projection1D"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Projection1D"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Projection1D"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Projection1D projection1D && this == projection1D;
|
public override bool Equals(object? obj) => obj is Projection1D projection1D && this == projection1D;
|
||||||
|
public bool Equals(Projection1D other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Projection1D"/>.
|
/// Generates a hash code for the <see cref="Projection1D"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -11,7 +13,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="Quaternion"/> struct with the specified positions.
|
/// Initializes a new instance of the <see cref="Quaternion"/> struct with the specified positions.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")]
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")]
|
||||||
public readonly struct Quaternion(float x, float y, float z, float w)
|
public readonly struct Quaternion(float x, float y, float z, float w) : IEquatable<Quaternion>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The X(i) imaginary of the <see cref="Quaternion"/>.
|
/// The X(i) imaginary of the <see cref="Quaternion"/>.
|
||||||
@@ -288,6 +290,7 @@ public readonly struct Quaternion(float x, float y, float z, float w)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Quaternion"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Quaternion"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Quaternion"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Quaternion"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Quaternion quaternion && this == quaternion;
|
public override bool Equals(object? obj) => obj is Quaternion quaternion && this == quaternion;
|
||||||
|
public bool Equals(Quaternion other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Quaternion"/>.
|
/// Generates a hash code for the <see cref="Quaternion"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -5,7 +7,7 @@ namespace Engine.Core;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Origin">The <see cref="Vector2D"/> in 2D space where the ray starts from.</param>
|
/// <param name="Origin">The <see cref="Vector2D"/> in 2D space where the ray starts from.</param>
|
||||||
/// <param name="Direction">Normalized <see cref="Vector2D"/> indicating the ray's is direction.</param>
|
/// <param name="Direction">Normalized <see cref="Vector2D"/> indicating the ray's is direction.</param>
|
||||||
public readonly struct Ray2D(Vector2D Origin, Vector2D Direction)
|
public readonly struct Ray2D(Vector2D Origin, Vector2D Direction) : IEquatable<Ray2D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The starting point of the <see cref="Ray2D"/>.
|
/// The starting point of the <see cref="Ray2D"/>.
|
||||||
@@ -72,6 +74,7 @@ public readonly struct Ray2D(Vector2D Origin, Vector2D Direction)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Ray2D"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Ray2D"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Ray2D"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Ray2D"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Ray2D ray2D && this == ray2D;
|
public override bool Equals(object? obj) => obj is Ray2D ray2D && this == ray2D;
|
||||||
|
public bool Equals(Ray2D other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Ray2D"/>.
|
/// Generates a hash code for the <see cref="Ray2D"/>.
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace 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) : IEquatable<Triangle>
|
||||||
{
|
{
|
||||||
public readonly Vector2D A { get; init; } = A;
|
public readonly Vector2D A { get; init; } = A;
|
||||||
public readonly Vector2D B { get; init; } = B;
|
public readonly Vector2D B { get; init; } = B;
|
||||||
@@ -54,6 +56,7 @@ public readonly struct Triangle(Vector2D A, Vector2D B, Vector2D C)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Triangle"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Triangle"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Triangle"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Triangle"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Triangle triangle && this == triangle;
|
public override bool Equals(object? obj) => obj is Triangle triangle && this == triangle;
|
||||||
|
public bool Equals(Triangle other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Triangle"/>.
|
/// Generates a hash code for the <see cref="Triangle"/>.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -9,7 +11,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="Vector2D"/> struct with the specified positions.
|
/// Initializes a new instance of the <see cref="Vector2D"/> struct with the specified positions.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")]
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")]
|
||||||
public readonly struct Vector2D(float x, float y)
|
public readonly struct Vector2D(float x, float y) : IEquatable<Vector2D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The X coordinate of the <see cref="Vector2D"/>.
|
/// The X coordinate of the <see cref="Vector2D"/>.
|
||||||
@@ -82,6 +84,7 @@ public readonly struct Vector2D(float x, float y)
|
|||||||
|
|
||||||
public static implicit operator System.Numerics.Vector2(Vector2D vector) => new(vector.X, vector.Y);
|
public static implicit operator System.Numerics.Vector2(Vector2D vector) => new(vector.X, vector.Y);
|
||||||
public static implicit operator Vector2D(System.Numerics.Vector2 vector) => new(vector.X, vector.Y);
|
public static implicit operator Vector2D(System.Numerics.Vector2 vector) => new(vector.X, vector.Y);
|
||||||
|
public static implicit operator Vector2D(Vector2DInt vector) => new(vector.X, vector.Y);
|
||||||
public static implicit operator Vector2D(Vector3D vector) => new(vector.X, vector.Y);
|
public static implicit operator Vector2D(Vector3D vector) => new(vector.X, vector.Y);
|
||||||
public static implicit operator Vector2D(System.Numerics.Vector3 vector) => new(vector.X, vector.Y);
|
public static implicit operator Vector2D(System.Numerics.Vector3 vector) => new(vector.X, vector.Y);
|
||||||
|
|
||||||
@@ -308,6 +311,7 @@ public readonly struct Vector2D(float x, float y)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Vector2D"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Vector2D"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector2D"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector2D"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Vector2D vector2D && this == vector2D;
|
public override bool Equals(object? obj) => obj is Vector2D vector2D && this == vector2D;
|
||||||
|
public bool Equals(Vector2D other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Vector2D"/>.
|
/// Generates a hash code for the <see cref="Vector2D"/>.
|
||||||
|
|||||||
306
Engine.Core/Primitives/Vector2DInt.cs
Normal file
306
Engine.Core/Primitives/Vector2DInt.cs
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Engine.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a two-dimensional integer vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">X position of the <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="y">Y position of the <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the <see cref="Vector2DInt"/> struct with the specified positions.
|
||||||
|
/// </remarks>
|
||||||
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
||||||
|
public readonly struct Vector2DInt(int x, int y) : IEquatable<Vector2DInt>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The X coordinate of the <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly int X = x;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Y coordinate of the <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly int Y = y;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The magnitude (length) of the <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float Magnitude => Length(this);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The squared magnitude (length) of the <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float MagnitudeSquared => LengthSquared(this);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="Vector2DInt"/> with the direction reversed.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Vector2DInt Reversed => -this;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector2DInt"/> pointing upwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector2DInt Up = new(0, 1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector2DInt"/> pointing downwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector2DInt Down = new(0, -1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector2DInt"/> pointing leftwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector2DInt Left = new(-1, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector2DInt"/> pointing rightwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector2DInt Right = new(1, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the zero <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector2DInt Zero = new(0, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the <see cref="Vector2DInt"/> with both components equal to 1.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector2DInt One = new(1, 1);
|
||||||
|
|
||||||
|
public static Vector2DInt operator -(Vector2DInt vector) => new(0 - vector.X, 0 - vector.Y);
|
||||||
|
public static Vector2DInt operator +(Vector2DInt left, Vector2DInt right) => new(left.X + right.X, left.Y + right.Y);
|
||||||
|
public static Vector2DInt operator -(Vector2DInt left, Vector2DInt right) => new(left.X - right.X, left.Y - right.Y);
|
||||||
|
public static Vector2DInt operator *(Vector2DInt vector, int value) => new(vector.X * value, vector.Y * value);
|
||||||
|
public static Vector2DInt operator *(int value, Vector2DInt vector) => new(vector.X * value, vector.Y * value);
|
||||||
|
public static Vector2DInt operator /(Vector2DInt vector, int value) => new(vector.X / value, vector.Y / value);
|
||||||
|
public static bool operator ==(Vector2DInt left, Vector2DInt right) => left.X == right.X && left.Y == right.Y;
|
||||||
|
public static bool operator !=(Vector2DInt left, Vector2DInt right) => left.X != right.X || left.Y != right.Y;
|
||||||
|
|
||||||
|
public static implicit operator Vector2DInt(Vector2D vector) => new(vector.X.RoundToInt(), vector.Y.RoundToInt());
|
||||||
|
public static implicit operator Vector2DInt(Vector3DInt vector) => new(vector.X, vector.Y);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the length of the <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The length of the <see cref="Vector2DInt"/>.</returns>
|
||||||
|
public static float Length(Vector2DInt vector) => Engine.Core.Math.Sqrt(LengthSquared(vector));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the squared length of the <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The squared length of the <see cref="Vector2DInt"/>.</returns>
|
||||||
|
public static float LengthSquared(Vector2DInt vector) => vector.X * vector.X + vector.Y * vector.Y;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the distance between two <see cref="Vector2DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">The start <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="to">The end <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The distance between the two <see cref="Vector2DInt"/>s.</returns>
|
||||||
|
public static float Distance(Vector2DInt from, Vector2DInt to) => Length(FromTo(from, to));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inverts the direction of the <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The inverted <see cref="Vector2DInt"/>.</returns>
|
||||||
|
public static Vector2DInt Invert(Vector2DInt vector) => -vector;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds two <see cref="Vector2DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The sum of the two <see cref="Vector2DInt"/>s.</returns>
|
||||||
|
public static Vector2DInt Add(Vector2DInt left, Vector2DInt right) => left + right;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subtracts one <see cref="Vector2DInt"/> from another.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The <see cref="Vector2DInt"/> to subtract from.</param>
|
||||||
|
/// <param name="right">The <see cref="Vector2DInt"/> to subtract.</param>
|
||||||
|
/// <returns>The result of subtracting the second <see cref="Vector2DInt"/> from the first.</returns>
|
||||||
|
public static Vector2DInt Subtract(Vector2DInt left, Vector2DInt right) => left - right;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Multiplies a <see cref="Vector2DInt"/> by a scalar value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="value">The scalar value.</param>
|
||||||
|
/// <returns>The result of multiplying the <see cref="Vector2DInt"/> by the scalar value.</returns>
|
||||||
|
public static Vector2DInt Multiply(Vector2DInt vector, int value) => vector * value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Divides a <see cref="Vector2DInt"/> by a scalar value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="value">The scalar value.</param>
|
||||||
|
/// <returns>The result of dividing the <see cref="Vector2DInt"/> by the scalar value.</returns>
|
||||||
|
public static Vector2DInt Divide(Vector2DInt vector, int value) => vector / value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the absolute value of each component of the vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The <see cref="Vector2DInt"/> with each component's absolute value.</returns>
|
||||||
|
public static Vector2DInt Abs(Vector2DInt vector) => new(Engine.Core.Math.Abs(vector.X), Engine.Core.Math.Abs(vector.Y));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the <see cref="Vector2DInt"/> from one point to another.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">The starting point.</param>
|
||||||
|
/// <param name="to">The ending point.</param>
|
||||||
|
/// <returns>The <see cref="Vector2DInt"/> from the starting point to the ending point.</returns>
|
||||||
|
public static Vector2DInt FromTo(Vector2DInt from, Vector2DInt to) => to - from;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scales a <see cref="Vector2DInt"/> by another <see cref="Vector2DInt"/> component-wise.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector2DInt"/> to scale.</param>
|
||||||
|
/// <param name="scale">The <see cref="Vector2DInt"/> containing the scaling factors for each component.</param>
|
||||||
|
/// <returns>The scaled <see cref="Vector2DInt"/>.</returns>
|
||||||
|
public static Vector2DInt Scale(Vector2DInt vector, Vector2DInt scale) => new(vector.X * scale.X, vector.Y * scale.Y);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates a perpendicular <see cref="Vector2DInt"/> to the given <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The input <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>A <see cref="Vector2DInt"/> perpendicular to the input <see cref="Vector2DInt"/>.</returns>
|
||||||
|
public static Vector2DInt Perpendicular(Vector2DInt vector) => new(-vector.Y, vector.X);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the component-wise minimum of two <see cref="Vector2DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The <see cref="Vector2DInt"/> containing the minimum components from both input <see cref="Vector2DInt"/>s.</returns>
|
||||||
|
public static Vector2DInt Min(Vector2DInt left, Vector2DInt right) => new((left.X < right.X) ? left.X : right.X, (left.Y < right.Y) ? left.Y : right.Y);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the component-wise maximum of two <see cref="Vector2DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The <see cref="Vector2DInt"/> containing the maximum components from both input <see cref="Vector2DInt"/>s.</returns>
|
||||||
|
public static Vector2DInt Max(Vector2DInt left, Vector2DInt right) => new((left.X > right.X) ? left.X : right.X, (left.Y > right.Y) ? left.Y : right.Y);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clamps each component of a <see cref="Vector2DInt"/> between the corresponding component of two other <see cref="Vector2DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector2DInt"/> to clamp.</param>
|
||||||
|
/// <param name="min">The <see cref="Vector2DInt"/> representing the minimum values for each component.</param>
|
||||||
|
/// <param name="max">The <see cref="Vector2DInt"/> representing the maximum values for each component.</param>
|
||||||
|
/// <returns>A <see cref="Vector2DInt"/> with each component clamped between the corresponding components of the min and max <see cref="Vector2DInt"/>s.</returns>
|
||||||
|
public static Vector2DInt Clamp(Vector2DInt vector, Vector2DInt min, Vector2DInt max) => new(Engine.Core.Math.Clamp(vector.X, min.X, max.X), Engine.Core.Math.Clamp(vector.Y, min.Y, max.Y));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs linear interpolation between two <see cref="Vector2DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">The starting <see cref="Vector2DInt"/> (t = 0).</param>
|
||||||
|
/// <param name="to">The ending <see cref="Vector2DInt"/> (t = 1).</param>
|
||||||
|
/// <param name="t">The interpolation parameter.</param>
|
||||||
|
/// <returns>The interpolated <see cref="Vector2DInt"/>.</returns>
|
||||||
|
public static Vector2DInt Lerp(Vector2DInt from, Vector2DInt to, int t) => from + FromTo(from, to) * t;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the cross product of two <see cref="Vector2DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The cross product of the two <see cref="Vector2DInt"/>s.</returns>
|
||||||
|
public static int Cross(Vector2DInt left, Vector2DInt right) => left.X * right.Y - left.Y * right.X;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the dot product of two <see cref="Vector2DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns>The dot product of the two <see cref="Vector2DInt"/>s.</returns>
|
||||||
|
public static int Dot(Vector2DInt left, Vector2DInt right) => left.X * right.X + left.Y * right.Y;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified object is equal to the current <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The object to compare with the current <see cref="Vector2DInt"/>.</param>
|
||||||
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector2DInt"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
|
public override bool Equals(object? obj) => obj is Vector2DInt vector2DInt && this == vector2DInt;
|
||||||
|
public bool Equals(Vector2DInt other) => this == other;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a hash code for the <see cref="Vector2DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A hash code for the <see cref="Vector2DInt"/>.</returns>
|
||||||
|
public override int GetHashCode() => System.HashCode.Combine(X, Y);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the <see cref="Vector2DInt"/> to its string representation.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A string representation of the <see cref="Vector2DInt"/>.</returns>
|
||||||
|
public override string ToString() => $"{nameof(Vector2DInt)}({X}, {Y})";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for <see cref="Vector2DInt"/> type.
|
||||||
|
/// </summary>
|
||||||
|
public static class Vector2DIntExtensions
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Length(Vector2DInt)" />
|
||||||
|
public static float Length(this Vector2DInt vector) => Vector2DInt.Length(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.LengthSquared(this vector) => Vector2DInt/>
|
||||||
|
public static float LengthSquared(this Vector2DInt vector) => Vector2DInt.LengthSquared(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Distance(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static float Distance(this Vector2DInt from, Vector2DInt to) => Vector2DInt.Distance(from, to);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Invert(this vector) => Vector2DInt/>
|
||||||
|
public static Vector2DInt Invert(this Vector2DInt vector) => Vector2DInt.Invert(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Add(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static Vector2DInt Add(this Vector2DInt vector, Vector2DInt vectorToAdd) => Vector2DInt.Add(vector, vectorToAdd);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Subtract(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static Vector2DInt Subtract(this Vector2DInt vector, Vector2DInt vectorToSubtract) => Vector2DInt.Subtract(vector, vectorToSubtract);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Multiply(Vector2DInt, int)" />
|
||||||
|
public static Vector2DInt Multiply(this Vector2DInt vector, int value) => Vector2DInt.Multiply(vector, value);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Divide(Vector2DInt, int)" />
|
||||||
|
public static Vector2DInt Divide(this Vector2DInt vector, int value) => Vector2DInt.Divide(vector, value);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Abs(Vector2DInt)" />
|
||||||
|
public static Vector2DInt Abs(this Vector2DInt vector) => Vector2DInt.Abs(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.FromTo(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static Vector2DInt FromTo(this Vector2DInt from, Vector2DInt to) => Vector2DInt.FromTo(from, to);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Scale(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static Vector2DInt Scale(this Vector2DInt vector, Vector2DInt scale) => Vector2DInt.Scale(vector, scale);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Perpendicular(Vector2DInt)" />
|
||||||
|
public static Vector2DInt Perpendicular(this Vector2DInt vector) => Vector2DInt.Perpendicular(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Min(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static Vector2DInt Min(this Vector2DInt left, Vector2DInt right) => Vector2DInt.Min(left, right);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Max(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static Vector2DInt Max(this Vector2DInt left, Vector2DInt right) => Vector2DInt.Max(left, right);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Clamp(Vector2DInt, Vector2DInt,Vector2DInt)" />
|
||||||
|
public static Vector2DInt Clamp(this Vector2DInt vector, Vector2DInt min, Vector2DInt max) => Vector2DInt.Clamp(vector, min, max);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Lerp(Vector2DInt, Vector2DInt," />
|
||||||
|
public static Vector2DInt Lerp(this Vector2DInt from, Vector2DInt to, int t) => Vector2DInt.Lerp(from, to, t);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Cross(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static int Cross(this Vector2DInt left, Vector2DInt right) => Vector2DInt.Cross(left, right);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2D.Angle(Vector2D, Vector2D)" />
|
||||||
|
public static float AngleBetween(this Vector2D left, Vector2D right) => Vector2D.Angle(left, right);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector2DInt.Dot(Vector2DInt, Vector2DInt)" />
|
||||||
|
public static int Dot(this Vector2DInt left, Vector2DInt right) => Vector2DInt.Dot(left, right);
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,7 +12,7 @@ namespace Engine.Core;
|
|||||||
/// Initializes a new instance of the <see cref="Vector3D"/> struct with the specified positions.
|
/// Initializes a new instance of the <see cref="Vector3D"/> struct with the specified positions.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")]
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")]
|
||||||
public readonly struct Vector3D(float x, float y, float z)
|
public readonly struct Vector3D(float x, float y, float z) : IEquatable<Vector3D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The X coordinate of the <see cref="Vector3D"/>.
|
/// The X coordinate of the <see cref="Vector3D"/>.
|
||||||
@@ -92,6 +94,7 @@ public readonly struct Vector3D(float x, float y, float z)
|
|||||||
|
|
||||||
public static implicit operator System.Numerics.Vector3(Vector3D vector) => new(vector.X, vector.Y, vector.Z);
|
public static implicit operator System.Numerics.Vector3(Vector3D vector) => new(vector.X, vector.Y, vector.Z);
|
||||||
public static implicit operator Vector3D(System.Numerics.Vector3 vector) => new(vector.X, vector.Y, vector.Z);
|
public static implicit operator Vector3D(System.Numerics.Vector3 vector) => new(vector.X, vector.Y, vector.Z);
|
||||||
|
public static implicit operator Vector3D(Vector3DInt vector) => new(vector.X, vector.Y, vector.Z);
|
||||||
public static implicit operator Vector3D(Vector2D vector) => new(vector.X, vector.Y, 0f);
|
public static implicit operator Vector3D(Vector2D vector) => new(vector.X, vector.Y, 0f);
|
||||||
public static implicit operator Vector3D(System.Numerics.Vector2 vector) => new(vector.X, vector.Y, 0f);
|
public static implicit operator Vector3D(System.Numerics.Vector2 vector) => new(vector.X, vector.Y, 0f);
|
||||||
|
|
||||||
@@ -277,6 +280,7 @@ public readonly struct Vector3D(float x, float y, float z)
|
|||||||
/// <param name="obj">The object to compare with the current <see cref="Vector3D"/>.</param>
|
/// <param name="obj">The object to compare with the current <see cref="Vector3D"/>.</param>
|
||||||
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector3D"/>; otherwise, <see cref="false"/>.</returns>
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector3D"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
public override bool Equals(object? obj) => obj is Vector3D vector3D && this == vector3D;
|
public override bool Equals(object? obj) => obj is Vector3D vector3D && this == vector3D;
|
||||||
|
public bool Equals(Vector3D other) => this == other;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a hash code for the <see cref="Vector3D"/>.
|
/// Generates a hash code for the <see cref="Vector3D"/>.
|
||||||
|
|||||||
314
Engine.Core/Primitives/Vector3DInt.cs
Normal file
314
Engine.Core/Primitives/Vector3DInt.cs
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Engine.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a three-dimensional integer vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">X position of the <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="y">Y position of the <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="z">Z position of the <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the <see cref="Vector3DInt"/> struct with the specified positions.
|
||||||
|
/// </remarks>
|
||||||
|
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
|
||||||
|
public readonly struct Vector3DInt(int x, int y, int z) : IEquatable<Vector3DInt>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The X coordinate of the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly int X = x;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Y coordinate of the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly int Y = y;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Z coordinate of the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly int Z = z;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The magnitude (length) of the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float Magnitude => Length(this);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The squared magnitude (length) of the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float MagnitudeSquared => LengthSquared(this);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector3DInt"/> pointing upwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector3DInt Up = new(0, 1, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector3DInt"/> pointing downwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector3DInt Down = new(0, -1, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector3DInt"/> pointing leftwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector3DInt Left = new(-1, 0, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector3DInt"/> pointing rightwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector3DInt Right = new(1, 0, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector3DInt"/> pointing forwards.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector3DInt Forward = new(0, 0, 1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the unit <see cref="Vector3DInt"/> pointing backwards.
|
||||||
|
public readonly static Vector3DInt Backward = new(0, 0, -1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the zero <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector3DInt Zero = new(0, 0, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the <see cref="Vector3DInt"/> with both components equal to 1.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Vector3DInt One = new(1, 1, 1);
|
||||||
|
|
||||||
|
public static Vector3DInt operator -(Vector3DInt vector) => new(0 - vector.X, 0 - vector.Y, 0 - vector.Z);
|
||||||
|
public static Vector3DInt operator +(Vector3DInt left, Vector3DInt right) => new(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||||
|
public static Vector3DInt operator -(Vector3DInt left, Vector3DInt right) => new(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||||
|
public static Vector3DInt operator *(Vector3DInt vector, int value) => new(vector.X * value, vector.Y * value, vector.Z * value);
|
||||||
|
public static Vector3DInt operator *(int value, Vector3DInt vector) => new(vector.X * value, vector.Y * value, vector.Z * value);
|
||||||
|
public static Vector3DInt operator /(Vector3DInt vector, int value) => new(vector.X / value, vector.Y / value, vector.Z / value);
|
||||||
|
public static bool operator ==(Vector3DInt left, Vector3DInt right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z;
|
||||||
|
public static bool operator !=(Vector3DInt left, Vector3DInt right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z;
|
||||||
|
|
||||||
|
public static implicit operator Vector3DInt(Vector3D vector) => new(vector.X.RoundToInt(), vector.Y.RoundToInt(), vector.Z.RoundToInt());
|
||||||
|
public static implicit operator Vector3DInt(Vector2DInt vector) => new(vector.X, vector.Y, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the length of the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The length of the <see cref="Vector3DInt"/>.</returns>
|
||||||
|
public static float Length(Vector3DInt vector) => Math.Sqrt(LengthSquared(vector));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the squared length of the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The squared length of the <see cref="Vector3DInt"/>.</returns>
|
||||||
|
public static float LengthSquared(Vector3DInt vector) => vector.X * vector.X + vector.Y * vector.Y + vector.Z * vector.Z;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the distance between two <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">The start <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="to">The end <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The distance between the two <see cref="Vector3DInt"/>s.</returns>
|
||||||
|
public static float Distance(Vector3DInt from, Vector3DInt to) => Length(FromTo(from, to));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inverts the direction of the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The inverted <see cref="Vector3DInt"/>.</returns>
|
||||||
|
public static Vector3DInt Invert(Vector3DInt vector) => -vector;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds two <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The sum of the two <see cref="Vector3DInt"/>s.</returns>
|
||||||
|
public static Vector3DInt Add(Vector3DInt left, Vector3DInt right) => left + right;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subtracts one <see cref="Vector3DInt"/> from another.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The <see cref="Vector3DInt"/> to subtract from.</param>
|
||||||
|
/// <param name="right">The <see cref="Vector3DInt"/> to subtract.</param>
|
||||||
|
/// <returns>The result of subtracting the second <see cref="Vector3DInt"/> from the first.</returns>
|
||||||
|
public static Vector3DInt Subtract(Vector3DInt left, Vector3DInt right) => left - right;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Multiplies a <see cref="Vector3DInt"/> by a scalar value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="value">The scalar value.</param>
|
||||||
|
/// <returns>The result of multiplying the <see cref="Vector3DInt"/> by the scalar value.</returns>
|
||||||
|
public static Vector3DInt Multiply(Vector3DInt vector, int value) => vector * value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Divides a <see cref="Vector3DInt"/> by a scalar value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="value">The scalar value.</param>
|
||||||
|
/// <returns>The result of dividing the <see cref="Vector3DInt"/> by the scalar value.</returns>
|
||||||
|
public static Vector3DInt Divide(Vector3DInt vector, int value) => vector / value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the absolute value of each component of the vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The <see cref="Vector3DInt"/> with each component's absolute value.</returns>
|
||||||
|
public static Vector3DInt Abs(Vector3DInt vector) => new(Math.Abs(vector.X), Math.Abs(vector.Y), Math.Abs(vector.Z));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the <see cref="Vector3DInt"/> from one point to another.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">The starting point.</param>
|
||||||
|
/// <param name="to">The ending point.</param>
|
||||||
|
/// <returns>The <see cref="Vector3DInt"/> from the starting point to the ending point.</returns>
|
||||||
|
public static Vector3DInt FromTo(Vector3DInt from, Vector3DInt to) => to - from;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scales a <see cref="Vector3DInt"/> by another <see cref="Vector3DInt"/> component-wise.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector3DInt"/> to scale.</param>
|
||||||
|
/// <param name="scale">The <see cref="Vector3DInt"/> containing the scaling factors for each component.</param>
|
||||||
|
/// <returns>The scaled <see cref="Vector3DInt"/>.</returns>
|
||||||
|
public static Vector3DInt Scale(Vector3DInt vector, Vector3DInt scale) => new(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the component-wise minimum of two <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The <see cref="Vector3DInt"/> containing the minimum components from both input <see cref="Vector3DInt"/>s.</returns>
|
||||||
|
public static Vector3DInt Min(Vector3DInt left, Vector3DInt right) => new((left.X < right.X) ? left.X : right.X, (left.Y < right.Y) ? left.Y : right.Y, (left.Z < right.Z) ? left.Z : right.Z);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the component-wise maximum of two <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The <see cref="Vector3DInt"/> containing the maximum components from both input <see cref="Vector3DInt"/>s.</returns>
|
||||||
|
public static Vector3DInt Max(Vector3DInt left, Vector3DInt right) => new((left.X > right.X) ? left.X : right.X, (left.Y > right.Y) ? left.Y : right.Y, (left.Z > right.Z) ? left.Z : right.Z);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clamps each component of a <see cref="Vector3DInt"/> between the corresponding component of two other <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">The <see cref="Vector3DInt"/> to clamp.</param>
|
||||||
|
/// <param name="min">The <see cref="Vector3DInt"/> representing the minimum values for each component.</param>
|
||||||
|
/// <param name="max">The <see cref="Vector3DInt"/> representing the maximum values for each component.</param>
|
||||||
|
/// <returns>A <see cref="Vector3DInt"/> with each component clamped between the corresponding components of the min and max <see cref="Vector3DInt"/>s.</returns>
|
||||||
|
public static Vector3DInt Clamp(Vector3DInt vector, Vector3DInt min, Vector3DInt max) => new(Math.Clamp(vector.X, min.X, max.X), Math.Clamp(vector.Y, min.Y, max.Y), Math.Clamp(vector.Z, min.Z, max.Z));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs linear interpolation between two <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">The starting <see cref="Vector3DInt"/> (t = 0).</param>
|
||||||
|
/// <param name="to">The ending <see cref="Vector3DInt"/> (t = 1).</param>
|
||||||
|
/// <param name="t">The interpolation parameter.</param>
|
||||||
|
/// <returns>The interpolated <see cref="Vector3DInt"/>.</returns>
|
||||||
|
public static Vector3DInt Lerp(Vector3DInt from, Vector3DInt to, int t) => from + FromTo(from, to) * t;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the cross product of two <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The cross product of the two <see cref="Vector3DInt"/>s.</returns>
|
||||||
|
public static Vector3DInt Cross(Vector3DInt left, Vector3DInt right) => new(left.Y * right.Z - left.Z * right.Y, left.Z * right.X - left.X * right.Z, left.X * right.Y - left.Y * right.X);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the angle between two <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The angle between the two <see cref="Vector3DInt"/>s in radians.</returns>
|
||||||
|
public static float Angle(Vector3DInt left, Vector3DInt right) => Math.Acos(Dot(left, right) / (Length(left) * Length(right)));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the dot product of two <see cref="Vector3DInt"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns>The dot product of the two <see cref="Vector3DInt"/>s.</returns>
|
||||||
|
public static int Dot(Vector3DInt left, Vector3DInt right) => left.X * right.X + left.Y * right.Y + left.Z * right.Z;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified object is equal to the current <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The object to compare with the current <see cref="Vector3DInt"/>.</param>
|
||||||
|
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector3DInt"/>; otherwise, <see cref="false"/>.</returns>
|
||||||
|
public override bool Equals(object? obj) => obj is Vector3DInt vector3D && this == vector3D;
|
||||||
|
public bool Equals(Vector3DInt other) => this == other;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a hash code for the <see cref="Vector3DInt"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A hash code for the <see cref="Vector3DInt"/>.</returns>
|
||||||
|
public override int GetHashCode() => System.HashCode.Combine(X, Y, Z);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the <see cref="Vector3DInt"/> to its string representation.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A string representation of the <see cref="Vector3DInt"/>.</returns>
|
||||||
|
public override string ToString() => $"{nameof(Vector3DInt)}({X}, {Y}, {Z})";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for <see cref="Vector3DInt"/> type.
|
||||||
|
/// </summary>
|
||||||
|
public static class Vector3DIntExtensions
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Length(Vector3DInt)" />
|
||||||
|
public static float Length(this Vector3DInt vector) => Vector3DInt.Length(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.LengthSquared(Vector3DInt)" />
|
||||||
|
public static float LengthSquared(this Vector3DInt vector) => Vector3DInt.LengthSquared(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Distance(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static float Distance(this Vector3DInt from, Vector3DInt to) => Vector3DInt.Distance(from, to);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Invert(Vector3DInt)" />
|
||||||
|
public static Vector3DInt Invert(this Vector3DInt vector) => Vector3DInt.Invert(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Add(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static Vector3DInt Add(this Vector3DInt vector, Vector3DInt vectorToAdd) => Vector3DInt.Add(vector, vectorToAdd);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Subtract(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static Vector3DInt Subtract(this Vector3DInt vector, Vector3DInt vectorToSubtract) => Vector3DInt.Subtract(vector, vectorToSubtract);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Multiply(Vector3DInt, int)" />
|
||||||
|
public static Vector3DInt Multiply(this Vector3DInt vector, int value) => Vector3DInt.Multiply(vector, value);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Divide(Vector3DInt, int)" />
|
||||||
|
public static Vector3DInt Divide(this Vector3DInt vector, int value) => Vector3DInt.Divide(vector, value);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Abs(Vector3DInt)" />
|
||||||
|
public static Vector3DInt Abs(this Vector3DInt vector) => Vector3DInt.Abs(vector);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.FromTo(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static Vector3DInt FromTo(this Vector3DInt from, Vector3DInt to) => Vector3DInt.FromTo(from, to);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Scale(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static Vector3DInt Scale(this Vector3DInt vector, Vector3DInt scale) => Vector3DInt.Scale(vector, scale);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Min(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static Vector3DInt Min(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Min(left, right);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Max(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static Vector3DInt Max(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Max(left, right);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Clamp(Vector3DInt, Vector3DInt, Vector3DInt)" />
|
||||||
|
public static Vector3DInt Clamp(this Vector3DInt vector, Vector3DInt min, Vector3DInt max) => Vector3DInt.Clamp(vector, min, max);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Lerp(Vector3DInt, Vector3DInt, int)" />
|
||||||
|
public static Vector3DInt Lerp(this Vector3DInt from, Vector3DInt to, int t) => Vector3DInt.Lerp(from, to, t);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Cross(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static Vector3DInt Cross(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Cross(left, right);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Angle(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static float AngleBetween(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Angle(left, right);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Vector3DInt.Dot(Vector3DInt, Vector3DInt)" />
|
||||||
|
public static int Dot(this Vector3DInt left, Vector3DInt right) => Vector3DInt.Dot(left, right);
|
||||||
|
}
|
||||||
@@ -5,11 +5,12 @@ namespace Engine.Core;
|
|||||||
public class DrawManager : Behaviour
|
public class DrawManager : Behaviour
|
||||||
{
|
{
|
||||||
// We use Descending order because draw calls are running from last to first
|
// We use Descending order because draw calls are running from last to first
|
||||||
private static Comparer<IBehaviour> SortByDescendingPriority() => Comparer<IBehaviour>.Create((x, y) => y.Priority.CompareTo(x.Priority));
|
private static Comparer<int> SortByDescendingPriority() => Comparer<int>.Create((x, y) => y.CompareTo(x));
|
||||||
|
private static System.Func<IBehaviour, int> GetPriority() => (b) => b.Priority;
|
||||||
|
|
||||||
private readonly ActiveBehaviourCollectorSorted<IPreDraw> preDrawEntities = new() { SortBy = SortByDescendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IPreDraw> preDrawEntities = new(GetPriority(), SortByDescendingPriority());
|
||||||
private readonly ActiveBehaviourCollectorSorted<IDraw> drawEntities = new() { SortBy = SortByDescendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IDraw> drawEntities = new(GetPriority(), SortByDescendingPriority());
|
||||||
private readonly ActiveBehaviourCollectorSorted<IPostDraw> postDrawEntities = new() { SortBy = SortByDescendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IPostDraw> postDrawEntities = new(GetPriority(), SortByDescendingPriority());
|
||||||
|
|
||||||
private void OnPreDraw(IUniverse sender)
|
private void OnPreDraw(IUniverse sender)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ namespace Engine.Core;
|
|||||||
public class UniverseEntranceManager : Behaviour
|
public class UniverseEntranceManager : Behaviour
|
||||||
{
|
{
|
||||||
// We use Ascending order because we are using reverse for loop to call them
|
// 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 static Comparer<int> SortByAscendingPriority() => Comparer<int>.Create((x, y) => x.CompareTo(y));
|
||||||
|
private static System.Func<IBehaviour, int> GetPriority() => (b) => b.Priority;
|
||||||
|
|
||||||
private readonly ActiveBehaviourCollectorSorted<IEnterUniverse> enterUniverses = new() { SortBy = SortByAscendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IEnterUniverse> enterUniverses = new(GetPriority(), SortByAscendingPriority());
|
||||||
private readonly ActiveBehaviourCollectorSorted<IExitUniverse> exitUniverses = new() { SortBy = SortByAscendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IExitUniverse> exitUniverses = new(GetPriority(), SortByAscendingPriority());
|
||||||
|
|
||||||
private readonly List<IEnterUniverse> toCallEnterUniverses = new(32);
|
private readonly List<IEnterUniverse> toCallEnterUniverses = new(32);
|
||||||
private readonly List<IExitUniverse> toCallExitUniverses = new(32);
|
private readonly List<IExitUniverse> toCallExitUniverses = new(32);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
@@ -6,13 +5,14 @@ namespace Engine.Core;
|
|||||||
public class UpdateManager : Behaviour
|
public class UpdateManager : Behaviour
|
||||||
{
|
{
|
||||||
// We use Ascending order because we are using reverse for loop to call them
|
// 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 static Comparer<int> SortByAscendingPriority() => Comparer<int>.Create((x, y) => x.CompareTo(y));
|
||||||
|
private static System.Func<IBehaviour, int> GetPriority() => (b) => b.Priority;
|
||||||
|
|
||||||
private readonly ActiveBehaviourCollectorSorted<IFirstFrameUpdate> firstFrameUpdates = new() { SortBy = SortByAscendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IFirstFrameUpdate> firstFrameUpdates = new(GetPriority(), SortByAscendingPriority());
|
||||||
private readonly ActiveBehaviourCollector<ILastFrameUpdate> lastFrameUpdates = new();
|
private readonly ActiveBehaviourCollector<ILastFrameUpdate> lastFrameUpdates = new();
|
||||||
private readonly ActiveBehaviourCollectorSorted<IPreUpdate> preUpdateEntities = new() { SortBy = SortByAscendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IPreUpdate> preUpdateEntities = new(GetPriority(), SortByAscendingPriority());
|
||||||
private readonly ActiveBehaviourCollectorSorted<IUpdate> updateEntities = new() { SortBy = SortByAscendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IUpdate> updateEntities = new(GetPriority(), SortByAscendingPriority());
|
||||||
private readonly ActiveBehaviourCollectorSorted<IPostUpdate> postUpdateEntities = new() { SortBy = SortByAscendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IPostUpdate> postUpdateEntities = new(GetPriority(), SortByAscendingPriority());
|
||||||
|
|
||||||
private readonly List<IFirstFrameUpdate> toCallFirstFrameUpdates = new(32);
|
private readonly List<IFirstFrameUpdate> toCallFirstFrameUpdates = new(32);
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class Universe : BaseEntity, IUniverse
|
|||||||
private readonly Event<IInitializable>.EventHandler delegateOnUniverseObjectFinalize = null!;
|
private readonly Event<IInitializable>.EventHandler delegateOnUniverseObjectFinalize = null!;
|
||||||
private readonly Event<IUniverseObject, IUniverseObject.ExitedUniverseArguments>.EventHandler delegateOnUniverseObjectExitedUniverse = null!;
|
private readonly Event<IUniverseObject, IUniverseObject.ExitedUniverseArguments>.EventHandler delegateOnUniverseObjectExitedUniverse = null!;
|
||||||
|
|
||||||
private readonly List<IUniverseObject> _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL);
|
private readonly FastList<IUniverseObject> _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL);
|
||||||
private float _timeScale = 1f;
|
private float _timeScale = 1f;
|
||||||
|
|
||||||
public Universe()
|
public Universe()
|
||||||
@@ -131,9 +131,10 @@ public class Universe : BaseEntity, IUniverse
|
|||||||
UnscaledTime = engineTime;
|
UnscaledTime = engineTime;
|
||||||
Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale)));
|
Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale)));
|
||||||
|
|
||||||
OnPreUpdate?.Invoke(this, new(Time));
|
IUniverse.UpdateArguments args = new(Time);
|
||||||
OnUpdate?.Invoke(this, new(Time));
|
OnPreUpdate?.Invoke(this, args);
|
||||||
OnPostUpdate?.Invoke(this, new(Time));
|
OnUpdate?.Invoke(this, args);
|
||||||
|
OnPostUpdate?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class UniverseObject : BaseEntity, IUniverseObject
|
|||||||
private IUniverse _universe = null!;
|
private IUniverse _universe = null!;
|
||||||
private IBehaviourController _behaviourController = null!;
|
private IBehaviourController _behaviourController = null!;
|
||||||
private bool _isActive = false;
|
private bool _isActive = false;
|
||||||
private readonly List<IUniverseObject> _children = [];
|
private readonly FastList<IUniverseObject> _children = [];
|
||||||
private IUniverseObject? _parent = null;
|
private IUniverseObject? _parent = null;
|
||||||
|
|
||||||
public IReadOnlyList<IUniverseObject> Children => _children;
|
public IReadOnlyList<IUniverseObject> Children => _children;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using System;
|
|||||||
|
|
||||||
namespace Engine.Core;
|
namespace Engine.Core;
|
||||||
|
|
||||||
public readonly struct UniverseTime(TimeSpan TimeSinceStart, TimeSpan TimeDelta)
|
public readonly record struct UniverseTime(TimeSpan TimeSinceStart, TimeSpan TimeDelta)
|
||||||
{
|
{
|
||||||
public readonly TimeSpan TimeSinceStart = TimeSinceStart;
|
public readonly TimeSpan TimeSinceStart = TimeSinceStart;
|
||||||
public readonly TimeSpan DeltaSpan = TimeDelta;
|
public readonly TimeSpan DeltaSpan = TimeDelta;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Engine.Core;
|
using Engine.Core;
|
||||||
|
|
||||||
namespace Engine.Integration.MonoGame;
|
namespace Engine.Integration.MonoGame;
|
||||||
@@ -6,9 +7,10 @@ namespace Engine.Integration.MonoGame;
|
|||||||
public class LoadContentManager : Behaviour, IFirstFrameUpdate
|
public class LoadContentManager : Behaviour, IFirstFrameUpdate
|
||||||
{
|
{
|
||||||
// We use Ascending order because we are using reverse for loop to call them
|
// 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 static Comparer<int> SortByAscendingPriority() => Comparer<int>.Create((x, y) => x.CompareTo(y));
|
||||||
|
private static System.Func<IBehaviour, int> GetPriority() => (b) => b.Priority;
|
||||||
|
|
||||||
private readonly ActiveBehaviourCollectorSorted<ILoadContent> loadContents = new() { SortBy = SortByAscendingPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, ILoadContent> loadContents = new(GetPriority(), SortByAscendingPriority());
|
||||||
private readonly List<ILoadContent> toCallLoadContents = new(32);
|
private readonly List<ILoadContent> toCallLoadContents = new(32);
|
||||||
|
|
||||||
private MonoGameWindowContainer monoGameWindowContainer = null!;
|
private MonoGameWindowContainer monoGameWindowContainer = null!;
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ namespace Engine.Integration.MonoGame;
|
|||||||
|
|
||||||
public class SpriteBatcher : BehaviourBase, IFirstFrameUpdate, IDraw
|
public class SpriteBatcher : BehaviourBase, IFirstFrameUpdate, IDraw
|
||||||
{
|
{
|
||||||
private static Comparer<IBehaviour> SortByPriority() => Comparer<IBehaviour>.Create((x, y) => y.Priority.CompareTo(x.Priority));
|
private static Comparer<int> SortByPriority() => Comparer<int>.Create((x, y) => y.CompareTo(x));
|
||||||
|
private static System.Func<IBehaviour, int> GetPriority() => (b) => b.Priority;
|
||||||
|
|
||||||
private ISpriteBatch spriteBatch = null!;
|
private ISpriteBatch spriteBatch = null!;
|
||||||
private MonoGameCamera2D camera2D = null!;
|
private MonoGameCamera2D camera2D = null!;
|
||||||
|
|
||||||
private readonly ActiveBehaviourCollectorSorted<IDrawableSprite> drawableSprites = new() { SortBy = SortByPriority() };
|
private readonly ActiveBehaviourCollectorOrdered<int, IDrawableSprite> drawableSprites = new(GetPriority(), SortByPriority());
|
||||||
|
|
||||||
public void FirstActiveFrame()
|
public void FirstActiveFrame()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ namespace Engine.Integration.MonoGame;
|
|||||||
|
|
||||||
public class TriangleBatcher : BehaviourBase, ITriangleBatch, IFirstFrameUpdate, IDraw
|
public class TriangleBatcher : BehaviourBase, ITriangleBatch, IFirstFrameUpdate, IDraw
|
||||||
{
|
{
|
||||||
private static Comparer<IBehaviour> SortByAscendingPriority() => Comparer<IBehaviour>.Create((x, y) => x.Priority.CompareTo(y.Priority));
|
private static Comparer<int> SortByAscendingPriority() => Comparer<int>.Create((x, y) => x.CompareTo(y));
|
||||||
|
private static System.Func<IBehaviour, int> GetPriority() => (b) => b.Priority;
|
||||||
|
|
||||||
private TriangleBatch triangleBatch = null!;
|
private TriangleBatch triangleBatch = null!;
|
||||||
private MonoGameCamera2D camera2D = null!;
|
private MonoGameCamera2D camera2D = null!;
|
||||||
private readonly ActiveBehaviourCollectorSorted<IDrawableTriangle> drawableShapes = new() { SortBy = SortByAscendingPriority() };
|
|
||||||
|
private readonly ActiveBehaviourCollectorOrdered<int, IDrawableTriangle> drawableShapes = new(GetPriority(), SortByAscendingPriority());
|
||||||
|
|
||||||
public void FirstActiveFrame()
|
public void FirstActiveFrame()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public class TriangleBatch : ITriangleBatch
|
|||||||
this.graphicsDevice = graphicsDevice;
|
this.graphicsDevice = graphicsDevice;
|
||||||
basicEffect = new(graphicsDevice);
|
basicEffect = new(graphicsDevice);
|
||||||
basicEffect.VertexColorEnabled = true;
|
basicEffect.VertexColorEnabled = true;
|
||||||
|
vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), 1024, BufferUsage.WriteOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(Triangle triangle, ColorRGBA colorRGBA)
|
public void Draw(Triangle triangle, ColorRGBA colorRGBA)
|
||||||
@@ -64,7 +65,6 @@ public class TriangleBatch : ITriangleBatch
|
|||||||
graphicsDevice.RasterizerState = rasterizerState;
|
graphicsDevice.RasterizerState = rasterizerState;
|
||||||
basicEffect.Projection = _projection;
|
basicEffect.Projection = _projection;
|
||||||
basicEffect.View = _view;
|
basicEffect.View = _view;
|
||||||
vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), 1024, BufferUsage.WriteOnly);
|
|
||||||
vertexBuffer.SetData(vertices);
|
vertexBuffer.SetData(vertices);
|
||||||
|
|
||||||
graphicsDevice.SetVertexBuffer(vertexBuffer);
|
graphicsDevice.SetVertexBuffer(vertexBuffer);
|
||||||
|
|||||||
@@ -17,11 +17,12 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D
|
|||||||
protected readonly ICollisionResolver2D collisionResolver = null!;
|
protected readonly ICollisionResolver2D collisionResolver = null!;
|
||||||
protected readonly IRaycastResolver2D raycastResolver = null!;
|
protected readonly IRaycastResolver2D raycastResolver = null!;
|
||||||
|
|
||||||
private static Comparer<IBehaviour> SortByPriority() => Comparer<IBehaviour>.Create((x, y) => y.Priority.CompareTo(x.Priority));
|
private static Comparer<int> SortByPriority() => Comparer<int>.Create((x, y) => y.CompareTo(x));
|
||||||
protected ActiveBehaviourCollectorSorted<IPrePhysicsUpdate> physicsPreUpdateCollector = new() { SortBy = SortByPriority() };
|
private static System.Func<IBehaviour, int> GetPriority() => (b) => b.Priority;
|
||||||
protected ActiveBehaviourCollectorSorted<IPhysicsUpdate> physicsUpdateCollector = new() { SortBy = SortByPriority() };
|
protected ActiveBehaviourCollectorOrdered<int, IPrePhysicsUpdate> physicsPreUpdateCollector = new(GetPriority(), SortByPriority());
|
||||||
protected ActiveBehaviourCollectorSorted<IPhysicsIteration> physicsIterationCollector = new() { SortBy = SortByPriority() };
|
protected ActiveBehaviourCollectorOrdered<int, IPhysicsUpdate> physicsUpdateCollector = new(GetPriority(), SortByPriority());
|
||||||
protected ActiveBehaviourCollectorSorted<IPostPhysicsUpdate> physicsPostUpdateCollector = new() { SortBy = SortByPriority() };
|
protected ActiveBehaviourCollectorOrdered<int, IPhysicsIteration> physicsIterationCollector = new(GetPriority(), SortByPriority());
|
||||||
|
protected ActiveBehaviourCollectorOrdered<int, IPostPhysicsUpdate> physicsPostUpdateCollector = new(GetPriority(), SortByPriority());
|
||||||
protected BehaviourCollector<IRigidBody2D> rigidBodyCollector = new();
|
protected BehaviourCollector<IRigidBody2D> rigidBodyCollector = new();
|
||||||
protected BehaviourCollector<ICollider2D> colliderCollector = new();
|
protected BehaviourCollector<ICollider2D> colliderCollector = new();
|
||||||
|
|
||||||
|
|||||||
Submodule Engine.Serializers/YamlDotNet deleted from 62048d7abe
Reference in New Issue
Block a user