Example #1
0
 public static void StopRoutines(FlushingOperation
                                 flushingOperation)
 {
     //note: _coroutines will be cleaned by the single tasks stopping silently. in this way they will be put
     //back to the pool. Let's be sure that the runner had the time to stop and recycle the previous tasks
     flushingOperation.stopped = true;
 }
Example #2
0
 public Process(ThreadSafeQueue <T> newTaskRoutines, FasterList <T> coroutines,
                FlushingOperation flushingOperation, TRunningInfo info)
 {
     _newTaskRoutines   = newTaskRoutines;
     _coroutines        = coroutines;
     _flushingOperation = flushingOperation;
     _info = info;
 }
Example #3
0
 internal static IEnumerator Process(ThreadSafeQueue <IPausableTask> newTaskRoutines,
                                     FasterList <IPausableTask> coroutines,
                                     FlushingOperation flushingOperation,
                                     RunningTasksInfo info,
                                     FlushTasksDel flushTaskDel)
 {
     return(Process(newTaskRoutines, coroutines,
                    flushingOperation, info, flushTaskDel, null, null));
 }
 protected static void NewFlushTasks(
     ThreadSafeQueue <PausableTask> newTaskRoutines,
     FasterList <PausableTask> coroutines, FlushingOperation flushingOperation)
 {
     if (newTaskRoutines.Count > 0)
     {
         newTaskRoutines.DequeueInto(coroutines, Mathf.CeilToInt(newTaskRoutines.Count / ((FlushingOperationStaggered)flushingOperation).framesLength));
     }
 }
 public HandItToUnity(object current,
                      IPausableTask task,
                      Action <IPausableTask> resumeOperation,
                      FlushingOperation flush)
 {
     _current           = current;
     _task              = task;
     _resumeOperation   = resumeOperation;
     _isDone            = false;
     _flushingOperation = flush;
 }
 public Process(ThreadSafeQueue <IPausableTask> newTaskRoutines,
                FasterList <IPausableTask> coroutines,
                FlushingOperation flushingOperation,
                RunningTasksInfo info,
                FlushTasksDel flushTaskDel,
                RunnerBehaviour runnerBehaviourForUnityCoroutine = null,
                Action <IPausableTask> resumeOperation           = null)
 {
     this._newTaskRoutines   = newTaskRoutines;
     this._coroutines        = coroutines;
     this._flushingOperation = flushingOperation;
     this._info         = info;
     this._flushTaskDel = flushTaskDel;
     this._runnerBehaviourForUnityCoroutine = runnerBehaviourForUnityCoroutine;
     this._resumeOperation = resumeOperation;
 }
Example #7
0
 public Process(ThreadSafeQueue <IPausableTask> newTaskRoutines,
                FasterList <IPausableTask> coroutines,
                FlushingOperation flushingOperation,
                RunningTasksInfo info,
                FlushTasksDel flushTaskDel,
                RunnerBehaviour runnerBehaviourForUnityCoroutine = null,
                Action <IPausableTask> resumeOperation           = null)
 {
     _newTaskRoutines   = newTaskRoutines;
     _coroutines        = coroutines;
     _flushingOperation = flushingOperation;
     _info         = info;
     _flushTaskDel = flushTaskDel;
     _runnerBehaviourForUnityCoroutine = runnerBehaviourForUnityCoroutine;
     _resumeOperation  = resumeOperation;
     _platformProfiler = new Svelto.Common.PlatformProfiler(_info.runnerName);
 }
Example #8
0
        protected static void InternalThreadUnsafeStartCoroutine(PausableTask task, ThreadSafeQueue <PausableTask> newTaskRoutines, FlushingOperation flushingOperation)
        {
            if (task == null || (flushingOperation.stopped == false && task.MoveNext() == false))
            {
                return;
            }

            newTaskRoutines.Enqueue(task); //careful this could run on another thread!
        }
Example #9
0
        static IEnumerator HandItToUnity(object current, PausableTask task, ThreadSafeQueue <PausableTask> newTaskRoutines, FlushingOperation flushingOperation)
        {
            yield return(current);

            InternalThreadUnsafeStartCoroutine(task, newTaskRoutines, flushingOperation);
        }
