예제 #1
0
        void IPoolable.OnDespawned()
        {
            var poolableYieldInstruction = Enumerator as IPoolableYieldInstruction;

            if (poolableYieldInstruction != null)
            {
                poolableYieldInstruction.Despawn();
            }

            Id         = -1;
            IsDone     = false;
            UpdateLoop = UpdateLoop.Update;
            Enumerator = null;
            Parent     = null;
            Child      = null;

            WaitTillTime         = float.MinValue;
            WaitTimeIsUnscaled   = false;
            WaitingForEndOfFrame = false;

            LinkedObject        = null;
            LinkedComponent     = null;
            IsLinkedToObject    = false;
            IsLinkedToComponent = false;
        }
예제 #2
0
        private static void Start(BetterCoroutine coroutine)
        {
            var scaledTime   = GetTime(coroutine.UpdateLoop, false);
            var unscaledTime = GetTime(coroutine.UpdateLoop, true);

            var continueRunning = UpdateCoroutine(scaledTime, unscaledTime, coroutine);

            if (!continueRunning)
            {
                PoolHelper <BetterCoroutine> .Despawn(coroutine);

                return;
            }

            IdToCoroutine[coroutine.Id] = coroutine;

            var list = GetList(coroutine.UpdateLoop);

            if (_current != null && _current.List == list.BackingList)
            {
                list.AddBefore(_current, coroutine);
            }
            else
            {
                list.AddFirst(coroutine);
            }
        }
예제 #3
0
        private static void StartChild(IEnumerator enumerator, BetterCoroutine parent)
        {
            var child = SpawnCoroutine(enumerator, parent.UpdateLoopId);

            child.Parent = parent;
            parent.Child = child;
            Start(child);
        }
예제 #4
0
        private static void Stop(BetterCoroutine coroutine)
        {
            if (coroutine.IsDone)
            {
                return;
            }

            if (coroutine.Parent != null)
            {
                coroutine.Parent.Child = null;
            }

            while (coroutine != null)
            {
                coroutine.IsDone = true;
                coroutine        = coroutine.Child;
            }
        }
예제 #5
0
        private static void Start(BetterCoroutine coroutine)
        {
            var scaledTime   = GetTime(coroutine.UpdateLoopId, false);
            var unscaledTime = GetTime(coroutine.UpdateLoopId, true);

            IdToCoroutine[coroutine.Id] = coroutine;

            var list = GetList(coroutine.UpdateLoopId);

            if (list == null)
            {
                UpdateLoopToCoroutines[coroutine.UpdateLoopId] = list = new PooledLinkedList <BetterCoroutine>(SharedNodePool);
                ManagedUpdate.AddListener(coroutine.UpdateLoopId, Instance);
            }

            var node = list.AddFirst(coroutine);

            var prevCurrent = _current;

            _current = node;

            var continueRunning = UpdateCoroutine(scaledTime, unscaledTime, coroutine);

            if (!continueRunning)
            {
                IdToCoroutine.Remove(coroutine.Id);
                list.Remove(coroutine);
                if (coroutine.Parent != null)
                {
                    coroutine.Parent.Child = null;
                }
                PoolHelper <BetterCoroutine> .Despawn(coroutine);
            }

            _current = prevCurrent;
        }
예제 #6
0
        // this method has gotten out of hand..
        private static bool UpdateCoroutine(float scaledTime, float unscaledTime, BetterCoroutine coroutine)
        {
            if (coroutine.IsDone)
            {
                return(false);
            }

            if (coroutine.IsLinkedToObject && (!coroutine.LinkedObject || !coroutine.LinkedObject.activeInHierarchy))
            {
                return(false);
            }

            if (coroutine.IsLinkedToComponent && (!coroutine.LinkedComponent || !coroutine.LinkedComponent.isActiveAndEnabled))
            {
                return(false);
            }

            if (coroutine.IsPaused || coroutine.IsParentPaused)
            {
                return(true);
            }

            if (coroutine.Child != null)
            {
                return(true);
            }

            if (coroutine.WaitingForEndOfFrame)
            {
                return(true);
            }

            var time = coroutine.WaitTimeIsUnscaled ? unscaledTime : scaledTime;

            if (coroutine.WaitTillTime > time)
            {
                return(true);
            }

            var enumerator = coroutine.Enumerator;

            try
            {
                if (!enumerator.MoveNext())
                {
                    return(false);
                }
            }
            catch (Exception e)
            {
                // something bad happened in the coroutine, just print out the error and stop the problematic routine.
                // todo: should this stop parent coroutines as well?
                Debug.LogError(e);
                return(false);
            }

            var current = enumerator.Current;

            if (current == null)
            {
                return(true);
            }

            var subroutineId = current as int?;

            if (subroutineId != null)
            {
                var subroutine = IdToCoroutine[subroutineId.Value];

                if (subroutine != null)
                {
                    coroutine.Child   = subroutine;
                    subroutine.Parent = coroutine;
                }
                return(true);
            }

            var subEnumerator = current as IEnumerator;

            if (subEnumerator != null)
            {
                StartChild(subEnumerator, coroutine);
                return(true);
            }

            var waitForSeconds = current as WaitForSecondsLite;

            if (waitForSeconds != null)
            {
                time = waitForSeconds.Unscaled ? unscaledTime : scaledTime;
                coroutine.WaitTimeIsUnscaled = waitForSeconds.Unscaled;
                coroutine.WaitTillTime       = time + waitForSeconds.Duration;
                return(true);
            }

            if (current is WaitForEndOfFrame)
            {
                coroutine.WaitingForEndOfFrame = true;
                CoroutinesWaitingForEndOfFrame.AddFirst(coroutine);
                return(true);
            }

            var www = current as WWW;

            if (www != null)
            {
                if (!www.isDone)
                {
                    StartChild(Coroutines.WaitForWWW.Create(www), coroutine);
                }
                return(true);
            }

            var asyncOperation = current as AsyncOperation;

            if (asyncOperation != null)
            {
                if (!asyncOperation.isDone)
                {
                    StartChild(Coroutines.WaitForAsyncOperation.Create(asyncOperation), coroutine);
                }
                return(true);
            }

            // we could use reflection, but it's slow and users really should switch over.
            if (current is WaitForSeconds)
            {
                Debug.LogError("UnityEngine.WaitForSeconds is not supported in BetterCoroutines. Please use BetterCoroutines.WaitForSeconds() instead.");
            }

            return(true);
        }