Пример #1
0
        /// <summary>
        /// Sets the update timing.
        /// </summary>
        public void SetPhase(RoutinePhase inUpdateMode)
        {
            if (m_Chained || m_UpdatePhase == inUpdateMode)
            {
                return;
            }

            if (inUpdateMode == RoutinePhase.Manual)
            {
                if (m_Disposing && !m_Executing)
                {
                    Dispose();
                    return;
                }

                // Clear out any special yield timing
                // Yield phases are meaningless in the context of manual updates
                if (m_YieldPhase != YieldPhase.None)
                {
                    Manager.Fibers.RemoveFiberFromYieldList(this, m_YieldPhase);
                    m_YieldPhase = YieldPhase.None;
                }
            }

            Manager.Fibers.RemoveFiberFromUpdateList(this, m_UpdatePhase);
            m_UpdatePhase = inUpdateMode;
            Manager.Fibers.AddFiberToUpdateList(this, m_UpdatePhase);
        }
Пример #2
0
        static private string GetPhaseUpdaterName(RoutinePhase inPhase)
        {
            switch (inPhase)
            {
            case RoutinePhase.FixedUpdate:
                return(ROUTINE_UPDATER_FIXEDUPDATE);

            case RoutinePhase.LateUpdate:
                return(ROUTINE_UPDATER_LATEUPDATE);

            case RoutinePhase.Update:
                return(ROUTINE_UPDATER_UPDATE);

            case RoutinePhase.Manual:
                return(ROUTINE_UPDATER_MANUAL);

            case RoutinePhase.CustomUpdate:
                return(ROUTINE_UPDATER_CUSTOMUPDATE);

            case RoutinePhase.ThinkUpdate:
                return(ROUTINE_UPDATER_THINKUPDATE);

            case RoutinePhase.RealtimeUpdate:
                return(ROUTINE_UPDATER_REALTIMEUPDATE);

            default:
                return(string.Empty);
            }
        }
Пример #3
0
        /// <summary>
        /// Adds a Fiber to the given update list.
        /// </summary>
        public void AddFiberToUpdateList(Fiber inFiber, RoutinePhase inUpdate)
        {
            switch (inUpdate)
            {
            case RoutinePhase.FixedUpdate:
                AddLast(inFiber, ref m_FixedUpdateList);
                m_FixedUpdateList.Dirty = true;
                break;

            case RoutinePhase.Update:
                AddLast(inFiber, ref m_UpdateList);
                m_UpdateList.Dirty = true;
                break;

            case RoutinePhase.LateUpdate:
                AddLast(inFiber, ref m_LateUpdateList);
                m_LateUpdateList.Dirty = true;
                break;

            case RoutinePhase.CustomUpdate:
                AddLast(inFiber, ref m_CustomUpdateList);
                m_CustomUpdateList.Dirty = true;
                break;

            case RoutinePhase.ThinkUpdate:
                AddLast(inFiber, ref m_ThinkUpdateList);
                m_ThinkUpdateList.Dirty = true;
                break;

            case RoutinePhase.Manual:
                AddLast(inFiber, ref m_ManualUpdateList);
                m_ManualUpdateList.Dirty = true;
                break;
            }
        }
Пример #4
0
        /// <summary>
        /// Marks an update list to be sorted at the next available time.
        /// </summary>
        public void SetUpdateListDirty(RoutinePhase inUpdate)
        {
            switch (inUpdate)
            {
            case RoutinePhase.FixedUpdate:
                m_FixedUpdateList.Dirty = true;
                break;

            case RoutinePhase.Update:
                m_UpdateList.Dirty = true;
                break;

            case RoutinePhase.LateUpdate:
                m_LateUpdateList.Dirty = true;
                break;

            case RoutinePhase.CustomUpdate:
                m_CustomUpdateList.Dirty = true;
                break;

            case RoutinePhase.ThinkUpdate:
                m_ThinkUpdateList.Dirty = true;
                break;

            case RoutinePhase.RealtimeUpdate:
                m_RealtimeUpdateList.Dirty = true;
                break;

            case RoutinePhase.Manual:
                m_ManualUpdateList.Dirty = true;
                break;
            }
        }
