Share Pastebin
Guest
Public paste!

jsedlak

By: a guest | May 10th, 2008 | Syntax: C# | Size: 7.49 KB | Hits: 78 | Expires: Never
Copy text to clipboard
  1. #region License
  2. // Permission is hereby granted, free of charge, to any person obtaining
  3. // a copy of this software and associated documentation files (the
  4. // "Software"), to deal in the Software without restriction, including
  5. // without limitation the rights to use, copy, modify, merge, publish,
  6. // distribute, sublicense, and/or sell copies of the Software, and to
  7. // permit persons to whom the Software is furnished to do so, subject to
  8. // the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be
  11. // included in all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  17. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  18. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  19. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. //
  21. // (C) 2008 John Sedlak
  22. //
  23. // Authors:
  24. //   John Sedlak (kriscsc@msn.com)
  25. //
  26. #endregion
  27.  
  28. using System;
  29. using System.Threading;
  30. using System.Collections.Generic;
  31. using Microsoft.Xna.Framework.Content;
  32.  
  33. using FocusedGames.Thrust;
  34.  
  35. namespace FocusedGames.Thrust.Content
  36. {
  37.     /// <summary>
  38.     /// Manages content both synchronously and asynchronously and allows for the piece-wise unloading of assets.
  39.     /// </summary>
  40.     public class AssetManager : ContentManager
  41.     {
  42.         #region Private Members
  43.         private List<ILoadable> content = new List<ILoadable>();
  44.         private Queue<ILoadable> asyncLoadables = new Queue<ILoadable>();
  45.  
  46.         private int current;
  47.         private int total;
  48.         private bool isLoading = false;
  49.  
  50.         private bool simulateLargeContent = false;
  51.         #endregion
  52.  
  53.         #region Events
  54.         private event EventHandler InternalBeginLoad;
  55.  
  56.         /// <summary>
  57.         /// Fired when the asset manager has finished loading a group of assets.
  58.         /// </summary>
  59.         public event EventHandler FinishedLoad;
  60.         #endregion
  61.  
  62.         #region Constructors
  63.         /// <summary>
  64.         /// Default constructor.
  65.         /// </summary>
  66.         /// <param name="serviceProvider">The Game's service container.</param>
  67.         public AssetManager(IServiceProvider serviceProvider)
  68.             : this(serviceProvider, String.Empty)
  69.         {
  70.         }
  71.  
  72.         /// <summary>
  73.         /// Secondary constructor.
  74.         /// </summary>
  75.         /// <param name="serviceProvider">The Game's service container.</param>
  76.         /// <param name="rootDirectory">The base directory where all assets are stored.</param>
  77.         public AssetManager(IServiceProvider serviceProvider, string rootDirectory)
  78.             : base(serviceProvider, rootDirectory)
  79.         {
  80.             InternalBeginLoad += OnBeginLoad;
  81.         }
  82.         #endregion
  83.  
  84.         #region Unloading
  85.         /// <summary>
  86.         /// DO NOT USE THIS. IT DOES NOTHING.
  87.         /// </summary>
  88.         /// <see cref="Unload(ILoadable)"/>
  89.         public new void Unload()
  90.         {
  91.         }
  92.  
  93.         /// <summary>
  94.         /// Unloads a single asset.
  95.         /// </summary>
  96.         /// <param name="asset">The asset to unload.</param>
  97.         public void Unload(ILoadable asset)
  98.         {
  99.             if (content.Contains(asset))
  100.                 content.Remove(asset);
  101.  
  102.             asset.Unload();
  103.  
  104.             asset = null;
  105.         }
  106.         #endregion
  107.  
  108.         #region Loading
  109.         /// <summary>
  110.         /// Loads a custom asset.
  111.         /// </summary>
  112.         /// <typeparam name="K">The type of asset to load.</typeparam>
  113.         /// <param name="source">The source file of the asset.</param>
  114.         /// <param name="asyncLoad">Whether to load it now or asynchronously and later on.</param>
  115.         /// <returns>A custom asset object.</returns>
  116.         public K LoadCustom<K>(string source, bool asyncLoad) where K : IAsset, new()
  117.         {
  118.             K newAsset = new K();
  119.             newAsset.Source = source;
  120.             newAsset.AssetManager = this;
  121.  
  122.             if (!asyncLoad)
  123.             {
  124.                 newAsset.Load();
  125.  
  126.                 content.Add(newAsset);
  127.             }
  128.             else
  129.             {
  130.                 asyncLoadables.Enqueue(newAsset);
  131.             }
  132.  
  133.             return newAsset;
  134.         }
  135.  
  136.         /// <summary>
  137.         /// Loads an asset.
  138.         /// </summary>
  139.         /// <typeparam name="T">The type of content item to load.</typeparam>
  140.         /// <param name="source">The source file of the asset.</param>
  141.         /// <param name="asyncLoad">Whether to load it now or asynchronously and later on.</param>
  142.         /// <returns>An Asset object.</returns>
  143.         /// <seealso cref="Asset{T}"/>
  144.         public Asset<T> Load<T>(string source, bool asyncLoad) where T : class
  145.         {
  146.             Asset<T> newAsset = new Asset<T>();
  147.             newAsset.Source = source;
  148.             newAsset.AssetManager = this;
  149.  
  150.             if (!asyncLoad)
  151.             {
  152.                 newAsset.Load();
  153.  
  154.                 content.Add(newAsset);
  155.             }
  156.             else
  157.             {
  158.                 asyncLoadables.Enqueue(newAsset);
  159.             }
  160.  
  161.             return newAsset;
  162.         }
  163.         #endregion
  164.  
  165.         #region Internal Loading (Async)
  166.         /// <summary>
  167.         /// Begins the asynchronous process of loading.
  168.         /// </summary>
  169.         public void BeginLoad()
  170.         {
  171.             isLoading = true;
  172.  
  173. #if ZUNE
  174.             InternalBeginLoad.Invoke(this, EventArgs.Empty);
  175.  
  176.             OnFinishLoad(null);
  177. #else
  178.             InternalBeginLoad.BeginInvoke(this, EventArgs.Empty, OnFinishLoad, null);
  179. #endif
  180.         }
  181.  
  182.         private void OnBeginLoad(object sender, EventArgs e)
  183.         {
  184.             total = asyncLoadables.Count;
  185.             current = 0;
  186.  
  187.             while (asyncLoadables.Count > 0)
  188.             {
  189.                 ILoadable asset = asyncLoadables.Dequeue();
  190.  
  191.                 if (asset.IsLoaded || content.Contains(asset))
  192.                     continue;
  193.  
  194.                 asset.Load();
  195.  
  196.                 current++;
  197.  
  198.                 content.Add(asset);
  199.  
  200.                 if (SimulateLargeContent)
  201.                     Thread.Sleep(250);
  202.             }
  203.         }
  204.  
  205.         private void OnFinishLoad(IAsyncResult result)
  206.         {
  207. #if !ZUNE
  208.             InternalBeginLoad.EndInvoke(result);
  209. #endif
  210.  
  211.             isLoading = false;
  212.  
  213.             if (FinishedLoad != null)
  214.                 FinishedLoad.Invoke(this, EventArgs.Empty);
  215.         }
  216.         #endregion
  217.  
  218.         #region Properties
  219.         /// <summary>
  220.         /// Gets or Sets whether or not to simulate large content.
  221.         /// </summary>
  222.         public bool SimulateLargeContent
  223.         {
  224.             get { return simulateLargeContent; }
  225.             set { simulateLargeContent = value; }
  226.         }
  227.  
  228.         /// <summary>
  229.         /// Gets the current number of assets loaded.
  230.         /// </summary>
  231.         public int Current { get { return current; } }
  232.  
  233.         /// <summary>
  234.         /// Gets the total number of assets that need to be loaded.
  235.         /// </summary>
  236.         public int Total { get { return total; } }
  237.  
  238.         /// <summary>
  239.         /// Gets whether or not the object is loading assets.
  240.         /// </summary>
  241.         public bool IsLoading { get { return isLoading; } }
  242.         #endregion
  243.     }
  244. }