rhythmbullet/RhythmBullet/Zer01HD/Utilities/ContentSystem/ContentSystem.cs

145 lines
4.3 KiB
C#
Raw Normal View History

2018-09-12 06:32:05 +00:00
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
2018-09-12 06:32:05 +00:00
using System;
using System.Collections.Generic;
2018-10-30 23:29:54 +00:00
using System.Diagnostics;
using System.IO;
2018-09-12 06:32:05 +00:00
using System.Linq;
using System.Text;
using System.Threading;
2018-09-12 06:32:05 +00:00
using System.Threading.Tasks;
namespace RhythmBullet.Zer01HD.Utilities.ContentSystem
{
public class ContentSystem
2018-09-12 06:32:05 +00:00
{
Thread thread;
readonly ContentManager contentManager;
2018-10-29 05:33:26 +00:00
readonly Queue<LoadableContent> queue;
Dictionary<string, IDisposable> assets;
2018-10-30 23:29:54 +00:00
public readonly Dictionary<Type, IContentPathModifier> contentPathModifier;
2018-09-12 06:32:05 +00:00
public ContentSystem(ContentManager contentManager)
{
this.contentManager = contentManager;
assets = new Dictionary<string, IDisposable>();
2018-10-29 05:33:26 +00:00
queue = new Queue<LoadableContent>();
2018-10-30 23:29:54 +00:00
contentPathModifier = new Dictionary<Type, IContentPathModifier>();
2018-09-12 06:32:05 +00:00
}
private void Load(string assetName, Type type)
2018-09-12 06:32:05 +00:00
{
2018-10-30 23:29:54 +00:00
IContentPathModifier handler = contentPathModifier[type];
string path = handler.Modify(assetName);
try
{
2018-10-30 23:29:54 +00:00
assets.Add(assetName, contentManager.Load<IDisposable>(path));
} catch (ContentLoadException cle)
{
Debug.WriteLine("Failed to load " + assetName + "with modified path: " + cle.Message);
Debug.WriteLine("Loading asset from root: " + assetName);
assets.Add(assetName, contentManager.Load<IDisposable>(assetName));
}
2018-10-30 23:29:54 +00:00
Debug.WriteLine("Loaded asset: " + assetName);
}
2018-10-30 23:29:54 +00:00
public T Get<T>(string assetName)
{
2018-10-30 23:29:54 +00:00
lock (queue)
{
return (T)assets[assetName];
}
}
2018-10-30 23:29:54 +00:00
public void Queue<T>(string assetName) where T : IDisposable
{
lock (queue)
{
if (!assets.ContainsKey(assetName))
{
2018-10-30 23:29:54 +00:00
queue.Enqueue(new LoadableContent(assetName, typeof(T)));
Debug.WriteLine("Queued asset: " + assetName);
}
else
{
Debug.WriteLine("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)
2018-09-12 06:32:05 +00:00
{
if (thread == null || !thread.IsAlive)
{
ThreadStart threadStart = new ThreadStart(LoadBatch);
thread = new Thread(threadStart);
2018-10-30 23:29:54 +00:00
thread.Start();
}
2018-09-12 06:32:05 +00:00
}
}
2018-10-30 23:29:54 +00:00
private void LoadBatch()
{
while (queue.Count != 0)
{
lock (queue)
{
LoadableContent content = queue.Dequeue();
Load(content.assetName, content.type);
}
}
}
/// <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)
{
if (assets.ContainsKey(name))
{
assets[name].Dispose();
assets.Remove(name);
}
}
/// <summary>
/// Clears the queue.
/// </summary>
public void ClearQueue()
{
2018-10-30 23:29:54 +00:00
lock (queue)
{
2018-10-30 23:29:54 +00:00
queue.Clear();
}
}
/// <summary>
/// Unloads everything from both queue and loaded list while properly disposing of the assets loaded.
/// </summary>
public void UnloadAll()
2018-09-12 06:32:05 +00:00
{
foreach (KeyValuePair<string, IDisposable> asset in assets)
{
asset.Value.Dispose();
assets.Remove(asset.Key);
}
ClearQueue();
2018-09-12 06:32:05 +00:00
}
2018-10-30 23:29:54 +00:00
public bool Done
{
2018-10-30 23:29:54 +00:00
get
{
return queue.Count == 0;
}
}
2018-09-12 06:32:05 +00:00
}
}