Skip to content

Commit e5df4a2

Browse files
author
Chris Elion
authored
Communicator factory (#4965)
1 parent 79f2303 commit e5df4a2

File tree

4 files changed

+54
-41
lines changed

4 files changed

+54
-41
lines changed

com.unity.ml-agents/Runtime/Academy.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -422,12 +422,7 @@ void InitializeEnvironment()
422422
var port = ReadPortFromArgs();
423423
if (port > 0)
424424
{
425-
Communicator = new RpcCommunicator(
426-
new CommunicatorInitParameters
427-
{
428-
port = port
429-
}
430-
);
425+
Communicator = CommunicatorFactory.Create();
431426
}
432427

433428
if (Communicator != null)
@@ -438,6 +433,7 @@ void InitializeEnvironment()
438433
bool initSuccessful = false;
439434
var communicatorInitParams = new CommunicatorInitParameters
440435
{
436+
port = port,
441437
unityCommunicationVersion = k_ApiVersion,
442438
unityPackageVersion = k_PackageVersion,
443439
name = "AcademySingleton",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
namespace Unity.MLAgents
2+
{
3+
/// <summary>
4+
/// Factory class for an ICommunicator instance. This is used to the <see cref="Academy"/> at startup.
5+
/// By default, on desktop platforms, an ICommunicator will be created and attempt to connect
6+
/// to a trainer. This behavior can be prevented by setting <see cref="CommunicatorFactory.Enabled"/> to false
7+
/// *before* the <see cref="Academy"/> is initialized.
8+
/// </summary>
9+
public static class CommunicatorFactory
10+
{
11+
static bool s_Enabled = true;
12+
13+
/// <summary>
14+
/// Whether or not an ICommunicator instance will be created when the <see cref="Academy"/> is initialized.
15+
/// Changing this has no effect after the <see cref="Academy"/> has already been initialized.
16+
/// </summary>
17+
public static bool Enabled
18+
{
19+
get => s_Enabled;
20+
set => s_Enabled = value;
21+
}
22+
23+
internal static ICommunicator Create()
24+
{
25+
#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
26+
if (s_Enabled)
27+
{
28+
return new RpcCommunicator();
29+
}
30+
#endif
31+
// Non-desktop or disabled
32+
return null;
33+
}
34+
}
35+
}

com.unity.ml-agents/Runtime/Communicator/CommunicatorFactory.cs.meta

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

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

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
# if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
1+
#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
22
using Grpc.Core;
3-
#endif
43
#if UNITY_EDITOR
54
using UnityEditor;
65
#endif
@@ -44,23 +43,17 @@ internal class RpcCommunicator : ICommunicator
4443
Dictionary<string, ActionSpec> m_UnsentBrainKeys = new Dictionary<string, ActionSpec>();
4544

4645

47-
#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
4846
/// The Unity to External client.
4947
UnityToExternalProto.UnityToExternalProtoClient m_Client;
50-
#endif
51-
/// The communicator parameters sent at construction
52-
CommunicatorInitParameters m_CommunicatorInitParameters;
5348

5449
/// <summary>
5550
/// Initializes a new instance of the RPCCommunicator class.
5651
/// </summary>
57-
/// <param name="communicatorInitParameters">Communicator parameters.</param>
58-
public RpcCommunicator(CommunicatorInitParameters communicatorInitParameters)
52+
public RpcCommunicator()
5953
{
60-
m_CommunicatorInitParameters = communicatorInitParameters;
6154
}
6255

63-
#region Initialization
56+
#region Initialization
6457

6558
internal static bool CheckCommunicationVersionsAreCompatible(
6659
string unityCommunicationVersion,
@@ -110,6 +103,7 @@ public bool Initialize(CommunicatorInitParameters initParameters, out UnityRLIni
110103
try
111104
{
112105
initializationInput = Initialize(
106+
initParameters.port,
113107
new UnityOutputProto
114108
{
115109
RlInitializationOutput = academyParameters
@@ -211,13 +205,10 @@ void UpdateEnvironmentWithInput(UnityRLInputProto rlInput)
211205
SendCommandEvent(rlInput.Command);
212206
}
213207

214-
UnityInputProto Initialize(UnityOutputProto unityOutput, out UnityInputProto unityInput)
208+
UnityInputProto Initialize(int port, UnityOutputProto unityOutput, out UnityInputProto unityInput)
215209
{
216-
#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
217210
m_IsOpen = true;
218-
var channel = new Channel(
219-
"localhost:" + m_CommunicatorInitParameters.port,
220-
ChannelCredentials.Insecure);
211+
var channel = new Channel($"localhost:{port}", ChannelCredentials.Insecure);
221212

222213
m_Client = new UnityToExternalProto.UnityToExternalProtoClient(channel);
223214
var result = m_Client.Exchange(WrapMessage(unityOutput, 200));
@@ -232,21 +223,17 @@ UnityInputProto Initialize(UnityOutputProto unityOutput, out UnityInputProto uni
232223
QuitCommandReceived?.Invoke();
233224
}
234225
return result.UnityInput;
235-
#else
236-
throw new UnityAgentsException("You cannot perform training on this platform.");
237-
#endif
238226
}
239227

240-
#endregion
228+
#endregion
241229

242-
#region Destruction
230+
#region Destruction
243231

244232
/// <summary>
245233
/// Close the communicator gracefully on both sides of the communication.
246234
/// </summary>
247235
public void Dispose()
248236
{
249-
#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
250237
if (!m_IsOpen)
251238
{
252239
return;
@@ -261,15 +248,11 @@ public void Dispose()
261248
{
262249
// ignored
263250
}
264-
#else
265-
throw new UnityAgentsException(
266-
"You cannot perform training on this platform.");
267-
#endif
268251
}
269252

270-
#endregion
253+
#endregion
271254

272-
#region Sending Events
255+
#region Sending Events
273256

274257
void SendCommandEvent(CommandProto command)
275258
{
@@ -296,9 +279,9 @@ void SendCommandEvent(CommandProto command)
296279
}
297280
}
298281

299-
#endregion
282+
#endregion
300283

301-
#region Sending and retreiving data
284+
#region Sending and retreiving data
302285

303286
public void DecideBatch()
304287
{
@@ -447,7 +430,6 @@ public ActionBuffers GetActions(string behaviorName, int agentId)
447430
/// <param name="unityOutput">The UnityOutput to be sent.</param>
448431
UnityInputProto Exchange(UnityOutputProto unityOutput)
449432
{
450-
#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
451433
if (!m_IsOpen)
452434
{
453435
return null;
@@ -500,10 +482,6 @@ UnityInputProto Exchange(UnityOutputProto unityOutput)
500482
QuitCommandReceived?.Invoke();
501483
return null;
502484
}
503-
#else
504-
throw new UnityAgentsException(
505-
"You cannot perform training on this platform.");
506-
#endif
507485
}
508486

509487
/// <summary>
@@ -573,7 +551,7 @@ void UpdateSentActionSpec(UnityRLInitializationOutputProto output)
573551
}
574552
}
575553

576-
#endregion
554+
#endregion
577555

578556
#if UNITY_EDITOR
579557
/// <summary>
@@ -592,3 +570,4 @@ void HandleOnPlayModeChanged(PlayModeStateChange state)
592570
#endif
593571
}
594572
}
573+
#endif // UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX

0 commit comments

Comments
 (0)