Destroy view-models when destroying trees
This commit is contained in:
@@ -97,7 +97,7 @@ class TreeNodeComponent extends React.Component<Props, State> {
|
|||||||
treeNode.viewModel.change.subscribe(this.viewStateHasChanged)
|
treeNode.viewModel.change.subscribe(this.viewStateHasChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
private viewStateHasChanged = (msg: void) => {
|
private viewStateHasChanged = () => {
|
||||||
this.props.treeNode.viewModel && this.setState({ selected: this.props.treeNode.viewModel.isSelected() })
|
this.props.treeNode.viewModel && this.setState({ selected: this.props.treeNode.viewModel.isSelected() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import { Destroyable } from '../../../backend/src/Model/Destroyable'
|
||||||
import { EventDispatcher } from '../../../events'
|
import { EventDispatcher } from '../../../events'
|
||||||
|
|
||||||
export class TopicViewModel {
|
export class TopicViewModel implements Destroyable {
|
||||||
private selected: boolean
|
private selected: boolean
|
||||||
public change = new EventDispatcher<void, TopicViewModel>()
|
public change = new EventDispatcher<void, TopicViewModel>()
|
||||||
|
|
||||||
@@ -8,6 +9,10 @@ export class TopicViewModel {
|
|||||||
this.selected = false
|
this.selected = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public destroy() {
|
||||||
|
this.change.removeAllListeners()
|
||||||
|
}
|
||||||
|
|
||||||
public isSelected() {
|
public isSelected() {
|
||||||
return this.selected
|
return this.selected
|
||||||
}
|
}
|
||||||
|
|||||||
3
backend/src/Model/Destroyable.ts
Normal file
3
backend/src/Model/Destroyable.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export interface Destroyable {
|
||||||
|
destroy(): void
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import { Destroyable } from './Destroyable'
|
||||||
import { Hashable, TreeNode } from './'
|
import { Hashable, TreeNode } from './'
|
||||||
const sha1 = require('sha1')
|
const sha1 = require('sha1')
|
||||||
|
|
||||||
export class Edge<ViewModel> implements Hashable {
|
export class Edge<ViewModel extends Destroyable> implements Hashable {
|
||||||
public name: string
|
public name: string
|
||||||
|
|
||||||
public target!: TreeNode<ViewModel>
|
public target!: TreeNode<ViewModel>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ChangeBuffer } from './ChangeBuffer'
|
import { ChangeBuffer } from './ChangeBuffer'
|
||||||
|
import { Destroyable } from './Destroyable'
|
||||||
import {
|
import {
|
||||||
EventBusInterface,
|
EventBusInterface,
|
||||||
EventDispatcher,
|
EventDispatcher,
|
||||||
@@ -8,7 +9,7 @@ import {
|
|||||||
import { TreeNode } from './'
|
import { TreeNode } from './'
|
||||||
import { TreeNodeFactory } from './TreeNodeFactory'
|
import { TreeNodeFactory } from './TreeNodeFactory'
|
||||||
|
|
||||||
export class Tree<ViewModel> extends TreeNode<ViewModel> {
|
export class Tree<ViewModel extends Destroyable> extends TreeNode<ViewModel> {
|
||||||
public connectionId?: string
|
public connectionId?: string
|
||||||
public updateSource?: EventBusInterface
|
public updateSource?: EventBusInterface
|
||||||
public nodeFilter?: (node: TreeNode<ViewModel>) => boolean
|
public nodeFilter?: (node: TreeNode<ViewModel>) => boolean
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import { Destroyable } from './Destroyable'
|
||||||
import { Edge, Message, RingBuffer } from './'
|
import { Edge, Message, RingBuffer } from './'
|
||||||
import { EventDispatcher, MqttMessage } from '../../../events'
|
import { EventDispatcher, MqttMessage } from '../../../events'
|
||||||
|
|
||||||
export class TreeNode<ViewModel> {
|
export class TreeNode<ViewModel extends Destroyable> {
|
||||||
public sourceEdge?: Edge<ViewModel>
|
public sourceEdge?: Edge<ViewModel>
|
||||||
public message?: Message
|
public message?: Message
|
||||||
public mqttMessage?: MqttMessage
|
public mqttMessage?: MqttMessage
|
||||||
@@ -103,6 +104,8 @@ export class TreeNode<ViewModel> {
|
|||||||
for (const edge of this.edgeArray) {
|
for (const edge of this.edgeArray) {
|
||||||
edge.target.destroy()
|
edge.target.destroy()
|
||||||
}
|
}
|
||||||
|
this.viewModel && this.viewModel.destroy()
|
||||||
|
this.viewModel = undefined
|
||||||
this.edgeArray = []
|
this.edgeArray = []
|
||||||
this.edges = {}
|
this.edges = {}
|
||||||
this.cachedChildTopics = []
|
this.cachedChildTopics = []
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Base64Message } from './Base64Message'
|
import { Base64Message } from './Base64Message'
|
||||||
|
import { Destroyable } from './Destroyable'
|
||||||
import { Edge, Tree, TreeNode } from './'
|
import { Edge, Tree, TreeNode } from './'
|
||||||
|
|
||||||
export abstract class TreeNodeFactory {
|
export abstract class TreeNodeFactory {
|
||||||
private static messageCounter = 0
|
private static messageCounter = 0
|
||||||
public static insertNodeAtPosition<ViewModel>(edgeNames: Array<string>, node: TreeNode<ViewModel>) {
|
public static insertNodeAtPosition<ViewModel extends Destroyable>(edgeNames: Array<string>, node: TreeNode<ViewModel>) {
|
||||||
let currentNode: TreeNode<ViewModel> = new Tree()
|
let currentNode: TreeNode<ViewModel> = new Tree()
|
||||||
let edge
|
let edge
|
||||||
for (const edgeName of edgeNames) {
|
for (const edgeName of edgeNames) {
|
||||||
@@ -16,7 +17,7 @@ export abstract class TreeNodeFactory {
|
|||||||
node.sourceEdge!.target = node
|
node.sourceEdge!.target = node
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromEdgesAndValue<ViewModel>(edgeNames: Array<string>, value?: Base64Message | null): TreeNode<ViewModel> {
|
public static fromEdgesAndValue<ViewModel extends Destroyable>(edgeNames: Array<string>, value?: Base64Message | null): TreeNode<ViewModel> {
|
||||||
const node = new TreeNode<ViewModel>()
|
const node = new TreeNode<ViewModel>()
|
||||||
node.setMessage({
|
node.setMessage({
|
||||||
value: value || undefined,
|
value: value || undefined,
|
||||||
|
|||||||
Reference in New Issue
Block a user