Skip to content
This repository was archived by the owner on Oct 20, 2021. It is now read-only.

Commit bbe216f

Browse files
author
Jamie Brynes
authored
Worker connector updates & refactoring (#271)
1 parent 4bf3371 commit bbe216f

File tree

9 files changed

+137
-186
lines changed

9 files changed

+137
-186
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
### Changed
66

77
- `MobileClient` now uses the `ModularKcp` networking type rather than `Kcp`. [#268](https://github.com/spatialos/gdk-for-unity-fps-starter-project/pull/268).
8+
- The `MapBuilder` is now using a `Task` based API instead of a coroutine based one. [#271](https://github.com/spatialos/gdk-for-unity-fps-starter-project/pull/271)
9+
- The `WorkerConnector` implementations have been refactored and simplified. [#271](https://github.com/spatialos/gdk-for-unity-fps-starter-project/pull/271)
810

911
### Removed
1012

gdk.pinned

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
develop e91ae1c92502abebe6e7d94b6047914dd43beea6
1+
develop 0266b65afbbd6a70ff777148b6368ec5f1d83b82

workers/unity/Assets/Fps/Scripts/Editor/WorldTiles/MapBuilderVisualisationWindow.cs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void OnGUI()
7070
SetupMapBuilder();
7171
}
7272

73-
UnwindCoroutine(mapBuilder.CleanAndBuild(layerCount, seed));
73+
mapBuilder.CleanAndBuild(layerCount, seed).Wait();
7474
}
7575
}
7676

@@ -99,16 +99,5 @@ private int GetTotalTilesFromLayers(int layers)
9999
{
100100
return Mathf.RoundToInt(Mathf.Pow(layers * 2, 2));
101101
}
102-
103-
private void UnwindCoroutine(IEnumerator enumerator)
104-
{
105-
while (enumerator.MoveNext())
106-
{
107-
if (enumerator.Current is IEnumerator nestedEnumerator)
108-
{
109-
UnwindCoroutine(nestedEnumerator);
110-
}
111-
}
112-
}
113102
}
114103
}

workers/unity/Assets/Fps/Scripts/SimulatedPlayer/SimulatedPlayerDriver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private void Start()
6262
agent.updateUpAxis = false;
6363
agent.Warp(transform.position);
6464
anchorPoint = transform.position;
65-
worldBounds = coordinator.GetWorldBounds();
65+
worldBounds = coordinator.Bounds;
6666
}
6767

6868
private void OnEnable()

workers/unity/Assets/Fps/Scripts/WorkerConnectors/ClientWorkerConnector.cs

