From 2fb5125ece30e6a05a052443f1a251e30274b79e Mon Sep 17 00:00:00 2001 From: dnesov Date: Sun, 18 Jun 2023 22:16:28 +0200 Subject: [PATCH] ResourceManager! --- DaggerFramework/DaggerFramework.csproj | 3 +- .../Source/Resources/Loaders/FontLoader.cs | 13 ++- .../Resources/Loaders/IResourceLoader.cs | 9 ++ .../Resources/Loaders/ResourceLoader.cs | 8 -- .../Source/Resources/Loaders/SoundLoader.cs | 13 ++- .../Resources/Loaders/Texture2dLoader.cs | 19 ++- .../Source/Resources/ResourceManager.cs | 110 ++++++++++++++++++ DaggerFramework/Source/Utils/Logger.cs | 47 ++++++++ TestGame/TestGame.cs | 15 ++- 9 files changed, 215 insertions(+), 22 deletions(-) create mode 100644 DaggerFramework/Source/Resources/Loaders/IResourceLoader.cs delete mode 100755 DaggerFramework/Source/Resources/Loaders/ResourceLoader.cs create mode 100644 DaggerFramework/Source/Resources/ResourceManager.cs create mode 100644 DaggerFramework/Source/Utils/Logger.cs diff --git a/DaggerFramework/DaggerFramework.csproj b/DaggerFramework/DaggerFramework.csproj index 1cd7198..9783d74 100644 --- a/DaggerFramework/DaggerFramework.csproj +++ b/DaggerFramework/DaggerFramework.csproj @@ -17,7 +17,8 @@ - + \ No newline at end of file diff --git a/DaggerFramework/Source/Resources/Loaders/FontLoader.cs b/DaggerFramework/Source/Resources/Loaders/FontLoader.cs index d6ddcf9..9cd9dae 100644 --- a/DaggerFramework/Source/Resources/Loaders/FontLoader.cs +++ b/DaggerFramework/Source/Resources/Loaders/FontLoader.cs @@ -1,8 +1,15 @@ -namespace DaggerFramework; +namespace DaggerFramework.Resources; -public class FontLoader : ResourceLoader +public class FontLoader : IResourceLoader { - public override Font Load(string path) + public IEnumerable SupportedExtensions => new string[] + { + ".ttf" + }; + + public Type ResourceType => typeof(Font); + + public Resource Load(string path) { return default; } diff --git a/DaggerFramework/Source/Resources/Loaders/IResourceLoader.cs b/DaggerFramework/Source/Resources/Loaders/IResourceLoader.cs new file mode 100644 index 0000000..79585ca --- /dev/null +++ b/DaggerFramework/Source/Resources/Loaders/IResourceLoader.cs @@ -0,0 +1,9 @@ +namespace DaggerFramework.Resources +{ + public interface IResourceLoader + { + public IEnumerable SupportedExtensions { get; } + public Type ResourceType { get; } + public Resource Load(string path); + } +} \ No newline at end of file diff --git a/DaggerFramework/Source/Resources/Loaders/ResourceLoader.cs b/DaggerFramework/Source/Resources/Loaders/ResourceLoader.cs deleted file mode 100755 index 5fef0d2..0000000 --- a/DaggerFramework/Source/Resources/Loaders/ResourceLoader.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace DaggerFramework -{ - public abstract class ResourceLoader : IDisposable where T : Resource - { - public void Dispose() { } - public abstract T Load(string path); - } -} \ No newline at end of file diff --git a/DaggerFramework/Source/Resources/Loaders/SoundLoader.cs b/DaggerFramework/Source/Resources/Loaders/SoundLoader.cs index 109ab50..0a934c7 100644 --- a/DaggerFramework/Source/Resources/Loaders/SoundLoader.cs +++ b/DaggerFramework/Source/Resources/Loaders/SoundLoader.cs @@ -1,10 +1,17 @@ using StbVorbisSharp; -namespace DaggerFramework +namespace DaggerFramework.Resources { - public class SoundLoader : ResourceLoader + public class SoundLoader : IResourceLoader { - public override Sound Load(string path) + public IEnumerable SupportedExtensions => new string[] + { + "ogg" + }; + + public Type ResourceType => typeof(Sound); + + public Resource Load(string path) { Vorbis vorbis; Sound result; diff --git a/DaggerFramework/Source/Resources/Loaders/Texture2dLoader.cs b/DaggerFramework/Source/Resources/Loaders/Texture2dLoader.cs index a8d5121..7e9e630 100755 --- a/DaggerFramework/Source/Resources/Loaders/Texture2dLoader.cs +++ b/DaggerFramework/Source/Resources/Loaders/Texture2dLoader.cs @@ -1,10 +1,20 @@ +using DaggerFramework.Resources; using StbImageSharp; namespace DaggerFramework { - public class Texture2dLoader : ResourceLoader + public class Texture2dLoader : IResourceLoader { - public override Texture2d Load(string path) + public IEnumerable SupportedExtensions => new string[] + { + ".png", + ".jpg", + ".jpeg" + }; + + public Type ResourceType => typeof(Texture2d); + + public Resource Load(string path) { ImageResult image; using (var stream = File.OpenRead(path)) @@ -18,5 +28,10 @@ namespace DaggerFramework return result; } + + Resource IResourceLoader.Load(string path) + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/DaggerFramework/Source/Resources/ResourceManager.cs b/DaggerFramework/Source/Resources/ResourceManager.cs new file mode 100644 index 0000000..10974b8 --- /dev/null +++ b/DaggerFramework/Source/Resources/ResourceManager.cs @@ -0,0 +1,110 @@ +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +using DaggerFramework.Utils; + +namespace DaggerFramework.Resources +{ + public class ResourceManager + { + public string ResourceRoot { get; set; } = "Resources/"; + + public bool TryLoad(string resourceId, string path) where T : Resource + { + T? resource = null; + + var fullPath = Path.Combine(ResourceRoot, path); + + // TODO: don't check if file doesn't exist in the file system, make it more generic but for now it's fine + if (!File.Exists(fullPath)) + { + _logger.Error($"File at \"{path}\" doesn't exist!"); + return false; + } + + _logger.Info($"Loading {path} as {typeof(T)} with id \"{resourceId}\"..."); + + if (!TryGetLoader(out IResourceLoader? loader)) + { + return false; + } + + var extension = Path.GetExtension(fullPath); + var hasExtension = loader.SupportedExtensions.Any(ext => extension[1..] == ext); + + if (!hasExtension) + { + _logger.Error($"Extension {extension} is not supported!"); + } + + if (loader.Load(fullPath) is not T loadedResource) + { + return false; + } + + resource = loadedResource; + _loadedResources.Add(resourceId, resource); + + _logger.Info($"\"{resourceId}\" was loaded successfully."); + + return true; + } + + public bool TryGetResource(string resourceId, [NotNullWhen(true)] out T? resource) where T : Resource + { + resource = null; + + if (!IsResourceLoaded(resourceId)) + { + _logger.Error($"Resource \"{resourceId}\" has not yet been loaded!"); + return false; + } + + var expectedResource = _loadedResources[resourceId]; + + if (expectedResource is not T loadedResource) + { + _logger.Error($"Given resource is of wrong type: provided {typeof(T)}, expected {expectedResource.GetType()}!"); + return false; + } + + resource = loadedResource; + + return true; + } + + public bool IsResourceLoaded(string resourceId) => _loadedResources.ContainsKey(resourceId); + + public void AddResourceAssociation(Type resourceType, IResourceLoader loader) + { + _resourceLoaderAssociations.Add(resourceType, loader); + } + + private bool TryGetLoader([NotNullWhen(true)] out IResourceLoader? loader) where T : Resource + { + loader = null; + + if (!_resourceLoaderAssociations.ContainsKey(typeof(T))) + { + _logger.Error($"No loader for {typeof(T).ToString()} was found!"); + return false; + } + + loader = _resourceLoaderAssociations[typeof(T)]; + + _logger.Info($"Using {loader.GetType().ToString()} for loading..."); + + return true; + } + + private Logger _logger = new(nameof(ResourceManager)); + + private readonly Dictionary _resourceLoaderAssociations = new() + { + {typeof(Sound), new SoundLoader()}, + {typeof(Texture2d), new Texture2dLoader()} + }; + + private Dictionary _loadedResources = new(); + } +} \ No newline at end of file diff --git a/DaggerFramework/Source/Utils/Logger.cs b/DaggerFramework/Source/Utils/Logger.cs new file mode 100644 index 0000000..74ee165 --- /dev/null +++ b/DaggerFramework/Source/Utils/Logger.cs @@ -0,0 +1,47 @@ +namespace DaggerFramework.Utils +{ + public class Logger + { + public static Action? OnLog; + public Logger(string className) + { + _className = className; + } + public void Info(object what) + { + LogType logType = LogType.Info; + string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}"; + LogConsole(message); + OnLog?.Invoke(message, logType); + } + + public void Warn(object what) + { + LogType logType = LogType.Warn; + string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}"; + LogConsole(message); + OnLog?.Invoke(message, logType); + } + + public void Error(object what) + { + LogType logType = LogType.Error; + string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}"; + LogConsole(message); + OnLog?.Invoke(message, logType); + } + + + private static string DateFormat => $"{DateTime.Now:t}"; + + private static void LogConsole(string what) => Console.WriteLine(what); + private readonly string _className; + } + + public enum LogType + { + Info, + Warn, + Error + } +} \ No newline at end of file diff --git a/TestGame/TestGame.cs b/TestGame/TestGame.cs index f46b9a7..6d208b7 100644 --- a/TestGame/TestGame.cs +++ b/TestGame/TestGame.cs @@ -1,7 +1,10 @@ -using DaggerFramework; using System.Numerics; + +using DaggerFramework; using DaggerFramework.Rendering; using DaggerFramework.Audio; +using DaggerFramework.Resources; + public class TestGame : Game { @@ -25,8 +28,10 @@ public class TestGame : Game protected override void LoadResources() { - _soundLoader = new SoundLoader(); - _testSound = _soundLoader.Load($"{ResourceRoot}sounds/test_sound.ogg"); + if (_resourceManager.TryLoad("my_sound", "sounds/test_sound.ogg")) + { + _resourceManager.TryGetResource("my_sound", out _testSound); + } } protected override void Ready() @@ -62,8 +67,8 @@ public class TestGame : Game } private Renderer _renderer; - private SoundLoader _soundLoader; - private Sound _testSound; + private ResourceManager _resourceManager = new(); + private Sound? _testSound; private FmodAudioBackend _audioBackend; private InputHandler _inputHandler; } \ No newline at end of file