179 lines
5.2 KiB
C#
179 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
using Syntriax.Engine.Core.Abstract;
|
|
using Syntriax.Engine.Core.Exceptions;
|
|
using Syntriax.Engine.Core.Factory;
|
|
|
|
namespace Syntriax.Engine.Core;
|
|
|
|
public class GameManager : IEntity
|
|
{
|
|
public Action<IInitialize>? OnInitialized { get; set; } = null;
|
|
public Action<IInitialize>? OnFinalized { get; set; } = null;
|
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
|
public Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; } = null;
|
|
|
|
|
|
private IList<IGameObject> _gameObjects = new List<IGameObject>(Constants.GAME_OBJECTS_SIZE_INITIAL);
|
|
private IList<IDrawable> _drawables = new List<IDrawable>(Constants.DRAWABLE_OBJECTS_SIZE_INITIAL);
|
|
|
|
private IStateEnable _stateEnable = null!;
|
|
private GameObjectFactory _gameObjectFactory = null!;
|
|
private bool _initialized = false;
|
|
|
|
private GameObjectFactory GameObjectFactory
|
|
{
|
|
get
|
|
{
|
|
if (_gameObjectFactory is null)
|
|
_gameObjectFactory = new GameObjectFactory();
|
|
return _gameObjectFactory;
|
|
}
|
|
}
|
|
|
|
public bool Initialized => _initialized;
|
|
public IList<IGameObject> GameObjects => _gameObjects;
|
|
public IStateEnable StateEnable { get { if (_stateEnable is null) Assign(new StateEnableFactory().Instantiate(this)); return _stateEnable; } }
|
|
|
|
public void RegisterGameObject(IGameObject gameObject)
|
|
{
|
|
if (_gameObjects.Contains(gameObject))
|
|
throw new Exception($"{nameof(IGameComponent)} named {gameObject.Name} is already registered to the {nameof(GameManager)}.");
|
|
|
|
Register(gameObject);
|
|
}
|
|
|
|
public T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject
|
|
{
|
|
T gameObject = GameObjectFactory.Instantiate<T>(args);
|
|
Register(gameObject);
|
|
return 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 bool Initialize()
|
|
{
|
|
if (Initialized)
|
|
return false;
|
|
|
|
NotAssignedException.Check(this, StateEnable);
|
|
|
|
foreach (var gameObject in GameObjects)
|
|
gameObject.Initialize();
|
|
|
|
OnInitialized?.Invoke(this);
|
|
return true;
|
|
}
|
|
|
|
public bool Finalize()
|
|
{
|
|
if (!Initialized)
|
|
return false;
|
|
|
|
for (int i = GameObjects.Count; i >= 0; i--)
|
|
GameObjects[i].Finalize();
|
|
|
|
OnFinalized?.Invoke(this);
|
|
return true;
|
|
}
|
|
|
|
public bool Assign(IStateEnable stateEnable)
|
|
{
|
|
if (Initialized)
|
|
return false;
|
|
|
|
_stateEnable = stateEnable;
|
|
OnStateEnableAssigned?.Invoke(this);
|
|
return true;
|
|
}
|
|
|
|
public bool Unassign()
|
|
{
|
|
if (Initialized)
|
|
return false;
|
|
|
|
_stateEnable = null!;
|
|
OnUnassigned?.Invoke(this);
|
|
return true;
|
|
}
|
|
|
|
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<Behaviours.IDrawBehaviour>(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<IDrawable>(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<IDrawable>(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);
|
|
}
|
|
}
|