PageRenderTime 83ms CodeModel.GetById 40ms app.highlight 7ms RepoModel.GetById 34ms app.codeStats 0ms

/ContentSystem/Rendering/EffectData.cs

#
C# | 173 lines | 107 code | 10 blank | 56 comment | 10 complexity | 332ae7413f22f81c5a3971ce7c8d7bcc MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.IO;
  4using Delta.ContentSystem.Rendering.Helpers;
  5using Delta.Engine.Dynamic;
  6using Delta.Utilities;
  7using Delta.Utilities.Helpers;
  8
  9namespace Delta.ContentSystem.Rendering
 10{
 11	/// <summary>
 12	/// The effect data class is the content implementation of a effect and
 13	/// handles all the saving and loading of an effect.
 14	/// Basically this class only contains a list of Emitters that is filled
 15	/// during loading. The further load logic is then in the EmitterData class.
 16	/// </summary>
 17	public class EffectData : Content, ISaveLoadBinary
 18	{
 19		#region Get (Static)
 20		/// <summary>
 21		/// This is the only method to load XmlData content. If a content object
 22		/// has already been loaded, it will be returned again.
 23		/// </summary>
 24		/// <param name="contentName">Name of the Xml content to load</param>
 25		/// <returns>The loaded XmlData object (or fallback if it failed)</returns>
 26		public static EffectData Get(string contentName)
 27		{
 28			return Get<EffectData>(contentName, ContentType.ParticleEffect);
 29		}
 30		#endregion
 31
 32		#region Emitters (Public)
 33		/// <summary>
 34		/// List of emitters.
 35		/// </summary>
 36		public List<EmitterData> Emitters
 37		{
 38			get;
 39			private set;
 40		}
 41		#endregion
 42
 43		#region Constructors
 44		/// <summary>
 45		/// Create and load new effect data. Use the static Get method to call this.
 46		/// </summary>
 47		/// <param name="setEffectName">Name of the effect.</param>
 48		protected EffectData(string setEffectName)
 49			: base(setEffectName, ContentType.ParticleEffect)
 50		{
 51		}
 52
 53		/// <summary>
 54		/// Create effect data from list of emitter data. Only used internally
 55		/// for the editors, it makes no sense to create content objects in the
 56		/// engine itself. You can dynamically create rendering classes like in
 57		/// this case a Effect class with custom emitters, but it is not a loaded
 58		/// EffectData content class then (the link to data will stay null in the
 59		/// Effect class).
 60		/// </summary>
 61		/// <param name="setEmitters">Set emitter data list</param>
 62		/// <exception cref="NullReferenceException">To create 'EffectData' you 
 63		/// have to provide a valid emitter data list!</exception>
 64		internal EffectData(List<EmitterData> setEmitters)
 65			// This is not a full content object yet, it is empty and needs to
 66			// be saved and then loaded again to become content.
 67			: base(EmptyName, ContentType.ParticleEffect)
 68		{
 69			if (setEmitters == null)
 70			{
 71				throw new NullReferenceException("To create 'EffectData' you have " +
 72				                                 "to provide a valid emitter data list!");
 73			}
 74
 75			Emitters = setEmitters;
 76		}
 77		#endregion
 78
 79		#region ISaveLoadBinary Members
 80		/// <summary>
 81		/// Load saved data back into this EffectData, usually only called from
 82		/// the Load method above from the Content System.
 83		/// </summary>
 84		/// <param name="reader">Reader to read the data from</param>
 85		public void Load(BinaryReader reader)
 86		{
 87			Emitters = new List<EmitterData>();
 88			try
 89			{
 90				// Simply read the number of emitters and load each of them.
 91				int numberOfEmitters = reader.ReadInt32();
 92				for (int index = 0; index < numberOfEmitters; index++)
 93				{
 94					Emitters.Add(Factory.Load<EmitterData>(reader));
 95				}
 96			}
 97			catch (Exception ex)
 98			{
 99				Log.Warning("Failed to load effect data '" + Name + "': " + ex);
100				FailedToLoad = true;
101			}
102		}
103
104		/// <summary>
105		/// Save effect data into stream. Usually called by the tool that saves
106		/// this data out (EffectEditor) or the ContentSystem for optimizations.
107		/// </summary>
108		/// <param name="writer">Writer for the stream to write into</param>
109		public void Save(BinaryWriter writer)
110		{
111			// Write how many emitters we have
112			writer.Write(Emitters.Count);
113			// And save them out one by one
114			for (int index = 0; index < Emitters.Count; index++)
115			{
116				Factory.Save(writer, Emitters[index]);
117			}
118		}
119		#endregion
120
121		#region Methods (Private)
122
123		#region Load
124		/// <summary>
125		/// Native load method, will just load or clone the effect data.
126		/// </summary>
127		/// <param name="alreadyLoadedNativeData">
128		/// The first instance that has already loaded the required content data
129		/// of this content class or just 'null' if there is none loaded yet (or
130		/// anymore).
131		/// </param>
132		protected override void Load(Content alreadyLoadedNativeData)
133		{
134			try
135			{
136				if (alreadyLoadedNativeData != null)
137				{
138					EffectData alreadyLoadedEffect = (EffectData)alreadyLoadedNativeData;
139					Emitters = new List<EmitterData>(alreadyLoadedEffect.Emitters);
140				} // if
141				else if (String.IsNullOrEmpty(RelativeFilePath))
142				{
143					// No file given, this is a generated effect, do not load anything!
144					Emitters = new List<EmitterData>();
145				}
146				else if (FileHelper.Exists(RelativeFilePath))
147				{
148					// Load via the ISaveLoadBinary interface methods below.
149					// Cloning should not really happen for effects anyway.
150					FileHelper.Load(RelativeFilePath, this);
151				} // else if
152				else
153				{
154					Log.Warning("Couldn't load the " + GetType().Name + " '" +
155					            Name + "' because the (relative) file path '" +
156					            RelativeFilePath +
157					            "' isn't valid or doesn't exists. Will just return the default" +
158					            " object.");
159					Emitters = new List<EmitterData>();
160				} // else
161			} // try
162			catch (Exception ex)
163			{
164				Log.Warning("Failed to load the '" + GetType().Name +
165				            "' because of reason:" + ex);
166				FailedToLoad = true;
167			} // catch
168		}
169		#endregion
170
171		#endregion
172	}
173}