Пример #1
0
        // MODIFIED AddSystemToPlayerLoopList from Unity.Entities.ScriptBehaviourUpdateOrder (ECS)
        //
        // => adds an update function to the Unity internal update type.
        // => Unity has different update loops:
        //    https://medium.com/@thebeardphantom/unity-2018-and-playerloop-5c46a12a677
        //      EarlyUpdate
        //      FixedUpdate
        //      PreUpdate
        //      Update
        //      PreLateUpdate
        //      PostLateUpdate
        //
        // function: the custom update function to add
        //           IMPORTANT: according to a comment in Unity.Entities.ScriptBehaviourUpdateOrder,
        //                      the UpdateFunction can not be virtual because
        //                      Mono 4.6 has problems invoking virtual methods
        //                      as delegates from native!
        // ownerType: the .type to fill in so it's obvious who the new function
        //            belongs to. seems to be mostly for debugging. pass any.
        // addMode: prepend or append to update list
        internal static bool AddToPlayerLoop(PlayerLoopSystem.UpdateFunction function, Type ownerType, ref PlayerLoopSystem playerLoop, Type playerLoopSystemType, AddMode addMode)
        {
            // did we find the type? e.g. EarlyUpdate/PreLateUpdate/etc.
            if (playerLoop.type == playerLoopSystemType)
            {
                // debugging
                //Debug.Log($"Found playerLoop of type {playerLoop.type} with {playerLoop.subSystemList.Length} Functions:");
                //foreach (PlayerLoopSystem sys in playerLoop.subSystemList)
                //    Debug.Log($"  ->{sys.type}");

                // resize & expand subSystemList to fit one more entry
                int oldListLength = (playerLoop.subSystemList != null) ? playerLoop.subSystemList.Length : 0;
                Array.Resize(ref playerLoop.subSystemList, oldListLength + 1);

                // prepend our custom loop to the beginning
                if (addMode == AddMode.Beginning)
                {
                    // shift to the right, write into first array element
                    Array.Copy(playerLoop.subSystemList, 0, playerLoop.subSystemList, 1, playerLoop.subSystemList.Length - 1);
                    playerLoop.subSystemList[0].type           = ownerType;
                    playerLoop.subSystemList[0].updateDelegate = function;
                }
                // append our custom loop to the end
                else if (addMode == AddMode.End)
                {
                    // simply write into last array element
                    playerLoop.subSystemList[oldListLength].type           = ownerType;
                    playerLoop.subSystemList[oldListLength].updateDelegate = function;
                }

                // debugging
                //Debug.Log($"New playerLoop of type {playerLoop.type} with {playerLoop.subSystemList.Length} Functions:");
                //foreach (PlayerLoopSystem sys in playerLoop.subSystemList)
                //    Debug.Log($"  ->{sys.type}");

                return(true);
            }

            // recursively keep looking
            if (playerLoop.subSystemList != null)
            {
                for (int i = 0; i < playerLoop.subSystemList.Length; ++i)
                {
                    if (AddToPlayerLoop(function, ownerType, ref playerLoop.subSystemList[i], playerLoopSystemType, addMode))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Пример #2
0
        private static void AddSystemLoop <T1, T2>(PlayerLoopSystem.UpdateFunction update)
        {
            PlayerLoopSystem mainLoopSystem = PlayerLoop.GetDefaultPlayerLoop();

            if (FindLoopSystem <T1>(mainLoopSystem, out int index, out PlayerLoopSystem targetLoopSystem))
            {
                PlayerLoopSystem[] loopSystem = targetLoopSystem.subSystemList;
                int length = loopSystem.Length;
                Array.Resize(ref loopSystem, length + 1);
                loopSystem[length].type             = typeof(T2);
                loopSystem[length].updateDelegate   = update;
                targetLoopSystem.subSystemList      = loopSystem;
                mainLoopSystem.subSystemList[index] = targetLoopSystem;
                PlayerLoop.SetPlayerLoop(mainLoopSystem);
            }
        }
Пример #3
0
        internal static int FindPlayerLoopEntryIndex(PlayerLoopSystem.UpdateFunction function, PlayerLoopSystem playerLoop, Type playerLoopSystemType)
        {
            if (playerLoop.type == playerLoopSystemType)
            {
                return(Array.FindIndex(playerLoop.subSystemList, (elem => elem.updateDelegate == function)));
            }

            if (playerLoop.subSystemList != null)
            {
                for (int i = 0; i < playerLoop.subSystemList.Length; ++i)
                {
                    int index = FindPlayerLoopEntryIndex(function, playerLoop.subSystemList[i], playerLoopSystemType);
                    if (index != -1)
                    {
                        return(index);
                    }
                }
            }
            return(-1);
        }
        // helper function to find an update function's index in a player loop
        // type. this is used for testing to guarantee our functions are added
        // at the beginning/end properly.
        internal static int FindPlayerLoopEntryIndex(PlayerLoopSystem.UpdateFunction function, PlayerLoopSystem playerLoop, Type playerLoopSystemType)
        {
            // did we find the type? e.g. EarlyUpdate/PreLateUpdate/etc.
            if (playerLoop.type == playerLoopSystemType)
            {
                return(Array.FindIndex(playerLoop.subSystemList, (elem => elem.updateDelegate == function)));
            }

            // recursively keep looking
            if (playerLoop.subSystemList != null)
            {
                for (int i = 0; i < playerLoop.subSystemList.Length; ++i)
                {
                    int index = FindPlayerLoopEntryIndex(function, playerLoop.subSystemList[i], playerLoopSystemType);
                    if (index != -1)
                    {
                        return(index);
                    }
                }
            }
            return(-1);
        }
Пример #5
0
        private PlayerLoopSystem InsertLoopSubSystem(PlayerLoopSystem.UpdateFunction managedCallback, Type subSystemType, PlayerLoopSystem target, int index)
        {
            var loopUpdateSubSystem = new PlayerLoopSystem()
            {
                type           = subSystemType,
                updateDelegate = managedCallback
            };

            var newSubSystems       = new PlayerLoopSystem[target.subSystemList.Length + 1];
            var nativeLoopCondition = IntPtr.Zero;

            for (int i = 0, newSubSystemCount = newSubSystems.Length; i < newSubSystemCount; ++i)
            {
                if (i < index)
                {
                    newSubSystems[i] = target.subSystemList[i];

                    if ((i + 1) == index)
                    {
                        nativeLoopCondition = target.subSystemList[i].loopConditionFunction;
                    }
                }
                else if (i == index)
                {
                    loopUpdateSubSystem.loopConditionFunction = nativeLoopCondition;
                    newSubSystems[i] = loopUpdateSubSystem;
                }
                else
                {
                    newSubSystems[i] = target.subSystemList[i - 1];
                }
            }

            target.subSystemList = newSubSystems;

            return(target);
        }