/// <summary>
 /// Deserialize the MmMetadataBlock
 /// </summary>
 /// <param name="reader">UNET based deserializer object</param>
 public virtual void Deserialize(NetworkReader reader)
 {
     LevelFilter    = (MmLevelFilter)reader.ReadInt16();
     ActiveFilter   = (MmActiveFilter)reader.ReadInt16();
     SelectedFilter = (MmSelectedFilter)reader.ReadInt16();
     NetworkFilter  = (MmNetworkFilter)reader.ReadInt16();
     Tag            = (MmTag)reader.ReadInt16();
 }
 /// <summary>
 /// Copy Constructor for MmMetadataBlock
 /// </summary>
 /// <param name="original">MmMetadataBlock to be copied.</param>
 public MmMetadataBlock(MmMetadataBlock original)
 {
     LevelFilter    = original.LevelFilter;
     ActiveFilter   = original.ActiveFilter;
     SelectedFilter = original.SelectedFilter;
     NetworkFilter  = original.NetworkFilter;
     Tag            = original.Tag;
 }
Exemplo n.º 3
0
 /// <summary>
 /// Deserialize the MmMetadataBlock
 /// </summary>
 /// <param name="data">Object array representation of a MmMetadataBlock</param>
 /// <param name="index">The index of the next element to be read from data</param>
 /// <returns>The index of the next element to be read from data</returns>
 public virtual int Deserialize(object[] data, int index)
 {
     LevelFilter    = (MercuryMessaging.MmLevelFilter)((short)data[index++]);
     ActiveFilter   = (MercuryMessaging.MmActiveFilter)((short)data[index++]);
     SelectedFilter = (MercuryMessaging.MmSelectedFilter)((short)data[index++]);
     NetworkFilter  = (MercuryMessaging.MmNetworkFilter)((short)data[index++]);
     Tag            = (MercuryMessaging.MmTag)((short)data[index++]);
     return(index);
 }
 /// <summary>
 /// Create an MmMetadataBlock
 /// </summary>
 /// <param name="tag"></param>
 /// <param name="levelFilter"><see cref="MmLevelFilter"/></param>
 /// <param name="activeFilter"><see cref="MmActiveFilter"/></param>
 /// <param name="selectedFilter"><see cref="MmSelectedFilter"/></param>
 /// <param name="networkFilter"><see cref="MmNetworkFilter"/></param>
 public MmMetadataBlock(MmTag tag,
                        MmLevelFilter levelFilter       = MmLevelFilterHelper.Default,
                        MmActiveFilter activeFilter     = default(MmActiveFilter),
                        MmSelectedFilter selectedFilter = default(MmSelectedFilter),
                        MmNetworkFilter networkFilter   = default(MmNetworkFilter))
 {
     LevelFilter    = levelFilter;
     ActiveFilter   = activeFilter;
     SelectedFilter = selectedFilter;
     NetworkFilter  = networkFilter;
     Tag            = tag;
 }
 /// <summary>
 /// Create an MmMetadataBlock
 /// </summary>
 /// <param name="levelFilter"><see cref="MmLevelFilter"/></param>
 /// <param name="activeFilter"><see cref="MmActiveFilter"/></param>
 /// <param name="selectedFilter"><see cref="MmSelectedFilter"/></param>
 /// <param name="networkFilter"><see cref="MmNetworkFilter"/></param>
 public MmMetadataBlock(
     MmLevelFilter levelFilter       = MmLevelFilterHelper.Default,
     MmActiveFilter activeFilter     = MmActiveFilter.Active,
     MmSelectedFilter selectedFilter = MmSelectedFilter.All,
     MmNetworkFilter networkFilter   = MmNetworkFilter.All)
 {
     LevelFilter    = levelFilter;
     ActiveFilter   = activeFilter;
     SelectedFilter = selectedFilter;
     NetworkFilter  = networkFilter;
     Tag            = MmTagHelper.Everything;
 }
Exemplo n.º 6
0
 /// <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));
 }
