/// <summary> /// Iterates through RoutingTable list and assigns /// this MmRelayNode as a parent to child MmResponders. /// </summary> public void RefreshParents() { MmLogger.LogFramework("Refreshing parents on MmRelayNode: " + gameObject.name); foreach (var child in RoutingTable.Where(x => x.Level == MmLevelFilter.Child)) { var childNode = child.Responder.GetRelayNode(); childNode.AddParent(this); childNode.RefreshParents(); } //Optimize later foreach (var parent in MmParentList) { //bool foundItem = RoutingTable.Select ((x) => x.Responder).Any (responder => responder == parent); MmRoutingTableItem foundItem = RoutingTable.First(x => x.Responder == parent); if (foundItem == null) { MmAddToRoutingTable(parent, MmLevelFilter.Parent); } else { foundItem.Level = MmLevelFilter.Parent; } } }
protected void OnEnable() { var mxmBehavior = (MmResponder)target; _myRelayNode = mxmBehavior.GetComponent <MmRelayNode>(); if (_myRelayNode == null || _myRelayNode == target) { return; } myListItem = _myRelayNode.MmAddToRoutingTable(mxmBehavior, mxmBehavior.name); }
/// <summary> /// This method determines if a particular MmResponder should /// receive a message via MmInvoke. /// This performs 4 checks: Tag Check, Level Check, Active Check, & Selected Check. /// </summary> /// <param name="levelFilter">Extracted message level filter - before adjust.</param> /// <param name="activeFilter">Extracted message active filter - before adjust.</param> /// <param name="selectedFilter">Extracted message selected filter - before adjust.</param> /// <param name="networkFilter">Extracted message network filter - before adjust.</param> /// <param name="mmRoutingTableItem">RoutingTableItem of currently observed MmResponder</param> /// <param name="message">MmMessage to be checked.</param> /// <returns>Returns whether responder has passed all checks.</returns> protected virtual bool ResponderCheck(MmLevelFilter levelFilter, MmActiveFilter activeFilter, MmSelectedFilter selectedFilter, MmNetworkFilter networkFilter, MmRoutingTableItem mmRoutingTableItem, MmMessage message) { if (!TagCheck(mmRoutingTableItem, message)) { return(false); // Failed TagCheck } return(LevelCheck(levelFilter, mmRoutingTableItem.Responder, mmRoutingTableItem.Level) && ActiveCheck(activeFilter, mmRoutingTableItem.Responder) && SelectedCheck(selectedFilter, mmRoutingTableItem.Responder) && NetworkCheck(mmRoutingTableItem, message)); }
/// <summary> /// Determine if MmResponder passes MmRelayNode tag filter check using value embedded in MmMessage. /// </summary> /// <param name="mmRoutingTableItem">RoutingTableItem of currently observed MmResponder</param> /// <param name="message">MmMessage to be checked.</param> /// <returns>Returns whether observed MmResponder has passed tag check.</returns> protected virtual bool TagCheck(MmRoutingTableItem mmRoutingTableItem, MmMessage message) { //var text = string.Format("Tag Check (GO: {0}, ListItem: {1}, msgType:{2}, msgTag={3}, responderTag={4}", // gameObject.name, // mmRoutingTableItem.Name, // param.MmMethod, // MmTagHelper.ToString(param.MetadataBlock.Tag), // MmTagHelper.ToString(mmRoutingTableItem.Tags)); // Responder's TagCheck toggle is not enabled, this passes if (!mmRoutingTableItem.Responder.TagCheckEnabled) { //Debug.Log(text + ") Passed -- TagCheckEnabled: FALSE"); return(true); } var msgTag = message.MetadataBlock.Tag; // This is "Everything" by default, will by-pass Tag-Check var responderTag = mmRoutingTableItem.Tags; // This is "Nothing" by default, if a message *has* a specific tag, // i.e. something other than "Everything", it won't pass // unless it has that tag's flag set to 1 // This message applies to everyone, this passes if (msgTag == MmTagHelper.Everything) { //Debug.Log(text + ") Passed -- msgTag = Everything"); return(true); } // This message has a tag, other than "Everything", but it matches responder's tag, so it passes if ((msgTag & responderTag) > 0) { //Debug.Log(text + ") Passed -- tag match"); return(true); } // This message has a tag, other than "Everything", and it doesn't match responder's tag, so it fails //Debug.Log(text + ") FAILED"); return(false); }
/// <summary> /// Checks if a responder should recieve a message based on /// the network flag in a control block. /// Network messages can go to other nodes, but not to self responders. /// </summary> /// <param name="mmRoutingTableItem">Observed MmResponder</param> /// <param name="message">Input message.</param> /// <returns></returns> protected virtual bool NetworkCheck(MmRoutingTableItem mmRoutingTableItem, MmMessage message) { //Need to check if the message is executing locally on a host (server + client). //If this occurs, two instances of a message will be seen in this node: // 1. The message originally passed in, that has just been sent over the network // 2. The message handled by the network and received by the client instance. //The first instance of a message should not execute locally. Instead, only the second instance // should. The Node needs to know if this is executing locally as a host, and if the // message has been deserialized (indicating receipt by the client instance). if ((mmRoutingTableItem.Level == MmLevelFilter.Self && message.MetadataBlock.NetworkFilter == MmNetworkFilter.Network && !message.IsDeserialized) || (message.MetadataBlock.NetworkFilter != MmNetworkFilter.Local && MmNetworkResponder != null && MmNetworkResponder.OnClient && MmNetworkResponder.OnServer && !message.IsDeserialized)) { return(false); } return(true); }
/// <summary> /// Add an MmResponder to the MmRoutingTable, with level designation. /// </summary> /// <param name="mmResponder">MmResponder to be added.</param> /// <param name="level">Level designation of responder.</param> /// <returns>Reference to new MmRoutingTable item.</returns> public virtual MmRoutingTableItem MmAddToRoutingTable(MmResponder mmResponder, MmLevelFilter level) { var routingTableItem = new MmRoutingTableItem(mmResponder.name, mmResponder) { Level = level }; if (RoutingTable.Contains(mmResponder)) { return(null); // Already in list } //If there is an MmInvoke executing, add it to the // MmRespondersToAdd queue. if (doNotModifyRoutingTable) { MmRespondersToAdd.Enqueue(routingTableItem); } else { RoutingTable.Add(routingTableItem); } return(routingTableItem); }