Initial commit: Unity WordConnect project
This commit is contained in:
@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
using UnityEngine.LowLevel;
|
||||
using UnityEngine.PlayerLoop;
|
||||
#else
|
||||
using UnityEngine.Experimental.LowLevel;
|
||||
using UnityEngine.Experimental.PlayerLoop;
|
||||
#endif
|
||||
|
||||
namespace VContainer.Unity
|
||||
{
|
||||
public struct VContainerInitialization {}
|
||||
public struct VContainerPostInitialization {}
|
||||
public struct VContainerStartup {}
|
||||
public struct VContainerPostStartup {}
|
||||
public struct VContainerFixedUpdate {}
|
||||
public struct VContainerPostFixedUpdate {}
|
||||
public struct VContainerUpdate {}
|
||||
public struct VContainerPostUpdate {}
|
||||
public struct VContainerLateUpdate {}
|
||||
public struct VContainerPostLateUpdate {}
|
||||
|
||||
enum PlayerLoopTiming
|
||||
{
|
||||
Initialization = 0,
|
||||
PostInitialization = 1,
|
||||
|
||||
Startup = 2,
|
||||
PostStartup = 3,
|
||||
|
||||
FixedUpdate = 4,
|
||||
PostFixedUpdate = 5,
|
||||
|
||||
Update = 6,
|
||||
PostUpdate = 7,
|
||||
|
||||
LateUpdate = 8,
|
||||
PostLateUpdate = 9,
|
||||
}
|
||||
|
||||
static class PlayerLoopHelper
|
||||
{
|
||||
static readonly PlayerLoopRunner[] Runners = new PlayerLoopRunner[10];
|
||||
static long initialized;
|
||||
|
||||
// [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
public static void EnsureInitialized()
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref initialized, 1, 0) != 0)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < Runners.Length; i++)
|
||||
{
|
||||
Runners[i] = new PlayerLoopRunner();
|
||||
}
|
||||
|
||||
var playerLoop =
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
PlayerLoop.GetCurrentPlayerLoop();
|
||||
#else
|
||||
PlayerLoop.GetDefaultPlayerLoop();
|
||||
#endif
|
||||
|
||||
var copyList = playerLoop.subSystemList;
|
||||
|
||||
ref var initializeSystem = ref FindSubSystem(typeof(Initialization), copyList);
|
||||
InsertSubsystem(
|
||||
ref initializeSystem,
|
||||
null,
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerInitialization),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.Initialization].Run
|
||||
},
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerPostInitialization),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.PostInitialization].Run
|
||||
});
|
||||
|
||||
|
||||
ref var earlyUpdateSystem = ref FindSubSystem(typeof(EarlyUpdate), copyList);
|
||||
InsertSubsystem(
|
||||
ref earlyUpdateSystem,
|
||||
typeof(EarlyUpdate.ScriptRunDelayedStartupFrame),
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerStartup),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.Startup].Run
|
||||
},
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerPostStartup),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.PostStartup].Run
|
||||
});
|
||||
|
||||
ref var fixedUpdateSystem = ref FindSubSystem(typeof(FixedUpdate), copyList);
|
||||
InsertSubsystem(
|
||||
ref fixedUpdateSystem,
|
||||
typeof(FixedUpdate.ScriptRunBehaviourFixedUpdate),
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerFixedUpdate),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.FixedUpdate].Run
|
||||
},
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerPostFixedUpdate),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.PostFixedUpdate].Run
|
||||
});
|
||||
|
||||
ref var updateSystem = ref FindSubSystem(typeof(Update), copyList);
|
||||
InsertSubsystem(
|
||||
ref updateSystem,
|
||||
typeof(Update.ScriptRunBehaviourUpdate),
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerUpdate),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.Update].Run
|
||||
},
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerPostUpdate),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.PostUpdate].Run
|
||||
});
|
||||
|
||||
ref var lateUpdateSystem = ref FindSubSystem(typeof(PreLateUpdate), copyList);
|
||||
InsertSubsystem(
|
||||
ref lateUpdateSystem,
|
||||
typeof(PreLateUpdate.ScriptRunBehaviourLateUpdate),
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerLateUpdate),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.LateUpdate].Run
|
||||
},
|
||||
new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(VContainerPostLateUpdate),
|
||||
updateDelegate = Runners[(int)PlayerLoopTiming.PostLateUpdate].Run
|
||||
});
|
||||
|
||||
playerLoop.subSystemList = copyList;
|
||||
PlayerLoop.SetPlayerLoop(playerLoop);
|
||||
}
|
||||
|
||||
public static void Dispatch(PlayerLoopTiming timing, IPlayerLoopItem item)
|
||||
{
|
||||
EnsureInitialized();
|
||||
Runners[(int)timing].Dispatch(item);
|
||||
}
|
||||
|
||||
static ref PlayerLoopSystem FindSubSystem(Type targetType, PlayerLoopSystem[] systems)
|
||||
{
|
||||
for (var i = 0; i < systems.Length; i++)
|
||||
{
|
||||
if (systems[i].type == targetType)
|
||||
return ref systems[i];
|
||||
}
|
||||
throw new InvalidOperationException($"{targetType.FullName} not in systems");
|
||||
}
|
||||
|
||||
static void InsertSubsystem(
|
||||
ref PlayerLoopSystem parentSystem,
|
||||
Type beforeType,
|
||||
PlayerLoopSystem newSystem,
|
||||
PlayerLoopSystem newPostSystem)
|
||||
{
|
||||
var source = parentSystem.subSystemList;
|
||||
var insertIndex = -1;
|
||||
if (beforeType == null)
|
||||
{
|
||||
insertIndex = 0;
|
||||
}
|
||||
for (var i = 0; i < source.Length; i++)
|
||||
{
|
||||
if (source[i].type == beforeType)
|
||||
{
|
||||
insertIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (insertIndex < 0)
|
||||
{
|
||||
throw new ArgumentException($"{beforeType.FullName} not in system {parentSystem} {parentSystem.type.FullName}");
|
||||
}
|
||||
|
||||
var dest = new PlayerLoopSystem[source.Length + 2];
|
||||
for (var i = 0; i < dest.Length; i++)
|
||||
{
|
||||
if (i == insertIndex)
|
||||
{
|
||||
dest[i] = newSystem;
|
||||
}
|
||||
else if (i == dest.Length - 1)
|
||||
{
|
||||
dest[i] = newPostSystem;
|
||||
}
|
||||
else if (i < insertIndex)
|
||||
{
|
||||
dest[i] = source[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[i] = source[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
parentSystem.subSystemList = dest;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user