Cleaned up asset loading system, and made progress on game engine structure.

This commit is contained in:
2020-05-18 14:07:25 -05:00
parent 8e2510903f
commit 635ed9fb7d
11 changed files with 90 additions and 33 deletions

View File

@@ -9,11 +9,11 @@ namespace RecrownedGTK.AssetsSystem {
public AssetLoader() {
typeLoaders = new Dictionary<Type, ILoader>();
}
public void AddLoaderResolver(Type type, ILoader loader) {
if (typeLoaders.ContainsKey(type)) {
throw new InvalidOperationException(String.Format("The type {0} already exists in this resolver.", type));
public void AddLoaderResolver(ILoader loader) {
if (typeLoaders.ContainsKey(loader.resultingType)) {
throw new InvalidOperationException(String.Format("The type {0} already exists in this resolver.", loader.resultingType));
}
typeLoaders.Add(type, loader);
typeLoaders.Add(loader.resultingType, loader);
}
public void RemoveLoaderResolver(Type type) {
if (!typeLoaders.ContainsKey(type)) {
@@ -21,6 +21,11 @@ namespace RecrownedGTK.AssetsSystem {
}
typeLoaders.Remove(type);
}
public void RemoveLoaderResolver(ILoader loader) {
RemoveLoaderResolver(loader.resultingType);
}
public IInfo Load(string path, Type type) {
if (!typeLoaders.ContainsKey(type)) {
throw new InvalidOperationException(String.Format("The type {0} doesn't exist in this resolver.", type));

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
@@ -11,16 +12,10 @@ namespace RecrownedGTK.AssetsSystem
/// </summary>
public class AssetManager
{
private AssetLoader assetLoader;
readonly Queue<ContentData> queue;
Dictionary<string, IDisposable> assets;
/// <summary>
/// Path modifiers to change the path in which the content manager looks to load a file. Used for better organizing things while not needing to type entire path.
/// </summary>
public readonly AssetLoader assetLoader;
readonly Queue<AssetOutline> queue;
ConcurrentDictionary<string, IDisposable> assets;
private readonly Dictionary<Type, IAssetPathResolver> contentPathModifier;
/// <summary>
/// Used when no path modifier is defined for that specific type.
/// </summary>
public IAssetPathResolver normalPathModifier = new NormalAssetPathResolver();
volatile float progress;
volatile bool running;
@@ -36,13 +31,21 @@ namespace RecrownedGTK.AssetsSystem
public float Progress { get { return progress; } }
/// <summary>
/// Wraps the <see cref="ContentManager"/>.
/// Creates an asset manager with a default asset loader.
/// </summary>
/// <param name="contentManager">The manager to wrap.</param>
public AssetManager()
public AssetManager() : this(new AssetLoader())
{
assets = new Dictionary<string, IDisposable>();
queue = new Queue<ContentData>();
}
/// <summary>
/// A manager for the given asset loader.
/// The manager will asynchronously load assets and store them.
/// </summary>
/// <param name="assetLoader">The asset loader to use for loading.</param>
public AssetManager(AssetLoader assetLoader) {
this.assetLoader = assetLoader;
assets = new ConcurrentDictionary<string, IDisposable>();
queue = new Queue<AssetOutline>();
contentPathModifier = new Dictionary<Type, IAssetPathResolver>();
}
@@ -80,8 +83,7 @@ namespace RecrownedGTK.AssetsSystem
}
path = handler.Modify(assetName);
}
assets.Add(assetName, assetLoader.Load(path, type).CreateUseable());
assets.TryAdd(assetName, assetLoader.Load(path, type).CreateUseable());
}
/// <summary>
@@ -110,7 +112,7 @@ namespace RecrownedGTK.AssetsSystem
{
if (!assets.ContainsKey(assetName))
{
queue.Enqueue(new ContentData(assetName, typeof(T), usePathModifier));
queue.Enqueue(new AssetOutline(assetName, typeof(T), usePathModifier));
Debug.WriteLine("Queued asset: " + assetName);
Update();
}
@@ -145,7 +147,7 @@ namespace RecrownedGTK.AssetsSystem
{
lock (queue)
{
ContentData content = queue.Dequeue();
AssetOutline content = queue.Dequeue();
Load(content.assetName, content.type, content.usePathModifier);
tasksCompleted++;
progress = (float)tasksCompleted / totalTasks;
@@ -169,7 +171,8 @@ namespace RecrownedGTK.AssetsSystem
{
((IDisposable)assets[name]).Dispose();
}
assets.Remove(name);
IDisposable disposable = null;
assets.TryRemove(name, out disposable);
}
}
}
@@ -201,13 +204,13 @@ namespace RecrownedGTK.AssetsSystem
Debug.WriteLine("Unloaded all assets.");
}
}
private struct ContentData
private struct AssetOutline
{
internal Type type;
internal string assetName;
internal bool usePathModifier;
public ContentData(string assetName, Type type, bool usePathModifier)
public AssetOutline(string assetName, Type type, bool usePathModifier)
{
this.type = type;
this.assetName = assetName;

View File

@@ -1,9 +1,12 @@
using System;
namespace RecrownedGTK.AssetsSystem.Information {
/// <summary>
/// Describes a serializable datatype.
/// Meant for use as a part of the asset pipeline.
/// </summary>
public interface IInfo
{
Type type {get;}
IDisposable CreateUseable();
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace RecrownedGTK.AssetsSystem.Information {
/// <summary>
/// An interface that describes an information class.
/// An information class is class that can produce a useable asset object.
/// In the asset pipeline, this is the second step, after loading the asset data.
/// </summary>
public interface IInformation
{
}
}

View File

@@ -5,7 +5,7 @@ namespace RecrownedGTK.AssetsSystem.Information {
public struct TextureInfo : IInfo {
public readonly byte[] textureData;
int width, height;
public Type type => typeof(TextureData);
public Type resultingType => typeof(TextureData);
public TextureInfo(int width, int height, byte[] textureData) {
this.width = width;
this.height = height;

View File

@@ -3,6 +3,7 @@ using RecrownedGTK.AssetsSystem.Information;
namespace RecrownedGTK.AssetsSystem.Loaders {
public interface ILoader
{
Type resultingType {get;}
IInfo load(string path);
}
}

View File

@@ -7,6 +7,8 @@ using RecrownedGTK.Graphics;
namespace RecrownedGTK.AssetsSystem.Loaders {
public class TextureLoader : ILoader
{
public Type resultingType => typeof(TextureData);
public IInfo load(string path)
{
int width;