- renamed aa to offset
[FaRetSys.git] / SaveLoad.cs
blob82c847c40cfd50312a65372a967e79b8eeaac01d
1 using Cairo;
2 using System;
3 using System.Collections;
4 using System.IO;
5 using System.Xml;
6 using Gtk;
7 using Mono.Unix;
9 namespace Eithne
11 class BlockError
13 private readonly string name, version, assembly, _class;
15 public string Name { get { return name; } }
16 public string Version { get { return version; } }
17 public string Assembly { get { return assembly; } }
18 public string Class { get { return _class; } }
20 public BlockError(string name, string version, string assembly, string _class)
22 this.name = name;
23 this.version = version;
24 this.assembly = assembly;
25 this._class = _class;
28 public static bool operator == (BlockError e1, BlockError e2)
30 return e1.name == e2.name && e1.version == e2.version && e1.assembly == e2.assembly && e1._class == e2._class;
33 public static bool operator != (BlockError e1, BlockError e2)
35 return !(e1==e2);
38 public override bool Equals(object o)
40 if(!(o is BlockError))
41 return false;
42 return this == (BlockError)o;
45 public override int GetHashCode()
47 return name.GetHashCode() ^ Version.GetHashCode() ^ Assembly.GetHashCode() ^ Class.GetHashCode();
51 class SaveLoad
53 private static XmlNode GenInfo(XmlDocument x, string fn)
55 XmlNode n, root = x.CreateNode(XmlNodeType.Element, "info", "");
57 n = x.CreateNode(XmlNodeType.Element, "version", "");
58 n.InnerText = Program.Version;
59 root.AppendChild(n);
61 n = x.CreateNode(XmlNodeType.Element, "filename", "");
62 n.InnerText = fn;
63 root.AppendChild(n);
65 n = x.CreateNode(XmlNodeType.Element, "time", "");
66 n.InnerText = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss zzz");
67 root.AppendChild(n);
69 return root;
72 private static XmlNode GenBlock(XmlDocument x, Block b, Hashtable h)
74 XmlNode n, n2, root = x.CreateNode(XmlNodeType.Element, "block", "");
76 XmlAttribute attr = x.CreateAttribute("id");
77 attr.Value = ((int)h[b]).ToString();
78 root.Attributes.Append(attr);
80 n = x.CreateNode(XmlNodeType.Element, "info", "");
82 n2 = x.CreateNode(XmlNodeType.Element, "name", "");
83 n2.InnerText = b.Plugin.Info.Name;
84 n.AppendChild(n2);
86 n2 = x.CreateNode(XmlNodeType.Element, "version", "");
87 n2.InnerText = b.Plugin.Info.Version;
88 n.AppendChild(n2);
90 Source s = (Source)b.Plugin.Source;
91 n2 = x.CreateNode(XmlNodeType.Element, "assembly", "");
92 n2.InnerText = s.Assembly;
93 n.AppendChild(n2);
94 n2 = x.CreateNode(XmlNodeType.Element, "class", "");
95 n2.InnerText = s.Class;
96 n.AppendChild(n2);
98 root.AppendChild(n);
100 n = x.CreateNode(XmlNodeType.Element, "x", "");
101 n.InnerText = b.X.ToString();
102 root.AppendChild(n);
104 n = x.CreateNode(XmlNodeType.Element, "y", "");
105 n.InnerText = b.Y.ToString();
106 root.AppendChild(n);
108 b.Plugin.XmlDoc = x;
109 n = b.Plugin.Config;
110 if(n == null)
111 n = x.CreateNode(XmlNodeType.Element, "config", "");
112 else if(n.Name != "config")
114 n = x.CreateNode(XmlNodeType.Element, "config", "");
115 n2 = x.CreateNode(XmlNodeType.Comment, "", "");
116 n2.InnerText = " Plugin returns incorrect configuration data! ";
117 n.AppendChild(n2);
119 root.AppendChild(n);
121 for(int i=0; i<b.Plugin.NumOut; i++)
123 n = x.CreateNode(XmlNodeType.Element, "socket", "");
125 if(b.SocketOut[i].Other != null)
127 n2 = x.CreateNode(XmlNodeType.Element, "connection", "");
128 n2.InnerText = ((int)h[b.SocketOut[i].Other.Parent]).ToString();
129 n.AppendChild(n2);
131 n2 = x.CreateNode(XmlNodeType.Element, "other", "");
132 n2.InnerText = b.SocketOut[i].Other.Num.ToString();
133 n.AppendChild(n2);
136 root.AppendChild(n);
139 return root;
142 private static XmlNode GenSchematic(XmlDocument x, Schematic s)
144 XmlNode root = x.CreateNode(XmlNodeType.Element, "schematic", "");
145 ArrayList l = s.Blocks;
146 Hashtable h = new Hashtable();
148 for(int i=0; i<l.Count; i++)
149 h.Add(l[i], i);
151 foreach(Block b in l)
152 root.AppendChild(GenBlock(x, b, h));
154 return root;
157 public static void Save(string fn, Schematic s)
159 XmlDocument x = new XmlDocument();
160 XmlNode n;
162 n = x.CreateNode(XmlNodeType.XmlDeclaration, "", "");
163 (n as XmlDeclaration).Encoding = "utf-8";
164 x.AppendChild(n);
166 n = x.CreateNode(XmlNodeType.Comment, "", "");
167 n.InnerText = String.Format(" {0} schematic. Do not hand modify. ", About.Name);
168 x.AppendChild(n);
170 n = x.CreateNode(XmlNodeType.Element, "eithne", "");
171 x.AppendChild(n);
173 n.AppendChild(GenInfo(x, fn));
174 n.AppendChild(GenSchematic(x, s));
176 x.Save(fn);
179 public static Block LoadBlock(XmlNode root, Context c, Hashtable h, ArrayList errors, Schematic schematic)
181 int x = Int32.Parse(root.SelectSingleNode("x").InnerText);
182 int y = Int32.Parse(root.SelectSingleNode("y").InnerText);
183 string sassembly = root.SelectSingleNode("info/assembly").InnerText;
184 string sclass = root.SelectSingleNode("info/class").InnerText;
185 int n = Int32.Parse(root.Attributes["id"].Value);
186 XmlNode config = root.SelectSingleNode("config");
188 Block b;
190 Source s = new Source(sassembly, sclass);
191 IFactory f = (IFactory)PluginDB.RevOrigin[s];
192 if(f == null)
194 string sname = root.SelectSingleNode("info/name").InnerText;
195 string sversion = root.SelectSingleNode("info/version").InnerText;
197 BlockError e = new BlockError(sname, sversion, sassembly, sclass);
198 if(!errors.Contains(e))
199 errors.Add(e);
201 b = null;
203 else
205 Plugin.Base p = f.Create();
206 p.Source = s;
208 b = new Block(schematic, c, p, x, y);
209 b.Plugin.Config = config;
211 h.Add(n, b);
214 return b;
217 public static void MakeConnections(XmlNode root, Hashtable h, Block from)
219 XmlNodeList nl = root.SelectNodes("socket");
221 int i = 0;
222 foreach(XmlNode n in nl)
224 XmlNode n2 = n.SelectSingleNode("connection");
225 if(n2 != null)
227 Block to = (Block)h[Int32.Parse(n2.InnerText)];
228 int j = Int32.Parse(n.SelectSingleNode("other").InnerText);
230 from.SocketOut[i].Connect(to.SocketIn[j]);
233 i++;
237 public static ArrayList Load(string fn, Schematic s)
239 ArrayList errors = new ArrayList();
240 ArrayList blocks = new ArrayList();
241 Hashtable h = new Hashtable();
243 XmlDocument x = new XmlDocument();
244 StreamReader sr = new StreamReader(fn);
245 x.Load(sr);
246 sr.Close();
247 XmlNode root = x.DocumentElement;
249 if(root.Name != "eithne")
251 new DialogMessage(String.Format(Catalog.GetString("File <i>{0}</i> is not an eithne system schematic!"), fn));
253 return null;
256 XmlNodeList nl = root.SelectNodes("schematic/block");
258 Context c = Gdk.Context.CreateDrawable(s.GdkWindow);
260 foreach(XmlNode n in nl)
261 blocks.Add(LoadBlock(n, c, h, errors, s));
263 ((IDisposable) c.Target).Dispose();
264 ((IDisposable) c).Dispose();
266 if(errors.Count == 0)
268 int i = 0;
269 foreach(XmlNode n in nl)
270 MakeConnections(n, h, (Block)blocks[i++]);
272 return blocks;
274 else
276 new LoadError(fn, errors);
278 return null;