complete refactor

This commit is contained in:
Dylan Vorster
2018-01-08 20:50:54 +02:00
parent 6b55811312
commit 518f481776
32 changed files with 191 additions and 241 deletions

View File

@ -8,14 +8,12 @@ import {
NodeModel, NodeModel,
DefaultPortModel, DefaultPortModel,
DiagramWidget, DiagramWidget,
DefaultNodeInstanceFactory,
DefaultPortInstanceFactory,
LinkInstanceFactory,
BaseModel BaseModel
} from "../../src/main"; } from "../../src/main";
import * as _ from "lodash"; import * as _ from "lodash";
import * as React from "react"; import * as React from "react";
import {DemoWorkspaceWidget} from "../.helpers/DemoWorkspaceWidget"; import {DemoWorkspaceWidget} from "../.helpers/DemoWorkspaceWidget";
import {DefaultPortFactory} from "../../src/defaults/DefaultPortFactory";
/** /**
* Tests cloning * Tests cloning
@ -66,8 +64,7 @@ class CloneSelected extends React.Component<any, any> {
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory());
//2) setup the diagram model //2) setup the diagram model
var model = new DiagramModel(); var model = new DiagramModel();
@ -97,11 +94,6 @@ export default () => {
//5) load model into engine //5) load model into engine
engine.setDiagramModel(model); engine.setDiagramModel(model);
//we need this to help the system know what models to create form the JSON
engine.registerInstanceFactory(new DefaultNodeInstanceFactory());
engine.registerInstanceFactory(new DefaultPortInstanceFactory());
engine.registerInstanceFactory(new LinkInstanceFactory());
//6) render the diagram! //6) render the diagram!
return <CloneSelected engine={engine} model={model} />; return <CloneSelected engine={engine} model={model} />;
}; };

View File

@ -13,15 +13,14 @@ import {
} from "../../src/main"; } from "../../src/main";
import { action } from "@storybook/addon-actions"; import { action } from "@storybook/addon-actions";
import * as React from "react"; import * as React from "react";
import { LinkWidgetFactory } from "../../src/WidgetFactories"; import {LinkFactory} from "../../src/AbstractFactory";
export class AdvancedLinkModel extends LinkModel { export class AdvancedLinkModel extends LinkModel {
size: number; size: number;
color: string; color: string;
constructor() { constructor() {
super(); super("advanced");
this.linkType = "advanced";
this.color = "green"; this.color = "green";
this.size = 6; this.size = 6;
} }
@ -39,7 +38,12 @@ export class AdvancedPortModel extends DefaultPortModel {
} }
} }
export class AdvancedLinkWidgetFactory extends LinkWidgetFactory { export class AdvancedLinkWidgetFactory extends LinkFactory<AdvancedLinkModel> {
getNewInstance(initialConfig?: any): AdvancedLinkModel {
return new AdvancedLinkModel();
}
constructor() { constructor() {
super("advanced"); super("advanced");
} }
@ -62,9 +66,8 @@ export class AdvancedLinkWidgetFactory extends LinkWidgetFactory {
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new AdvancedLinkWidgetFactory()); engine.registerLinkFactory(new AdvancedLinkWidgetFactory());
engine.registerLinkFactory(new DefaultLinkFactory());
var node1 = new DefaultNodeModel("Source", "rgb(0,192,255)"); var node1 = new DefaultNodeModel("Source", "rgb(0,192,255)");
var port1 = node1.addPort(new AdvancedPortModel(false, "out-1", "Out thick")); var port1 = node1.addPort(new AdvancedPortModel(false, "out-1", "Out thick"));

View File

@ -1,23 +0,0 @@
import * as SRD from "../../src/main";
import { DiamondNodeModel } from "./DiamondNodeModel";
import { DiamondPortModel } from "./DiamondPortModel";
export class DiamondNodeFactory extends SRD.AbstractInstanceFactory<DiamondNodeModel> {
constructor() {
super("DiamondNodeModel");
}
getInstance() {
return new DiamondNodeModel();
}
}
export class DiamondPortFactory extends SRD.AbstractInstanceFactory<DiamondPortModel> {
constructor() {
super("DiamondPortModel");
}
getInstance() {
return new DiamondPortModel();
}
}

View File

@ -1,7 +1,9 @@
import * as SRD from "../../src/main"; import * as SRD from "../../src/main";
import { DiamonNodeWidgetFactory } from "./DiamondNodeWidget"; import { DiamonNodeWidgetFactory } from "./DiamondNodeWidget";
import {DiamondNodeModel} from "./DiamondNodeModel";
export class DiamondNodeFactory extends SRD.NodeFactory {
export class DiamondWidgetFactory extends SRD.NodeWidgetFactory {
constructor() { constructor() {
super("diamond"); super("diamond");
} }
@ -9,4 +11,8 @@ export class DiamondWidgetFactory extends SRD.NodeWidgetFactory {
generateReactWidget(diagramEngine: SRD.DiagramEngine, node: SRD.NodeModel): JSX.Element { generateReactWidget(diagramEngine: SRD.DiagramEngine, node: SRD.NodeModel): JSX.Element {
return DiamonNodeWidgetFactory({ node: node }); return DiamonNodeWidgetFactory({ node: node });
} }
getNewInstance() {
return new DiamondNodeModel();
}
} }

View File

@ -10,7 +10,9 @@ import {
} from "../../src/main"; } from "../../src/main";
import * as React from "react"; import * as React from "react";
import { DiamondNodeModel } from "./DiamondNodeModel"; import { DiamondNodeModel } from "./DiamondNodeModel";
import { DiamondWidgetFactory } from "./DiamondWidgetFactory"; import { DiamondNodeFactory} from "./DiamondNodeFactory";
import {SimplePortFactory} from "../../src/AbstractFactory";
import {DiamondPortModel} from "./DiamondPortModel";
/** /**
* @Author Dylan Vorster * @Author Dylan Vorster
@ -18,9 +20,9 @@ import { DiamondWidgetFactory } from "./DiamondWidgetFactory";
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory()); engine.registerPortFactory(new SimplePortFactory('diamond', (config) => new DiamondPortModel()));
engine.registerNodeFactory(new DiamondWidgetFactory()); engine.registerNodeFactory(new DiamondNodeFactory());
//2) setup the diagram model //2) setup the diagram model
var model = new DiagramModel(); var model = new DiagramModel();

View File

@ -7,9 +7,6 @@ import {
LinkModel, LinkModel,
DefaultPortModel, DefaultPortModel,
DiagramWidget, DiagramWidget,
DefaultNodeInstanceFactory,
DefaultPortInstanceFactory,
LinkInstanceFactory
} from "../../src/main"; } from "../../src/main";
import { distributeElements } from "./dagre-utils"; import { distributeElements } from "./dagre-utils";
import * as React from "react"; import * as React from "react";
@ -73,8 +70,7 @@ function getDistributedModel(engine, model) {
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
let engine = new DiagramEngine(); let engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory());
//2) setup the diagram model //2) setup the diagram model
let model = new DiagramModel(); let model = new DiagramModel();
@ -113,10 +109,6 @@ export default () => {
model.addLink(link); model.addLink(link);
}); });
//5) load model into engine //5) load model into engine
//we need this to help the system know what models to create form the JSON
engine.registerInstanceFactory(new DefaultNodeInstanceFactory());
engine.registerInstanceFactory(new DefaultPortInstanceFactory());
engine.registerInstanceFactory(new LinkInstanceFactory());
let model2 = getDistributedModel(engine, model); let model2 = getDistributedModel(engine, model);
engine.setDiagramModel(model2); engine.setDiagramModel(model2);

View File

@ -8,9 +8,7 @@ export class Application {
constructor() { constructor() {
this.diagramEngine = new SRD.DiagramEngine(); this.diagramEngine = new SRD.DiagramEngine();
this.diagramEngine.installDefaultFactories();
this.diagramEngine.registerNodeFactory(new SRD.DefaultNodeFactory());
this.diagramEngine.registerLinkFactory(new SRD.DefaultLinkFactory());
this.newModel(); this.newModel();
} }

View File

@ -16,8 +16,7 @@ import * as React from "react";
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory());
//2) setup the diagram model //2) setup the diagram model
var model = new DiagramModel(); var model = new DiagramModel();

View File

@ -8,8 +8,7 @@ import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget
export default () => { export default () => {
// setup the diagram engine // setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new SRD.DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new SRD.DefaultLinkFactory());
var model = new DiagramModel(); var model = new DiagramModel();

View File

@ -9,8 +9,7 @@ import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget
export default () => { export default () => {
// setup the diagram engine // setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new SRD.DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new SRD.DefaultLinkFactory());
var model = new DiagramModel(); var model = new DiagramModel();

View File

@ -11,8 +11,7 @@ import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, PointModel, D
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new SRD.DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new SRD.DefaultLinkFactory());
var model = new DiagramModel(); var model = new DiagramModel();

View File

@ -7,9 +7,6 @@ import {
LinkModel, LinkModel,
DefaultPortModel, DefaultPortModel,
DiagramWidget, DiagramWidget,
DefaultNodeInstanceFactory,
DefaultPortInstanceFactory,
LinkInstanceFactory
} from "../../src/main"; } from "../../src/main";
import * as React from "react"; import * as React from "react";
import {DemoWorkspaceWidget} from "../.helpers/DemoWorkspaceWidget"; import {DemoWorkspaceWidget} from "../.helpers/DemoWorkspaceWidget";
@ -63,8 +60,7 @@ class NodeDelayedPosition extends React.Component<any, any> {
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory());
//2) setup the diagram model //2) setup the diagram model
var model = new DiagramModel(); var model = new DiagramModel();
@ -94,11 +90,6 @@ export default () => {
//5) load model into engine //5) load model into engine
engine.setDiagramModel(model); engine.setDiagramModel(model);
//we need this to help the system know what models to create form the JSON
engine.registerInstanceFactory(new DefaultNodeInstanceFactory());
engine.registerInstanceFactory(new DefaultPortInstanceFactory());
engine.registerInstanceFactory(new LinkInstanceFactory());
//6) render the diagram! //6) render the diagram!
return <NodeDelayedPosition engine={engine} model={model} />; return <NodeDelayedPosition engine={engine} model={model} />;
}; };

View File

@ -1,7 +1,5 @@
import { import {
DiagramEngine, DiagramEngine,
DefaultNodeFactory,
DefaultLinkFactory,
DiagramModel, DiagramModel,
DefaultNodeModel, DefaultNodeModel,
LinkModel, LinkModel,
@ -20,8 +18,7 @@ import * as React from "react";
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory());
function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) { function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) {
//3-A) create a default node //3-A) create a default node

View File

@ -7,9 +7,6 @@ import {
LinkModel, LinkModel,
DefaultPortModel, DefaultPortModel,
DiagramWidget, DiagramWidget,
DefaultNodeInstanceFactory,
DefaultPortInstanceFactory,
LinkInstanceFactory
} from "../../src/main"; } from "../../src/main";
import * as React from "react"; import * as React from "react";
import {DemoWorkspaceWidget} from "../.helpers/DemoWorkspaceWidget"; import {DemoWorkspaceWidget} from "../.helpers/DemoWorkspaceWidget";
@ -19,8 +16,7 @@ var beautify = require("json-beautify");
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory());
//2) setup the diagram model //2) setup the diagram model
var model = new DiagramModel(); var model = new DiagramModel();
@ -56,12 +52,6 @@ export default () => {
//!------------- DESERIALIZING ---------------- //!------------- DESERIALIZING ----------------
//we need this to help the system know what models to create form the JSON
engine.registerInstanceFactory(new DefaultNodeInstanceFactory());
engine.registerInstanceFactory(new DefaultPortInstanceFactory());
engine.registerInstanceFactory(new LinkInstanceFactory());
//deserialize the model
var model2 = new DiagramModel(); var model2 = new DiagramModel();
model2.deSerializeDiagram(JSON.parse(str), engine); model2.deSerializeDiagram(JSON.parse(str), engine);
engine.setDiagramModel(model2); engine.setDiagramModel(model2);

View File

@ -1,7 +1,5 @@
import { import {
DiagramEngine, DiagramEngine,
DefaultNodeFactory,
DefaultLinkFactory,
DiagramModel, DiagramModel,
DefaultNodeModel, DefaultNodeModel,
LinkModel, LinkModel,
@ -13,8 +11,7 @@ import * as React from "react";
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory());
//2) setup the diagram model //2) setup the diagram model
var model = new DiagramModel(); var model = new DiagramModel();

View File

@ -20,8 +20,7 @@ import {DemoWorkspaceWidget} from "../.helpers/DemoWorkspaceWidget";
export default () => { export default () => {
//1) setup the diagram engine //1) setup the diagram engine
var engine = new DiagramEngine(); var engine = new DiagramEngine();
engine.registerNodeFactory(new DefaultNodeFactory()); engine.installDefaultFactories();
engine.registerLinkFactory(new DefaultLinkFactory());
function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) { function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) {
//3-A) create a default node //3-A) create a default node

51
src/AbstractFactory.ts Normal file
View File

@ -0,0 +1,51 @@
import {BaseModel} from "./models/BaseModel";
import {NodeModel} from "./models/NodeModel";
import {LinkModel} from "./models/LinkModel";
import {DiagramEngine} from "./DiagramEngine";
import {PortModel} from "./models/PortModel";
export abstract class AbstractFactory<T extends BaseModel>{
type: string;
constructor(name: string) {
this.type = name;
}
getType(): string {
return this.type;
}
abstract getNewInstance(initialConfig?: any): T
}
export abstract class NodeFactory<T extends NodeModel = NodeModel> extends AbstractFactory<T>{
abstract generateReactWidget(diagramEngine: DiagramEngine, node: T): JSX.Element;
}
export abstract class LinkFactory<T extends LinkModel = LinkModel> extends AbstractFactory<T>{
abstract generateReactWidget(diagramEngine: DiagramEngine, link: T): JSX.Element;
}
export abstract class PortFactory<T extends PortModel = PortModel> extends AbstractFactory<T>{
}
export class SimplePortFactory extends PortFactory{
cb: (initialConfig?: any) => PortModel;
constructor(type: string, cb: (initialConfig?: any) => PortModel){
super(type);
this.cb = cb;
}
getNewInstance(initialConfig?: any): PortModel {
return this.cb(initialConfig);
}
}

View File

@ -1,17 +0,0 @@
import { BaseEntity, BaseListener } from "./BaseEntity";
/**
* @author Dylan Vorster
*/
export abstract class AbstractInstanceFactory<T extends BaseEntity<BaseListener>> {
className: string;
constructor(className: string) {
this.className = className;
}
getName() {
return this.className;
}
abstract getInstance(initialConfig?: any): T;
}