Пример #5
0
        /// <summary>
        /// Returns the total number of fibers for the given update list.
        /// </summary>
        public int GetUpdateCount(RoutinePhase inUpdate)
        {
            switch (inUpdate)
            {
            case RoutinePhase.FixedUpdate:
                return(m_FixedUpdateList.Count);

            case RoutinePhase.Update:
                return(m_UpdateList.Count);

            case RoutinePhase.Manual:
                return(m_ManualUpdateList.Count);

            case RoutinePhase.LateUpdate:
                return(m_LateUpdateList.Count);

            case RoutinePhase.CustomUpdate:
                return(m_CustomUpdateList.Count);

            case RoutinePhase.ThinkUpdate:
                return(m_ThinkUpdateList.Count);

            case RoutinePhase.RealtimeUpdate:
                return(m_RealtimeUpdateList.Count);

            default:
                return(0);
            }
        }
Пример #6
0
        /// <summary>
        /// Removes a Fiber from the given update list.
        /// </summary>
        public void RemoveFiberFromUpdateList(Fiber inFiber, RoutinePhase inUpdate)
        {
            m_MainUpdate.RemoveFromUpdate(this, inUpdate, inFiber);

            switch (inUpdate)
            {
            case RoutinePhase.FixedUpdate:
                RemoveEntry(inFiber, ref m_FixedUpdateList);
                break;

            case RoutinePhase.Update:
                RemoveEntry(inFiber, ref m_UpdateList);
                break;

            case RoutinePhase.LateUpdate:
                RemoveEntry(inFiber, ref m_LateUpdateList);
                break;

            case RoutinePhase.CustomUpdate:
                RemoveEntry(inFiber, ref m_CustomUpdateList);
                break;

            case RoutinePhase.ThinkUpdate:
                RemoveEntry(inFiber, ref m_ThinkUpdateList);
                break;

            case RoutinePhase.Manual:
                // Nested list is only involved in a manual update
                m_NestedUpdate.RemoveFromUpdate(this, inUpdate, inFiber);

                RemoveEntry(inFiber, ref m_ManualUpdateList);
                break;
            }
        }
Пример #7
0
        // Runs a nested update on the given update list (always manual)
        private void RunUpdateNested(RoutinePhase inUpdateMode, ref UpdateList ioList)
        {
            if (ioList.Dirty)
            {
                SortUpdateList(ref ioList);
                ioList.Dirty = false;
            }

            m_NestedUpdate.Start(inUpdateMode, ref ioList);

            bool bPrevUpdating = ioList.Updating;

            ioList.Updating = true;
            {
                while (m_NestedUpdate.Next != -1 && m_NestedUpdate.Counter-- > 0)
                {
                    Entry e = m_Entries[m_NestedUpdate.Next];
                    m_NestedUpdate.Next = e.UpdateNext;
                    if (e.Fiber.PrepareUpdate(inUpdateMode))
                    {
                        e.Fiber.Update();
                    }
                }
            }
            ioList.Updating = bPrevUpdating;

            m_NestedUpdate.Clear();
        }
Пример #8
0
 public void Clear()
 {
     Phase   = (RoutinePhase)(-1);
     Yield   = YieldPhase.None;
     Next    = -1;
     Counter = -1;
 }
Пример #9
0
        /// <summary>
        /// Returns if the given list is updating.
        /// </summary>
        public bool GetIsUpdating(RoutinePhase inUpdate)
        {
            switch (inUpdate)
            {
            case RoutinePhase.FixedUpdate:
                return(m_FixedUpdateList.Updating);

            case RoutinePhase.Update:
                return(m_UpdateList.Updating);

            case RoutinePhase.Manual:
                return(m_ManualUpdateList.Updating);

            case RoutinePhase.LateUpdate:
                return(m_LateUpdateList.Updating);

            case RoutinePhase.CustomUpdate:
                return(m_CustomUpdateList.Updating);

            case RoutinePhase.ThinkUpdate:
                return(m_ThinkUpdateList.Updating);

            case RoutinePhase.RealtimeUpdate:
                return(m_RealtimeUpdateList.Updating);

            default:
                return(false);
            }
        }
Пример #10
0
 public void RemoveFromUpdate(Table inTable, RoutinePhase inPhase, Fiber inFiber)
 {
     if (Counter >= 0 && Next == inFiber.Index && Yield == YieldPhase.None && Phase == inPhase)
     {
         Next = inTable.m_Entries[inFiber.Index].UpdateNext;
         --Counter;
     }
 }