Example #10
0
        protected static IEnumerator CoroutinesRunner(ThreadSafeQueue <PausableTask> newTaskRoutines,
                                                      FasterList <PausableTask> coroutines, FlushingOperation flushingOperation, RunningTasksInfo info,
                                                      FlushTasksDel flushTaskDel, RunnerBehaviour runnerBehaviourForUnityCoroutine = null)
        {
            while (true)
            {
                if (flushingOperation.waitForflush == false) //don't start anything while flushing
                {
                    flushTaskDel(newTaskRoutines, coroutines, flushingOperation);
                }

                info.count = coroutines.Count;

                for (int i = 0; i < info.count; i++)
                {
                    var enumerator = coroutines[i];

                    try
                    {
                        //let's spend few words about this. Special YieldInstruction can be only processed internally
                        //by Unity. The simplest way to handle them is to hand them to Unity itself.
                        //However while the Unity routine is processed, the rest of the coroutine is waiting for it.
                        //This would defeat the purpose of the parallel procedures. For this reason, the Parallel
                        //routines will mark the enumerator returned as ParallelYield which will change the way the routine is processed.
                        //in this case the MonoRunner won't wait for the Unity routine to continue processing the next tasks.
                        var          current            = enumerator.Current;
                        PausableTask enumeratorToHandle = null;
                        var          yield = current as ParallelYield;
                        if (yield != null)
                        {
                            current = yield.Current;
                        }
                        else
                        {
                            enumeratorToHandle = enumerator;
                        }

                        if (runnerBehaviourForUnityCoroutine != null)
                        {
                            if (current is YieldInstruction || current is AsyncOperation)
                            {
                                runnerBehaviourForUnityCoroutine.StartCoroutine(HandItToUnity(current, enumeratorToHandle, newTaskRoutines, flushingOperation));

                                if (enumeratorToHandle != null)
                                {
                                    coroutines.UnorderredRemoveAt(i--);

                                    info.count = coroutines.Count;

                                    continue;
                                }
                            }
                        }

                        bool result;
#if TASKS_PROFILER_ENABLED && UNITY_EDITOR
                        result = Tasks.Profiler.TaskProfiler.MonitorUpdateDuration(enumerator);
#else
                        result = enumerator.MoveNext();
#endif
                        if (result == false)
                        {
                            var disposable = enumerator as IDisposable;
                            if (disposable != null)
                            {
                                disposable.Dispose();
                            }

                            coroutines.UnorderredRemoveAt(i--);
                        }
                    }
                    catch (Exception e)
                    {
                        string message = "Coroutine Exception: ";

                        Utility.Console.LogException(new CoroutineException(message, e));

                        coroutines.UnorderredRemoveAt(i--);
                    }

                    info.count = coroutines.Count;
                }

                if (flushingOperation.waitForflush == true && coroutines.Count == 0)
                {  //this process is more complex than I like, not 100% sure it covers all the cases yet
                    flushingOperation.waitForflush = false;
                    flushingOperation.stopped      = false;
                }

                yield return(null);
            }
        }
Example #11
0
 protected static void FlushTasks(ThreadSafeQueue <PausableTask> newTaskRoutines, FasterList <PausableTask> coroutines, FlushingOperation flushingOperation)
 {
     if (newTaskRoutines.Count > 0)
     {
         newTaskRoutines.DequeueAllInto(coroutines);
     }
 }
Example #12
0
 public static void KillProcess(FlushingOperation flushingOperation)
 {
     flushingOperation.kill = true;
 }
 public static void StandardTasksFlushing(ThreadSafeQueue <IPausableTask> newTaskRoutines,
                                          FasterList <IPausableTask> coroutines, FlushingOperation flushingOperation)
 {
     if (newTaskRoutines.Count > 0)
     {
         newTaskRoutines.DequeueAllInto(coroutines);
     }
 }
