예제 #1
0
        /// @brief Load a plugin from file.
        /// @details Try to open the XML definition for the plugin from the file name given as
        /// parameter. Then extract information from the XML (class name, auxiliary references
        /// and source code to compile), trying to compile the C# source code (based on
        /// Gear.PluginSupport.PluginCommon class) and returning the new class instance. If the
        /// compilation fails, then it opens the plugin editor to show errors and source code.
        /// @param[in] FileName Name and path to the XML plugin file to open
        /// @returns Reference to the new plugin instance (on success) or NULL (on fail).
        /// @throws Exception
        // TODO Modify the method to receive a PluginData, and delete the validation
        public void LoadPlugin(string FileName)
        {
            object objInst = null;
            //create the structure to fill data from file
            PluginData pluginCandidate = new PluginData();

            //Determine if the XML is valid, and for which DTD version
            if (!pluginCandidate.ValidatePluginFile(FileName))
            {
                string allMessages = string.Empty;
                //case not valid file, so show the errors.
                foreach (string strText in pluginCandidate.ValidationErrors)
                {
                    allMessages += (strText.Trim() + "\r\n");
                }
                /// @todo Add a custom dialog to show every error message in a grid.
                //show messages
                MessageBox.Show(allMessages,
                                "Emulator - OpenPlugin.",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
            else  //...XML plugin file is valid & system version is determined
            {
                //determine time to use to build the plugin
                DateTime TimeOfBuild = AssemblyUtils.GetFileDateTime(FileName);
                for (int i = 0; i < pluginCandidate.UseExtFiles.Length; i++)
                {
                    if (pluginCandidate.UseExtFiles[i] == true)
                    {
                        TimeOfBuild = DateTime.FromBinary(Math.Max(
                                                              TimeOfBuild.ToBinary(),
                                                              AssemblyUtils.GetFileDateTime(pluginCandidate.ExtFiles[i]).ToBinary()));
                    }
                }
                //generate the full name of the assembly corresponding to the plugin candidate
                string candidateAssemblyFullName =
                    pluginCandidate.PluginAssemblyFullName(TimeOfBuild).FullName;

                //determine the version to look for the correct method to load it
                switch (pluginCandidate.PluginSystemVersion)
                {
                case "0.0":
                    if (PluginPersistence.GetDataFromXML_v0_0(FileName, ref pluginCandidate))
                    {
                        //Search and replace plugin class declarations for V0.0 plugin
                        // system compatibility.
                        pluginCandidate.Codes[0] =
                            PluginSystem.ReplacePropellerClassV0_0(
                                PluginSystem.ReplaceBaseClassV0_0(pluginCandidate.Codes[0]));
                    }
                    break;

                case "1.0":
                    PluginPersistence.GetDataFromXML_v1_0(FileName, ref pluginCandidate);
                    objInst = this.Chip;
                    break;

                default:
                    MessageBox.Show(string.Format("Plugin system version '{0}' not recognized " +
                                                  "on file \"{1}\".", pluginCandidate.PluginSystemVersion, FileName),
                                    "Emulator - Open File.",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                    return;
                }
                //add information into plugin's code to generate with assembly attributes
                pluginCandidate.Codes[0] = PluginSystem.InsertAssemblyDetails(
                    pluginCandidate.Codes[0],
                    TimeOfBuild,
                    pluginCandidate.InstanceName,
                    pluginCandidate.Description,
                    pluginCandidate.PluginVersion);
                try
                {
                    //Dynamic load and compile the plugin module as a class, giving the chip
                    // instance as a parameter, and casting to appropriate class
                    PluginCommon plugin = ModuleCompiler.LoadModule(
                        pluginCandidate.Codes,                  //string[] codeTexts
                        pluginCandidate.ExtFiles,               //string[] sourceFiles
                        pluginCandidate.InstanceName,           //string module
                        pluginCandidate.References,             //string[] references
                        objInst,                                //object objInstance
                        pluginCandidate.PluginSystemVersion);   //string pluginSystemVersion,
                    if (plugin == null)
                    {
                        throw new Exception("Emulator - OpenPlugin: plugin object not generated!" +
                                            " (null response from memory loading).");
                    }
                    else //if success compiling & instantiate the new instance...
                    {
                        //...add to the corresponding plugin list of the emulator instance
                        AttachPlugin(plugin);
                        //update location of last plugin
                        Properties.Settings.Default.LastPlugin = FileName;
                        Properties.Settings.Default.Save();
                    }
                }
                catch (Exception)
                {
                    //open plugin editor in other window
                    PluginEditor errorPlugin = new PluginEditor(false);
                    if (errorPlugin.OpenFile(FileName, true))
                    {
                        //remember plugin successfully loaded
                        errorPlugin.UpdateLastPluginOpened();
                        //show plugin editor loaded with the faultly one
                        errorPlugin.MdiParent = this.MdiParent;
                        //the compilation errors are displayed in the error grid
                        ModuleCompiler.EnumerateErrors(errorPlugin.EnumErrors);
                        //show the error list
                        errorPlugin.ShowErrorGrid(true);
                        errorPlugin.Show();
                    }
                }
            }
        }