feat: improve loading times
This commit is contained in:
parent
92a7e62d6a
commit
84bcfa61d8
@ -24,7 +24,7 @@
|
||||
.selection {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
border: solid 0.2px white;
|
||||
border: solid 0.2px rgba(200, 200, 200, 0.8);
|
||||
border-style: dashed;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
@ -19,17 +19,11 @@
|
||||
import { CubicBezierCurve } from "three/src/extras/curves/CubicBezierCurve.js";
|
||||
import { Vector3 } from "three/src/math/Vector3.js";
|
||||
import { Vector2 } from "three/src/math/Vector2.js";
|
||||
import { LineMaterial } from "three/examples/jsm/Addons.js";
|
||||
|
||||
export let from: { x: number; y: number };
|
||||
export let to: { x: number; y: number };
|
||||
|
||||
const samples = Math.max(
|
||||
5,
|
||||
Math.floor(
|
||||
Math.sqrt(Math.pow(to.x - from.x, 2) + Math.pow(to.y - from.y, 2)) / 2,
|
||||
),
|
||||
);
|
||||
let samples = 5;
|
||||
|
||||
const curve = new CubicBezierCurve(
|
||||
new Vector2(from.x, from.y),
|
||||
@ -45,8 +39,6 @@
|
||||
|
||||
let mesh: Mesh;
|
||||
|
||||
const color = new Color(32 / 255, 32 / 255, 32 / 255);
|
||||
|
||||
export const update = function (force = false) {
|
||||
if (!force) {
|
||||
const new_x = from.x + to.x;
|
||||
@ -60,18 +52,17 @@
|
||||
|
||||
const mid = new Vector2((from.x + to.x) / 2, (from.y + to.y) / 2);
|
||||
|
||||
// const length = Math.sqrt(
|
||||
// Math.pow(to.x - from.x, 2) + Math.pow(to.y - from.y, 2),
|
||||
// );
|
||||
//
|
||||
const length = Math.floor(
|
||||
Math.sqrt(Math.pow(to.x - from.x, 2) + Math.pow(to.y - from.y, 2)) / 4,
|
||||
);
|
||||
samples = Math.min(Math.max(10, length), 100);
|
||||
|
||||
curve.v0.set(from.x, from.y);
|
||||
curve.v1.set(mid.x, from.y);
|
||||
curve.v2.set(mid.x, to.y);
|
||||
curve.v3.set(to.x, to.y);
|
||||
|
||||
points = curve.getPoints(samples).map((p) => new Vector3(p.x, 0, p.y));
|
||||
// mesh.setGeometry(points);
|
||||
// mesh.needsUpdate = true;
|
||||
};
|
||||
|
||||
update();
|
||||
@ -101,7 +92,9 @@
|
||||
</T.Mesh>
|
||||
|
||||
<T.Mesh position.y={0.5} bind:ref={mesh}>
|
||||
{#key samples}
|
||||
<MeshLineGeometry {points} />
|
||||
{/key}
|
||||
<MeshLineMaterial
|
||||
width={4}
|
||||
attenuate={false}
|
||||
|
@ -24,6 +24,7 @@
|
||||
const status = graph.status;
|
||||
const nodes = graph.nodes;
|
||||
const edges = graph.edges;
|
||||
const graphId = graph.id;
|
||||
|
||||
let camera: OrthographicCamera;
|
||||
const minZoom = 1;
|
||||
@ -523,8 +524,6 @@
|
||||
|
||||
const clickedNodeId = getNodeIdFromEvent(event);
|
||||
|
||||
console.log({ clickedNodeId });
|
||||
|
||||
if (clickedNodeId !== -1) {
|
||||
if (activeNode) {
|
||||
if (!activeNode?.tmp?.isMoving && !event.ctrlKey && !event.shiftKey) {
|
||||
@ -676,7 +675,9 @@
|
||||
to={{ x: mousePosition[0], y: mousePosition[1] }}
|
||||
/>
|
||||
{/if}
|
||||
{#key $graphId}
|
||||
<GraphView {nodes} {edges} {cameraPosition} />
|
||||
{/key}
|
||||
{:else if $status === "loading"}
|
||||
<span>Loading</span>
|
||||
{:else if $status === "error"}
|
||||
|
@ -78,6 +78,7 @@
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
transform: scale(calc(var(--cz) * 0.1));
|
||||
--input-opacity: calc((var(--cz) - 2) / 5);
|
||||
display: var(--node-display, block);
|
||||
opacity: calc((var(--cz) - 2) / 5);
|
||||
}
|
||||
</style>
|
||||
|
@ -4,7 +4,7 @@ import { writable, type Writable } from "svelte/store";
|
||||
import { Color } from "three/src/math/Color.js";
|
||||
|
||||
export const activeNodeId: Writable<number> = writable(-1);
|
||||
export const selectedNodes: Writable<Set<number> | null> = writable(null);
|
||||
export const selectedNodes: Writable<Set<number> | null> = writable(new Set());
|
||||
|
||||
export const activeSocket: Writable<Socket | null> = writable(null);
|
||||
export const hoveredSocket: Writable<Socket | null> = writable(null);
|
||||
|
@ -68,7 +68,7 @@
|
||||
uniforms={{
|
||||
uColorBright: { value: colorBright },
|
||||
uColorDark: { value: colorDark },
|
||||
uSelectedColor: { value: new Color("#f2be90") },
|
||||
uSelectedColor: { value: new Color("#9d5f28") },
|
||||
uActiveColor: { value: new Color("white") },
|
||||
uSelected: { value: false },
|
||||
uActive: { value: false },
|
||||
@ -113,10 +113,8 @@
|
||||
transform: translate3d(var(--nx), var(--ny), 0);
|
||||
z-index: 1;
|
||||
font-weight: 300;
|
||||
display: var(--node-display, block);
|
||||
--stroke: var(--background-color-lighter);
|
||||
--stroke-width: 2px;
|
||||
opacity: var(--input-opacity);
|
||||
}
|
||||
|
||||
.node.active {
|
||||
@ -125,7 +123,7 @@
|
||||
}
|
||||
|
||||
.node.selected {
|
||||
--stroke: #f2be90;
|
||||
--stroke: #9d5f28;
|
||||
--stroke-width: 1px;
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,15 @@ import { type Graph, type Node, type Edge, type Socket, type NodeRegistry, type
|
||||
import { HistoryManager } from "./history-manager";
|
||||
import * as templates from "./graphs";
|
||||
import EventEmitter from "./helpers/EventEmitter";
|
||||
import throttle from "./helpers/throttle";
|
||||
|
||||
export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
|
||||
status: Writable<"loading" | "idle" | "error"> = writable("loading");
|
||||
loaded = false;
|
||||
|
||||
graph: Graph = { nodes: [], edges: [] };
|
||||
graph: Graph = { id: 0, nodes: [], edges: [] };
|
||||
id = writable(0);
|
||||
|
||||
private _nodes: Map<number, Node> = new Map();
|
||||
nodes: Writable<Map<number, Node>> = writable(new Map());
|
||||
@ -32,6 +35,7 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
}
|
||||
this.inputSockets.set(s);
|
||||
});
|
||||
this.execute = throttle(() => this._execute(), 100);
|
||||
}
|
||||
|
||||
serialize(): Graph {
|
||||
@ -42,11 +46,12 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
props: node.props,
|
||||
}));
|
||||
const edges = this._edges.map(edge => [edge[0].id, edge[1], edge[2].id, edge[3]]) as Graph["edges"];
|
||||
return { nodes, edges };
|
||||
return { id: this.graph.id, nodes, edges };
|
||||
}
|
||||
|
||||
execute() {
|
||||
if (!this.runtime["loaded"]) return;
|
||||
execute() { }
|
||||
_execute() {
|
||||
if (this.loaded === false) return;
|
||||
const start = performance.now();
|
||||
const result = this.runtime.execute(this.serialize());
|
||||
const end = performance.now();
|
||||
@ -64,12 +69,11 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
return [node.id, node]
|
||||
}));
|
||||
|
||||
this.edges.set(graph.edges.map((edge) => {
|
||||
const edges = graph.edges.map((edge) => {
|
||||
const from = nodes.get(edge[0]);
|
||||
const to = nodes.get(edge[2]);
|
||||
if (!from || !to) {
|
||||
console.error("Edge references non-existing node");
|
||||
return;
|
||||
throw new Error("Edge references non-existing node");
|
||||
};
|
||||
from.tmp = from.tmp || {};
|
||||
from.tmp.children = from.tmp.children || [];
|
||||
@ -77,19 +81,22 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
to.tmp = to.tmp || {};
|
||||
to.tmp.parents = to.tmp.parents || [];
|
||||
to.tmp.parents.push(from);
|
||||
return [from, edge[1], to, edge[3]] as const;
|
||||
return [from, edge[1], to, edge[3]] as Edge;
|
||||
})
|
||||
.filter(Boolean) as unknown as [Node, number, Node, string][]
|
||||
);
|
||||
|
||||
this.edges.set(edges);
|
||||
this.nodes.set(nodes);
|
||||
|
||||
}
|
||||
|
||||
async load(graph: Graph) {
|
||||
this.loaded = false;
|
||||
this.graph = graph;
|
||||
const a = performance.now();
|
||||
this.status.set("loading");
|
||||
this.id.set(graph.id);
|
||||
|
||||
const b = performance.now();
|
||||
for (const node of this.graph.nodes) {
|
||||
const nodeType = this.nodeRegistry.getNode(node.type);
|
||||
if (!nodeType) {
|
||||
@ -100,13 +107,24 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
node.tmp = node.tmp || {};
|
||||
node.tmp.type = nodeType;
|
||||
}
|
||||
const c = performance.now();
|
||||
|
||||
this._init(this.graph);
|
||||
|
||||
setTimeout(() => {
|
||||
this.status.set("idle");
|
||||
const d = performance.now();
|
||||
|
||||
this.save();
|
||||
}, 100)
|
||||
|
||||
const e = performance.now();
|
||||
|
||||
this.status.set("idle");
|
||||
|
||||
this.loaded = true;
|
||||
const f = performance.now();
|
||||
requestAnimationFrame(() => {
|
||||
console.log(`Loading took ${f - a}ms; a-b: ${b - a}ms; b-c: ${c - b}ms; c-d: ${d - c}ms; d-e: ${e - d}ms; e-f: ${f - e}ms`);
|
||||
this.execute();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,6 +3,7 @@ import type { Graph } from "$lib/types";
|
||||
export function grid(width: number, height: number) {
|
||||
|
||||
const graph: Graph = {
|
||||
id: Math.floor(Math.random() * 100000),
|
||||
edges: [],
|
||||
nodes: [],
|
||||
};
|
||||
|
@ -47,6 +47,10 @@ export function tree(depth: number): Graph {
|
||||
}
|
||||
|
||||
|
||||
return { nodes, edges };
|
||||
return {
|
||||
id: Math.floor(Math.random() * 100000),
|
||||
nodes,
|
||||
edges
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,14 +1,8 @@
|
||||
import type { Graph, Node, NodeRegistry, NodeType, RuntimeExecutor } from "./types";
|
||||
import type { Graph, NodeRegistry, NodeType, RuntimeExecutor } from "./types";
|
||||
|
||||
export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
|
||||
loaded = false;
|
||||
|
||||
constructor(private registry: NodeRegistry) {
|
||||
setTimeout(() => {
|
||||
this.loaded = true;
|
||||
}, 500);
|
||||
}
|
||||
constructor(private registry: NodeRegistry) { }
|
||||
|
||||
private getNodeTypes(graph: Graph) {
|
||||
|
||||
@ -92,7 +86,6 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
}
|
||||
|
||||
execute(graph: Graph) {
|
||||
if (!this.loaded) return;
|
||||
|
||||
// Then we add some metadata to the graph
|
||||
const [outputNode, nodes] = this.addMetaData(graph);
|
||||
|
@ -7,6 +7,7 @@ export type Node = {
|
||||
props?: Record<string, any>,
|
||||
tmp?: {
|
||||
depth?: number;
|
||||
mesh?: any;
|
||||
parents?: Node[],
|
||||
children?: Node[],
|
||||
inputNodes?: Record<string, Node>
|
||||
@ -58,6 +59,7 @@ export interface RuntimeExecutor {
|
||||
export type Edge = [Node, number, Node, string];
|
||||
|
||||
export type Graph = {
|
||||
id: number;
|
||||
meta?: {
|
||||
title?: string;
|
||||
lastModified?: string;
|
||||
|
@ -37,7 +37,7 @@
|
||||
<br />
|
||||
<button
|
||||
on:click={() =>
|
||||
graphManager.load(graphManager.createTemplate("grid", 5, 5))}
|
||||
graphManager.load(graphManager.createTemplate("grid", 10, 10))}
|
||||
>load grid</button
|
||||
>
|
||||
<br />
|
||||
|
Loading…
Reference in New Issue
Block a user