@openhps/core
Version:
Open Hybrid Positioning System - Core component
301 lines • 11.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphShapeBuilder = exports.GraphBuilder = void 0;
const utils_1 = require("../../utils");
const GraphShape_1 = require("../_internal/implementations/GraphShape");
const PlaceholderNode_1 = require("../../nodes/_internal/PlaceholderNode");
const SourceNode_1 = require("../../nodes/SourceNode");
const Edge_1 = require("../Edge");
const implementations_1 = require("../_internal/implementations");
/**
* Graph builder
* @category Graph
*/
class GraphBuilder {
constructor(graph = new GraphShape_1.GraphShape()) {
this.graph = graph;
this.graph.name = 'graph';
}
static create() {
return new GraphBuilder();
}
on(name, listener) {
this.graph.once(name, listener);
return this;
}
from(...nodes) {
const selectedNodes = [];
nodes.forEach((node) => {
if (node === undefined) {
throw new Error('Undefined node was provided as a source!');
}
else if (typeof node === 'string') {
let nodeObject = this.graph.findNodeByUID(node) || this.graph.findNodeByName(node);
if (nodeObject === undefined) {
// Add a placeholder
nodeObject = new PlaceholderNode_1.PlaceholderNode(node);
}
this.graph.addNode(nodeObject);
selectedNodes.push(nodeObject);
}
else {
this.graph.addNode(node);
if (node instanceof SourceNode_1.SourceNode) {
this.graph.addEdge(new Edge_1.Edge(this.graph.internalSource, node));
}
selectedNodes.push(node);
}
});
return new GraphShapeBuilder(this, this.graph, selectedNodes.length === 0 ? [this.graph.internalSource] : selectedNodes);
}
addNode(node) {
this.graph.addNode(node);
return this;
}
addEdge(edge) {
this.graph.addEdge(edge);
return this;
}
deleteEdge(edge) {
this.graph.deleteEdge(edge);
return this;
}
deleteNode(node) {
this.graph.deleteNode(node);
return this;
}
/**
* Add graph shape to graph
* @param {GraphBuilder | GraphShape} shape Graph builder or abstract graph
* @returns {GraphBuilder} Current graph builder instance
*/
addShape(shape) {
let graph;
if (shape instanceof GraphBuilder) {
graph = shape.graph;
}
else {
graph = shape;
}
// Add the graph node and edges
graph.nodes.forEach((node) => {
// Check if the node is a placeholder
if (node instanceof PlaceholderNode_1.PlaceholderNode) {
// Try to find a node with the same uid/name as the placeholder node
const existingNode = this.graph.findNodeByUID(node.name) || this.graph.findNodeByName(node.name);
if (existingNode) {
// Edit the edges connected to this placeholder
const outputEdges = graph.edges.filter((edge) => edge.inputNode === node);
const inputEdges = graph.edges.filter((edge) => edge.outputNode === node);
outputEdges.map((edge) => (edge.inputNode = existingNode));
inputEdges.map((edge) => (edge.outputNode = existingNode));
this.addNode(existingNode);
}
else {
// Add the node as a placeholder
this.addNode(node);
}
}
else {
this.addNode(node);
}
});
graph.edges.forEach((edge) => {
this.addEdge(edge);
});
// Connect internal and external output to shape
this.graph.addEdge(new Edge_1.Edge(this.graph.internalSource, graph.internalSource));
this.graph.addEdge(new Edge_1.Edge(graph.internalSink, this.graph.internalSink));
return this;
}
// worker(options?: WorkerOptions): Promise<Graph<In, Out>> {
// return new Promise((resolve, reject) => {
// this.build()
// .then((graph) => {
// const worker = new WorkerNode(graph, options);
// resolve(GraphBuilder.create().from().via(worker).to());
// })
// .catch(reject);
// });
// }
build() {
return new Promise((resolve, reject) => {
implementations_1.GraphValidator.validate(this.graph);
this.graph.once('ready', () => {
resolve(this.graph);
});
this.graph.emitAsync('build', this).catch((ex) => {
// Destroy model
this.graph.emit('destroy');
reject(ex);
});
});
}
}
exports.GraphBuilder = GraphBuilder;
class GraphShapeBuilder {
constructor(graphBuilder, graph, nodes) {
this.graphBuilder = graphBuilder;
this.previousNodes = nodes;
this.graph = graph;
}
viaGraph(graph) {
// Add graph as node
graph.nodes.forEach((node) => {
node.graph = this.graph;
this.graph.addNode(node);
});
graph.edges.forEach((edge) => {
this.graph.addEdge(edge);
});
this._insertNode(graph.internalSource);
return graph.internalSink;
}
via(...nodes) {
const selectedNodes = [];
nodes.forEach((node) => {
if (node === undefined) {
throw new Error('Undefined node was provided!');
}
else if (node instanceof GraphBuilder) {
selectedNodes.push(this.viaGraph(node.graph));
}
else if (node instanceof GraphShape_1.GraphShape) {
selectedNodes.push(this.viaGraph(node));
}
else {
let nodeObject;
if (typeof node === 'string') {
nodeObject = this.graph.findNodeByUID(node) || this.graph.findNodeByName(node);
if (nodeObject === undefined) {
// Add a placeholder
nodeObject = new PlaceholderNode_1.PlaceholderNode(node);
}
}
else {
nodeObject = node;
}
this.graph.addNode(nodeObject);
this._insertNode(nodeObject);
selectedNodes.push(nodeObject);
}
});
this.previousNodes = selectedNodes;
return this;
}
/**
* Insert a new node in the existing graph
* @param {Node} node Node to insert
*/
_insertNode(node) {
this.previousNodes.forEach((prevNode) => {
this.graph.addEdge(new Edge_1.Edge(prevNode, node));
});
}
static registerShape(key, fn) {
GraphShapeBuilder.shapes.set(key, fn);
}
chunk(size, timeout, timeoutUnit) {
return this.via(GraphShapeBuilder.shapes.get('chunk')(size, timeout, timeoutUnit));
}
flatten() {
return this.via(GraphShapeBuilder.shapes.get('flatten')());
}
filter(filterFn) {
return this.via(GraphShapeBuilder.shapes.get('filter')(filterFn));
}
/**
* Filter objects inside frames
* @param {Function} filterFn Filter function (true to keep, false to remove)
* @returns {GraphShapeBuilder} Current graph builder instance
*/
filterObjects(filterFn) {
return this.via(GraphShapeBuilder.shapes.get('filterObjects')(filterFn));
}
/**
* Merge objects
* @param {Function} by Merge key
* @param {number} timeout Timeout
* @param {TimeUnit} timeoutUnit Timeout unit
* @returns {GraphShapeBuilder} Current graph shape builder
*/
merge(by = () => true, timeout = 100, timeoutUnit = utils_1.TimeUnit.MILLISECOND) {
return this.via(GraphShapeBuilder.shapes.get('merge')(by, timeout, timeoutUnit));
}
debounce(timeout = 100, timeoutUnit = utils_1.TimeUnit.MILLISECOND) {
return this.via(GraphShapeBuilder.shapes.get('debounce')(timeout, timeoutUnit));
}
delay(timeout = 100, timeoutUnit = utils_1.TimeUnit.MILLISECOND) {
return this.via(GraphShapeBuilder.shapes.get('delay')(timeout, timeoutUnit));
}
/**
* Clone frames
* @returns {GraphShapeBuilder} Current graph shape builder
*/
clone() {
return this.via(GraphShapeBuilder.shapes.get('clone')());
}
/**
* Convert positions of all objects to a certain reference space
* @param {ReferenceSpace | string} referenceSpace Reference space to convert to
* @returns {GraphShapeBuilder} Current graph shape builder
*/
convertToSpace(referenceSpace) {
return this.via(GraphShapeBuilder.shapes.get('convertToSpace')(referenceSpace));
}
/**
* Convert positions of all objects from a certain reference space
* @param {ReferenceSpace | string} referenceSpace Reference space to convert from
* @returns {GraphShapeBuilder} Current graph shape builder
*/
convertFromSpace(referenceSpace) {
return this.via(GraphShapeBuilder.shapes.get('convertFromSpace')(referenceSpace));
}
/**
* Buffer pushed objects
* @returns {GraphShapeBuilder} Current graph shape builder
*/
buffer() {
return this.via(GraphShapeBuilder.shapes.get('buffer')());
}
/**
* Storage as sink node
* @returns {GraphBuilder} Graph builder
*/
store() {
return this.to(GraphShapeBuilder.shapes.get('store')());
}
to(...nodes) {
if (nodes.length !== 0) {
const selectedNodes = [];
nodes.forEach((node) => {
let nodeObject;
if (node === undefined) {
throw new Error('Undefined node was provided as a sink!');
}
else if (typeof node === 'string') {
nodeObject = this.graph.findNodeByUID(node) || this.graph.findNodeByName(node);
if (nodeObject === undefined) {
// Add a placeholder
nodeObject = new PlaceholderNode_1.PlaceholderNode(node);
}
}
else {
nodeObject = node;
}
this.graph.addNode(nodeObject);
this._insertNode(nodeObject);
this.graph.addEdge(new Edge_1.Edge(nodeObject, this.graph.internalSink));
selectedNodes.push(nodeObject);
});
this.previousNodes = selectedNodes;
}
else {
this._insertNode(this.graph.internalSink);
}
return this.graphBuilder;
}
}
exports.GraphShapeBuilder = GraphShapeBuilder;
GraphShapeBuilder.shapes = new Map();
//# sourceMappingURL=GraphBuilder.js.map