Make most subsystems available as protected properties in base Game class, implement IDisposable on systems.
This commit is contained in:
@@ -4,7 +4,7 @@ namespace Voile.Audio
|
||||
{
|
||||
public abstract void Initialize();
|
||||
public abstract void Update();
|
||||
public abstract void Shutdown();
|
||||
protected abstract void Shutdown();
|
||||
// BUS
|
||||
public abstract void CreateBus(string busName);
|
||||
public abstract void SetBusVolume(string busName, float volume);
|
||||
@@ -26,6 +26,7 @@ namespace Voile.Audio
|
||||
public void Dispose()
|
||||
{
|
||||
Shutdown();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private LehmerRandom _random = new LehmerRandom();
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Voile.Audio
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
protected override void Shutdown()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,11 @@ namespace Voile.Audio
|
||||
channelGroup.addDSP(0, dsp);
|
||||
}
|
||||
|
||||
protected override void Shutdown()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private DSP CreateReverbDsp(AudioEffectReverb effectReverb)
|
||||
{
|
||||
DSP dsp;
|
||||
@@ -122,11 +127,6 @@ namespace Voile.Audio
|
||||
return _channelGroups[busName];
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private FMOD.System _system;
|
||||
|
||||
// TODO: use a different key for the dictionary, paths are not good :( (waste of memory lol)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Voile.Rendering;
|
||||
using Voile.Resources;
|
||||
|
||||
namespace Voile
|
||||
@@ -8,12 +9,36 @@ namespace Voile
|
||||
/// The ResourceManager associated with this game.
|
||||
/// </summary>
|
||||
protected ResourceManager ResourceManager { get; private set; }
|
||||
public abstract string ResourceRoot { get; }
|
||||
/// <summary>
|
||||
/// The InputHandler associated with this game. Uses <see cref="RaylibInputHandler"/> by default.
|
||||
/// </summary>
|
||||
protected InputHandler Input { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Renderer associated with this game. Uses <see cref="RaylibRenderer"/> by default.
|
||||
/// </summary>
|
||||
protected Renderer Renderer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Resource root path for this game.
|
||||
/// </summary>
|
||||
public virtual string ResourceRoot => "Resources/";
|
||||
|
||||
/// <summary>
|
||||
/// Path to the engine configuration file.
|
||||
/// </summary>
|
||||
public virtual string EngineConfigPath => "engine.config";
|
||||
|
||||
/// <summary>
|
||||
/// Name of this game. Also used as a default window title.
|
||||
/// </summary>
|
||||
public virtual string Name => "";
|
||||
|
||||
public Game()
|
||||
{
|
||||
ResourceManager = new ResourceManager();
|
||||
Input = new RaylibInputHandler();
|
||||
Renderer = new RaylibRenderer();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -22,8 +47,6 @@ namespace Voile
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
Configure();
|
||||
|
||||
Initialize();
|
||||
LoadResources();
|
||||
Ready();
|
||||
@@ -32,15 +55,36 @@ namespace Voile
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when it's time to initialize the subsystems.
|
||||
/// Initializes subsystems using default types and settings.
|
||||
/// </summary>
|
||||
public void InitializeDefault()
|
||||
{
|
||||
ResourceManager.ResourceRoot = ResourceRoot;
|
||||
|
||||
Input = new RaylibInputHandler();
|
||||
Renderer = new RaylibRenderer();
|
||||
|
||||
InitializeRenderer();
|
||||
}
|
||||
|
||||
public void ShutdownDefault()
|
||||
{
|
||||
Input.Dispose();
|
||||
Renderer.Dispose();
|
||||
ResourceManager.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when it's time to initialize the subsystems, or modify default game settings or systems.
|
||||
/// </summary>
|
||||
public abstract void Initialize();
|
||||
/// <summary>
|
||||
/// Called when it's time to load the application's resources, such as images or sounds.
|
||||
/// Called when it's time to load the game's resources, such as images or sounds.
|
||||
/// </summary>
|
||||
protected abstract void LoadResources();
|
||||
/// <summary>
|
||||
/// Called when it's safe to manipulate with the resources or/and systems.
|
||||
/// You can safely create game objects, scenes, etc. in this method.
|
||||
/// </summary>
|
||||
protected abstract void Ready();
|
||||
/// <summary>
|
||||
@@ -52,9 +96,14 @@ namespace Voile
|
||||
/// </summary>
|
||||
public abstract void Shutdown();
|
||||
|
||||
private void Configure()
|
||||
private void InitializeRenderer()
|
||||
{
|
||||
ResourceManager.ResourceRoot = ResourceRoot;
|
||||
var windowSettings = WindowSettings.Default;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Name))
|
||||
windowSettings.Title = Name;
|
||||
|
||||
Renderer.CreateAndInitialize(windowSettings, RendererSettings.Default);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,14 +4,18 @@ using Voile.Utils;
|
||||
|
||||
namespace Voile
|
||||
{
|
||||
public abstract class InputHandler
|
||||
public abstract class InputHandler : IDisposable
|
||||
{
|
||||
public static IReadOnlyDictionary<string, List<InputAction>> InputMappings => inputMappings;
|
||||
|
||||
public InputHandler()
|
||||
{
|
||||
inputMappings = new Dictionary<string, IEnumerable<InputAction>>();
|
||||
inputMappings = new Dictionary<string, List<InputAction>>();
|
||||
CreateDefaultMappings();
|
||||
}
|
||||
public Action OnInput;
|
||||
|
||||
public void Dispose() => GC.SuppressFinalize(this);
|
||||
|
||||
public bool Handled { get => _handled; set => _handled = value; }
|
||||
public abstract bool IsKeyboardKeyDown(KeyboardKey key);
|
||||
public abstract bool KeyboardKeyJustPressed(KeyboardKey key);
|
||||
@@ -36,7 +40,7 @@ namespace Voile
|
||||
|
||||
public void AddInputMapping(string actionName, IEnumerable<InputAction> inputActions)
|
||||
{
|
||||
inputMappings.Add(actionName, inputActions);
|
||||
inputMappings.Add(actionName, inputActions.ToList());
|
||||
}
|
||||
|
||||
private void CreateDefaultMappings()
|
||||
@@ -75,9 +79,9 @@ namespace Voile
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool _handled;
|
||||
protected Dictionary<string, IEnumerable<InputAction>> inputMappings;
|
||||
|
||||
protected static Dictionary<string, List<InputAction>> inputMappings = new();
|
||||
private bool _handled;
|
||||
private Logger _logger = new(nameof(InputHandler));
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,6 @@ namespace Voile
|
||||
public override bool IsKeyboardKeyDown(KeyboardKey key)
|
||||
{
|
||||
Raylib_cs.KeyboardKey rayKey = (Raylib_cs.KeyboardKey)key;
|
||||
OnInput?.Invoke();
|
||||
return Raylib.IsKeyDown(rayKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Voile.Rendering
|
||||
return Raylib.WindowShouldClose();
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
protected override void Shutdown()
|
||||
{
|
||||
Raylib.CloseWindow();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Voile.Rendering
|
||||
/// <summary>
|
||||
/// An abstract class representing the graphics renderer.
|
||||
/// </summary>
|
||||
public abstract class Renderer
|
||||
public abstract class Renderer : IDisposable
|
||||
{
|
||||
// INIT
|
||||
/// <summary>
|
||||
@@ -46,6 +46,13 @@ namespace Voile.Rendering
|
||||
/// </summary>
|
||||
public abstract Vector2 MonitorSize { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
Shutdown();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a window.
|
||||
/// </summary>
|
||||
@@ -59,7 +66,7 @@ namespace Voile.Rendering
|
||||
protected abstract int GetMonitorHeight(int monitorId);
|
||||
protected abstract int GetCurrentMonitor();
|
||||
protected abstract bool WindowShouldClose();
|
||||
public abstract void Shutdown();
|
||||
protected abstract void Shutdown();
|
||||
|
||||
// DRAWING
|
||||
/// <summary>
|
||||
@@ -171,7 +178,7 @@ namespace Voile.Rendering
|
||||
public struct WindowSettings
|
||||
{
|
||||
public string Title;
|
||||
public Vector2 Size = new Vector2(640, 480);
|
||||
public Vector2 Size = new Vector2(1280, 720);
|
||||
public bool Resizable { get; set; }
|
||||
|
||||
public WindowSettings(string title, Vector2 size)
|
||||
@@ -179,5 +186,7 @@ namespace Voile.Rendering
|
||||
Title = title;
|
||||
Size = size;
|
||||
}
|
||||
|
||||
public static WindowSettings Default => new("Voile Game", new Vector2(1280, 720));
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ namespace Voile.Rendering
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Shutdown()
|
||||
protected override void Shutdown()
|
||||
{
|
||||
_window!.DoEvents();
|
||||
_window.Reset();
|
||||
|
||||
@@ -4,7 +4,7 @@ using Voile.Utils;
|
||||
|
||||
namespace Voile.Resources
|
||||
{
|
||||
public class ResourceManager
|
||||
public class ResourceManager : IDisposable
|
||||
{
|
||||
public string ResourceRoot { get; set; } = "Resources/";
|
||||
|
||||
@@ -49,6 +49,24 @@ namespace Voile.Resources
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryUnload(string resourceId)
|
||||
{
|
||||
_logger.Info($"Unloading resource with id \"{resourceId}\"...");
|
||||
|
||||
if (!_loadedResources.ContainsKey(resourceId))
|
||||
{
|
||||
_logger.Error($"Cannot unload resource with id \"{resourceId}\": resource doesn't exist!");
|
||||
return false;
|
||||
}
|
||||
|
||||
var resource = _loadedResources[resourceId];
|
||||
|
||||
_loadedResources.Remove(resourceId);
|
||||
resource.Dispose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TrySave<T>(string path, in T resource) where T : Resource
|
||||
{
|
||||
if (!TryGetSaver(out IResourceSaver<T>? saver))
|
||||
@@ -151,6 +169,17 @@ namespace Voile.Resources
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var resource in _loadedResources)
|
||||
{
|
||||
TryUnload(resource.Key);
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
|
||||
private Logger _logger = new(nameof(ResourceManager));
|
||||
|
||||
private readonly Dictionary<Type, object> _resourceLoaderAssociations = new()
|
||||
|
||||
Reference in New Issue
Block a user