source: trunk/CrypPlugins/WorkspaceManager/Execution/ExecutionEngine.cs @ 1562

Last change on this file since 1562 was 1562, checked in by kopal, 12 years ago
  • replaced x,y.coordinates of PluginModel with a Point
  • Fetched OnPluginProgressChanged now by PluginModel and automatically set PercentageFinished
  • some small fixes
File size: 8.1 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.Linq;
20using System.Text;
21
22using WorkspaceManager.Model;
23using System.Threading;
24using System.Collections;
25using Cryptool.PluginBase;
26using System.Reflection;
27
28namespace WorkspaceManager.Execution
29{
30    /// <summary>
31    /// Engine to execute a model of the WorkspaceManager
32    /// </summary>
33    public class ExecutionEngine
34    {
35        private Hashtable RunningPlugins = Hashtable.Synchronized(new Hashtable());
36        private WorkspaceManager WorkspaceManagerEditor;
37        private Mutex mutex = new Mutex();
38
39        /// <summary>
40        /// Enable/Disable the Debug Mode
41        /// </summary>
42        public bool DebugMode { get; set; }
43
44        /// <summary>
45        /// Creates a new ExecutionEngine
46        /// </summary>
47        /// <param name="workspaceManagerEditor"></param>
48        public ExecutionEngine(WorkspaceManager workspaceManagerEditor)
49        {
50            WorkspaceManagerEditor = workspaceManagerEditor;
51        }
52
53        /// <summary>
54        /// Is this ExecutionEngine running?
55        /// </summary>
56        public bool IsRunning
57        {
58            get;
59            private set;
60        }
61
62        /// <summary>
63        /// Execute the current Model
64        /// </summary>
65        /// <param name="workspaceModel"></param>
66        public void Execute(WorkspaceModel workspaceModel)
67        {           
68            RunningPlugins.Clear();
69            GuiLogMessage("ExecutionEngine starts", NotificationLevel.Debug);
70            ThreadPool.SetMaxThreads(1, 1);
71            ThreadPool.QueueUserWorkItem(new WaitCallback(Schedule), workspaceModel);
72        }
73
74        /// <summary>
75        /// Scheduler Thread
76        /// </summary>
77        /// <param name="stateInfo"></param>
78        public void Schedule(object stateInfo)
79        {
80            WorkspaceModel workspaceModel = (WorkspaceModel)stateInfo;
81            if (!IsRunning)
82            {
83                IsRunning = true;
84                workspaceModel.resetStates();
85
86                //Initially check if a plugin can be executed
87                foreach (PluginModel pluginModel in workspaceModel.AllPluginModels)
88                {
89                    pluginModel.checkExecutable();
90                }
91
92                //Now start Plugins if they are executable
93                while (IsRunning)
94                {
95                    foreach (PluginModel pluginModel in workspaceModel.AllPluginModels)
96                    {
97                       
98                        //execute the plugin in a new Thread only if it is executable
99                        if (IsRunning && pluginModel.ExecutionState == PluginModelState.Executable && !RunningPlugins.Contains(pluginModel))
100                        {
101                            AddRunningPlugin(pluginModel);
102                            ThreadPool.QueueUserWorkItem(new WaitCallback(runPlugin), pluginModel);
103                        }
104                        Thread.Sleep(50);
105                    }
106                }
107                GuiLogMessage("ExecutionEngine ends", NotificationLevel.Debug);
108            }
109        }
110
111        /// <summary>
112        /// Runs a Plugin
113        /// </summary>
114        /// <param name="stateInfo"></param>
115        private void runPlugin(object stateInfo)
116        {   
117         
118            PluginModel pluginModel = (PluginModel)stateInfo;           
119            GuiLogMessage("Running Plugin " + pluginModel.Name + " now!", NotificationLevel.Debug);
120           
121            //Fill the plugins Inputs with data
122            foreach (ConnectorModel connectorModel in pluginModel.InputConnectors)
123            {
124                if (connectorModel.HasData)
125                {                   
126                    PropertyInfo propertyInfo = pluginModel.Plugin.GetType().GetProperty(connectorModel.PropertyName);
127                    GuiLogMessage("Setting for " + connectorModel.PluginModel.Name + " the value of property " + propertyInfo.Name + " to \"" + connectorModel.Data +"\"", NotificationLevel.Debug);
128                    propertyInfo.SetValue(pluginModel.Plugin, connectorModel.Data, null);   
129                    connectorModel.Data = null;
130                    connectorModel.HasData = false;
131                    connectorModel.InputConnection.Active = false;
132                }
133            }
134
135            //Run execution
136            try
137            {
138                pluginModel.ExecutionState = PluginModelState.PreExecuting;
139                pluginModel.Plugin.PreExecution();
140                pluginModel.ExecutionState = PluginModelState.Executing;
141                pluginModel.Plugin.Execute();
142                pluginModel.ExecutionState = PluginModelState.PostExecuting;
143                pluginModel.Plugin.PostExecution();
144                pluginModel.ExecutionState = PluginModelState.Terminated;
145            }
146            catch (Exception ex)
147            {
148                pluginModel.ExecutionState = PluginModelState.Error;
149                GuiLogMessage("Error during Execution of Plugin " + pluginModel.Name + ": " + ex.Message, NotificationLevel.Error);
150            }
151            //Remove plugin from being-executed-list so that it can be
152            //executed again
153            if (IsRunning)
154            {
155                //we only remove the plugin if we are in state running;otherwise
156                //the Stop() method will remove it
157                RemoveRunningPlugin(pluginModel);
158            }
159            GuiLogMessage("Stopped Plugin " + pluginModel.Name, NotificationLevel.Debug);
160            Thread.Sleep(15);
161        }
162
163        /// <summary>
164        /// Stop the execution
165        /// </summary>
166        public void Stop()
167        {
168            mutex.WaitOne();
169            IsRunning = false;
170            foreach (PluginModel pluginModel in RunningPlugins.Keys)
171            {
172                pluginModel.Plugin.Stop();             
173            }
174            RunningPlugins.Clear();
175            mutex.ReleaseMutex();
176        }
177
178        /// <summary>
179        /// Pause the execution
180        /// </summary>
181        public void Pause()
182        {
183            //not implemented yet
184        }
185
186        /// <summary>
187        /// Use the logger of the WorkspaceManagerEditor
188        /// </summary>
189        /// <param name="message"></param>
190        /// <param name="level"></param>
191        private void GuiLogMessage(string message, NotificationLevel level)
192        {
193            if (DebugMode || level.Equals(NotificationLevel.Error) || level.Equals(NotificationLevel.Warning))
194            {
195                WorkspaceManagerEditor.GuiLogMessage(message, level);
196            }
197        }
198
199        /// <summary>
200        /// Add a running plugin
201        /// </summary>
202        /// <param name="pluginModel"></param>
203        private void AddRunningPlugin(PluginModel pluginModel)
204        {
205            mutex.WaitOne();
206            if (IsRunning)
207            {
208                RunningPlugins.Add(pluginModel, pluginModel);
209            }
210            mutex.ReleaseMutex();
211        }
212
213        /// <summary>
214        /// Remove a running plugin
215        /// </summary>
216        /// <param name="pluginModel"></param>
217        private void RemoveRunningPlugin(PluginModel pluginModel)
218        {
219            mutex.WaitOne();
220            if(RunningPlugins.Contains(pluginModel))
221            {
222                RunningPlugins.Remove(pluginModel);
223            }
224            mutex.ReleaseMutex();
225        }
226
227    }
228}
Note: See TracBrowser for help on using the repository browser.