/// Invoke a general MmMethod with parameter: MmMessage. /// </summary> /// <param name="mmMethod">MmMethod Identifier - <see cref="MmMethod"/></param> /// <param name="param">MmMethod parameter: MmMessage. <see cref="MmMessage"/> </param> /// <param name="metadataBlock">Object defining the routing of /// Mmessages through MercuryMessaging Hierarchies. <see cref="MmMetadataBlock"/></param> public virtual void MmInvoke(MmMethod mmMethod, MmMessage param, MmMessageType msgType, MmMetadataBlock metadataBlock = null) { MmMessage msg = param.Copy(); msg.MmMethod = mmMethod; msg.MetadataBlock = metadataBlock; MmInvoke(msg); }
/// <summary> /// Deserialize the MmMessage /// </summary> /// <param name="data">Object array representation of a MmMessage</param> /// <returns>The index of the next element to be read from data</returns> public virtual int Deserialize(object[] data) { int index = 0; MmMethod = (MercuryMessaging.MmMethod)((short)data[index++]); MmMessageType = (MercuryMessaging.MmMessageType)(short) data[index++]; NetId = (uint)((int)data[index++]); index = MetadataBlock.Deserialize(data, index); IsDeserialized = true; return(index); }
/// <summary> /// Overrides the base MmInvoke /// Here we just stop the stopwatch. But we could throw in a switch (to represent normal usage) too. /// </summary> public override void MmInvoke(MmMessageType msgType, MmMessage message) { //base.MmInvoke (msgType, message); //Executable code //Debug.Log ("Function Called."); //int i = 3 + 4; stopWatch.Stop(); simpleLock = false; }
public override void MmInvoke (MmMessageType msgType, MmMessage message) { switch (message.MmMethod) { case MmMethod.Transform: MmMessageTransform newMsg = message as MmMessageTransform; HandleTransform (newMsg); break; default: base.MmInvoke(msgType, message); break; } }
/// <summary> /// Create an MmMessage, with defined control block and MmMethod /// </summary> /// <param name="mmMethod">Identifier of target MmMethod</param> /// <param name="msgType">Type of Mercury Message.</param> /// <param name="metadataBlock">Object defining the routing of messages through MercuryMessaging Hierarchys.</param> public MmMessage(MmMethod mmMethod, MmMessageType msgType = default(MmMessageType), MmMetadataBlock metadataBlock = null) { MmMethod = mmMethod; MmMessageType = msgType; if (metadataBlock != null) { MetadataBlock = new MmMetadataBlock(metadataBlock); } else { MetadataBlock = new MmMetadataBlock(); } }
/// <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> /// <param name="msgType">Type of Mercury Message.</param> public MmMessage(MmMethod mmMethod, MmLevelFilter levelFilter, MmActiveFilter activeFilter, MmSelectedFilter selectedFilter, MmNetworkFilter networkFilter, MmMessageType msgType = default(MmMessageType) ) { MmMethod = mmMethod; MmMessageType = msgType; MetadataBlock = new MmMetadataBlock(); MetadataBlock.LevelFilter = levelFilter; MetadataBlock.ActiveFilter = activeFilter; MetadataBlock.SelectedFilter = selectedFilter; MetadataBlock.NetworkFilter = networkFilter; }
/// <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(MmMessageType msgType, MmMessage message) { if (AllowStandardMmInvoke) { base.MmInvoke(msgType, 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(msgType, 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(msgType, message); } } }
/// <summary> /// This is the network equivalent of IMmResponder's MmInvoke. /// The difference is this class allows specification of connectionIDs /// which can be used to ensure messages are routed to the correct /// objects on network clients. /// </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="msg">The message to send. /// This class builds on UNET's MessageBase so it is /// Auto [de]serialized by UNET.</param> /// <param name="connectionId">Connection ID - use to identify clients.</param> public virtual void MmInvoke(MmMessageType msgType, MmMessage message, int connectionId = -1) { message.NetId = netId.Value; //If the connection ID is defined, only send it there, // otherwise, it follows the standard execution flow for the chosen // network solution. if (connectionId != -1) { MmSendMessageToClient(connectionId, (short)msgType, message); return; } //Need to call the right method based on whether this object // is a client or a server. if (NetworkServer.active) { MmSendMessageToClient((short)msgType, message); } else if (allowClientToSend) { MmSendMessageToServer((short)msgType, message); } }
/// <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; //} }
/// <summary> /// Creates a basic MmMessage with the passed control block. /// </summary> /// <param name="metadataBlock">Object defining the routing of messages.</param> /// <param name="msgType">Type of Mercury Message.</param> public MmMessage(MmMetadataBlock metadataBlock, MmMessageType msgType = default(MmMessageType)) { MetadataBlock = new MmMetadataBlock(metadataBlock); MmMessageType = msgType; }
/// <summary> /// Creates a basic MmMessage with a default control block /// </summary> public MmMessage() { MetadataBlock = new MmMetadataBlock(); MmMessageType = MmMessageType.MmVoid; }
/// <summary> /// Creates a basic MmMessage with the passed MmMessageType. /// </summary> /// <param name="msgType">Type of Mercury Message.</param> public MmMessage(MmMessageType msgType) : this(new MmMetadataBlock(), msgType) { }
/// <summary> /// Invoke an MmMethod. /// Implements a switch that handles the different MmMethods /// defined by default set in MmMethod <see cref="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. <see cref="MmMessageType"/> /// </param> /// <param name="message">The message to send. /// This class builds on UNET's MessageBase so it is /// Auto [de]serialized by UNET. <see cref="MmMessage"/></param> public override void MmInvoke(MmMessageType msgType, MmMessage message) { var type = message.MmMethod; switch (type) { case MmMethod.NoOp: break; case MmMethod.SetActive: var messageBool = (MmMessageBool)message; SetActive(messageBool.value); break; case MmMethod.Refresh: var messageTransform = (MmMessageTransformList)message; Refresh(messageTransform.transforms); break; case MmMethod.Initialize: Initialize(); break; case MmMethod.Switch: var messageString = (MmMessageString)message; Switch(messageString.value); break; case MmMethod.Complete: var messageCompleteBool = (MmMessageBool)message; Complete(messageCompleteBool.value); break; case MmMethod.TaskInfo: var messageSerializable = (MmMessageSerializable)message; ApplyTaskInfo(messageSerializable.value); break; case MmMethod.Message: ReceivedMessage(message); break; case MmMethod.MessageBool: ReceivedMessage((MmMessageString)message); break; case MmMethod.MessageByteArray: ReceivedMessage((MmMessageByteArray)message); break; case MmMethod.MessageFloat: ReceivedMessage((MmMessageFloat)message); break; case MmMethod.MessageInt: ReceivedMessage((MmMessageInt)message); break; case MmMethod.MessageSerializable: ReceivedMessage((MmMessageSerializable)message); break; case MmMethod.MessageString: ReceivedMessage((MmMessageString)message); break; case MmMethod.MessageTransform: ReceivedMessage((MmMessageTransform)message); break; case MmMethod.MessageTransformList: ReceivedMessage((MmMessageTransformList)message); break; case MmMethod.MessageVector3: ReceivedMessage((MmMessageVector3)message); break; case MmMethod.MessageVector4: ReceivedMessage((MmMessageVector4)message); break; default: Debug.Log(message.MmMethod.ToString()); throw new ArgumentOutOfRangeException(); } }
/// <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 virtual void MmInvoke(MmMessageType msgType, MmMessage message) { }
/// <summary> /// Invoke an MmMethod with any message type. /// </summary> /// <param name="mmMethod">MmMethod Identifier - <see cref="MmMethod"/></param> /// <param name="param">MmMethod parameter: Any Message type.</param> /// <param name="msgType">Type of MmMessage parameter.</param> /// <param name="metadataBlock">Object defining the routing of /// Mmessages through MercuryMessaging Hierarchies. <see cref="MmMetadataBlock"/></param> public virtual void MmInvoke(MmMethod mmMethod, MmMessage param, MmMessageType msgType, MmMetadataBlock metadataBlock = null) { param.MmMethod = mmMethod; param.MetadataBlock = metadataBlock; MmInvoke(msgType, param); }
/// <summary> /// Process a message and send it to the associated object. /// </summary> /// <param name="netMsg">UNET network message</param> public virtual void ReceivedMessage(NetworkMessage netMsg) { MmMessageType mmMessageType = (MmMessageType)netMsg.msgType; try { switch (mmMessageType) { case MmMessageType.MmVoid: MmMessage msg = netMsg.ReadMessage <MmMessage>(); MmRelayNodes[msg.NetId].MmInvoke(mmMessageType, msg); break; case MmMessageType.MmInt: MmMessageInt msgInt = netMsg.ReadMessage <MmMessageInt>(); MmRelayNodes[msgInt.NetId].MmInvoke(mmMessageType, msgInt); break; case MmMessageType.MmBool: MmMessageBool msgBool = netMsg.ReadMessage <MmMessageBool>(); MmRelayNodes[msgBool.NetId].MmInvoke(mmMessageType, msgBool); break; case MmMessageType.MmFloat: MmMessageFloat msgFloat = netMsg.ReadMessage <MmMessageFloat>(); MmRelayNodes[msgFloat.NetId].MmInvoke(mmMessageType, msgFloat); break; case MmMessageType.MmVector3: MmMessageVector3 msgVector3 = netMsg.ReadMessage <MmMessageVector3>(); MmRelayNodes[msgVector3.NetId].MmInvoke(mmMessageType, msgVector3); break; case MmMessageType.MmVector4: MmMessageVector4 msgVector4 = netMsg.ReadMessage <MmMessageVector4>(); MmRelayNodes[msgVector4.NetId].MmInvoke(mmMessageType, msgVector4); break; case MmMessageType.MmString: MmMessageString msgString = netMsg.ReadMessage <MmMessageString>(); MmRelayNodes[msgString.NetId].MmInvoke(mmMessageType, msgString); break; case MmMessageType.MmByteArray: MmMessageByteArray msgByteArray = netMsg.ReadMessage <MmMessageByteArray>(); MmRelayNodes[msgByteArray.NetId].MmInvoke(mmMessageType, msgByteArray); break; case MmMessageType.MmTransform: MmMessageTransform msgTransform = netMsg.ReadMessage <MmMessageTransform>(); MmRelayNodes[msgTransform.NetId].MmInvoke(mmMessageType, msgTransform); break; case MmMessageType.MmTransformList: MmMessageTransformList msgTransformList = netMsg.ReadMessage <MmMessageTransformList>(); MmRelayNodes[msgTransformList.NetId].MmInvoke(mmMessageType, msgTransformList); break; case MmMessageType.MmSerializable: MmMessageSerializable msgSerializable = netMsg.ReadMessage <MmMessageSerializable>(); MmRelayNodes[msgSerializable.NetId].MmInvoke(mmMessageType, msgSerializable); break; case MmMessageType.MmGameObject: MmMessageGameObject msgGameObject = netMsg.ReadMessage <MmMessageGameObject>(); MmRelayNodes[msgGameObject.NetId].MmInvoke(mmMessageType, msgGameObject); break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception e) { MmLogger.LogError(e.Message); } }
/// <summary> /// Process a message and send it to the associated object. /// </summary> /// <param name="photonEvent">Photon RaiseEvent message data</param> public virtual void ReceivedMessage(EventData photonEvent) { short eventCode = (short)photonEvent.Code; if (eventCode != 1) { return; } MmMessageType mmMessageType = (MmMessageType)(eventCode); object[] data = (object[])photonEvent.CustomData; MmMessage msg = new MmMessage(); msg.Deserialize(data); try { switch (msg.MmMessageType) { case MmMessageType.MmVoid: MmRelayNode.MmInvoke(msg); break; case MmMessageType.MmInt: MmMessageInt msgInt = new MmMessageInt(); msgInt.Deserialize(data); MmRelayNode.MmInvoke(msgInt); break; case MmMessageType.MmBool: MmMessageBool msgBool = new MmMessageBool(); msgBool.Deserialize(data); MmRelayNode.MmInvoke(msgBool); break; case MmMessageType.MmFloat: MmMessageFloat msgFloat = new MmMessageFloat(); msgFloat.Deserialize(data); MmRelayNode.MmInvoke(msgFloat); break; case MmMessageType.MmVector3: MmMessageVector3 msgVector3 = new MmMessageVector3(); msgVector3.Deserialize(data); MmRelayNode.MmInvoke(msgVector3); break; case MmMessageType.MmVector4: MmMessageVector4 msgVector4 = new MmMessageVector4(); msgVector4.Deserialize(data); MmRelayNode.MmInvoke(msgVector4); break; case MmMessageType.MmString: MmMessageString msgString = new MmMessageString(); msgString.Deserialize(data); MmRelayNode.MmInvoke(msgString); break; case MmMessageType.MmByteArray: MmMessageByteArray msgByteArray = new MmMessageByteArray(); msgByteArray.Deserialize(data); MmRelayNode.MmInvoke(msgByteArray); break; case MmMessageType.MmTransform: MmMessageTransform msgTransform = new MmMessageTransform(); msgTransform.Deserialize(data); MmRelayNode.MmInvoke(msgTransform); break; case MmMessageType.MmTransformList: MmMessageTransformList msgTransformList = new MmMessageTransformList(); msgTransformList.Deserialize(data); MmRelayNode.MmInvoke(msgTransformList); break; case MmMessageType.MmSerializable: MmMessageSerializable msgSerializable = new MmMessageSerializable(); msgSerializable.Deserialize(data); MmRelayNode.MmInvoke(msgSerializable); break; case MmMessageType.MmGameObject: MmMessageGameObject msgGameObject = new MmMessageGameObject(); msgGameObject.Deserialize(data); MmRelayNode.MmInvoke(msgGameObject); break; default: Debug.Log(eventCode); throw new ArgumentOutOfRangeException(); } } catch (Exception e) { MmLogger.LogError(e.Message); } }