refactor!: renamed GameManager to Universe and HierarchyObject to UniverseObject
This commit is contained in:
141
Engine.Core/Universe.cs
Normal file
141
Engine.Core/Universe.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Syntriax.Engine.Core.Abstract;
|
||||
|
||||
namespace Syntriax.Engine.Core;
|
||||
|
||||
[System.Diagnostics.DebuggerDisplay("UniverseObject Count: {_universeObjects.Count}")]
|
||||
public class Universe : BaseEntity, IUniverse
|
||||
{
|
||||
public event IUniverse.UpdateEventHandler? OnPreUpdate = null;
|
||||
public event IUniverse.UpdateEventHandler? OnUpdate = null;
|
||||
public event IUniverse.PreDrawEventHandler? OnPreDraw = null;
|
||||
|
||||
public event IUniverse.UniverseObjectRegisteredEventHandler? OnUniverseObjectRegistered = null;
|
||||
public event IUniverse.UniverseObjectUnRegisteredEventHandler? OnUniverseObjectUnRegistered = null;
|
||||
|
||||
private readonly List<IUniverseObject> _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL);
|
||||
private float _timeScale = 1f;
|
||||
|
||||
public IReadOnlyList<IUniverseObject> UniverseObjects => _universeObjects;
|
||||
|
||||
public UniverseTime Time { get; private set; } = new();
|
||||
public UniverseTime UnscaledTime { get; private set; } = new();
|
||||
public float TimeScale
|
||||
{
|
||||
get => _timeScale;
|
||||
set => _timeScale = value.Max(0f);
|
||||
}
|
||||
|
||||
public void Register(IUniverseObject universeObject)
|
||||
{
|
||||
if (_universeObjects.Contains(universeObject))
|
||||
throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is already registered to the {nameof(Universe)}.");
|
||||
|
||||
universeObject.OnFinalized += OnUniverseObjectFinalize;
|
||||
universeObject.OnExitedUniverse += OnUniverseObjectExitedUniverse;
|
||||
|
||||
if (!universeObject.Initialize())
|
||||
throw new Exception($"{universeObject.Name} can't be initialized");
|
||||
|
||||
for (int i = 0; i < universeObject.Children.Count; i++)
|
||||
Register(universeObject.Children[i]);
|
||||
|
||||
_universeObjects.Add(universeObject);
|
||||
|
||||
if (!universeObject.EnterUniverse(this))
|
||||
throw new Exception($"{universeObject.Name} can't enter the universe");
|
||||
|
||||
OnUniverseObjectRegistered?.InvokeSafe(this, universeObject);
|
||||
}
|
||||
|
||||
public T InstantiateUniverseObject<T>(params object?[]? args) where T : class, IUniverseObject
|
||||
{
|
||||
T universeObject = Factory.UniverseObjectFactory.Instantiate<T>(args);
|
||||
Register(universeObject);
|
||||
return universeObject;
|
||||
}
|
||||
|
||||
public void Remove(IUniverseObject universeObject)
|
||||
{
|
||||
universeObject.SetParent(null);
|
||||
RemoveIncursive(universeObject);
|
||||
}
|
||||
|
||||
private void RemoveIncursive(IUniverseObject universeObject)
|
||||
{
|
||||
if (!_universeObjects.Contains(universeObject))
|
||||
throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is not registered to the {nameof(Universe)}.");
|
||||
|
||||
universeObject.OnFinalized -= OnUniverseObjectFinalize;
|
||||
universeObject.OnExitedUniverse -= OnUniverseObjectExitedUniverse;
|
||||
|
||||
for (int i = universeObject.Children.Count - 1; i >= 0; i--)
|
||||
Remove(universeObject.Children[i]);
|
||||
|
||||
_universeObjects.Remove(universeObject);
|
||||
|
||||
if (!universeObject.ExitUniverse())
|
||||
throw new Exception($"{universeObject.Name} can't exit the universe");
|
||||
|
||||
if (!universeObject.Finalize())
|
||||
throw new Exception($"{universeObject.Name} can't be finalized");
|
||||
|
||||
OnUniverseObjectUnRegistered?.InvokeSafe(this, universeObject);
|
||||
}
|
||||
|
||||
protected override void InitializeInternal()
|
||||
{
|
||||
foreach (IUniverseObject universeObject in UniverseObjects)
|
||||
universeObject.Initialize();
|
||||
}
|
||||
|
||||
protected override void FinalizeInternal()
|
||||
{
|
||||
base.FinalizeInternal();
|
||||
for (int i = UniverseObjects.Count; i >= 0; i--)
|
||||
UniverseObjects[i].Finalize();
|
||||
}
|
||||
|
||||
public void Update(UniverseTime engineTime)
|
||||
{
|
||||
Debug.AssertHelpers.AssertInitialized(this);
|
||||
|
||||
UnscaledTime = engineTime;
|
||||
Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale)));
|
||||
|
||||
OnPreUpdate?.InvokeSafe(this, Time);
|
||||
|
||||
for (int i = 0; i < UniverseObjects.Count; i++)
|
||||
UniverseObjects[i].BehaviourController.Update();
|
||||
|
||||
OnUpdate?.InvokeSafe(this, Time);
|
||||
}
|
||||
|
||||
public void PreDraw()
|
||||
{
|
||||
Debug.AssertHelpers.AssertInitialized(this);
|
||||
|
||||
for (int i = 0; i < UniverseObjects.Count; i++)
|
||||
UniverseObjects[i].BehaviourController.UpdatePreDraw();
|
||||
|
||||
OnPreDraw?.InvokeSafe(this);
|
||||
}
|
||||
|
||||
private void OnUniverseObjectFinalize(IInitializable initializable)
|
||||
{
|
||||
if (initializable is IUniverseObject universeObject)
|
||||
Remove(universeObject);
|
||||
}
|
||||
|
||||
private void OnUniverseObjectExitedUniverse(IUniverseObject sender, IUniverse universe)
|
||||
{
|
||||
if (sender is IUniverseObject universeObject)
|
||||
Remove(universeObject);
|
||||
}
|
||||
|
||||
public IEnumerator<IUniverseObject> GetEnumerator() => _universeObjects.GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator() => _universeObjects.GetEnumerator();
|
||||
}
|
Reference in New Issue
Block a user