@@ -571,6 +571,53 @@ export function schedule_effect(signal) {
571
571
current_queued_root_effects . push ( effect ) ;
572
572
}
573
573
574
+ /**
575
+ * @param {Effect } effect
576
+ * @param {Effect[] } effects
577
+ */
578
+ function process_effect_children ( effect , effects ) {
579
+ var current = effect . first ;
580
+
581
+ while ( current !== null ) {
582
+ var next = current . next ;
583
+ process_effect ( current , effects ) ;
584
+ current = next ;
585
+ }
586
+ }
587
+
588
+ /**
589
+ * @param {Effect } effect
590
+ * @param {Effect[] } effects
591
+ */
592
+ function process_effect ( effect , effects ) {
593
+ var flags = effect . f ;
594
+ // TODO: we probably don't need to check for destroyed as it shouldn't be encountered?
595
+ var is_active = ( flags & ( DESTROYED | INERT ) ) === 0 ;
596
+ var is_branch = ( flags & BRANCH_EFFECT ) !== 0 ;
597
+ var is_clean = ( flags & CLEAN ) !== 0 ;
598
+
599
+ // Skip this branch if it's clean
600
+ if ( is_active && ( ! is_branch || ! is_clean ) ) {
601
+ if ( is_branch ) {
602
+ set_signal_status ( effect , CLEAN ) ;
603
+ }
604
+
605
+ if ( ( flags & RENDER_EFFECT ) !== 0 ) {
606
+ if ( ! is_branch && check_dirtiness ( effect ) ) {
607
+ update_effect ( effect ) ;
608
+ }
609
+
610
+ process_effect_children ( effect , effects ) ;
611
+ } else if ( ( flags & EFFECT ) !== 0 ) {
612
+ if ( is_branch || is_clean ) {
613
+ process_effect_children ( effect , effects ) ;
614
+ } else {
615
+ effects . push ( effect ) ;
616
+ }
617
+ }
618
+ }
619
+ }
620
+
574
621
/**
575
622
*
576
623
* This function both runs render effects and collects user effects in topological order
@@ -583,70 +630,13 @@ export function schedule_effect(signal) {
583
630
* @returns {void }
584
631
*/
585
632
function process_effects ( effect , collected_effects ) {
586
- var current_effect = effect . first ;
633
+ /** @type { Effect[] } */
587
634
var effects = [ ] ;
588
-
589
- main_loop: while ( current_effect !== null ) {
590
- var flags = current_effect . f ;
591
- // TODO: we probably don't need to check for destroyed as it shouldn't be encountered?
592
- var is_active = ( flags & ( DESTROYED | INERT ) ) === 0 ;
593
- var is_branch = flags & BRANCH_EFFECT ;
594
- var is_clean = ( flags & CLEAN ) !== 0 ;
595
- var child = current_effect . first ;
596
-
597
- // Skip this branch if it's clean
598
- if ( is_active && ( ! is_branch || ! is_clean ) ) {
599
- if ( is_branch ) {
600
- set_signal_status ( current_effect , CLEAN ) ;
601
- }
602
-
603
- if ( ( flags & RENDER_EFFECT ) !== 0 ) {
604
- if ( ! is_branch && check_dirtiness ( current_effect ) ) {
605
- update_effect ( current_effect ) ;
606
- // Child might have been mutated since running the effect
607
- child = current_effect . first ;
608
- }
609
-
610
- if ( child !== null ) {
611
- current_effect = child ;
612
- continue ;
613
- }
614
- } else if ( ( flags & EFFECT ) !== 0 ) {
615
- if ( is_branch || is_clean ) {
616
- if ( child !== null ) {
617
- current_effect = child ;
618
- continue ;
619
- }
620
- } else {
621
- effects . push ( current_effect ) ;
622
- }
623
- }
624
- }
625
- var sibling = current_effect . next ;
626
-
627
- if ( sibling === null ) {
628
- let parent = current_effect . parent ;
629
-
630
- while ( parent !== null ) {
631
- if ( effect === parent ) {
632
- break main_loop;
633
- }
634
- var parent_sibling = parent . next ;
635
- if ( parent_sibling !== null ) {
636
- current_effect = parent_sibling ;
637
- continue main_loop;
638
- }
639
- parent = parent . parent ;
640
- }
641
- }
642
-
643
- current_effect = sibling ;
644
- }
645
-
635
+ process_effect_children ( effect , effects ) ;
646
636
// We might be dealing with many effects here, far more than can be spread into
647
637
// an array push call (callstack overflow). So let's deal with each effect in a loop.
648
638
for ( var i = 0 ; i < effects . length ; i ++ ) {
649
- child = effects [ i ] ;
639
+ var child = effects [ i ] ;
650
640
collected_effects . push ( child ) ;
651
641
process_effects ( child , collected_effects ) ;
652
642
}
0 commit comments