From f0ccbf808ec51fd5ae6ca028e18dc31e608664ff Mon Sep 17 00:00:00 2001 From: Max Richter Date: Wed, 24 Apr 2024 01:40:04 +0200 Subject: [PATCH] feat: load props from node store --- app/src/lib/graph-interface/graph-manager.ts | 2 - .../lib/graph-interface/graph/Graph.svelte | 10 +- .../lib/graph-interface/history-manager.ts | 1 + app/src/lib/node-store/DraggableNode.svelte | 27 +++-- app/src/lib/runtime-executor.ts | 112 +++++++----------- app/src/lib/settings/ActiveNode.svelte | 12 +- app/src/lib/settings/NestedSettings.svelte | 63 +++++----- app/src/routes/+page.svelte | 7 +- nodes/max/plantarium/noise/src/input.json | 1 + packages/types/src/lib.rs | 1 - packages/ui/src/lib/elements/Integer.svelte | 1 + packages/utils/src/flatTree.ts | 2 +- packages/utils/src/geometry/extrude_path.rs | 2 - 13 files changed, 109 insertions(+), 132 deletions(-) diff --git a/app/src/lib/graph-interface/graph-manager.ts b/app/src/lib/graph-interface/graph-manager.ts index 1764979..c9d3545 100644 --- a/app/src/lib/graph-interface/graph-manager.ts +++ b/app/src/lib/graph-interface/graph-manager.ts @@ -384,8 +384,6 @@ export class GraphManager extends EventEmitter<{ "save": Graph, "result": any, " return; } - - const node: Node = { id: this.createNodeId(), type, position, tmp: { type: nodeType }, props }; this.nodes.update((nodes) => { diff --git a/app/src/lib/graph-interface/graph/Graph.svelte b/app/src/lib/graph-interface/graph/Graph.svelte index 56e34c5..272bc1c 100644 --- a/app/src/lib/graph-interface/graph/Graph.svelte +++ b/app/src/lib/graph-interface/graph/Graph.svelte @@ -796,11 +796,19 @@ my += parseInt(nodeOffsetY); } + let props = {}; + let rawNodeProps = event.dataTransfer.getData("data/node-props"); + if (rawNodeProps) { + try { + props = JSON.parse(rawNodeProps); + } catch (e) {} + } + const pos = projectScreenToWorld(mx, my); graph.loadNode(nodeId).then(() => { graph.createNode({ type: nodeId, - props: {}, + props, position: pos, }); }); diff --git a/app/src/lib/graph-interface/history-manager.ts b/app/src/lib/graph-interface/history-manager.ts index 2a6bfc2..f485c4f 100644 --- a/app/src/lib/graph-interface/history-manager.ts +++ b/app/src/lib/graph-interface/history-manager.ts @@ -15,6 +15,7 @@ const diff = create({ }) const log = createLogger("history") +log.mute(); export class HistoryManager { diff --git a/app/src/lib/node-store/DraggableNode.svelte b/app/src/lib/node-store/DraggableNode.svelte index 682a7e0..3815c76 100644 --- a/app/src/lib/node-store/DraggableNode.svelte +++ b/app/src/lib/node-store/DraggableNode.svelte @@ -6,12 +6,25 @@ let dragging = false; + let nodeData = { + id: 0, + type: node.id, + position: [0, 0] as [number, number], + props: {}, + tmp: { + type: node, + }, + }; + function handleDragStart(e: DragEvent) { dragging = true; const box = (e?.target as HTMLElement)?.getBoundingClientRect(); if (e.dataTransfer === null) return; e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData("data/node-id", node.id); + if (nodeData.props) { + e.dataTransfer.setData("data/node-props", JSON.stringify(nodeData.props)); + } e.dataTransfer.setData( "data/node-offset-x", Math.round(box.left - e.clientX).toString(), @@ -33,19 +46,7 @@ tabindex="0" on:dragstart={handleDragStart} > - + diff --git a/app/src/lib/runtime-executor.ts b/app/src/lib/runtime-executor.ts index e17231b..2dd8ea3 100644 --- a/app/src/lib/runtime-executor.ts +++ b/app/src/lib/runtime-executor.ts @@ -121,110 +121,80 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor { const node_type = this.definitionMap.get(node.type)!; if (node?.tmp && node_type?.execute) { - const inputs: Record = {}; - for (const [key, input] of Object.entries(node_type.inputs || {})) { + + const inputs = Object.entries(node_type.inputs || {}).map(([key, input]) => { if (input.type === "seed") { - inputs[key] = runSeed; - continue; + return runSeed; } if (input.setting) { if (settings[input.setting] === undefined) { - if (input.value !== undefined) { - inputs[key] = input.value; + if ("value" in input && input.value !== undefined) { + if (input.type === "float") { + return encodeFloat(input.value); + } + return input.value; } else { log.warn(`Setting ${input.setting} is not defined`); } } else { - inputs[key] = settings[input.setting] as number; + if (input.type === "float") { + return encodeFloat(settings[input.setting] as number); + } + return settings[input.setting]; } - continue; } // check if the input is connected to another node - const inputNode = node.tmp.inputNodes?.[key]; + const inputNode = node.tmp?.inputNodes?.[key]; if (inputNode) { if (results[inputNode.id] === undefined) { throw new Error("Input node has no result"); } - inputs[key] = results[inputNode.id]; - continue; + return results[inputNode.id]; } - // if the input is not connected to another node, we use the value from the node itself - let value = node.props?.[key] ?? input?.value; - if (Array.isArray(value)) { - inputs[key] = [0, value.length + 1, ...value, 1, 1]; - } else { - inputs[key] = value; + // If the value is stored in the node itself, we use that value + if (node.props?.[key] !== undefined) { + let value = node.props[key]; + if (input.type === "vec3") { + return [0, 4, ...value.map(v => encodeFloat(v)), 1, 1] + } else if (Array.isArray(value)) { + return [0, value.length + 1, ...value, 1, 1]; + } else if (input.type === "float") { + return encodeFloat(value); + } else { + return value; + } } - } + let defaultValue = input.value; + if (defaultValue !== undefined) { + if (Array.isArray(defaultValue)) { + return [0, defaultValue.length + 1, ...defaultValue.map(v => encodeFloat(v)), 1, 1]; + } else if (input.type === "float") { + return encodeFloat(defaultValue); + } else { + return defaultValue; + } + } + throw new Error(`Input ${key} is not connected and has no default value`); - // log.log(" "); - // log.log("--> EXECUTING NODE " + node_type.id, node.id); + }); - - // execute the node and store the result try { - const a0 = performance.now(); - const node_inputs = Object.entries(inputs); - const cacheKey = "123" || `${node.id}/${fastHash(node_inputs.map(([_, value]: [string, any]) => { - return value - }))}`; - - const a1 = performance.now(); - // log.log(`${a1 - a0}ms hashed inputs: ${node.id} -> ${cacheKey}`); - - if (false && this.cache[cacheKey] && this.cache[cacheKey].eol > Date.now()) { - results[node.id] = this.cache[cacheKey].value; - log.log(`Using cached value`); - continue; - } - - const transformed_inputs = node_inputs.map(([key, value]: [string, any]) => { - const input_type = node_type.inputs?.[key]!; - if (value instanceof Int32Array) { - let _v = new Array(value.length); - for (let i = 0; i < value.length; i++) { - _v[i] = value[i]; - } - return _v; - } - - if (input_type.type === "float") { - return encodeFloat(value as number); - } - - return value; - }); - - // log.log(transformed_inputs); - - const a2 = performance.now(); - - // log.log(`${a2 - a1}ms TRANSFORMED_INPUTS`); - - const encoded_inputs = concatEncodedArrays(transformed_inputs); - const a3 = performance.now(); + const encoded_inputs = concatEncodedArrays(inputs); log.group(`executing ${node_type.id || node.id}`); - log.log(`Inputs:`, transformed_inputs); + log.log(`Inputs:`, inputs); log.log(`Encoded Inputs:`, encoded_inputs); results[node.id] = node_type.execute(encoded_inputs); log.log("Result:", results[node.id]); log.log("Result (decoded):", decodeNestedArray(results[node.id])); log.groupEnd(); - const duration = performance.now() - a3; - if (duration > 5) { - this.cache[cacheKey] = { eol: Date.now() + 10_000, value: results[node.id] }; - // log.log(`Caching for 10 seconds`); - } - // log.log(`${duration}ms Executed`); - const a4 = performance.now(); - // log.log(`${a4 - a0}ms e2e duration`); + } catch (e) { log.groupEnd(); log.error(`Error executing node ${node_type.id || node.id}`, e); diff --git a/app/src/lib/settings/ActiveNode.svelte b/app/src/lib/settings/ActiveNode.svelte index 7cd5120..415ab4c 100644 --- a/app/src/lib/settings/ActiveNode.svelte +++ b/app/src/lib/settings/ActiveNode.svelte @@ -3,7 +3,6 @@ import NestedSettings from "./NestedSettings.svelte"; import { writable } from "svelte/store"; import type { GraphManager } from "$lib/graph-interface/graph-manager"; - import { encodeFloat } from "@nodes/utils"; function filterInputs(inputs: Record) { return Object.fromEntries( @@ -43,16 +42,11 @@ node.props = node.props || {}; const key = _key as keyof typeof $store; if (node && $store) { - if (Array.isArray($store[key])) { - node.props[key] = [...$store[key]].map((v) => encodeFloat(v)); - needsUpdate = true; - } else if (node.props[key] !== $store[key]) { - needsUpdate = true; - node.props[key] = $store[key]; - } + needsUpdate = true; + node.props[key] = $store[key]; } }); - console.log(needsUpdate, node.props, $store); + // console.log(needsUpdate, node.props, $store); if (needsUpdate) { manager.execute(); } diff --git a/app/src/lib/settings/NestedSettings.svelte b/app/src/lib/settings/NestedSettings.svelte index 486b091..8f229a5 100644 --- a/app/src/lib/settings/NestedSettings.svelte +++ b/app/src/lib/settings/NestedSettings.svelte @@ -25,38 +25,39 @@ } -{#each keys as key} - {@const value = settings[key]} -
- {#if isNodeInput(value)} -
- {#if settings[key].type === "button"} - - {:else} - - - {/if} -
- {:else} - {#if depth > 0} -
- {/if} - -
- {settings[key]?.__title || key} -
- +{#if store} + {#each keys as key} + {@const value = settings[key]} +
+ {#if isNodeInput(value)} +
+ {#if settings[key].type === "button"} + + {:else if "setting" in value} + + + {:else} + + + {/if}
-
- {/if} -
-{/each} + {:else} + {#if depth > 0} +
+ {/if} + +
+ {settings[key]?.__title || key} +
+ +
+
+ {/if} + + {/each} +{/if}