Пример #1
0
 // Runs a coroutine group then runs the next queued coroutine group if available.
 // Increments numActive before running the coroutine and decrements it after.
 // returns values yielded by the given coroutine
 // coroutineGroup: Coroutine Group to run
 private IEnumerator CoroutineGroupRunner(CoroutineGroup coroutineGroup)
 {
     // increment number of active coroutines
     numActive++;
     // save a reference to currently running corouting group
     runningCoroutineGroup = coroutineGroup;
     // Run coroutine group
     coroutineGroup.Run();
     // wait while all coroutines in the group are finished
     while (coroutineGroup.NumberOfCoroutinesToExecute > 0)
     {
         // Debug.Log("Coroutine group NumberOfCoroutinesToExecute: " + coroutineGroup.NumberOfCoroutinesToExecute);
         // skip to the next frame
         yield return(null);
     }
     // coroutine is finished
     // reset running corouting group reference
     runningCoroutineGroup = null;
     // decrement number of active coroutines
     numActive--;
     // verify if there still coroutine groups left in a queue
     if (queue.Count > 0)
     {
         // get next coroutine group from the queue
         var nextCoroutineGroup = queue.Dequeue();
         // run next coroutine group
         Run(nextCoroutineGroup);
     }
 }
Пример #2
0
        public static Coroutine StartCoroutine(object obj, IEnumerator coroutine,
                                               CoroutineGroup group, string tag = null, bool pool = Coroutine.PoolByDefault)
        {
            Coroutine result = null;

            // Let the caller do this check

            /*if (!FThreading.IsInGameThread())
             * {
             *  FThreading.RunOnGameThread(delegate () { result = StartCoroutine(obj, coroutine, group, tag, pool); });
             *  return result;
             * }*/

            if (pool)
            {
                result = CoroutinePool.New(coroutine);
            }
            else
            {
                result = new Coroutine(coroutine);
            }
            result.Owner = obj;
            result.Group = group;
            result.Tag   = tag;
            result.mainCollectionIndex = coroutines.Count;
            coroutines.Add(result);
            return(result);
        }
Пример #3
0
        public static Coroutine StartCoroutine(object obj, IEnumerator coroutine,
                                               CoroutineGroup group, string tag = null, bool pool = Coroutine.PoolByDefault)
        {
            Coroutine result = null;

            UObject ownerObj = obj as UObject;

            if (ownerObj != null)
            {
                IntPtr world = Native_UObject.GetWorld(ownerObj.Address);
                Debug.Assert(world != IntPtr.Zero, "UObject coroutines must be objects with a UWorld reference (e.g. AActor) - " +
                             "this is so that the coroutine can be stopped when the world is destroyed.");
            }

            // Let the caller do this check

            /*if (!FThreading.IsInGameThread())
             * {
             *  FThreading.RunOnGameThread(delegate () { result = StartCoroutine(obj, coroutine, group, tag, pool); });
             *  return result;
             * }*/

            if (pool)
            {
                result = CoroutinePool.New(coroutine);
            }
            else
            {
                result = new Coroutine(coroutine);
            }
            result.Owner = obj;
            result.Group = group;
            result.mainCollectionIndex = coroutines.Count;
            result.Tag = tag;
            coroutines.Add(result);

            if (ownerObj != null)
            {
                List <Coroutine> collection;
                if (!coroutinesByObject.TryGetValue(ownerObj, out collection))
                {
                    coroutinesByObject.Add(ownerObj, collection = new List <Coroutine>());
                }
                result.objectsCollectionIndex = collection.Count;
                collection.Add(result);
            }

            if (!string.IsNullOrEmpty(tag))
            {
                List <Coroutine> collection;
                if (!coroutinesByTag.TryGetValue(tag, out collection))
                {
                    coroutinesByTag.Add(tag, collection = new List <Coroutine>());
                }
                result.tagsCollectionIndex = collection.Count;
                collection.Add(result);
            }

            return(result);
        }
