22 PATHFINDING_PROCESS_LOOP_RATE ,
33 PATHFINDING_PROCESS_NEXT_DIRECTIINS_DIAGONAL ,
44 PATHFINDING_PROCESS_NEXT_DIRECTIINS_STRAIGHT ,
5- PATHFINDING_PROCESS_TASK_PROCESS_RATE ,
5+ PATHFINDING_PROCESS_TASK_HANDLING_MAX_STACK_SIZE ,
66} from './const' ;
77
88import type { PathfindingProcessConfig } from './types' ;
@@ -21,26 +21,27 @@ export class PathfindingProcess {
2121
2222 private queue : PathfindingTask [ ] = [ ] ;
2323
24- private timer : NodeJS . Timeout | null = null ;
24+ private readonly timer : NodeJS . Timeout ;
2525
26- private readonly taskProcessRate : number ;
27-
28- private readonly loopRate : number ;
26+ private processing : boolean = false ;
2927
3028 constructor ( {
31- taskProcessRate = PATHFINDING_PROCESS_TASK_PROCESS_RATE ,
3229 loopRate = PATHFINDING_PROCESS_LOOP_RATE ,
3330 } : PathfindingProcessConfig ) {
34- this . taskProcessRate = taskProcessRate ;
35- this . loopRate = loopRate ;
36-
37- this . handleTask ( ) ;
31+ this . timer = setInterval ( ( ) => {
32+ try {
33+ if ( ! this . processing ) {
34+ this . processing = true ;
35+ this . handleTask ( ) ;
36+ }
37+ } catch ( error ) {
38+ console . error ( 'Pathfinding process error:' , error ) ;
39+ }
40+ } , loopRate ) ;
3841 }
3942
4043 public destroy ( ) : void {
41- if ( this . timer ) {
42- clearTimeout ( this . timer ) ;
43- }
44+ clearTimeout ( this . timer ) ;
4445 }
4546
4647 public createTask ( task : PathfindingTask ) : void {
@@ -101,76 +102,77 @@ export class PathfindingProcess {
101102 grid [ position . y ] [ position . x ] = state ;
102103 }
103104
104- private handleTask ( ) : void {
105+ private handleTask ( stackSize : number = 0 ) : void {
105106 const task = this . queue [ 0 ] ;
106107 if ( ! task ) {
107- this . timer = setTimeout ( ( ) => {
108- this . timer = null ;
109- this . handleTask ( ) ;
110- } , this . loopRate ) ;
108+ this . processing = false ;
111109 return ;
112110 }
113111
114112 const next = ( ) => {
115- setTimeout ( ( ) => {
116- this . handleTask ( ) ;
117- } , this . taskProcessRate ) ;
113+ if ( stackSize >= PATHFINDING_PROCESS_TASK_HANDLING_MAX_STACK_SIZE ) {
114+ setTimeout ( ( ) => {
115+ this . handleTask ( ) ;
116+ } ) ;
117+ } else {
118+ this . handleTask ( stackSize + 1 ) ;
119+ }
118120 } ;
119121
120122 const complete = ( result : PathfindingTaskResultRaw ) => {
121123 this . queue . shift ( ) ;
122124 task . complete ( result ) ;
125+ this . processing = false ;
123126 } ;
124127
125128 try {
126129 const currentNode = task . takeLastNode ( ) ;
127- if ( currentNode ) {
128- if ( task . isVisited ( currentNode . position ) ) {
129- next ( ) ;
130+ if ( ! currentNode ) {
131+ return complete ( {
132+ path : null ,
133+ weight : Infinity ,
134+ } ) ;
135+ }
136+
137+ if ( task . isVisited ( currentNode . position ) ) {
138+ return next ( ) ;
139+ }
140+
141+ task . markVisited ( currentNode . position ) ;
142+
143+ if (
144+ currentNode . position . x === task . to . x &&
145+ currentNode . position . y === task . to . y
146+ ) {
147+ return complete ( currentNode . compute ( ) ) ;
148+ }
149+
150+ this . getNextDirections ( task , currentNode ) . forEach ( ( offset ) => {
151+ const position = {
152+ x : currentNode . position . x + offset . x ,
153+ y : currentNode . position . y + offset . y ,
154+ } ;
155+
156+ if ( task . isVisited ( position ) ) {
130157 return ;
131158 }
132159
133- task . markVisited ( currentNode . position ) ;
160+ const weights = this . weights . get ( task . idLayer ) ?? [ ] ;
161+ const nextWeight = task . getNextWeight ( currentNode , offset , weights ) ;
162+ const nextNode = task . pickNode ( position ) ;
134163
135- if (
136- currentNode . position . x === task . to . x &&
137- currentNode . position . y === task . to . y
138- ) {
139- complete ( currentNode . compute ( ) ) ;
164+ if ( nextNode ) {
165+ if ( nextWeight < nextNode . getWeight ( ) ) {
166+ task . rewriteNode ( currentNode , nextNode , nextWeight ) ;
167+ }
140168 } else {
141- this . getNextDirections ( task , currentNode ) . forEach ( ( offset ) => {
142- const position = {
143- x : currentNode . position . x + offset . x ,
144- y : currentNode . position . y + offset . y ,
145- } ;
146-
147- if ( task . isVisited ( position ) ) {
148- return ;
149- }
150-
151- const weights = this . weights . get ( task . idLayer ) ?? [ ] ;
152- const nextWeight = task . getNextWeight ( currentNode , offset , weights ) ;
153- const nextNode = task . pickNode ( position ) ;
154-
155- if ( nextNode ) {
156- if ( nextWeight < nextNode . getWeight ( ) ) {
157- task . rewriteNode ( currentNode , nextNode , nextWeight ) ;
158- }
159- } else {
160- task . addNode ( currentNode , position , nextWeight ) ;
161- }
162- } ) ;
169+ task . addNode ( currentNode , position , nextWeight ) ;
163170 }
164- } else {
165- complete ( {
166- path : null ,
167- weight : Infinity ,
168- } ) ;
169- }
171+ } ) ;
170172
171173 next ( ) ;
172174 } catch ( error ) {
173- console . error ( 'Pathfinding process error:' , error ) ;
175+ console . error ( 'Pathfinding handle task error:' , error ) ;
174176 complete ( {
175177 path : null ,
176178 weight : Infinity ,
0 commit comments