Ejemplo n.º 1
0
        public static void UpdateThreads()          //called each time any thread is complete
        {
            try{
                if (!on || queue.Count == 0)
                {
                    return;
                }

                        #if WDEBUG
                if (IsMainThread)
                {
                    Profiler.BeginSample("Update Threads");
                }
                        #endif

                int threadsRunning = 0;         //current number of threads then multithreading is on

                //calculating number of threads running
                int queueCount = queue.Count;
                for (int i = 0; i < queueCount; i++)
                {
                    if (queue[i].stage == Stage.threadRunning)
                    {
                        threadsRunning++;
                    }
                }

                //guard if all possible threads already started: exit with no queue locking
                if (threadsRunning >= maxThreads)
                {
                                #if WDEBUG
                    if (IsMainThread)
                    {
                        Profiler.EndSample();
                    }
                                #endif

                    return;
                }

                //staring new threads
                lock (queue)
                    while (threadsRunning < maxThreads)
                    {
                        //finding suitable worker with highest priority
                        float maxProirity = -2000000;
//				int maxProirityNum = -1;
                        ThreadWorker maxPriorityWorker = null;

                        queueCount = queue.Count;
                        for (int i = 0; i < queueCount; i++)
                        {
                            ThreadWorker worker = queue[i];
                            if (worker == null)
                            {
                                continue;
                            }
                            if (worker.priority < maxProirity)
                            {
                                continue;
                            }
                            if (worker.stage != Stage.threadEnqueued)
                            {
                                continue;                                                 //if object destroyed or other stage
                            }
                            if (worker.threadCondition != null && !worker.threadCondition())
                            {
                                continue;
                            }

                            maxPriorityWorker = worker;
                            maxProirity       = worker.priority;
//					maxProirityNum = i;
                        }

                        //no suitable threads
                        if (maxPriorityWorker == null)
                        {
                            break;
                        }

                        //starting thread
                        //lock (maxPriorityWorker.locker)
                        Monitor.Enter(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = true;
                        try
                        {
                            if (maxPriorityWorker.stage != Stage.threadEnqueued)
                            {
                                return;                                                              //this could happen if two threads selecting one worker, or worker stopped while being selected
                            }
                            if (logging)
                            {
                                Log(maxPriorityWorker, "Refresh:ThreadSelected (max" + maxProirity + ") ");
                            }

                            threadsRunning++;

                            if (multithreading)
                            {
                                maxPriorityWorker.thread = new System.Threading.Thread(maxPriorityWorker.ThreadFn);

                                maxPriorityWorker.thread.IsBackground = true;
                                maxPriorityWorker.SwitchStage(Stage.threadRunning, "Refresh: start thread");                 //before actually starting

                                maxPriorityWorker.thread.Start();
                            }
                            else
                            {
                                maxPriorityWorker.ThreadFn(); if (IsMainThread)
                                {
                                    UnityEngine.Profiling.Profiler.EndSample();
                                }
                                if (oneThreadPerFrame)
                                {
                                    break;
                                }
                            }
                        }
                        finally { Monitor.Exit(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = false; }
                    }

                        #if WDEBUG
                if (IsMainThread)
                {
                    Profiler.EndSample();
                }
                        #endif
            } catch (System.Exception e) { Debug.LogError("Spinner Error: " + e); }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 更新应用
        /// </summary>
        public static void UpdateApply()
        {
            if (!on || queue.Count == 0)
            {
                return;
            }

#if WDEBUG
            Profiler.BeginSample("Update Apply");
#endif

            var timer = new System.Diagnostics.Stopwatch();
            timer.Start();

            while (timer.ElapsedMilliseconds < maxApplyTime)
            {
                //if couroutine has started - moving coroutine
                if (CurrentCoroutine != null)
                {
                    currentCoroutineWorker.CoroutineFn(); continue;
                }

                //finding suitable worker with highest priority
                float maxProirity = -2000000;
//				int maxProirityNum = -1;
                ThreadWorker maxPriorityWorker = null;

                int queueCount = queue.Count;
                for (int i = 0; i < queueCount; i++)
                {
                    ThreadWorker worker = queue[i];

                    if (worker == null)
                    {
                        continue;                                   //if object destroyed
                    }
                    if (worker.priority < maxProirity)
                    {
                        continue;
                    }
                    if (worker.stage != Stage.applyEnqueued && worker.stage != Stage.prepareEnqueued && worker.stage != Stage.coroutineEnqueued && worker.stage != Stage.coroutineRunning)
                    {
                        continue;                                                                                                                                                                                //other stage
                    }
                    if (worker.stage == Stage.prepareEnqueued && worker.prepareCondition != null && !worker.prepareCondition())
                    {
                        continue;
                    }
                    if (worker.stage == Stage.applyEnqueued && worker.applyCondition != null && !worker.applyCondition())
                    {
                        continue;                                                                                                                   //if apply condition has not met
                    }
                    if (worker.stage == Stage.coroutineEnqueued && worker.coroutineCondition != null && !worker.coroutineCondition())
                    {
                        continue;                                                                                                                               //if coroutine condition has not met (note that conditions is checked only before starting coroutine)
                    }
                    maxPriorityWorker = worker;
                    maxProirity       = worker.priority;
//					maxProirityNum = i;
                }

                //no suitable applies
                if (maxPriorityWorker == null)
                {
                    break;
                }

                //apply
                //lock (maxPriorityWorker.locker)
                Monitor.Enter(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = true;
                try
                {
                    if (logging)
                    {
                        Log(maxPriorityWorker, "Refresh:ApplyPrepSelected");
                    }

                    if (maxPriorityWorker.stage == Stage.prepareEnqueued)
                    {
                        //maxPriorityWorker.SwitchStage(Stage.applyRunning);
                        maxPriorityWorker.PrepareFn();
                    }

                    if (maxPriorityWorker.stage == Stage.applyEnqueued)
                    {
                        //maxPriorityWorker.SwitchStage(Stage.applyRunning);
                        maxPriorityWorker.ApplyFn();
                    }

                    if (maxPriorityWorker.stage == Stage.coroutineEnqueued || maxPriorityWorker.stage == Stage.coroutineRunning)
                    {
                        maxPriorityWorker.CoroutineFn();
                    }
                }
                finally { Monitor.Exit(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = false; }
            }

                        #if WDEBUG
            Profiler.EndSample();
                        #endif
        }