Пример #4
0
 // If the number of active coroutines is under the limit specified in the constructor, run the
 // given coroutine. Otherwise, queue it to be run when other coroutines finish.
 // coroutine: Coroutine group to run or place in a queue
 public void Run(CoroutineGroup coroutineGroup)
 {
     // verify if number of running coroutine groups is less then max allowed number
     if (numActive < maxActive)
     {
         Debug.Log("Run " + coroutineGroup.CoroutineGroupID);
         // create new coroutine group runner
         var runner = CoroutineGroupRunner(coroutineGroup);
         // run new coroutine
         coroutineStarter(runner);
     }
     else
     {
         // verify if group is not already in a queue
         if (GetCoroutineGroupFromQueueByID(coroutineGroup.CoroutineGroupID) == null)
         {
             Debug.Log("Queued " + coroutineGroup.CoroutineGroupID);
             queue.Enqueue(coroutineGroup);
         }
         else
         {
             Debug.Log(coroutineGroup.CoroutineGroupID + " group is already in a queue");
         }
     }
 }
Пример #5
0
        private IEnumerator isFinishedEmpty_VerifyTrue()
        {
            CoroutineGroup coroutineGroup = new CoroutineGroup();

            IntegrationTestEx.FailIf(!coroutineGroup.IsFinished);
            yield break;
        }
Пример #6
0
        internal static void ProcessCoroutines(CoroutineGroup group)
        {
            runningGroup = group;

            insideMainCoroutineLoop = true;
            for (int i = coroutines.Count - 1; i >= 0; --i)
            {
                Coroutine coroutine = coroutines[i];
                Debug.Assert(coroutine.mainCollectionIndex == i, "Coroutine main collection index is invalid");
                if (coroutine.CurrentGroup == group && !coroutine.Complete)
                {
                    coroutine.Process(group);
                }
                if (coroutine.Complete)
                {
                    CoroutineRemoveAtSwap(coroutine, true);
                }
            }
            insideMainCoroutineLoop = false;

            // Do we need some kind of while loop here? If a coroutine has been processed here
            // and gets added to a different comparable collection it wont be processed until
            // the next frame even if it would be completed in this frame. Possibly return
            // a bool in Process if it an item was removed from the collection and keep running
            // this loop until all Process calls return false?
            for (int i = comparableCollections.Count - 1; i >= 0; --i)
            {
                IComparableYieldInstructionCollection collection = comparableCollections[i];
                collection.Process(group);
            }

            runningGroup = CoroutineGroup.None;
        }
Пример #7
0
        internal WaitForGroup PoolNew(CoroutineGroup group, ulong skipTicks, uint skipFrames)
        {
            hasWaitForTicks  = false;
            hasWaitForFrames = false;

            Group = group;

            if (skipTicks > 0)
            {
                if (waitForTicks == null)
                {
                    waitForTicks = new WaitForTicks(skipTicks);
                }
                else
                {
                    waitForTicks.Ticks = skipTicks;
                }
                hasWaitForTicks = true;
            }
            if (skipFrames > 0)
            {
                if (waitForFrames == null)
                {
                    waitForFrames = new WaitForFrames(skipFrames);
                }
                else
                {
                    waitForFrames.Frames = skipFrames;
                }
                hasWaitForFrames = true;
            }

            return(this);
        }
Пример #8
0
        private bool ProcessCurrentInstruction(CoroutineGroup group)
        {
            if (CurrentInstruction != null)
            {
                if (!ProcessInstruction(CurrentInstruction, group))
                {
                    return(false);
                }
                CurrentInstruction = null;
            }

            while (injectedInstructionQueue != null && injectedInstructionQueue.Count > 0)
            {
                CurrentInstruction = injectedInstructionQueue.Dequeue();
                CurrentInstruction.Begin();
                IsCurrentInstructionInjected = true;
                if (!ProcessInstruction(CurrentInstruction, group))
                {
                    return(false);
                }
            }
            IsCurrentInstructionInjected = false;

            return(true);
        }
Пример #9
0
 private void addCoroutineToGroup(ICoroutine coroutine, CoroutineGroup group)
 {
     if (!coroutine.Disposed && !coroutine.Cancelled && !coroutine.Completed)
     {
         group.Add(coroutine);
     }
 }
