/Agro2D/Managers/SpriteFactory.cs
C# | 294 lines | 167 code | 33 blank | 94 comment | 12 complexity | 7d52a339d39ec8fd2028d385081ce1d0 MD5 | raw file
- #region License
- //-----------------------------------------------------------------------------
- // Copyright (c) 2008, Aaron MacDougall, Daniel Jeffery
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are met:
- //
- // * Redistributions of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- //
- // * Redistributions in binary form must reproduce the above copyright notice,
- // this list of conditions and the following disclaimer in the documentation
- // and/or other materials provided with the distribution.
- //
- // * Neither the name of Aaron MacDougall or Daniel Jeffery nor the names of its contributors may
- // be used to endorse or promote products derived from this software without
- // specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- //-----------------------------------------------------------------------------
- #endregion
-
- #region Using Statements
- using System;
- using System.Collections.Generic;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Audio;
- using Microsoft.Xna.Framework.Content;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- using Microsoft.Xna.Framework.Storage;
- using System.Diagnostics;
- using System.Reflection;
-
- using Agro2DPipeline;
- #endregion
-
- namespace Agro2D
- {
- /// <summary>
- /// Stores types and clones them for use. Spritefactory can be
- /// loaded with a filename that describes these templates.
- /// </summary>
- public class SpriteFactory
- {
- #region Cstors/Dstors
- /// <summary>
- /// Consttructor.
- /// </summary>
- public SpriteFactory()
- {
- spriteConcreteTypes = new Dictionary<string, Sprite>();
- spriteInfo = new SpriteTemplateInfo();
-
- spriteInfoTemplates = new Dictionary<string, SpriteInfo>(10);
- }
- #endregion
-
- #region Public Interface
-
- public void Initialize(GraphicsDevice graphicsDevice)
- {
- this.graphicsDevice = graphicsDevice;
- SpriteLoader.Initialize(graphicsDevice);
- }
- /// <summary>
- /// Loads the Sprite type file and loads these types so they can be created for use later.
- /// </summary>
- /// <param name="assetName">The name of the XML asset that contains the Template data</param>
- /// <param name="content">A content manager with which to load the type data asset</param>
- /// <param name="spriteManager">SpriteManager to pass to the constructor of Sprite Prototypes</param>
- public virtual void LoadSpriteTypesFile(string assetName, ContentManager content, SpriteManager spriteManager, Assembly myAssembly)
- {
- //Clear();
- spriteInfo = content.Load<SpriteTemplateInfo>(assetName);
- int spriteCount = spriteInfo.Sprites.Count;
-
- // Sprites and animations.
- foreach(SpriteInfo info in this.spriteInfo.Sprites)
- {
- string type = string.Empty;
- if(info.Properties.ContainsKey("Type"))
- type = info.Properties["Type"];
-
- Debug.Assert(type != string.Empty, "Sprite type in: \"" + assetName +
- "\" hasn't been given a type name. Loading aborted.");
-
- if(type == string.Empty) {
- Log.Instance.LogMessage("Sprite type in: \"" + assetName +
- "\" hasn't been given a type name. Loading aborted.");
- return;
- }
-
- try
- {
- if(!spriteInfoTemplates.ContainsKey(type))
- spriteInfoTemplates.Add(type, info);
- }
- catch(ArgumentException e)
- {
- Debug.Assert(false, e.Message + ". Loading aborted.");
- Log.Instance.LogMessage(e.Message + ". Loading aborted.");
- return;
- }
- }
- }
-
- /// <summary>
- /// Use this method to instantiate a Template (specified in file) at run-time.
- /// Associated data will be set. 'Overload' any of its data that you need modified.
- /// This functionality is used internally by Level to overload types.
- /// </summary>
- /// <param name="type">The name of the type to instantiate</param>
- /// <returns>A sprite of the the C# type and custom Sprite type specified in the type file</returns>
- public virtual Sprite CreateTemplateInstance(string type, SpriteManager spriteManager)
- {
- Debug.Assert(type.Length > 0);
- Debug.Assert(spriteInfoTemplates.ContainsKey(type), "Sprite type: \"" + type + "\" not registered with SpriteFactory");
-
- if(spriteInfoTemplates.ContainsKey(type))
- {
- SpriteInfo info = spriteInfoTemplates[type];
- Sprite spriteTemplate = SpriteLoader.LoadSpriteTemplate(info, spriteManager, null);
- // Load animations.
- if(info.Animation != null)
- spriteTemplate.Animation = SpriteLoader.LoadAnimations(info.Animation, null);
-
- return spriteTemplate;
- }
- else
- {
- Log.Instance.LogMessage("SpriteManager.CreateTemplateInstance: type \"" + type + "\" has not been loaded");
- return null;
- }
-
-
- }
-
- /// <summary>
- /// Creates a instance of a class registered with this factory. No data is loaded from script, this is done
- /// by CreateSpriteTemplate type
- /// </summary>
- /// <param name="type"></param>
- /// <param name="spriteManager"></param>
- /// <returns></returns>
- internal Sprite CreateSpriteInstance(string type, SpriteManager spriteManager)
- {
- Debug.Assert(spriteConcreteTypes.ContainsKey(type), "Sprite type: \"" + type + "\" not registered with SpriteFactory."
- + " You must manually register it to SpriteFactory");
-
- if(spriteConcreteTypes.ContainsKey(type))
- {
- return (Sprite)spriteConcreteTypes[type].Clone();
- }
- else
- {
- Log.Instance.LogMessage("SpriteManager.CreateSpriteInstance: type \"" + type + "\" has not been loaded."
- + " You must manually register it to SpriteFactory");
- return null;
- }
- }
-
- /// <summary>
- /// Reload sprite types. Note that it is safe to clear the current types as they are cloned in the Level,
- /// and not used directly.
- /// </summary>
- public void ReLoadSpriteTypesFile(string assetName, ContentManager content, SpriteManager spriteManager)
- {
- LoadSpriteTypesFile(assetName, content, spriteManager, null);
- }
-
- /// <summary>
- /// Register a sprite with the Factory so it can be created through CreateSprite later.
- /// This will save you duplicating loading code.
- /// </summary>
- /// <param name="type">The name to give the type you are creating</param>
- /// <param name="obj">The actual sprite with which to clone later through CreateSprite</param>
- public void AddSpriteType(string type, Sprite sprite)
- {
- Debug.Assert(!spriteConcreteTypes.ContainsKey(type));
-
- if(!spriteConcreteTypes.ContainsKey(type))
- spriteConcreteTypes.Add(type, sprite);
- else
- {
- Log.Instance.LogMessage("SpriteFactory.AddSprite: type \"" + type
- + "\" has already been added to SpriteFactory");
- }
- }
-
- /// <summary>
- /// Remove a sprite from the factory; it won't be able to be instantiated later.
- /// </summary>
- /// <param name="sprite">The type of sprite with which to remove</param>
- public void RemoveSpriteType(Sprite sprite)
- {
- Debug.Assert(spriteConcreteTypes.ContainsKey(sprite.Type));
-
- if(spriteConcreteTypes.ContainsKey(sprite.Type))
- spriteConcreteTypes.Remove(sprite.Type);
- else
- {
- Log.Instance.LogMessage("SpriteFactory.RemoveSprite: type \"" + sprite.Type
- + "\" does not exist in SpriteFactory");
- }
-
- }
- /// <summary>
- /// Remove a sprite from the Factory; it won't be able to be instantiated later.
- /// </summary>
- /// <param name="sprite">The type of sprite with which to remove</param>
- public void RemoveSpriteType(string type)
- {
- Debug.Assert(spriteConcreteTypes.ContainsKey(type));
-
- if(spriteConcreteTypes.ContainsKey(type))
- spriteConcreteTypes.Remove(type);
- else
- {
- Log.Instance.LogMessage("SpriteFactory.RemoveSprite: type \"" + type + "\" does not exist in SpriteFactory");
- }
- }
-
- public Dictionary<string, SpriteInfo> GetSpriteInfoTemplates()
- {
- return spriteInfoTemplates;
- }
-
- /// <summary>
- /// Clear all sprites from the Factory.
- /// </summary>
- public void Clear()
- {
- spriteConcreteTypes.Clear();
- spriteInfo.Sprites.Clear();
- }
- #endregion
-
- #region Private Interface
- #endregion
-
- #region Properties
- /// <summary>
- /// Singleton interface to retrieve the Sprite Factory.
- /// </summary>
- public static SpriteFactory Instance
- {
- get { return instance; }
- }
- #endregion
-
- #region Attributes
- // Prototypes.
- private static readonly SpriteFactory instance = new SpriteFactory();
- // Concrete C# types
- protected Dictionary<string, Sprite> spriteConcreteTypes;
- // Script types
- protected Dictionary<string, SpriteInfo> spriteInfoTemplates;
- protected SpriteTemplateInfo spriteInfo;
- GraphicsDevice graphicsDevice;
- #endregion
- }
-
- /// <summary>
- /// Reads in .xnb content to load SpriteTemplateInfo.
- /// </summary>
- public class SpriteTemplateReader : ContentTypeReader<SpriteTemplateInfo>
- {
- /// <summary>
- /// Takes the Level input, and converts it to a format that can be used to
- /// at runtime.
- /// </summary>
- protected override SpriteTemplateInfo Read(ContentReader input, SpriteTemplateInfo instance)
- {
- instance = new SpriteTemplateInfo();
- SpriteLoader.ReadSprites(input, instance);
-
- return instance;
- }
-
- }
-
- }