Exemplo n.º 7
0
        /// <summary>
        /// Create an MmMessage, with filters defined directly
        /// </summary>
        /// <param name="mmMethod">Identifier of target MmMethod</param>
        /// <param name="levelFilter">Determines direction of messages</param>
        /// <param name="activeFilter">Determines whether message sent to active and/or inactive objects</param>
        /// <param name="selectedFilter">Determines whether message sent to objects "selected" as defined by MmRelayNode implementation</param>
        /// <param name="networkFilter">Determines whether message will remain local or can be sent over the network</param>
        public MmMessage(MmMethod mmMethod,
                         MmLevelFilter levelFilter,
                         MmActiveFilter activeFilter,
                         MmSelectedFilter selectedFilter,
                         MmNetworkFilter networkFilter)
        {
            MmMethod = mmMethod;

            MetadataBlock                = new MmMetadataBlock();
            MetadataBlock.LevelFilter    = levelFilter;
            MetadataBlock.ActiveFilter   = activeFilter;
            MetadataBlock.SelectedFilter = selectedFilter;
            MetadataBlock.NetworkFilter  = networkFilter;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Override the basic functionality of MmRelayNode to allow for faster processing by skipping checks.
        /// </summary>
        /// <param name="msgType">Type of message. This specifies
        /// the type of the payload. This is important in
        /// networked scenarios, when proper deseriaization into
        /// the correct type requires knowing what was
        /// used to serialize the object originally.</param>
        /// <param name="message">The message to send.
        /// This class builds on UNET's MessageBase so it is
        /// Auto [de]serialized by UNET.</param>
        public override void MmInvoke(MmMessage message)
        {
            if (AllowStandardMmInvoke)
            {
                base.MmInvoke(message);
            }
            else
            {
                //If the MmRelayNode has not been initialized, initialize it here,
                //  and refresh the parents - to ensure proper routing can occur.
                InitializeNode();

                MmNetworkFilter networkFilter = message.MetadataBlock.NetworkFilter;

                if (MmNetworkResponder != null &&
                    message.MetadataBlock.NetworkFilter != MmNetworkFilter.Local &&
                    !message.IsDeserialized)
                {
                    MmNetworkFilter originalNetworkFilter = NetworkFilterAdjust(ref message);
                    MmNetworkResponder.MmInvoke(message);
                    message.MetadataBlock.NetworkFilter = originalNetworkFilter;
                }

                if (!AllowNetworkPropagationLocally && !message.IsDeserialized &&
                    message.MetadataBlock.NetworkFilter == MmNetworkFilter.Network)
                {
                    return;
                }

                foreach (var routingTableItem in RoutingTable)
                {
                    var responder = routingTableItem.Responder;

                    //bool isLocalResponder = responder.MmGameObject == this.gameObject;
                    MmLevelFilter responderLevel = routingTableItem.Level;

                    responder.MmInvoke(message);
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Checks the provided MmRoutingTableItem to see
        /// whether it passes the list filter requirements.
        /// </summary>
        /// <param name="item">Observed MmRoutingTableItem.</param>
        /// <param name="listFilter">ListFilter <see cref="ListFilter"/></param>
        /// <param name="levelFilter">LevelFilter <see cref="MmLevelFilter"/></param>
        /// <returns>Whether MmRoutingTableItem passes filter check.</returns>
        public bool CheckFilter(MmRoutingTableItem item,
                                ListFilter listFilter, MmLevelFilter levelFilter)
        {
            //Level Check
            if ((levelFilter & item.Level) == 0)
            {
                return(false);
            }

            //List Filter check
            if (listFilter == ListFilter.RelayNodeOnly && !(item.Responder is MmRelayNode))
            {
                return(false);
            }
            if (listFilter == ListFilter.ResponderOnly && item.Responder is MmRelayNode)
            {
                return(false);
            }

            //All conditions passed, return true
            return(true);
        }
Exemplo n.º 10
0
 /// <summary>
 /// Get a list of the names all MmRoutingTableItems that
 /// match the provided filters.
 /// </summary>
 /// <param name="filter">ListFilter <see cref="ListFilter"/></param>
 /// <param name="levelFilter">LevelFilter <see cref="MmLevelFilter"/></param>
 /// <returns>List of names of MmRoutingTableItems that pass filter checks.</returns>
 public List <string> GetMmNames(ListFilter filter         = default(ListFilter),
                                 MmLevelFilter levelFilter = MmLevelFilterHelper.Default)
 {
     return(GetMmRoutingTableItems(filter, levelFilter).
            Select(x => x.Name).ToList());
 }
Exemplo n.º 11
0
 /// <summary>
 /// Get a list of all MmRoutingTableItems that
 /// match the provided filters.
 /// </summary>
 /// <param name="filter">ListFilter <see cref="ListFilter"/></param>
 /// <param name="levelFilter">LevelFilter <see cref="MmLevelFilter"/></param>
 /// <returns>List of MmRoutingTableItems that pass filter checks.</returns>
 public List <MmRoutingTableItem> GetMmRoutingTableItems(
     ListFilter filter         = default(ListFilter),
     MmLevelFilter levelFilter = MmLevelFilterHelper.Default)
 {
     return(this.Where(x => CheckFilter(x, filter, levelFilter)).ToList());
 }
        /// <summary>
        /// Draw method for MmBehaviorListItemDrawer.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="property"></param>
        /// <param name="label"></param>
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            int oldIndentLevel = EditorGUI.indentLevel;

            EditorGUI.indentLevel = 0;

            label = EditorGUI.BeginProperty(position, label, property);

            Rect contentPosition = EditorGUI.PrefixLabel(position, label);

            /*
             * if (position.height > 16f) {
             *      position.height = 16f;
             *      EditorGUI.indentLevel += 1;
             *      contentPosition = EditorGUI.IndentedRect(position);
             *      contentPosition.y += 18f;
             * }
             */

            var originalWidth  = contentPosition.width;
            var remainingWidth = originalWidth;

            /*---------------------------*/
            contentPosition.width = (originalWidth - (FieldWidthClone + FieldWidthLevel + FieldWidthTags)) / 2f;

            SerializedProperty behaviorProperty = property.FindPropertyRelative("Responder");

            var level        = property.FindPropertyRelative("Level");
            var listItemName = property.FindPropertyRelative("Name");

            EditorGUI.BeginChangeCheck();

            EditorGUI.PropertyField(
                contentPosition,
                behaviorProperty,
                GUIContent.none);

            if (EditorGUI.EndChangeCheck())
            {
                MmResponder responderObj = behaviorProperty.objectReferenceValue as System.Object as MmResponder;

                if (responderObj != null)
                {
                    MonoBehaviour containerObj = property.serializedObject.targetObject as MonoBehaviour;

                    //Get Name & Tag from the assigned object and apply it as the name of the object.
                    listItemName.stringValue = responderObj.gameObject.name;

                    //Get the reference of the list owner's WFNode for comparison.
                    //Then, assign the level based on whether this is the same object, or a different one.
                    MmLevelFilter levelFilterValue = MmLevelFilter.Self;

                    if (responderObj.gameObject == containerObj.gameObject)
                    {
                        levelFilterValue = MmLevelFilter.Self;
                    }
                    else
                    {
                        levelFilterValue = MmLevelFilter.Child;
                    }

                    level.enumValueIndex = Array.IndexOf(Enum.GetValues(typeof(MmLevelFilter)), levelFilterValue);
                }
            }

            remainingWidth    -= contentPosition.width;
            contentPosition.x += contentPosition.width;
            /*---------------------------*/
            contentPosition.width = (originalWidth - (FieldWidthClone + FieldWidthLevel + FieldWidthTags)) / 2f;           // (Same as above)

            EditorGUI.PropertyField(
                contentPosition,
                listItemName,
                GUIContent.none);

            remainingWidth    -= contentPosition.width;
            contentPosition.x += contentPosition.width;
            /*---------------------------*/
            contentPosition.width = FieldWidthLevel;

            //Level

            EditorGUI.LabelField(
                contentPosition,
                new GUIContent(level.enumValueIndex != -1 ? level.enumNames[level.enumValueIndex] : "None"),
                EditorStyles.label);

            remainingWidth    -= contentPosition.width;
            contentPosition.x += contentPosition.width;
            /*---------------------------*/
            contentPosition.width = FieldWidthClone;

            EditorGUI.PropertyField(
                contentPosition,
                property.FindPropertyRelative("Clone"),
                GUIContent.none);

            remainingWidth    -= contentPosition.width;
            contentPosition.x += contentPosition.width;
            /*---------------------------*/

            contentPosition.width = FieldWidthTags;

            EditorGUI.PropertyField(
                contentPosition,
                property.FindPropertyRelative("Tags"),
                GUIContent.none);

            remainingWidth    -= contentPosition.width;
            contentPosition.x += contentPosition.width;

            EditorGUI.EndProperty();

            EditorGUI.indentLevel = oldIndentLevel;
        }
Exemplo n.º 13
0
 /// <summary>
 /// Determine if MmResponder passes MmRelayNode level filter check using value embedded in MmMessage.
 /// </summary>
 /// <param name="levelFilter">Level filter value extracted from MmMessage.</param>
 /// <param name="responder">Observed MmResponder.</param>
 /// <param name="responderLevel">Observed MmResponder Level.</param>
 /// <returns>Returns whether observed MmResponder has passed level filter check.</returns>
 protected virtual bool LevelCheck(MmLevelFilter levelFilter,
                                   IMmResponder responder, MmLevelFilter responderLevel)
 {
     return((levelFilter & responderLevel) > 0);
 }
Exemplo n.º 14
0
 /// <summary>
 /// If the level filter is designated 'Child', then it is recorded locally,
 /// but converted to a 'Child+Self' for use by the RoutingTable
 /// (which need to pass the message on to all children, but still need to be able
 /// to execute the message on their own responders, otherwise, it just goes
 /// to the terminal points of the graph without ever executing).
 /// </summary>
 /// <param name="message">MmMessage to be adjusted.</param>
 /// <param name="direction">Intended direction of message</param>
 /// <returns>Base implementation returns messages's level filter.</returns>
 protected virtual MmLevelFilter LevelFilterAdjust(ref MmMessage message,
                                                   MmLevelFilter direction)
 {
     return(message.MetadataBlock.LevelFilter);
 }
Exemplo n.º 15
0
        /// <summary>
        /// Invoke an MmMethod.
        /// </summary>
        /// <param name="msgType">Type of message. This specifies
        /// the type of the payload. This is important in
        /// networked scenarios, when proper deseriaization into
        /// the correct type requires knowing what was
        /// used to serialize the object originally.
        /// </param>
        /// <param name="message">The message to send.
        /// This class builds on UNET's MessageBase so it is
        /// Auto [de]serialized by UNET.</param>
        public override void MmInvoke(MmMessageType msgType, MmMessage message)
        {
            //If the MmRelayNode has not been initialized, initialize it here,
            //  and refresh the parents - to ensure proper routing can occur.
            InitializeNode();

            //TODO: Switch to using mutex for threaded applications
            doNotModifyRoutingTable = true;
            MmNetworkFilter networkFilter = message.MetadataBlock.NetworkFilter;

            //Experimental: Allow forced serial execution (ordered) of messages.
            //if (serialExecution)
            //{
            //    if (!_executing)
            //    {
            //        _executing = true;
            //    }
            //    else
            //    {
            //        MmLogger.LogFramework("<<<<<>>>>>Queueing<<<<<>>>>>");
            //        KeyValuePair<MmMessageType, MmMessage> newMessage =
            //            new KeyValuePair<MmMessageType, MmMessage>(msgType, message);
            //        SerialExecutionQueue.Enqueue(newMessage);
            //        return;
            //    }
            //}

            //MmLogger.LogFramework (gameObject.name + ": MmRelayNode received MmMethod call: " + param.MmMethod.ToString ());

            //	If an MmNetworkResponder is attached to this object, and the MmMessage has not already been deserialized
            //	then call the MmNetworkResponder's network message invocation function.
            if (MmNetworkResponder != null &&
                message.MetadataBlock.NetworkFilter != MmNetworkFilter.Local &&
                !message.IsDeserialized)
            {
                //if (!dirty)
                //{
                //    dirty = true;
                //    message.TimeStamp = DateTime.UtcNow.ToShortTimeString();
                //    _prevMessageTime = message.TimeStamp;
                //}

                //This will ensure that beyond the point at which a message is determined to be sendable,
                //  it will not be treated as networ
                networkFilter = NetworkFilterAdjust(ref message);

                MmNetworkResponder.MmInvoke(msgType, message);
            }


            //Todo: it's possible to get this to happen only once per graph. Switch Invoke code to support.
            var upwardMessage = message.Copy();

            upwardMessage.MetadataBlock.LevelFilter = MmLevelFilterHelper.SelfAndParents;
            var downwardMessage = message.Copy();

            downwardMessage.MetadataBlock.LevelFilter = MmLevelFilterHelper.SelfAndChildren;

            MmLevelFilter    levelFilter    = message.MetadataBlock.LevelFilter;
            MmActiveFilter   activeFilter   = ActiveFilterAdjust(ref message);
            MmSelectedFilter selectedFilter = SelectedFilterAdjust(ref message);

            //If this message was a network-only message and
            //  this node does not allow for propagation of network messages,
            //  then return.
            if (!AllowNetworkPropagationLocally && !message.IsDeserialized &&
                message.MetadataBlock.NetworkFilter == MmNetworkFilter.Network)
            {
                return;
            }

            foreach (var routingTableItem in RoutingTable)
            {
                var responder = routingTableItem.Responder;

                //bool isLocalResponder = responder.MmGameObject == this.gameObject;
                MmLevelFilter responderLevel = routingTableItem.Level;

                //Check individual responder level and then call the right param.
                MmMessage responderSpecificMessage;
                if ((responderLevel & MmLevelFilter.Parent) > 0)
                {
                    responderSpecificMessage = upwardMessage;
                }
                else if ((responderLevel & MmLevelFilter.Child) > 0)
                {
                    responderSpecificMessage = downwardMessage;
                }
                else
                {
                    responderSpecificMessage = message;
                }

                //MmLogger.LogFramework (gameObject.name + "observing " + responder.MmGameObject.name);

                if (ResponderCheck(levelFilter, activeFilter, selectedFilter, networkFilter,
                                   routingTableItem, responderSpecificMessage))
                {
                    responder.MmInvoke(msgType, responderSpecificMessage);
                }
            }

            //if (dirty && _prevMessageTime == message.TimeStamp)
            //{
            //    dirty = false;
            //}

            doNotModifyRoutingTable = false;

            while (MmRespondersToAdd.Any())
            {
                var routingTableItem = MmRespondersToAdd.Dequeue();

                MmAddToRoutingTable(routingTableItem.Responder, routingTableItem.Level);

                if (ResponderCheck(levelFilter, activeFilter, selectedFilter, networkFilter,
                                   routingTableItem, message))
                {
                    routingTableItem.Responder.MmInvoke(msgType, message);
                }
            }

            //if (serialExecution)
            //{
            //    if (SerialExecutionQueue.Count != 0)
            //    {
            //        MmLogger.LogFramework("%%%%%%%%%%%Dequeueing%%%%%%%%%");
            //        KeyValuePair<MmMessageType, MmMessage> DequeuedMessage = SerialExecutionQueue.Dequeue();
            //        MmInvoke(DequeuedMessage.Key, DequeuedMessage.Value);
            //    }

            //    _executing = false;
            //}
        }
Exemplo n.º 16
0
        /// <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);
        }