diff --git a/Engine.Core/GameManager.cs b/Engine.Core/GameManager.cs index 02e13e8..8fafe00 100644 --- a/Engine.Core/GameManager.cs +++ b/Engine.Core/GameManager.cs @@ -1,7 +1,5 @@ -using System; -using System.Collections.Generic; - using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Factory; @@ -10,8 +8,8 @@ namespace Syntriax.Engine.Core; public class GameManager { - public Game Game { get; private set; } = null!; private IList _gameObjects = new List(Constants.GAME_OBJECTS_SIZE_INITIAL); + private IList _drawables = new List(Constants.DRAWABLE_OBJECTS_SIZE_INITIAL); private GameObjectFactory _gameObjectFactory = null!; private GameObjectFactory GameObjectFactory @@ -31,32 +29,95 @@ public class GameManager if (_gameObjects.Contains(gameObject)) throw new Exception($"{nameof(IGameComponent)} named {gameObject.Name} is already registered to the {nameof(GameManager)}."); - _gameObjects.Add(gameObject); + Register(gameObject); } public T InstantiateGameObject(params object?[]? args) where T : class, IGameObject { T gameObject = GameObjectFactory.Instantiate(args); - _gameObjects.Add(gameObject); + Register(gameObject); return gameObject; } - // public TGameObject RegisterGameObject() - // where TGameObject : class, IGameObject - // where TTransform : class, ITransform - // where TBehaviourController : class, IBehaviourController - // where TStateEnable : class, IStateEnable - // { - // TGameObject gameObject = Factory.GameObjectFactory.Get(); - // _gameObjects.Add(gameObject); - // return gameObject; - // } - - public void RemoveGameObject(IGameObject gameObject) + public IGameObject RemoveGameObject(IGameObject gameObject) { if (!_gameObjects.Contains(gameObject)) throw new Exception($"{nameof(IGameComponent)} named {gameObject.Name} is not registered to the {nameof(GameManager)}."); + Unregister(gameObject); + return gameObject; + } + + public void Initialize() + { + foreach (var gameObject in GameObjects) + gameObject.Initialize(); + } + + public void Update(GameTime time) + { + foreach (var gameObject in GameObjects) + gameObject.BehaviourController.Update(time); + } + + public void PreDraw(GameTime time) + { + foreach (var gameObject in GameObjects) + gameObject.BehaviourController.UpdatePreDraw(time); + } + + public void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Begin(); + + foreach (var gameObject in GameObjects) + if (gameObject.BehaviourController.TryGetBehaviour(out var drawable)) + drawable.Draw(spriteBatch); + + spriteBatch.End(); + } + + ///////////////////////////////////////////////////////////////// + + private void Unregister(IGameObject gameObject) + { + gameObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdd; + gameObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemove; + gameObject.OnFinalized -= OnGameObjectFinalize; + + if (gameObject.BehaviourController.TryGetBehaviour(out var drawable)) + _drawables.Remove(drawable); + _gameObjects.Remove(gameObject); } + + private void Register(IGameObject gameObject) + { + gameObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdd; + gameObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemove; + gameObject.OnFinalized += OnGameObjectFinalize; + + if (gameObject.BehaviourController.TryGetBehaviour(out var drawable)) + _drawables.Add(drawable); + + _gameObjects.Add(gameObject); + } + + private void OnGameObjectFinalize(IInitialize initialize) + { + if (initialize is IGameObject gameObject) + Unregister(gameObject); + } + + private void OnBehaviourAdd(IBehaviourController controller, IBehaviour behaviour) + { + if (behaviour is IDrawable drawable) + _drawables.Add(drawable); + } + + private void OnBehaviourRemove(IBehaviourController controller, IBehaviour behaviour) + { + if (behaviour is IDrawable drawable) + _drawables.Remove(drawable); + } } diff --git a/Engine.Core/Static/Internal/Constants.cs b/Engine.Core/Static/Internal/Constants.cs index 76ba5d8..2d10f70 100644 --- a/Engine.Core/Static/Internal/Constants.cs +++ b/Engine.Core/Static/Internal/Constants.cs @@ -7,4 +7,5 @@ internal static class Constants { internal static int BEHAVIOURS_SIZE_INITIAL = 16; internal static int GAME_OBJECTS_SIZE_INITIAL = 256; + internal static int DRAWABLE_OBJECTS_SIZE_INITIAL = 256; }