source: trunk/CrypPlugins/WorkspaceManager/WorkspaceManager.cs @ 1929

Last change on this file since 1929 was 1929, checked in by kopal, 11 years ago
  • some optimization
  • Benchmark now loggs Plugins/sec and Memory Usage to logg files (only for testing purposes; will be removed in later releases)
File size: 21.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
17
18using System;
19using System.Collections.Generic;
20using System.Linq;
21using System.Text;
22using Cryptool.Core;
23using Cryptool.PluginBase.Editor;
24using Cryptool.UiPluginBase;
25using Cryptool.PluginBase.IO;
26using Cryptool.PluginBase;
27
28using WorkspaceManager.Model;
29using WorkspaceManager.View;
30using WorkspaceManager.Execution;
31using WorkspaceManager.View.Container;
32using WorkspaceManager.View.Converter;
33using System.Windows;
34using System.Windows.Threading;
35using System.Threading;
36using System.Windows.Controls;
37using System.Windows.Media;
38using Cryptool.PluginBase.Miscellaneous;
39
40//Disable warnings for unused or unassigned fields and events:
41#pragma warning disable 0169, 0414, 0067
42
43namespace WorkspaceManager
44{
45    /// <summary>
46    /// Workspace Manager - PluginEditor based on MVC Pattern
47    /// </summary>
48    [EditorInfo("cwm")]
49    [Author("Viktor Matkovic,Nils Kopal", "nils.kopal@cryptool.org", "Universität Duisburg-Essen", "http://www.uni-due.de")]
50    [PluginInfo("WorkspaceManager.Resources.Attributes", false, "Workspace Manager", "Graphical plugin editor for the CrypTool workspace", null,
51      "AnotherEditor/icon.png",
52      "AnotherEditor/Images/addWorkspace.png",
53      "AnotherEditor/Images/deleteWorkspace.png",
54      "AnotherEditor/Images/importSubWorkspace.png")]
55    public class WorkspaceManager : IEditor
56    {
57
58        /// <summary>
59        /// Create a new Instance of the Editor
60        /// </summary>
61        public WorkspaceManager()
62        {
63            Settings = new WorkspaceManagerSettings();
64            WorkspaceModel = new WorkspaceModel();
65            WorkspaceModel.WorkspaceManagerEditor = this;
66            WorkspaceSpaceEditorView = new WorkSpaceEditorView(WorkspaceModel);
67            HasChanges = false;                               
68        }
69
70        #region private Members
71
72        private WorkspaceModel WorkspaceModel = null;
73        private WorkSpaceEditorView WorkspaceSpaceEditorView = null;
74        private ExecutionEngine ExecutionEngine = null;
75        private volatile bool executing = false;
76
77        #endregion
78
79        /// <summary>
80        /// Is this Editor executing?
81        /// </summary>
82        public bool isExecuting(){
83            return executing;
84        }
85
86        #region IEditor Members
87
88        /// <summary>
89        ///
90        /// </summary>
91        public event ChangeDisplayLevelHandler OnChangeDisplayLevel;
92
93        /// <summary>
94        ///
95        /// </summary>
96        public event SelectedPluginChangedHandler OnSelectedPluginChanged;
97
98        /// <summary>
99        ///
100        /// </summary>
101        public event ProjectTitleChangedHandler OnProjectTitleChanged;
102
103        /// <summary>
104        ///
105        /// </summary>
106        public event OpenProjectFileHandler OnOpenProjectFile;
107
108        /// <summary>
109        ///
110        /// </summary>
111        public event EditorSpecificPluginsChanged OnEditorSpecificPluginsChanged;
112
113        /// <summary>
114        /// Called by clicking on the new button of CrypTool
115        /// Creates a new Model
116        /// </summary>
117        public void New()
118        {
119            foreach (PluginModel pluginModel in new List<PluginModel>(WorkspaceModel.AllPluginModels))
120            {
121                WorkspaceModel.deletePluginModel(pluginModel);
122            }
123            this.HasChanges = false;
124            this.OnProjectTitleChanged.BeginInvoke(this, "unnamed project", null, null);
125        }
126
127        /// <summary>
128        /// Called by clicking on the open button of CrypTool
129        /// loads a serialized model
130        /// </summary>
131        /// <param name="fileName"></param>
132        public void Open(string fileName)
133        {
134            try
135            {
136                New();
137                GuiLogMessage("Loading Model: " + fileName, NotificationLevel.Info);               
138                WorkspaceModel = ModelPersistance.loadModel(fileName,this);               
139                WorkspaceSpaceEditorView.Load(WorkspaceModel);
140                HasChanges = false;
141                this.OnProjectTitleChanged.BeginInvoke(this, fileName, null, null);
142            }
143            catch (Exception ex)
144            {
145                GuiLogMessage("Could not load Model:" + ex.ToString(), NotificationLevel.Error);
146            }
147        }
148
149        /// <summary>
150        /// Called by clicking on the save button of CrypTool
151        /// serializes the current model
152        /// </summary>
153        /// <param name="fileName"></param>
154        public void Save(string fileName)
155        {
156            try
157            {
158                GuiLogMessage("Saving Model: " + fileName, NotificationLevel.Info);
159                ModelPersistance.saveModel(this.WorkspaceModel, fileName);
160                HasChanges = false;
161                this.OnProjectTitleChanged.BeginInvoke(this, fileName, null, null);
162            }
163            catch (Exception ex)
164            {
165                GuiLogMessage("Could not save Model:" + ex.ToString(), NotificationLevel.Error);               
166            }
167           
168        }
169
170        /// <summary>
171        /// Called by double clicking on a plugin symbol of CrypTool
172        /// Adds a new PluginModel wrapping an instance of the selected plugin
173        /// </summary>
174        /// <param name="type"></param>
175        public void Add(Type type)
176        {
177            /*if (!executing)
178            {
179                PluginModel newPluginModel = WorkspaceModel.newPluginModel(new Point(10, 10), 100, 100, type);
180                GuiLogMessage("Added by double click: " + newPluginModel.Name, NotificationLevel.Info);
181                HasChanges = true;
182            }*/
183        }
184
185        /// <summary>
186        ///
187        /// </summary>
188        /// <param name="espi"></param>
189        public void AddEditorSpecific(EditorSpecificPluginInfo espi)
190        {
191            //to be implemented
192        }
193
194        /// <summary>
195        ///
196        /// </summary>
197        /// <param name="espi"></param>
198        public void DeleteEditorSpecific(EditorSpecificPluginInfo espi)
199        {
200            //to be implemented   
201        }
202
203        /// <summary>
204        /// Undo changes
205        /// </summary>
206        public void Undo()
207        {
208            //to be implemented
209        }
210
211        /// <summary>
212        /// Redo changes
213        /// </summary>
214        public void Redo()
215        {
216            //to be implemented
217        }
218
219        /// <summary>
220        /// Show the Help site
221        /// </summary>
222        public void ShowHelp()
223        {
224            //to be implemented
225        }
226
227        /// <summary>
228        /// Show the Description of the selected plugin
229        /// </summary>
230        public void ShowSelectedPluginDescription()
231        {
232            //to be implemented
233        }
234
235        /// <summary>
236        /// Is Undo possible
237        /// </summary>
238        public bool CanUndo
239        {
240            get;
241            set;
242        }
243
244        /// <summary>
245        /// Is Redo possible?
246        /// </summary>
247        public bool CanRedo
248        {
249            get;
250            set;
251        }
252
253        /// <summary>
254        /// Can the ExecutionEngine be started?
255        /// </summary>
256        public bool CanExecute
257        {
258            get{return !executing;}
259        }
260
261        /// <summary>
262        /// Can the ExecutionEngine be stopped?
263        /// </summary>
264        public bool CanStop
265        {
266            get { return executing; }
267        }
268
269        /// <summary>
270        /// Does this Editor has changes?
271        /// </summary>
272        public bool HasChanges
273        {
274            get;
275            set;
276        }
277
278        /// <summary>
279        /// DisplayLevel
280        /// </summary>
281        public DisplayLevel DisplayLevel
282        {
283            get;
284            set;
285           
286        }
287
288        /// <summary>
289        ///
290        /// </summary>
291        public List<EditorSpecificPluginInfo> EditorSpecificPlugins
292        {
293            get;
294            set;
295        }
296
297        #endregion
298
299        #region IPlugin Members
300
301        /// <summary>
302        ///
303        /// </summary>
304        public event StatusChangedEventHandler OnPluginStatusChanged;
305
306        /// <summary>
307        ///
308        /// </summary>
309        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
310
311        /// <summary>
312        ///
313        /// </summary>
314        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
315
316        /// <summary>
317        /// Settings of this editor
318        /// </summary>
319        public ISettings Settings
320        {
321            get;
322            set;
323        }
324
325        /// <summary>
326        /// The Presentation of this editor
327        /// </summary>
328        public System.Windows.Controls.UserControl Presentation
329        {
330            get {return WorkspaceSpaceEditorView;}
331            set { WorkspaceSpaceEditorView = (WorkSpaceEditorView)value; }
332        }
333
334        /// <summary>
335        /// The QuickWatchPresentation of this editor
336        /// </summary>
337        public System.Windows.Controls.UserControl QuickWatchPresentation
338        {
339            get;
340            set;
341        }
342
343        /// <summary>
344        /// Called before execution
345        /// </summary>
346        public void PreExecution()
347        {
348            //to be implemented
349        }
350
351        /// <summary>
352        /// Starts the ExecutionEngine to execute the model
353        /// </summary>
354        public void Execute()
355        {
356            if (executing)
357            {
358                return;
359            }
360            EventsHelper.AsynchronousPropertyChanged = false;
361            try
362            {
363                GuiLogMessage("Execute Model now!", NotificationLevel.Info);
364                executing = true;
365
366                if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
367                {
368                    EventsHelper.AsynchronousProgressChanged = false;
369                    EventsHelper.AsynchronousGuiLogMessage = false;
370                    EventsHelper.AsynchronousStatusChanged = false;
371                }
372
373                //Get the gui Thread
374                this.WorkspaceSpaceEditorView.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
375                {
376                    this.WorkspaceSpaceEditorView.ResetConnections();
377                    this.WorkspaceSpaceEditorView.State = EditorState.BUSY;                   
378                }
379                , null);
380
381                this.ExecutionEngine = new ExecutionEngine(this);
382
383                try
384                {
385                    ExecutionEngine.GuiUpdateInterval = int.Parse(((WorkspaceManagerSettings)this.Settings).GuiUpdateInterval);
386                    if (ExecutionEngine.GuiUpdateInterval <= 0)
387                    {
388                        GuiLogMessage("GuiUpdateInterval can not be <=0; Use GuiUpdateInterval = 1", NotificationLevel.Warning);
389                        ExecutionEngine.GuiUpdateInterval = 1;
390                    }
391                }
392                catch (Exception ex)
393                {
394                    GuiLogMessage("Could not set GuiUpdateInterval: " + ex.Message, NotificationLevel.Warning);
395                    ExecutionEngine.GuiUpdateInterval = 100;
396                }
397
398                try
399                {
400                    ExecutionEngine.SleepTime = int.Parse(((WorkspaceManagerSettings)this.Settings).SleepTime);
401                    if (ExecutionEngine.SleepTime < 0)
402                    {
403                        GuiLogMessage("SleepTime can not be <=0; Use GuiUpdateInterval = 0", NotificationLevel.Warning);
404                        ExecutionEngine.SleepTime = 0;
405                    }
406                }
407                catch (Exception ex)
408                {
409                    GuiLogMessage("Could not set SleepTime: " + ex.Message, NotificationLevel.Warning);
410                    ExecutionEngine.GuiUpdateInterval = 0;
411                }
412
413                int schedulers=0;
414                try
415                {
416                   schedulers = int.Parse(((WorkspaceManagerSettings)this.Settings).Threads);
417                    if (ExecutionEngine.SleepTime < 0)
418                    {
419                        GuiLogMessage("Schedulers can not be <=0; Use Schedulers = 1", NotificationLevel.Warning);
420                        schedulers = 1;
421                    }
422                }
423                catch (Exception ex)
424                {
425                    GuiLogMessage("Could not set Schedulers: " + ex.Message, NotificationLevel.Warning);
426                    schedulers = 1;
427                }
428
429                ExecutionEngine.BenchmarkPlugins = ((WorkspaceManagerSettings)this.Settings).BenchmarkPlugins;
430                ExecutionEngine.ThreadPriority = ((WorkspaceManagerSettings)this.Settings).ThreadPriority;
431
432                ExecutionEngine.Execute(WorkspaceModel, schedulers);               
433            }
434            catch (Exception ex)
435            {
436                GuiLogMessage("Exception during the execution: " + ex.Message, NotificationLevel.Error);
437                executing = false;
438                if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
439                {
440                    EventsHelper.AsynchronousProgressChanged = true;
441                    EventsHelper.AsynchronousGuiLogMessage = true;
442                    EventsHelper.AsynchronousStatusChanged = true;
443                }
444            }
445        }
446
447        /// <summary>
448        /// Called after the execution
449        /// </summary>
450        public void PostExecution()
451        {
452            //to be implemented
453        }
454
455        /// <summary>
456        /// Pause the execution
457        /// </summary>
458        public void Pause()
459        {   
460            //to be implemented
461        }
462
463        /// <summary>
464        /// Stop the ExecutionEngine
465        /// </summary>
466        public void Stop()
467        {
468            if (!executing)
469            {
470                return;
471            }
472
473            EventsHelper.AsynchronousPropertyChanged = true;
474
475            if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
476            {
477                EventsHelper.AsynchronousProgressChanged = true;
478                EventsHelper.AsynchronousGuiLogMessage = true;
479                EventsHelper.AsynchronousStatusChanged = true;
480            }
481
482            try
483            {
484                GuiLogMessage("Executing stopped by User!", NotificationLevel.Info);
485                ExecutionEngine.Stop();
486                //Get the gui Thread
487                this.WorkspaceSpaceEditorView.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
488                {
489                    this.WorkspaceSpaceEditorView.ResetConnections();
490                    this.WorkspaceSpaceEditorView.State = EditorState.READY;
491                }
492                , null);
493            }
494            catch (Exception ex)
495            {
496                GuiLogMessage("Exception during the stopping of the execution: " + ex.Message, NotificationLevel.Error);
497               
498            }
499            executing = false;
500            this.ExecutionEngine = null;
501            GC.Collect();
502        }
503
504        /// <summary>
505        /// Called to initialize the editor
506        /// </summary>
507        public void Initialize()
508        {
509            //to be implemented
510        }
511
512        /// <summary>
513        /// Called when the editor is disposed
514        /// </summary>
515        public void Dispose()
516        {
517            if (ExecutionEngine != null && ExecutionEngine.IsRunning)
518            {
519                ExecutionEngine.Stop();
520            }
521            EventsHelper.AsynchronousPropertyChanged = true;
522        }
523
524        #endregion
525
526        #region INotifyPropertyChanged Members
527
528        /// <summary>
529        ///
530        /// </summary>
531        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
532
533        #endregion
534
535        #region IApplication Members
536
537        /// <summary>
538        ///
539        /// </summary>
540        private PluginManager pluginManager;
541        public PluginManager PluginManager
542        {
543            get { return pluginManager; }
544            set
545            {
546                pluginManager = value;
547                DragDropDataObjectToPluginConverter.PluginManager = value;
548            }         
549        }
550
551        #endregion
552
553        #region GuiLogMessage, Progress
554
555        /// <summary>
556        /// Loggs a message to the logging mechanism of CrypTool
557        /// </summary>
558        /// <param name="Message"></param>
559        /// <param name="notificationLevel"></param>
560        public void GuiLogMessage(string Message, NotificationLevel notificationLevel)
561        {
562            if (OnGuiLogNotificationOccured != null)
563            {
564                GuiLogEventArgs args = new GuiLogEventArgs(Message, this, notificationLevel);
565                args.Title = "-";
566                OnGuiLogNotificationOccured(this, args);
567            }
568        }
569
570        /// <summary>
571        /// GuiLogNotificationOccured
572        /// </summary>
573        /// <param name="sender"></param>
574        /// <param name="args"></param>
575        public void GuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
576        {
577            //Check if the logging event is Warning or Error and set the State of the PluginModel to
578            //the corresponding PluginModelState
579            if (args.NotificationLevel == NotificationLevel.Warning)
580            {               
581                foreach (PluginModel pluginModel in this.WorkspaceModel.AllPluginModels)
582                {
583                    if (pluginModel.Plugin == sender)
584                    {
585                        pluginModel.State = PluginModelState.Warning;
586                        pluginModel.GuiNeedsUpdate = true;
587                    }
588                }
589            }
590
591            if (args.NotificationLevel == NotificationLevel.Error)
592            {               
593                foreach (PluginModel pluginModel in this.WorkspaceModel.AllPluginModels)
594                {
595                    if (pluginModel.Plugin == sender)
596                    {
597                        pluginModel.State = PluginModelState.Error;
598                        pluginModel.GuiNeedsUpdate = true;
599                    }
600                }
601            }
602
603            if (OnGuiLogNotificationOccured != null)
604            {
605                switch (((WorkspaceManagerSettings)this.Settings).LogLevel)
606                {
607                    case 3://Error
608                        if (args.NotificationLevel == NotificationLevel.Debug ||
609                            args.NotificationLevel == NotificationLevel.Info ||
610                            args.NotificationLevel == NotificationLevel.Warning)
611                        {
612                            return;
613                        }
614                        break;
615
616                    case 2://Warning
617                        if (args.NotificationLevel == NotificationLevel.Debug ||
618                            args.NotificationLevel == NotificationLevel.Info)
619                        {
620                            return;
621                        }
622                        break;
623
624                    case 1://Info
625                        if (args.NotificationLevel == NotificationLevel.Debug)
626                        {
627                            return;
628                        }
629                        break;
630                }
631                OnGuiLogNotificationOccured(sender, args);
632            }
633               
634        }
635
636        /// <summary>
637        /// Progress of this editor
638        /// </summary>
639        /// <param name="Value"></param>
640        /// <param name="MaxValue"></param>
641        private void Progress(int Value, int MaxValue)
642        {
643            if (OnPluginProgressChanged != null)
644            {
645                OnPluginProgressChanged(this, new PluginProgressEventArgs(Value, MaxValue));
646            }
647        }
648        #endregion GuiLogMessage, Progress
649
650        /// <summary>
651        /// Selected Plugin changed by View
652        /// </summary>
653        /// <param name="args"></param>
654        public void onSelectedPluginChanged(PluginChangedEventArgs args)
655        {
656            this.OnSelectedPluginChanged(this, args);
657        }
658    }
659}
660
661//Restore warnings for unused or unassigned fields and events:
662#pragma warning restore 0169, 0414, 0067
Note: See TracBrowser for help on using the repository browser.