//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn private bool IsTrue(EventTriggerType trigger, BaseMessage message) /// /// \brief Query if 'trigger' is true. /// /// \par Description. /// - Check other triggers type (not the Initialize trigger) /// /// \par Algorithm. /// - Get the MessageType of the message and the round of the message /// - Calculate the other end of the message according to the trigger /// - For Send events the other end is the target of the message /// - For Receive events the other end is the source of the message /// - Check if all the parameters retrieved from the message are equal to the /// EventTrigger members /// /// \par Usage Notes. /// /// \author Ilanh /// \date 09/05/2018 /// /// \param trigger (EventTriggerType) - The trigger. /// \param message (BaseMessage) - The message. /// /// \return True if true, false if not. //////////////////////////////////////////////////////////////////////////////////////////////////// private bool IsTrue(EventTriggerType trigger, BaseMessage message) { // Get the data of the message that caused the event int messageRound = message.GetHeaderField(bm.pak.Round); dynamic messageType = message.GetHeaderField(bm.pak.MessageType); // Get the other end of the message that caused the event: // For a sending event this is the destination of the message // For a receive event this is the source of the message int messageOtherEnd; if (trigger == EventTriggerType.AfterSendMessage || trigger == EventTriggerType.BeforeSendMessage) { messageOtherEnd = message.GetHeaderField(bm.pak.DestProcess); } else { messageOtherEnd = message.GetHeaderField(bm.pak.SourceProcess); } if (this[Comps.Trigger] == trigger && this[Comps.Round] == messageRound && TypesUtility.CompareDynamics(this[Comps.MessageType], messageType) && this[Comps.OtherEnd] == messageOtherEnd) { return(true); } return(false); }
/* * ReceiveHandling * This method is responssible to devide the data received to packets and call * the ReceiveHandling method of the process * Note that there no connection from the way the data is sent to the way it is * Received. That meens that a several packets can be received in one Receive and * There is no garentee that the last packet in the data will end. * The packets (messages) are send with '#' termination flag * The received data is collected in state.buffer * Then it is copied to state.sb . The role of this variable is to hold all the * data that was not processed * Then it converted to string * Then it is devided to packets * Then each packet except the last packet is handled * Then the last packet is checked : * If the data received ends with '#' - do nothing because that meens that the last * packet is empty * else clear the state.data and fill it with the unterminated last packet to be joined * by the next receive data * The following is the handling of a complete packet * 1. Generate a message object from the message data * 2. If the MessageType attribute of the message is "Terminate" set the termnateFlag and return * 3. wait untill the ReceiveHandling method of the process is not locked by another * AsynchronousReader object * 4. Activate the ReceiveHandling method of the process with the data. */ /**********************************************************************************************//** * Receive handling. * * \author Ilan Hindy * \date 29/09/2016 * * \param bytesReceived The bytes received. * **************************************************************************************************/ public void ReceiveHandling(int bytesReceived) { String content = String.Empty; // There might be more data, so store the data received so far. state.sb.Append(Encoding.ASCII.GetString( state.buffer, 0, bytesReceived)); //Convert the data to string content = state.sb.ToString(); // Get the process BaseProcess process = state.process; //If any end of packets was received if (content.IndexOf("#") > -1) { //Devide the data to packets string[] packets = Regex.Split(content, "#"); //Packet handling for (int idx = 0; idx < packets.Length - 1; idx++) { //Create message from the packet //BaseMessage message = new BaseMessage(packets[idx]); string processName = "Process_" + process.ea[ne.eak.Id].ToString(); Logger.Log(Logger.LogMode.MainLogAndProcessLog, processName, "Receive", "Received message - packets[idx]", packets[idx], "ProcessReceive"); BaseMessage message = BaseMessage.CreateMessage(process.Network, packets[idx]); if (TypesUtility.CompareDynamics(message.GetHeaderField(bm.pak.MessageType), bm.MessageTypes.Terminate)) { terminateFlag = true; } process.MessageQHandling(ref message, MessageQOperation.AddMessage); MessageRouter.ReportMessageReceive(process, new object[] { message }); //Logger.Log(Logger.LogMode.MainLogAndProcessLog, process.ToString(), "Receive", "Received message", message); } //If there is a unfinished packet if (content[content.Length - 1] != '#') { //This is the last packet received and it is fregmented with the next package state.sb.Clear(); state.sb.Append(packets[packets.Length - 1]); } else { state.sb.Clear(); } } }
private void InitialExpand() { ItemsControl item = controlsAttributeLinks.Values.First(l => TypesUtility.CompareDynamics(l.key, NetworkElement.ElementDictionaries.PrivateAttributes)).item; ((TreeViewItem)item).IsExpanded = true; }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn public static void Button_SelectSelectedAlgorithmDebugFile_Click(object sender, RoutedEventArgs e) /// /// \brief Event handler. Called by Button_SelectSelectedAlgorithmDebugFile for click events. /// /// \par Description. /// /// \par Algorithm. /// /// \par Usage Notes. /// /// \author Ilanh /// \date 14/11/2017 /// /// \param sender (object) - Source of the event. /// \param e (RoutedEventArgs) - Routed event information. //////////////////////////////////////////////////////////////////////////////////////////////////// public static void Button_SelectSelectedAlgorithmDebugFile_Click(object sender, RoutedEventArgs e) { // Get the config and config window ConfigWindow configWindow = (ConfigWindow)GetWindow((Button)sender); Config config = (Config)configWindow.networkElements[0]; // Get the data file name and path from the buttons Button debugfileNameButton = (Button)configWindow.controlsAttributeLinks.Values.First(link => TypesUtility.CompareDynamics(link.key, Config.Keys.SelectedDebugFileName)).newValueControl; string selectedAlgorithmDebugFileName = (string)debugfileNameButton.Content; Button debugfilePathButton = (Button)configWindow.controlsAttributeLinks.Values.First(link => TypesUtility.CompareDynamics(link.key, Config.Keys.SelectedDebugPath)).newValueControl; string selectedAlgorithmDebugPath = (string)debugfilePathButton.Content; // Get the subject and the algorithm names ComboBox subjectComboBox = (ComboBox)configWindow.controlsAttributeLinks.Values.First(link => TypesUtility.CompareDynamics(link.key, Config.Keys.SelectedSubject)).newValueControl; string subjectName = (string)subjectComboBox.SelectedItem; ComboBox algorithmComboBox = (ComboBox)configWindow.controlsAttributeLinks.Values.First(link => TypesUtility.CompareDynamics(link.key, Config.Keys.SelectedAlgorithm)).newValueControl; string algorithmName = (string)algorithmComboBox.SelectedItem; // Select the file if (FileUtilities.SelectInputFile("debug", ref selectedAlgorithmDebugFileName, ref selectedAlgorithmDebugPath)) { // Update the buttons configWindow.UpdateNewValueChanged(debugfileNameButton, selectedAlgorithmDebugFileName); debugfileNameButton.Content = selectedAlgorithmDebugFileName; configWindow.UpdateNewValueChanged(debugfilePathButton, selectedAlgorithmDebugPath); debugfilePathButton.Content = selectedAlgorithmDebugPath; configWindow.selectionChanged = true; } }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn public static bool CheckIfBelongsToBaseAlgorithmEnum(this IValueHolder valueHolder, NetworkElement networkElement, NetworkElement.ElementDictionaries mainDictionary) /// /// \brief An IValueHolder extension method that determine if belongs to base algorithm enum. /// /// \par Description. /// /// \par Algorithm. /// /// \par Usage Notes. /// /// \author Ilanh /// \date 29/10/2017 /// /// \param valueHolder The valueHolder to act on. /// \param networkElement (NetworkElement) - The network element. /// \param mainDictionary (ElementDictionaries) - Dictionary of mains. /// /// \return True if the value holder belongs to the base network element. //////////////////////////////////////////////////////////////////////////////////////////////////// public static bool BelongsToBaseAlgorithmEnum(this IValueHolder valueHolder, NetworkElement networkElement, NetworkElement.ElementDictionaries mainDictionary) { // If the value holder is not attribute get the attribute of the value holder Attribute attribute; if (!(valueHolder is Attribute)) { attribute = (Attribute)valueHolder.Parent; } else { attribute = (Attribute)valueHolder; } // The condition is that the attribute which is the ancestor of our attribute // which is in the main dictionary belongs to the base class // Find the ancestor. // The parent sequence is ending in the following way // null <- networkElement <- Attribute <- mainDictionary <- Attribute // We have to find the last element in the chain described below // We do it with a loop that advances 2 parameters: The attribute and the chain end // The chain end is 4 times the parent of the attribute // Get the first chain end (If we cannot end the chain that means that the valueHolder is // one of the value holders at the middle of the chain hence they are not attributes in the // base classes main dictionary IValueHolder chainEnd = attribute; for (int idx = 0; idx < 4; idx++) { chainEnd = chainEnd.Parent; if (chainEnd == null && idx != 3) { return(false); } } // Find the ancestor while (chainEnd != null) { chainEnd = chainEnd.Parent.Parent; attribute = (Attribute)attribute.Parent.Parent; } // Decide if the attribute is part of the main dictionary if (!((AttributeDictionary)networkElement[mainDictionary]).Values.Any(a => a == attribute)) { return(false); } // Get the key of the attribute dynamic key = attribute.Parent.GetChildKey(attribute); if (TypesUtility.CompareDynamics(key, bn.ork.SingleStepStatus)) { int x = 1; } // Get the base NetworkElement Type baseNetworkElementType = networkElement.GetType().BaseType; NetworkElement baseNetworkElement = (NetworkElement)TypesUtility.CreateObjectFromTypeString(baseNetworkElementType.ToString()); baseNetworkElement.Init(0); // Check if the key is found in the base network element's dictionary return(((AttributeDictionary)baseNetworkElement[mainDictionary]).Keys.Any(k => TypesUtility.CompareDynamics(k, key))); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn private void MergeDictionaries(Attribute existAttribute, Attribute newAttribute) /// /// \brief Merge dictionaries. /// /// \par Description. /// - Clever merge between the existing and new dictionaries /// - If the attribute is found in the existing and the new /// - Copy the value from the existing to the new only if the value of the attribute was changed during network build /// - If the attribute is found in the existing and not the new /// - Add the attribute tree to the new /// - If (Default case - automatically happens) The attribute exists in the new and not the old /// - keep it in the new /// - The attributes are identified using the keys /// /// \par Algorithm. /// /// \par Usage Notes. /// /// \author Ilanh /// \date 28/12/2017 /// /// \param existAttribute (Attribute) - The exist attribute. /// \param newAttribute (Attribute) - The new attribute. //////////////////////////////////////////////////////////////////////////////////////////////////// private void MergeDictionaries(Attribute existAttribute, Attribute newAttribute) { foreach (var existEntry in existAttribute.Value) { Attribute newAttr = ((AttributeDictionary)newAttribute.Value).FirstOrDefault(e => TypesUtility.CompareDynamics(e.Key, existEntry.Key)).Value; string s = " ** " + TypesUtility.GetKeyToString(existEntry.Key) + " **"; if (newAttr == null) { s += "Attribute null"; } else { s += "Attribute value = " + newAttr.Value.ToString(); } MessageRouter.ReportMessage("Attribute Dictionary Merge ", "", s); if (newAttr is null) { newAttr = new Attribute(); ((AttributeDictionary)newAttribute.Value).Add(existEntry.Key, newAttr); newAttr.DeepCopy(existEntry.Value); } else { if (existEntry.Value.Changed) { if (Attribute.GetValueCategory(existEntry.Value) == Attribute.AttributeCategory.PrimitiveAttribute) { newAttr.Value = existEntry.Value.Value; } } } } foreach (var newEntry in newAttribute.Value) { if (!existAttribute.Value.ContainsKey(newEntry.Key)) { Attribute attr = new Attribute(); attr.DeepCopy(newEntry.Value); existAttribute.Value.Add(newEntry.Key, attr); } } }