Пример #11
0
            public void Start(YieldPhase inYield, ref YieldList inList)
            {
                Phase = (RoutinePhase)(-1);
                Yield = inYield;

                Next    = inList.Head;
                Counter = inList.Count;
            }
Пример #12
0
            public void Start(RoutinePhase inPhase, ref UpdateList inList)
            {
                Phase = inPhase;
                Yield = YieldPhase.None;

                Next    = inList.Head;
                Counter = inList.Count;
            }
Пример #13
0
        /// <summary>
        /// Returns if the Fiber will update with the given mode.
        /// </summary>
        public bool PrepareUpdate(RoutinePhase inUpdateMode)
        {
            if (m_StackPosition < 0 || m_Executing)
            {
                return(false);
            }

            return(m_UpdatePhase == inUpdateMode);
        }
Пример #14
0
        /// <summary>
        /// Clears the update routine for the object and update phase.
        /// </summary>
        static public Routine ClearUpdateRoutine(this MonoBehaviour inHost, RoutinePhase inPhase = RoutinePhase.Update)
        {
            Manager m = Manager.Get();

            if (m != null)
            {
                string phaseName = GetPhaseUpdaterName(inPhase);
                Routine.Stop(inHost, phaseName);
            }
            return(Routine.Null);
        }
Пример #15
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 DEVELOPMENT
            if (Manager.DebugMode && !(inStart is IDisposable))
            {
                throw new ArgumentException("IEnumerators must also implement IDisposable.");
            }
            #endif // DEVELOPMENT

            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_LockCount = 0;

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

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

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

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

            m_TimeScale = 1.0f;

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

            CheckForNesting(inStart);

            if (!m_Chained)
            {
                m_UpdatePhase = Manager.DefaultPhase;
                Manager.Fibers.AddFiberToUpdateList(this, m_UpdatePhase);
            }

            return(m_Handle);
        }
Пример #16
0
        /// <summary>
        /// Sets the update timing for the routine.
        /// Note that if this update is currently running,
        /// this routine will not execute until the next update.
        /// </summary>
        public Routine SetPhase(RoutinePhase inUpdate)
        {
            Manager m = Manager.Get();

            if (m != null)
            {
                Fiber fiber = m.Fibers[this];
                if (fiber != null)
                {
                    fiber.SetPhase(inUpdate);
                }
            }
            return(this);
        }
Пример #17
0
        /// <summary>
        /// Updates all fibers in the given list.
        /// </summary>
        public void RunUpdate(RoutinePhase inUpdateMode)
        {
            switch (inUpdateMode)
            {
            case RoutinePhase.FixedUpdate:
                RunUpdate(RoutinePhase.FixedUpdate, ref m_FixedUpdateList);
                break;

            case RoutinePhase.Update:
                RunUpdate(RoutinePhase.Update, ref m_UpdateList);
                break;

            case RoutinePhase.LateUpdate:
                RunUpdate(RoutinePhase.LateUpdate, ref m_LateUpdateList);
                break;

            case RoutinePhase.CustomUpdate:
                RunUpdate(RoutinePhase.CustomUpdate, ref m_CustomUpdateList);
                break;

            case RoutinePhase.ThinkUpdate:
                RunUpdate(RoutinePhase.ThinkUpdate, ref m_ThinkUpdateList);
                break;

            case RoutinePhase.RealtimeUpdate:
                RunUpdate(RoutinePhase.RealtimeUpdate, ref m_RealtimeUpdateList);
                break;

            case RoutinePhase.Manual:
                if (m_MainUpdate.Counter >= 0)
                {
                    RunUpdateNested(RoutinePhase.Manual, ref m_ManualUpdateList);
                }
                else
                {
                    RunUpdate(RoutinePhase.Manual, ref m_ManualUpdateList);
                }
                break;
            }
        }
