source: trunk/CrypPlugins/WorkspaceManager/Model/PluginModel.cs @ 1809

Last change on this file since 1809 was 1809, checked in by kopal, 11 years ago
  • Editor now disables asynchronous PropertyChanged in EventHelpers at startup of ExecutionEngine and enables it at termination
  • now Connector PropertyChanged is used to propagate output data (so next plugins may be executed even if plugin before is running)
File size: 17.1 KB
Line 
1/*                             
2   Copyright 2010 Nils Kopal, Viktor M.
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17
18using System;
19using System.Collections.Generic;
20using System.Linq;
21using System.Text;
22using Cryptool.PluginBase;
23using System.Threading;
24using System.Windows.Controls;
25using Gears4Net;
26using WorkspaceManager.Execution;
27using System.Windows.Threading;
28using Cryptool.PluginBase.IO;
29using System.Reflection;
30using System.ComponentModel;
31
32namespace WorkspaceManager.Model
33{
34    /// <summary>
35    /// Class to represent and wrap a IPlugin in our model graph
36    /// </summary>
37    [Serializable]
38    public class PluginModel : VisualElementModel
39    {
40        #region private members
41
42        [NonSerialized]
43        private PluginProtocol pluginProtocol;
44        [NonSerialized]
45        private IPlugin plugin;         
46        private int imageIndex = 0;
47        [NonSerialized]
48        private PluginModelState state = PluginModelState.Normal;
49        private string PluginTypeName = null;
50        private string PluginTypeAssemblyName = null;
51       
52        #endregion
53
54        #region public members
55
56        /// <summary>
57        /// State of the Plugin
58        /// </summary>
59       
60        public PluginModelState State {
61            get { return state; } 
62            set { state = value; }
63        }
64
65        /// <summary>
66        /// All ingoing connectors of this PluginModel
67        /// </summary>
68        public List<ConnectorModel> InputConnectors = null;
69
70        /// <summary>
71        /// All outgoing connectors of this PluginModel
72        /// </summary>
73        public List<ConnectorModel> OutputConnectors = null;
74
75        /// <summary>
76        /// The wrapped IPlugin of this PluginModel
77        /// if there is currently no plugin instance it
78        /// will automatically create one. Otherwise
79        /// this acts as singleton and returns the created
80        /// instance
81        /// </summary>       
82        public IPlugin Plugin{
83            get { 
84                if(plugin==null && PluginType != null){
85                    plugin = PluginType.CreateObject();                   
86                }
87                return plugin;
88            }
89
90            private set
91            {
92                plugin = value;
93            }
94        }
95
96        /// <summary>
97        /// The Type of the Wrapped IPlugin of this PluginModel
98        /// Depending on this the Plugin of this PluginModel will be instanciated
99        /// </summary>       
100        public Type PluginType{
101            get{
102                if (this.PluginTypeName != null){
103                    Assembly assembly = Assembly.Load(PluginTypeAssemblyName);
104                    Type t = assembly.GetType(PluginTypeName);
105                    return t;
106                }
107                else
108                {
109                    return null;
110                }
111            } 
112            set{
113                this.PluginTypeName = value.FullName;
114                this.PluginTypeAssemblyName = value.Assembly.FullName;
115            }
116        }
117
118        /// <summary>
119        /// Should this plugin may be startet again when it
120        /// is startable?
121        /// </summary>
122        public bool RepeatStart;
123
124        /// <summary>
125        /// Is the wrapped plugin startable
126        /// </summary>
127        public bool Startable;
128       
129        /// <summary>
130        /// Is the Plugin actually minimized?
131        /// </summary>
132        public bool Minimized { get; set; }
133
134        /// <summary>
135        /// The execution state of the progress of the wrapped plugin
136        /// </summary>
137        public double PercentageFinished { get; set; }
138
139        /// <summary>
140        /// Create a new PluginModel
141        /// </summary>
142        public PluginModel()
143        {
144            this.InputConnectors = new List<ConnectorModel>();
145            this.OutputConnectors = new List<ConnectorModel>();
146        }
147     
148        /// <summary>
149        /// The WorkspaceModel of this PluginModel
150        /// </summary>
151        public WorkspaceModel WorkspaceModel { get; set; }
152
153        /// <summary>
154        /// Generates all Connectors of this Plugin.
155        /// </summary>
156        public void generateConnectors()
157        {
158
159            if (Plugin != null)
160            {   
161                foreach (PropertyInfoAttribute propertyInfoAttribute in Plugin.GetProperties())
162                {
163                    if (propertyInfoAttribute.Direction.Equals(Direction.InputData))
164                    {
165                        ConnectorModel connectorModel = new ConnectorModel();
166                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
167                        connectorModel.WorkspaceModel = WorkspaceModel;
168                        connectorModel.PluginModel = this;
169                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
170                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
171                        connectorModel.Name = propertyInfoAttribute.PropertyName;
172                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
173                        connectorModel.IControl = false;
174                        connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
175                        InputConnectors.Add(connectorModel);
176                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
177                    }
178                    else if (propertyInfoAttribute.Direction.Equals(Direction.ControlSlave))
179                    {
180                        ConnectorModel connectorModel = new ConnectorModel();
181                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
182                        connectorModel.WorkspaceModel = WorkspaceModel;
183                        connectorModel.PluginModel = this;
184                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
185                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
186                        connectorModel.Name = propertyInfoAttribute.PropertyName;
187                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
188                        connectorModel.IControl = true;
189                        connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
190                        InputConnectors.Add(connectorModel);
191                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
192                    }
193                    else if (propertyInfoAttribute.Direction.Equals(Direction.OutputData))
194                    {
195                        ConnectorModel connectorModel = new ConnectorModel();
196                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
197                        connectorModel.WorkspaceModel = WorkspaceModel;
198                        connectorModel.PluginModel = this;
199                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
200                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
201                        connectorModel.Name = propertyInfoAttribute.PropertyName;
202                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
203                        connectorModel.Outgoing = true;
204                        connectorModel.IControl = false;
205                        connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
206                        OutputConnectors.Add(connectorModel);
207                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
208                    }
209                    else if (propertyInfoAttribute.Direction.Equals(Direction.ControlMaster))
210                    {
211                        ConnectorModel connectorModel = new ConnectorModel();
212                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
213                        connectorModel.WorkspaceModel = WorkspaceModel;
214                        connectorModel.PluginModel = this;
215                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
216                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
217                        connectorModel.Name = propertyInfoAttribute.PropertyName;
218                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
219                        connectorModel.Outgoing = true;
220                        connectorModel.IControl = true;
221                        connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
222                        OutputConnectors.Add(connectorModel);
223                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
224                    }
225                }
226
227                Dictionary<string, DynamicProperty> dictionary = Plugin.GetDynamicPropertyList();
228                if (dictionary != null)
229                {
230                    DynamicPropertyInfoAttribute dynamicPropertyInfoAttribute = Plugin.GetDynamicPropertyInfo();
231                    foreach (DynamicProperty dynamicProperty in dictionary.Values)
232                    {
233
234                        if (dynamicProperty.PInfo.Direction.Equals(Direction.InputData))
235                        {
236                            ConnectorModel connectorModel = new ConnectorModel();
237                            connectorModel.ConnectorType = dynamicProperty.Type;
238                            connectorModel.WorkspaceModel = WorkspaceModel;
239                            connectorModel.PluginModel = this;
240                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
241                            connectorModel.PropertyName = dynamicProperty.Name;
242                            connectorModel.Name = dynamicProperty.Name;
243                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
244                            EventInfo eventinfo = Plugin.GetType().GetEvent(dynamicPropertyInfoAttribute.UpdateDynamicPropertiesEvent);
245                            connectorModel.IsDynamic = true;
246                            connectorModel.DynamicGetterName = dynamicPropertyInfoAttribute.MethodGetValue;
247                            connectorModel.DynamicSetterName = dynamicPropertyInfoAttribute.MethodSetValue;
248                            connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
249                            eventinfo.AddEventHandler(Plugin, new DynamicPropertiesChanged(connectorModel.PropertyTypeChangedOnPlugin));
250                            InputConnectors.Add(connectorModel);
251                            WorkspaceModel.AllConnectorModels.Add(connectorModel);
252                        }
253                        else if (dynamicProperty.PInfo.Direction.Equals(Direction.OutputData))
254                        {
255                            ConnectorModel connectorModel = new ConnectorModel();
256                            connectorModel.ConnectorType = dynamicProperty.Type;
257                            connectorModel.WorkspaceModel = WorkspaceModel;
258                            connectorModel.PluginModel = this;
259                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
260                            connectorModel.PropertyName = dynamicProperty.Name;
261                            connectorModel.Name = dynamicProperty.Name;
262                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
263                             EventInfo eventinfo = Plugin.GetType().GetEvent(dynamicPropertyInfoAttribute.UpdateDynamicPropertiesEvent);
264                            eventinfo.AddEventHandler(Plugin, new DynamicPropertiesChanged(connectorModel.PropertyTypeChangedOnPlugin));
265                            connectorModel.IsDynamic = true;
266                            connectorModel.DynamicGetterName = dynamicPropertyInfoAttribute.MethodGetValue;
267                            connectorModel.DynamicSetterName = dynamicPropertyInfoAttribute.MethodSetValue;
268                            connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
269                            connectorModel.Outgoing = true;
270                            OutputConnectors.Add(connectorModel);
271                            WorkspaceModel.AllConnectorModels.Add(connectorModel);
272
273                        }
274                    }
275                }
276            }
277        }
278        /// <summary>
279        /// Get the Image of the Plugin
280        /// </summary>
281        /// <returns></returns>
282        public Image getImage()
283        {
284            return Plugin.GetImage(imageIndex);
285        }
286
287        /// <summary>
288        /// Returns the Presentation of the wrapped IPlugin
289        /// </summary>
290        public UserControl PluginPresentation
291        {
292            get
293            {
294                if(this.Plugin.Presentation != null){
295                    return this.Plugin.Presentation;
296                }else{
297                    return this.Plugin.QuickWatchPresentation;
298                }
299            }
300        }
301             
302        /// <summary>
303        /// Should be called by the UI-Thread to paint changes of the PluginModel
304        /// </summary>
305        public void paint()
306        {
307            //Enter some Code which calls the paint method of the IPlugin
308        }       
309
310        /// <summary>
311        /// Progress of the plugin changed
312        /// </summary>
313        /// <param name="sender"></param>
314        /// <param name="args"></param>
315        public void PluginProgressChanged(IPlugin sender, PluginProgressEventArgs args)
316        {
317            //Calculate % of the plugins process
318            this.PercentageFinished = args.Value / args.Max;
319            //Tell the ExecutionEngine that this plugin needs a gui update
320            this.GuiNeedsUpdate = true;
321        }
322
323        /// <summary>
324        /// Status of the plugin changed
325        /// </summary>
326        /// <param name="sender"></param>
327        /// <param name="args"></param>
328        public void PluginStatusChanged(IPlugin sender, StatusEventArgs args)
329        {
330            if (args.StatusChangedMode == StatusChangedMode.ImageUpdate)
331            {
332                this.imageIndex = args.ImageIndex;
333            }
334               
335            if (this.WorkspaceModel.WorkspaceManagerEditor.isExecuting())
336            {
337                this.GuiNeedsUpdate = true;
338            }
339            else
340            {
341                this.WorkspaceModel.WorkspaceManagerEditor.Presentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
342                {
343                    this.UpdateableView.update();
344                }, null);
345            }           
346        }
347
348        /// <summary>
349        /// The pluginProtocol of the current ExecutionEngine run to set/get
350        /// </summary>
351        public PluginProtocol PluginProtocol {
352            get { return pluginProtocol; }
353            set { pluginProtocol = value;}
354        }
355
356        /// <summary>
357        /// All occured log events of this plugin
358        /// </summary>
359        [NonSerialized]
360        public List<GuiLogEventArgs> GuiLogEvents = new List<GuiLogEventArgs>();
361
362        /// <summary>
363        /// GuiLogNotificationOccured
364        /// saves the plugins log events and tells the gui that it needs
365        /// an update
366        /// </summary>
367        /// <param name="sender"></param>
368        /// <param name="args"></param>
369        public void GuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
370        {
371            if (sender == this.plugin)
372            {
373                this.GuiLogEvents.Add(args);
374                this.GuiNeedsUpdate = true;
375            }
376        }
377
378        /// <summary>
379        /// Called if a Setting of a Plugin is changed and notifies the Editor that
380        /// there is a change
381        /// </summary>
382        /// <param name="sender"></param>
383        /// <param name="propertyChangedEventArgs"></param>
384        public void SettingsPropertyChanged(Object sender, PropertyChangedEventArgs propertyChangedEventArgs)
385        {
386            this.WorkspaceModel.WorkspaceManagerEditor.HasChanges = true;
387        }
388
389        #endregion
390    }
391
392    /// <summary>
393    /// The internal state of a Plugin Model
394    /// </summary>
395    public enum PluginModelState{
396        Normal,
397        Warning,
398        Error
399    }
400}
Note: See TracBrowser for help on using the repository browser.