Пример #10
0
        private static Invoker StartInvoker(object obj, InvokerHandlerType handlerType, Delegate handler, InvokerType type,
                                            ulong value, ulong repeatValue, CoroutineGroup group = CoroutineGroup.Tick, bool pool = PoolByDefault)
        {
            IntPtr  world    = IntPtr.Zero;
            UObject ownerObj = obj as UObject;

            if (ownerObj != null)
            {
                world = Native_UObject.GetWorld(ownerObj.Address);
                Debug.Assert(world != IntPtr.Zero, "UObject invokers must be objects with a UWorld reference (e.g. AActor) - " +
                             "this is so that the invoker can be stopped when the world is destroyed.");
            }

            Invoker invoker = pool ? InvokerPool.GetObject() : new Invoker();

            invoker.OwnerWorld = world;
            invoker.Owner      = obj;
            invoker.SetHandler(handlerType, handler);
            switch (type)
            {
            case InvokerType.Delay:
                TimeSpan time       = TimeSpan.FromTicks((long)value);
                TimeSpan repeatTime = TimeSpan.FromTicks((long)repeatValue);
                if (repeatTime != default(TimeSpan))
                {
                    invoker.SetTime(time, repeatTime);
                }
                else
                {
                    invoker.SetTime(time);
                }
                break;

            case InvokerType.Ticks:
                if (repeatValue != default(ulong))
                {
                    invoker.SetTicks(value, repeatValue);
                }
                else
                {
                    invoker.SetTicks(value);
                }
                break;

            case InvokerType.Frames:
                if (repeatValue != default(ulong))
                {
                    invoker.SetFrames(value, repeatValue);
                }
                else
                {
                    invoker.SetFrames(value);
                }
                break;
            }
            invoker.SetGroup(group);
            invoker.Start();
            return(invoker);
        }
Пример #11
0
        private IEnumerator isFinished_VerifyFalse()
        {
            CoroutineGroup coroutineGroup = new CoroutineGroup();

            coroutineGroup.StartAndAdd(testerCoroutine(), this, "testerCoroutineEmptyEnumator");
            IntegrationTestEx.FailIf(coroutineGroup.IsFinished);
            yield break;
        }
Пример #12
0
        private IEnumerator isFinished_VerifyTrue()
        {
            CoroutineGroup group = new CoroutineGroup();

            yield return(group.StartAndAdd(testerCoroutine(), this, "testerCoroutineEmptyEnumator"));

            IntegrationTestEx.FailIf(!group.IsFinished);
        }
    void OnEnable()
    {
        mCoroutineGroup = CoroutineHelper.Factory.CreateCoroutineGroup();

        for (int i = 0; i < 20; i++)
        {
            mCoroutineGroup.StartCoroutine(Foo());
        }
    }
Пример #14
0
 private bool ProcessInstruction(YieldInstruction instruction, CoroutineGroup group)
 {
     if (CurrentGroup != group || instruction.KeepWaiting)
     {
         return(false);
     }
     instruction.End();
     ReleaseInstruction(instruction);
     return(true);
 }
Пример #15
0
 // Create the queue, initially with no coroutine groups
 // maxActive:
 // Maximum number of coroutines to run at once. This must be at least one.
 // coroutineStarter:
 // Delegate to start coroutines with. Normally you'd pass
 // MonoBehaviour.StartCoroutinefor this.
 // Exception ArgumentException if maxActive is zero.
 public CoroutineGroupQueue(uint maxActive, Func <IEnumerator, Coroutine> coroutineStarter)
 {
     if (maxActive == 0)
     {
         throw new ArgumentException("Must be at least one", "maxActive");
     }
     this.maxActive        = maxActive;
     this.coroutineStarter = coroutineStarter;
     queue = new Queue <CoroutineGroup>();
     runningCoroutineGroup = null;
 }
        private void OnGroupChanged(T instruction, CoroutineGroup oldGroup, CoroutineGroup newGroup)
        {
            UnrealBinaryHeapEx <T> oldCollection = GetCollection(oldGroup);
            UnrealBinaryHeapEx <T> newCollection = GetCollection(newGroup);

            if (oldCollection != null && newCollection != null && oldCollection != newCollection)
            {
                oldCollection.HeapRemove(instruction);
                newCollection.HeapPush(instruction);
            }
        }
