diff --git a/src/editor/js/structures/graph/graph.ts b/src/editor/js/structures/graph/graph.ts index b8dc963ac3f09a1074d2acc923e393574ccaab57..9553a532fc96fa9e9da6ac17b21ea84c0d7207ca 100644 --- a/src/editor/js/structures/graph/graph.ts +++ b/src/editor/js/structures/graph/graph.ts @@ -157,6 +157,36 @@ export class Graph extends ManagedData { }; } + /** + * Adds a pre-created node type to the graph. + * @param nodeType New node type object. + * @returns True, if successful. + */ + public addNodeType(nodeType: NodeType) { + if (this.data.types.includes(nodeType)) { + return true; // Already exists in graph. + } + + // Update id + nodeType.id = this.nextTypeId; + this.nextTypeId += 1; + + // Is valid node? + if (nodeType.name == undefined) { + nodeType.name = "Unnamed"; + } + if (nodeType.color == undefined) { + nodeType.color = "#000000"; + } + + this.data.types.push(node); + + this.triggerOnChange(); + this.storeCurrentData("Added node [" + nodeType + "]"); + + return true; + } + /** * Adds a pre-created node to the graph. * @param node New node object. @@ -180,21 +210,59 @@ export class Graph extends ManagedData { // Just give first type in list node.type = this.types[0]; } else { - // Give empty type - // TODO: Properly add new type, with proper ID. Implemented this.addType(..); - node.type = new NodeType(this); + const newType = new NodeType(this); + newType.add(); + node.type = newType; } } this.data.nodes.push(node); this.triggerOnChange(); - // TODO: Use toString implementation of node this.storeCurrentData("Added node [" + node + "]"); return true; } + /** + * Deletes a node type from the graph. Only works if at least one type remains after deletion. + * @param nodeType Node type object to remove. + * @returns True, if successful. + */ + public deleteNodeType(nodeType: NodeType): boolean { + // Only allow deletion if at least one other type remains + if (this.types.length <= 1) { + return false; + } + + if (!this.data.types.includes(nodeType)) { + return true; // Doesn't even exist in graph to begin with. + } + + this.data.types = this.data.types.filter((n: NodeType) => !n.equals(nodeType)); + + try { + // No save points should be created when replacing usages + this.disableStoring(); + + // Replace all usages of this type with the first one in the list + this.nodes.forEach((n: Node) => { + if (n.type.equals(nodeType)) { + n.type = this.types[0]; + } + }); + } finally { + this.enableStoring(); + } + + this.triggerOnChange(); + this.storeCurrentData( + "Deleted type [" + nodeType + "] and replaced usages" + ); + + return true; + } + /** * Deletes a node from the graph. * @param node Node object to remove. @@ -220,7 +288,6 @@ export class Graph extends ManagedData { } this.triggerOnChange(); - // TODO: Use toString implementation of node this.storeCurrentData( "Deleted node [" + node + "] and all connected links" ); @@ -262,7 +329,6 @@ export class Graph extends ManagedData { this.data.links.push(link); this.triggerOnChange(); - // TODO: Use toString implementation of link this.storeCurrentData("Added link [" + link + "]"); return true; @@ -281,7 +347,6 @@ export class Graph extends ManagedData { this.data.links = this.data.links.filter((l: Link) => !l.equals(link)); this.triggerOnChange(); - // TODO: Use toString implementation of link this.storeCurrentData("Deleted link [" + link + "]"); return true; diff --git a/src/editor/js/structures/graph/nodetype.ts b/src/editor/js/structures/graph/nodetype.ts index 430ce90672471298be3ef953f04483acd9fb7e3c..78362ea791496c58395bcf23f5d7adc723118043 100644 --- a/src/editor/js/structures/graph/nodetype.ts +++ b/src/editor/js/structures/graph/nodetype.ts @@ -13,13 +13,16 @@ export class NodeType extends GraphElement { } public delete(): boolean { - // TODO: Implement - throw new Error('Function "delete()" has not been implemented.'); + return this.graph.deleteNodeType(this); } public add(graph: Graph = this.graph): boolean { - // TODO: Implement - throw new Error('Function "add(graph)" has not been implemented.'); + this.graph = graph; + if (this.graph == undefined) { + return false; + } + + return this.graph.addNodeType(this); } public getCleanInstance(): any {