Skip to content

Commit 12cd892

Browse files
author
Chris Elion
authored
Merge pull request #3596 from Unity-Technologies/develop-sidechannel-usability
SideChannel helpers
2 parents 97e4fea + e21b35f commit 12cd892

20 files changed

+619
-161
lines changed

com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -505,13 +505,17 @@ public void RegisterSideChannel(SideChannel sideChannel)
505505
"side channels of the same id.", channelId));
506506
}
507507

508+
// Process any messages that we've already received for this channel ID.
508509
var numMessages = m_CachedMessages.Count;
509510
for (int i = 0; i < numMessages; i++)
510511
{
511512
var cachedMessage = m_CachedMessages.Dequeue();
512513
if (channelId == cachedMessage.ChannelId)
513514
{
514-
sideChannel.OnMessageReceived(cachedMessage.Message);
515+
using (var incomingMsg = new IncomingMessage(cachedMessage.Message))
516+
{
517+
sideChannel.OnMessageReceived(incomingMsg);
518+
}
515519
}
516520
else
517521
{
@@ -581,7 +585,10 @@ public static void ProcessSideChannelData(Dictionary<Guid, SideChannel> sideChan
581585
var cachedMessage = m_CachedMessages.Dequeue();
582586
if (sideChannels.ContainsKey(cachedMessage.ChannelId))
583587
{
584-
sideChannels[cachedMessage.ChannelId].OnMessageReceived(cachedMessage.Message);
588+
using (var incomingMsg = new IncomingMessage(cachedMessage.Message))
589+
{
590+
sideChannels[cachedMessage.ChannelId].OnMessageReceived(incomingMsg);
591+
}
585592
}
586593
else
587594
{
@@ -618,7 +625,10 @@ public static void ProcessSideChannelData(Dictionary<Guid, SideChannel> sideChan
618625
}
619626
if (sideChannels.ContainsKey(channelId))
620627
{
621-
sideChannels[channelId].OnMessageReceived(message);
628+
using (var incomingMsg = new IncomingMessage(message))
629+
{
630+
sideChannels[channelId].OnMessageReceived(incomingMsg);
631+
}
622632
}
623633
else
624634
{
Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.IO;
21
using System;
32
using UnityEngine;
43

@@ -20,27 +19,21 @@ public EngineConfigurationChannel()
2019
}
2120

2221
/// <inheritdoc/>
23-
public override void OnMessageReceived(byte[] data)
22+
public override void OnMessageReceived(IncomingMessage msg)
2423
{
25-
using (var memStream = new MemoryStream(data))
26-
{
27-
using (var binaryReader = new BinaryReader(memStream))
28-
{
29-
var width = binaryReader.ReadInt32();
30-
var height = binaryReader.ReadInt32();
31-
var qualityLevel = binaryReader.ReadInt32();
32-
var timeScale = binaryReader.ReadSingle();
33-
var targetFrameRate = binaryReader.ReadInt32();
24+
var width = msg.ReadInt32();
25+
var height = msg.ReadInt32();
26+
var qualityLevel = msg.ReadInt32();
27+
var timeScale = msg.ReadFloat32();
28+
var targetFrameRate = msg.ReadInt32();
3429

35-
timeScale = Mathf.Clamp(timeScale, 1, 100);
30+
timeScale = Mathf.Clamp(timeScale, 1, 100);
3631

37-
Screen.SetResolution(width, height, false);
38-
QualitySettings.SetQualityLevel(qualityLevel, true);
39-
Time.timeScale = timeScale;
40-
Time.captureFramerate = 60;
41-
Application.targetFrameRate = targetFrameRate;
42-
}
43-
}
32+
Screen.SetResolution(width, height, false);
33+
QualitySettings.SetQualityLevel(qualityLevel, true);
34+
Time.timeScale = timeScale;
35+
Time.captureFramerate = 60;
36+
Application.targetFrameRate = targetFrameRate;
4437
}
4538
}
4639
}
Lines changed: 20 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System.Collections.Generic;
2-
using System.IO;
32
using System;
4-
using System.Text;
53

64
namespace MLAgents.SideChannels
75
{
@@ -32,38 +30,40 @@ public class FloatPropertiesChannel : SideChannel
3230
}
3331

3432
/// <inheritdoc/>
35-
public override void OnMessageReceived(byte[] data)
33+
public override void OnMessageReceived(IncomingMessage msg)
3634
{
37-
var kv = DeserializeMessage(data);
38-
m_FloatProperties[kv.Key] = kv.Value;
39-
if (m_RegisteredActions.ContainsKey(kv.Key))
40-
{
41-
m_RegisteredActions[kv.Key].Invoke(kv.Value);
42-
}
35+
var key = msg.ReadString();
36+
var value = msg.ReadFloat32();
37+
38+
m_FloatProperties[key] = value;
39+
40+
Action<float> action;
41+
m_RegisteredActions.TryGetValue(key, out action);
42+
action?.Invoke(value);
4343
}
4444

4545
/// <inheritdoc/>
4646
public void SetProperty(string key, float value)
4747
{
4848
m_FloatProperties[key] = value;
49-
QueueMessageToSend(SerializeMessage(key, value));
50-
if (m_RegisteredActions.ContainsKey(key))
49+
using (var msgOut = new OutgoingMessage())
5150
{
52-
m_RegisteredActions[key].Invoke(value);
51+
msgOut.WriteString(key);
52+
msgOut.WriteFloat32(value);
53+
QueueMessageToSend(msgOut);
5354
}
55+
56+
Action<float> action;
57+
m_RegisteredActions.TryGetValue(key, out action);
58+
action?.Invoke(value);
5459
}
5560

5661
/// <inheritdoc/>
5762
public float GetPropertyWithDefault(string key, float defaultValue)
5863
{
59-
if (m_FloatProperties.ContainsKey(key))
60-
{
61-
return m_FloatProperties[key];
62-
}
63-
else
64-
{
65-
return defaultValue;
66-
}
64+
float valueOut;
65+
bool hasKey = m_FloatProperties.TryGetValue(key, out valueOut);
66+
return hasKey ? valueOut : defaultValue;
6767
}
6868

6969
/// <inheritdoc/>
@@ -77,34 +77,5 @@ public IList<string> ListProperties()
7777
{
7878
return new List<string>(m_FloatProperties.Keys);
7979
}
80-
81-
static KeyValuePair<string, float> DeserializeMessage(byte[] data)
82-
{
83-
using (var memStream = new MemoryStream(data))
84-
{
85-
using (var binaryReader = new BinaryReader(memStream))
86-
{
87-
var keyLength = binaryReader.ReadInt32();
88-
var key = Encoding.ASCII.GetString(binaryReader.ReadBytes(keyLength));
89-
var value = binaryReader.ReadSingle();
90-
return new KeyValuePair<string, float>(key, value);
91-
}
92-
}
93-
}
94-
95-
static byte[] SerializeMessage(string key, float value)
96-
{
97-
using (var memStream = new MemoryStream())
98-
{
99-
using (var binaryWriter = new BinaryWriter(memStream))
100-
{
101-
var stringEncoded = Encoding.ASCII.GetBytes(key);
102-
binaryWriter.Write(stringEncoded.Length);
103-
binaryWriter.Write(stringEncoded);
104-
binaryWriter.Write(value);
105-
return memStream.ToArray();
106-
}
107-
}
108-
}
10980
}
11081
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System.Collections.Generic;
2+
using System;
3+
using System.IO;
4+
using System.Text;
5+
6+
namespace MLAgents.SideChannels
7+
{
8+
/// <summary>
9+
/// Utility class for reading the data sent to the SideChannel.
10+
/// </summary>
11+
public class IncomingMessage : IDisposable
12+
{
13+
byte[] m_Data;
14+
Stream m_Stream;
15+
BinaryReader m_Reader;
16+
17+
/// <summary>
18+
/// Construct an IncomingMessage from the byte array.
19+
/// </summary>
20+
/// <param name="data"></param>
21+
public IncomingMessage(byte[] data)
22+
{
23+
m_Data = data;
24+
m_Stream = new MemoryStream(data);
25+
m_Reader = new BinaryReader(m_Stream);
26+
}
27+
28+
/// <summary>
29+
/// Read a boolan value from the message.
30+
/// </summary>
31+
/// <returns></returns>
32+
public bool ReadBoolean()
33+
{
34+
return m_Reader.ReadBoolean();
35+
}
36+
37+
/// <summary>
38+
/// Read an integer value from the message.
39+
/// </summary>
40+
/// <returns></returns>
41+
public int ReadInt32()
42+
{
43+
return m_Reader.ReadInt32();
44+
}
45+
46+
/// <summary>
47+
/// Read a float value from the message.
48+
/// </summary>
49+
/// <returns></returns>
50+
public float ReadFloat32()
51+
{
52+
return m_Reader.ReadSingle();
53+
}
54+
55+
/// <summary>
56+
/// Read a string value from the message.
57+
/// </summary>
58+
/// <returns></returns>
59+
public string ReadString()
60+
{
61+
var strLength = ReadInt32();
62+
var str = Encoding.ASCII.GetString(m_Reader.ReadBytes(strLength));
63+
return str;
64+
}
65+
66+
/// <summary>
67+
/// Reads a list of floats from the message. The length of the list is stored in the message.
68+
/// </summary>
69+
/// <returns></returns>
70+
public IList<float> ReadFloatList()
71+
{
72+
var len = ReadInt32();
73+
var output = new float[len];
74+
for (var i = 0; i < len; i++)
75+
{
76+
output[i] = ReadFloat32();
77+
}
78+
79+
return output;
80+
}
81+
82+
/// <summary>
83+
/// Gets the original data of the message. Note that this will return all of the data,
84+
/// even if part of it has already been read.
85+
/// </summary>
86+
/// <returns></returns>
87+
public byte[] GetRawBytes()
88+
{
89+
return m_Data;
90+
}
91+
92+
/// <summary>
93+
/// Clean up the internal storage.
94+
/// </summary>
95+
public void Dispose()
96+
{
97+
m_Reader?.Dispose();
98+
m_Stream?.Dispose();
99+
}
100+
}
101+
}

com.unity.ml-agents/Runtime/SideChannels/IncomingMessage.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)