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

/ContentSystem/Rendering/EffectData.cs

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