Skip to content

Commit

Permalink
stagger mounting/unmounting/deleting
Browse files Browse the repository at this point in the history
  • Loading branch information
jameslaneconkling committed Oct 2, 2023
1 parent b3b4701 commit 706eee6
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 26 deletions.
45 changes: 36 additions & 9 deletions src/renderers/webgl/edge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export class EdgeRenderer {
targetRadius?: number

private arrow?: { forward: Arrow; reverse?: undefined } | { forward?: undefined; reverse: Arrow } | { forward: Arrow; reverse: Arrow }
private lineMounted = false
private forwardArrowMounted = false
private reverseArrowMounted = false

constructor(renderer: Renderer, edge: Graph.Edge, source: NodeRenderer, target: NodeRenderer) {
this.renderer = renderer
Expand All @@ -42,6 +45,8 @@ export class EdgeRenderer {
if (arrow !== (this.edge?.style?.arrow ?? DEFAULT_ARROW)) {
this.arrow?.forward?.delete()
this.arrow?.reverse?.delete()
this.forwardArrowMounted = false
this.reverseArrowMounted = false
this.arrow = undefined

switch (arrow) {
Expand Down Expand Up @@ -71,9 +76,18 @@ export class EdgeRenderer {
const isVisible = this.visible(Math.min(x0, x1), Math.min(y0, y1), Math.max(x0, x1), Math.max(y0, y1))

if (this.renderer.zoom > MIN_EDGES_ZOOM && isVisible) {
this.lineSegment.mount()
this.arrow?.forward?.mount()
this.arrow?.reverse?.mount()
if (!this.lineMounted) {
this.renderer.edgeObjectManager.mount(this.lineSegment)
this.lineMounted = true
}
if (this.arrow?.forward && !this.forwardArrowMounted) {
this.renderer.edgeObjectManager.mount(this.arrow.forward)
this.forwardArrowMounted = true
}
if (this.arrow?.reverse && !this.reverseArrowMounted) {
this.renderer.edgeObjectManager.mount(this.arrow.reverse)
this.reverseArrowMounted = true
}

// this.edgeGraphic.alpha = this.renderer.zoom <= MIN_EDGES_ZOOM + 0.1 ?
// (this.renderer.zoom - MIN_EDGES_ZOOM) / MIN_EDGES_ZOOM + 0.1 : 1
Expand Down Expand Up @@ -130,16 +144,29 @@ export class EdgeRenderer {
this.lineSegment.update(edgeX0, edgeY0, edgeX1, edgeY1, width, stroke, strokeOpacity)
}
} else {
this.lineSegment.unmount()
this.arrow?.forward?.unmount()
this.arrow?.reverse?.unmount()
if (this.lineMounted) {
this.renderer.edgeObjectManager.unmount(this.lineSegment)
this.lineMounted = false
}
if (this.arrow?.forward && this.forwardArrowMounted) {
this.renderer.edgeObjectManager.unmount(this.arrow.forward)
this.forwardArrowMounted = false
}
if (this.arrow?.reverse && this.reverseArrowMounted) {
this.renderer.edgeObjectManager.unmount(this.arrow.reverse)
this.reverseArrowMounted = false
}
}
}

delete() {
this.lineSegment.delete()
this.arrow?.forward?.delete()
this.arrow?.reverse?.delete()
this.renderer.edgeObjectManager.delete(this.lineSegment)
if (this.arrow?.forward) {
this.renderer.edgeObjectManager.delete(this.arrow.forward)
}
if (this.arrow?.reverse) {
this.renderer.edgeObjectManager.delete(this.arrow.reverse)
}
}

private visible(minX: number, minY: number, maxX: number, maxY: number) {
Expand Down
10 changes: 9 additions & 1 deletion src/renderers/webgl/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CircleTexture } from './textures/circle'
import { Font } from './objects/font'
import { interpolate } from '../../utils'
import { logUnknownEdgeError } from './utils'
import { ObjectManager } from './objectManager'

export type Keys = { altKey?: boolean; ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean }
export type MousePosition = { x: number; y: number; clientX: number; clientY: number }
Expand Down Expand Up @@ -130,6 +131,9 @@ export class Renderer {
zoomInteraction = new Zoom(this)
dragInteraction = new Drag(this)
decelerateInteraction = new Decelerate(this)
nodeObjectManager = new ObjectManager(4000)
edgeObjectManager = new ObjectManager(4000)
labelObjectManager = new ObjectManager(4000)
font = new Font()
eventSystem: EventSystem
nodes: Graph.Node[] = []
Expand Down Expand Up @@ -208,7 +212,7 @@ export class Renderer {
autoDensity: true,
powerPreference: 'high-performance',
backgroundAlpha: 0,
forceCanvas: forceCanvas
forceCanvas: forceCanvas,
})

this.width = width
Expand Down Expand Up @@ -485,6 +489,10 @@ export class Renderer {
this.edgeRenderersById[edge.id].render()
}

this.nodeObjectManager.render()
this.edgeObjectManager.render()
this.labelObjectManager.render()

this.app.render()
}

Expand Down
47 changes: 35 additions & 12 deletions src/renderers/webgl/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export class NodeRenderer {
private interpolateX?: (dt: number) => { value: number; done: boolean }
private interpolateY?: (dt: number) => { value: number; done: boolean }
private interpolateRadius?: (dt: number) => { value: number; done: boolean }
private fillMounted = false
private strokeMounted = false
private labelMounted = false

constructor(renderer: Renderer, node: Graph.Node) {
this.renderer = renderer
Expand All @@ -38,7 +41,9 @@ export class NodeRenderer {
}
} else {
if (node.label === undefined) {
this.label = this.label.delete()
this.renderer.labelObjectManager.delete(this.label)
this.labelMounted = false
this.label = undefined
}
}

Expand Down Expand Up @@ -128,33 +133,51 @@ export class NodeRenderer {
}

if (isVisible) {
this.fill.mount()
if (!this.fillMounted) {
this.renderer.nodeObjectManager.mount(this.fill)
this.fillMounted = true
}
} else {
this.fill.unmount()
if (!this.fillMounted) {
this.renderer.nodeObjectManager.unmount(this.fill)
this.fillMounted = false
}
}

if (isVisible && this.renderer.zoom > MIN_NODE_STROKE_ZOOM) {
this.strokes.mount()
if (!this.strokeMounted) {
this.renderer.nodeObjectManager.mount(this.strokes)
this.strokeMounted = true
}
} else {
this.strokes.unmount()
if (this.strokeMounted) {
this.renderer.nodeObjectManager.unmount(this.strokes)
this.strokeMounted = false
}
}

if (this.label) {
if (isVisible && this.renderer.zoom > MIN_LABEL_ZOOM) {
// this.label.alpha = this.renderer.zoom <= MIN_LABEL_ZOOM + 0.1 ?
// (this.renderer.zoom - MIN_LABEL_ZOOM) / MIN_LABEL_ZOOM + 0.1 : 1
this.label.mount()
if (!this.labelMounted) {
this.renderer.labelObjectManager.mount(this.label)
this.labelMounted = true
}
} else {
this.label.unmount()
if (this.labelMounted) {
this.renderer.labelObjectManager.unmount(this.label)
this.labelMounted = false
}
}
}
}

delete() {
clearTimeout(this.doubleClickTimeout)
this.fill.delete()
this.strokes.delete()
this.label?.delete()
this.renderer.nodeObjectManager.delete(this.fill)
this.renderer.nodeObjectManager.delete(this.strokes)
if (this.label) {
this.renderer.labelObjectManager.delete(this.label)
}
}

private setPosition(node: Graph.Node, x: number, y: number, radius: number) {
Expand Down
155 changes: 155 additions & 0 deletions src/renderers/webgl/objectManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
export interface RenderObject {
mounted: boolean

mount(): this

unmount(): this

delete(): void
}

export class ObjectManager {

private batchSize: number

private toMount = new Set<RenderObject>()

private toUnmount = new Set<RenderObject>()

private toDelete = new Set<RenderObject>()

constructor(batchSize: number) {
this.batchSize = batchSize
}

mount(object: RenderObject) {
this.toUnmount.delete(object)
this.toMount.add(object)
}

unmount(object: RenderObject) {
this.toMount.delete(object)
this.toUnmount.add(object)
}

delete(object: RenderObject) {
this.toMount.delete(object)
this.toUnmount.delete(object)
this.toDelete.add(object)
}

render() {
let toDeleteCount = 0
let toMountCount = 0
let toUnmountCount = 0

for (const object of this.toDelete) {
if (toMountCount === this.batchSize) {
break
}

object.delete()

this.toDelete.delete(object)

toDeleteCount++
}

for (const object of this.toMount) {
if (toMountCount === this.batchSize) {
break
}

object.mount()

this.toMount.delete(object)

toMountCount++
}

for (const object of this.toUnmount) {
if (toUnmountCount === this.batchSize) {
break
}

object.unmount()

this.toUnmount.delete(object)

toUnmountCount++
}
}
}

// export class ObjectManager {

// private batchSize: number

// private toMount = new Set<RenderObject>()

// private toUnmount = new Set<RenderObject>()

// private toDelete = new Set<RenderObject>()

// constructor(batchSize: number) {
// this.batchSize = batchSize
// }

// mount(object: RenderObject) {
// this.toUnmount.delete(object)
// this.toMount.add(object)
// }

// unmount(object: RenderObject) {
// this.toMount.delete(object)
// this.toUnmount.add(object)
// }

// delete(object: RenderObject) {
// this.toDelete.add(object)
// }

// render() {
// let toDeleteCount = 0
// let toMountCount = 0
// let toUnmountCount = 0

// for (const object of this.toDelete) {
// if (toMountCount === this.batchSize) {
// break
// }

// object.delete()

// this.toMount.delete(object)
// this.toUnmount.delete(object)
// this.toDelete.delete(object)

// toDeleteCount++
// }

// for (const object of this.toMount) {
// if (toMountCount === this.batchSize) {
// break
// }

// object.mount()

// this.toMount.delete(object)

// toMountCount++
// }

// for (const object of this.toUnmount) {
// if (toUnmountCount === this.batchSize) {
// break
// }

// object.unmount()

// this.toUnmount.delete(object)

// toUnmountCount++
// }
// }
// }
Loading

0 comments on commit 706eee6

Please sign in to comment.