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

Last change on this file since 1759 was 1759, checked in by kopal, 11 years ago

optimized executionEngine

File size: 17.9 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;
30
31namespace WorkspaceManager.Model
32{
33    /// <summary>
34    /// Class to represent and wrap a IPlugin in our model graph
35    /// </summary>
36    [Serializable]
37    public class PluginModel : VisualElementModel
38    {
39        #region private members
40
41        [NonSerialized]
42        private PluginProtocol pluginProtocol;
43        [NonSerialized]
44        private IPlugin plugin;         
45        private int imageIndex = 0;
46        private PluginModelState state = PluginModelState.Normal;
47
48        /// <summary>
49        /// Name of the wrapped Plugins type
50        /// </summary>
51        private string PluginTypeName = null;
52        /// <summary>
53        /// Name of the wrapped Plugins assembly
54        /// </summary>
55        private string PluginTypeAssemblyName = null;
56       
57        #endregion
58
59        #region public members
60
61        /// <summary>
62        /// State of the Plugin
63        /// </summary>
64       
65        public PluginModelState State {
66            get { return state; } 
67            set { state = value; }
68        }     
69
70        /// <summary>
71        /// All ingoing connectors of this PluginModel
72        /// </summary>
73        public List<ConnectorModel> InputConnectors = null;
74
75        /// <summary>
76        /// All outgoing connectors of this PluginModel
77        /// </summary>
78        public List<ConnectorModel> OutputConnectors = null;
79
80        /// <summary>
81        /// The wrapped IPlugin of this PluginModel
82        /// if there is currently no plugin instance it
83        /// will automatically create one. Otherwise
84        /// this acts as singleton and returns the created
85        /// instance
86        /// </summary>       
87        public IPlugin Plugin{
88            get { 
89                if(plugin==null && PluginType != null){
90                    plugin = PluginType.CreateObject();                   
91                }
92                return plugin;
93            }
94
95            private set
96            {
97                plugin = value;
98            }
99        }
100
101        /// <summary>
102        /// The Type of the Wrapped IPlugin of this PluginModel
103        /// Depending on this the Plugin of this PluginModel will be instanciated
104        /// </summary>       
105        public Type PluginType{
106            get{
107                if (this.PluginTypeName != null){
108                    Assembly assembly = Assembly.Load(PluginTypeAssemblyName);
109                    Type t = assembly.GetType(PluginTypeName);
110                    return t;
111                }
112                else
113                {
114                    return null;
115                }
116            } 
117            set{
118                this.PluginTypeName = value.FullName;
119                this.PluginTypeAssemblyName = value.Assembly.FullName;
120            }
121        }
122
123        /// <summary>
124        /// Is the wrapped plugin startable
125        /// </summary>
126        public bool Startable;
127       
128        /// <summary>
129        /// Is the Plugin actually minimized?
130        /// </summary>
131        public bool? Minimized { get; set; }
132
133        /// <summary>
134        /// The execution state of the progress of the wrapped plugin
135        /// </summary>
136        public double PercentageFinished { get; set; }
137
138        /// <summary>
139        /// Create a new PluginModel
140        /// </summary>
141        public PluginModel()
142        {
143            this.InputConnectors = new List<ConnectorModel>();
144            this.OutputConnectors = new List<ConnectorModel>();
145        }
146
147        /// <summary>
148        /// The WorkspaceModel of this PluginModel
149        /// </summary>
150        public WorkspaceModel WorkspaceModel { get; set; }
151
152        /// <summary>
153        /// Generates all Connectors of this Plugin.
154        /// </summary>
155        public void generateConnectors()
156        {
157
158            if (Plugin != null)
159            {   
160                foreach (PropertyInfoAttribute propertyInfoAttribute in Plugin.GetProperties())
161                {
162                    if (propertyInfoAttribute.Direction.Equals(Direction.InputData))
163                    {
164                        ConnectorModel connectorModel = new ConnectorModel();
165                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
166                        connectorModel.WorkspaceModel = WorkspaceModel;
167                        connectorModel.PluginModel = this;
168                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
169                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
170                        connectorModel.Name = propertyInfoAttribute.PropertyName;
171                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
172                        connectorModel.IControl = false;
173                        InputConnectors.Add(connectorModel);
174                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
175                    }
176                    else if (propertyInfoAttribute.Direction.Equals(Direction.ControlSlave))
177                    {
178                        ConnectorModel connectorModel = new ConnectorModel();
179                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
180                        connectorModel.WorkspaceModel = WorkspaceModel;
181                        connectorModel.PluginModel = this;
182                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
183                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
184                        connectorModel.Name = propertyInfoAttribute.PropertyName;
185                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
186                        connectorModel.IControl = true;
187                        InputConnectors.Add(connectorModel);
188                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
189                    }
190                    else if (propertyInfoAttribute.Direction.Equals(Direction.OutputData))
191                    {
192                        ConnectorModel connectorModel = new ConnectorModel();
193                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
194                        connectorModel.WorkspaceModel = WorkspaceModel;
195                        connectorModel.PluginModel = this;
196                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
197                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
198                        connectorModel.Name = propertyInfoAttribute.PropertyName;
199                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
200                        connectorModel.Outgoing = true;
201                        connectorModel.IControl = false;
202                        Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
203                        OutputConnectors.Add(connectorModel);
204                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
205                    }
206                    else if (propertyInfoAttribute.Direction.Equals(Direction.ControlMaster))
207                    {
208                        ConnectorModel connectorModel = new ConnectorModel();
209                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
210                        connectorModel.WorkspaceModel = WorkspaceModel;
211                        connectorModel.PluginModel = this;
212                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
213                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
214                        connectorModel.Name = propertyInfoAttribute.PropertyName;
215                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
216                        connectorModel.Outgoing = true;
217                        connectorModel.IControl = true;
218                        Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
219                        OutputConnectors.Add(connectorModel);
220                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
221                    }
222                }
223
224                Dictionary<string, DynamicProperty> dictionary = Plugin.GetDynamicPropertyList();
225                if (dictionary != null)
226                {
227                    DynamicPropertyInfoAttribute dynamicPropertyInfoAttribute = Plugin.GetDynamicPropertyInfo();
228                    foreach (DynamicProperty dynamicProperty in dictionary.Values)
229                    {
230
231                        if (dynamicProperty.PInfo.Direction.Equals(Direction.InputData))
232                        {
233                            ConnectorModel connectorModel = new ConnectorModel();
234                            connectorModel.ConnectorType = dynamicProperty.Type;
235                            connectorModel.WorkspaceModel = WorkspaceModel;
236                            connectorModel.PluginModel = this;
237                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
238                            connectorModel.PropertyName = dynamicProperty.Name;
239                            connectorModel.Name = dynamicProperty.Name;
240                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
241                           EventInfo eventinfo = Plugin.GetType().GetEvent(dynamicPropertyInfoAttribute.UpdateDynamicPropertiesEvent);
242                            connectorModel.IsDynamic = true;
243                            connectorModel.DynamicGetterName = dynamicPropertyInfoAttribute.MethodGetValue;
244                            connectorModel.DynamicSetterName = dynamicPropertyInfoAttribute.MethodSetValue;
245                            eventinfo.AddEventHandler(Plugin, new DynamicPropertiesChanged(connectorModel.PropertyTypeChangedOnPlugin));
246                            InputConnectors.Add(connectorModel);
247                            WorkspaceModel.AllConnectorModels.Add(connectorModel);
248                        }
249                        else if (dynamicProperty.PInfo.Direction.Equals(Direction.OutputData))
250                        {
251                            ConnectorModel connectorModel = new ConnectorModel();
252                            connectorModel.ConnectorType = dynamicProperty.Type;
253                            connectorModel.WorkspaceModel = WorkspaceModel;
254                            connectorModel.PluginModel = this;
255                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
256                            connectorModel.PropertyName = dynamicProperty.Name;
257                            connectorModel.Name = dynamicProperty.Name;
258                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
259                             EventInfo eventinfo = Plugin.GetType().GetEvent(dynamicPropertyInfoAttribute.UpdateDynamicPropertiesEvent);
260                            eventinfo.AddEventHandler(Plugin, new DynamicPropertiesChanged(connectorModel.PropertyTypeChangedOnPlugin));
261                            connectorModel.IsDynamic = true;
262                            connectorModel.DynamicGetterName = dynamicPropertyInfoAttribute.MethodGetValue;
263                            connectorModel.DynamicSetterName = dynamicPropertyInfoAttribute.MethodSetValue;
264                            connectorModel.Outgoing = true;
265                            Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
266                            OutputConnectors.Add(connectorModel);
267                            WorkspaceModel.AllConnectorModels.Add(connectorModel);
268
269                        }
270                    }
271                }
272            }
273        }
274        /// <summary>
275        /// Get the Image of the Plugin
276        /// </summary>
277        /// <returns></returns>
278        public Image getImage()
279        {
280            return Plugin.GetImage(imageIndex);
281        }
282
283        /// <summary>
284        /// Returns the Presentation of the wrapped IPlugin
285        /// </summary>
286        public UserControl PluginPresentation
287        {
288            get
289            {
290                if(this.Plugin.Presentation != null){
291                    return this.Plugin.Presentation;
292                }else{
293                    return this.Plugin.QuickWatchPresentation;
294                }
295            }
296        }
297             
298        /// <summary>
299        /// Should be called by the UI-Thread to paint changes of the PluginModel
300        /// </summary>
301        public void paint()
302        {
303            //Enter some Code which calls the paint method of the IPlugin
304        }
305
306        /// <summary>
307        /// Checks wether this PluginModel is executable and if yes it broadcasts a execution message
308        /// </summary>
309        public void checkExecutable(ProtocolBase protocolBase)
310        {
311            if (!this.WorkspaceModel.WorkspaceManagerEditor.isExecuting())
312            {
313                return;
314            }
315
316            MessageExecution msg;           
317            foreach (ConnectorModel connectorModel in this.InputConnectors)
318            {
319                if (!connectorModel.IControl && (connectorModel.IsMandatory || connectorModel.InputConnections.Count > 0) && !connectorModel.HasData)
320                {                   
321                    return;
322                }               
323            }
324
325            foreach (ConnectorModel connectorModel in this.OutputConnectors)
326            {
327                if (!connectorModel.IControl)
328                {
329                    foreach(ConnectionModel connectionModel in connectorModel.OutputConnections)
330                    {
331                        if (connectionModel.To.HasData)
332                        {
333                            return;
334                        }
335                    }
336                }
337            }
338
339            msg = new MessageExecution();
340            msg.PluginModel = this;
341               
342            //protocolBase is set at Startup of the ExecutionEngine
343            //but it could be that we have an event before setting
344            //of the protocl base (triggered by user clicking on
345            //a plugins presentation (button or so))
346            if (protocolBase != null && protocolBase.QueueLength == 0)
347            {
348                protocolBase.BroadcastMessageReliably(msg);
349            }
350
351            return;
352        }
353
354        /// <summary>
355        /// Progress of the plugin changed
356        /// </summary>
357        /// <param name="sender"></param>
358        /// <param name="args"></param>
359        public void PluginProgressChanged(IPlugin sender, PluginProgressEventArgs args)
360        {
361            //Calculate % of the plugins process
362            this.PercentageFinished = args.Value / args.Max;
363            //Tell the ExecutionEngine that this plugin needs a gui update
364            this.GuiNeedsUpdate = true;
365        }
366
367        /// <summary>
368        /// Status of the plugin changed
369        /// </summary>
370        /// <param name="sender"></param>
371        /// <param name="args"></param>
372        public void PluginStatusChanged(IPlugin sender, StatusEventArgs args)
373        {
374            if (args.StatusChangedMode == StatusChangedMode.ImageUpdate)
375            {
376                this.imageIndex = args.ImageIndex;
377            }
378               
379            if (this.WorkspaceModel.WorkspaceManagerEditor.isExecuting())
380            {
381                this.GuiNeedsUpdate = true;
382            }
383            else
384            {
385                this.WorkspaceModel.WorkspaceManagerEditor.Presentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
386                {
387                    this.UpdateableView.update();
388                }, null);
389            }           
390        }
391
392        /// <summary>
393        /// The pluginProtocol of the current ExecutionEngine run to set/get
394        /// </summary>
395        public PluginProtocol PluginProtocol {
396            get { return pluginProtocol; }
397            set { pluginProtocol = value;}
398        }
399
400        /// <summary>
401        /// All occured log events of this plugin
402        /// </summary>
403        [NonSerialized]
404        public List<GuiLogEventArgs> GuiLogEvents = new List<GuiLogEventArgs>();
405
406        /// <summary>
407        /// GuiLogNotificationOccured
408        /// saves the plugins log events and tells the gui that it needs
409        /// an update
410        /// </summary>
411        /// <param name="sender"></param>
412        /// <param name="args"></param>
413        public void GuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
414        {
415            if (sender == this.plugin)
416            {
417                this.GuiLogEvents.Add(args);
418                this.GuiNeedsUpdate = true;
419            }
420        }
421
422        #endregion
423    }
424
425    /// <summary>
426    /// The internal state of a Plugin Model
427    /// </summary>
428    public enum PluginModelState{
429        Normal,
430        Warning,
431        Error
432    }
433}
Note: See TracBrowser for help on using the repository browser.