Cleaned up asset loading system, and made progress on game engine structure.
This commit is contained in:
parent
8e2510903f
commit
635ed9fb7d
1
.vscode/launch.json
vendored
1
.vscode/launch.json
vendored
@ -4,6 +4,7 @@
|
|||||||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": ".NET Core Launch (console)",
|
"name": ".NET Core Launch (console)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
|
BIN
RecrownedGTK.Tests/assets/texture_test_2048x2048.png
Normal file
BIN
RecrownedGTK.Tests/assets/texture_test_2048x2048.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 675 KiB |
@ -9,11 +9,11 @@ namespace RecrownedGTK.AssetsSystem {
|
|||||||
public AssetLoader() {
|
public AssetLoader() {
|
||||||
typeLoaders = new Dictionary<Type, ILoader>();
|
typeLoaders = new Dictionary<Type, ILoader>();
|
||||||
}
|
}
|
||||||
public void AddLoaderResolver(Type type, ILoader loader) {
|
public void AddLoaderResolver(ILoader loader) {
|
||||||
if (typeLoaders.ContainsKey(type)) {
|
if (typeLoaders.ContainsKey(loader.resultingType)) {
|
||||||
throw new InvalidOperationException(String.Format("The type {0} already exists in this resolver.", type));
|
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) {
|
public void RemoveLoaderResolver(Type type) {
|
||||||
if (!typeLoaders.ContainsKey(type)) {
|
if (!typeLoaders.ContainsKey(type)) {
|
||||||
@ -21,6 +21,11 @@ namespace RecrownedGTK.AssetsSystem {
|
|||||||
}
|
}
|
||||||
typeLoaders.Remove(type);
|
typeLoaders.Remove(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveLoaderResolver(ILoader loader) {
|
||||||
|
RemoveLoaderResolver(loader.resultingType);
|
||||||
|
}
|
||||||
|
|
||||||
public IInfo Load(string path, Type type) {
|
public IInfo Load(string path, Type type) {
|
||||||
if (!typeLoaders.ContainsKey(type)) {
|
if (!typeLoaders.ContainsKey(type)) {
|
||||||
throw new InvalidOperationException(String.Format("The type {0} doesn't exist in this resolver.", type));
|
throw new InvalidOperationException(String.Format("The type {0} doesn't exist in this resolver.", type));
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -11,16 +12,10 @@ namespace RecrownedGTK.AssetsSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class AssetManager
|
public class AssetManager
|
||||||
{
|
{
|
||||||
private AssetLoader assetLoader;
|
public readonly AssetLoader assetLoader;
|
||||||
readonly Queue<ContentData> queue;
|
readonly Queue<AssetOutline> queue;
|
||||||
Dictionary<string, IDisposable> assets;
|
ConcurrentDictionary<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>
|
|
||||||
private readonly Dictionary<Type, IAssetPathResolver> contentPathModifier;
|
private readonly Dictionary<Type, IAssetPathResolver> contentPathModifier;
|
||||||
/// <summary>
|
|
||||||
/// Used when no path modifier is defined for that specific type.
|
|
||||||
/// </summary>
|
|
||||||
public IAssetPathResolver normalPathModifier = new NormalAssetPathResolver();
|
public IAssetPathResolver normalPathModifier = new NormalAssetPathResolver();
|
||||||
volatile float progress;
|
volatile float progress;
|
||||||
volatile bool running;
|
volatile bool running;
|
||||||
@ -36,13 +31,21 @@ namespace RecrownedGTK.AssetsSystem
|
|||||||
public float Progress { get { return progress; } }
|
public float Progress { get { return progress; } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Wraps the <see cref="ContentManager"/>.
|
/// Creates an asset manager with a default asset loader.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="contentManager">The manager to wrap.</param>
|
public AssetManager() : this(new AssetLoader())
|
||||||
public AssetManager()
|
|
||||||
{
|
{
|
||||||
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>();
|
contentPathModifier = new Dictionary<Type, IAssetPathResolver>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,8 +83,7 @@ namespace RecrownedGTK.AssetsSystem
|
|||||||
}
|
}
|
||||||
path = handler.Modify(assetName);
|
path = handler.Modify(assetName);
|
||||||
}
|
}
|
||||||
assets.Add(assetName, assetLoader.Load(path, type).CreateUseable());
|
assets.TryAdd(assetName, assetLoader.Load(path, type).CreateUseable());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -110,7 +112,7 @@ namespace RecrownedGTK.AssetsSystem
|
|||||||
{
|
{
|
||||||
if (!assets.ContainsKey(assetName))
|
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);
|
Debug.WriteLine("Queued asset: " + assetName);
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
@ -145,7 +147,7 @@ namespace RecrownedGTK.AssetsSystem
|
|||||||
{
|
{
|
||||||
lock (queue)
|
lock (queue)
|
||||||
{
|
{
|
||||||
ContentData content = queue.Dequeue();
|
AssetOutline content = queue.Dequeue();
|
||||||
Load(content.assetName, content.type, content.usePathModifier);
|
Load(content.assetName, content.type, content.usePathModifier);
|
||||||
tasksCompleted++;
|
tasksCompleted++;
|
||||||
progress = (float)tasksCompleted / totalTasks;
|
progress = (float)tasksCompleted / totalTasks;
|
||||||
@ -169,7 +171,8 @@ namespace RecrownedGTK.AssetsSystem
|
|||||||
{
|
{
|
||||||
((IDisposable)assets[name]).Dispose();
|
((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.");
|
Debug.WriteLine("Unloaded all assets.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private struct ContentData
|
private struct AssetOutline
|
||||||
{
|
{
|
||||||
internal Type type;
|
internal Type type;
|
||||||
internal string assetName;
|
internal string assetName;
|
||||||
internal bool usePathModifier;
|
internal bool usePathModifier;
|
||||||
|
|
||||||
public ContentData(string assetName, Type type, bool usePathModifier)
|
public AssetOutline(string assetName, Type type, bool usePathModifier)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.assetName = assetName;
|
this.assetName = assetName;
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace RecrownedGTK.AssetsSystem.Information {
|
namespace RecrownedGTK.AssetsSystem.Information {
|
||||||
|
/// <summary>
|
||||||
|
/// Describes a serializable datatype.
|
||||||
|
/// Meant for use as a part of the asset pipeline.
|
||||||
|
/// </summary>
|
||||||
public interface IInfo
|
public interface IInfo
|
||||||
{
|
{
|
||||||
Type type {get;}
|
|
||||||
IDisposable CreateUseable();
|
IDisposable CreateUseable();
|
||||||
}
|
}
|
||||||
}
|
}
|
12
RecrownedGTK/AssetsSystem/Information/IInformation.cs
Normal file
12
RecrownedGTK/AssetsSystem/Information/IInformation.cs
Normal 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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ namespace RecrownedGTK.AssetsSystem.Information {
|
|||||||
public struct TextureInfo : IInfo {
|
public struct TextureInfo : IInfo {
|
||||||
public readonly byte[] textureData;
|
public readonly byte[] textureData;
|
||||||
int width, height;
|
int width, height;
|
||||||
public Type type => typeof(TextureData);
|
public Type resultingType => typeof(TextureData);
|
||||||
public TextureInfo(int width, int height, byte[] textureData) {
|
public TextureInfo(int width, int height, byte[] textureData) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
@ -3,6 +3,7 @@ using RecrownedGTK.AssetsSystem.Information;
|
|||||||
namespace RecrownedGTK.AssetsSystem.Loaders {
|
namespace RecrownedGTK.AssetsSystem.Loaders {
|
||||||
public interface ILoader
|
public interface ILoader
|
||||||
{
|
{
|
||||||
|
Type resultingType {get;}
|
||||||
IInfo load(string path);
|
IInfo load(string path);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,6 +7,8 @@ using RecrownedGTK.Graphics;
|
|||||||
namespace RecrownedGTK.AssetsSystem.Loaders {
|
namespace RecrownedGTK.AssetsSystem.Loaders {
|
||||||
public class TextureLoader : ILoader
|
public class TextureLoader : ILoader
|
||||||
{
|
{
|
||||||
|
public Type resultingType => typeof(TextureData);
|
||||||
|
|
||||||
public IInfo load(string path)
|
public IInfo load(string path)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
|
@ -7,12 +7,8 @@ using RecrownedGTK.AssetsSystem;
|
|||||||
namespace RecrownedGTK.Game {
|
namespace RecrownedGTK.Game {
|
||||||
public sealed class GameEngine : GameWindow {
|
public sealed class GameEngine : GameWindow {
|
||||||
private IState state;
|
private IState state;
|
||||||
public readonly Preferences preferences;
|
public GameEngine(IState initialState) : base() {
|
||||||
public readonly AssetManager assets;
|
|
||||||
public GameEngine(IState initialState, Preferences preferences, AssetManager assets) : base() {
|
|
||||||
this.state = initialState;
|
this.state = initialState;
|
||||||
this.assets = assets;
|
|
||||||
this.preferences = preferences;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUpdateFrame(FrameEventArgs e) {
|
protected override void OnUpdateFrame(FrameEventArgs e) {
|
||||||
@ -34,7 +30,7 @@ namespace RecrownedGTK.Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnClosed(EventArgs e) {
|
protected override void OnClosed(EventArgs e) {
|
||||||
if (state.CloseRequested()) {
|
if (!state.CloseRequested()) {
|
||||||
((CancelEventArgs) e).Cancel = true;
|
((CancelEventArgs) e).Cancel = true;
|
||||||
}
|
}
|
||||||
base.OnClosed(e);
|
base.OnClosed(e);
|
||||||
|
@ -3,13 +3,47 @@ using OpenTK.Input;
|
|||||||
namespace RecrownedGTK.Game {
|
namespace RecrownedGTK.Game {
|
||||||
public interface IState
|
public interface IState
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Called when this state is going to be shown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameManager">The instance of the game manager that is requesting this.</param>
|
||||||
|
/// <returns>True of it's ready to be displayed, false otherwise.</returns>
|
||||||
bool Shown(GameEngine gameManager);
|
bool Shown(GameEngine gameManager);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on updating the state.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The time that has passed since the last update in seconds.</param>
|
||||||
void Update(double time);
|
void Update(double time);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called for rendering things.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The time that has elapsed since last rendering in seconds.</param>
|
||||||
void Render(double time);
|
void Render(double time);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when this state is no longer being displayed.
|
||||||
|
/// </summary>
|
||||||
void Hidden();
|
void Hidden();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the game window size is updated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="width">The new width</param>
|
||||||
|
/// <param name="height">The new height</param>
|
||||||
void WindowSizeUpdate(int width, int height);
|
void WindowSizeUpdate(int width, int height);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When the game is being requested to be closed.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if closing is acceptable, or false otherwise.</returns>
|
||||||
bool CloseRequested();
|
bool CloseRequested();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called every update in the case that there should be a state change.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Another state if ready to change states, or null if not.</returns>
|
||||||
IState ChangeState();
|
IState ChangeState();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user