private void ConnectEBC(IEBCBase outputEBC, IEBCBase inputEBC)
        {
            outputEBC.Out_SendMessage += (IEBCMessage ebcMessage) => this.EBCInputData[inputEBC] = ebcMessage;

            if (!this.EBCOutputConnections.ContainsKey(outputEBC))
            {
                Dictionary<IEBCBase, Action<IEBCMessage>> inputEBCsAndMessages = new Dictionary<IEBCBase, Action<IEBCMessage>>();
                inputEBCsAndMessages.Add(inputEBC, (IEBCMessage ebcMessage) => inputEBC.In_ReceiveMessage(ebcMessage));

                this.EBCOutputConnections.Add(outputEBC, inputEBCsAndMessages);
            }
            else
            {
                // If there's already a Connection between those Shapes, cancel the new one.
                if (this.EBCOutputConnections[outputEBC].ContainsKey(inputEBC))
                    throw new ShapeConnectionException("Eine entsprechende Verbindung ist schon vorhanden und kann nicht erneut angelegt werden!");

                this.EBCOutputConnections[outputEBC].Add(inputEBC, (IEBCMessage ebcMessage) => inputEBC.In_ReceiveMessage(ebcMessage));
            }

            try
            {
                // Check for circular connections.
                this.DetectCircularConnections(outputEBC, outputEBC);

                if (!this.EBCInputConnections.ContainsKey(inputEBC))
                {
                    List<IEBCBase> outputEBCs = new List<IEBCBase>();
                    outputEBCs.Add(outputEBC);

                    this.EBCInputConnections.Add(inputEBC, outputEBCs);
                }
                else
                {
                    this.EBCInputConnections[inputEBC].Add(outputEBC);
                }

                outputEBC.Out_SendMessage += this.EBCOutputConnections[outputEBC][inputEBC];
            }
            catch (CircularConnectionException circularConnectionException)
            {
                this.EBCOutputConnections.Remove(outputEBC);

                throw circularConnectionException;
            }
        }
        private void AutoConnectEvents(ConnectDirections connectDirection, IShapeBase shapeBase, IEBCBase ebcBase, EventInfo[] events, MethodInfo[] methods)
        {
            Dictionary<string, MethodInfo> methodInfoToName = new Dictionary<string, MethodInfo>();

            object eventSource = null;
            object firstDelegateArgument = null;

            // Shape to EBC
            if (connectDirection == ConnectDirections.ShapeToEBC)
            {
                eventSource = shapeBase;
                firstDelegateArgument = ebcBase;
            }
            // EBC to Shape
            else if (connectDirection == ConnectDirections.EBCToShape)
            {
                eventSource = ebcBase;
                firstDelegateArgument = shapeBase;
            }

            // Save all methods in a dictionary with it's name as key.
            foreach (var currentMethod in methods)
            {
                if (currentMethod.Name.StartsWith("In_"))
                    methodInfoToName.Add(currentMethod.Name.Replace("In_", ""), currentMethod);
            }

            // Iterate over all found EBC-events and check if there is a matching EBC-handler.
            foreach (var currentEvent in events)
            {
                if (currentEvent.Name.StartsWith("Out_"))
                {
                    string name = currentEvent.Name.Replace("Out_", "");

                    if (methodInfoToName.ContainsKey(name))
                    {
                        // Connect them.
                        currentEvent.AddEventHandler(eventSource,
                                Delegate.CreateDelegate(currentEvent.EventHandlerType, firstDelegateArgument, methodInfoToName[name]));
                    }
                }
            }
        }
        private void ConnectShapeToEBC(IShapeBase shape, IEBCBase ebc)
        {
            Type shapeType = shape.GetType();
            Type ebcType = ebc.GetType();

            // First, events of shapeBase to matching methods of ebcBase.
            EventInfo[] shapeBaseEvents = shapeType.GetEvents();
            MethodInfo[] ebcBaseMethods = ebcType.GetMethods(BindingFlags.Public | BindingFlags.Instance);

            this.AutoConnectEvents(ConnectDirections.ShapeToEBC, shape, ebc, shapeBaseEvents, ebcBaseMethods);

            // Second, events of ebcBase to matching methods of shapeBase.
            EventInfo[] ebcBaseEvent = ebcType.GetEvents();
            MethodInfo[] shapeBaseMethods = shapeType.GetMethods(BindingFlags.Public | BindingFlags.Instance);

            this.AutoConnectEvents(ConnectDirections.EBCToShape, shape, ebc, ebcBaseEvent, shapeBaseMethods);

            // Last, set the EBC-Name to the shape.
            shape.Name = ebc.Name;
        }
 public STEConnectMessage(IShapeBase shape, IEBCBase ebc)
 {
     this.Shape = shape;
     this.EBC = ebc;
 }
 public DisconnectEBCMessage(IEBCBase outputEBC, IEBCBase inputEBC)
 {
     this.OutputEBC = outputEBC;
     this.InputEBC = inputEBC;
 }
 public EBCExecutionTimeData(TimeSpan endTime, long usedMilliseconds, IEBCBase ebcBase)
 {
     this.EndTime = endTime;
     this.UsedMilliseconds = usedMilliseconds;
     this.EBC = ebcBase;
 }
        public void In_DeleteEBC(IEBCBase ebc)
        {
            if (this.EBCOutputConnections.ContainsKey(ebc))
            {
                // Remove all SendMessage events to the target ebcs.
                foreach (var ebcToEBCMessages in this.EBCOutputConnections[ebc])
                {
                    ebc.Out_SendMessage -= ebcToEBCMessages.Value;

                    this.EBCInputConnections.Remove(ebcToEBCMessages.Key);
                }

                this.EBCOutputConnections.Remove(ebc);
            }

            if (this.EBCInputConnections.ContainsKey(ebc))
            {
                foreach (var inputEBC in this.EBCInputConnections[ebc])
                {
                    if (this.EBCOutputConnections.ContainsKey(inputEBC))
                    {
                        bool completeDeletion = true;
                        foreach (var item3 in this.EBCOutputConnections[inputEBC])
                        {
                            if (item3.Key == ebc)
                                inputEBC.Out_SendMessage -= item3.Value;
                            else
                                completeDeletion = false;
                        }

                        if (completeDeletion)
                            this.EBCOutputConnections.Remove(inputEBC);
                    }
                }

                this.EBCInputConnections.Remove(ebc);
            }

            this.EBCInputData.Remove(ebc);
            this.EBCExecutionTimes.Remove(ebc);
        }
 public AddShapeMessage(IShapeBase shape, IEBCBase ebc, Point shapeLocation)
 {
     this.Shape = shape;
     this.EBC = ebc;
     this.ShapeLocation = shapeLocation;
 }
 public void In_EBCAdded(IEBCBase ebc)
 {
     ebc.Out_SendMessage += (IEBCMessage ebcMessage) => this.CalcDateTime(ebc);
     ebc.Out_SendMessage += (IEBCMessage ebcMessage) => this.ProtocolOutputData(ebc, ebcMessage);
     ebc.Out_EBCDebugMessage += (IEBCDebugMessage ebcDebugMessage) => this.ProcotolDebugData(ebcDebugMessage);
     ebc.Out_WorkException += (IEBCExceptionMessage ebcExceptionMessage) => this.Out_EBCWorkExceptionHandled(ebcExceptionMessage);
 }
 private void StartEBCWork(IEBCBase firstEBC)
 {
     if (this.EBCInputData.ContainsKey(firstEBC))
         firstEBC.In_ReceiveMessage(this.EBCInputData[firstEBC]);
     else
         firstEBC.In_ReceiveMessage(null);
 }
 private void DetectCircularConnections(IEBCBase outputEBC, IEBCBase referenceEBC)
 {
     foreach (var ebc in this.EBCOutputConnections[outputEBC].Keys)
     {
         if (ebc == referenceEBC)
         {
             throw new CircularConnectionException("Die aktuelle Verbindung kann aufgrund einer Zirkularität nicht erstellt werden!");
         }
         else if (this.EBCOutputConnections.ContainsKey(ebc))
         {
             this.DetectCircularConnections(ebc, referenceEBC);
         }
     }
 }
        private void DisconnectEBC(IEBCBase outputEBC, IEBCBase inputEBC)
        {
            outputEBC.Out_SendMessage -= this.EBCOutputConnections[outputEBC][inputEBC];

            this.EBCOutputConnections[outputEBC].Remove(inputEBC);

            this.EBCInputConnections.Remove(inputEBC);
        }
 public EBCDebugMessage(IEBCBase ebc, IDebugData debugData)
 {
     this.EBC = ebc;
     this.DebugData = debugData;
 }
 public void In_AddShape(IShapeBase shapeBase, IEBCBase ebcBase, Point shapeLocation)
 {
     this.Out_AddShape(new AddShapeMessage(shapeBase, ebcBase, shapeLocation));
 }
 public EBCOutputData(IEBCBase ebcBase, IEBCMessageData ebcMessageData, EBCOutputDataTypes ebcOutputDataType)
 {
     this.EBC = ebcBase;
     this.EBCMessageData = ebcMessageData;
     this.EBCOutputDataType = ebcOutputDataType;
 }
        private void AddShape(IShapeBase shape, IEBCBase ebc, Point shapeLocation)
        {
            try
            {
                if (!(shape is ConnectionShape))
                {
                    this.Out_STEAutoConnect(new STEConnectMessage(shape, ebc));

                    shape.Out_PinClicked += new Action<IEBCPinClickedMessage>(shapeBase_Out_PinClicked);

                    if (!shapeLocation.IsEmpty)
                        shape.SetInitialPosition(shapeLocation);

                    this.EBCs.Add(ebc);
                    this.ShapeToEBC.Add(shape.ID, ebc);
                    this.EBCtoShape.Add(ebc, shape.ID);

                    shape.Out_StartProcess += () => this.Out_ExecuteFirstEBC(new ExecuteFirstEBCMessage(this.ShapeToEBC[shape.ID])); // this.StartProcessEvents[shape];

                    this.Inner_ChangeShapeStatus += (IChangeShapeStatusMessage changeShapeStatus) => shape.In_ChangeShapeStatus(changeShapeStatus); // this.ChangeShapeStatusEvents[shape];
                }

                Dictionary<string, Action<MouseEventArgs>> mouseEvents = new Dictionary<string, Action<MouseEventArgs>>();

                Action<MouseEventArgs> mouseClickEvent = (MouseEventArgs mouseEventArgs) => shape.In_MouseClick(mouseEventArgs);
                Action<MouseEventArgs> mouseDoubleClickEvent = (MouseEventArgs mouseEventArgs) => shape.In_MouseDoubleClick(mouseEventArgs);
                Action<MouseEventArgs> mouseMoveEvent = (MouseEventArgs mouseEventArgs) => shape.In_MouseMove(mouseEventArgs);
                Action<MouseEventArgs> mouseUpEvent = (MouseEventArgs mouseEventArgs) => shape.In_MouseUp(mouseEventArgs);
                Action<MouseEventArgs> mouseDownEvent = (MouseEventArgs mouseEventArgs) => shape.In_MouseDown(mouseEventArgs);

                mouseEvents.Add("MouseMove", mouseMoveEvent);
                mouseEvents.Add("MouseUp", mouseUpEvent);
                mouseEvents.Add("MouseDown", mouseDownEvent);
                mouseEvents.Add("MouseClick", mouseClickEvent);
                mouseEvents.Add("MouseDoubleClick", mouseDoubleClickEvent);

                this.Out_MouseClick += mouseClickEvent;
                this.Out_MouseMove += mouseMoveEvent;
                this.Out_MouseUp += mouseUpEvent;
                this.Out_MouseDown += mouseDownEvent;
                this.Out_MouseDoubleClick += mouseDoubleClickEvent;

                shape.Out_PaintRequest += () => this.Out_PaintRequest();

                this.MouseEvents.Add(shape, mouseEvents);

                this.ShapeLevels.Insert(0, shape.ID);
                this.Shapes.Add(shape.ID, shape);

                if (!(shape is ConnectionShape))
                {
                    this.Out_EBCAdded(ebc);

                    // use the EBC type for counting.
                    Type ebcType = ebc.GetType();

                    if (this.ShapeTypeCount.ContainsKey(ebcType))
                    {
                        this.ShapeTypeCount[ebcType]++;

                        // Only add the type number, if there is a minimum of two EBCs with this type.
                        shape.Name += " " + this.ShapeTypeCount[ebcType];
                        ebc.Name = shape.Name;
                    }
                    else
                    {
                        this.ShapeTypeCount.Add(ebcType, 1);
                    }
                }
            }
            catch (TargetException targetException)
            {
                this.OnOut_ReportError(new STEAutoConnectionException("Die Automatische Verbindung von Shape und EBC ist fehlgeschlagen!",
                    targetException));
            }
        }
        private void ProtocolOutputData(IEBCBase ebcBase, IEBCMessage ebcMessage)
        {
            // Send the elapsed time to the associated shape.
            ebcBase.ExecutionFinished(new ExecutionTimeMessage(this.EBCExecutionTimes[ebcBase].UsedMilliseconds));

            if (ebcBase.CanProtocolOutputData)
            {
                this.Out_ExecutionFinished(new ExecutionFinishedMessage(this.EBCExecutionTimes[ebcBase],
                    new EBCOutputData(ebcBase, ebcMessage.EBCMessageData, EBCOutputDataTypes.Result)));
            }
            else
            {
                this.Out_ExecutionFinished(new ExecutionFinishedMessage(this.EBCExecutionTimes[ebcBase]));
            }
        }
        private void CalcDateTime(IEBCBase ebcBase)
        {
            this.Stopwatch.Stop();

            if (!this.EBCExecutionTimes.ContainsKey(ebcBase))
            {
                this.EBCExecutionTimes.Add(ebcBase, new EBCExecutionTimeData(DateTime.Now.TimeOfDay, this.Stopwatch.ElapsedMilliseconds, ebcBase));
            }
            else
            {
                this.EBCExecutionTimes[ebcBase] = new EBCExecutionTimeData(DateTime.Now.TimeOfDay, this.Stopwatch.ElapsedMilliseconds, ebcBase);
            }

            this.Stopwatch.Restart();
        }
 public EBCExceptionMessage(IEBCBase ebcBase, IWorkException ebcWorkException)
 {
     this.EBC = ebcBase;
     this.WorkException = ebcWorkException;
 }
 public ExecuteFirstEBCMessage(IEBCBase firstEBC)
 {
     this.EBC = firstEBC;
 }