@@ -7,9 +7,10 @@ const getKey = ( x, y, l ) => {
77} ;
88
99// Ref-counts active requests per (x, y, level) tile and fires a 'toggle' event when a tile
10- // transitions between inactive (ref === 0) and active (ref > 0). Tiles can also be marked as
11- // "loading", which will lock an existing parent tile as active to ensure coverage until the
12- // child has loaded
10+ // transitions between inactive and active. A tile is considered active when its own 'active'
11+ // ref is non-zero AND it has no in-flight loads of its own ('loading' === 0). Tiles can also
12+ // be marked as "loading", which will lock an existing parent tile as active to ensure coverage
13+ // until the child has loaded.
1314export class HierarchicalLock extends EventDispatcher {
1415
1516 constructor ( ) {
@@ -51,11 +52,12 @@ export class HierarchicalLock extends EventDispatcher {
5152 }
5253
5354 const childLock = locks [ childKey ] ;
54- childLock . loadingCount ++ ;
55+ childLock . loading ++ ;
56+ this . _checkToggle ( childKey ) ;
5557
5658 // Only lock the ancestor on the first markLoading call — subsequent concurrent
5759 // loads for the same tile share the same ancestor hold
58- if ( childLock . loadingCount === 1 ) {
60+ if ( childLock . loading === 1 ) {
5961
6062 while ( al > 0 ) {
6163
@@ -64,7 +66,7 @@ export class HierarchicalLock extends EventDispatcher {
6466 ay >>= 1 ;
6567
6668 const ancestorKey = getKey ( ax , ay , al ) ;
67- if ( ancestorKey in locks ) {
69+ if ( ancestorKey in locks && locks [ ancestorKey ] . dispatched ) {
6870
6971 // save the reference so we can unlock it later when load is finished
7072 this . _incrLock ( ax , ay , al , true ) ;
@@ -91,10 +93,11 @@ export class HierarchicalLock extends EventDispatcher {
9193
9294 }
9395
94- childLock . loadingCount -- ;
96+ childLock . loading -- ;
97+ this . _checkToggle ( childKey ) ;
9598
9699 // Release the ancestor only when the last concurrent load finishes
97- if ( childLock . loadingCount === 0 && childLock . lockedAncestor ) {
100+ if ( childLock . loading === 0 && childLock . lockedAncestor ) {
98101
99102 const { x : ax , y : ay , level : al } = childLock . lockedAncestor ;
100103 this . _incrLock ( ax , ay , al , false ) ;
@@ -111,7 +114,7 @@ export class HierarchicalLock extends EventDispatcher {
111114 _tryDeleteLock ( key ) {
112115
113116 const lock = this . locks [ key ] ;
114- if ( lock && lock . ref === 0 && lock . lockedAncestor === null && lock . loadingCount === 0 ) {
117+ if ( lock && lock . active === 0 && lock . lockedAncestor === null && lock . loading === 0 ) {
115118
116119 delete this . locks [ key ] ;
117120
@@ -125,14 +128,34 @@ export class HierarchicalLock extends EventDispatcher {
125128 x,
126129 y,
127130 level,
128- ref : 0 ,
131+ active : 0 ,
132+ loading : 0 ,
129133 dispatched : false ,
130134 lockedAncestor : null ,
131- loadingCount : 0 ,
132135 } ;
133136
134137 }
135138
139+ _checkToggle ( key ) {
140+
141+ const { locks } = this ;
142+ const lock = locks [ key ] ;
143+ if ( ! lock ) {
144+
145+ return ;
146+
147+ }
148+
149+ const shouldShow = lock . loading === 0 && lock . active > 0 ;
150+ if ( shouldShow !== lock . dispatched ) {
151+
152+ lock . dispatched = shouldShow ;
153+ this . dispatchEvent ( { type : 'toggle' , active : shouldShow , x : lock . x , y : lock . y , level : lock . level } ) ;
154+
155+ }
156+
157+ }
158+
136159 _incrLock ( x , y , level , incr ) {
137160
138161 const { locks } = this ;
@@ -145,21 +168,14 @@ export class HierarchicalLock extends EventDispatcher {
145168 }
146169
147170 const lock = locks [ key ] ;
148- lock . ref += incr ? 1 : - 1 ;
149- if ( lock . ref < 0 ) {
171+ lock . active += incr ? 1 : - 1 ;
172+ if ( lock . active < 0 ) {
150173
151174 throw new Error ( 'HierarchicalLock: ref count went negative — mismatched markActive/markInactive calls.' ) ;
152175
153176 }
154177
155- const active = lock . ref > 0 ;
156- if ( active !== lock . dispatched ) {
157-
158- lock . dispatched = active ;
159- this . dispatchEvent ( { type : 'toggle' , active, x, y, level } ) ;
160-
161- }
162-
178+ this . _checkToggle ( key ) ;
163179 this . _tryDeleteLock ( key ) ;
164180
165181 }
0 commit comments