Lines changed: 21 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,34 @@ namespace Fps.WorkerConnectors
1111
{
1212
public class ClientWorkerConnector : WorkerConnectorBase
1313
{
14-
protected string deployment;
15-
1614
private string playerName;
1715
private bool isReadyToSpawn;
1816
private bool wantsSpawn;
1917
private Action<PlayerCreator.CreatePlayer.ReceivedResponse> onPlayerResponse;
20-
private AdvancedEntityPipeline entityPipeline;
2118

2219
public bool HasConnected => Worker != null;
2320

2421
public event Action OnLostPlayerEntity;
2522

26-
public async void Connect(string deployment = "")
23+
public void Start()
24+
{
25+
Application.targetFrameRate = 60;
26+
}
27+
28+
public async void Connect()
2729
{
28-
this.deployment = deployment.Trim();
29-
await AttemptConnect();
30+
try
31+
{
32+
await Connect(GetConnectionHandlerBuilder(), new ForwardingDispatcher());
33+
await LoadWorld();
34+
isReadyToSpawn = true;
35+
}
36+
catch (Exception e)
37+
{
38+
Debug.LogException(e);
39+
Dispose();
40+
Destroy(gameObject);
41+
}
3042
}
3143

3244
public void SpawnPlayer(string playerName, Action<PlayerCreator.CreatePlayer.ReceivedResponse> onPlayerResponse)
@@ -36,11 +48,6 @@ public void SpawnPlayer(string playerName, Action<PlayerCreator.CreatePlayer.Rec
3648
wantsSpawn = true;
3749
}
3850

39-
public void DisconnectPlayer()
40-
{
41-
StartCoroutine(PrepareDestroy());
42-
}
43-
4451
protected virtual string GetAuthPlayerPrefabPath()
4552
{
4653
return "Prefabs/UnityClient/Authoritative/Player";
@@ -51,7 +58,7 @@ protected virtual string GetNonAuthPlayerPrefabPath()
5158
return "Prefabs/UnityClient/NonAuthoritative/Player";
5259
}
5360

54-
protected override IConnectionHandlerBuilder GetConnectionHandlerBuilder()
61+
protected virtual IConnectionHandlerBuilder GetConnectionHandlerBuilder()
5562
{
5663
IConnectionFlow connectionFlow;
5764
var connectionParams = CreateConnectionParameters(WorkerUtils.UnityClient);
@@ -91,33 +98,19 @@ protected override void HandleWorkerConnectionEstablished()
9198
PlayerLifecycleHelper.AddClientSystems(world, autoRequestPlayerCreation: false);
9299
PlayerLifecycleConfig.MaxPlayerCreationRetries = 0;
93100

94-
entityPipeline = new AdvancedEntityPipeline(Worker, GetAuthPlayerPrefabPath(), GetNonAuthPlayerPrefabPath());
101+
var entityPipeline = new AdvancedEntityPipeline(Worker, GetAuthPlayerPrefabPath(), GetNonAuthPlayerPrefabPath());
95102
entityPipeline.OnRemovedAuthoritativePlayer += RemovingAuthoritativePlayer;
96103

97104
// Set the Worker gameObject to the ClientWorker so it can access PlayerCreater reader/writers
98105
GameObjectCreationHelper.EnableStandardGameObjectCreation(world, entityPipeline, gameObject);
99-
100-
base.HandleWorkerConnectionEstablished();
101106
}
102107

103108
private void RemovingAuthoritativePlayer()
104109
{
105-
Debug.LogError($"Player entity got removed while still being connected. Disconnecting...");
110+
Debug.LogWarning($"Player entity got removed while still being connected. Disconnecting...");
106111
OnLostPlayerEntity?.Invoke();
107112
}
108113

109-
protected override void HandleWorkerConnectionFailure(string errorMessage)
110-
{
111-
Debug.LogError($"Connection failed: {errorMessage}");
112-
Destroy(gameObject);
113-
}
114-
115-
protected override IEnumerator LoadWorld()
116-
{
117-
yield return base.LoadWorld();
118-
isReadyToSpawn = true;
119-
}
120-
121114
private void Update()
122115
{
123116
if (wantsSpawn && isReadyToSpawn)
@@ -127,22 +120,6 @@ private void Update()
127120
}
128121
}
129122

130-
public override void Dispose()
131-
{
132-
if (entityPipeline != null)
133-
{
134-
entityPipeline.OnRemovedAuthoritativePlayer -= RemovingAuthoritativePlayer;
135-
}
136-
137-
base.Dispose();
138-
}
139-
140-
private IEnumerator PrepareDestroy()
141-
{
142-
yield return DeferredDisposeWorker();
143-
Destroy(gameObject);
144-
}
145-
146123
private void SendRequest()
147124
{
148125
var serializedArgs = Encoding.ASCII.GetBytes(playerName);

workers/unity/Assets/Fps/Scripts/WorkerConnectors/GameLogicWorkerConnector.cs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,23 @@ public class GameLogicWorkerConnector : WorkerConnectorBase
1515
{
1616
public bool DisableRenderers = true;
1717

18-
protected override async void Start()
18+
protected async void Start()
1919
{
20-
base.Start();
21-
await AttemptConnect();
20+
Application.targetFrameRate = 60;
21+
22+
await Connect(GetConnectionHandlerBuilder(), new ForwardingDispatcher());
23+
await LoadWorld();
24+
25+
if (DisableRenderers)
26+
{
27+
foreach (var childRenderer in LevelInstance.GetComponentsInChildren<Renderer>())
28+
{
29+
childRenderer.enabled = false;
30+
}
31+
}
2232
}
2333

24-
protected override IConnectionHandlerBuilder GetConnectionHandlerBuilder()
34+
private IConnectionHandlerBuilder GetConnectionHandlerBuilder()
2535
{
2636
IConnectionFlow connectionFlow;
2737
ConnectionParameters connectionParameters;
@@ -61,21 +71,6 @@ protected override void HandleWorkerConnectionEstablished()
6171
// Health
6272
world.GetOrCreateSystem<ServerHealthModifierSystem>();
6373
world.GetOrCreateSystem<HealthRegenSystem>();
64-
65-
base.HandleWorkerConnectionEstablished();
66-
}
67-
68-
protected override IEnumerator LoadWorld()
69-
{
70-
yield return base.LoadWorld();
71-
72-
if (DisableRenderers)
73-
{
74-
foreach (var childRenderer in LevelInstance.GetComponentsInChildren<Renderer>())
75-
{
76-
childRenderer.enabled = false;
77-
}
78-
}
7974
}
8075
}
8176
}

workers/unity/Assets/Fps/Scripts/WorkerConnectors/SimulatedPlayerCoordinatorWorkerConnector.cs

Lines changed: 57 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public class SimulatedPlayerCoordinatorWorkerConnector : WorkerConnectorBase
3030
public int MaxSimulatedPlayerCount = 1;
3131
public int SimulatedPlayerCreationInterval = 5;
3232

33+
public Bounds Bounds { get; private set; }
34+
3335
private readonly Dictionary<EntityId, List<GameObject>> proxies = new Dictionary<EntityId, List<GameObject>>();
3436
private readonly List<EntityId> localSimulatedPlayers = new List<EntityId>();
3537

@@ -40,10 +42,11 @@ public class SimulatedPlayerCoordinatorWorkerConnector : WorkerConnectorBase
4042
private CancellationTokenSource tokenSource;
4143
private int TimeBetweenCycleSecs = 2;
4244

43-
protected override async void Start()
45+
protected async void Start()
4446
{
45-
var args = CommandLineArgs.FromCommandLine();
47+
Application.targetFrameRate = 60;
4648

49+
var args = CommandLineArgs.FromCommandLine();
4750
var deploymentName = string.Empty;
4851

4952
if (args.TryGetCommandLineValue(DeploymentNameFlag, ref deploymentName))
@@ -56,45 +59,22 @@ protected override async void Start()
5659
connectPlayersWithDevAuth = false;
5760
}
5861

59-
Application.targetFrameRate = 60;
60-
await AttemptConnect();
61-
}
62+
await Connect(GetConnectionHandlerBuilder(), new ForwardingDispatcher());
6263

