@@ -4,7 +4,7 @@ export interface IEffect extends Subscriber {
44}
55
66export interface IComputed extends Dependency , Subscriber {
7- update ( ) : void ;
7+ update ( ) : boolean ;
88}
99
1010export interface Dependency {
@@ -169,7 +169,7 @@ export namespace Dependency {
169169 let link : Link | undefined = subs ;
170170 let dep = subs . dep ;
171171 let dirtyLevel = DirtyLevels . Dirty ;
172- let remainingQuantity = 0 ;
172+ let stack = 0 ;
173173
174174 do {
175175 if ( link !== undefined ) {
@@ -193,7 +193,7 @@ export namespace Dependency {
193193 } else {
194194 dirtyLevel = DirtyLevels . MaybeDirty ;
195195 }
196- remainingQuantity ++ ;
196+ stack ++ ;
197197
198198 continue ;
199199 }
@@ -223,7 +223,7 @@ export namespace Dependency {
223223 } else {
224224 dirtyLevel = DirtyLevels . MaybeDirty ;
225225 }
226- remainingQuantity ++ ;
226+ stack ++ ;
227227
228228 continue ;
229229 } else if ( 'notify' in sub ) {
@@ -242,17 +242,17 @@ export namespace Dependency {
242242 continue ;
243243 }
244244
245- if ( remainingQuantity !== 0 ) {
245+ if ( stack > 0 ) {
246246 const depsTail = ( dep as IComputed | IEffect ) . depsTail ! ;
247247 const prevLink = depsTail . nextDep ! ;
248248 const prevSub = prevLink . sub ;
249249
250250 depsTail . nextDep = undefined ;
251251 dep = prevLink . dep ;
252252 link = prevLink . nextSub ;
253- remainingQuantity -- ;
253+ stack -- ;
254254
255- if ( remainingQuantity === 0 ) {
255+ if ( stack === 0 ) {
256256 dirtyLevel = DirtyLevels . Dirty ;
257257 } else if ( 'notify' in dep ) {
258258 dirtyLevel = DirtyLevels . SideEffectsOnly ;
@@ -282,43 +282,41 @@ export namespace Subscriber {
282282
283283 const system = System ;
284284
285- export function resolveMaybeDirty ( sub : IComputed | IEffect , depth = 0 ) : void {
286- let link = sub . deps ;
287-
288- while ( link !== undefined ) {
285+ export function checkDirty ( link : Link , depth = 0 ) : boolean {
286+ do {
289287 const dep = link . dep ;
290288 if ( 'update' in dep ) {
291- let dirtyLevel = dep . dirtyLevel ;
292-
293- if ( dirtyLevel === DirtyLevels . MaybeDirty ) {
294- if ( depth >= 4 ) {
295- resolveMaybeDirtyNonRecursive ( dep ) ;
289+ const dirtyLevel = dep . dirtyLevel ;
290+ if ( dirtyLevel !== DirtyLevels . None ) {
291+ if (
292+ dirtyLevel === DirtyLevels . Dirty
293+ || (
294+ depth < 4
295+ ? checkDirty ( dep . deps ! , depth + 1 )
296+ : checkDirtyNonRecursive ( dep )
297+ )
298+ ) {
299+ if ( dep . update ( ) ) {
300+ Dependency . propagate ( dep . subs ! ) ;
301+ return true ;
302+ }
296303 } else {
297- resolveMaybeDirty ( dep , depth + 1 ) ;
298- }
299- dirtyLevel = dep . dirtyLevel ;
300- }
301- if ( dirtyLevel === DirtyLevels . Dirty ) {
302- dep . update ( ) ;
303- if ( sub . dirtyLevel === DirtyLevels . Dirty ) {
304- break ;
304+ dep . dirtyLevel = DirtyLevels . None ;
305305 }
306306 }
307307 }
308- link = link . nextDep ;
309- }
310-
311- if ( sub . dirtyLevel === DirtyLevels . MaybeDirty ) {
312- sub . dirtyLevel = DirtyLevels . None ;
313- }
308+ link = link . nextDep ! ;
309+ } while ( link !== undefined ) ;
310+ return false ;
314311 }
315312
316- export function resolveMaybeDirtyNonRecursive ( sub : IComputed | IEffect ) : void {
317- let link = sub . deps ;
318- let remaining = 0 ;
313+ function checkDirtyNonRecursive ( sub : Link [ 'sub' ] ) : boolean {
314+ let subDirtyLevel = DirtyLevels . MaybeDirty ;
315+ let link = sub . deps ! ;
316+ let stack = 0 ;
319317
320318 do {
321- if ( link !== undefined ) {
319+ if ( subDirtyLevel === DirtyLevels . MaybeDirty ) {
322320 const dep = link . dep ;
323321
324322 if ( 'update' in dep ) {
@@ -327,61 +325,51 @@ export namespace Subscriber {
327325 if ( depDirtyLevel === DirtyLevels . MaybeDirty ) {
328326 dep . subs ! . prevSub = link ;
329327 sub = dep ;
330- link = dep . deps ;
331- remaining ++ ;
332-
328+ link = dep . deps ! ;
329+ stack ++ ;
333330 continue ;
334- } else if ( depDirtyLevel === DirtyLevels . Dirty ) {
335- dep . update ( ) ;
336-
337- if ( sub . dirtyLevel === DirtyLevels . Dirty ) {
338- if ( remaining !== 0 ) {
339- const subSubs = ( sub as IComputed ) . subs ! ;
340- const prevLink = subSubs . prevSub ! ;
341- ( sub as IComputed ) . update ( ) ;
342- subSubs . prevSub = undefined ;
343- sub = prevLink . sub as IComputed | IEffect ;
344- link = prevLink . nextDep ;
345- remaining -- ;
346- continue ;
347- }
348-
349- break ;
331+ }
332+ if ( depDirtyLevel === DirtyLevels . Dirty ) {
333+ if ( dep . update ( ) ) {
334+ Dependency . propagate ( dep . subs ! ) ;
335+ subDirtyLevel = DirtyLevels . Dirty ;
336+ continue ;
350337 }
351338 }
352339 }
353340
354- link = link . nextDep ;
341+ link = link . nextDep ! ;
342+ if ( link === undefined ) {
343+ subDirtyLevel = DirtyLevels . None ;
344+ }
355345 continue ;
356346 }
357347
358- const dirtyLevel = sub . dirtyLevel ;
359-
360- if ( dirtyLevel === DirtyLevels . MaybeDirty ) {
361- sub . dirtyLevel = DirtyLevels . None ;
362- if ( remaining !== 0 ) {
363- const subSubs = ( sub as IComputed ) . subs ! ;
364- const prevLink = subSubs . prevSub ! ;
365- subSubs . prevSub = undefined ;
366- sub = prevLink . sub as IComputed | IEffect ;
367- link = prevLink . nextDep ;
368- remaining -- ;
369- continue ;
370- }
371- } else if ( remaining !== 0 ) {
372- if ( dirtyLevel === DirtyLevels . Dirty ) {
373- ( sub as IComputed ) . update ( ) ;
374- }
348+ if ( stack > 0 ) {
349+ stack -- ;
375350 const subSubs = ( sub as IComputed ) . subs ! ;
376351 const prevLink = subSubs . prevSub ! ;
377352 subSubs . prevSub = undefined ;
378- sub = prevLink . sub as IComputed | IEffect ;
379- link = prevLink . nextDep ;
380- remaining -- ;
353+ if ( subDirtyLevel === DirtyLevels . Dirty ) {
354+ if ( ( sub as IComputed ) . update ( ) ) {
355+ Dependency . propagate ( subSubs ) ;
356+ sub = prevLink . sub ;
357+ continue ;
358+ }
359+ } else {
360+ sub . dirtyLevel = DirtyLevels . None ;
361+ }
362+ link = prevLink . nextDep ! ;
363+ sub = prevLink . sub ;
364+ if ( link !== undefined ) {
365+ subDirtyLevel = DirtyLevels . MaybeDirty ;
366+ } else {
367+ subDirtyLevel = DirtyLevels . None ;
368+ }
381369 continue ;
382370 }
383371
384- break ;
372+ return subDirtyLevel === DirtyLevels . Dirty ;
385373 } while ( true ) ;
386374 }
387375
0 commit comments