Пример #18
0
        private void RenderStats(RoutineStats inStats, bool inbCanAdjust, bool inbNested)
        {
            if (!inbNested)
            {
                // Render id
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("ID/", GUILayout.Width(FIELD_NAME_WIDTH));
                    uint handleID = (uint)inStats.Handle;
                    uint index    = handleID & Table.INDEX_MASK;
                    uint counter  = (handleID & Table.COUNTER_MASK) >> Table.COUNTER_SHIFT;
                    EditorGUILayout.LabelField(index.ToString() + " (" + counter.ToString("X2") + ")", GUILayout.ExpandWidth(true));
                }
                EditorGUILayout.EndHorizontal();

                // Render name
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("NAME/", GUILayout.Width(FIELD_NAME_WIDTH));
                    if (!inbCanAdjust)
                    {
                        GUI.enabled = false;
                    }
                    string newName = EditorGUILayout.TextField(inStats.Name, GUILayout.ExpandWidth(true));
                    if (newName != inStats.Name)
                    {
                        inStats.Handle.SetName(newName);
                    }
                    GUI.enabled = true;
                }
                EditorGUILayout.EndHorizontal();
            }

            if (!inbNested && !ReferenceEquals(inStats.Host, null))
            {
                // Render host
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("HOST/", GUILayout.Width(FIELD_NAME_WIDTH));
                    GUI.enabled = false;
                    EditorGUILayout.ObjectField(inStats.Host, typeof(MonoBehaviour), true, GUILayout.ExpandWidth(true));
                    GUI.enabled = true;
                }
                EditorGUILayout.EndHorizontal();
            }

            // Current state
            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("STATUS/", GUILayout.Width(FIELD_NAME_WIDTH));
                EditorGUILayout.LabelField(inStats.State, GUILayout.ExpandWidth(true));
            }
            EditorGUILayout.EndHorizontal();

            // Time Scale
            if (!inbNested)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("TIMESCALE/", GUILayout.Width(FIELD_NAME_WIDTH));
                    if (!inbCanAdjust)
                    {
                        GUI.enabled = false;
                    }
                    #if SUPPORTS_DELAYEDFIELDS
                    float timeScale = EditorGUILayout.DelayedFloatField(inStats.TimeScale, GUILayout.ExpandWidth(true));
                    #else
                    float timeScale = EditorGUILayout.FloatField(inStats.TimeScale, GUILayout.ExpandWidth(true));
                    #endif
                    if (timeScale < 0)
                    {
                        timeScale = 0;
                    }
                    if (timeScale != inStats.TimeScale)
                    {
                        inStats.Handle.SetTimeScale(timeScale);
                    }
                    GUI.enabled = true;
                }
                EditorGUILayout.EndHorizontal();
            }

            // Priority
            if (!inbNested)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("PRIORITY/", GUILayout.Width(FIELD_NAME_WIDTH));
                    if (!inbCanAdjust)
                    {
                        GUI.enabled = false;
                    }
                    #if SUPPORTS_DELAYEDFIELDS
                    int priority = EditorGUILayout.DelayedIntField(inStats.Priority, GUILayout.ExpandWidth(true));
                    #else
                    int priority = EditorGUILayout.IntField(inStats.Priority, GUILayout.ExpandWidth(true));
                    #endif
                    if (priority != inStats.Priority)
                    {
                        inStats.Handle.SetPriority(priority);
                    }
                    GUI.enabled = true;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("PHASE/", GUILayout.Width(FIELD_NAME_WIDTH));
                    if (!inbCanAdjust)
                    {
                        GUI.enabled = false;
                    }
                    RoutinePhase update = (RoutinePhase)EditorGUILayout.EnumPopup(inStats.Phase, GUILayout.ExpandWidth(true));
                    if (update != inStats.Phase)
                    {
                        inStats.Handle.SetPhase(update);
                    }
                    GUI.enabled = true;
                }
                EditorGUILayout.EndHorizontal();
            }

            // Current Function Name
            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("FUNCTION/" + inStats.StackDepth + "/", GUILayout.Width(FIELD_NAME_WIDTH));
                EditorGUILayout.LabelField(inStats.Function == null ? "[Null]" : inStats.Function, GUILayout.ExpandWidth(true));
            }
            EditorGUILayout.EndHorizontal();

            if (inStats.State != RoutineState.Disposing && inbCanAdjust)
            {
                // Functions
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button("Pause"))
                    {
                        inStats.Handle.Pause();
                    }
                    if (GUILayout.Button("Resume"))
                    {
                        inStats.Handle.Resume();
                    }
                    if (GUILayout.Button("Stop"))
                    {
                        inStats.Handle.Stop();
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            if (inStats.Nested != null && inStats.Nested.Length > 0)
            {
                EditorGUILayout.LabelField("NESTED/");
                BeginIndent();
                RenderStatGroup(inStats.Nested, inbCanAdjust, true);
                EndIndent();
            }
        }