View File

@ -1,17 +1,21 @@
import { NodeWidgetFactory, LinkWidgetFactory } from "./WidgetFactories";
import { BaseEntity, BaseListener } from "./BaseEntity"; import { BaseEntity, BaseListener } from "./BaseEntity";
import { DiagramModel } from "./models/DiagramModel"; import { DiagramModel } from "./models/DiagramModel";
import { AbstractInstanceFactory } from "./AbstractInstanceFactory";
import * as _ from "lodash"; import * as _ from "lodash";
import { BaseModel, BaseModelListener } from "./models/BaseModel"; import { BaseModel, BaseModelListener } from "./models/BaseModel";
import { NodeModel } from "./models/NodeModel"; import { NodeModel } from "./models/NodeModel";
import { PointModel } from "./models/PointModel"; import { PointModel } from "./models/PointModel";
import { PortModel } from "./models/PortModel"; import { PortModel } from "./models/PortModel";
import { LinkModel } from "./models/LinkModel"; import { LinkModel } from "./models/LinkModel";
import {LinkFactory, NodeFactory, PortFactory} from "./AbstractFactory";
import {DefaultLinkFactory, DefaultNodeFactory} from "./main";
import {DefaultPortFactory} from "./defaults/DefaultPortFactory";
/** /**
* @author Dylan Vorster * @author Dylan Vorster
*/ */
export interface DiagramEngineListener extends BaseListener { export interface DiagramEngineListener extends BaseListener {
portFactoriesUpdated?(): void;
nodeFactoriesUpdated?(): void; nodeFactoriesUpdated?(): void;
linkFactoriesUpdated?(): void; linkFactoriesUpdated?(): void;
@ -23,11 +27,10 @@ export interface DiagramEngineListener extends BaseListener {
* Passed as a parameter to the DiagramWidget * Passed as a parameter to the DiagramWidget
*/ */
export class DiagramEngine extends BaseEntity<DiagramEngineListener> { export class DiagramEngine extends BaseEntity<DiagramEngineListener> {
nodeFactories: { [s: string]: NodeWidgetFactory };
linkFactories: { [s: string]: LinkWidgetFactory }; nodeFactories: { [s: string]: NodeFactory };
instanceFactories: { linkFactories: { [s: string]: LinkFactory };
[s: string]: AbstractInstanceFactory<BaseEntity<BaseListener>>; portFactories: { [s: string]: PortFactory };
};
diagramModel: DiagramModel; diagramModel: DiagramModel;
canvas: Element; canvas: Element;
@ -41,12 +44,18 @@ export class DiagramEngine extends BaseEntity<DiagramEngineListener> {
this.diagramModel = new DiagramModel(); this.diagramModel = new DiagramModel();
this.nodeFactories = {}; this.nodeFactories = {};
this.linkFactories = {}; this.linkFactories = {};
this.instanceFactories = {}; this.portFactories = {};
this.canvas = null; this.canvas = null;
this.paintableWidgets = null; this.paintableWidgets = null;
this.linksThatHaveInitiallyRendered = {}; this.linksThatHaveInitiallyRendered = {};
} }
installDefaultFactories(){
this.registerNodeFactory(new DefaultNodeFactory());
this.registerLinkFactory(new DefaultLinkFactory());
this.registerPortFactory(new DefaultPortFactory());
}
repaintCanvas() { repaintCanvas() {
this.iterateListeners(listener => { this.iterateListeners(listener => {
listener.repaintCanvas && listener.repaintCanvas(); listener.repaintCanvas && listener.repaintCanvas();
@ -131,23 +140,24 @@ export class DiagramEngine extends BaseEntity<DiagramEngineListener> {
return this.diagramModel; return this.diagramModel;
} }
getNodeFactories(): { [s: string]: NodeWidgetFactory } { getNodeFactories(): { [s: string]: NodeFactory } {
return this.nodeFactories; return this.nodeFactories;
} }
getLinkFactories(): { [s: string]: LinkWidgetFactory } { getLinkFactories(): { [s: string]: LinkFactory } {
return this.linkFactories; return this.linkFactories;
} }
getInstanceFactory(className: string): AbstractInstanceFactory<BaseEntity<BaseListener>> { registerPortFactory(factory: PortFactory) {
return this.instanceFactories[className]; this.portFactories[factory.getType()] = factory;
this.iterateListeners(listener => {
if (listener.portFactoriesUpdated) {
listener.portFactoriesUpdated();
}
});
} }
registerInstanceFactory(factory: AbstractInstanceFactory<BaseEntity<BaseListener>>) { registerNodeFactory(factory: NodeFactory) {
this.instanceFactories[factory.getName()] = factory;
}
registerNodeFactory(factory: NodeWidgetFactory) {
this.nodeFactories[factory.getType()] = factory; this.nodeFactories[factory.getType()] = factory;
this.iterateListeners(listener => { this.iterateListeners(listener => {
if (listener.nodeFactoriesUpdated) { if (listener.nodeFactoriesUpdated) {
@ -156,7 +166,7 @@ export class DiagramEngine extends BaseEntity<DiagramEngineListener> {
}); });
} }
registerLinkFactory(factory: LinkWidgetFactory) { registerLinkFactory(factory: LinkFactory) {
this.linkFactories[factory.getType()] = factory; this.linkFactories[factory.getType()] = factory;
this.iterateListeners(listener => { this.iterateListeners(listener => {
if (listener.linkFactoriesUpdated) { if (listener.linkFactoriesUpdated) {
@ -165,22 +175,38 @@ export class DiagramEngine extends BaseEntity<DiagramEngineListener> {
}); });
} }
getFactoryForNode(node: NodeModel): NodeWidgetFactory | null { getPortFactory(type: string): PortFactory{
if (this.nodeFactories[node.getType()]) { if (this.portFactories[type]) {
return this.nodeFactories[node.getType()]; return this.portFactories[type];
} }
console.log("cannot find widget factory for node of type: [" + node.getType() + "]"); console.log("cannot find factory for port of type: [" + type + "]");
return null; return null;
} }
getFactoryForLink(link: LinkModel): LinkWidgetFactory | null { getNodeFactory(type: string): NodeFactory{
if (this.linkFactories[link.getType()]) { if (this.nodeFactories[type]) {
return this.linkFactories[link.getType()]; return this.nodeFactories[type];
} }
console.log("cannot find widget factory for link of type: [" + link.getType() + "]"); console.log("cannot find factory for node of type: [" + type + "]");
return null; return null;
} }
getLinkFactory(type: string): LinkFactory{
if (this.linkFactories[type]) {
return this.linkFactories[type];
}
console.log("cannot find factory for link of type: [" + type + "]");
return null;
}
getFactoryForNode(node: NodeModel): NodeFactory | null {
return this.getNodeFactory(node.getType());
}
getFactoryForLink(link: LinkModel): LinkFactory | null {
return this.getLinkFactory(link.getType());
}
generateWidgetForLink(link: LinkModel): JSX.Element | null { generateWidgetForLink(link: LinkModel): JSX.Element | null {
var linkFactory = this.getFactoryForLink(link); var linkFactory = this.getFactoryForLink(link);
if (!linkFactory) { if (!linkFactory) {

View File

@ -1,14 +0,0 @@
import { AbstractInstanceFactory } from "./AbstractInstanceFactory";
import { LinkModel } from "./models/LinkModel";
/**
* @author Dylan Vorster
*/
export class LinkInstanceFactory extends AbstractInstanceFactory<LinkModel> {
constructor() {
super("LinkModel");
}
getInstance() {
return new LinkModel();
}
}

View File

@ -1,25 +0,0 @@
import { DiagramEngine } from "./DiagramEngine";
import { NodeModel } from "./models/NodeModel";
import { LinkModel } from "./models/LinkModel";
/**
* @author Dylan Vorster
*/
export abstract class WidgetFactory {
type: string;
constructor(name: string) {
this.type = name;
}
getType(): string {
return this.type;
}
}
export abstract class NodeWidgetFactory extends WidgetFactory {
abstract generateReactWidget(diagramEngine: DiagramEngine, node: NodeModel): JSX.Element;
}
export abstract class LinkWidgetFactory extends WidgetFactory {
abstract generateReactWidget(diagramEngine: DiagramEngine, link: LinkModel): JSX.Element;
}

View File

@ -1,12 +1,13 @@
import { LinkWidgetFactory } from "../WidgetFactories";
import * as React from "react"; import * as React from "react";
import { DefaultLinkWidget } from "./DefaultLinkWidget"; import { DefaultLinkWidget } from "./DefaultLinkWidget";
import { DiagramEngine } from "../DiagramEngine"; import { DiagramEngine } from "../DiagramEngine";
import { LinkModel } from "../models/LinkModel"; import { LinkModel } from "../models/LinkModel";
import {LinkFactory} from "../AbstractFactory";
/** /**
* @author Dylan Vorster * @author Dylan Vorster
*/ */
export class DefaultLinkFactory extends LinkWidgetFactory { export class DefaultLinkFactory extends LinkFactory {
constructor() { constructor() {
super("default"); super("default");
} }
@ -17,4 +18,8 @@ export class DefaultLinkFactory extends LinkWidgetFactory {
diagramEngine: diagramEngine diagramEngine: diagramEngine
}); });
} }
getNewInstance(initialConfig?: any): LinkModel {
return new LinkModel();
}
} }

View File

@ -1,12 +1,13 @@
import { NodeWidgetFactory } from "../WidgetFactories";
import { DefaultNodeModel } from "./DefaultNodeModel"; import { DefaultNodeModel } from "./DefaultNodeModel";
import * as React from "react"; import * as React from "react";
import { DefaultNodeWidget } from "./DefaultNodeWidget"; import { DefaultNodeWidget } from "./DefaultNodeWidget";
import { DiagramEngine } from "../DiagramEngine"; import { DiagramEngine } from "../DiagramEngine";
import {NodeFactory} from "../AbstractFactory";
/** /**
* @author Dylan Vorster * @author Dylan Vorster
*/ */
export class DefaultNodeFactory extends NodeWidgetFactory { export class DefaultNodeFactory extends NodeFactory<DefaultNodeModel> {
constructor() { constructor() {
super("default"); super("default");
} }
@ -17,4 +18,8 @@ export class DefaultNodeFactory extends NodeWidgetFactory {
diagramEngine: diagramEngine diagramEngine: diagramEngine
}); });
} }
getNewInstance(initialConfig?: any): DefaultNodeModel {
return new DefaultNodeModel();
}
} }

View File

@ -1,19 +1,8 @@
import { DefaultPortModel } from "./DefaultPortModel"; import { DefaultPortModel } from "./DefaultPortModel";
import * as _ from "lodash"; import * as _ from "lodash";
import { AbstractInstanceFactory } from "../AbstractInstanceFactory";
import { NodeModel } from "../models/NodeModel"; import { NodeModel } from "../models/NodeModel";
export class DefaultNodeInstanceFactory extends AbstractInstanceFactory<DefaultNodeModel> {
constructor() {
super("DefaultNodeModel");
}
getInstance() {
return new DefaultNodeModel();
}
}
/** /**
* @author Dylan Vorster * @author Dylan Vorster
*/ */

View File

@ -0,0 +1,13 @@
import {DefaultPortModel} from "./DefaultPortModel";
import {PortFactory} from "../AbstractFactory";
export class DefaultPortFactory extends PortFactory<DefaultPortModel> {
constructor() {
super("default");
}
getNewInstance(initialConfig?: any): DefaultPortModel {
return new DefaultPortModel(true, "unknown");
}
}

View File

@ -1,17 +1,6 @@
import * as _ from "lodash"; import * as _ from "lodash";
import { AbstractInstanceFactory } from "../AbstractInstanceFactory";
import { PortModel } from "../models/PortModel"; import { PortModel } from "../models/PortModel";
export class DefaultPortInstanceFactory extends AbstractInstanceFactory<DefaultPortModel> {
constructor() {
super("DefaultPortModel");
}
getInstance() {
return new DefaultPortModel(true, "unknown");
}
}
/** /**
* @author Dylan Vorster * @author Dylan Vorster
*/ */
@ -20,7 +9,7 @@ export class DefaultPortModel extends PortModel {
label: string; label: string;
constructor(isInput: boolean, name: string, label: string = null, id?: string) { constructor(isInput: boolean, name: string, label: string = null, id?: string) {
super(name, id); super(name, "default", id);
this.in = isInput; this.in = isInput;
this.label = label || name; this.label = label || name;
} }

View File

@ -11,15 +11,13 @@ export * from "./defaults/DefaultNodeModel";
export * from "./defaults/DefaultPortModel"; export * from "./defaults/DefaultPortModel";
export * from "./defaults/DefaultPortLabelWidget"; export * from "./defaults/DefaultPortLabelWidget";
export * from "./WidgetFactories"; export * from "./AbstractFactory";
export * from "./Toolkit"; export * from "./Toolkit";
export * from "./DiagramEngine"; export * from "./DiagramEngine";
export * from "./models/DiagramModel"; export * from "./models/DiagramModel";
export * from "./BaseEntity"; export * from "./BaseEntity";
export * from "./CanvasActions"; export * from "./CanvasActions";
export * from "./AbstractInstanceFactory";
export * from "./LinkInstanceFactory";
export * from "./models/BaseModel"; export * from "./models/BaseModel";
export * from "./models/DiagramModel"; export * from "./models/DiagramModel";

View File

@ -12,13 +12,14 @@ export interface BaseModelListener extends BaseListener {
* @author Dylan Vorster * @author Dylan Vorster
*/ */
export class BaseModel<T extends BaseModelListener = BaseModelListener> extends BaseEntity<BaseModelListener> { export class BaseModel<T extends BaseModelListener = BaseModelListener> extends BaseEntity<BaseModelListener> {
selected: boolean;
class: string;
constructor(id?: string) { type: string;
selected: boolean;
constructor(type?: string, id?: string) {
super(id); super(id);
this.type = type;
this.selected = false; this.selected = false;
this.class = this.constructor.name;
} }
public getSelectedEntities(): BaseModel<T>[] { public getSelectedEntities(): BaseModel<T>[] {
@ -30,16 +31,21 @@ export class BaseModel<T extends BaseModelListener = BaseModelListener> extends
public deSerialize(ob) { public deSerialize(ob) {
super.deSerialize(ob); super.deSerialize(ob);
this.type = ob.type;
this.selected = ob.selected; this.selected = ob.selected;
} }
public serialize() { public serialize() {
return _.merge(super.serialize(), { return _.merge(super.serialize(), {
_class: this.class, type: this.type,
selected: this.selected selected: this.selected
}); });
} }
public getType(): string{
return this.type;
}
public getID(): string { public getID(): string {
return this.id; return this.id;
} }

View File

@ -74,11 +74,11 @@ export class DiagramModel extends BaseEntity<DiagramListener> {
//deserialize nodes //deserialize nodes
_.forEach(object.nodes, (node: any) => { _.forEach(object.nodes, (node: any) => {
let nodeOb = diagramEngine.getInstanceFactory(node._class).getInstance(node) as NodeModel; let nodeOb = diagramEngine.getNodeFactory(node.type).getNewInstance(node);
nodeOb.deSerialize(node); nodeOb.deSerialize(node);
//deserialize ports //deserialize ports
_.forEach(node.ports, (port: any) => { _.forEach(node.ports, (port: any) => {
let portOb = diagramEngine.getInstanceFactory(port._class).getInstance() as PortModel; let portOb = diagramEngine.getPortFactory(port.type).getNewInstance();
portOb.deSerialize(port); portOb.deSerialize(port);
nodeOb.addPort(portOb); nodeOb.addPort(portOb);
}); });
@ -87,7 +87,7 @@ export class DiagramModel extends BaseEntity<DiagramListener> {
}); });
_.forEach(object.links, (link: any) => { _.forEach(object.links, (link: any) => {
let linkOb = diagramEngine.getInstanceFactory(link._class).getInstance() as LinkModel; let linkOb = diagramEngine.getLinkFactory(link.type).getNewInstance();
linkOb.deSerialize(link); linkOb.deSerialize(link);
if (link.target) { if (link.target) {

View File

@ -11,15 +11,13 @@ export interface LinkModelListener extends BaseModelListener {
} }
export class LinkModel extends BaseModel<LinkModelListener> { export class LinkModel extends BaseModel<LinkModelListener> {
linkType: string;
sourcePort: PortModel | null; sourcePort: PortModel | null;
targetPort: PortModel | null; targetPort: PortModel | null;
points: PointModel[]; points: PointModel[];
extras: {}; extras: {};
constructor() { constructor(linkType: string = "default", id?: string) {
super(); super(linkType, id);
this.linkType = "default";
this.points = [new PointModel(this, { x: 0, y: 0 }), new PointModel(this, { x: 0, y: 0 })]; this.points = [new PointModel(this, { x: 0, y: 0 }), new PointModel(this, { x: 0, y: 0 })];
this.extras = {}; this.extras = {};
this.sourcePort = null; this.sourcePort = null;
@ -28,7 +26,6 @@ export class LinkModel extends BaseModel<LinkModelListener> {
deSerialize(ob) { deSerialize(ob) {
super.deSerialize(ob); super.deSerialize(ob);
this.linkType = ob.type;
this.extras = ob.extras; this.extras = ob.extras;
this.points = _.map(ob.points, (point: { x; y }) => { this.points = _.map(ob.points, (point: { x; y }) => {
var p = new PointModel(this, { x: point.x, y: point.y }); var p = new PointModel(this, { x: point.x, y: point.y });
@ -39,7 +36,6 @@ export class LinkModel extends BaseModel<LinkModelListener> {
serialize() { serialize() {
return _.merge(super.serialize(), { return _.merge(super.serialize(), {
type: this.linkType,
source: this.sourcePort ? this.sourcePort.getParent().id : null, source: this.sourcePort ? this.sourcePort.getParent().id : null,
sourcePort: this.sourcePort ? this.sourcePort.id : null, sourcePort: this.sourcePort ? this.sourcePort.id : null,
target: this.targetPort ? this.targetPort.getParent().id : null, target: this.targetPort ? this.targetPort.getParent().id : null,
@ -172,8 +168,4 @@ export class LinkModel extends BaseModel<LinkModelListener> {
pointModel.link = this; pointModel.link = this;
this.points.splice(index, 0, pointModel); this.points.splice(index, 0, pointModel);
} }
getType(): string {
return this.linkType;
}
} }

View File

@ -3,15 +3,13 @@ import { PortModel } from "./PortModel";
import * as _ from "lodash"; import * as _ from "lodash";
export class NodeModel extends BaseModel<BaseModelListener> { export class NodeModel extends BaseModel<BaseModelListener> {
nodeType: string;
x: number; x: number;
y: number; y: number;
extras: {}; extras: {};
ports: { [s: string]: PortModel }; ports: { [s: string]: PortModel };
constructor(nodeType: string = "default", id?: string) { constructor(nodeType: string = "default", id?: string) {
super(id); super(nodeType, id);
this.nodeType = nodeType;
this.x = 0; this.x = 0;
this.y = 0; this.y = 0;
this.extras = {}; this.extras = {};
@ -52,7 +50,6 @@ export class NodeModel extends BaseModel<BaseModelListener> {
deSerialize(ob) { deSerialize(ob) {
super.deSerialize(ob); super.deSerialize(ob);
this.nodeType = ob.type;
this.x = ob.x; this.x = ob.x;
this.y = ob.y; this.y = ob.y;
this.extras = ob.extras; this.extras = ob.extras;
@ -60,7 +57,6 @@ export class NodeModel extends BaseModel<BaseModelListener> {
serialize() { serialize() {
return _.merge(super.serialize(), { return _.merge(super.serialize(), {
type: this.nodeType,
x: this.x, x: this.x,
y: this.y, y: this.y,
extras: this.extras, extras: this.extras,
@ -117,8 +113,4 @@ export class NodeModel extends BaseModel<BaseModelListener> {
this.ports[port.name] = port; this.ports[port.name] = port;
return port; return port;
} }
getType(): string {
return this.nodeType;
}
} }

View File

@ -8,6 +8,13 @@ export class PortModel extends BaseModel<BaseModelListener> {
parentNode: NodeModel; parentNode: NodeModel;
links: { [id: string]: LinkModel }; links: { [id: string]: LinkModel };
constructor(name: string, type?: string, id?: string) {
super(type, id);
this.name = name;
this.links = {};
this.parentNode = null;
}
deSerialize(ob) { deSerialize(ob) {
super.deSerialize(ob); super.deSerialize(ob);
this.name = ob.name; this.name = ob.name;
@ -28,13 +35,6 @@ export class PortModel extends BaseModel<BaseModelListener> {
clone.parentNode = this.parentNode.clone(lookupTable); clone.parentNode = this.parentNode.clone(lookupTable);
} }
constructor(name: string, id?: string) {
super(id);
this.name = name;
this.links = {};
this.parentNode = null;
}
getName(): string { getName(): string {
return this.name; return this.name;
} }