nodes/frontend/src/lib/graph-manager.ts

117 lines
2.5 KiB
TypeScript
Raw Normal View History

2024-03-06 18:31:06 +01:00
import { writable, type Writable } from "svelte/store";
import type { Graph, NodeRegistry as INodeRegistry, NodeType, Node } from "./types";
import { snapToGrid } from "./helpers";
const nodeTypes: NodeType[] = [
{
id: "input/float",
inputs: {
"value": { type: "float" },
},
outputs: ["float"],
},
{
id: "math",
inputs: {
"a": { type: "float" },
"b": { type: "float" },
},
outputs: ["float"],
},
]
export class NodeRegistry implements INodeRegistry {
getNode(id: string): NodeType | undefined {
return nodeTypes.find((nodeType) => nodeType.id === id);
}
}
export class GraphManager {
status: Writable<"loading" | "idle" | "error"> = writable("loading");
nodes: Node[] = [];
edges: { from: string, to: string }[] = [];
private constructor(private graph: Graph, private nodeRegistry: NodeRegistry = new NodeRegistry()) {
}
async load() {
const nodes = this.graph.nodes;
for (const node of nodes) {
const nodeType = this.getNodeType(node.type);
if (!nodeType) {
console.error(`Node type not found: ${node.type}`);
this.status.set("error");
return;
}
}
this.nodes = this.graph.nodes;
this.edges = this.graph.edges;
this.status.set("idle");
}
getNode(id: string) {
return this.nodes.find((node) => node.id === id);
}
public getNodeType(id: string): NodeType {
return this.nodeRegistry.getNode(id)!;
}
public getEdges() {
return this.edges
.map((edge) => {
const from = this.nodes.find((node) => node.id === edge.from);
const to = this.nodes.find((node) => node.id === edge.to);
if (!from || !to) return;
return [from, to] as const;
})
.filter(Boolean) as unknown as [Node, Node][];
}
static createEmptyGraph({ width = 20, height = 20 } = {}): GraphManager {
2024-03-06 18:31:06 +01:00
const graph: Graph = {
edges: [],
nodes: [],
};
const amount = width * height;
for (let i = 0; i < amount; i++) {
const x = i % width;
const y = Math.floor(i / height);
2024-03-06 18:31:06 +01:00
graph.nodes.push({
id: `${i.toString()}`,
tmp: {
visible: false,
},
position: {
x: x * 7.5,
y: y * 10,
2024-03-06 18:31:06 +01:00
},
props: i == 0 ? { value: 0 } : {},
type: i == 0 ? "input/float" : "math",
});
graph.edges.push({
from: i.toString(),
to: (i + 1).toString(),
});
}
return new GraphManager(graph);
}
}