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

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