/// <inheritdoc/> protected override void OnMessageReceived(IncomingMessage msg) { throw new UnityAgentsException("StatsSideChannel should never receive messages."); }
/// <summary> /// Separates the data received from Python into individual messages for each registered side channel. /// </summary> /// <param name="sideChannels">A dictionary of channel type to channel.</param> /// <param name="dataReceived">The byte array of data received from Python.</param> internal static void ProcessSideChannelData(Dictionary <Guid, SideChannel> sideChannels, byte[] dataReceived) { while (m_CachedMessages.Count != 0) { var cachedMessage = m_CachedMessages.Dequeue(); if (sideChannels.ContainsKey(cachedMessage.ChannelId)) { using (var incomingMsg = new IncomingMessage(cachedMessage.Message)) { sideChannels[cachedMessage.ChannelId].OnMessageReceived(incomingMsg); } } else { Debug.Log(string.Format( "Unknown side channel data received. Channel Id is " + ": {0}", cachedMessage.ChannelId)); } } if (dataReceived.Length == 0) { return; } using (var memStream = new MemoryStream(dataReceived)) { using (var binaryReader = new BinaryReader(memStream)) { while (memStream.Position < memStream.Length) { Guid channelId = Guid.Empty; byte[] message = null; try { channelId = new Guid(binaryReader.ReadBytes(16)); var messageLength = binaryReader.ReadInt32(); message = binaryReader.ReadBytes(messageLength); } catch (Exception ex) { throw new UnityAgentsException( "There was a problem reading a message in a SideChannel. Please make sure the " + "version of MLAgents in Unity is compatible with the Python version. Original error : " + ex.Message); } if (sideChannels.ContainsKey(channelId)) { using (var incomingMsg = new IncomingMessage(message)) { sideChannels[channelId].OnMessageReceived(incomingMsg); } } else { // Don't recognize this ID, but cache it in case the SideChannel that can handle // it is registered before the next call to ProcessSideChannelData. m_CachedMessages.Enqueue(new CachedSideChannelMessage { ChannelId = channelId, Message = message }); } } } } }
/// <summary> /// Is called by the communicator every time a message is received from Python by the SideChannel. /// Can be called multiple times per simulation step if multiple messages were sent. /// </summary> /// <param name="msg">The incoming message.</param> public abstract void OnMessageReceived(IncomingMessage msg);
/// <summary> /// Is called by the communicator every time a message is received from Python by the SideChannel. /// Can be called multiple times per simulation step if multiple messages were sent. /// </summary> /// <param name="msg">The incoming message.</param> protected abstract void OnMessageReceived(IncomingMessage msg);