Пример #19
0
        /// <summary>
        /// Runs the Fiber one frame.
        /// Will dispose itself if requested.
        /// Returns if still running.
        /// </summary>
        public bool Update(YieldPhase inYieldUpdate = YieldPhase.None)
        {
            // We don't support recursive Fiber updates
            if (m_Executing)
            {
                return(true);
            }

            if (m_StackPosition < 0)
            {
                return(false);
            }

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

            if (inYieldUpdate != YieldPhase.None && m_YieldFrameDelay > 0)
            {
                --m_YieldFrameDelay;
                return(true);
            }

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

            if (m_YieldPhase != inYieldUpdate)
            {
                return(true);
            }

            if (inYieldUpdate != YieldPhase.None)
            {
                Manager.Fibers.RemoveFiberFromYieldList(this, m_YieldPhase);
                m_YieldPhase = YieldPhase.None;

                // If we're in a manual update, don't proceed from here
                if (m_UpdatePhase == RoutinePhase.Manual)
                {
                    return(true);
                }
            }

            // If we're a chained routine, just accept
            // the parent's delta time.
            if (!m_Chained)
            {
                ApplyDeltaTime();
            }
            else if (inYieldUpdate != YieldPhase.None)
            {
                m_RootFiber.ApplyDeltaTime();
            }

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

                // We don't modify delta time in the fixed update phase,
                // to preserve a consistent delta time within fixed update.
                if (m_UpdatePhase != RoutinePhase.FixedUpdate && inYieldUpdate != YieldPhase.WaitForFixedUpdate)
                {
                    Manager.Frame.DeltaTime += m_WaitTime;
                }

                m_WaitTime = 0;
            }

            bool bExecuteStack = true;

            while (bExecuteStack)
            {
                bExecuteStack = false;

                // Set this flag to prevent updating this routine mid-execution
                m_Executing = true;

                IEnumerator current    = m_Stack[m_StackPosition];
                bool        bMovedNext = false;

                if (Manager.HandleExceptions || m_HandleExceptions || (m_Chained && m_RootFiber.m_HandleExceptions))
                {
                    try
                    {
                        bMovedNext = current.MoveNext();
                    }
                    catch (Exception e)
                    {
                        Debug.LogException(e);

                        Routine.ExceptionHandler exceptionHandler = m_OnException;
                        if (m_Chained)
                        {
                            exceptionHandler        = m_RootFiber.m_OnException;
                            m_RootFiber.m_Disposing = true;
                        }

                        if (exceptionHandler != null)
                        {
                            exceptionHandler(e);
                        }

                        m_Disposing = true;
                    }
                }
                else
                {
                    bMovedNext = current.MoveNext();
                }

                m_Executing = false;

                // 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_DOUBLE)
                    {
                        m_WaitTime = (float)(double)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)
                    {
                        // Disable obsolete WWW warning
                        #pragma warning disable 612, 618

                        m_UnityWait = Manager.Host.StartCoroutine(UnityWait((WWW)result));
                        return(true);

                        // Restore obsolete WWW warning
                        #pragma warning restore 612, 618
                    }

                    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);

                        case Routine.Command.BreakAndResume:
                            m_Stack[m_StackPosition--] = null;
                            ((IDisposable)current).Dispose();
                            if (m_StackPosition < 0)
                            {
                                Dispose();
                                return(false);
                            }
                            bExecuteStack = true;
                            break;

                        case Routine.Command.Continue:
                            bExecuteStack = true;
                            break;
                        }

                        if (!bExecuteStack)
                        {
                            return(true);
                        }

                        continue;
                    }

                    if (resultType == TYPEHANDLE_DECORATOR)
                    {
                        RoutineDecorator decorator           = (RoutineDecorator)result;
                        IEnumerator      decoratedEnumerator = decorator.Enumerator;
                        bExecuteStack = (decorator.Flags & RoutineDecoratorFlag.Inline) != 0;

                        if (decoratedEnumerator != 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] = decorator;

                            CheckForNesting(decoratedEnumerator);
                        }

                        if (!bExecuteStack)
                        {
                            return(true);
                        }

                        continue;
                    }

                    // Check for yield timing changes

                    if (m_UpdatePhase != RoutinePhase.Manual)
                    {
                        bool bApplyYieldDelay = !Manager.IsUpdating(RoutinePhase.Manual) && inYieldUpdate == YieldPhase.None;

                        if (resultType == TYPEHANDLE_ROUTINEPHASE)
                        {
                            RoutinePhase phase = (RoutinePhase)result;

                            switch (phase)
                            {
                            case RoutinePhase.FixedUpdate:
                            {
                                Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForFixedUpdate);
                                Manager.Host.WaitForFixedUpdate();
                                m_YieldPhase      = YieldPhase.WaitForFixedUpdate;
                                m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.FixedUpdate && Manager.IsUpdating(RoutinePhase.FixedUpdate) ? 1 : 0;
                                return(true);
                            }

                            case RoutinePhase.LateUpdate:
                            {
                                Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForLateUpdate);
                                m_YieldPhase      = YieldPhase.WaitForLateUpdate;
                                m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.LateUpdate && Manager.IsUpdating(RoutinePhase.LateUpdate) ? 1 : 0;
                                return(true);
                            }

                            case RoutinePhase.Update:
                            {
                                Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForUpdate);
                                m_YieldPhase      = YieldPhase.WaitForUpdate;
                                m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.Update && Manager.IsUpdating(RoutinePhase.Update) ? 1 : 0;
                                return(true);
                            }

                            case RoutinePhase.CustomUpdate:
                            {
                                Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForCustomUpdate);
                                m_YieldPhase      = YieldPhase.WaitForCustomUpdate;
                                m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.CustomUpdate && Manager.IsUpdating(RoutinePhase.CustomUpdate) ? 1 : 0;
                                return(true);
                            }

                            case RoutinePhase.ThinkUpdate:
                            {
                                Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForThinkUpdate);
                                m_YieldPhase      = YieldPhase.WaitForThinkUpdate;
                                m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.ThinkUpdate && Manager.IsUpdating(RoutinePhase.ThinkUpdate) ? 1 : 0;
                                return(true);
                            }

                            case RoutinePhase.RealtimeUpdate:
                            {
                                Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForRealtimeUpdate);
                                m_YieldPhase      = YieldPhase.WaitForRealtimeUpdate;
                                m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.RealtimeUpdate && Manager.IsUpdating(RoutinePhase.RealtimeUpdate) ? 1 : 0;
                                return(true);
                            }

                            case RoutinePhase.Manual:
                            default:
                            {
                                // Yielding a manual will not do anything
                                return(true);
                            }
                            }
                        }

                        if (resultType == TYPEHANDLE_WAITFORENDOFFRAME)
                        {
                            Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForEndOfFrame);
                            m_YieldPhase      = YieldPhase.WaitForEndOfFrame;
                            m_YieldFrameDelay = 0;
                            return(true);
                        }

                        if (resultType == TYPEHANDLE_WAITFORFIXEDUPDATE)
                        {
                            Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForFixedUpdate);
                            Manager.Host.WaitForFixedUpdate();
                            m_YieldPhase      = YieldPhase.WaitForFixedUpdate;
                            m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.FixedUpdate && Manager.IsUpdating(RoutinePhase.FixedUpdate) ? 1 : 0;
                            return(true);
                        }

                        if (resultType == TYPEHANDLE_WAITFORLATEUPDATE)
                        {
                            Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForLateUpdate);
                            m_YieldPhase      = YieldPhase.WaitForLateUpdate;
                            m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.LateUpdate && Manager.IsUpdating(RoutinePhase.LateUpdate) ? 1 : 0;
                            return(true);
                        }

                        if (resultType == TYPEHANDLE_WAITFORUPDATE)
                        {
                            Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForUpdate);
                            m_YieldPhase      = YieldPhase.WaitForUpdate;
                            m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.Update && Manager.IsUpdating(RoutinePhase.Update) ? 1 : 0;
                            return(true);
                        }

                        if (resultType == TYPEHANDLE_WAITFORCUSTOMUPDATE)
                        {
                            Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForCustomUpdate);
                            m_YieldPhase      = YieldPhase.WaitForCustomUpdate;
                            m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.CustomUpdate && Manager.IsUpdating(RoutinePhase.CustomUpdate) ? 1 : 0;
                            return(true);
                        }

                        if (resultType == TYPEHANDLE_WAITFORTHINKUPDATE)
                        {
                            Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForThinkUpdate);
                            m_YieldPhase      = YieldPhase.WaitForThinkUpdate;
                            m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.ThinkUpdate && Manager.IsUpdating(RoutinePhase.ThinkUpdate) ? 1 : 0;
                            return(true);
                        }

                        if (resultType == TYPEHANDLE_WAITFORREALTIMEUPDATE)
                        {
                            Manager.Fibers.AddFiberToYieldList(this, YieldPhase.WaitForRealtimeUpdate);
                            m_YieldPhase      = YieldPhase.WaitForRealtimeUpdate;
                            m_YieldFrameDelay = bApplyYieldDelay && m_UpdatePhase == RoutinePhase.RealtimeUpdate && Manager.IsUpdating(RoutinePhase.RealtimeUpdate) ? 1 : 0;
                            return(true);
                        }
                    }

                    if (WAITFORSECONDS_BYPASS && resultType == TYPEHANDLE_WAITFORSECONDS)
                    {
                        m_WaitTime = (float)FIELD_WAITFORSECONDS_SECONDS.GetValue(result);
                        return(true);
                    }

                    // Check for the subclassable types

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

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

                    IFuture future = result as IFuture;
                    if (future != null)
                    {
                        if (!future.IsDone())
                        {
                            IEnumerator waitSequence = future.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);
                    }

                    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;

                        CheckForNesting(enumerator);

                        return(true);
                    }
                }
                else
                {
                    bExecuteStack = current is RoutineDecorator && (((RoutineDecorator)current).Flags & RoutineDecoratorFlag.Inline) != 0;
                    m_Stack[m_StackPosition--] = null;
                    ((IDisposable)current).Dispose();
                    if (m_StackPosition < 0)
                    {
                        Dispose();
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #20
0
 /// <summary>
 /// Is the manager in the middle of updating the given update list.
 /// </summary>
 public bool IsUpdating(RoutinePhase inUpdate)
 {
     return(Fibers.GetIsUpdating(inUpdate));
 }
Пример #21
0
        /// <summary>
        /// Cleans up the Fiber.
        /// </summary>
        public void Dispose()
        {
            if ((uint)m_Handle == 0)
            {
                return;
            }

            if (m_UnityWait != null)
            {
                Manager.Host.StopCoroutine(m_UnityWait);
                m_UnityWait = null;
            }

            bool bKilled  = m_StackPosition >= 0;
            bool bChained = m_Chained;

            ClearStack();

            m_Handle       = Routine.Null;
            m_Host         = null;
            m_HostIdentity = null;

            // If this is chained and we have a parallel
            if (bChained && m_Container != null)
            {
                m_Container.RemoveFiber(this);
            }

            m_Chained = m_Disposing = m_HasIdentity = m_Paused = m_IgnoreObjectTimescale = m_HostedByManager = m_IgnoreObjectActive = m_Executing = false;

            m_WaitTime  = 0;
            m_LockCount = 0;
            m_Name      = null;
            Priority    = 0;

            m_Container = null;
            m_RootFiber = null;

            m_TimeScale       = 1.0f;
            m_YieldFrameDelay = 0;

            if (m_YieldPhase != YieldPhase.None)
            {
                Manager.Fibers.RemoveFiberFromYieldList(this, m_YieldPhase);
                m_YieldPhase = YieldPhase.None;
            }

            if (!bChained)
            {
                Manager.Fibers.RemoveFiberFromUpdateList(this, m_UpdatePhase);
            }
            Manager.RecycleFiber(this, bChained);

            m_UpdatePhase      = Manager.DefaultPhase;
            m_OnException      = null;
            m_HandleExceptions = false;

            if (bKilled)
            {
                m_OnComplete = null;
                Action onStop = m_OnStop;
                m_OnStop = null;
                if (onStop != null)
                {
                    onStop();
                }
            }
            else
            {
                m_OnStop = null;
                Action onComplete = m_OnComplete;
                m_OnComplete = null;
                if (onComplete != null)
                {
                    onComplete();
                }
            }
        }
Пример #22
0
 /// <summary>
 /// Returns the update routine associated with the object and update phase.
 /// </summary>
 static public Routine GetUpdateRoutine(this MonoBehaviour inHost, RoutinePhase inPhase = RoutinePhase.Update)
 {
     return(Routine.Find(inHost, GetPhaseUpdaterName(inPhase)));
 }
Пример #23
0
        /// <summary>
        /// Sets the update routine for the object and update phase.
        /// </summary>
        static public Routine SetUpdateRoutine(this MonoBehaviour inHost, IEnumerator inUpdateLoop, RoutinePhase inPhase = RoutinePhase.Update)
        {
            Manager m = Manager.Get();

            if (m != null)
            {
                string  phaseName = GetPhaseUpdaterName(inPhase);
                Routine routine   = Routine.Find(inHost, phaseName)
                                    .Replace(inHost, inUpdateLoop).SetPhase(inPhase);
                Fiber fiber = m.Fibers[routine];
                if (fiber != null)
                {
                    fiber.SetNameUnchecked(phaseName);
                }
                return(routine);
            }
            return(Routine.Null);
        }
Пример #24
0
        /// <summary>
        /// Updates all running routines.
        /// </summary>
        public void Update(float inDeltaTime, RoutinePhase inPhase)
        {
            Frame.IncrementSerial();
            Frame.ResetTime(inDeltaTime, TimeScale);
            Frame.PauseMask = m_QueuedPauseMask;
            if (m_GroupTimescaleDirty)
            {
                m_GroupTimescaleDirty = false;
                Array.Copy(m_QueuedGroupTimescale, Frame.GroupTimeScale, Routine.MAX_GROUPS);
            }

            bool bPrevUpdating = m_Updating;

            m_Updating = true;
            {
                #if DEVELOPMENT
                if (DebugMode && !bPrevUpdating && ProfilingEnabled)
                {
                    m_UpdateTimer.Reset();
                    m_UpdateTimer.Start();

                    if (m_NeedsSnapshot)
                    {
                        m_Snapshot      = GetRoutineStats();
                        m_NeedsSnapshot = false;
                    }

                    if (!Paused && !SystemPaused && Fibers.GetUpdateCount(inPhase) > 0)
                    {
                        Fibers.RunUpdate(inPhase);
                        Frame.ResetTimeScale();
                    }

                    m_UpdateTimer.Stop();

                    m_TotalUpdateTime += m_UpdateTimer.ElapsedTicks;

                    if (inPhase == RoutinePhase.LateUpdate)
                    {
                        ++m_TotalUpdateFrames;
                        if (Time.unscaledTime >= m_LastProfileLogTime + 10f)
                        {
                            m_LastProfileLogTime = Time.unscaledTime;

                            m_LogBuilder.Length = 0;
                            m_LogBuilder.Append("Running: ").Append(Fibers.TotalActive)
                            .Append('/').Append(m_MaxConcurrent)
                            .Append('/').Append(Fibers.TotalCapacity)
                            .Append("; Avg Update: ").Append((m_TotalUpdateTime / 10000f) / m_TotalUpdateFrames).Append("ms");
                            Log(string.Empty);
                        }

                        if (m_TotalUpdateFrames >= MAX_UPDATE_SAMPLES || m_UpdateTimer.ElapsedMilliseconds > MAX_UPDATE_MS)
                        {
                            m_TotalUpdateFrames = 0;
                            m_TotalUpdateTime   = 0;
                        }
                    }
                }
                else
                #endif // DEVELOPMENT
                {
                    if (!Paused && !SystemPaused && Fibers.GetUpdateCount(inPhase) > 0)
                    {
                        Fibers.RunUpdate(inPhase);
                        Frame.ResetTimeScale();
                    }
                }
            }
            m_Updating = bPrevUpdating;

            if (!m_Updating)
            {
                if (m_Destroying)
                {
                    m_Destroying = false;
                    Destroy();
                }
            }
        }
Пример #25
0
        /// <summary>
        /// Sets the update routine for the object and update phase.
        /// </summary>
        static public Routine SetUpdateRoutineGenerator(this MonoBehaviour inHost, Func <IEnumerator> inUpdateFunc, RoutinePhase inPhase = RoutinePhase.Update)
        {
            string  phaseName = GetPhaseUpdaterName(inPhase);
            Routine routine   = Routine.Find(inHost, phaseName).Replace(Routine.StartLoopRoutine(inHost, inUpdateFunc)).SetPhase(inPhase);
            Fiber   fiber     = Manager.Get().Fibers[routine];

            if (fiber != null)
            {
                fiber.SetNameUnchecked(phaseName);
            }
            return(routine);
        }