private void EndFrame()
        {
            TaskUpdate(Time.deltaTime);

            #region Handle Disable
            for (int iBehaviour = 0; iBehaviour < m_BehavioursForTraverse.Count; iBehaviour++)
            {
                BaseBehaviour behaviour = m_BehavioursForTraverse[iBehaviour];
                DisableBehaviour(behaviour);
            }
            #endregion

            #region Handle Release
            for (int iBehaviour = 0; iBehaviour < m_RemoveBehavioursCache.Count; iBehaviour++)
            {
                BaseBehaviour behaviour = m_RemoveBehavioursCache[iBehaviour];
                ReleaseBehaviour(behaviour);
            }
            m_RemoveBehavioursCache.Clear();
            #endregion

            m_BehavioursForTraverse.Clear();

            MDebug.LogVerbose("Core", "EndFrame " + Time.frameCount);
        }
예제 #2
0
 public TaskUpdateItem SetData(BaseBehaviour behaviour, float deltaTime)
 {
     Behaviour = behaviour;
     ManualResetEvent.Reset();
     DeltaTime = deltaTime;
     return(this);
 }
        protected void FixedUpdate()
        {
            BeginFrame();

            float deltaTime = Time.fixedDeltaTime;

            for (int iBehaviour = 0; iBehaviour < m_BehavioursForTraverse.Count; iBehaviour++)
            {
                BaseBehaviour iterBehaviour = m_BehavioursForTraverse[iBehaviour];
                if (!iterBehaviour.CanUpdate())
                {
                    continue;
                }

                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {iterBehaviour.GetName()}.OnFixedUpdate");

                    iterBehaviour.OnFixedUpdate(deltaTime);

                    MDebug.LogVerbose("Core"
                                      , $"After execute {iterBehaviour.GetName()}.OnFixedUpdate");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {iterBehaviour.GetName()}.OnFixedUpdate Exception:{e.ToString()}");
                }
            }
        }
        private void DisableBehaviour(BaseBehaviour behaviour)
        {
            if (!behaviour.IsEnable() && behaviour.IsLastEnable())
            {
                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {behaviour.GetName()}.OnDisable");

                    behaviour.OnDisable();

                    MDebug.LogVerbose("Core"
                                      , $"After execute {behaviour.GetName()}.OnDisable");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {behaviour.GetName()}.OnDisable Exception:{e.ToString()}");
                }
                finally
                {
                    behaviour.SetLastEnable(false);
                }
            }
        }
        private void ParallelUpdate(float deltaTime)
        {
            MDebug.Assert(m_ParallelItemsCache.Count == 0, "Core", "m_ParallelTasksCache.Count == 0");

            string lastGroupName = string.Empty;

            for (int iBehaviour = 0; iBehaviour < m_BehavioursForTraverse.Count; iBehaviour++)
            {
                BaseBehaviour iterBehaviour = m_BehavioursForTraverse[iBehaviour];
                if (!iterBehaviour.CanUpdate() ||
                    !iterBehaviour.HasFeature(FeatureFlag.ParallelUpdate))
                {
                    continue;
                }

                string groupName = iterBehaviour.GetGroup();
                if (groupName != lastGroupName)
                {
                    ExecuteParallelUpdateGroup();
                }

                lastGroupName = groupName;
                m_ParallelItemsCache.Add(m_ParallelItemPool.Alloc()
                                         .SetData(iterBehaviour, deltaTime));
            }

            ExecuteParallelUpdateGroup();
        }
        /// <summary>
        /// 等待所有的<see cref="TaskUpdate"/>完成
        /// </summary>
        private void WaitTaskUpdate()
        {
            for (int iTask = 0; iTask < m_TaskItemsCache.Count; iTask++)
            {
                TaskUpdateItem taskItem = m_TaskItemsCache[iTask];
                taskItem.ManualResetEvent.WaitOne();

                BaseBehaviour iterBehaviour = taskItem.Behaviour;
                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {iterBehaviour.GetName()}.OnAfterTaskUpdate");

                    iterBehaviour.OnAfterTaskUpdate(taskItem.Output);

                    MDebug.LogVerbose("Core"
                                      , $"After execute {iterBehaviour.GetName()}.OnAfterTaskUpdate");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {iterBehaviour.GetName()}.OnAfterTaskUpdate Exception:{e.ToString()}");
                }

                m_TaskItemPool.Release(taskItem);
            }

            m_TaskItemsCache.Clear();
        }
        protected void Update()
        {
            // 这里也要调用一次的原因是,当前帧可能没执行FixedUpdate
            BeginFrame();

            float deltaTime  = Time.deltaTime;
            int   frameCount = Time.frameCount;

            ParallelUpdate(deltaTime);

            for (int iBehaviour = 0; iBehaviour < m_BehavioursForTraverse.Count; iBehaviour++)
            {
                BaseBehaviour iterBehaviour = m_BehavioursForTraverse[iBehaviour];
                if (!iterBehaviour.CanUpdate())
                {
                    continue;
                }

                float behaviourDeltaTime;
                if (iterBehaviour.HasFeature(FeatureFlag.UpdateFrequency))
                {
                    try
                    {
                        if (!iterBehaviour.ControlUpdateFrequency(out behaviourDeltaTime, deltaTime, frameCount))
                        {
                            continue;
                        }
                    }
                    catch (Exception e)
                    {
                        MDebug.LogError("Core"
                                        , $"Execute {iterBehaviour.GetName()}.ControlUpdateFrequency Exception:{e.ToString()}");
                        continue;
                    }
                }
                else
                {
                    behaviourDeltaTime = deltaTime;
                }

                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {iterBehaviour.GetName()}.OnUpdate");

                    iterBehaviour.OnUpdate(behaviourDeltaTime);

                    MDebug.LogVerbose("Core"
                                      , $"After execute {iterBehaviour.GetName()}.OnUpdate");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {iterBehaviour.GetName()}.OnUpdate Exception:{e.ToString()}");
                }
            }
        }
 internal void AddBehavior(BaseBehaviour behaviour)
 {
     if (!behaviour.IsAlive())
     {
         m_BehaviourOrdered.Add(behaviour);
         m_AddBehavioursCache.Add(behaviour);
     }
     else
     {
         MDebug.LogError("Core"
                         , $"AddBehavior ({behaviour.GetName()}) failed. It already alive.");
     }
 }
 internal void RemoveBehavior(BaseBehaviour behaviour)
 {
     if (behaviour.IsAlive())
     {
         behaviour.SetEnable(false);
         behaviour.SetAlive(false);
         m_BehaviourOrdered.DeleteByIndex(m_BehaviourOrdered.GetIndexByKey(behaviour));
         m_RemoveBehavioursCache.Add(behaviour);
     }
     else
     {
         MDebug.LogError("Core"
                         , $"RemoveBehavior ({behaviour.GetName()}) failed. It doesn't alive.");
     }
 }
        private void ReleaseBehaviour(BaseBehaviour behaviour)
        {
            try
            {
                MDebug.LogVerbose("Core"
                                  , $"Before execute {behaviour.GetName()}.OnRelease");

                behaviour.OnRelease();

                MDebug.LogVerbose("Core"
                                  , $"After execute {behaviour.GetName()}.OnRelease");
            }
            catch (Exception e)
            {
                MDebug.LogError("Core"
                                , $"Execute {behaviour.GetName()}.OnRelease Exception:{e.ToString()}");
            }
        }
        private void TaskUpdate(float deltaTime)
        {
            MDebug.Assert(m_TaskItemsCache.Count == 0, "Core", "m_TaskItemsCache.Count == 0");

            for (int iBehaviour = 0; iBehaviour < m_BehavioursForTraverse.Count; iBehaviour++)
            {
                BaseBehaviour iterBehaviour = m_BehavioursForTraverse[iBehaviour];
                if (!iterBehaviour.CanUpdate() ||
                    !iterBehaviour.HasFeature(FeatureFlag.TaskUpdate))
                {
                    continue;
                }

                TaskUpdateItem iterTaskItem = m_TaskItemPool.Alloc()
                                              .SetData(iterBehaviour, deltaTime);
                m_TaskItemsCache.Add(iterTaskItem);

                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {iterBehaviour.GetName()}.OnBeforeTastUpdate");

                    iterTaskItem.Input = iterBehaviour.OnBeforeTastUpdate();

                    MDebug.LogVerbose("Core"
                                      , $"After execute {iterBehaviour.GetName()}.OnBeforeTastUpdate");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {iterBehaviour.GetName()}.OnBeforeTastUpdate Exception:{e.ToString()}");
                }

                System.Threading.ThreadPool.QueueUserWorkItem(iterBehaviour.DoTaskUpdate_Thread, iterTaskItem);
            }
        }
        protected void OnApplicationQuit()
        {
            WaitTaskUpdate();
            CollectionBehavioursForTraverse();

            for (int iBehaviour = 0; iBehaviour < m_BehavioursForTraverse.Count; iBehaviour++)
            {
                BaseBehaviour behaviour = m_BehavioursForTraverse[iBehaviour];
                behaviour.SetEnable(false);
                DisableBehaviour(behaviour);
            }

            for (int iBehaviour = 0; iBehaviour < m_BehavioursForTraverse.Count; iBehaviour++)
            {
                BaseBehaviour behaviour = m_BehavioursForTraverse[iBehaviour];
                behaviour.SetAlive(false);
                ReleaseBehaviour(behaviour);
            }

            m_BehavioursForTraverse.Clear();
            m_AddBehavioursCache.Clear();
            m_RemoveBehavioursCache.Clear();
            m_BehaviourOrdered.Clear();
        }
