11using System ;
2- using System . Linq ;
32using System . Collections . Generic ;
43using UnityEngine ;
54using UnityEngine . LowLevel ;
@@ -234,131 +233,166 @@ public static PlayerLoopSystem CreateLoopSystem()
234233 }
235234 }
236235
237- [ RuntimeInitializeOnLoadMethod ]
236+ [ RuntimeInitializeOnLoadMethod ( RuntimeInitializeLoadType . SubsystemRegistration ) ]
238237 private static void Initialize ( )
239238 {
240- var customPlayerLoop = PlayerLoop . GetCurrentPlayerLoop ( ) ;
239+ UnregisterLoopSystems ( ) ;
240+ RegisterLoopSystems ( ) ;
241+ }
241242
242- for ( int i = 0 ; i < customPlayerLoop . subSystemList . Length ; i ++ )
243- {
244- var playerLoopSystem = customPlayerLoop . subSystemList [ i ] ;
243+ private enum LoopSystemPosition
244+ {
245+ After ,
246+ Before
247+ }
245248
246- if ( playerLoopSystem . type == typeof ( Initialization ) )
249+ private static bool TryAddLoopSystem ( ref PlayerLoopSystem parentLoopSystem , PlayerLoopSystem childLoopSystem , Type anchorSystemType , LoopSystemPosition loopSystemPosition )
250+ {
251+ int systemPosition = - 1 ;
252+ if ( anchorSystemType != null )
253+ {
254+ for ( int i = 0 ; i < parentLoopSystem . subSystemList . Length ; i ++ )
247255 {
248- var subsystems = playerLoopSystem . subSystemList . ToList ( ) ;
256+ var subsystem = parentLoopSystem . subSystemList [ i ] ;
257+ if ( subsystem . type == anchorSystemType )
249258 {
250- // insert at the bottom of `Initialization`
251- subsystems . Add ( NetworkInitialization . CreateLoopSystem ( ) ) ;
259+ systemPosition = loopSystemPosition == LoopSystemPosition . After ? i + 1 : i ;
260+ break ;
252261 }
253- playerLoopSystem . subSystemList = subsystems . ToArray ( ) ;
254262 }
255- else if ( playerLoopSystem . type == typeof ( EarlyUpdate ) )
263+ }
264+ else
265+ {
266+ systemPosition = loopSystemPosition == LoopSystemPosition . After ? parentLoopSystem . subSystemList . Length : 0 ;
267+ }
268+
269+ if ( systemPosition == - 1 ) return false ;
270+
271+ var newSubsystemList = new PlayerLoopSystem [ parentLoopSystem . subSystemList . Length + 1 ] ;
272+
273+ // begin = systemsBefore + systemsAfter
274+ // + systemsBefore
275+ if ( systemPosition > 0 ) Array . Copy ( parentLoopSystem . subSystemList , newSubsystemList , systemPosition ) ;
276+ // + childSystem
277+ newSubsystemList [ systemPosition ] = childLoopSystem ;
278+ // + systemsAfter
279+ if ( systemPosition < parentLoopSystem . subSystemList . Length ) Array . Copy ( parentLoopSystem . subSystemList , systemPosition , newSubsystemList , systemPosition + 1 , parentLoopSystem . subSystemList . Length - systemPosition ) ;
280+ // end = systemsBefore + childSystem + systemsAfter
281+
282+ parentLoopSystem . subSystemList = newSubsystemList ;
283+
284+ return true ;
285+ }
286+
287+ private static bool TryRemoveLoopSystem ( ref PlayerLoopSystem parentLoopSystem , Type childSystemType )
288+ {
289+ int systemPosition = - 1 ;
290+ for ( int i = 0 ; i < parentLoopSystem . subSystemList . Length ; i ++ )
291+ {
292+ var subsystem = parentLoopSystem . subSystemList [ i ] ;
293+ if ( subsystem . type == childSystemType )
256294 {
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 ( ) ;
295+ systemPosition = i ;
296+ break ;
271297 }
272- else if ( playerLoopSystem . type == typeof ( FixedUpdate ) )
298+ }
299+
300+ if ( systemPosition == - 1 ) return false ;
301+
302+ var newSubsystemList = new PlayerLoopSystem [ parentLoopSystem . subSystemList . Length - 1 ] ;
303+
304+ // begin = systemsBefore + childSystem + systemsAfter
305+ // + systemsBefore
306+ if ( systemPosition > 0 ) Array . Copy ( parentLoopSystem . subSystemList , newSubsystemList , systemPosition ) ;
307+ // + systemsAfter
308+ if ( systemPosition < parentLoopSystem . subSystemList . Length - 1 ) Array . Copy ( parentLoopSystem . subSystemList , systemPosition + 1 , newSubsystemList , systemPosition , parentLoopSystem . subSystemList . Length - systemPosition - 1 ) ;
309+ // end = systemsBefore + systemsAfter
310+
311+ parentLoopSystem . subSystemList = newSubsystemList ;
312+
313+ return true ;
314+ }
315+
316+ internal static void RegisterLoopSystems ( )
317+ {
318+ var rootPlayerLoop = PlayerLoop . GetCurrentPlayerLoop ( ) ;
319+
320+ for ( int i = 0 ; i < rootPlayerLoop . subSystemList . Length ; i ++ )
321+ {
322+ ref var currentSystem = ref rootPlayerLoop . subSystemList [ i ] ;
323+
324+ if ( currentSystem . type == typeof ( Initialization ) )
273325 {
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 ( ) ;
326+ TryAddLoopSystem ( ref currentSystem , NetworkInitialization . CreateLoopSystem ( ) , null , LoopSystemPosition . After ) ;
288327 }
289- else if ( playerLoopSystem . type == typeof ( PreUpdate ) )
328+ else if ( currentSystem . type == typeof ( EarlyUpdate ) )
290329 {
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 ( ) ;
330+ TryAddLoopSystem ( ref currentSystem , NetworkEarlyUpdate . CreateLoopSystem ( ) , typeof ( EarlyUpdate . ScriptRunDelayedStartupFrame ) , LoopSystemPosition . Before ) ;
305331 }
306- else if ( playerLoopSystem . type == typeof ( Update ) )
332+ else if ( currentSystem . type == typeof ( FixedUpdate ) )
307333 {
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 ( ) ;
334+ TryAddLoopSystem ( ref currentSystem , NetworkFixedUpdate . CreateLoopSystem ( ) , typeof ( FixedUpdate . ScriptRunBehaviourFixedUpdate ) , LoopSystemPosition . Before ) ;
322335 }
323- else if ( playerLoopSystem . type == typeof ( PreLateUpdate ) )
336+ else if ( currentSystem . type == typeof ( PreUpdate ) )
324337 {
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 ( ) ;
338+ TryAddLoopSystem ( ref currentSystem , NetworkPreUpdate . CreateLoopSystem ( ) , typeof ( PreUpdate . PhysicsUpdate ) , LoopSystemPosition . Before ) ;
339339 }
340- else if ( playerLoopSystem . type == typeof ( PostLateUpdate ) )
340+ else if ( currentSystem . type == typeof ( Update ) )
341341 {
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 ( ) ;
342+ TryAddLoopSystem ( ref currentSystem , NetworkUpdate . CreateLoopSystem ( ) , typeof ( Update . ScriptRunBehaviourUpdate ) , LoopSystemPosition . Before ) ;
356343 }
344+ else if ( currentSystem . type == typeof ( PreLateUpdate ) )
345+ {
346+ TryAddLoopSystem ( ref currentSystem , NetworkPreLateUpdate . CreateLoopSystem ( ) , typeof ( PreLateUpdate . ScriptRunBehaviourLateUpdate ) , LoopSystemPosition . Before ) ;
347+ }
348+ else if ( currentSystem . type == typeof ( PostLateUpdate ) )
349+ {
350+ TryAddLoopSystem ( ref currentSystem , NetworkPostLateUpdate . CreateLoopSystem ( ) , typeof ( PostLateUpdate . PlayerSendFrameComplete ) , LoopSystemPosition . After ) ;
351+ }
352+ }
353+
354+ PlayerLoop . SetPlayerLoop ( rootPlayerLoop ) ;
355+ }
356+
357+ internal static void UnregisterLoopSystems ( )
358+ {
359+ var rootPlayerLoop = PlayerLoop . GetCurrentPlayerLoop ( ) ;
360+
361+ for ( int i = 0 ; i < rootPlayerLoop . subSystemList . Length ; i ++ )
362+ {
363+ ref var currentSystem = ref rootPlayerLoop . subSystemList [ i ] ;
357364
358- customPlayerLoop . subSystemList [ i ] = playerLoopSystem ;
365+ if ( currentSystem . type == typeof ( Initialization ) )
366+ {
367+ TryRemoveLoopSystem ( ref currentSystem , typeof ( NetworkInitialization ) ) ;
368+ }
369+ else if ( currentSystem . type == typeof ( EarlyUpdate ) )
370+ {
371+ TryRemoveLoopSystem ( ref currentSystem , typeof ( NetworkEarlyUpdate ) ) ;
372+ }
373+ else if ( currentSystem . type == typeof ( FixedUpdate ) )
374+ {
375+ TryRemoveLoopSystem ( ref currentSystem , typeof ( NetworkFixedUpdate ) ) ;
376+ }
377+ else if ( currentSystem . type == typeof ( PreUpdate ) )
378+ {
379+ TryRemoveLoopSystem ( ref currentSystem , typeof ( NetworkPreUpdate ) ) ;
380+ }
381+ else if ( currentSystem . type == typeof ( Update ) )
382+ {
383+ TryRemoveLoopSystem ( ref currentSystem , typeof ( NetworkUpdate ) ) ;
384+ }
385+ else if ( currentSystem . type == typeof ( PreLateUpdate ) )
386+ {
387+ TryRemoveLoopSystem ( ref currentSystem , typeof ( NetworkPreLateUpdate ) ) ;
388+ }
389+ else if ( currentSystem . type == typeof ( PostLateUpdate ) )
390+ {
391+ TryRemoveLoopSystem ( ref currentSystem , typeof ( NetworkPostLateUpdate ) ) ;
392+ }
359393 }
360394
361- PlayerLoop . SetPlayerLoop ( customPlayerLoop ) ;
395+ PlayerLoop . SetPlayerLoop ( rootPlayerLoop ) ;
362396 }
363397 }
364- }
398+ }
0 commit comments