Пример #17
0
        private static InvokerCollectionGroup GetInvokerGroup(CoroutineGroup group)
        {
            switch (group)
            {
            case CoroutineGroup.Tick: return(tickInvokers);

            case CoroutineGroup.BeginFrame: return(beginFrameInvokers);

            case CoroutineGroup.EndFrame: return(endFrameInvokers);
            }
            return(null);
        }
Пример #18
0
        public void Process(CoroutineGroup group)
        {
            if (IsPaused)
            {
                return;
            }

            if (!ProcessCurrentInstruction(group))
            {
                return;
            }

            if (Enumerator == null)
            {
                FMessage.Log(ELogVerbosity.Error, "Coroutine enumerator is null");
                Stop();
                return;
            }

            try
            {
                while (Enumerator.MoveNext())
                {
                    object           current     = Enumerator.Current;
                    YieldInstruction instruction = current as YieldInstruction;
                    if (instruction != null)
                    {
                        CurrentInstruction       = instruction;
                        CurrentInstruction.Owner = this;
                        CurrentInstruction.Begin();

                        if (!ProcessCurrentInstruction(group))
                        {
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                FMessage.Log(ELogVerbosity.Error, "Exception when running coroutine. " + Environment.NewLine + e.ToString());
                Stop();
                return;
            }

            Complete = true;
        }
Пример #19
0
    private IEnumerator loadIconsForTubeDefinition(TubeDefinition tubeDefinition)
    {
        CoroutineGroup coroutineGroup = new CoroutineGroup();

        addCoroutineToGroup(CoroutineRunner.Start(loadIcon(0, tubeDefinition.ButtonIconKeyDisabled.Key), this, ""), coroutineGroup);
        addCoroutineToGroup(CoroutineRunner.Start(loadIcon(1, tubeDefinition.ButtonIconKeyOff.Key), this, ""), coroutineGroup);
        addCoroutineToGroup(CoroutineRunner.Start(loadIcon(2, tubeDefinition.ButtonIconKeyOn.Key), this, ""), coroutineGroup);
        addCoroutineToGroup(CoroutineRunner.Start(loadIcon(3, tubeDefinition.ButtonIconKeyOn.Key), this, ""), coroutineGroup);
        while (!coroutineGroup.IsFinished)
        {
            yield return(null);
        }
        coroutineGroup.Clear();
        trayInputButton.Icon.sprite = trayInputButton.IconSprite.Sprites[(int)trayInputButton.CurrentViewState];
    }
Пример #20
0
        public WaitForGroup(CoroutineGroup group, ulong skipTicks = 0, uint skipFrames = 0)
        {
            Group = group;

            if (skipTicks > 0)
            {
                waitForTicks    = new WaitForTicks(skipTicks);
                hasWaitForTicks = true;
            }
            if (skipFrames > 0)
            {
                waitForFrames    = new WaitForFrames(skipFrames);
                hasWaitForFrames = true;
            }
        }
        private UnrealBinaryHeapEx <T> GetCollection(CoroutineGroup group)
        {
            switch (group)
            {
            case CoroutineGroup.Tick:
                return(tick);

            case CoroutineGroup.BeginFrame:
                return(beginFrame);

            case CoroutineGroup.EndFrame:
                return(endFrame);

            default: return(null);
            }
        }
Пример #22
0
        private static Invoker StartInvoker(object obj, InvokerHandlerType handlerType, Delegate handler, InvokerType type,
                                            ulong value, ulong repeatValue, CoroutineGroup group = CoroutineGroup.Tick, bool pool = PoolByDefault)
        {
            Invoker invoker = pool ? InvokerPool.GetObject() : new Invoker();

            invoker.SetHandler(handlerType, handler);
            switch (type)
            {
            case InvokerType.Delay:
                TimeSpan time       = TimeSpan.FromTicks((long)value);
                TimeSpan repeatTime = TimeSpan.FromTicks((long)repeatValue);
                if (repeatTime != default(TimeSpan))
                {
                    invoker.SetTime(time, repeatTime);
                }
                else
                {
                    invoker.SetTime(time);
                }
                break;

            case InvokerType.Ticks:
                if (repeatValue != default(ulong))
                {
                    invoker.SetTicks(value, repeatValue);
                }
                else
                {
                    invoker.SetTicks(value);
                }
                break;

            case InvokerType.Frames:
                if (repeatValue != default(ulong))
                {
                    invoker.SetFrames(value, repeatValue);
                }
                else
                {
                    invoker.SetFrames(value);
                }
                break;
            }
            invoker.SetGroup(group);
            invoker.Start();
            return(invoker);
        }
        public void Process(CoroutineGroup group)
        {
            UnrealBinaryHeapEx <T> collection = GetCollection(group);

            while (collection.Count > 0)
            {
                T instruction = collection.HeapTop();
                if (instruction.KeepWaiting)
                {
                    return;
                }
                collection.HeapPopDiscard();

                // Return the control over to the main coroutines collection
                instruction.comparableCollection = null;
                Coroutine.ComparableEnd(instruction.Owner);
            }
        }
        private IEnumerator loadWidgets(List <CellPhoneActivityDefinition> widgetDatas)
        {
            CoroutineGroup coroutineGroup = new CoroutineGroup();
            Dictionary <CellPhoneActivityDefinition, GameObject> widgetDataToPrefab = new Dictionary <CellPhoneActivityDefinition, GameObject>();

            for (int i = 0; i < widgetDatas.Count; i++)
            {
                ICoroutine coroutine = CoroutineRunner.Start(loadWidget(widgetDatas[i], widgetDataToPrefab), this, "loadWidget");
                if (!coroutine.Disposed && !coroutine.Cancelled && !coroutine.Completed)
                {
                    coroutineGroup.Add(coroutine);
                }
            }
            while (!coroutineGroup.IsFinished)
            {
                yield return(null);
            }
            instantiateWidgets(widgetDatas, widgetDataToPrefab);
        }
Пример #25
0
        private IEnumerator clear_VerifyDidNotCancel()
        {
            CoroutineGroup group           = new CoroutineGroup();
            bool           testerDidFinish = false;
            bool           testerDidCancel = false;
            ICoroutine     coroutine       = group.StartAndAdd(testerCoroutine(), this, "testerCoroutine");

            coroutine.ECompleted += delegate
            {
                testerDidFinish = true;
            };
            coroutine.ECancelled += delegate
            {
                testerDidCancel = true;
            };
            group.Clear();
            yield return(coroutine);

            IntegrationTestEx.FailIf(testerDidCancel);
            IntegrationTestEx.FailIf(!testerDidFinish);
        }
Пример #26
0
 public CoroutineGroup GetCoroutineGroupByID(string coroutineGroupID)
 {
     // verify if coroutine group ID is empty
     if (coroutineGroupID == null)
     {
         // create new random group id
         coroutineGroupID = Guid.NewGuid().ToString();
         // create and return new coroutine group
         return(new CoroutineGroup(coroutineGroupID, coroutineStarter));
     }
     else
     {
         // verify if running coroutine group is not null
         if (runningCoroutineGroup != null)
         {
             // verify if this not already running coroutin group
             // Note running coroutine group is already removed from queue, so you will not be able to find it there
             if (runningCoroutineGroup.CoroutineGroupID == coroutineGroupID)
             {
                 // return reference to the running coroutine group
                 return(runningCoroutineGroup);
             }
         }
         // if we are still here..
         // try to get coroutine group by its ID from a queue
         CoroutineGroup coroutineGroup = GetCoroutineGroupFromQueueByID(coroutineGroupID);
         // verify if coroutine group is null
         if (coroutineGroup == null)
         {
             // create new coroutine group with defined ID
             return(new CoroutineGroup(coroutineGroupID, coroutineStarter));
         }
         else
         {
             // return reference to existing coroutine group from queue
             return(coroutineGroup);
         }
     }
 }
Пример #27
0
    // Run corotine with defined or not defined group ID
    public void Run(IEnumerator coroutine, string coroutineGroupID = null)
    {
        if (coroutineGroupID != null)
        {
            Debug.Log("Running " + coroutine.ToString() + " coroutine with " + coroutineGroupID + " group ID");
        }
        else
        {
            Debug.Log("Running " + coroutine.ToString() + " coroutine ");
        }
        // init coroutineGroup variable
        CoroutineGroup coroutineGroup = GetCoroutineGroupByID(coroutineGroupID);

        // add coroutine to the group
        coroutineGroup.Add(coroutine);
        // verify if coroutine group is not already running
        if (!coroutineGroup.IsRunning)
        {
            // try to run Coroutine group
            Run(coroutineGroup);
        }
    }
Пример #28
0
        private IEnumerator startAndAddMultiple_VerifyDidComplete()
        {
            CoroutineGroup group            = new CoroutineGroup();
            bool           tester1DidFinish = false;
            bool           tester1DidCancel = false;
            bool           tester2DidFinish = false;
            bool           tester2DidCancel = false;
            ICoroutine     coroutine1       = group.StartAndAdd(testerCoroutine(), this, "testerCoroutine1");
            ICoroutine     coroutine2       = group.StartAndAdd(testerCoroutine(), this, "testerCoroutine2");

            coroutine1.ECompleted += delegate
            {
                tester1DidFinish = true;
            };
            coroutine1.ECancelled += delegate
            {
                tester1DidCancel = true;
            };
            coroutine2.ECompleted += delegate
            {
                tester2DidFinish = true;
            };
            coroutine2.ECancelled += delegate
            {
                tester2DidCancel = true;
            };
            IntegrationTestEx.FailIf(!group.Contains(coroutine1));
            IntegrationTestEx.FailIf(!group.Contains(coroutine2));
            while (!group.IsFinished)
            {
                yield return(null);
            }
            IntegrationTestEx.FailIf(!tester1DidFinish);
            IntegrationTestEx.FailIf(tester1DidCancel);
            IntegrationTestEx.FailIf(!tester2DidFinish);
            IntegrationTestEx.FailIf(tester2DidCancel);
            IntegrationTestEx.FailIf(group.Contains(coroutine1));
            IntegrationTestEx.FailIf(group.Contains(coroutine2));
        }
Пример #29
0
        private IEnumerator add_VerifyDoesContainAndDidFinish()
        {
            CoroutineGroup group           = new CoroutineGroup();
            bool           testerDidFinish = false;
            bool           testerDidCancel = false;
            ICoroutine     coroutine       = CoroutineRunner.Start(testerCoroutine(), this, "testerCoroutine");

            coroutine.ECompleted += delegate
            {
                testerDidFinish = true;
            };
            coroutine.ECancelled += delegate
            {
                testerDidCancel = true;
            };
            IntegrationTestEx.FailIf(group.Contains(coroutine));
            group.Add(coroutine);
            IntegrationTestEx.FailIf(!group.Contains(coroutine));
            yield return(coroutine);

            IntegrationTestEx.FailIf(group.Contains(coroutine));
            IntegrationTestEx.FailIf(!testerDidFinish);
            IntegrationTestEx.FailIf(testerDidCancel);
        }
Пример #30
0
        private IEnumerator remove_VerifyDoesNotContain()
        {
            CoroutineGroup group           = new CoroutineGroup();
            bool           testerDidFinish = false;
            bool           testerDidCancel = false;
            ICoroutine     coroutine       = group.StartAndAdd(testerCoroutine(), this, "testerCoroutine");

            coroutine.ECompleted += delegate
            {
                testerDidFinish = true;
            };
            coroutine.ECancelled += delegate
            {
                testerDidCancel = true;
            };
            IntegrationTestEx.FailIf(!group.Contains(coroutine));
            group.Remove(coroutine);
            IntegrationTestEx.FailIf(group.Contains(coroutine));
            yield return(coroutine);

            IntegrationTestEx.FailIf(!testerDidFinish);
            IntegrationTestEx.FailIf(testerDidCancel);
            IntegrationTestEx.FailIf(group.Contains(coroutine));
        }