Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/memory leak #4009

Merged
merged 3 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/x6-common/src/__tests__/dom/event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,16 @@ describe('EventDom', () => {
expect(() => div.off('click', false)).not.toThrowError()
})

it('should do noting for elem which do not bind any events', () => {
it('should do nothing for elem which do not bind any events', () => {
const div = new EventDom()
expect(() => div.off()).not.toThrowError()
})

it('should do nothing for unexist event', () => {
const div = new EventDom()
div.on('whatever', () => {})
expect(() => div.off('unexist')).not.toThrowError()
})
})

describe('trigger()', () => {
Expand Down
10 changes: 9 additions & 1 deletion packages/x6-common/src/common/basecoat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { EventArgs } from '../event/types'
import { ObjectExt } from '../object'
import { Disposable } from './disposable'

export class Basecoat<A extends EventArgs = any> extends Events<A> {}
export class Basecoat<A extends EventArgs = any>
extends Events<A>
implements Disposable
{
@Disposable.dispose()
dispose() {
this.off()
}
}

export interface Basecoat extends Disposable {}

Expand Down
5 changes: 4 additions & 1 deletion packages/x6-common/src/dom/event/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ export namespace Core {
let type = originType
const hook = EventHook.get(type)
type = (selector ? hook.delegateType : hook.bindType) || type
const bag = events[type] || {}
const bag = events[type]
if (!bag) {
return
}
const rns =
namespaces.length > 0
? new RegExp(`(^|\\.)${namespaces.join('\\.(?:.*\\.|)')}(\\.|$)`)
Expand Down
5 changes: 2 additions & 3 deletions packages/x6/src/graph/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@ export class Graph extends Basecoat<EventArgs> {
const aboutToChangePlugins = this.getPlugins(postPlugins)
aboutToChangePlugins?.forEach((plugin) => {
plugin.dispose()
this.installedPlugins.delete(plugin)
})
return this
}
Expand All @@ -1273,11 +1274,9 @@ export class Graph extends Basecoat<EventArgs> {
@Basecoat.dispose()
dispose(clean = true) {
if (clean) {
this.clearCells()
this.model.dispose()
}

this.off()

this.css.dispose()
this.defs.dispose()
this.grid.dispose()
Expand Down
5 changes: 5 additions & 0 deletions packages/x6/src/model/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,11 @@ export class Collection extends Basecoat<Collection.EventArgs> {
this.cells = []
this.map = {}
}

@Collection.dispose()
dispose() {
this.reset([])
}
}

export namespace Collection {
Expand Down
5 changes: 5 additions & 0 deletions packages/x6/src/model/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,11 @@ export class Model extends Basecoat<Model.EventArgs> {
}

// #endregion

@Model.dispose()
dispose() {
this.collection.dispose()
}
}

export namespace Model {
Expand Down
5 changes: 5 additions & 0 deletions packages/x6/src/renderer/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,11 @@ export class Scheduler extends Disposable {
@Disposable.dispose()
dispose() {
this.stopListening()
// clear views
Object.keys(this.views).forEach((id) => {
this.views[id].view.dispose()
})
this.views = {}
}
}
export namespace Scheduler {
Expand Down
23 changes: 15 additions & 8 deletions packages/x6/src/shape/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ export namespace HTML {
export class View extends NodeView<HTML> {
protected init() {
super.init()
this.cell.on('change:*', ({ key }) => {
const content = shapeMaps[this.cell.shape]
if (content) {
const { effect } = content
if (!effect || effect.includes(key)) {
this.renderHTMLComponent()
}
this.cell.on('change:*', this.onCellChangeAny, this)
}

protected onCellChangeAny({ key }: Cell.EventArgs['change:*']) {
const content = shapeMaps[this.cell.shape]
if (content) {
const { effect } = content
if (!effect || effect.includes(key)) {
this.renderHTMLComponent()
}
})
}
}

confirmUpdate(flag: number) {
Expand Down Expand Up @@ -58,6 +60,11 @@ export namespace HTML {
}
}
}

@View.dispose()
dispose() {
this.cell.off('change:*', this.onCellChangeAny, this)
}
}

export namespace View {
Expand Down
11 changes: 10 additions & 1 deletion packages/x6/src/view/cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,11 @@ export class CellView<
}

protected setup() {
this.cell.on('changed', ({ options }) => this.onAttrsChange(options))
this.cell.on('changed', this.onCellChanged, this)
}

protected onCellChanged({ options }: Cell.EventArgs['changed']) {
this.onAttrsChange(options)
}

protected onAttrsChange(options: Cell.MutateOptions) {
Expand Down Expand Up @@ -739,6 +743,11 @@ export class CellView<
view.onMouseEnter(e as Dom.MouseEnterEvent)
}

@CellView.dispose()
dispose() {
this.cell.off('changed', this.onCellChanged, this)
}

// #endregion
}

Expand Down
5 changes: 5 additions & 0 deletions packages/x6/src/view/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,11 @@ export abstract class View<A extends EventArgs = any> extends Basecoat<A> {
normalizeEvent<T extends Dom.EventObject>(evt: T) {
return View.normalizeEvent(evt)
}

@View.dispose()
dispose() {
this.remove()
}
}

export namespace View {
Expand Down
Loading