Esempio n. 1
0
		private void CalculatePathsThreaded(PathThreadInfo threadInfo)
		{
			try
			{
				PathHandler runData = threadInfo.runData;
				if (runData.nodes == null)
				{
					throw new NullReferenceException("NodeRuns must be assigned to the threadInfo.runData.nodes field before threads are started\nthreadInfo is an argument to the thread functions");
				}
				long num = (long)(this.astar.maxFrameTime * 10000f);
				long num2 = DateTime.UtcNow.Ticks + num;
				for (;;)
				{
					Path path = this.queue.Pop();
					num = (long)(this.astar.maxFrameTime * 10000f);
					path.PrepareBase(runData);
					path.AdvanceState(PathState.Processing);
					if (this.OnPathPreSearch != null)
					{
						this.OnPathPreSearch(path);
					}
					long ticks = DateTime.UtcNow.Ticks;
					long num3 = 0L;
					path.Prepare();
					if (!path.IsDone())
					{
						this.astar.debugPath = path;
						path.Initialize();
						while (!path.IsDone())
						{
							path.CalculateStep(num2);
							path.searchIterations++;
							if (path.IsDone())
							{
								break;
							}
							num3 += DateTime.UtcNow.Ticks - ticks;
							Thread.Sleep(0);
							ticks = DateTime.UtcNow.Ticks;
							num2 = ticks + num;
							if (this.queue.IsTerminating)
							{
								path.Error();
							}
						}
						num3 += DateTime.UtcNow.Ticks - ticks;
						path.duration = (float)num3 * 0.0001f;
					}
					path.Cleanup();
					if (path.immediateCallback != null)
					{
						path.immediateCallback(path);
					}
					if (this.OnPathPostSearch != null)
					{
						this.OnPathPostSearch(path);
					}
					this.returnQueue.Enqueue(path);
					path.AdvanceState(PathState.ReturnQueue);
					if (DateTime.UtcNow.Ticks > num2)
					{
						Thread.Sleep(1);
						num2 = DateTime.UtcNow.Ticks + num;
					}
				}
			}
			catch (Exception ex)
			{
				if (ex is ThreadAbortException || ex is ThreadControlQueue.QueueTerminationException)
				{
					if (this.astar.logPathResults == PathLog.Heavy)
					{
						Debug.LogWarning("Shutting down pathfinding thread #" + threadInfo.threadIndex);
					}
					return;
				}
				Debug.LogException(ex);
				Debug.LogError("Unhandled exception during pathfinding. Terminating.");
				this.queue.TerminateReceivers();
			}
			Debug.LogError("Error : This part should never be reached.");
			this.queue.ReceiverTerminated();
		}
