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

Last change on this file since 1680 was 1680, checked in by kopal, 11 years ago
  • Execution now is always triggered when one input changed and provides also old inputs
  • Added support for dynamic Connectors
  • some small bug fixing
File size: 13.7 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        [NonSerialized]
40        private IPlugin plugin;
41       
42        /// <summary>
43        /// This is the current index of the image which should be shown
44        /// on the plugins view
45        /// </summary>
46        private int imageIndex = 0;
47       
48        /// <summary>
49        /// All ingoing connectors of this PluginModel
50        /// </summary>
51        public List<ConnectorModel> InputConnectors = null;
52
53        /// <summary>
54        /// All outgoing connectors of this PluginModel
55        /// </summary>
56        public List<ConnectorModel> OutputConnectors = null;
57
58        /// <summary>
59        /// The wrapped IPlugin of this PluginModel
60        /// if there is currently no plugin instance it
61        /// will automatically create one. Otherwise
62        /// this acts as singleton and returns the created
63        /// instance
64        /// </summary>
65        public IPlugin Plugin{
66            get { 
67                if(plugin==null && PluginType != null){
68                    plugin = PluginType.CreateObject();                   
69                }
70                return plugin;
71            }
72
73            private set
74            {
75                plugin = value;
76            }
77        } 
78
79        /// <summary>
80        /// The Type of the Wrapped IPlugin of this PluginModel
81        /// Depending on this the Plugin of this PluginModel will be instanciated
82        /// </summary>       
83        public Type PluginType = null;
84
85        /// <summary>
86        /// Is the wrapped plugin startable
87        /// </summary>
88        public bool Startable;
89       
90        /// <summary>
91        /// Is the Plugin actually minimized?
92        /// </summary>
93        public bool Minimized { get; set; }
94
95        /// <summary>
96        /// The execution state of the progress of the wrapped plugin
97        /// </summary>
98        public double PercentageFinished { get; set; }
99
100        /// <summary>
101        /// Create a new PluginModel
102        /// </summary>
103        public PluginModel()
104        {
105            this.InputConnectors = new List<ConnectorModel>();
106            this.OutputConnectors = new List<ConnectorModel>();
107        }
108
109        /// <summary>
110        /// The WorkspaceModel of this PluginModel
111        /// </summary>
112        public WorkspaceModel WorkspaceModel { get; set; }
113
114        /// <summary>
115        /// Generates all Connectors of this Plugin.
116        /// Warning: Before generation all "old" Connectors will be deleted
117        /// </summary>
118        public void generateConnectors()
119        {
120
121            if (Plugin != null)
122            {   
123                foreach (PropertyInfoAttribute propertyInfoAttribute in Plugin.GetProperties())
124                {
125                    if (propertyInfoAttribute.Direction.Equals(Direction.InputData))
126                    {
127                        ConnectorModel connectorModel = new ConnectorModel();
128                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
129                        connectorModel.WorkspaceModel = WorkspaceModel;
130                        connectorModel.PluginModel = this;
131                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
132                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
133                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
134                        connectorModel.ConnectorOrientation = ConnectorOrientation.West;
135                        InputConnectors.Add(connectorModel);
136                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
137                    }
138                    else if (propertyInfoAttribute.Direction.Equals(Direction.OutputData))
139                    {
140                        ConnectorModel connectorModel = new ConnectorModel();
141                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
142                        connectorModel.WorkspaceModel = WorkspaceModel;
143                        connectorModel.PluginModel = this;
144                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
145                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
146                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
147                        connectorModel.ConnectorOrientation = ConnectorOrientation.East;
148                        connectorModel.Outgoing = true;
149                        Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
150                        OutputConnectors.Add(connectorModel);
151                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
152                    }
153                }
154
155                Dictionary<string, DynamicProperty> dictionary = Plugin.GetDynamicPropertyList();
156                if (dictionary != null)
157                {
158                    DynamicPropertyInfoAttribute dynamicPropertyInfoAttribute = Plugin.GetDynamicPropertyInfo();
159                    foreach (DynamicProperty dynamicProperty in dictionary.Values)
160                    {
161
162                        if (dynamicProperty.PInfo.Direction.Equals(Direction.InputData))
163                        {
164                            ConnectorModel connectorModel = new ConnectorModel();
165                            connectorModel.ConnectorType = dynamicProperty.Type;
166                            connectorModel.WorkspaceModel = WorkspaceModel;
167                            connectorModel.PluginModel = this;
168                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
169                            connectorModel.PropertyName = dynamicProperty.Name;                           
170                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
171                            connectorModel.ConnectorOrientation = ConnectorOrientation.West;
172                            EventInfo eventinfo = Plugin.GetType().GetEvent(dynamicPropertyInfoAttribute.UpdateDynamicPropertiesEvent);
173                            connectorModel.IsDynamic = true;
174                            connectorModel.DynamicGetterName = dynamicPropertyInfoAttribute.MethodGetValue;
175                            connectorModel.DynamicSetterName = dynamicPropertyInfoAttribute.MethodSetValue;
176                            eventinfo.AddEventHandler(Plugin, new DynamicPropertiesChanged(connectorModel.PropertyTypeChangedOnPlugin));
177                            InputConnectors.Add(connectorModel);
178                            WorkspaceModel.AllConnectorModels.Add(connectorModel);
179                        }
180                        else if (dynamicProperty.PInfo.Direction.Equals(Direction.OutputData))
181                        {
182                            ConnectorModel connectorModel = new ConnectorModel();
183                            connectorModel.ConnectorType = dynamicProperty.Type;
184                            connectorModel.WorkspaceModel = WorkspaceModel;
185                            connectorModel.PluginModel = this;
186                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
187                            connectorModel.PropertyName = dynamicProperty.Name;
188                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
189                            connectorModel.ConnectorOrientation = ConnectorOrientation.East;
190                            EventInfo eventinfo = Plugin.GetType().GetEvent(dynamicPropertyInfoAttribute.UpdateDynamicPropertiesEvent);
191                            eventinfo.AddEventHandler(Plugin, new DynamicPropertiesChanged(connectorModel.PropertyTypeChangedOnPlugin));
192                            connectorModel.IsDynamic = true;
193                            connectorModel.DynamicGetterName = dynamicPropertyInfoAttribute.MethodGetValue;
194                            connectorModel.DynamicSetterName = dynamicPropertyInfoAttribute.MethodSetValue;
195                            connectorModel.Outgoing = true;
196                            Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
197                            OutputConnectors.Add(connectorModel);
198                            WorkspaceModel.AllConnectorModels.Add(connectorModel);
199
200                        }
201                    }
202                }
203            }
204        }
205        /// <summary>
206        /// Get the Image of the Plugin
207        /// </summary>
208        /// <returns></returns>
209        public Image getImage()
210        {
211            return Plugin.GetImage(imageIndex);
212        }
213
214        /// <summary>
215        /// Returns the Presentation of the wrapped IPlugin
216        /// </summary>
217        public UserControl PluginPresentation
218        {
219            get
220            {
221                if(this.Plugin.Presentation != null){
222                    return this.Plugin.Presentation;
223                }else{
224                    return this.Plugin.QuickWatchPresentation;
225                }
226            }
227        }
228             
229        /// <summary>
230        /// Should be called by the UI-Thread to paint changes of the PluginModel
231        /// </summary>
232        public void paint()
233        {
234            //Enter some Code which calls the paint method of the IPlugin
235        }
236
237
238        /// <summary>
239        /// Checks wether this PluginModel is executable or not and sets the isExecutable bool
240        ///
241        /// There are 3 ways in that a plugin can be executable:
242        ///     1. All mandatory inputs are set + all outputs are "free"
243        ///     2. There are no mandatory inputs and at least one non-mandatory input is set + all outputs are "free"
244        ///     3. There are no inputs + all outputs are "free"
245        /// </summary>
246        public void checkExecutable(ProtocolBase protocolBase)
247        {                           
248            bool AtLeastOneInputSet = false;
249            //First test if every mandatory Connector has data
250            //or one non-mandatory input has data
251            foreach (ConnectorModel connectorModel in this.InputConnectors)
252            {
253                if (connectorModel.IsMandatory && !connectorModel.HasData)
254                {
255                    return;
256                }
257                else if (connectorModel.HasData)
258                {
259                    AtLeastOneInputSet = true;
260                }
261            }
262
263            if (AtLeastOneInputSet || this.InputConnectors.Count == 0)
264            {
265                MessageExecution msg = new MessageExecution();
266                msg.PluginModel = this;
267               
268                //protocolBase is set at Startup of the ExecutionEngine
269                //but it could be that we have an event before setting
270                //of the protocl base (triggered by user clicking on
271                //a plugins presentation (button or so))
272                if (protocolBase != null)
273                {
274                    protocolBase.BroadcastMessageReliably(msg);
275                }
276            }
277            return;
278        }
279
280        /// <summary>
281        /// Progress of the plugin changed
282        /// </summary>
283        /// <param name="sender"></param>
284        /// <param name="args"></param>
285        public void PluginProgressChanged(IPlugin sender, PluginProgressEventArgs args)
286        {
287            //Calculate % of the plugins process
288            this.PercentageFinished = args.Value / args.Max;
289            //Tell the ExecutionEngine that this plugin needs a gui update
290            this.GuiNeedsUpdate = true;
291        }
292
293        /// <summary>
294        /// Status of the plugin changed
295        /// </summary>
296        /// <param name="sender"></param>
297        /// <param name="args"></param>
298        public void PluginStatusChanged(IPlugin sender, StatusEventArgs args)
299        {
300            if (args.StatusChangedMode == StatusChangedMode.ImageUpdate)
301            {
302                this.imageIndex = args.ImageIndex;
303            }
304               
305            if (this.WorkspaceModel.WorkspaceManagerEditor.isExecuting())
306            {
307                this.GuiNeedsUpdate = true;
308            }
309            else
310            {
311                this.WorkspaceModel.WorkspaceManagerEditor.Presentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
312                {
313                    this.UpdateableView.update();
314                }, null);
315            }           
316        }
317
318        /// <summary>
319        /// The pluginProtocol of the current ExecutionEngine run to set/get
320        /// </summary>
321        public PluginProtocol PluginProtocol { get; set; }
322    }
323}
Note: See TracBrowser for help on using the repository browser.