using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace RhythmBullet.Zer01HD.Utilities.ContentSystem { public class ContentSystem { Thread thread; readonly ContentManager contentManager; readonly Queue queue; Dictionary assets; public readonly Dictionary contentPathModifier; public ContentSystem(ContentManager contentManager) { this.contentManager = contentManager; assets = new Dictionary(); queue = new Queue(); contentPathModifier = new Dictionary(); } private void Load(string assetName, Type type) { IContentPathModifier handler = contentPathModifier[type]; string path = handler.Modify(assetName); try { assets.Add(assetName, contentManager.Load(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(assetName)); } Debug.WriteLine("Loaded asset: " + assetName); } public T Get(string assetName) { lock (queue) { return (T)assets[assetName]; } } public void Queue(string assetName) where T : IDisposable { lock (queue) { if (!assets.ContainsKey(assetName)) { 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); } } } /// /// Called whenever a batch of assets should be loaded from the queue. Safe to call once every frame. /// public void Update() { if (queue.Count > 0 && (thread == null || !thread.IsAlive)) { ThreadStart threadStart = new ThreadStart(LoadBatch); thread = new Thread(threadStart); thread.Start(); } } private void LoadBatch() { while (queue.Count != 0) { lock (queue) { LoadableContent content = queue.Dequeue(); Load(content.assetName, content.type); } } } /// /// Removes the asset from the list of assets in the system. /// Cannot remove from queue. /// /// the string name used to load the asset public void Remove(string name) { if (assets.ContainsKey(name)) { assets[name].Dispose(); assets.Remove(name); } } /// /// Clears the queue. /// public void ClearQueue() { lock (queue) { queue.Clear(); } } /// /// Unloads everything from both queue and loaded list while properly disposing of the assets loaded. /// public void UnloadAll() { foreach (KeyValuePair asset in assets) { asset.Value.Dispose(); assets.Remove(asset.Key); } ClearQueue(); } public bool Done { get { return queue.Count == 0; } } } }