Esempio n. 2
0
        /** Main pathfinding method (multithreaded).
         * This method will calculate the paths in the pathfinding queue when multithreading is enabled.
         *
         * \see CalculatePaths
         * \see StartPath
         *
         * \astarpro
         */
        void CalculatePathsThreaded(PathThreadInfo threadInfo)
        {
#if !ASTAR_FAST_BUT_NO_EXCEPTIONS
            try {
#endif

            //Initialize memory for this thread
            PathHandler runData = threadInfo.runData;

            if (runData.nodes == null)
            {
                throw new System.NullReferenceException("NodeRuns must be assigned to the threadInfo.runData.nodes field before threads are started\nthreadInfo is an argument to the thread functions");
            }

            //Max number of ticks before yielding/sleeping
            long maxTicks   = (long)(astar.maxFrameTime * 10000);
            long targetTick = System.DateTime.UtcNow.Ticks + maxTicks;

            while (true)
            {
                //The path we are currently calculating
                Path p = queue.Pop();

                //Max number of ticks we are allowed to continue working in one run
                //One tick is 1/10000 of a millisecond
                maxTicks = (long)(astar.maxFrameTime * 10000);


                AstarProfiler.StartFastProfile(0);
                p.PrepareBase(runData);

                //Now processing the path
                //Will advance to Processing
                p.AdvanceState(PathState.Processing);

                //Call some callbacks
                if (OnPathPreSearch != null)
                {
                    OnPathPreSearch(p);
                }

                //Tick for when the path started, used for calculating how long time the calculation took
                long startTicks = System.DateTime.UtcNow.Ticks;
                long totalTicks = 0;

                //Prepare the path
                p.Prepare();

                AstarProfiler.EndFastProfile(0);

                if (!p.IsDone())
                {
                    //For debug uses, we set the last computed path to p, so we can view debug info on it in the editor (scene view).
                    astar.debugPath = p;

                    AstarProfiler.StartFastProfile(1);

                    //Initialize the path, now ready to begin search
                    p.Initialize();

                    AstarProfiler.EndFastProfile(1);

                    //The error can turn up in the Init function
                    while (!p.IsDone())
                    {
                        //Do some work on the path calculation.
                        //The function will return when it has taken too much time
                        //or when it has finished calculation
                        AstarProfiler.StartFastProfile(2);
                        p.CalculateStep(targetTick);
                        p.searchIterations++;

                        AstarProfiler.EndFastProfile(2);

                        // If the path has finished calculation, we can break here directly instead of sleeping
                        if (p.IsDone())
                        {
                            break;
                        }

                        // Yield/sleep so other threads can work
                        totalTicks += System.DateTime.UtcNow.Ticks - startTicks;
                        Thread.Sleep(0);
                        startTicks = System.DateTime.UtcNow.Ticks;

                        targetTick = startTicks + maxTicks;

                        // Cancel function (and thus the thread) if no more paths should be accepted.
                        // This is done when the A* object is about to be destroyed
                        // The path is returned and then this function will be terminated
                        if (queue.IsTerminating)
                        {
                            p.Error();
                        }
                    }

                    totalTicks += System.DateTime.UtcNow.Ticks - startTicks;
                    p.duration  = totalTicks * 0.0001F;

#if ProfileAstar
                    System.Threading.Interlocked.Increment(ref AstarPath.PathsCompleted);
                    System.Threading.Interlocked.Add(ref AstarPath.TotalSearchedNodes, p.searchedNodes);
                    System.Threading.Interlocked.Add(ref AstarPath.TotalSearchTime, totalTicks);
#endif
                }

                // Cleans up node tagging and other things
                p.Cleanup();

                AstarProfiler.StartFastProfile(9);

                if (p.immediateCallback != null)
                {
                    p.immediateCallback(p);
                }

                if (OnPathPostSearch != null)
                {
                    OnPathPostSearch(p);
                }

                // Push the path onto the return stack
                // It will be detected by the main Unity thread and returned as fast as possible (the next late update hopefully)
                returnQueue.Enqueue(p);

                // Will advance to ReturnQueue
                p.AdvanceState(PathState.ReturnQueue);

                AstarProfiler.EndFastProfile(9);

                // Wait a bit if we have calculated a lot of paths
                if (System.DateTime.UtcNow.Ticks > targetTick)
                {
                    Thread.Sleep(1);
                    targetTick = System.DateTime.UtcNow.Ticks + maxTicks;
                }
            }
#if !ASTAR_FAST_BUT_NO_EXCEPTIONS
        }

        catch (System.Exception e) {
#if !NETFX_CORE
            if (e is ThreadAbortException || e is ThreadControlQueue.QueueTerminationException)
#else
            if (e is ThreadControlQueue.QueueTerminationException)
#endif
            {
                if (astar.logPathResults == PathLog.Heavy)
                {
                    Debug.LogWarning("Shutting down pathfinding thread #" + threadInfo.threadIndex);
                }
                return;
            }
            Debug.LogException(e);
            Debug.LogError("Unhandled exception during pathfinding. Terminating.");
            //Unhandled exception, kill pathfinding
            queue.TerminateReceivers();
        }
#endif

            Debug.LogError("Error : This part should never be reached.");
            queue.ReceiverTerminated();
        }
