Syntriax.Engine/Engine.Core/GameManager.cs

206 lines
5.7 KiB
C#
Raw Normal View History

2023-11-24 16:58:07 +03:00
using System;
using System.Collections.Generic;
2023-11-23 22:07:49 +03:00
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
2023-11-23 22:07:49 +03:00
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Core.Exceptions;
2023-11-23 22:07:49 +03:00
using Syntriax.Engine.Core.Factory;
namespace Syntriax.Engine.Core;
public class GameManager : IEntity
2023-11-23 22:07:49 +03:00
{
2023-11-27 13:46:01 +03:00
public Action<GameManager>? OnCameraChanged { get; set; } = null;
public Action<IInitialize>? OnInitialized { get; set; } = null;
public Action<IInitialize>? OnFinalized { get; set; } = null;
2023-11-24 17:03:21 +03:00
public Action<IAssignable>? OnUnassigned { get; set; } = null;
public Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; } = null;
2023-11-23 22:07:49 +03:00
private IList<IGameObject> _gameObjects = new List<IGameObject>(Constants.GAME_OBJECTS_SIZE_INITIAL);
2023-11-27 11:06:02 +03:00
private IList<IDisplayable> _drawables = new List<IDisplayable>(Constants.DRAWABLE_OBJECTS_SIZE_INITIAL);
2023-11-23 22:07:49 +03:00
private IStateEnable _stateEnable = null!;
2023-11-23 22:07:49 +03:00
private GameObjectFactory _gameObjectFactory = null!;
private bool _initialized = false;
2023-11-27 13:46:01 +03:00
private ICamera _camera = null!;
2023-11-23 22:07:49 +03:00
private GameObjectFactory GameObjectFactory
{
get
{
if (_gameObjectFactory is null)
_gameObjectFactory = new GameObjectFactory();
return _gameObjectFactory;
}
}
public bool Initialized => _initialized;
2023-11-23 22:07:49 +03:00
public IList<IGameObject> GameObjects => _gameObjects;
public IStateEnable StateEnable
{
get
{
if (_stateEnable is null)
{
Assign(new StateEnableFactory().Instantiate(this));
if (_stateEnable is null)
throw NotAssignedException.From(this, _stateEnable);
}
return _stateEnable;
}
}
2023-11-23 22:07:49 +03:00
2023-11-27 13:46:01 +03:00
public ICamera Camera
{
get => _camera;
set
{
if (_camera == value)
return;
_camera = value;
OnCameraChanged?.Invoke(this);
}
}
2023-11-23 22:07:49 +03:00
public void RegisterGameObject(IGameObject gameObject)
{
if (_gameObjects.Contains(gameObject))
2023-11-27 11:06:02 +03:00
throw new Exception($"{nameof(IGameObject)} named {gameObject.Name} is already registered to the {nameof(GameManager)}.");
2023-11-23 22:07:49 +03:00
Register(gameObject);
2023-11-23 22:07:49 +03:00
}
public T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject
2023-11-23 22:07:49 +03:00
{
T gameObject = GameObjectFactory.Instantiate<T>(args);
Register(gameObject);
2023-11-23 22:07:49 +03:00
return gameObject;
}
public IGameObject RemoveGameObject(IGameObject gameObject)
2023-11-23 22:07:49 +03:00
{
if (!_gameObjects.Contains(gameObject))
2023-11-27 11:06:02 +03:00
throw new Exception($"{nameof(IGameObject)} named {gameObject.Name} is not registered to the {nameof(GameManager)}.");
2023-11-23 22:07:49 +03:00
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;
}
2023-11-24 17:03:21 +03:00
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)
{
2023-11-27 13:46:01 +03:00
spriteBatch.Begin(SpriteSortMode.Deferred, transformMatrix: Camera.MatrixTransform);
2023-11-27 11:06:02 +03:00
foreach (var drawable in _drawables)
drawable.Draw(spriteBatch);
spriteBatch.End();
}
/////////////////////////////////////////////////////////////////
private void Unregister(IGameObject gameObject)
{
gameObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdd;
gameObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemove;
gameObject.OnFinalized -= OnGameObjectFinalize;
2023-11-27 11:06:02 +03:00
if (gameObject.BehaviourController.TryGetBehaviour<IDisplayable>(out var drawable))
_drawables.Remove(drawable);
2023-11-23 22:07:49 +03:00
_gameObjects.Remove(gameObject);
}
private void Register(IGameObject gameObject)
{
gameObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdd;
gameObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemove;
gameObject.OnFinalized += OnGameObjectFinalize;
2023-11-27 11:06:02 +03:00
if (gameObject.BehaviourController.TryGetBehaviour<IDisplayable>(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)
{
2023-11-27 11:06:02 +03:00
if (behaviour is IDisplayable drawable)
_drawables.Add(drawable);
}
private void OnBehaviourRemove(IBehaviourController controller, IBehaviour behaviour)
{
2023-11-27 11:06:02 +03:00
if (behaviour is IDisplayable drawable)
_drawables.Remove(drawable);
}
2023-11-23 22:07:49 +03:00
}