PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/Agro2D/Managers/SpriteFactory.cs

http://agro2d.codeplex.com
C# | 294 lines | 167 code | 33 blank | 94 comment | 12 complexity | 7d52a339d39ec8fd2028d385081ce1d0 MD5 | raw file
  1. #region License
  2. //-----------------------------------------------------------------------------
  3. // Copyright (c) 2008, Aaron MacDougall, Daniel Jeffery
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. // * Redistributions of source code must retain the above copyright notice,
  10. // this list of conditions and the following disclaimer.
  11. //
  12. // * Redistributions in binary form must reproduce the above copyright notice,
  13. // this list of conditions and the following disclaimer in the documentation
  14. // and/or other materials provided with the distribution.
  15. //
  16. // * Neither the name of Aaron MacDougall or Daniel Jeffery nor the names of its contributors may
  17. // be used to endorse or promote products derived from this software without
  18. // specific prior written permission.
  19. //
  20. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  24. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. // POSSIBILITY OF SUCH DAMAGE.
  31. //-----------------------------------------------------------------------------
  32. #endregion
  33. #region Using Statements
  34. using System;
  35. using System.Collections.Generic;
  36. using Microsoft.Xna.Framework;
  37. using Microsoft.Xna.Framework.Audio;
  38. using Microsoft.Xna.Framework.Content;
  39. using Microsoft.Xna.Framework.Graphics;
  40. using Microsoft.Xna.Framework.Input;
  41. using Microsoft.Xna.Framework.Storage;
  42. using System.Diagnostics;
  43. using System.Reflection;
  44. using Agro2DPipeline;
  45. #endregion
  46. namespace Agro2D
  47. {
  48. /// <summary>
  49. /// Stores types and clones them for use. Spritefactory can be
  50. /// loaded with a filename that describes these templates.
  51. /// </summary>
  52. public class SpriteFactory
  53. {
  54. #region Cstors/Dstors
  55. /// <summary>
  56. /// Consttructor.
  57. /// </summary>
  58. public SpriteFactory()
  59. {
  60. spriteConcreteTypes = new Dictionary<string, Sprite>();
  61. spriteInfo = new SpriteTemplateInfo();
  62. spriteInfoTemplates = new Dictionary<string, SpriteInfo>(10);
  63. }
  64. #endregion
  65. #region Public Interface
  66. public void Initialize(GraphicsDevice graphicsDevice)
  67. {
  68. this.graphicsDevice = graphicsDevice;
  69. SpriteLoader.Initialize(graphicsDevice);
  70. }
  71. /// <summary>
  72. /// Loads the Sprite type file and loads these types so they can be created for use later.
  73. /// </summary>
  74. /// <param name="assetName">The name of the XML asset that contains the Template data</param>
  75. /// <param name="content">A content manager with which to load the type data asset</param>
  76. /// <param name="spriteManager">SpriteManager to pass to the constructor of Sprite Prototypes</param>
  77. public virtual void LoadSpriteTypesFile(string assetName, ContentManager content, SpriteManager spriteManager, Assembly myAssembly)
  78. {
  79. //Clear();
  80. spriteInfo = content.Load<SpriteTemplateInfo>(assetName);
  81. int spriteCount = spriteInfo.Sprites.Count;
  82. // Sprites and animations.
  83. foreach(SpriteInfo info in this.spriteInfo.Sprites)
  84. {
  85. string type = string.Empty;
  86. if(info.Properties.ContainsKey("Type"))
  87. type = info.Properties["Type"];
  88. Debug.Assert(type != string.Empty, "Sprite type in: \"" + assetName +
  89. "\" hasn't been given a type name. Loading aborted.");
  90. if(type == string.Empty) {
  91. Log.Instance.LogMessage("Sprite type in: \"" + assetName +
  92. "\" hasn't been given a type name. Loading aborted.");
  93. return;
  94. }
  95. try
  96. {
  97. if(!spriteInfoTemplates.ContainsKey(type))
  98. spriteInfoTemplates.Add(type, info);
  99. }
  100. catch(ArgumentException e)
  101. {
  102. Debug.Assert(false, e.Message + ". Loading aborted.");
  103. Log.Instance.LogMessage(e.Message + ". Loading aborted.");
  104. return;
  105. }
  106. }
  107. }
  108. /// <summary>
  109. /// Use this method to instantiate a Template (specified in file) at run-time.
  110. /// Associated data will be set. 'Overload' any of its data that you need modified.
  111. /// This functionality is used internally by Level to overload types.
  112. /// </summary>
  113. /// <param name="type">The name of the type to instantiate</param>
  114. /// <returns>A sprite of the the C# type and custom Sprite type specified in the type file</returns>
  115. public virtual Sprite CreateTemplateInstance(string type, SpriteManager spriteManager)
  116. {
  117. Debug.Assert(type.Length > 0);
  118. Debug.Assert(spriteInfoTemplates.ContainsKey(type), "Sprite type: \"" + type + "\" not registered with SpriteFactory");
  119. if(spriteInfoTemplates.ContainsKey(type))
  120. {
  121. SpriteInfo info = spriteInfoTemplates[type];
  122. Sprite spriteTemplate = SpriteLoader.LoadSpriteTemplate(info, spriteManager, null);
  123. // Load animations.
  124. if(info.Animation != null)
  125. spriteTemplate.Animation = SpriteLoader.LoadAnimations(info.Animation, null);
  126. return spriteTemplate;
  127. }
  128. else
  129. {
  130. Log.Instance.LogMessage("SpriteManager.CreateTemplateInstance: type \"" + type + "\" has not been loaded");
  131. return null;
  132. }
  133. }
  134. /// <summary>
  135. /// Creates a instance of a class registered with this factory. No data is loaded from script, this is done
  136. /// by CreateSpriteTemplate type
  137. /// </summary>
  138. /// <param name="type"></param>
  139. /// <param name="spriteManager"></param>
  140. /// <returns></returns>
  141. internal Sprite CreateSpriteInstance(string type, SpriteManager spriteManager)
  142. {
  143. Debug.Assert(spriteConcreteTypes.ContainsKey(type), "Sprite type: \"" + type + "\" not registered with SpriteFactory."
  144. + " You must manually register it to SpriteFactory");
  145. if(spriteConcreteTypes.ContainsKey(type))
  146. {
  147. return (Sprite)spriteConcreteTypes[type].Clone();
  148. }
  149. else
  150. {
  151. Log.Instance.LogMessage("SpriteManager.CreateSpriteInstance: type \"" + type + "\" has not been loaded."
  152. + " You must manually register it to SpriteFactory");
  153. return null;
  154. }
  155. }
  156. /// <summary>
  157. /// Reload sprite types. Note that it is safe to clear the current types as they are cloned in the Level,
  158. /// and not used directly.
  159. /// </summary>
  160. public void ReLoadSpriteTypesFile(string assetName, ContentManager content, SpriteManager spriteManager)
  161. {
  162. LoadSpriteTypesFile(assetName, content, spriteManager, null);
  163. }
  164. /// <summary>
  165. /// Register a sprite with the Factory so it can be created through CreateSprite later.
  166. /// This will save you duplicating loading code.
  167. /// </summary>
  168. /// <param name="type">The name to give the type you are creating</param>
  169. /// <param name="obj">The actual sprite with which to clone later through CreateSprite</param>
  170. public void AddSpriteType(string type, Sprite sprite)
  171. {
  172. Debug.Assert(!spriteConcreteTypes.ContainsKey(type));
  173. if(!spriteConcreteTypes.ContainsKey(type))
  174. spriteConcreteTypes.Add(type, sprite);
  175. else
  176. {
  177. Log.Instance.LogMessage("SpriteFactory.AddSprite: type \"" + type
  178. + "\" has already been added to SpriteFactory");
  179. }
  180. }
  181. /// <summary>
  182. /// Remove a sprite from the factory; it won't be able to be instantiated later.
  183. /// </summary>
  184. /// <param name="sprite">The type of sprite with which to remove</param>
  185. public void RemoveSpriteType(Sprite sprite)
  186. {
  187. Debug.Assert(spriteConcreteTypes.ContainsKey(sprite.Type));
  188. if(spriteConcreteTypes.ContainsKey(sprite.Type))
  189. spriteConcreteTypes.Remove(sprite.Type);
  190. else
  191. {
  192. Log.Instance.LogMessage("SpriteFactory.RemoveSprite: type \"" + sprite.Type
  193. + "\" does not exist in SpriteFactory");
  194. }
  195. }
  196. /// <summary>
  197. /// Remove a sprite from the Factory; it won't be able to be instantiated later.
  198. /// </summary>
  199. /// <param name="sprite">The type of sprite with which to remove</param>
  200. public void RemoveSpriteType(string type)
  201. {
  202. Debug.Assert(spriteConcreteTypes.ContainsKey(type));
  203. if(spriteConcreteTypes.ContainsKey(type))
  204. spriteConcreteTypes.Remove(type);
  205. else
  206. {
  207. Log.Instance.LogMessage("SpriteFactory.RemoveSprite: type \"" + type + "\" does not exist in SpriteFactory");
  208. }
  209. }
  210. public Dictionary<string, SpriteInfo> GetSpriteInfoTemplates()
  211. {
  212. return spriteInfoTemplates;
  213. }
  214. /// <summary>
  215. /// Clear all sprites from the Factory.
  216. /// </summary>
  217. public void Clear()
  218. {
  219. spriteConcreteTypes.Clear();
  220. spriteInfo.Sprites.Clear();
  221. }
  222. #endregion
  223. #region Private Interface
  224. #endregion
  225. #region Properties
  226. /// <summary>
  227. /// Singleton interface to retrieve the Sprite Factory.
  228. /// </summary>
  229. public static SpriteFactory Instance
  230. {
  231. get { return instance; }
  232. }
  233. #endregion
  234. #region Attributes
  235. // Prototypes.
  236. private static readonly SpriteFactory instance = new SpriteFactory();
  237. // Concrete C# types
  238. protected Dictionary<string, Sprite> spriteConcreteTypes;
  239. // Script types
  240. protected Dictionary<string, SpriteInfo> spriteInfoTemplates;
  241. protected SpriteTemplateInfo spriteInfo;
  242. GraphicsDevice graphicsDevice;
  243. #endregion
  244. }
  245. /// <summary>
  246. /// Reads in .xnb content to load SpriteTemplateInfo.
  247. /// </summary>
  248. public class SpriteTemplateReader : ContentTypeReader<SpriteTemplateInfo>
  249. {
  250. /// <summary>
  251. /// Takes the Level input, and converts it to a format that can be used to
  252. /// at runtime.
  253. /// </summary>
  254. protected override SpriteTemplateInfo Read(ContentReader input, SpriteTemplateInfo instance)
  255. {
  256. instance = new SpriteTemplateInfo();
  257. SpriteLoader.ReadSprites(input, instance);
  258. return instance;
  259. }
  260. }
  261. }