source: trunk/CrypPlugins/WorkspaceManager/Model/ConnectorModel.cs @ 2280

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

some optimizations -> the reflected methods of input/output connectors will be cached now to avoid too much reflection and to speed up the ExecutionEngine

File size: 11.3 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
17using System;
18using System.Collections.Generic;
19using System.ComponentModel;
20using System.Windows.Media;
21using Cryptool.PluginBase;
22using WorkspaceManager.View.Container;
23using System.Reflection;
24using WorkspaceManager.Execution;
25using System.Threading;
26
27namespace WorkspaceManager.Model
28{
29   
30    /// <summary>
31    /// Class to represent the Connection between two Connector Models
32    /// </summary>
33    [Serializable]
34    public class ConnectorModel : VisualElementModel
35    {
36        #region private members
37
38        /// <summary>
39        /// Does this Connector Model has actually data?
40        /// </summary>
41        [NonSerialized]
42        private volatile bool hasData = false;
43       
44        /// <summary>
45        /// Name of the Connector type
46        /// </summary>
47        private string ConnectorTypeName = null;
48        /// <summary>
49        /// Name of the Connector assembly
50        /// </summary>
51        private string ConnectorTypeAssemblyName = null;
52
53        #endregion
54
55        #region public members
56
57        /// <summary>
58        /// The method to get/set the value of the input/output represented by this connectorModel
59        /// This is needed, if we have a dynamic input/output
60        /// </summary>
61        [NonSerialized]
62        public MethodInfo method = null;
63
64        /// <summary>
65        /// The property of the plugin behind this connectorModel
66        /// </summary>     
67        [NonSerialized]
68        public PropertyInfo property = null;
69
70
71        /// <summary>
72        /// The PluginModel this Connector belongs to
73        /// </summary>
74        public PluginModel PluginModel { get; set; }
75
76        /// <summary>
77        /// The Type of the Connector Model
78        /// </summary>       
79        public Type ConnectorType
80        {
81            get
82            {
83                if (this.ConnectorTypeName != null)
84                {
85                    if (ConnectorTypeName.Equals("System.Numerics.BigInteger"))
86                    {
87                        return typeof(System.Numerics.BigInteger);
88                    }
89                    if (ConnectorTypeName.Equals("System.Numerics.BigInteger[]"))
90                    {
91                        return typeof(System.Numerics.BigInteger[]);
92                    }
93                    Assembly assembly = Assembly.Load(ConnectorTypeAssemblyName);
94                    Type t = assembly.GetType(ConnectorTypeName);
95                    return t;
96                                       
97                }
98                else
99                {
100                    return null;
101                }
102            }
103            set
104            {
105                this.ConnectorTypeName = value.FullName;
106                this.ConnectorTypeAssemblyName = value.Assembly.GetName().Name;
107            }
108        }
109
110        /// <summary>
111        /// Is this Connector Outgoing?
112        /// </summary>
113        public bool Outgoing { get; set; }
114
115        /// <summary>
116        /// Is this Connector Outgoing?
117        /// </summary>
118        public bool IControl { get; set; }
119
120        /// <summary>
121        /// The InputConnections of this ConnectorModel
122        /// </summary>
123        public List<ConnectionModel> InputConnections;
124
125        /// <summary>
126        /// The OutputConnections of this ConnectorModel
127        /// </summary>
128        public List<ConnectionModel> OutputConnections;
129
130        /// <summary>
131        /// The Orientation of this ConnectorModel
132        /// </summary>
133        public ConnectorOrientation Orientation = ConnectorOrientation.Unset;
134
135        /// <summary>
136        /// Creates a new ConnectorModel
137        /// </summary>
138        public ConnectorModel()
139        {
140            this.InputConnections = new List<ConnectionModel>();
141            this.OutputConnections = new List<ConnectionModel>();
142        }
143
144        /// <summary>
145        /// The WorkspaceModel of this PluginModel
146        /// </summary>
147        public WorkspaceModel WorkspaceModel { get; set; }
148
149        /// <summary>
150        /// Is this Connectors Data mandatory?
151        /// </summary>
152        /// <returns></returns>
153        public bool IsMandatory
154        {
155            get;
156            set;
157        }
158
159        /// <summary>
160        /// Is this a dynamic connector?
161        /// </summary>
162        public bool IsDynamic
163        {
164            get;
165            set;
166        }
167
168        /// <summary>
169        /// DynamicGetterName
170        /// </summary>
171        public string DynamicGetterName
172        {
173            get;
174            set;
175        }
176
177        /// <summary>
178        /// DynamicSetterName
179        /// </summary>
180        public string DynamicSetterName
181        {
182            get;
183            set;
184        }
185
186        /// <summary>
187        /// Does this Connector currently provides Data?
188        /// </summary>
189        /// <returns></returns>
190        public bool HasData
191        {           
192            get
193            {
194                return hasData;
195            }
196
197            set
198            {
199                hasData = value;
200            }
201        }
202
203        /// <summary>
204        /// Data of this Connector
205        /// </summary>
206        [NonSerialized]
207        public object Data = null;
208
209        /// <summary>
210        /// Name of the represented Property of the IPlugin of this ConnectorModel
211        /// </summary>
212        public string PropertyName { get; set; }
213
214        /// <summary>
215        /// ToolTip of this Connector
216        /// </summary>
217        public string ToolTip { get; set; }
218
219        /// Plugin informs the Connector that a PropertyChanged
220        /// </summary>
221        /// <param name="sender"></param>
222        /// <param name="propertyChangedEventArgs"></param>
223        public void PropertyChangedOnPlugin(Object sender, PropertyChangedEventArgs propertyChangedEventArgs)
224        {
225            if (!this.PluginModel.WorkspaceModel.WorkspaceManagerEditor.isExecuting() ||
226                !(sender == this.PluginModel.Plugin) ||
227                !propertyChangedEventArgs.PropertyName.Equals(PropertyName))
228            {
229                return;
230            }
231
232            if (Outgoing)
233            {
234                if (this.OutputConnections.Count == 0)
235                {
236                    return;
237                }
238                object data = null;
239                if (IsDynamic)
240                {
241                    if (method == null)
242                    {
243                        method = sender.GetType().GetMethod(DynamicGetterName);
244                    }
245                    data = method.Invoke(sender, new object[] { this.PropertyName });
246                   
247                }
248                else
249                {
250                    if (property == null)
251                    {
252                        property = sender.GetType().GetProperty(propertyChangedEventArgs.PropertyName);
253                    }
254                    data = property.GetValue(sender, null);
255                }
256
257                if (data == null)
258                {
259                    return;
260                }
261
262                this.Data = data;
263
264                List<ConnectionModel> outputConnections = this.OutputConnections;
265                foreach (ConnectionModel connectionModel in outputConnections)
266                {
267                    connectionModel.To.Data = data;
268                    connectionModel.To.HasData = true;
269                    connectionModel.Active = true;
270                    connectionModel.GuiNeedsUpdate = true;
271                }
272
273                //We changed an input on the PluginModels where "To"s are belonging to so
274                //we have to check if there are executable now
275                foreach (ConnectionModel connectionModel in outputConnections)
276                {
277                    if (connectionModel.To.PluginModel.PluginProtocol.QueueLength == 0)
278                    {
279                        connectionModel.To.PluginModel.PluginProtocol.BroadcastMessage(connectionModel.To.PluginModel.MessageExecution);
280                    }
281                }
282            }
283            else
284            {
285                this.Data = null;
286                this.hasData = false;
287                this.GuiNeedsUpdate = true;
288
289                List<ConnectionModel> inputConnections = this.InputConnections;
290                foreach (ConnectionModel connectionModel in inputConnections)
291                {
292                    connectionModel.Active = false;
293                    connectionModel.GuiNeedsUpdate = true;
294                }
295                foreach (ConnectionModel connectionModel in inputConnections)
296                {
297                    if (!connectionModel.From.PluginModel.Startable ||
298                        (connectionModel.From.PluginModel.Startable && connectionModel.From.PluginModel.RepeatStart))
299                    {
300                        if (connectionModel.From.PluginModel.PluginProtocol.QueueLength == 0)
301                        {
302                            connectionModel.From.PluginModel.PluginProtocol.BroadcastMessage(connectionModel.From.PluginModel.MessageExecution);
303                        }
304                    }
305                }
306            }
307        }
308
309
310        /// <summary>
311        /// The data type of the wrapped property changes
312        /// </summary>       
313        public void PropertyTypeChangedOnPlugin(IPlugin plugin)
314        {
315            Dictionary<string, DynamicProperty> dictionary = plugin.GetDynamicPropertyList();
316            DynamicPropertyInfoAttribute dynamicPropertyInfoAttribute = plugin.GetDynamicPropertyInfo();
317            foreach (DynamicProperty dynamicProperty in dictionary.Values)
318            {
319
320                if (this.PropertyName == dynamicProperty.Name)
321                {
322                    foreach (ConnectionModel connectionModel in new List<ConnectionModel>(InputConnections))
323                    {
324                        this.WorkspaceModel.deleteConnectionModel(connectionModel);
325                    }
326                    foreach (ConnectionModel connectionModel in new List<ConnectionModel>(this.OutputConnections))
327                    {
328                        this.WorkspaceModel.deleteConnectionModel(connectionModel);
329                    }
330                    this.ConnectorType = dynamicProperty.Type;
331                    if (this.UpdateableView != null)
332                    {
333                        ((ConnectorView)this.UpdateableView).ConnectorRep.Fill = new SolidColorBrush(ColorHelper.GetColor(this.ConnectorType));
334                    }
335                }
336            }
337        }
338
339        #endregion
340               
341    }
342}
Note: See TracBrowser for help on using the repository browser.