63-
protected override IConnectionHandlerBuilder GetConnectionHandlerBuilder()
64-
{
65-
IConnectionFlow connectionFlow;
66-
ConnectionParameters connectionParameters;
67-
68-
var workerId = CreateNewWorkerId(WorkerUtils.SimulatedPlayerCoordinator);
69-
70-
if (Application.isEditor)
71-
{
72-
connectionFlow = new ReceptionistFlow(workerId);
73-
connectionParameters = CreateConnectionParameters(WorkerUtils.SimulatedPlayerCoordinator);
74-
}
75-
else
64+
if (SimulatedPlayerWorkerConnector == null)
7665
{
77-
connectionFlow = new ReceptionistFlow(workerId, new CommandLineConnectionFlowInitializer());
78-
connectionParameters = CreateConnectionParameters(WorkerUtils.SimulatedPlayerCoordinator,
79-
new CommandLineConnectionParameterInitializer());
66+
Worker.LogDispatcher.HandleLog(LogType.Error, new LogEvent("Did not find a SimulatedPlayerWorkerConnector GameObject."));
67+
return;
8068
}
8169

82-
return new SpatialOSConnectionHandlerBuilder()
83-
.SetConnectionFlow(connectionFlow)
84-
.SetConnectionParameters(connectionParameters);
70+
Bounds = await GetWorldBounds();
71+
72+
await LoadWorld();
73+
await ConnectSimulatedPlayers();
8574
}
8675

