feat: load props from node store
This commit is contained in:
parent
f1e537d596
commit
f0ccbf808e
@ -384,8 +384,6 @@ export class GraphManager extends EventEmitter<{ "save": Graph, "result": any, "
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const node: Node = { id: this.createNodeId(), type, position, tmp: { type: nodeType }, props };
|
const node: Node = { id: this.createNodeId(), type, position, tmp: { type: nodeType }, props };
|
||||||
|
|
||||||
this.nodes.update((nodes) => {
|
this.nodes.update((nodes) => {
|
||||||
|
@ -796,11 +796,19 @@
|
|||||||
my += parseInt(nodeOffsetY);
|
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);
|
const pos = projectScreenToWorld(mx, my);
|
||||||
graph.loadNode(nodeId).then(() => {
|
graph.loadNode(nodeId).then(() => {
|
||||||
graph.createNode({
|
graph.createNode({
|
||||||
type: nodeId,
|
type: nodeId,
|
||||||
props: {},
|
props,
|
||||||
position: pos,
|
position: pos,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -15,6 +15,7 @@ const diff = create({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const log = createLogger("history")
|
const log = createLogger("history")
|
||||||
|
log.mute();
|
||||||
|
|
||||||
export class HistoryManager {
|
export class HistoryManager {
|
||||||
|
|
||||||
|
@ -6,12 +6,25 @@
|
|||||||
|
|
||||||
let dragging = false;
|
let dragging = false;
|
||||||
|
|
||||||
|
let nodeData = {
|
||||||
|
id: 0,
|
||||||
|
type: node.id,
|
||||||
|
position: [0, 0] as [number, number],
|
||||||
|
props: {},
|
||||||
|
tmp: {
|
||||||
|
type: node,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
function handleDragStart(e: DragEvent) {
|
function handleDragStart(e: DragEvent) {
|
||||||
dragging = true;
|
dragging = true;
|
||||||
const box = (e?.target as HTMLElement)?.getBoundingClientRect();
|
const box = (e?.target as HTMLElement)?.getBoundingClientRect();
|
||||||
if (e.dataTransfer === null) return;
|
if (e.dataTransfer === null) return;
|
||||||
e.dataTransfer.effectAllowed = "move";
|
e.dataTransfer.effectAllowed = "move";
|
||||||
e.dataTransfer.setData("data/node-id", node.id);
|
e.dataTransfer.setData("data/node-id", node.id);
|
||||||
|
if (nodeData.props) {
|
||||||
|
e.dataTransfer.setData("data/node-props", JSON.stringify(nodeData.props));
|
||||||
|
}
|
||||||
e.dataTransfer.setData(
|
e.dataTransfer.setData(
|
||||||
"data/node-offset-x",
|
"data/node-offset-x",
|
||||||
Math.round(box.left - e.clientX).toString(),
|
Math.round(box.left - e.clientX).toString(),
|
||||||
@ -33,19 +46,7 @@
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
on:dragstart={handleDragStart}
|
on:dragstart={handleDragStart}
|
||||||
>
|
>
|
||||||
<NodeHtml
|
<NodeHtml inView={true} position={"relative"} z={5} bind:node={nodeData} />
|
||||||
inView={true}
|
|
||||||
position={"relative"}
|
|
||||||
z={5}
|
|
||||||
node={{
|
|
||||||
id: 0,
|
|
||||||
type: node.id,
|
|
||||||
position: [0, 0],
|
|
||||||
tmp: {
|
|
||||||
type: node,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -121,110 +121,80 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
const node_type = this.definitionMap.get(node.type)!;
|
const node_type = this.definitionMap.get(node.type)!;
|
||||||
|
|
||||||
if (node?.tmp && node_type?.execute) {
|
if (node?.tmp && node_type?.execute) {
|
||||||
const inputs: Record<string, string | number | boolean> = {};
|
|
||||||
for (const [key, input] of Object.entries(node_type.inputs || {})) {
|
const inputs = Object.entries(node_type.inputs || {}).map(([key, input]) => {
|
||||||
|
|
||||||
if (input.type === "seed") {
|
if (input.type === "seed") {
|
||||||
inputs[key] = runSeed;
|
return runSeed;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.setting) {
|
if (input.setting) {
|
||||||
if (settings[input.setting] === undefined) {
|
if (settings[input.setting] === undefined) {
|
||||||
if (input.value !== undefined) {
|
if ("value" in input && input.value !== undefined) {
|
||||||
inputs[key] = input.value;
|
if (input.type === "float") {
|
||||||
|
return encodeFloat(input.value);
|
||||||
|
}
|
||||||
|
return input.value;
|
||||||
} else {
|
} else {
|
||||||
log.warn(`Setting ${input.setting} is not defined`);
|
log.warn(`Setting ${input.setting} is not defined`);
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// check if the input is connected to another node
|
||||||
const inputNode = node.tmp.inputNodes?.[key];
|
const inputNode = node.tmp?.inputNodes?.[key];
|
||||||
if (inputNode) {
|
if (inputNode) {
|
||||||
if (results[inputNode.id] === undefined) {
|
if (results[inputNode.id] === undefined) {
|
||||||
throw new Error("Input node has no result");
|
throw new Error("Input node has no result");
|
||||||
}
|
}
|
||||||
inputs[key] = results[inputNode.id];
|
return results[inputNode.id];
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the input is not connected to another node, we use the value from the node itself
|
// If the value is stored in the node itself, we use that value
|
||||||
let value = node.props?.[key] ?? input?.value;
|
if (node.props?.[key] !== undefined) {
|
||||||
if (Array.isArray(value)) {
|
let value = node.props[key];
|
||||||
inputs[key] = [0, value.length + 1, ...value, 1, 1];
|
if (input.type === "vec3") {
|
||||||
} else {
|
return [0, 4, ...value.map(v => encodeFloat(v)), 1, 1]
|
||||||
inputs[key] = value;
|
} 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 {
|
try {
|
||||||
const a0 = performance.now();
|
|
||||||
|
|
||||||
const node_inputs = Object.entries(inputs);
|
const encoded_inputs = concatEncodedArrays(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();
|
|
||||||
log.group(`executing ${node_type.id || node.id}`);
|
log.group(`executing ${node_type.id || node.id}`);
|
||||||
log.log(`Inputs:`, transformed_inputs);
|
log.log(`Inputs:`, inputs);
|
||||||
log.log(`Encoded Inputs:`, encoded_inputs);
|
log.log(`Encoded Inputs:`, encoded_inputs);
|
||||||
results[node.id] = node_type.execute(encoded_inputs);
|
results[node.id] = node_type.execute(encoded_inputs);
|
||||||
log.log("Result:", results[node.id]);
|
log.log("Result:", results[node.id]);
|
||||||
log.log("Result (decoded):", decodeNestedArray(results[node.id]));
|
log.log("Result (decoded):", decodeNestedArray(results[node.id]));
|
||||||
log.groupEnd();
|
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) {
|
} catch (e) {
|
||||||
log.groupEnd();
|
log.groupEnd();
|
||||||
log.error(`Error executing node ${node_type.id || node.id}`, e);
|
log.error(`Error executing node ${node_type.id || node.id}`, e);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
import NestedSettings from "./NestedSettings.svelte";
|
import NestedSettings from "./NestedSettings.svelte";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
import type { GraphManager } from "$lib/graph-interface/graph-manager";
|
import type { GraphManager } from "$lib/graph-interface/graph-manager";
|
||||||
import { encodeFloat } from "@nodes/utils";
|
|
||||||
|
|
||||||
function filterInputs(inputs: Record<string, NodeInput>) {
|
function filterInputs(inputs: Record<string, NodeInput>) {
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
@ -43,16 +42,11 @@
|
|||||||
node.props = node.props || {};
|
node.props = node.props || {};
|
||||||
const key = _key as keyof typeof $store;
|
const key = _key as keyof typeof $store;
|
||||||
if (node && $store) {
|
if (node && $store) {
|
||||||
if (Array.isArray($store[key])) {
|
needsUpdate = true;
|
||||||
node.props[key] = [...$store[key]].map((v) => encodeFloat(v));
|
node.props[key] = $store[key];
|
||||||
needsUpdate = true;
|
|
||||||
} else if (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) {
|
if (needsUpdate) {
|
||||||
manager.execute();
|
manager.execute();
|
||||||
}
|
}
|
||||||
|
@ -25,38 +25,39 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each keys as key}
|
{#if store}
|
||||||
{@const value = settings[key]}
|
{#each keys as key}
|
||||||
<div class="wrapper" class:first-level={depth === 0}>
|
{@const value = settings[key]}
|
||||||
{#if isNodeInput(value)}
|
<div class="wrapper" class:first-level={depth === 0}>
|
||||||
<div class="input input-{settings[key].type}">
|
{#if isNodeInput(value)}
|
||||||
{#if settings[key].type === "button"}
|
<div class="input input-{settings[key].type}">
|
||||||
<button on:click={() => settings[key]?.callback?.()}
|
{#if settings[key].type === "button"}
|
||||||
>{settings[key].label || key}</button
|
<button on:click={() => settings[key]?.callback?.()}
|
||||||
>
|
>{settings[key].label || key}</button
|
||||||
{:else}
|
>
|
||||||
<label for={key}>{settings[key].label || key}</label>
|
{:else if "setting" in value}
|
||||||
<Input
|
<label for={key}>{settings[key].label || key}</label>
|
||||||
id={key}
|
<Input id={key} input={value} bind:value={$store[value?.setting]} />
|
||||||
input={value}
|
{:else}
|
||||||
bind:value={$store[value?.setting || key]}
|
<label for={key}>{settings[key].label || key}</label>
|
||||||
/>
|
<Input id={key} input={value} bind:value={$store[key]} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
{#if depth > 0}
|
|
||||||
<hr />
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<details bind:open={$expandedDetails[key]}>
|
|
||||||
<summary>{settings[key]?.__title || key}</summary>
|
|
||||||
<div class="content">
|
|
||||||
<svelte:self settings={settings[key]} {store} depth={depth + 1} />
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
{:else}
|
||||||
{/if}
|
{#if depth > 0}
|
||||||
</div>
|
<hr />
|
||||||
{/each}
|
{/if}
|
||||||
|
|
||||||
|
<details bind:open={$expandedDetails[key]}>
|
||||||
|
<summary>{settings[key]?.__title || key}</summary>
|
||||||
|
<div class="content">
|
||||||
|
<svelte:self settings={settings[key]} {store} depth={depth + 1} />
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
summary {
|
summary {
|
||||||
|
@ -14,7 +14,11 @@
|
|||||||
import NodeStore from "$lib/node-store/NodeStore.svelte";
|
import NodeStore from "$lib/node-store/NodeStore.svelte";
|
||||||
import type { GraphManager } from "$lib/graph-interface/graph-manager";
|
import type { GraphManager } from "$lib/graph-interface/graph-manager";
|
||||||
import { setContext } from "svelte";
|
import { setContext } from "svelte";
|
||||||
import { decodeNestedArray, encodeNestedArray } from "@nodes/utils";
|
import {
|
||||||
|
decodeFloat,
|
||||||
|
decodeNestedArray,
|
||||||
|
encodeNestedArray,
|
||||||
|
} from "@nodes/utils";
|
||||||
import type { PerspectiveCamera, Vector3 } from "three";
|
import type { PerspectiveCamera, Vector3 } from "three";
|
||||||
import type { OrbitControls } from "three/examples/jsm/Addons.js";
|
import type { OrbitControls } from "three/examples/jsm/Addons.js";
|
||||||
import ActiveNode from "$lib/settings/ActiveNode.svelte";
|
import ActiveNode from "$lib/settings/ActiveNode.svelte";
|
||||||
@ -24,6 +28,7 @@
|
|||||||
|
|
||||||
globalThis.decode = decodeNestedArray;
|
globalThis.decode = decodeNestedArray;
|
||||||
globalThis.encode = encodeNestedArray;
|
globalThis.encode = encodeNestedArray;
|
||||||
|
globalThis.decodeFloat = decodeFloat;
|
||||||
|
|
||||||
let res: Int32Array;
|
let res: Int32Array;
|
||||||
let viewerCamera: PerspectiveCamera;
|
let viewerCamera: PerspectiveCamera;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"type": "float",
|
"type": "float",
|
||||||
"label": "Fixate bottom of plant",
|
"label": "Fixate bottom of plant",
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
|
"value": 0,
|
||||||
"min": 0,
|
"min": 0,
|
||||||
"max": 1
|
"max": 1
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
export let max: number | undefined = undefined;
|
export let max: number | undefined = undefined;
|
||||||
export let step = 1;
|
export let step = 1;
|
||||||
export let value = 0;
|
export let value = 0;
|
||||||
|
export let id = "";
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
value = 0;
|
value = 0;
|
||||||
|
@ -12,7 +12,7 @@ export function concatEncodedArrays(input: (number | number[])[]): number[] {
|
|||||||
|
|
||||||
for (let i = 0; i < input.length; i++) {
|
for (let i = 0; i < input.length; i++) {
|
||||||
const item = input[i];
|
const item = input[i];
|
||||||
if (Array.isArray(item)) {
|
if (Array.isArray(item) || item instanceof Int32Array) {
|
||||||
result.push(...item);
|
result.push(...item);
|
||||||
last_closing_bracket = result.length - 1;
|
last_closing_bracket = result.length - 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use crate::log;
|
|
||||||
|
|
||||||
use super::{create_geometry_data, wrap_geometry_data};
|
use super::{create_geometry_data, wrap_geometry_data};
|
||||||
use glam::{Mat4, Vec3};
|
use glam::{Mat4, Vec3};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user