/// <summary> /// Reloads the composition. /// </summary> /// <remarks>Reloading is useful if you want to run simulation multiple times in one execution time. /// Some models aren't able to run simulation after it was already run, and may crash in such case. /// That's because they need to create new instance of them, on which the <c>Initialize</c> method /// is called. /// Reloading is done same way like when you save the composition to OPR file, restarts the application, /// and open this OPR file again. Of course, it is done only internally in the memory.</remarks> public void Reload() { _editorMode = EEditorMode.Unspecified; XmlDocument xmlDocument = new XmlDocument(); SaveToXmlDocument(xmlDocument); // preserve members that aren't saved to XML bool oldShouldBeSaved = _shouldBeSaved; Release(); AssemblySupport.ReleaseAll(); LoadFromXmlDocument(Path.GetDirectoryName(_filePath), xmlDocument); _shouldBeSaved = oldShouldBeSaved; }
/// <summary> /// Sets this model according to OMI file. /// </summary> /// <param name="filename">Relative or absolute path to OMI file describing the model.</param> /// <param name="relativeDirectory">Directory <c>filename</c> is relative to, or <c>null</c> if <c>filename</c> is absolute or relative to current directory.</param> /// <remarks>See <see cref="Utils.GetFileInfo">Utils.GetFileInfo</see> for more info about how /// specified file is searched.</remarks> public void ReadOMIFile(string relativeDirectory, string filename) { // Open OMI file as xmlDocument FileInfo omiFileInfo = Utils.GetFileInfo(relativeDirectory, filename); if (!omiFileInfo.Exists) { throw(new Exception("Omi file not found (CurrentDirectory='" + Directory.GetCurrentDirectory() + "', File='" + filename + "')")); } XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(omiFileInfo.FullName); // get 1st LinkableComponent element XmlElement xmlLinkableComponent = null; foreach (XmlNode node in xmlDocument.ChildNodes) { if (node.Name == "LinkableComponent") { xmlLinkableComponent = (XmlElement)node; break; } } // load assembly if present (from relative location of the OMI file) if (xmlLinkableComponent == null) { throw new Exception("No linkable components found in composition file " + omiFileInfo); } else { string assemblyFilename = xmlLinkableComponent.GetAttribute("Assembly"); if (assemblyFilename != null) { AssemblySupport.LoadAssembly(omiFileInfo.DirectoryName, assemblyFilename); } } // read arguments ArrayList linkableComponentArguments = new ArrayList(); foreach (XmlElement xmlArguments in xmlLinkableComponent.ChildNodes) { if (xmlArguments.Name == "Arguments") { foreach (XmlElement xmlArgument in xmlArguments.ChildNodes) { linkableComponentArguments.Add(new Argument(xmlArgument.GetAttribute("Key"), xmlArgument.GetAttribute("Value"), true, "No description")); } } } // get new instance of ILinkableComponent type // for this moment set current directory to omi file's directory string oldDirectory = Directory.GetCurrentDirectory(); try { Directory.SetCurrentDirectory(omiFileInfo.DirectoryName); string classTypeName = xmlLinkableComponent.GetAttribute("Type"); object obj = AssemblySupport.GetNewInstance(classTypeName); if (!(obj is ILinkableComponent)) { throw new Exception("\n\nThe class type " + classTypeName + " in\n" + filename + "\nis not an OpenMI.Standard.ILinkableComponent (OpenMI.Standard.dll version 1.4.0.0)." + "\nYou may have specified a wrong class name, " + "\nor the class implements the ILinkableComponent interface of a previous version of the OpenMI Standard.\n"); } _linkableComponent = (ILinkableComponent)obj; _linkableComponent.Initialize((IArgument[])linkableComponentArguments.ToArray(typeof(IArgument))); } finally { Directory.SetCurrentDirectory(oldDirectory); } _omiFilename = omiFileInfo.FullName; _modelID = _linkableComponent.ModelID; // remote components have rectangle style string componentDescription = _linkableComponent.ComponentDescription; if (componentDescription != null) { if (componentDescription.IndexOf("OpenMI.Distributed") >= 0) { _rectanglePen.DashStyle = DashStyle.Dash; } } }