2023-11-24 16:58:07 +03:00
|
|
|
using System;
|
2024-01-23 12:06:14 +03:00
|
|
|
using System.Collections;
|
2023-11-24 16:58:07 +03:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
2023-11-23 22:07:49 +03:00
|
|
|
using Syntriax.Engine.Core.Abstract;
|
2023-11-24 16:37:09 +03:00
|
|
|
using Syntriax.Engine.Core.Exceptions;
|
2023-11-23 22:07:49 +03:00
|
|
|
using Syntriax.Engine.Core.Factory;
|
|
|
|
|
|
|
|
namespace Syntriax.Engine.Core;
|
|
|
|
|
2024-01-27 21:05:56 +03:00
|
|
|
[System.Diagnostics.DebuggerDisplay("GameObject Count: {_gameObjects.Count}")]
|
2024-02-02 12:11:51 +03:00
|
|
|
public class GameManager : BaseEntity, IGameManager
|
2023-11-23 22:07:49 +03:00
|
|
|
{
|
2024-10-25 23:10:20 +03:00
|
|
|
public event IGameManager.OnUpdateDelegate? OnUpdate = null;
|
|
|
|
public event IGameManager.OnPreDawDelegate? OnPreDraw = null;
|
|
|
|
|
2024-07-15 01:13:39 +03:00
|
|
|
public event IGameManager.OnGameObjectRegisteredDelegate? OnGameObjectRegistered = null;
|
|
|
|
public event IGameManager.OnGameObjectUnRegisteredDelegate? OnGameObjectUnRegistered = null;
|
2024-10-22 22:02:38 +03:00
|
|
|
public event IGameManager.OnHierarchyObjectRegisteredDelegate? OnHierarchyObjectRegistered = null;
|
|
|
|
public event IGameManager.OnHierarchyObjectUnRegisteredDelegate? OnHierarchyObjectUnRegistered = null;
|
2023-11-24 11:52:14 +03:00
|
|
|
|
2024-01-30 12:08:21 +03:00
|
|
|
private readonly List<IGameObject> _gameObjects = new(Constants.GAME_OBJECTS_SIZE_INITIAL);
|
2024-10-22 22:02:38 +03:00
|
|
|
private readonly List<IHierarchyObject> _hierarchyObjects = new(Constants.GAME_OBJECTS_SIZE_INITIAL);
|
2023-11-23 22:07:49 +03:00
|
|
|
|
|
|
|
private GameObjectFactory _gameObjectFactory = null!;
|
2023-11-24 11:52:14 +03:00
|
|
|
|
2023-11-23 22:07:49 +03:00
|
|
|
private GameObjectFactory GameObjectFactory
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
if (_gameObjectFactory is null)
|
|
|
|
_gameObjectFactory = new GameObjectFactory();
|
|
|
|
return _gameObjectFactory;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-30 12:08:21 +03:00
|
|
|
public IReadOnlyList<IGameObject> GameObjects => _gameObjects;
|
2024-10-22 22:02:38 +03:00
|
|
|
public IReadOnlyList<IHierarchyObject> HierarchyObjects => _hierarchyObjects;
|
2024-01-30 12:08:21 +03:00
|
|
|
|
2024-02-02 12:11:51 +03:00
|
|
|
public override IStateEnable StateEnable
|
2023-11-27 11:11:58 +03:00
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
2024-02-02 12:11:51 +03:00
|
|
|
if (base.StateEnable is null)
|
2023-11-27 11:11:58 +03:00
|
|
|
{
|
|
|
|
Assign(new StateEnableFactory().Instantiate(this));
|
2024-02-02 12:11:51 +03:00
|
|
|
if (base.StateEnable is null)
|
|
|
|
throw NotAssignedException.From(this, base.StateEnable);
|
2023-11-27 11:11:58 +03:00
|
|
|
}
|
|
|
|
|
2024-02-02 12:11:51 +03:00
|
|
|
return base.StateEnable;
|
2023-11-27 11:11:58 +03:00
|
|
|
}
|
|
|
|
}
|
2023-11-23 22:07:49 +03:00
|
|
|
|
2024-10-26 13:46:04 +03:00
|
|
|
public void Register(IHierarchyObject hierarchyObject)
|
2023-11-23 22:07:49 +03:00
|
|
|
{
|
2024-10-26 13:46:04 +03:00
|
|
|
if (_hierarchyObjects.Contains(hierarchyObject))
|
|
|
|
throw new Exception($"{nameof(IHierarchyObject)} named {hierarchyObject.Name} is already registered to the {nameof(GameManager)}.");
|
2023-11-23 22:07:49 +03:00
|
|
|
|
2024-10-26 13:46:04 +03:00
|
|
|
if (hierarchyObject is IGameObject gameObject)
|
|
|
|
Register(gameObject);
|
|
|
|
else
|
|
|
|
{
|
2024-11-03 19:58:57 +03:00
|
|
|
if (!hierarchyObject.Initialize())
|
|
|
|
throw new Exception($"{nameof(hierarchyObject)} can't be initialized");
|
|
|
|
|
2024-10-26 13:46:04 +03:00
|
|
|
_hierarchyObjects.Add(hierarchyObject);
|
|
|
|
hierarchyObject.EnterHierarchy(this);
|
2024-10-26 22:45:24 +03:00
|
|
|
|
2024-10-26 13:46:04 +03:00
|
|
|
OnHierarchyObjectRegistered?.Invoke(this, hierarchyObject);
|
|
|
|
}
|
2023-11-23 22:07:49 +03:00
|
|
|
}
|
|
|
|
|
2023-11-24 09:45:10 +03:00
|
|
|
public T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject
|
2023-11-23 22:07:49 +03:00
|
|
|
{
|
2023-11-24 09:45:10 +03:00
|
|
|
T gameObject = GameObjectFactory.Instantiate<T>(args);
|
2023-11-24 11:42:51 +03:00
|
|
|
Register(gameObject);
|
2023-11-23 22:07:49 +03:00
|
|
|
return gameObject;
|
|
|
|
}
|
|
|
|
|
2024-10-26 13:46:04 +03:00
|
|
|
public void Remove(IHierarchyObject hierarchyObject)
|
2023-11-23 22:07:49 +03:00
|
|
|
{
|
2024-10-26 13:46:04 +03:00
|
|
|
if (!_hierarchyObjects.Contains(hierarchyObject))
|
|
|
|
throw new Exception($"{nameof(IHierarchyObject)} named {hierarchyObject.Name} is not registered to the {nameof(GameManager)}.");
|
2023-11-23 22:07:49 +03:00
|
|
|
|
2024-10-26 13:46:04 +03:00
|
|
|
if (hierarchyObject is IGameObject gameObject)
|
|
|
|
Unregister(gameObject);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_hierarchyObjects.Remove(hierarchyObject);
|
|
|
|
hierarchyObject.ExitHierarchy();
|
2024-10-26 22:45:24 +03:00
|
|
|
|
|
|
|
if (!hierarchyObject.Finalize())
|
|
|
|
throw new Exception($"{nameof(hierarchyObject)} can't be finalized");
|
|
|
|
|
2024-10-26 13:46:04 +03:00
|
|
|
OnHierarchyObjectUnRegistered?.Invoke(this, hierarchyObject);
|
|
|
|
}
|
2023-11-24 11:42:51 +03:00
|
|
|
}
|
|
|
|
|
2024-02-02 12:11:51 +03:00
|
|
|
protected override void InitializeInternal()
|
2023-11-24 11:42:51 +03:00
|
|
|
{
|
2024-02-02 12:11:51 +03:00
|
|
|
base.InitializeInternal();
|
2023-11-24 16:37:09 +03:00
|
|
|
NotAssignedException.Check(this, StateEnable);
|
|
|
|
|
2023-11-24 11:42:51 +03:00
|
|
|
foreach (var gameObject in GameObjects)
|
|
|
|
gameObject.Initialize();
|
2023-11-24 11:52:14 +03:00
|
|
|
}
|
|
|
|
|
2024-02-02 12:11:51 +03:00
|
|
|
protected override void FinalizeInternal()
|
2023-11-24 11:52:14 +03:00
|
|
|
{
|
2024-02-02 12:11:51 +03:00
|
|
|
base.FinalizeInternal();
|
2023-11-24 11:52:14 +03:00
|
|
|
for (int i = GameObjects.Count; i >= 0; i--)
|
|
|
|
GameObjects[i].Finalize();
|
2023-11-24 17:03:21 +03:00
|
|
|
}
|
|
|
|
|
2024-01-23 12:06:21 +03:00
|
|
|
public void Update(EngineTime time)
|
2023-11-24 11:42:51 +03:00
|
|
|
{
|
2024-01-23 12:06:21 +03:00
|
|
|
Time.SetTime(time);
|
2024-09-27 18:38:24 +03:00
|
|
|
for (int i = 0; i < GameObjects.Count; i++)
|
|
|
|
GameObjects[i].BehaviourController.Update();
|
2024-10-25 23:10:20 +03:00
|
|
|
|
|
|
|
OnUpdate?.Invoke(this, time);
|
2023-11-24 11:42:51 +03:00
|
|
|
}
|
|
|
|
|
2024-01-22 22:45:40 +03:00
|
|
|
public void PreDraw()
|
2023-11-24 11:42:51 +03:00
|
|
|
{
|
2024-09-27 18:38:24 +03:00
|
|
|
for (int i = 0; i < GameObjects.Count; i++)
|
|
|
|
GameObjects[i].BehaviourController.UpdatePreDraw();
|
2024-10-25 23:10:20 +03:00
|
|
|
|
|
|
|
OnPreDraw?.Invoke(this);
|
2023-11-24 11:42:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
|
2024-10-22 22:02:38 +03:00
|
|
|
private void Register(IGameObject gameObject)
|
|
|
|
{
|
2024-10-26 13:46:04 +03:00
|
|
|
if (_gameObjects.Contains(gameObject))
|
|
|
|
throw new Exception($"{nameof(IGameObject)} named {gameObject.Name} is already registered to the {nameof(GameManager)}.");
|
|
|
|
|
2024-01-23 12:08:50 +03:00
|
|
|
gameObject.OnFinalized += OnGameObjectFinalize;
|
2024-10-22 22:02:38 +03:00
|
|
|
gameObject.OnExitedHierarchy += OnGameObjectExitedHierarchy;
|
2023-11-24 11:42:51 +03:00
|
|
|
|
2024-11-03 19:58:57 +03:00
|
|
|
if (!gameObject.Initialize())
|
|
|
|
throw new Exception($"{nameof(gameObject)} can't be initialized");
|
|
|
|
|
2024-11-10 20:21:53 +03:00
|
|
|
foreach (ITransform child in gameObject.Transform.Children)
|
|
|
|
Register(child.GameObject);
|
|
|
|
|
2024-01-23 12:08:50 +03:00
|
|
|
_gameObjects.Add(gameObject);
|
2024-10-22 22:02:38 +03:00
|
|
|
_hierarchyObjects.Add(gameObject);
|
|
|
|
|
|
|
|
if (!gameObject.EnterHierarchy(this))
|
|
|
|
throw new Exception($"{nameof(gameObject)} can't enter the hierarchy");
|
|
|
|
|
|
|
|
OnHierarchyObjectRegistered?.Invoke(this, gameObject);
|
2024-01-23 12:08:50 +03:00
|
|
|
OnGameObjectRegistered?.Invoke(this, gameObject);
|
2023-11-23 22:07:49 +03:00
|
|
|
}
|
2023-11-24 11:42:51 +03:00
|
|
|
|
2024-01-23 12:08:50 +03:00
|
|
|
private void Unregister(IGameObject gameObject)
|
2023-11-24 11:42:51 +03:00
|
|
|
{
|
2024-10-26 13:46:04 +03:00
|
|
|
if (!_gameObjects.Contains(gameObject))
|
|
|
|
throw new Exception($"{nameof(IGameObject)} named {gameObject.Name} is not registered to the {nameof(GameManager)}.");
|
|
|
|
|
2024-01-23 12:08:50 +03:00
|
|
|
gameObject.OnFinalized -= OnGameObjectFinalize;
|
2024-10-22 22:02:38 +03:00
|
|
|
gameObject.OnExitedHierarchy -= OnGameObjectExitedHierarchy;
|
2023-11-24 11:42:51 +03:00
|
|
|
|
2024-11-10 19:18:44 +03:00
|
|
|
foreach (ITransform child in gameObject.Transform.Children)
|
|
|
|
Unregister(child.GameObject);
|
|
|
|
|
2024-01-23 12:08:50 +03:00
|
|
|
_gameObjects.Remove(gameObject);
|
2024-10-22 22:02:38 +03:00
|
|
|
_hierarchyObjects.Remove(gameObject);
|
|
|
|
|
|
|
|
if (!gameObject.ExitHierarchy())
|
|
|
|
throw new Exception($"{nameof(gameObject)} can't exit the hierarchy");
|
|
|
|
|
2024-10-26 22:45:24 +03:00
|
|
|
if (!gameObject.Finalize())
|
|
|
|
throw new Exception($"{nameof(gameObject)} can't be finalized");
|
|
|
|
|
2024-10-22 22:02:38 +03:00
|
|
|
OnHierarchyObjectUnRegistered?.Invoke(this, gameObject);
|
2024-01-23 12:08:50 +03:00
|
|
|
OnGameObjectUnRegistered?.Invoke(this, gameObject);
|
2023-11-24 11:42:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
private void OnGameObjectFinalize(IInitialize initialize)
|
|
|
|
{
|
|
|
|
if (initialize is IGameObject gameObject)
|
|
|
|
Unregister(gameObject);
|
|
|
|
}
|
2024-01-23 12:06:14 +03:00
|
|
|
|
2024-11-03 20:13:25 +03:00
|
|
|
private void OnGameObjectExitedHierarchy(IHierarchyObject sender, IGameManager gameManager)
|
2024-10-22 22:02:38 +03:00
|
|
|
{
|
|
|
|
if (sender is IGameObject gameObject)
|
|
|
|
Unregister(gameObject);
|
|
|
|
}
|
2023-11-23 22:07:49 +03:00
|
|
|
}
|