refactor: simplify for size
This commit is contained in:
@@ -8,21 +8,25 @@ export class EffectScope {
|
||||
active = true
|
||||
effects: ReactiveEffect[] = []
|
||||
cleanups: (() => void)[] = []
|
||||
|
||||
parent: EffectScope | undefined
|
||||
private children: EffectScope[] | undefined
|
||||
private parentIndex: number | undefined
|
||||
scopes: EffectScope[] | undefined
|
||||
/**
|
||||
* track a child scope's index in its parent's scopes array for optimized
|
||||
* removal
|
||||
*/
|
||||
private index: number | undefined
|
||||
|
||||
constructor(detached = false) {
|
||||
if (!detached) {
|
||||
this.recordEffectScope()
|
||||
if (!detached && activeEffectScope) {
|
||||
this.parent = activeEffectScope
|
||||
this.index =
|
||||
(activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(
|
||||
this
|
||||
) - 1
|
||||
}
|
||||
}
|
||||
|
||||
get scopes(): EffectScope[] {
|
||||
if (!this.children) this.children = []
|
||||
return this.children
|
||||
}
|
||||
|
||||
run<T>(fn: () => T): T | undefined {
|
||||
if (this.active) {
|
||||
try {
|
||||
@@ -50,33 +54,25 @@ export class EffectScope {
|
||||
}
|
||||
}
|
||||
|
||||
stop() {
|
||||
stop(fromParent?: boolean) {
|
||||
if (this.active) {
|
||||
this.effects.forEach(e => e.stop())
|
||||
this.children?.forEach(e => e.stop())
|
||||
this.cleanups.forEach(cleanup => cleanup())
|
||||
this.parent?.derefChildScope(this)
|
||||
if (this.scopes) {
|
||||
this.scopes.forEach(e => e.stop(true))
|
||||
}
|
||||
// nested scope, dereference from parent to avoid memory leaks
|
||||
if (this.parent && !fromParent) {
|
||||
// optimized O(1) removal
|
||||
const last = this.parent.scopes!.pop()
|
||||
if (last && last !== this) {
|
||||
this.parent.scopes![this.index!] = last
|
||||
last.index = this.index!
|
||||
}
|
||||
}
|
||||
this.active = false
|
||||
}
|
||||
}
|
||||
|
||||
private recordEffectScope() {
|
||||
const parent = activeEffectScope
|
||||
if (parent && parent.active) {
|
||||
this.parent = parent
|
||||
this.parentIndex = parent.scopes.push(this) - 1
|
||||
}
|
||||
}
|
||||
|
||||
private derefChildScope(scope: EffectScope) {
|
||||
// reuse the freed index by moving the last array entry
|
||||
const last = this.scopes.pop()
|
||||
if (last && last !== scope) {
|
||||
const childIndex = scope.parentIndex!
|
||||
this.scopes[childIndex] = last
|
||||
last.parentIndex = childIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function effectScope(detached?: boolean) {
|
||||
|
||||
Reference in New Issue
Block a user