87-
protected override async void HandleWorkerConnectionEstablished()
76+
private async Task ConnectSimulatedPlayers()
8877
{
89-
base.HandleWorkerConnectionEstablished();
90-
91-
Worker.World.GetOrCreateSystem<MetricSendSystem>();
92-
93-
if (SimulatedPlayerWorkerConnector == null)
94-
{
95-
return;
96-
}
97-
9878
tokenSource = new CancellationTokenSource();
9979

10080
try
@@ -103,7 +83,7 @@ protected override async void HandleWorkerConnectionEstablished()
10383
// to change the parameters..
10484
if (connectPlayersWithDevAuth)
10585
{
106-
await WaitForWorkerFlags(flagDevAuthTokenId, flagTargetDeployment, flagClientCount,
86+
await WaitForWorkerFlags(tokenSource.Token, flagDevAuthTokenId, flagTargetDeployment, flagClientCount,
10787
flagCreationInterval);
10888

10989
var simulatedPlayerDevAuthTokenId = Worker.GetWorkerFlag(flagDevAuthTokenId);
@@ -142,30 +122,42 @@ await Monitor(MaxSimulatedPlayerCount, SimulatedPlayerCreationInterval,
142122
}
143123
}
144124

145-
public override void Dispose()
125+
private IConnectionHandlerBuilder GetConnectionHandlerBuilder()
146126
{
147-
tokenSource?.Cancel();
148-
tokenSource?.Dispose();
149-
tokenSource = null;
127+
IConnectionFlow connectionFlow;
128+
ConnectionParameters connectionParameters;
150129

151-
base.Dispose();
130+
var workerId = CreateNewWorkerId(WorkerUtils.SimulatedPlayerCoordinator);
131+
132+
if (Application.isEditor)
133+
{
134+
connectionFlow = new ReceptionistFlow(workerId);
135+
connectionParameters = CreateConnectionParameters(WorkerUtils.SimulatedPlayerCoordinator);
136+
}
137+
else
138+
{
139+
connectionFlow = new ReceptionistFlow(workerId, new CommandLineConnectionFlowInitializer());
140+
connectionParameters = CreateConnectionParameters(WorkerUtils.SimulatedPlayerCoordinator,
141+
new CommandLineConnectionParameterInitializer());
142+
}
143+
144+
return new SpatialOSConnectionHandlerBuilder()
145+
.SetConnectionFlow(connectionFlow)
146+
.SetConnectionParameters(connectionParameters);
152147
}
153148

154-
// Wait for a number of worker flags to be present for this worker. Will spin forever otherwise.
155-
private async Task WaitForWorkerFlags(params string[] flagKeys)
149+
protected override void HandleWorkerConnectionEstablished()
156150
{
157-
var token = tokenSource.Token;
151+
Worker.World.GetOrCreateSystem<MetricSendSystem>();
152+
}
158153

159-
while (flagKeys.Any(key => string.IsNullOrEmpty(Worker.GetWorkerFlag(key))))
160-
{
161-
if (token.IsCancellationRequested)
162-
{
163-
throw new TaskCanceledException();
164-
}
154+
public override void Dispose()
155+
{
156+
tokenSource?.Cancel();
157+
tokenSource?.Dispose();
158+
tokenSource = null;
165159

166-
Worker.LogDispatcher.HandleLog(LogType.Log, new LogEvent("Waiting for required worker flags.."));
167-
await Task.Delay(TimeSpan.FromSeconds(TimeBetweenCycleSecs), token);
168-
}
160+
base.Dispose();
169161
}
170162

171163
// Update worker flags if they have changed.
@@ -221,7 +213,17 @@ private async Task CreateSimPlayer(int delayInterval, Func<SimulatedPlayerWorker
221213
var simPlayer = Instantiate(SimulatedPlayerWorkerConnector, transform.position, transform.rotation);
222214
var connector = simPlayer.GetComponent<SimulatedPlayerWorkerConnector>();
223215

224-
await connectMethod(connector);
216+
try
217+
{
218+
await connectMethod(connector);
219+
}
220+
catch (Exception e)
221+
{
222+
Worker.LogDispatcher.HandleLog(LogType.Exception, new LogEvent("Failed to connect simulated player").WithException(e));
223+
Destroy(simPlayer);
224+
return;
225+
}
226+
225227
connector.SpawnPlayer(simulatedPlayerConnectors.Count);
226228

227229
simulatedPlayerConnectors.Add(simPlayer);
@@ -307,9 +309,9 @@ public void UnregisterLocalSimulatedPlayer(EntityId entityId, GameObject prefab)
307309
}
308310
}
309311

310-
public Bounds GetWorldBounds()
312+
public async Task<Bounds> GetWorldBounds()
311313
{
312-
var worldSize = GetWorldSize();
314+
var worldSize = await GetWorldSize();
313315
return new Bounds(Worker.Origin, MapBuilder.GetWorldDimensions(worldSize));
314316
}
315317

0 commit comments

Comments
 (0)