Changeset 1700


Ignore:
Timestamp:
Jun 24, 2010, 4:32:45 PM (11 years ago)
Author:
kopal
Message:
  • WorkspaceManager now allows multiple Connections on InputConnectors
  • Created own Gears4Net Scheduler which implements flow control in WorkspaceManagers ExecutionEngine to support loops
  • some small bugfixes
Location:
trunk/CrypPlugins/WorkspaceManager
Files:
5 edited

Legend:

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

    r1684 r1700  
    2727using Gears4Net;
    2828using System.Windows.Threading;
     29using System.Runtime.Remoting.Contexts;
    2930
    3031namespace WorkspaceManager.Execution
     
    8182                //use this amount of schedulers
    8283                schedulers = new Scheduler[System.Environment.ProcessorCount*2];
    83                 for(int i=0;i<System.Environment.ProcessorCount*2;i++){
    84                     schedulers[i] = new STAScheduler("Scheduler" + i);
    85                 }
    86 
     84                for(int i=0;i< System.Environment.ProcessorCount*2;i++){
     85                    schedulers[i] = new WorkspaceManagerScheduler("Scheduler" + i);                   
     86                }
     87               
    8788                //We have to reset all states of PluginModels, ConnectorModels and ConnectionModels:
    8889                workspaceModel.resetStates();
     
    122123                        pluginProtocol.BroadcastMessageReliably(msg);
    123124                    }
     125                }
     126
     127                foreach (Scheduler scheduler in schedulers)
     128                {
     129                    ((WorkspaceManagerScheduler)scheduler).startScheduler();
    124130                }
    125131            }
     
    298304    public class PluginProtocol : ProtocolBase
    299305    {
    300         private PluginModel pluginModel;
     306        public PluginModel PluginModel;
    301307        private ExecutionEngine executionEngine;
    302308
     
    309315            : base(scheduler)
    310316        {
    311             this.pluginModel = pluginModel;
     317            this.PluginModel = pluginModel;
    312318            this.executionEngine = executionEngine;
    313319        }
     
    322328            while (this.executionEngine.IsRunning)
    323329            {
    324                 yield return Receive<MessageExecution>(null, this.HandleExecute);             
     330                yield return Receive<MessageExecution>(null, this.HandleExecute);
     331                //yield return Parallel(1,new PluginWaitReceiver()) & Receive<MessageExecution>(null, this.HandleExecute);
     332                //yield return new PluginWaitReceiver() + Receive<MessageExecution>(null, this.HandleExecute);
     333                //yield return Parallel(1,new PluginWaitReceiver()) + Receive<MessageExecution>(null, this.HandleExecute);
    325334            }
    326335        }
     
    332341        private void HandleExecute(MessageExecution msg)
    333342        {
    334            
    335343            //executionEngine.GuiLogMessage("HandleExecute for \"" + msg.PluginModel.Name + "\"", NotificationLevel.Debug);
    336344            //Fill the plugins Inputs with data
    337             foreach (ConnectorModel connectorModel in pluginModel.InputConnectors)
     345            foreach (ConnectorModel connectorModel in PluginModel.InputConnectors)
    338346            {
    339347                if (connectorModel.HasData)
    340                 {
    341                     if (connectorModel.IsDynamic)
    342                     {
    343                         MethodInfo propertyInfo = pluginModel.Plugin.GetType().GetMethod(connectorModel.DynamicSetterName);
    344                         propertyInfo.Invoke(pluginModel.Plugin, new object[]{connectorModel.PropertyName, connectorModel.Data});
    345                     }
    346                     else
    347                     {
    348                         PropertyInfo propertyInfo = pluginModel.Plugin.GetType().GetProperty(connectorModel.PropertyName);
    349                         propertyInfo.SetValue(pluginModel.Plugin, connectorModel.Data, null);
     348                {                   
     349                    try
     350                    {
     351                        if (connectorModel.IsDynamic)
     352                        {
     353                            MethodInfo propertyInfo = PluginModel.Plugin.GetType().GetMethod(connectorModel.DynamicSetterName);
     354                            propertyInfo.Invoke(PluginModel.Plugin, new object[] { connectorModel.PropertyName, connectorModel.Data });
     355                        }
     356                        else
     357                        {
     358                            PropertyInfo propertyInfo = PluginModel.Plugin.GetType().GetProperty(connectorModel.PropertyName);
     359                            propertyInfo.SetValue(PluginModel.Plugin, connectorModel.Data, null);
     360                        }
     361                    }
     362                    catch (Exception ex)
     363                    {
     364                        this.PluginModel.WorkspaceModel.WorkspaceManagerEditor.GuiLogMessage("An error occured while setting value of connector \"" + connectorModel.Name + "\" of \"" + PluginModel + "\": " + ex.Message, NotificationLevel.Error);
     365                        this.PluginModel.State = PluginModelState.Error;
     366                        this.PluginModel.GuiNeedsUpdate = true;
     367                        return;
    350368                    }
    351369                }
     
    361379     
    362380    }
     381
     382    public class WorkspaceManagerScheduler : Scheduler
     383    {
     384        private System.Threading.AutoResetEvent wakeup = new System.Threading.AutoResetEvent(false);
     385        private bool shutdown = false;
     386        private System.Threading.Thread thread;
     387        private Context currentContext;
     388
     389                public WorkspaceManagerScheduler() : this(String.Empty)
     390                {
     391
     392                }
     393
     394        public WorkspaceManagerScheduler(string name)
     395            : base()
     396        {
     397            this.currentContext = Thread.CurrentContext;
     398
     399            thread = new System.Threading.Thread(this.Start);
     400            thread.SetApartmentState(System.Threading.ApartmentState.STA);
     401                        thread.Name = name;
     402           
     403        }
     404
     405        public void startScheduler()
     406        {
     407            thread.Start();
     408        }
     409
     410        private void Start()
     411        {
     412            if (this.currentContext != Thread.CurrentContext)
     413                this.currentContext.DoCallBack(Start);
     414
     415            // Loop forever
     416            while (true)
     417            {
     418                this.wakeup.WaitOne();
     419
     420                // Loop while there are more protocols waiting
     421                while (true)
     422                {
     423                    // Should the scheduler stop?
     424                    if (this.shutdown)
     425                        return;
     426                   
     427                    bool donotrun = false;
     428                    ProtocolBase protocol = null;
     429                    lock (this)
     430                    {
     431                        // No more protocols? -> Wait
     432                        if (this.waitingProtocols.Count == 0)
     433                            break;
     434                        protocol = this.waitingProtocols.Dequeue();
     435
     436                        if (protocol is PluginProtocol)
     437                        {
     438                            PluginProtocol pluginProtocol = (PluginProtocol)protocol;
     439                            foreach (ConnectorModel outputConnector in pluginProtocol.PluginModel.OutputConnectors)
     440                            {
     441                                foreach (ConnectionModel connection in outputConnector.OutputConnections)
     442                                {
     443                                   
     444                                    if (connection.To.PluginModel.PluginProtocol.QueueLength > 0 &&
     445                                        connection.To.PluginModel != pluginProtocol.PluginModel &&
     446                                        donotrun == false)
     447                                    {                                           
     448                                        this.waitingProtocols.Enqueue(protocol);
     449                                        donotrun = true;
     450                                    }
     451                                 
     452                                }
     453                            }               
     454                        }
     455
     456                    }
     457
     458                    if (donotrun == false)
     459                    {
     460                        ProtocolStatus status = protocol.Run();
     461
     462                        lock (this)
     463                        {
     464                            switch (status)
     465                            {
     466                                case ProtocolStatus.Created:
     467                                    System.Diagnostics.Debug.Assert(false);
     468                                    break;
     469                                case ProtocolStatus.Ready:
     470                                    this.waitingProtocols.Enqueue(protocol);
     471                                    break;
     472                                case ProtocolStatus.Waiting:
     473                                    break;
     474                                case ProtocolStatus.Terminated:
     475                                    System.Diagnostics.Debug.Assert(!this.waitingProtocols.Contains(protocol));
     476                                    this.RemoveProtocol(protocol);
     477                                    break;
     478                            }
     479                        }
     480                    }
     481                }
     482            }
     483        }
     484
     485        public override void RemoveProtocol(ProtocolBase protocol)
     486        {
     487            lock (this)
     488            {
     489                this.protocols.Remove(protocol);
     490                if (this.protocols.Count == 0)
     491                    this.Shutdown();
     492            }
     493        }
     494
     495        public override void AddProtocol(ProtocolBase protocol)
     496        {
     497            lock (this)
     498            {
     499                this.protocols.Add(protocol);
     500            }
     501        }
     502
     503        public override void Wakeup(ProtocolBase protocol)
     504        {
     505            lock (this)
     506            {
     507                if (!this.waitingProtocols.Contains(protocol))
     508                    this.waitingProtocols.Enqueue(protocol);
     509                this.wakeup.Set();
     510            }
     511        }
     512
     513        public override void Shutdown()
     514        {
     515            this.shutdown = true;
     516            this.wakeup.Set();
     517        }
     518    }
    363519}
  • trunk/CrypPlugins/WorkspaceManager/Model/ConnectorModel.cs

    r1680 r1700  
    1616
    1717using System;
    18 using System.Collections.Generic;
    1918using System.Linq;
    2019using System.Text;
     
    2423using WorkspaceManager.View.Container;
    2524using System.Windows.Media;
     25using System.Collections.Generic;
    2626
    2727namespace WorkspaceManager.Model
    2828{
    2929   
    30 
    3130    /// <summary>
    3231    /// Class to represent the Connection between two Connector Models
     
    3736        [NonSerialized]
    3837        private bool hasData = false;
    39 
    40         [NonSerialized]
    41         private object data;
    4238       
    4339        /// <summary>
     
    5753       
    5854        /// <summary>
    59         /// The InputConnection of this ConnectorModel
    60         /// </summary>
    61         public ConnectionModel InputConnection { get; set; }
     55        /// The InputConnections of this ConnectorModel
     56        /// </summary>
     57        public List<ConnectionModel> InputConnections;
    6258
    6359        /// <summary>
     
    7167        public ConnectorModel()
    7268        {
    73             this.OutputConnections = new List<ConnectionModel>();
     69            this.InputConnections = new List<ConnectionModel>();
     70            this.OutputConnections = new List<ConnectionModel>();           
    7471        }
    7572
     
    135132        /// Data of this Connector
    136133        /// </summary>
    137         public object Data
    138         {
    139             get
    140             {
    141                 return data;
    142             }
    143 
    144             set
    145             {
    146                 data = value;
    147             }
    148         }       
    149 
     134        [NonSerialized]
     135        public object Data = null;
     136       
    150137        /// <summary>
    151138        /// Name of the represented Property of the IPlugin of this ConnectorModel
     
    181168                    connectionModel.To.HasData = true;
    182169                    connectionModel.Active = true;
    183                    
    184                     //We changed an input on the PluginModel where "To" is belonging to so
    185                     //we have to check if this is executable now
     170                }
     171
     172               //We changed an input on the PluginModels where "To"s are belonging to so
     173                //we have to check if there are executable now
     174                foreach (ConnectionModel connectionModel in this.OutputConnections)
     175                {
    186176                    connectionModel.To.PluginModel.checkExecutable(connectionModel.To.PluginModel.PluginProtocol);
    187177                }
     
    206196                if (this.PropertyName == dynamicProperty.Name)
    207197                {
    208                     if(this.InputConnection != null){
    209                         this.WorkspaceModel.deleteConnectionModel(this.InputConnection);
     198                    foreach(ConnectionModel connectionModel in new List<ConnectionModel>(InputConnections)){
     199                        this.WorkspaceModel.deleteConnectionModel(connectionModel);
    210200                    }
    211201                    foreach(ConnectionModel connectionModel in new List<ConnectionModel>(this.OutputConnections))
  • trunk/CrypPlugins/WorkspaceManager/Model/PluginModel.cs

    r1684 r1700  
    139139                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
    140140                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
     141                        connectorModel.Name = propertyInfoAttribute.PropertyName;
    141142                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
    142143                        connectorModel.ConnectorOrientation = ConnectorOrientation.West;
     
    152153                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
    153154                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
     155                        connectorModel.Name = propertyInfoAttribute.PropertyName;
    154156                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
    155157                        connectorModel.ConnectorOrientation = ConnectorOrientation.East;
     
    175177                            connectorModel.PluginModel = this;
    176178                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
    177                             connectorModel.PropertyName = dynamicProperty.Name;                           
     179                            connectorModel.PropertyName = dynamicProperty.Name;
     180                            connectorModel.Name = dynamicProperty.Name;
    178181                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
    179182                            connectorModel.ConnectorOrientation = ConnectorOrientation.West;
     
    194197                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
    195198                            connectorModel.PropertyName = dynamicProperty.Name;
     199                            connectorModel.Name = dynamicProperty.Name;
    196200                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
    197201                            connectorModel.ConnectorOrientation = ConnectorOrientation.East;
     
    258262                return;
    259263            }
    260 
    261             bool AtLeastOneInputSet = false;
     264           
    262265            //First test if every mandatory Connector has data
    263266            //or one non-mandatory input has data
    264267            foreach (ConnectorModel connectorModel in this.InputConnectors)
    265268            {
    266                 if ((connectorModel.IsMandatory /*|| connectorModel.InputConnection != null*/) && !connectorModel.HasData)
     269                if ((connectorModel.IsMandatory || connectorModel.InputConnections.Count > 0) && !connectorModel.HasData)
    267270                {
    268271                    return;
    269                 }
    270                 else if (connectorModel.HasData)
    271                 {
    272                     AtLeastOneInputSet = true;
    273                 }
    274             }
    275 
    276             if (AtLeastOneInputSet)
    277             {
    278                 MessageExecution msg = new MessageExecution();
    279                 msg.PluginModel = this;
     272                }               
     273            }
     274
     275            MessageExecution msg = new MessageExecution();
     276            msg.PluginModel = this;
    280277               
    281                 //protocolBase is set at Startup of the ExecutionEngine
    282                 //but it could be that we have an event before setting
    283                 //of the protocl base (triggered by user clicking on
    284                 //a plugins presentation (button or so))
    285                 if (protocolBase != null)
    286                 {
    287                     protocolBase.BroadcastMessageReliably(msg);
    288                 }
    289             }
     278            //protocolBase is set at Startup of the ExecutionEngine
     279            //but it could be that we have an event before setting
     280            //of the protocl base (triggered by user clicking on
     281            //a plugins presentation (button or so))
     282            if (protocolBase != null)
     283            {
     284                protocolBase.BroadcastMessageReliably(msg);
     285            }
     286
    290287            return;
    291288        }
  • trunk/CrypPlugins/WorkspaceManager/Model/WorkspaceModel.cs

    r1684 r1700  
    125125            connectionModel.To = to;
    126126            from.OutputConnections.Add(connectionModel);
    127             to.InputConnection = connectionModel;
     127            to.InputConnections.Add(connectionModel);
    128128            connectionModel.ConnectionType = connectionType;
    129129            this.AllConnectionModels.Add(connectionModel);
     
    173173            if(this.AllConnectorModels.Contains(connectorModel)){
    174174
     175                //remove all input ConnectionModels belonging to this Connector from our WorkspaceModel
     176                foreach (ConnectionModel connectionModel in new List<ConnectionModel>(connectorModel.InputConnections))
     177                {
     178                    deleteConnectionModel(connectionModel);
     179                }
     180
    175181                //remove all output ConnectionModels belonging to this Connector from our WorkspaceModel
    176182                foreach (ConnectionModel outputConnection in new List<ConnectionModel>(connectorModel.OutputConnections))
     
    178184                    deleteConnectionModel(outputConnection);
    179185                }
    180 
    181                 //remove the input ConnectionModel belonging to this Connector from our WorkspaceModel
    182                 if (connectorModel.InputConnection != null)
    183                 {
    184                     deleteConnectionModel(connectorModel.InputConnection);
    185                 }
     186                               
    186187                connectorModel.onDelete();
    187188                this.WorkspaceManagerEditor.HasChanges = true;
     
    201202                return false;
    202203
    203             connectionModel.From.OutputConnections.Remove(connectionModel);
    204             connectionModel.To.InputConnection = null;
     204            connectionModel.To.InputConnections.Remove(connectionModel);
     205            connectionModel.From.OutputConnections.Remove(connectionModel);           
    205206            connectionModel.onDelete();
    206207            this.WorkspaceManagerEditor.HasChanges = true;
     
    238239            if (connectionModel.To != null)
    239240            {
    240                 connectionModel.To.InputConnection = null;
     241                connectionModel.To.InputConnections.Remove(connectionModel);
    241242            }
    242243            connectionModel.To = connectorModel;
    243             connectorModel.InputConnection = connectionModel;
     244            connectorModel.InputConnections.Add(connectionModel);
    244245            this.WorkspaceManagerEditor.HasChanges = true;
    245246            return true;
     
    256257        public static bool compatibleConnectors(ConnectorModel connectorModelA, ConnectorModel connectorModelB)
    257258        {
    258             if (!connectorModelA.Outgoing || connectorModelB.Outgoing || connectorModelB.InputConnection != null)
     259            if (!connectorModelA.Outgoing || connectorModelB.Outgoing)
    259260            {
    260261                return false;
  • trunk/CrypPlugins/WorkspaceManager/View/Container/PluginContainerView.xaml.cs

    r1685 r1700  
    239239            ProgressBarInit.Value = model.PercentageFinished;
    240240            Icon = model.getImage();
     241
     242            if (PresentationPanel.Child is Image)
     243            {
     244                PresentationPanel.Child = this.Icon;
     245            }
    241246        }
    242247
Note: See TracChangeset for help on using the changeset viewer.