/WorldModel/WorldModel/GameLoader/ObjectSaver.cs

http://quest.codeplex.com · C# · 340 lines · 281 code · 58 blank · 1 comment · 28 complexity · 1975749bb9478efe21fc7a2e50bbb17a MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Xml;
  6. namespace TextAdventures.Quest
  7. {
  8. internal partial class GameSaver
  9. {
  10. private class ObjectsSaver : IElementsSaver
  11. {
  12. #region IElementsSaver Members
  13. public ElementType AppliesTo
  14. {
  15. get { return ElementType.Object; }
  16. }
  17. public void Save(GameXmlWriter writer, WorldModel worldModel)
  18. {
  19. ObjectSaver elementSaver = new ObjectSaver();
  20. elementSaver.GameSaver = GameSaver;
  21. IEnumerable<Element> allObjects = worldModel.Elements.GetElements(ElementType.Object).OrderBy(o => o.MetaFields[MetaFieldDefinitions.SortIndex]);
  22. foreach (Element e in allObjects.Where(e => e.Parent == null && GameSaver.CanSave(e)))
  23. {
  24. SaveObjectAndChildren(writer, allObjects, e, elementSaver);
  25. }
  26. }
  27. public GameSaver GameSaver { get; set; }
  28. #endregion
  29. private void SaveObjectAndChildren(GameXmlWriter writer, IEnumerable<Element> allObjects, Element e, ObjectSaver saver)
  30. {
  31. saver.StartSave(writer, e);
  32. IEnumerable<Element> orderedChildren = from child in allObjects
  33. where child.Parent == e
  34. orderby child.MetaFields[MetaFieldDefinitions.SortIndex]
  35. select child;
  36. foreach (Element child in orderedChildren)
  37. {
  38. SaveObjectAndChildren(writer, allObjects, child, saver);
  39. }
  40. saver.EndSave(writer, e);
  41. }
  42. }
  43. private class ObjectSaver : ElementSaverBase
  44. {
  45. private Dictionary<ObjectType, IObjectSaver> m_savers = new Dictionary<ObjectType, IObjectSaver>();
  46. public ObjectSaver()
  47. {
  48. AddIgnoreField("type");
  49. AddIgnoreField("parent");
  50. }
  51. protected override void Initialise()
  52. {
  53. // Use Reflection to create instances of all IObjectSavers
  54. foreach (Type t in TextAdventures.Utility.Classes.GetImplementations(System.Reflection.Assembly.GetExecutingAssembly(),
  55. typeof(IObjectSaver)))
  56. {
  57. AddSaver((IObjectSaver)Activator.CreateInstance(t));
  58. }
  59. }
  60. private void AddSaver(IObjectSaver saver)
  61. {
  62. saver.ObjectSaver = this;
  63. m_savers.Add(saver.AppliesTo, saver);
  64. }
  65. #region IElementSaver Members
  66. public override ElementType AppliesTo
  67. {
  68. get { return ElementType.Object; }
  69. }
  70. public override void Save(GameXmlWriter writer, Element e)
  71. {
  72. IObjectSaver saver;
  73. if (GetSaver(writer, e, out saver))
  74. {
  75. saver.StartSave(writer, e);
  76. saver.EndSave(writer, e);
  77. }
  78. }
  79. #endregion
  80. private bool GetSaver(GameXmlWriter writer, Element e, out IObjectSaver saver)
  81. {
  82. if (!m_savers.TryGetValue(e.Type, out saver))
  83. {
  84. throw new Exception("ERROR: No ObjectSaver for type " + e.Type.ToString());
  85. }
  86. return true;
  87. }
  88. public void StartSave(GameXmlWriter writer, Element e)
  89. {
  90. IObjectSaver saver;
  91. if (GetSaver(writer, e, out saver))
  92. {
  93. saver.StartSave(writer, e);
  94. }
  95. }
  96. public void EndSave(GameXmlWriter writer, Element e)
  97. {
  98. IObjectSaver saver;
  99. if (GetSaver(writer, e, out saver))
  100. {
  101. saver.EndSave(writer, e);
  102. }
  103. }
  104. protected override bool CanSaveAttribute(string attribute, Element e)
  105. {
  106. if (!base.CanSaveAttribute(attribute, e)) return false;
  107. return m_savers[e.Type].CanSaveAttribute(attribute);
  108. }
  109. protected override bool CanSaveTypeName(GameXmlWriter writer, string type, Element e)
  110. {
  111. if (!base.CanSaveTypeName(writer, type, e)) return false;
  112. if (e.Type == ObjectType.Command && e.Fields[FieldDefinitions.IsVerb] && type == "defaultverb") return false;
  113. return true;
  114. }
  115. private interface IObjectSaver
  116. {
  117. ObjectType AppliesTo { get; }
  118. void StartSave(GameXmlWriter writer, Element e);
  119. void EndSave(GameXmlWriter writer, Element e);
  120. ObjectSaver ObjectSaver { set; }
  121. bool CanSaveAttribute(string attribute);
  122. }
  123. private abstract class ObjectSaverBase : IObjectSaver
  124. {
  125. private List<string> m_ignoreAttributes = new List<string>();
  126. protected void AddIgnoreField(string field)
  127. {
  128. m_ignoreAttributes.Add(field);
  129. }
  130. #region IObjectSaver Members
  131. public abstract ObjectType AppliesTo { get; }
  132. public abstract void StartSave(GameXmlWriter writer, Element e);
  133. public abstract void EndSave(GameXmlWriter writer, Element e);
  134. public ObjectSaver ObjectSaver
  135. {
  136. get;
  137. set;
  138. }
  139. public bool CanSaveAttribute(string attribute)
  140. {
  141. if (m_ignoreAttributes.Contains(attribute)) return false;
  142. return true;
  143. }
  144. #endregion
  145. }
  146. private class ObjectElementSaver : ObjectSaverBase
  147. {
  148. #region IObjectSaver Members
  149. public override ObjectType AppliesTo
  150. {
  151. get { return ObjectType.Object; }
  152. }
  153. public override void StartSave(GameXmlWriter writer, Element e)
  154. {
  155. writer.WriteStartElement("object");
  156. writer.WriteAttributeString("name", e.Name);
  157. ObjectSaver.SaveFields(writer, e);
  158. }
  159. public override void EndSave(GameXmlWriter writer, Element e)
  160. {
  161. writer.WriteEndElement();
  162. }
  163. #endregion
  164. }
  165. private class GameElementSaver : ObjectSaverBase
  166. {
  167. public GameElementSaver()
  168. {
  169. AddIgnoreField("gamename");
  170. }
  171. #region IObjectSaver Members
  172. public override ObjectType AppliesTo
  173. {
  174. get { return ObjectType.Game; }
  175. }
  176. public override void StartSave(GameXmlWriter writer, Element e)
  177. {
  178. writer.WriteStartElement("game");
  179. writer.WriteAttributeString("name", e.Fields.GetString("gamename"));
  180. ObjectSaver.SaveFields(writer, e);
  181. }
  182. public override void EndSave(GameXmlWriter writer, Element e)
  183. {
  184. writer.WriteEndElement();
  185. }
  186. #endregion
  187. }
  188. private class CommandSaver : ObjectSaverBase
  189. {
  190. public CommandSaver()
  191. {
  192. AddIgnoreField("isverb");
  193. AddIgnoreField("anonymous");
  194. }
  195. #region IObjectSaver Members
  196. public override ObjectType AppliesTo
  197. {
  198. get { return ObjectType.Command; }
  199. }
  200. public override void StartSave(GameXmlWriter writer, Element e)
  201. {
  202. if (e.Fields[FieldDefinitions.IsVerb])
  203. {
  204. writer.WriteStartElement("verb");
  205. }
  206. else
  207. {
  208. writer.WriteStartElement("command");
  209. }
  210. if (writer.Mode == SaveMode.SavedGame || !e.Fields[FieldDefinitions.Anonymous])
  211. {
  212. writer.WriteAttributeString("name", e.Name);
  213. }
  214. ObjectSaver.SaveFields(writer, e);
  215. }
  216. public override void EndSave(GameXmlWriter writer, Element e)
  217. {
  218. writer.WriteEndElement();
  219. }
  220. #endregion
  221. }
  222. private class ExitElementSaver : ObjectSaverBase
  223. {
  224. public ExitElementSaver()
  225. {
  226. AddIgnoreField("to");
  227. AddIgnoreField("alias");
  228. AddIgnoreField("anonymous");
  229. }
  230. public override ObjectType AppliesTo
  231. {
  232. get { return ObjectType.Exit; }
  233. }
  234. public override void StartSave(GameXmlWriter writer, Element e)
  235. {
  236. writer.WriteStartElement("exit");
  237. if (writer.Mode == SaveMode.SavedGame || !e.Fields[FieldDefinitions.Anonymous])
  238. {
  239. writer.WriteAttributeString("name", e.Name);
  240. }
  241. if (!string.IsNullOrEmpty(e.Fields[FieldDefinitions.Alias]))
  242. {
  243. writer.WriteAttributeString("alias", e.Fields[FieldDefinitions.Alias]);
  244. }
  245. if (e.Fields[FieldDefinitions.To] != null)
  246. {
  247. writer.WriteAttributeString("to", e.Fields[FieldDefinitions.To].Name);
  248. }
  249. ObjectSaver.SaveFields(writer, e);
  250. }
  251. public override void EndSave(GameXmlWriter writer, Element e)
  252. {
  253. writer.WriteEndElement();
  254. }
  255. }
  256. private class TurnScriptElementSaver : ObjectSaverBase
  257. {
  258. public TurnScriptElementSaver()
  259. {
  260. AddIgnoreField("anonymous");
  261. }
  262. public override ObjectType AppliesTo
  263. {
  264. get { return ObjectType.TurnScript; }
  265. }
  266. public override void StartSave(GameXmlWriter writer, Element e)
  267. {
  268. writer.WriteStartElement("turnscript");
  269. if (writer.Mode == SaveMode.SavedGame || !e.Fields[FieldDefinitions.Anonymous])
  270. {
  271. writer.WriteAttributeString("name", e.Name);
  272. }
  273. ObjectSaver.SaveFields(writer, e);
  274. }
  275. public override void EndSave(GameXmlWriter writer, Element e)
  276. {
  277. writer.WriteEndElement();
  278. }
  279. }
  280. }
  281. }
  282. }