Example #14
0
        internal static IEnumerator Process(
            ThreadSafeQueue <IPausableTask> newTaskRoutines,
            FasterList <IPausableTask> coroutines,
            FlushingOperation flushingOperation,
            RunningTasksInfo info,
            FlushTasksDel flushTaskDel,
            RunnerBehaviour runnerBehaviourForUnityCoroutine,
            Action <IPausableTask>
            resumeOperation)
        {
            while (true)
            {
                if (false == flushingOperation.stopped) //don't start anything while flushing
                {
                    flushTaskDel(newTaskRoutines, coroutines, flushingOperation);
                }
                else
                if (runnerBehaviourForUnityCoroutine != null)
                {
                    runnerBehaviourForUnityCoroutine.StopAllCoroutines();
                }

                info.count = coroutines.Count;

                for (var i = 0; i < info.count; i++)
                {
                    var pausableTask = coroutines[i];

                    //let's spend few words on this.
                    //yielded YieldInstruction and AsyncOperation can
                    //only be processed internally by Unity.
                    //The simplest way to handle them is to hand them to Unity itself.
                    //However while the Unity routine is processed, the rest of the
                    //coroutine is waiting for it. This would defeat the purpose
                    //of the parallel procedures. For this reason, a Parallel
                    //task will mark the enumerator returned as ParallelYield which
                    //will change the way the routine is processed.
                    //in this case the MonoRunner won't wait for the Unity routine
                    //to continue processing the next tasks.
                    //Note that it is much better to return wrap AsyncOperation around
                    //custom IEnumerator classes then returning them directly as
                    //most of the time they don't need to be handled by Unity as
                    //YieldInstructions do

                    ///
                    /// Handle special Unity instructions
                    /// you should avoid them or wrap them
                    /// around custom IEnumerator to avoid
                    /// the cost of two allocations per instruction
                    ///

                    if (runnerBehaviourForUnityCoroutine != null &&
                        flushingOperation.stopped == false)
                    {
                        var current = pausableTask.Current;

                        if (current is YieldInstruction)
                        {
                            var handItToUnity = new HandItToUnity
                                                    (current, pausableTask, resumeOperation, flushingOperation);

                            //remove the special instruction. it will
                            //be added back once Unity completes.
                            coroutines.UnorderedRemoveAt(i--);

                            info.count = coroutines.Count;

                            var coroutine = runnerBehaviourForUnityCoroutine.StartCoroutine
                                                (handItToUnity.GetEnumerator());

                            (pausableTask as PausableTask).onExplicitlyStopped = () =>
                            {
                                runnerBehaviourForUnityCoroutine.StopCoroutine(coroutine);
                                handItToUnity.ForceStop();
                            };

                            continue;
                        }

                        var parallelTask = (current as ParallelTaskCollection.ParallelTask);

                        if (parallelTask != null &&
                            parallelTask.current is YieldInstruction)
                        {
                            var handItToUnity = new HandItToUnity(parallelTask.current);

                            parallelTask.Add(handItToUnity.WaitUntilIsDone());

                            var coroutine = runnerBehaviourForUnityCoroutine.StartCoroutine
                                                (handItToUnity.GetEnumerator());

                            (pausableTask as PausableTask).onExplicitlyStopped = () =>
                            {
                                runnerBehaviourForUnityCoroutine.StopCoroutine(coroutine);
                                handItToUnity.ForceStop();
                            };
                        }
                    }

                    bool result;
#if TASKS_PROFILER_ENABLED && UNITY_EDITOR
                    result = TASK_PROFILER.MonitorUpdateDuration(pausableTask, info.runnerName);
#else
                    result = pausableTask.MoveNext();
#endif
                    if (result == false)
                    {
                        var disposable = pausableTask as IDisposable;
                        if (disposable != null)
                        {
                            disposable.Dispose();
                        }

                        coroutines.UnorderedRemoveAt(i--);
                    }

                    info.count = coroutines.Count;
                }

                if (flushingOperation.stopped == true && coroutines.Count == 0)
                {   //once all the coroutines are flushed
                    //the loop can return accepting new tasks
                    flushingOperation.stopped = false;
                }

                yield return(null);
            }
        }