Changeset 1680


Ignore:
Timestamp:
Jun 20, 2010, 3:30:22 PM (11 years ago)
Author:
kopal
Message:
  • Execution now is always triggered when one input changed and provides also old inputs
  • Added support for dynamic Connectors
  • some small bug fixing
Location:
trunk/CrypPlugins/WorkspaceManager
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/WorkspaceManager/Execution/ExecutionEngine.cs

    r1637 r1680  
    4545        public long ExecutedPluginsCounter { get; set; }
    4646        public bool BenchmarkPlugins { get; set; }
    47         public long CheckInterval { get; set; }
    4847        public long GuiUpdateInterval { get; set; }
    4948
     
    9493                updateGuiProtocol.Start();
    9594
    96                 //The CheckExecutableProtocl is also a kind of "daemon" which will check from time to time if a
    97                 //plugin can be executed again
    98                 CheckExecutableProtocol checkExecutableProtocol = new CheckExecutableProtocol(schedulers[0], workspaceModel, this);
    99                 schedulers[0].AddProtocol(checkExecutableProtocol);
    100                 checkExecutableProtocol.Start();
    101 
    10295                //The BenchmarkProtocl counts the amount of executed plugins per seconds and writes this to debug
    10396                if (this.BenchmarkPlugins)
     
    117110                    pluginModel.PluginProtocol = pluginProtocol;
    118111                    schedulers[counter].AddProtocol(pluginProtocol);
    119                     pluginModel.checkExecutable(pluginProtocol);
     112                   
    120113                    pluginProtocol.Start();
    121114                    counter = (counter + 1) % (System.Environment.ProcessorCount*2);
     115
     116                    if (pluginModel.Startable)
     117                    {
     118                        MessageExecution msg = new MessageExecution();
     119                        msg.PluginModel = pluginModel;
     120                        pluginProtocol.BroadcastMessageReliably(msg);
     121
     122                    }
    122123                }
    123124            }
     
    241242    }
    242243
    243     /// <summary>
    244     /// A Protocol for checking if plugins are executable in time intervals
    245     /// </summary>
    246     public class CheckExecutableProtocol : ProtocolBase
     244   
     245    /// <summary>
     246    /// A Protocol for benchmarking
     247    /// </summary>
     248    public class BenchmarkProtocol : ProtocolBase
    247249    {
    248250        private WorkspaceModel workspaceModel;
    249251        private ExecutionEngine executionEngine;
    250      
     252
    251253        /// <summary>
    252254        /// Create a new protocol. Each protocol requires a scheduler which provides
     
    254256        /// </summary>
    255257        /// <param name="scheduler"></param>
    256         public CheckExecutableProtocol(Scheduler scheduler, WorkspaceModel workspaceModel, ExecutionEngine executionEngine)
     258        public BenchmarkProtocol(Scheduler scheduler, WorkspaceModel workspaceModel, ExecutionEngine executionEngine)
    257259            : base(scheduler)
    258260        {
     
    270272            while (this.executionEngine.IsRunning)
    271273            {
    272                 yield return Timeout(this.executionEngine.CheckInterval, HandleCheckExecutable);
     274                yield return Timeout(1000, HandleBenchmark);
    273275            }
    274276        }
     
    279281        /// </summary>
    280282        /// <param name="msg"></param>
    281         private void HandleCheckExecutable()
    282         {
    283             foreach (PluginModel pluginModel in workspaceModel.AllPluginModels)
    284             {
    285                 pluginModel.checkExecutable(pluginModel.PluginProtocol);
    286             }
    287         }
    288        
    289     }
    290 
    291     /// <summary>
    292     /// A Protocol for checking if plugins are executable in time intervals
    293     /// </summary>
    294     public class BenchmarkProtocol : ProtocolBase
    295     {
    296         private WorkspaceModel workspaceModel;
     283        private void HandleBenchmark()
     284        {
     285            this.workspaceModel.WorkspaceManagerEditor.GuiLogMessage("Executing at about " + this.executionEngine.ExecutedPluginsCounter + " Plugins/s", NotificationLevel.Debug);
     286            this.executionEngine.ExecutedPluginsCounter = 0;
     287        }
     288
     289    }
     290
     291    /// <summary>
     292    /// A Protocol for a PluginModel
     293    /// </summary>
     294    public class PluginProtocol : ProtocolBase
     295    {
     296        private PluginModel pluginModel;
    297297        private ExecutionEngine executionEngine;
    298298
     
    302302        /// </summary>
    303303        /// <param name="scheduler"></param>
    304         public BenchmarkProtocol(Scheduler scheduler, WorkspaceModel workspaceModel, ExecutionEngine executionEngine)
     304        public PluginProtocol(Scheduler scheduler, PluginModel pluginModel,ExecutionEngine executionEngine)
    305305            : base(scheduler)
    306306        {
    307             this.workspaceModel = workspaceModel;
     307            this.pluginModel = pluginModel;
    308308            this.executionEngine = executionEngine;
    309309        }
    310310
    311311        /// <summary>
    312         /// The main function of the protocol
     312        /// The main function of the protocol     
    313313        /// </summary>
    314314        /// <param name="stateMachine"></param>
     
    318318            while (this.executionEngine.IsRunning)
    319319            {
    320                 yield return Timeout(1000, HandleBenchmark);
    321             }
    322         }
    323 
    324         /// <summary>
    325         /// Handler function for a message.
    326         /// This handler must not block, because it executes inside the thread of the scheduler.
    327         /// </summary>
    328         /// <param name="msg"></param>
    329         private void HandleBenchmark()
    330         {
    331             this.workspaceModel.WorkspaceManagerEditor.GuiLogMessage("Executing at about " + this.executionEngine.ExecutedPluginsCounter + " Plugins/s", NotificationLevel.Debug);
    332             this.executionEngine.ExecutedPluginsCounter = 0;
    333         }
    334 
    335     }
    336 
    337     /// <summary>
    338     /// A Protocol for a PluginModel
    339     /// </summary>
    340     public class PluginProtocol : ProtocolBase
    341     {
    342         private PluginModel pluginModel;
    343         private ExecutionEngine executionEngine;
    344 
    345         /// <summary>
    346         /// Create a new protocol. Each protocol requires a scheduler which provides
    347         /// a thread for execution.
    348         /// </summary>
    349         /// <param name="scheduler"></param>
    350         public PluginProtocol(Scheduler scheduler, PluginModel pluginModel,ExecutionEngine executionEngine)
    351             : base(scheduler)
    352         {
    353             this.pluginModel = pluginModel;
    354             this.executionEngine = executionEngine;
    355         }
    356 
    357         /// <summary>
    358         /// The main function of the protocol
    359         ///
    360         /// states are here:
    361         ///
    362         ///     PreExecution -> Execution -> PostExecution
    363         ///        /\                           |
    364         ///         |---------------------------|
    365         ///         
    366         /// </summary>
    367         /// <param name="stateMachine"></param>
    368         /// <returns></returns>
    369         public override System.Collections.Generic.IEnumerator<ReceiverBase> Execute(AbstractStateMachine stateMachine)
    370         {
    371             while (this.executionEngine.IsRunning)
    372             {
    373320                yield return Receive<MessageExecution>(null, this.HandleExecute);             
    374321            }
     
    389336                if (connectorModel.HasData)
    390337                {
    391                     PropertyInfo propertyInfo = pluginModel.Plugin.GetType().GetProperty(connectorModel.PropertyName);
    392                     propertyInfo.SetValue(pluginModel.Plugin, connectorModel.Data, null);
    393                     connectorModel.HasLastData = true;
    394                     connectorModel.LastData = connectorModel.Data;
    395                     connectorModel.Data = null;
    396                     connectorModel.HasData = false;
    397                     connectorModel.InputConnection.Active = false;                   
     338                    if (connectorModel.IsDynamic)
     339                    {
     340                        MethodInfo propertyInfo = pluginModel.Plugin.GetType().GetMethod(connectorModel.DynamicSetterName);
     341                        propertyInfo.Invoke(pluginModel.Plugin, new object[]{connectorModel.PropertyName, connectorModel.Data});
     342                    }
     343                    else
     344                    {
     345                        PropertyInfo propertyInfo = pluginModel.Plugin.GetType().GetProperty(connectorModel.PropertyName);
     346                        propertyInfo.SetValue(pluginModel.Plugin, connectorModel.Data, null);
     347                    }
    398348                }
    399349            }
  • trunk/CrypPlugins/WorkspaceManager/Model/ConnectorModel.cs

    r1620 r1680  
    2121using System.ComponentModel;
    2222using System.Threading;
     23using Cryptool.PluginBase;
     24using WorkspaceManager.View.Container;
     25using System.Windows.Media;
    2326
    2427namespace WorkspaceManager.Model
     
    3134    [Serializable]
    3235    public class ConnectorModel : VisualElementModel
    33     {       
     36    {        
    3437        [NonSerialized]
    3538        private bool hasData = false;
    3639
    3740        [NonSerialized]
    38         private bool hasLastData = false;
    39 
    40         [NonSerialized]
    4141        private object data;
    42 
    43         [NonSerialized]
    44         private object lastData;
    4542       
    4643        /// <summary>
     
    8784        /// <returns></returns>
    8885        public bool IsMandatory
     86        {
     87            get;
     88            set;
     89        }
     90
     91        /// <summary>
     92        /// Is this a dynamic connector?
     93        /// </summary>
     94        public bool IsDynamic
     95        {
     96            get;
     97            set;
     98        }
     99
     100        /// <summary>
     101        /// DynamicGetterName
     102        /// </summary>
     103        public string DynamicGetterName
     104        {
     105            get;
     106            set;
     107        }
     108
     109        /// <summary>
     110        /// DynamicSetterName
     111        /// </summary>
     112        public string DynamicSetterName
    89113        {
    90114            get;
     
    122146                data = value;
    123147            }
    124         }
    125 
    126         /// <summary>
    127         /// Does this Connector currently provides last Data?
    128         /// </summary>
    129         /// <returns></returns>
    130         public bool HasLastData
    131         {
    132             get
    133             {
    134                 return hasLastData;
    135             }
    136 
    137             set
    138             {
    139                 hasLastData = value;
    140             }
    141         }
    142 
    143         /// <summary>
    144         /// LastData of this Connector
    145         /// </summary>
    146         public object LastData
    147         {
    148             get
    149             {
    150                 return lastData;
    151             }
    152 
    153             set
    154             {
    155                 lastData = value;
    156             }
    157         }
     148        }       
    158149
    159150        /// <summary>
     
    179170               
    180171                foreach (ConnectionModel connectionModel in this.OutputConnections)
    181                 {                   
    182                     connectionModel.To.Data = sender.GetType().GetProperty(propertyChangedEventArgs.PropertyName).GetValue(sender, null);
     172                {
     173                    if (IsDynamic)
     174                    {
     175                        connectionModel.To.Data = sender.GetType().GetMethod(DynamicGetterName).Invoke(sender, new object[] { this.PropertyName });
     176                    }
     177                    else
     178                    {
     179                        connectionModel.To.Data = sender.GetType().GetProperty(propertyChangedEventArgs.PropertyName).GetValue(sender, null);
     180                    }
    183181                    connectionModel.To.HasData = true;
    184182                    connectionModel.Active = true;
    185                     //this.WorkspaceModel.WorkspaceManagerEditor.GuiLogMessage("PropertyChanged for  \"" + this.PluginModel.Name + "\" Property \"" + PropertyName + "\"", Cryptool.PluginBase.NotificationLevel.Debug);
    186 
     183                   
    187184                    //We changed an input on the PluginModel where "To" is belonging to so
    188185                    //we have to check if this is executable now
     
    197194        public ConnectorOrientation ConnectorOrientation { get; set; }
    198195
     196        /// <summary>
     197        ///
     198        /// </summary>
     199        public void PropertyTypeChangedOnPlugin(IPlugin plugin)
     200        {
     201            Dictionary<string, DynamicProperty> dictionary = plugin.GetDynamicPropertyList();
     202            DynamicPropertyInfoAttribute dynamicPropertyInfoAttribute = plugin.GetDynamicPropertyInfo();
     203            foreach (DynamicProperty dynamicProperty in dictionary.Values)
     204            {
     205               
     206                if (this.PropertyName == dynamicProperty.Name)
     207                {
     208                    if(this.InputConnection != null){
     209                        this.WorkspaceModel.deleteConnectionModel(this.InputConnection);
     210                    }
     211                    foreach(ConnectionModel connectionModel in new List<ConnectionModel>(this.OutputConnections))
     212                    {
     213                        this.WorkspaceModel.deleteConnectionModel(connectionModel);
     214                    }
     215                    this.ConnectorType = dynamicProperty.Type;
     216                    if (this.UpdateableView != null)
     217                    {
     218                        ((ConnectorView)this.UpdateableView).Ellipse.Fill = new SolidColorBrush(ColorHelper.GetColor(this.ConnectorType));
     219                    }
     220                }
     221            }
     222        }
    199223    }
    200224
  • trunk/CrypPlugins/WorkspaceManager/Model/PluginModel.cs

    r1640 r1680  
    2626using WorkspaceManager.Execution;
    2727using System.Windows.Threading;
     28using Cryptool.PluginBase.IO;
     29using System.Reflection;
    2830
    2931namespace WorkspaceManager.Model
     
    8082        /// </summary>       
    8183        public Type PluginType = null;
     84
     85        /// <summary>
     86        /// Is the wrapped plugin startable
     87        /// </summary>
     88        public bool Startable;
    8289       
    8390        /// <summary>
     
    109116        /// Warning: Before generation all "old" Connectors will be deleted
    110117        /// </summary>
    111         public void generateConnectors(){
    112            
     118        public void generateConnectors()
     119        {
     120
    113121            if (Plugin != null)
    114             {
    115                 this.InputConnectors.Clear();
    116                 this.OutputConnectors.Clear();
    117 
     122            {   
    118123                foreach (PropertyInfoAttribute propertyInfoAttribute in Plugin.GetProperties())
    119                 {                   
     124                {
    120125                    if (propertyInfoAttribute.Direction.Equals(Direction.InputData))
    121126                    {
     
    145150                        OutputConnectors.Add(connectorModel);
    146151                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
    147                     }                   
    148                 }
    149             }     
    150         }
    151 
     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        }
    152205        /// <summary>
    153206        /// Get the Image of the Plugin
     
    205258                {
    206259                    AtLeastOneInputSet = true;
    207                 }
    208 
    209             }
    210 
    211             //Next test if every connected output Connection is not active
    212             foreach (ConnectorModel connectorModel in this.OutputConnectors)
    213             {
    214                 foreach (ConnectionModel connection in connectorModel.OutputConnections)
    215                 {
    216                     if (connection.Active)
    217                     {                           
    218                        return;
    219                     }                       
    220260                }
    221261            }
  • trunk/CrypPlugins/WorkspaceManager/Model/WorkspaceModel.cs

    r1620 r1680  
    8383        {
    8484            PluginModel pluginModel = new PluginModel();
    85             pluginModel.WorkspaceModel = this;
     85            pluginModel.WorkspaceModel = this;           
     86            pluginModel.Startable = pluginType.GetPluginInfoAttribute().Startable;
    8687            pluginModel.Position = position;
    8788            pluginModel.Width = width;
    8889            pluginModel.Height = height;
    89             pluginModel.PluginType = pluginType;
     90            pluginModel.PluginType = pluginType;           
     91            pluginModel.Name = pluginType.Name;
    9092            pluginModel.generateConnectors();
    91             pluginModel.Name = pluginType.Name;
    9293            pluginModel.Plugin.OnGuiLogNotificationOccured += this.WorkspaceManagerEditor.GuiLogNotificationOccured;
    9394            pluginModel.Plugin.OnPluginProgressChanged += pluginModel.PluginProgressChanged;
     
    255256                return false;
    256257            }
    257 
     258           
    258259            if (connectorModelA.ConnectorType.Equals(connectorModelB.ConnectorType)
    259                 || connectorModelA.ConnectorType.BaseType.Equals(connectorModelB.ConnectorType))
     260                || connectorModelA.ConnectorType.FullName == "System.Object"
     261                || connectorModelB.ConnectorType.FullName == "System.Object"
     262                || connectorModelA.ConnectorType.IsSubclassOf(connectorModelB.ConnectorType)
     263                || connectorModelA.ConnectorType.GetInterfaces().Contains(connectorModelB.ConnectorType))             
    260264            {
    261265                return true;
     
    265269                return false;
    266270            }
    267         }       
     271        }
    268272    }
    269273}
  • trunk/CrypPlugins/WorkspaceManager/View/Container/ConnectorView.xaml.cs

    r1640 r1680  
    6464            this.MouseLeftButtonDown += new MouseButtonEventHandler(ConnectorView_MouseLeftButtonDown);
    6565            this.Model = cModel;
     66            this.Model.UpdateableView = this;
    6667            InitializeComponent();
    6768            Color color = ColorHelper.GetColor(cModel.ConnectorType);
     
    8586        public void update()
    8687        {
    87             if (model.HasLastData)
     88            if (model.HasData)
    8889            {
    89                 ToolTip = model.LastData;
     90                ToolTip = model.Data;
    9091            }
    9192        }
  • trunk/CrypPlugins/WorkspaceManager/View/Container/PluginContainerView.xaml

    r1640 r1680  
    4242        <Border Name="Window" Background="{StaticResource ResourceKey=GlassBrush}" CornerRadius="7" BorderBrush="#82bbef" BorderThickness="1.3">
    4343            <Grid>
    44                 <ProgressBar Name="ProgressBar" Foreground="Green" Background="{Binding ElementName=PluginNamePlate, Path=Fill}" Opacity="0.3" >
     44                <ProgressBar Name="ProgressBar" Maximum="1.0" Foreground="Green" Background="{Binding ElementName=PluginNamePlate, Path=Fill}" Opacity="0.3" >
    4545                    <ProgressBar.Resources>
    4646                        <ResourceDictionary Source="/PresentationFramework.Aero;v3.0.0.0;31bf3856ad364e35;component/themes/aero.normalcolor.xaml"/>
  • trunk/CrypPlugins/WorkspaceManager/WorkspaceManager.cs

    r1637 r1680  
    3434using System.Windows.Threading;
    3535using System.Threading;
     36using System.Windows.Controls;
    3637
    3738//Disable warnings for unused or unassigned fields and events:
     
    354355                this.WorkspaceManagerEditorView.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
    355356                {
    356                     this.WorkspaceManagerEditorView.root.IsEnabled = false;   
     357                    this.WorkspaceManagerEditorView.root.IsEnabled = false;                    
    357358                }
    358                 , null);
    359 
    360                 try
    361                 {
    362                     ExecutionEngine.CheckInterval = long.Parse(((WorkspaceManagerSettings)this.Settings).CheckInterval);
    363                 }
    364                 catch (Exception ex)
    365                 {
    366                     GuiLogMessage("Could not set CheckInterval: " + ex.Message, NotificationLevel.Warning);
    367                     ExecutionEngine.CheckInterval = 10;
    368                 }
     359                , null);               
    369360
    370361                try
  • trunk/CrypPlugins/WorkspaceManager/WorkspaceManagerSettings.cs

    r1637 r1680  
    3838                OnPropertyChanged("GuiUpdateInterval");
    3939            }
    40         }
    41 
    42         private String checkInterval = "10";
    43         [TaskPane("CheckInterval", "The interval the plugins should be checked for being executable.", null, 1, false, DisplayLevel.Beginner, ControlType.TextBox)]
    44         public String CheckInterval
    45         {
    46             get
    47             {
    48                 return checkInterval;
    49             }
    50             set
    51             {
    52                 checkInterval = value;
    53                 OnPropertyChanged("CheckInterval");
    54             }
    55         }
     40        }     
    5641
    5742        private bool benchmarkPlugins = false;
Note: See TracChangeset for help on using the changeset viewer.