Files renamed to RecrownedGTK.
This commit is contained in:
207
RecrownedGTK/Assets/AssetManager.cs
Normal file
207
RecrownedGTK/Assets/AssetManager.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace RecrownedGTK.Assets
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper for the content manager that helps with controlling it by adding automated multithreaded content loading.
|
||||
/// </summary>
|
||||
public class AssetManager
|
||||
{
|
||||
Thread thread;
|
||||
readonly AssetManager contentManager;
|
||||
readonly Queue<ContentData> queue;
|
||||
Dictionary<string, Object> 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;
|
||||
/// <summary>
|
||||
/// Used when no path modifier is defined for that specific type.
|
||||
/// </summary>
|
||||
public IAssetPathResolver normalPathModifier = new NormalAssetPathResolver();
|
||||
volatile float progress;
|
||||
volatile bool running;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the queue is empty and all content is loaded.
|
||||
/// </summary>
|
||||
public bool Done { get { return !running && queue.Count == 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// The progress of the loading. 1 is complete while 0 is incomplete.
|
||||
/// </summary>
|
||||
public float Progress { get { return progress; } }
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the <see cref="ContentManager"/>.
|
||||
/// </summary>
|
||||
/// <param name="contentManager">The manager to wrap.</param>
|
||||
public AssetManager()
|
||||
{
|
||||
assets = new Dictionary<string, Object>();
|
||||
queue = new Queue<ContentData>();
|
||||
contentPathModifier = new Dictionary<Type, IAssetPathResolver>();
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a <see cref="IContentPathResolver"/> to this handler.
|
||||
/// </summary>
|
||||
/// <param name="assetType"></param>
|
||||
/// <param name="contentResolver"></param>
|
||||
public void AddContentPathResolver(Type assetType, IAssetPathResolver contentResolver) {
|
||||
contentPathModifier.Add(assetType, contentResolver);
|
||||
}
|
||||
/// <summary>
|
||||
/// Removes the <see cref="IContentPathResolver"/> for the key.
|
||||
/// </summary>
|
||||
/// <param name="assetType"></param>
|
||||
public void RemoveContentResolver(Type assetType) {
|
||||
contentPathModifier.Remove(assetType);
|
||||
}
|
||||
private void Load(string assetName, Type type, bool usePathModifier)
|
||||
{
|
||||
Debug.WriteLine("Loading asset: " + assetName);
|
||||
string path = assetName;
|
||||
if (usePathModifier)
|
||||
{
|
||||
IAssetPathResolver handler;
|
||||
if (contentPathModifier.ContainsKey(type))
|
||||
{
|
||||
handler = contentPathModifier[type];
|
||||
}
|
||||
else
|
||||
{
|
||||
handler = normalPathModifier;
|
||||
}
|
||||
path = handler.Modify(assetName);
|
||||
}
|
||||
assets.Add(assetName, contentManager.Load<Object>(path));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the requested asset.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the asset for an alternative way to cast.</typeparam>
|
||||
/// <param name="assetName">The name of the asset.</param>
|
||||
/// <returns>The asset casted to the type given with T.</returns>
|
||||
public T Get<T>(string assetName)
|
||||
{
|
||||
lock (queue)
|
||||
{
|
||||
return (T)assets[assetName];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues an asset to be loaded.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the asset to be queued.</typeparam>
|
||||
/// <param name="assetName">Name of asset to look for.</param>
|
||||
/// <param name="usePathModifier">Whether or not to use the path modifiers.</param>
|
||||
public void Queue<T>(string assetName, bool usePathModifier = true)
|
||||
{
|
||||
lock (queue)
|
||||
{
|
||||
if (!assets.ContainsKey(assetName))
|
||||
{
|
||||
queue.Enqueue(new ContentData(assetName, typeof(T), usePathModifier));
|
||||
Debug.WriteLine("Queued asset: " + assetName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Did not queue asset due to asset with same name being loaded: " + assetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever a batch of assets should be loaded from the queue. Safe to call once every frame.
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
if (queue.Count > 0 && (thread == null || !thread.IsAlive))
|
||||
{
|
||||
thread = new Thread(LoadBatch);
|
||||
thread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadBatch()
|
||||
{
|
||||
running = true;
|
||||
int totalTasks = queue.Count;
|
||||
int tasksCompleted = 0;
|
||||
while (queue.Count != 0)
|
||||
{
|
||||
lock (queue)
|
||||
{
|
||||
ContentData content = queue.Dequeue();
|
||||
Load(content.assetName, content.type, content.usePathModifier);
|
||||
tasksCompleted++;
|
||||
progress = (float)tasksCompleted / totalTasks;
|
||||
}
|
||||
}
|
||||
running = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Removes the asset from the list of assets in the system.
|
||||
/// Cannot remove from queue.
|
||||
/// </summary>
|
||||
/// <param name="name">the string name used to load the asset</param>
|
||||
public void Remove(string name)
|
||||
{
|
||||
lock (queue)
|
||||
{
|
||||
if (assets.ContainsKey(name))
|
||||
{
|
||||
if (assets[name] is IDisposable)
|
||||
{
|
||||
((IDisposable)assets[name]).Dispose();
|
||||
}
|
||||
assets.Remove(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the queue.
|
||||
/// </summary>
|
||||
public void ClearQueue()
|
||||
{
|
||||
lock (queue)
|
||||
{
|
||||
queue.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unloads everything from both queue and loaded list while properly disposing of the assets loaded.
|
||||
/// </summary>
|
||||
public void UnloadAll()
|
||||
{
|
||||
lock (queue)
|
||||
{
|
||||
contentManager.Unload();
|
||||
assets.Clear();
|
||||
ClearQueue();
|
||||
Debug.WriteLine("Unloaded all assets.");
|
||||
}
|
||||
}
|
||||
private struct ContentData
|
||||
{
|
||||
internal Type type;
|
||||
internal string assetName;
|
||||
internal bool usePathModifier;
|
||||
|
||||
public ContentData(string assetName, Type type, bool usePathModifier)
|
||||
{
|
||||
this.type = type;
|
||||
this.assetName = assetName;
|
||||
this.usePathModifier = usePathModifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
RecrownedGTK/Assets/IAssetPathResolver.cs
Normal file
15
RecrownedGTK/Assets/IAssetPathResolver.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace RecrownedGTK.Assets
|
||||
{
|
||||
/// <summary>
|
||||
/// Modifies the given path based on a name. Used to simplify long paths for the <see cref="AssetManager"/>
|
||||
/// </summary>
|
||||
public interface IAssetPathResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the complete path with the content folder as root.
|
||||
/// </summary>
|
||||
/// <param name="contentPath">Is the asset's name</param>
|
||||
/// <returns></returns>
|
||||
string Modify(string contentPath);
|
||||
}
|
||||
}
|
18
RecrownedGTK/Assets/NormalContentResolver.cs
Normal file
18
RecrownedGTK/Assets/NormalContentResolver.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace RecrownedGTK.Assets
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver that does nothing. Used for looking in the root by default.
|
||||
/// </summary>
|
||||
public class NormalAssetPathResolver : IAssetPathResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Passes the path through without modification as this is the normal content resolver and is meant to just pass things on.
|
||||
/// </summary>
|
||||
/// <param name="contentPath">The path to modify.</param>
|
||||
/// <returns></returns>
|
||||
public string Modify(string contentPath)
|
||||
{
|
||||
return contentPath;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user