Skip to content

Commit 9687207

Browse files
author
JS Fauteux
committed
Merge branch 'feature/performance_data_propagation' of github.com:Unity-Technologies/com.unity.multiplayer.mlapi into feature/profiler_override
2 parents a0a5da8 + ed7b4a4 commit 9687207

21 files changed

Lines changed: 789 additions & 681 deletions

com.unity.multiplayer.mlapi/Editor/PostProcessScene.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ public class NetworkScenePostProcess : MonoBehaviour
1111
[PostProcessScene(int.MaxValue)]
1212
public static void ProcessScene()
1313
{
14+
//If we are in playmode (editor or stand alone) we do not want this to execute
15+
if(Application.isPlaying)
16+
{
17+
return;
18+
}
19+
1420
List<NetworkedObject> traverseSortedObjects = MonoBehaviour.FindObjectsOfType<NetworkedObject>().ToList();
1521

1622
traverseSortedObjects.Sort((x, y) =>
@@ -57,4 +63,4 @@ internal static List<int> TraversedSiblingIndex(this NetworkedObject networkedOb
5763
return paths;
5864
}
5965
}
60-
}
66+
}
Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
using System;
2+
using System.Linq;
3+
using System.Collections.Generic;
4+
using UnityEngine;
5+
using UnityEngine.LowLevel;
6+
using UnityEngine.PlayerLoop;
7+
8+
namespace MLAPI
9+
{
10+
/// <summary>
11+
/// Defines the required interface of a network update system being executed by the network update loop.
12+
/// </summary>
13+
public interface INetworkUpdateSystem
14+
{
15+
void NetworkUpdate(NetworkUpdateStage updateStage);
16+
}
17+
18+
/// <summary>
19+
/// Defines network update stages being executed by the network update loop.
20+
/// </summary>
21+
public enum NetworkUpdateStage : byte
22+
{
23+
Initialization = 1,
24+
EarlyUpdate = 2,
25+
FixedUpdate = 3,
26+
PreUpdate = 4,
27+
Update = 0, // Default
28+
PreLateUpdate = 5,
29+
PostLateUpdate = 6
30+
}
31+
32+
/// <summary>
33+
/// Represents the network update loop injected into low-level player loop in Unity.
34+
/// </summary>
35+
public static class NetworkUpdateLoop
36+
{
37+
private static readonly Dictionary<NetworkUpdateStage, HashSet<INetworkUpdateSystem>> m_UpdateSystem_Sets;
38+
private static readonly Dictionary<NetworkUpdateStage, INetworkUpdateSystem[]> m_UpdateSystem_Arrays;
39+
private const int k_UpdateSystem_InitialArrayCapacity = 1024;
40+
41+
static NetworkUpdateLoop()
42+
{
43+
m_UpdateSystem_Sets = new Dictionary<NetworkUpdateStage, HashSet<INetworkUpdateSystem>>();
44+
m_UpdateSystem_Arrays = new Dictionary<NetworkUpdateStage, INetworkUpdateSystem[]>();
45+
46+
foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
47+
{
48+
m_UpdateSystem_Sets.Add(updateStage, new HashSet<INetworkUpdateSystem>());
49+
m_UpdateSystem_Arrays.Add(updateStage, new INetworkUpdateSystem[k_UpdateSystem_InitialArrayCapacity]);
50+
}
51+
}
52+
53+
/// <summary>
54+
/// Registers a network update system to be executed in all network update stages.
55+
/// </summary>
56+
public static void RegisterAllNetworkUpdates(this INetworkUpdateSystem updateSystem)
57+
{
58+
foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
59+
{
60+
RegisterNetworkUpdate(updateSystem, updateStage);
61+
}
62+
}
63+
64+
/// <summary>
65+
/// Registers a network update system to be executed in a specific network update stage.
66+
/// </summary>
67+
public static void RegisterNetworkUpdate(this INetworkUpdateSystem updateSystem, NetworkUpdateStage updateStage = NetworkUpdateStage.Update)
68+
{
69+
var sysSet = m_UpdateSystem_Sets[updateStage];
70+
if (!sysSet.Contains(updateSystem))
71+
{
72+
sysSet.Add(updateSystem);
73+
74+
int setLen = sysSet.Count;
75+
var sysArr = m_UpdateSystem_Arrays[updateStage];
76+
int arrLen = sysArr.Length;
77+
78+
if (setLen > arrLen)
79+
{
80+
// double capacity
81+
sysArr = m_UpdateSystem_Arrays[updateStage] = new INetworkUpdateSystem[arrLen *= 2];
82+
}
83+
84+
sysSet.CopyTo(sysArr);
85+
86+
if (setLen < arrLen)
87+
{
88+
// null terminator
89+
sysArr[setLen] = null;
90+
}
91+
}
92+
}
93+
94+
/// <summary>
95+
/// Unregisters a network update system from all network update stages.
96+
/// </summary>
97+
public static void UnregisterAllNetworkUpdates(this INetworkUpdateSystem updateSystem)
98+
{
99+
foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
100+
{
101+
UnregisterNetworkUpdate(updateSystem, updateStage);
102+
}
103+
}
104+
105+
/// <summary>
106+
/// Unregisters a network update system from a specific network update stage.
107+
/// </summary>
108+
public static void UnregisterNetworkUpdate(this INetworkUpdateSystem updateSystem, NetworkUpdateStage updateStage = NetworkUpdateStage.Update)
109+
{
110+
var sysSet = m_UpdateSystem_Sets[updateStage];
111+
if (sysSet.Contains(updateSystem))
112+
{
113+
sysSet.Remove(updateSystem);
114+
115+
int setLen = sysSet.Count;
116+
var sysArr = m_UpdateSystem_Arrays[updateStage];
117+
int arrLen = sysArr.Length;
118+
119+
sysSet.CopyTo(sysArr);
120+
121+
if (setLen < arrLen)
122+
{
123+
// null terminator
124+
sysArr[setLen] = null;
125+
}
126+
}
127+
}
128+
129+
/// <summary>
130+
/// The current network update stage being executed.
131+
/// </summary>
132+
public static NetworkUpdateStage UpdateStage;
133+
134+
private static void RunNetworkUpdateStage(NetworkUpdateStage updateStage)
135+
{
136+
UpdateStage = updateStage;
137+
138+
var sysArr = m_UpdateSystem_Arrays[updateStage];
139+
int arrLen = sysArr.Length;
140+
for (int curIdx = 0; curIdx < arrLen; curIdx++)
141+
{
142+
var curSys = sysArr[curIdx];
143+
if (curSys == null)
144+
{
145+
// null terminator
146+
break;
147+
}
148+
149+
curSys.NetworkUpdate(updateStage);
150+
}
151+
}
152+
153+
private struct NetworkInitialization
154+
{
155+
public static PlayerLoopSystem CreateLoopSystem()
156+
{
157+
return new PlayerLoopSystem
158+
{
159+
type = typeof(NetworkInitialization),
160+
updateDelegate = () => RunNetworkUpdateStage(NetworkUpdateStage.Initialization)
161+
};
162+
}
163+
}
164+
165+
private struct NetworkEarlyUpdate
166+
{
167+
public static PlayerLoopSystem CreateLoopSystem()
168+
{
169+
return new PlayerLoopSystem
170+
{
171+
type = typeof(NetworkEarlyUpdate),
172+
updateDelegate = () => RunNetworkUpdateStage(NetworkUpdateStage.EarlyUpdate)
173+
};
174+
}
175+
}
176+
177+
private struct NetworkFixedUpdate
178+
{
179+
public static PlayerLoopSystem CreateLoopSystem()
180+
{
181+
return new PlayerLoopSystem
182+
{
183+
type = typeof(NetworkFixedUpdate),
184+
updateDelegate = () => RunNetworkUpdateStage(NetworkUpdateStage.FixedUpdate)
185+
};
186+
}
187+
}
188+
189+
private struct NetworkPreUpdate
190+
{
191+
public static PlayerLoopSystem CreateLoopSystem()
192+
{
193+
return new PlayerLoopSystem
194+
{
195+
type = typeof(NetworkPreUpdate),
196+
updateDelegate = () => RunNetworkUpdateStage(NetworkUpdateStage.PreUpdate)
197+
};
198+
}
199+
}
200+
201+
private struct NetworkUpdate
202+
{
203+
public static PlayerLoopSystem CreateLoopSystem()
204+
{
205+
return new PlayerLoopSystem
206+
{
207+
type = typeof(NetworkUpdate),
208+
updateDelegate = () => RunNetworkUpdateStage(NetworkUpdateStage.Update)
209+
};
210+
}
211+
}
212+
213+
private struct NetworkPreLateUpdate
214+
{
215+
public static PlayerLoopSystem CreateLoopSystem()
216+
{
217+
return new PlayerLoopSystem
218+
{
219+
type = typeof(NetworkPreLateUpdate),
220+
updateDelegate = () => RunNetworkUpdateStage(NetworkUpdateStage.PreLateUpdate)
221+
};
222+
}
223+
}
224+
225+
private struct NetworkPostLateUpdate
226+
{
227+
public static PlayerLoopSystem CreateLoopSystem()
228+
{
229+
return new PlayerLoopSystem
230+
{
231+
type = typeof(NetworkPostLateUpdate),
232+
updateDelegate = () => RunNetworkUpdateStage(NetworkUpdateStage.PostLateUpdate)
233+
};
234+
}
235+
}
236+
237+
[RuntimeInitializeOnLoadMethod]
238+
private static void Initialize()
239+
{
240+
var customPlayerLoop = PlayerLoop.GetCurrentPlayerLoop();
241+
242+
for (int i = 0; i < customPlayerLoop.subSystemList.Length; i++)
243+
{
244+
var playerLoopSystem = customPlayerLoop.subSystemList[i];
245+
246+
if (playerLoopSystem.type == typeof(Initialization))
247+
{
248+
var subsystems = playerLoopSystem.subSystemList.ToList();
249+
{
250+
// insert at the bottom of `Initialization`
251+
subsystems.Add(NetworkInitialization.CreateLoopSystem());
252+
}
253+
playerLoopSystem.subSystemList = subsystems.ToArray();
254+
}
255+
else if (playerLoopSystem.type == typeof(EarlyUpdate))
256+
{
257+
var subsystems = playerLoopSystem.subSystemList.ToList();
258+
{
259+
int subsystemCount = subsystems.Count;
260+
for (int k = 0; k < subsystemCount; k++)
261+
{
262+
if (subsystems[k].type == typeof(EarlyUpdate.ScriptRunDelayedStartupFrame))
263+
{
264+
// insert before `EarlyUpdate.ScriptRunDelayedStartupFrame`
265+
subsystems.Insert(k, NetworkEarlyUpdate.CreateLoopSystem());
266+
break;
267+
}
268+
}
269+
}
270+
playerLoopSystem.subSystemList = subsystems.ToArray();
271+
}
272+
else if (playerLoopSystem.type == typeof(FixedUpdate))
273+
{
274+
var subsystems = playerLoopSystem.subSystemList.ToList();
275+
{
276+
int subsystemCount = subsystems.Count;
277+
for (int k = 0; k < subsystemCount; k++)
278+
{
279+
if (subsystems[k].type == typeof(FixedUpdate.ScriptRunBehaviourFixedUpdate))
280+
{
281+
// insert before `FixedUpdate.ScriptRunBehaviourFixedUpdate`
282+
subsystems.Insert(k, NetworkFixedUpdate.CreateLoopSystem());
283+
break;
284+
}
285+
}
286+
}
287+
playerLoopSystem.subSystemList = subsystems.ToArray();
288+
}
289+
else if (playerLoopSystem.type == typeof(PreUpdate))
290+
{
291+
var subsystems = playerLoopSystem.subSystemList.ToList();
292+
{
293+
int subsystemCount = subsystems.Count;
294+
for (int k = 0; k < subsystemCount; k++)
295+
{
296+
if (subsystems[k].type == typeof(PreUpdate.PhysicsUpdate))
297+
{
298+
// insert before `PreUpdate.PhysicsUpdate`
299+
subsystems.Insert(k, NetworkPreUpdate.CreateLoopSystem());
300+
break;
301+
}
302+
}
303+
}
304+
playerLoopSystem.subSystemList = subsystems.ToArray();
305+
}
306+
else if (playerLoopSystem.type == typeof(Update))
307+
{
308+
var subsystems = playerLoopSystem.subSystemList.ToList();
309+
{
310+
int subsystemCount = subsystems.Count;
311+
for (int k = 0; k < subsystemCount; k++)
312+
{
313+
if (subsystems[k].type == typeof(Update.ScriptRunBehaviourUpdate))
314+
{
315+
// insert before `Update.ScriptRunBehaviourUpdate`
316+
subsystems.Insert(k, NetworkUpdate.CreateLoopSystem());
317+
break;
318+
}
319+
}
320+
}
321+
playerLoopSystem.subSystemList = subsystems.ToArray();
322+
}
323+
else if (playerLoopSystem.type == typeof(PreLateUpdate))
324+
{
325+
var subsystems = playerLoopSystem.subSystemList.ToList();
326+
{
327+
int subsystemCount = subsystems.Count;
328+
for (int k = 0; k < subsystemCount; k++)
329+
{
330+
if (subsystems[k].type == typeof(PreLateUpdate.ScriptRunBehaviourLateUpdate))
331+
{
332+
// insert before `PreLateUpdate.ScriptRunBehaviourLateUpdate`
333+
subsystems.Insert(k, NetworkPreLateUpdate.CreateLoopSystem());
334+
break;
335+
}
336+
}
337+
}
338+
playerLoopSystem.subSystemList = subsystems.ToArray();
339+
}
340+
else if (playerLoopSystem.type == typeof(PostLateUpdate))
341+
{
342+
var subsystems = playerLoopSystem.subSystemList.ToList();
343+
{
344+
int subsystemCount = subsystems.Count;
345+
for (int k = 0; k < subsystemCount; k++)
346+
{
347+
if (subsystems[k].type == typeof(PostLateUpdate.PlayerSendFrameComplete))
348+
{
349+
// insert after `PostLateUpdate.PlayerSendFrameComplete`
350+
subsystems.Insert(k + 1, NetworkPostLateUpdate.CreateLoopSystem());
351+
break;
352+
}
353+
}
354+
}
355+
playerLoopSystem.subSystemList = subsystems.ToArray();
356+
}
357+
358+
customPlayerLoop.subSystemList[i] = playerLoopSystem;
359+
}
360+
361+
PlayerLoop.SetPlayerLoop(customPlayerLoop);
362+
}
363+
}
364+
}

com.unity.multiplayer.mlapi/Runtime/Core/NetworkUpdateLoopSystem.cs.meta renamed to com.unity.multiplayer.mlapi/Runtime/Core/NetworkUpdateLoop.cs.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)