This commit is contained in:
ImportWU 2025-06-27 22:10:06 +08:00 committed by GitHub
commit 9da14c40c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 44 additions and 31 deletions

View File

@ -32,21 +32,24 @@ export class EffectScope {
* record undetached scopes * record undetached scopes
* @internal * @internal
*/ */
scopes: EffectScope[] | undefined scopes: EffectScope | undefined
scopesTail: EffectScope | undefined
/** /**
* track a child scope's index in its parent's scopes array for optimized * sibling scope
* removal
* @internal
*/ */
private index: number | undefined prevEffectScope: EffectScope | undefined
nextEffectScope: EffectScope | undefined
constructor(public detached = false) { constructor(public detached = false) {
this.parent = activeEffectScope this.parent = activeEffectScope
if (!detached && activeEffectScope) { if (!detached && activeEffectScope) {
this.index = if (activeEffectScope.scopesTail) {
(activeEffectScope.scopes || (activeEffectScope.scopes = [])).push( this.prevEffectScope = activeEffectScope.scopesTail
this, activeEffectScope.scopesTail.nextEffectScope = this
) - 1 activeEffectScope.scopesTail = this
} else {
activeEffectScope.scopes = activeEffectScope.scopesTail = this
}
} }
} }
@ -57,13 +60,14 @@ export class EffectScope {
pause(): void { pause(): void {
if (this._active) { if (this._active) {
this._isPaused = true this._isPaused = true
let i, l for (
if (this.scopes) { let child = this.scopes;
for (i = 0, l = this.scopes.length; i < l; i++) { child != undefined;
this.scopes[i].pause() child = child.nextEffectScope
} ) {
child.pause()
} }
for (i = 0, l = this.effects.length; i < l; i++) { for (let i = 0, l = this.effects.length; i < l; i++) {
this.effects[i].pause() this.effects[i].pause()
} }
} }
@ -76,13 +80,14 @@ export class EffectScope {
if (this._active) { if (this._active) {
if (this._isPaused) { if (this._isPaused) {
this._isPaused = false this._isPaused = false
let i, l for (
if (this.scopes) { let child = this.scopes;
for (i = 0, l = this.scopes.length; i < l; i++) { child != undefined;
this.scopes[i].resume() child = child.nextEffectScope
} ) {
child.resume()
} }
for (i = 0, l = this.effects.length; i < l; i++) { for (let i = 0, l = this.effects.length; i < l; i++) {
this.effects[i].resume() this.effects[i].resume()
} }
} }
@ -140,20 +145,28 @@ export class EffectScope {
} }
this.cleanups.length = 0 this.cleanups.length = 0
if (this.scopes) { for (
for (i = 0, l = this.scopes.length; i < l; i++) { let child = this.scopes;
this.scopes[i].stop(true) child != undefined;
} child = child.nextEffectScope
this.scopes.length = 0 ) {
child.stop(true)
} }
this.scopes = this.scopesTail = undefined
// nested scope, dereference from parent to avoid memory leaks // nested scope, dereference from parent to avoid memory leaks
if (!this.detached && this.parent && !fromParent) { if (!this.detached && this.parent && !fromParent) {
// optimized O(1) removal if (this.prevEffectScope) {
const last = this.parent.scopes!.pop() this.prevEffectScope.nextEffectScope = this.nextEffectScope
if (last && last !== this) { }
this.parent.scopes![this.index!] = last if (this.nextEffectScope) {
last.index = this.index! this.nextEffectScope.prevEffectScope = this.prevEffectScope
}
if (this.parent.scopes == this) {
this.parent.scopes = this.nextEffectScope
}
if (this.parent.scopesTail == this) {
this.parent.scopesTail = this.prevEffectScope
} }
} }
this.parent = undefined this.parent = undefined