Esempio n. 3
0
        /// <summary>
        /// Main pathfinding method (multithreaded).
        /// This method will calculate the paths in the pathfinding queue when multithreading is enabled.
        ///
        /// See: CalculatePaths
        /// See: StartPath
        /// </summary>
        void CalculatePathsThreaded(PathHandler pathHandler)
        {
#if UNITY_2017_3_OR_NEWER
            UnityEngine.Profiling.Profiler.BeginThreadProfiling("Pathfinding", "Pathfinding thread #" + (pathHandler.threadID + 1));
#endif

#if !ASTAR_FAST_BUT_NO_EXCEPTIONS
            try {
#endif

            // Max number of ticks we are allowed to continue working in one run.
            // One tick is 1/10000 of a millisecond.
            // We need to check once in a while if the thread should be stopped.
            long maxTicks   = (long)(10 * 10000);
            long targetTick = System.DateTime.UtcNow.Ticks + maxTicks;
            while (true)
            {
                // The path we are currently calculating
                Path path = queue.Pop();
#if UNITY_2017_3_OR_NEWER
                profilingSampler.Begin();
#endif
                // Access the internal implementation methods
                IPathInternals ipath = (IPathInternals)path;


                AstarProfiler.StartFastProfile(0);
                ipath.PrepareBase(pathHandler);

                // Now processing the path
                // Will advance to Processing
                ipath.AdvanceState(PathState.Processing);

                // Call some callbacks
                if (OnPathPreSearch != null)
                {
                    OnPathPreSearch(path);
                }

                // Tick for when the path started, used for calculating how long time the calculation took
                long startTicks = System.DateTime.UtcNow.Ticks;

                // Prepare the path
                ipath.Prepare();

                AstarProfiler.EndFastProfile(0);

                if (path.CompleteState == PathCompleteState.NotCalculated)
                {
                    // For visualization purposes, we set the last computed path to p, so we can view debug info on it in the editor (scene view).
                    astar.debugPathData = ipath.PathHandler;
                    astar.debugPathID   = path.pathID;

                    AstarProfiler.StartFastProfile(1);

                    // Initialize the path, now ready to begin search
                    ipath.Initialize();

                    AstarProfiler.EndFastProfile(1);

                    // Loop while the path has not been fully calculated
                    while (path.CompleteState == PathCompleteState.NotCalculated)
                    {
                        // Do some work on the path calculation.
                        // The function will return when it has taken too much time
                        // or when it has finished calculation
                        AstarProfiler.StartFastProfile(2);
                        ipath.CalculateStep(targetTick);
                        AstarProfiler.EndFastProfile(2);

                        targetTick = System.DateTime.UtcNow.Ticks + maxTicks;

                        // Cancel function (and thus the thread) if no more paths should be accepted.
                        // This is done when the A* object is about to be destroyed
                        // The path is returned and then this function will be terminated
                        if (queue.IsTerminating)
                        {
                            path.FailWithError("AstarPath object destroyed");
                        }
                    }

                    path.duration = (System.DateTime.UtcNow.Ticks - startTicks) * 0.0001F;

#if ProfileAstar
                    System.Threading.Interlocked.Increment(ref AstarPath.PathsCompleted);
                    System.Threading.Interlocked.Add(ref AstarPath.TotalSearchTime, System.DateTime.UtcNow.Ticks - startTicks);
#endif
                }

                // Cleans up node tagging and other things
                ipath.Cleanup();

                AstarProfiler.StartFastProfile(9);

                if (path.immediateCallback != null)
                {
                    path.immediateCallback(path);
                }

                if (OnPathPostSearch != null)
                {
                    OnPathPostSearch(path);
                }

                // Push the path onto the return stack
                // It will be detected by the main Unity thread and returned as fast as possible (the next late update hopefully)
                returnQueue.Enqueue(path);

                // Will advance to ReturnQueue
                ipath.AdvanceState(PathState.ReturnQueue);

                AstarProfiler.EndFastProfile(9);
#if UNITY_2017_3_OR_NEWER
                profilingSampler.End();
#endif
            }
#if !ASTAR_FAST_BUT_NO_EXCEPTIONS
        }

        catch (System.Exception e) {
#if !NETFX_CORE
            if (e is ThreadAbortException || e is ThreadControlQueue.QueueTerminationException)
#else
            if (e is ThreadControlQueue.QueueTerminationException)
#endif
            {
                if (astar.logPathResults == PathLog.Heavy)
                {
                    Debug.LogWarning("Shutting down pathfinding thread #" + pathHandler.threadID);
                }
                return;
            }
            Debug.LogException(e);
            Debug.LogError("Unhandled exception during pathfinding. Terminating.");
            // Unhandled exception, kill pathfinding
            queue.TerminateReceivers();
        } finally {
#if UNITY_2017_3_OR_NEWER
            UnityEngine.Profiling.Profiler.EndThreadProfiling();
#endif
        }
#endif

            Debug.LogError("Error : This part should never be reached.");
            queue.ReceiverTerminated();
        }
 // Token: 0x06002377 RID: 9079 RVA: 0x001995EC File Offset: 0x001977EC
 private void CalculatePathsThreaded(PathHandler pathHandler)
 {
     try
     {
         long num        = 100000L;
         long targetTick = DateTime.UtcNow.Ticks + num;
         for (;;)
         {
             Path           path          = this.queue.Pop();
             IPathInternals pathInternals = path;
             pathInternals.PrepareBase(pathHandler);
             pathInternals.AdvanceState(PathState.Processing);
             if (this.OnPathPreSearch != null)
             {
                 this.OnPathPreSearch(path);
             }
             long ticks = DateTime.UtcNow.Ticks;
             pathInternals.Prepare();
             if (!path.IsDone())
             {
                 this.astar.debugPathData = pathInternals.PathHandler;
                 this.astar.debugPathID   = path.pathID;
                 pathInternals.Initialize();
                 while (!path.IsDone())
                 {
                     pathInternals.CalculateStep(targetTick);
                     targetTick = DateTime.UtcNow.Ticks + num;
                     if (this.queue.IsTerminating)
                     {
                         path.FailWithError("AstarPath object destroyed");
                     }
                 }
                 path.duration = (float)(DateTime.UtcNow.Ticks - ticks) * 0.0001f;
             }
             pathInternals.Cleanup();
             if (path.immediateCallback != null)
             {
                 path.immediateCallback(path);
             }
             if (this.OnPathPostSearch != null)
             {
                 this.OnPathPostSearch(path);
             }
             this.returnQueue.Enqueue(path);
             pathInternals.AdvanceState(PathState.ReturnQueue);
         }
     }
     catch (Exception ex)
     {
         if (ex is ThreadAbortException || ex is ThreadControlQueue.QueueTerminationException)
         {
             if (this.astar.logPathResults == PathLog.Heavy)
             {
                 Debug.LogWarning("Shutting down pathfinding thread #" + pathHandler.threadID);
             }
             return;
         }
         Debug.LogException(ex);
         Debug.LogError("Unhandled exception during pathfinding. Terminating.");
         this.queue.TerminateReceivers();
     }
     Debug.LogError("Error : This part should never be reached.");
     this.queue.ReceiverTerminated();
 }