Пример #1
0
        /// <summary>
        /// Sets up a Fiber to run with the given host and routine.
        /// </summary>
        public Routine Initialize(MonoBehaviour inHost, IEnumerator inStart, bool inChained)
        {
            if (Manager.DebugMode && !(inStart is IDisposable))
            {
                throw new ArgumentException("IEnumerators must also implement IDisposable.");
            }

            m_Counter = (byte)(m_Counter == byte.MaxValue ? 1 : m_Counter + 1);

            m_Handle = (Routine)Table.GenerateID(Index, m_Counter);
            m_Host   = inHost;

            m_HostIdentity = RoutineIdentity.Find(m_Host.gameObject);

            m_WaitTime = 0;

            m_UnityWait = null;
            m_Name      = null;
            Priority    = 0;

            m_GroupMask = ReferenceEquals(m_HostIdentity, null) ? 0 : 1 << m_HostIdentity.Group;

            // Chained routines are always hosted on the manager
            if (inChained)
            {
                m_Chained = m_HostedByManager = true;
            }

            if (!inChained && ReferenceEquals(inHost, Manager))
            {
                m_HostedByManager = true;
            }

            if (!ReferenceEquals(m_HostIdentity, null))
            {
                m_HasIdentity = true;
            }

            m_TimeScale = 1.0f;

            m_RootFunction = inStart;
            m_Stack[m_StackPosition = 0] = inStart;

            IRoutineEnumerator callback = inStart as IRoutineEnumerator;

            if (callback != null)
            {
                if (!callback.OnRoutineStart())
                {
                    ClearStack();
                    Stop();
                }
            }

            return(m_Handle);
        }
Пример #2
0
        /// <summary>
        /// Runs the Fiber one frame.
        /// Will dispose itself if requested.
        /// Returns if still running.
        /// </summary>
        public bool Run()
        {
            if ((uint)m_Handle == 0)
            {
                return(false);
            }

            if (m_Disposing || (!m_HostedByManager && !m_Host))
            {
                Dispose();
                return(false);
            }

            if (IsPaused() || m_UnityWait != null)
            {
                return(true);
            }

            ApplyDeltaTime();

            if (m_WaitTime > 0)
            {
                m_WaitTime -= Manager.Frame.DeltaTime;
                if (m_WaitTime > 0)
                {
                    return(true);
                }
            }

            IEnumerator current    = m_Stack[m_StackPosition];
            bool        bMovedNext = current.MoveNext();

            // Don't check for the object being destroyed.
            // Destroy won't go into effect until after
            // all the Fibers are done processing anyways.
            if (m_Disposing)
            {
                Dispose();
                return(false);
            }

            if (bMovedNext)
            {
                object result = current.Current;
                if (result == null)
                {
                    return(true);
                }

                IntPtr resultType = result.GetType().TypeHandle.Value;

                // Check all the easy-to-identify result types

                if (resultType == TYPEHANDLE_INT)
                {
                    m_WaitTime = (int)result;
                    return(true);
                }

                if (resultType == TYPEHANDLE_FLOAT)
                {
                    m_WaitTime = (float)result;
                    return(true);
                }

                if (resultType == TYPEHANDLE_ROUTINE)
                {
                    IEnumerator waitSequence = ((Routine)result).Wait();
                    if (waitSequence != null)
                    {
                        if (m_StackPosition == m_StackSize - 1)
                        {
                            Array.Resize(ref m_Stack, m_StackSize *= 2);
                        }
                        m_Stack[++m_StackPosition] = waitSequence;
                    }
                    return(true);
                }

                if (resultType == TYPEHANDLE_WWW)
                {
                    m_UnityWait = Manager.Host.StartCoroutine(UnityWait((WWW)result));
                    return(true);
                }

                if (resultType == TYPEHANDLE_COMMAND)
                {
                    Routine.Command c = (Routine.Command)result;
                    switch (c)
                    {
                    case Routine.Command.Pause:
                        Pause();
                        return(true);

                    case Routine.Command.Stop:
                        Stop();
                        Dispose();
                        return(false);
                    }
                    return(true);
                }

                // Check for the subclassable types

                CustomYieldInstruction customInstruction = result as CustomYieldInstruction;
                if (customInstruction != null)
                {
                    m_UnityWait = Manager.Host.StartCoroutine(UnityWait(customInstruction));
                    return(true);
                }

                YieldInstruction instruction = result as YieldInstruction;
                if (instruction != null)
                {
                    m_UnityWait = Manager.Host.StartCoroutine(UnityWait(instruction));
                    return(true);
                }

                IEnumerator enumerator = result as IEnumerator;
                if (enumerator != null)
                {
                    // Check if we need to resize the stack
                    if (m_StackPosition == m_StackSize - 1)
                    {
                        Array.Resize(ref m_Stack, m_StackSize *= 2);
                    }
                    m_Stack[++m_StackPosition] = enumerator;

                    IRoutineEnumerator callback = enumerator as IRoutineEnumerator;
                    if (callback != null)
                    {
                        bool bContinue = callback.OnRoutineStart();
                        if (!bContinue)
                        {
                            Dispose();
                        }
                        return(bContinue);
                    }

                    return(true);
                }
            }
            else
            {
                m_Stack[m_StackPosition--] = null;
                ((IDisposable)current).Dispose();
                if (m_StackPosition < 0)
                {
                    Dispose();
                    return(false);
                }
            }

            return(true);
        }