/// <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;
 }
Пример #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;
 }
Пример #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));
 }
Пример #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;
        }
Пример #8
0
 /// <summary>
 /// Overrides MmRelayNode's Selected check to handle the FSM's current state.
 /// </summary>
 /// <param name="selectedFilter"><see cref="SelectedCheck"/></param>
 /// <param name="responder">Observed MmResponder.</param>
 /// <returns></returns>
 protected override bool SelectedCheck(MmSelectedFilter selectedFilter, IMmResponder responder)
 {
     return(selectedFilter == MmSelectedFilter.All ||
            (RespondersFSM.Current != null &&
             responder.MmGameObject == RespondersFSM.Current.Responder.MmGameObject));
 }
Пример #9
0
 /// <summary>
 /// Determine if MmResponder passes MmRelayNode selected filter check using value embedded in MmMessage.
 /// </summary>
 /// <param name="selectedFilter">Selected filter value extracted from MmMessage.</param>
 /// <param name="responder">Observed MmResponder</param>
 /// <returns>Returns whether observed MmResponder has passed selected filter check.
 /// In base MmRelayNode, this always returns true.</returns>
 protected virtual bool SelectedCheck(MmSelectedFilter selectedFilter,
                                      IMmResponder responder)
 {
     return(true);
 }
Пример #10
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;
            //}
        }