예제 #13
0
 public void OnRelease()
 {
     Behaviour = null;
     Input     = null;
     Output    = null;
 }
 public ParallelUpdateItem SetData(BaseBehaviour behaviour, float deltaTime)
 {
     Behaviour = behaviour;
     DeltaTime = deltaTime;
     return(this);
 }
        private void BeginFrame()
        {
            if (Time.frameCount <= m_LastBeginFrame)
            {
                return;
            }
            m_LastBeginFrame = Time.frameCount;

            MDebug.LogVerbose("Core", "BeginFrame " + m_LastBeginFrame);
            WaitTaskUpdate();

            CollectionBehavioursForTraverse();

            #region Handle Initialize
            for (int iBehaviour = 0; iBehaviour < m_AddBehavioursCache.Count; iBehaviour++)
            {
                BaseBehaviour behaviour = m_AddBehavioursCache[iBehaviour];

                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {behaviour.GetName()}.OnInitialize");

                    behaviour.OnInitialize();

                    MDebug.LogVerbose("Core"
                                      , $"After execute {behaviour.GetName()}.OnInitialize");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {behaviour.GetName()}.OnInitialize Exception:{e.ToString()}");
                }
                behaviour.SetAlive(true);
            }
            m_AddBehavioursCache.Clear();
            #endregion

            #region Handle Enable
            for (int iBehaviour = 0; iBehaviour < m_BehavioursForTraverse.Count; iBehaviour++)
            {
                BaseBehaviour behaviour = m_BehavioursForTraverse[iBehaviour];
                if (behaviour.IsEnable() && !behaviour.IsLastEnable())
                {
                    try
                    {
                        MDebug.LogVerbose("Core"
                                          , $"Before execute {behaviour.GetName()}.OnEnable");

                        behaviour.OnEnable();

                        MDebug.LogVerbose("Core"
                                          , $"After execute {behaviour.GetName()}.OnEnable");
                    }
                    catch (Exception e)
                    {
                        MDebug.LogError("Core"
                                        , $"Execute {behaviour.GetName()}.OnEnable Exception:{e.ToString()}");
                    }
                    finally
                    {
                        behaviour.SetLastEnable(true);
                    }
                }
            }
            #endregion
        }
        private void ExecuteParallelUpdateGroup()
        {
            if (m_ParallelItemsCache.Count == 0)
            {
                return;
            }

            for (int iBehaviour = 0; iBehaviour < m_ParallelItemsCache.Count; iBehaviour++)
            {
                ParallelUpdateItem iterTask      = m_ParallelItemsCache[iBehaviour];
                BaseBehaviour      iterBehaviour = iterTask.Behaviour;

                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {iterBehaviour.GetName()}.OnBeforeParallelUpdate");

                    iterTask.Input = iterBehaviour.OnBeforeParallelUpdate(iterTask.DeltaTime);

                    MDebug.LogVerbose("Core"
                                      , $"After execute {iterBehaviour.GetName()}.OnBeforeParallelUpdate");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {iterBehaviour.GetName()}.OnBeforeParallelUpdate Exception:{e.ToString()}");
                }
            }

            System.Threading.Tasks.Parallel.For(0, m_ParallelItemsCache.Count, (iBehaviour) =>
            {
                ParallelUpdateItem iterTask = m_ParallelItemsCache[iBehaviour];
                BaseBehaviour iterBehaviour = iterTask.Behaviour;

                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {iterBehaviour.GetName()}.OnParallelUpdate_Thread");

                    iterTask.Output = iterBehaviour.OnParallelUpdate_Thread(iterTask.Input, iterTask.DeltaTime);

                    MDebug.LogVerbose("Core"
                                      , $"After execute {iterBehaviour.GetName()}.OnParallelUpdate_Thread");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {iterBehaviour.GetName()}.OnParallelUpdate_Thread Exception:{e.ToString()}");
                }
            });

            for (int iBehaviour = 0; iBehaviour < m_ParallelItemsCache.Count; iBehaviour++)
            {
                ParallelUpdateItem iterTask      = m_ParallelItemsCache[iBehaviour];
                BaseBehaviour      iterBehaviour = iterTask.Behaviour;

                try
                {
                    MDebug.LogVerbose("Core"
                                      , $"Before execute {iterBehaviour.GetName()}.OnAfterParallelUpdate");

                    iterBehaviour.OnAfterParallelUpdate(iterTask.Output, iterTask.DeltaTime);

                    MDebug.LogVerbose("Core"
                                      , $"After execute {iterBehaviour.GetName()}.OnAfterParallelUpdate");
                }
                catch (Exception e)
                {
                    MDebug.LogError("Core"
                                    , $"Execute {iterBehaviour.GetName()}.OnAfterParallelUpdate Exception:{e.ToString()}");
                }

                m_ParallelItemPool.Release(iterTask);
            }

            m_ParallelItemsCache.Clear();
        }