using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace RhythmBullet.Zer01HD.Utilities.ContentSystem { public class ContentSystem { volatile bool queued; Thread thread; readonly ContentManager contentManager; readonly Queue queue; Dictionary assets; public readonly Dictionary contentResolver; public ContentSystem(ContentManager contentManager) { this.contentManager = contentManager; assets = new Dictionary(); queue = new Queue(); contentResolver = new Dictionary(); } private void Load(string assetName, Type type) { IContentResolver handler = contentResolver[type]; string path = handler.Load(assetName); assets.Add(assetName, contentManager.Load(path)); } private void LoadBatch() { while (queue.Count != 0) { lock (queue) { ContentLoad content = queue.Dequeue(); Load(content.assetName, content.type); } queued = false; } } public T Get(string assetName) { lock(queue) { return (T)assets[assetName]; } } public void Queue(string assetName, Type type) { queued = true; lock (queue) { if (!assets.ContainsKey(assetName)) { queue.Enqueue(new ContentLoad(assetName, type)); } } } /// /// 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) { if (thread == null || !thread.IsAlive) { ThreadStart threadStart = new ThreadStart(LoadBatch); thread = new Thread(threadStart); } } } /// /// 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() { return queued; } } }