From 0ecf9798c4b9f9b664e79e4dc390bc3a93267118 Mon Sep 17 00:00:00 2001 From: Max Richter Date: Fri, 5 Apr 2024 19:38:10 +0200 Subject: [PATCH] feat: some stuff --- Cargo.lock | 27 +++++---- app/src/lib/components/graph/Graph.svelte | 14 ++++- app/src/lib/components/node/Node.svelte | 4 +- .../lib/components/node/NodeParameter.svelte | 2 +- app/src/lib/graphs/grid.ts | 4 +- app/src/lib/node-registry.ts | 10 ++-- app/src/lib/runtime-executor.ts | 7 ++- app/src/routes/+page.svelte | 7 ++- .../{input-float => float}/.gitignore | 0 .../{input-float => float}/Cargo.toml | 2 +- .../{input-float => float}/package.json | 0 .../{input-float => float}/src/lib.rs | 5 -- .../{input-float => float}/src/utils.rs | 0 .../{input-float => float}/tests/web.rs | 0 nodes/max/plantarium/math/src/lib.rs | 9 +-- nodes/max/plantarium/output/Cargo.toml | 1 + nodes/max/plantarium/output/src/lib.rs | 16 ++--- nodes/max/plantarium/random/src/lib.rs | 42 ++++++++++--- packages/node-registry/src/lib/registry.ts | 3 +- packages/plantarium/Cargo.toml | 2 + packages/plantarium/src/helpers.rs | 60 +++++++++++++++++-- packages/types/inputs.ts | 8 ++- 22 files changed, 157 insertions(+), 66 deletions(-) rename nodes/max/plantarium/{input-float => float}/.gitignore (100%) rename nodes/max/plantarium/{input-float => float}/Cargo.toml (97%) rename nodes/max/plantarium/{input-float => float}/package.json (100%) rename nodes/max/plantarium/{input-float => float}/src/lib.rs (86%) rename nodes/max/plantarium/{input-float => float}/src/utils.rs (100%) rename nodes/max/plantarium/{input-float => float}/tests/web.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index ac635f6..84ceb68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -950,6 +950,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "plantarium", + "serde", + "serde-wasm-bindgen", + "wasm-bindgen", + "wasm-bindgen-test", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1626,18 +1638,6 @@ dependencies = [ "cfb", ] -[[package]] -name = "input-float" -version = "0.1.0" -dependencies = [ - "console_error_panic_hook", - "plantarium", - "serde", - "serde-wasm-bindgen", - "wasm-bindgen", - "wasm-bindgen-test", -] - [[package]] name = "instant" version = "0.1.12" @@ -2234,6 +2234,7 @@ dependencies = [ "plantarium", "serde", "serde-wasm-bindgen", + "serde_json", "wasm-bindgen", "wasm-bindgen-test", ] @@ -2486,6 +2487,8 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" name = "plantarium" version = "0.1.0" dependencies = [ + "serde", + "serde_json", "wasm-bindgen", ] diff --git a/app/src/lib/components/graph/Graph.svelte b/app/src/lib/components/graph/Graph.svelte index 8f6e68a..dd36812 100644 --- a/app/src/lib/components/graph/Graph.svelte +++ b/app/src/lib/components/graph/Graph.svelte @@ -111,7 +111,8 @@ if (!node?.inputs) { return 5; } - const height = 5 + 10 * Object.keys(node.inputs).length; + const height = + 5 + 10 * Object.keys(node.inputs).filter((i) => i !== "seed").length; nodeHeightCache[nodeTypeId] = height; return height; } @@ -385,6 +386,17 @@ function handleMouseDown(event: MouseEvent) { if (mouseDown) return; + + if (event.target instanceof HTMLElement) { + if ( + event.target.nodeName !== "CANVAS" && + !event.target.classList.contains("node") && + !event.target.classList.contains("content") + ) { + return; + } + } + mouseDown = [event.clientX, event.clientY]; cameraDown[0] = cameraPosition[0]; cameraDown[1] = cameraPosition[1]; diff --git a/app/src/lib/components/node/Node.svelte b/app/src/lib/components/node/Node.svelte index ca9fce1..01ba489 100644 --- a/app/src/lib/components/node/Node.svelte +++ b/app/src/lib/components/node/Node.svelte @@ -23,7 +23,9 @@ const type = node?.tmp?.type; - const parameters = Object.entries(type?.inputs || {}); + const parameters = Object.entries(type?.inputs || {}).filter( + (p) => p[1].type !== "seed", + ); let ref: HTMLDivElement; let meshRef: Mesh; diff --git a/app/src/lib/components/node/NodeParameter.svelte b/app/src/lib/components/node/NodeParameter.svelte index cce5a36..4990d8a 100644 --- a/app/src/lib/components/node/NodeParameter.svelte +++ b/app/src/lib/components/node/NodeParameter.svelte @@ -71,7 +71,7 @@ {#key id && graphId} {#if node?.tmp?.type?.inputs?.[id]?.external !== true}
- +
{/if} diff --git a/app/src/lib/graphs/grid.ts b/app/src/lib/graphs/grid.ts index 2302111..9e276df 100644 --- a/app/src/lib/graphs/grid.ts +++ b/app/src/lib/graphs/grid.ts @@ -20,8 +20,8 @@ export function grid(width: number, height: number) { visible: false, }, position: [x * 30, y * 40], - props: i == 0 ? { value: 0 } : { op_type: 1, a: 2, b: i }, - type: i == 0 ? "max/plantarium/input-float" : "max/plantarium/math", + props: i == 0 ? { value: 0 } : { op_type: 2, a: 2, b: 2 }, + type: i == 0 ? "max/plantarium/float" : "max/plantarium/math", }); graph.edges.push([i, 0, i + 1, i === amount - 1 ? "input" : "a",]); diff --git a/app/src/lib/node-registry.ts b/app/src/lib/node-registry.ts index 08f7c98..32752a1 100644 --- a/app/src/lib/node-registry.ts +++ b/app/src/lib/node-registry.ts @@ -1,11 +1,10 @@ import type { NodeRegistry, NodeType } from "@nodes/types"; -import * as d from "plantarium-nodes-math"; import { createLogger } from "./helpers"; const nodeTypes: NodeType[] = [ { - id: "max/plantarium/input-float", + id: "max/plantarium/float", inputs: { "value": { type: "float", value: 0.1, internal: true }, }, @@ -48,6 +47,8 @@ export class RemoteNodeRegistry implements NodeRegistry { async load(nodeIds: string[]) { const a = performance.now(); + nodeIds.push("max/plantarium/random"); + nodeIds.push("max/plantarium/float"); for (const id of nodeIds) { const nodeUrl = `${this.url}/n/${id}`; const response = await fetch(nodeUrl); @@ -70,10 +71,7 @@ wasm = val;`); throw new Error(`Failed to load node ${id}`); } const node = await response.json(); - node.execute = (...args) => { - console.log("Executing", id, args); - return wasmWrapper.execute(...args) - }; + node.execute = wasmWrapper.execute; this.nodes.set(id, node); } diff --git a/app/src/lib/runtime-executor.ts b/app/src/lib/runtime-executor.ts index c59cfb5..e226044 100644 --- a/app/src/lib/runtime-executor.ts +++ b/app/src/lib/runtime-executor.ts @@ -101,7 +101,6 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor { // we execute the nodes from the bottom up const sortedNodes = nodes.sort((a, b) => (b.tmp?.depth || 0) - (a.tmp?.depth || 0)); - // here we store the intermediate results of the nodes const results: Record = {}; @@ -110,6 +109,11 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor { const inputs: Record = {}; for (const [key, input] of Object.entries(node.tmp.type.inputs || {})) { + if (input.type === "seed") { + inputs[key] = Math.floor(Math.random() * 100000000); + continue; + } + // check if the input is connected to another node const inputNode = node.tmp.inputNodes?.[key]; if (inputNode) { @@ -122,6 +126,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor { // if the input is not connected to another node, we use the value from the node itself inputs[key] = node.props?.[key] ?? input?.value; + } // execute the node and store the result diff --git a/app/src/routes/+page.svelte b/app/src/routes/+page.svelte index 8267508..8d048de 100644 --- a/app/src/routes/+page.svelte +++ b/app/src/routes/+page.svelte @@ -39,9 +39,14 @@
+

diff --git a/nodes/max/plantarium/input-float/.gitignore b/nodes/max/plantarium/float/.gitignore similarity index 100% rename from nodes/max/plantarium/input-float/.gitignore rename to nodes/max/plantarium/float/.gitignore diff --git a/nodes/max/plantarium/input-float/Cargo.toml b/nodes/max/plantarium/float/Cargo.toml similarity index 97% rename from nodes/max/plantarium/input-float/Cargo.toml rename to nodes/max/plantarium/float/Cargo.toml index 61ebfc3..4ad3ce8 100644 --- a/nodes/max/plantarium/input-float/Cargo.toml +++ b/nodes/max/plantarium/float/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "input-float" +name = "float" version = "0.1.0" authors = ["Max Richter "] edition = "2018" diff --git a/nodes/max/plantarium/input-float/package.json b/nodes/max/plantarium/float/package.json similarity index 100% rename from nodes/max/plantarium/input-float/package.json rename to nodes/max/plantarium/float/package.json diff --git a/nodes/max/plantarium/input-float/src/lib.rs b/nodes/max/plantarium/float/src/lib.rs similarity index 86% rename from nodes/max/plantarium/input-float/src/lib.rs rename to nodes/max/plantarium/float/src/lib.rs index 5d3ec7f..3c1712f 100644 --- a/nodes/max/plantarium/input-float/src/lib.rs +++ b/nodes/max/plantarium/float/src/lib.rs @@ -7,11 +7,6 @@ pub fn get_outputs() -> Vec { vec!["float".to_string()] } -#[wasm_bindgen] -pub fn get_id() -> String { - "float".to_string() -} - #[wasm_bindgen] pub fn get_input_types() -> String { utils::set_panic_hook(); diff --git a/nodes/max/plantarium/input-float/src/utils.rs b/nodes/max/plantarium/float/src/utils.rs similarity index 100% rename from nodes/max/plantarium/input-float/src/utils.rs rename to nodes/max/plantarium/float/src/utils.rs diff --git a/nodes/max/plantarium/input-float/tests/web.rs b/nodes/max/plantarium/float/tests/web.rs similarity index 100% rename from nodes/max/plantarium/input-float/tests/web.rs rename to nodes/max/plantarium/float/tests/web.rs diff --git a/nodes/max/plantarium/math/src/lib.rs b/nodes/max/plantarium/math/src/lib.rs index a034bb7..1abb125 100644 --- a/nodes/max/plantarium/math/src/lib.rs +++ b/nodes/max/plantarium/math/src/lib.rs @@ -8,16 +8,11 @@ pub fn get_outputs() -> Vec { vec!["float".to_string()] } -#[wasm_bindgen] -pub fn get_id() -> String { - "math".to_string() -} - #[wasm_bindgen] pub fn get_input_types() -> String { utils::set_panic_hook(); r#"{ - "op_type": { "type": "select", "labels": ["add", "subtract", "multiply", "divide"], "internal": true, "value": 0 }, + "op_type": { "label": "type", "type": "select", "labels": ["add", "subtract", "multiply", "divide"], "internal": true, "value": 0 }, "a": { "type": "float", "value": 2 }, "b": { "type": "float", "value": 2 } }"#.to_string() @@ -44,7 +39,7 @@ pub fn execute(var_op_type: u8, var_a: JsValue, var_b: JsValue) -> String { // Interpolate strings into JSON format let json_string = format!( - r#"{{"parameter": "math", "op_type": {}, "a": {}, "b": {}}}"#, + r#"{{"__type": "math", "op_type": {}, "a": {}, "b": {}}}"#, var_op_type, a, b ); diff --git a/nodes/max/plantarium/output/Cargo.toml b/nodes/max/plantarium/output/Cargo.toml index e6587ab..a9f8251 100644 --- a/nodes/max/plantarium/output/Cargo.toml +++ b/nodes/max/plantarium/output/Cargo.toml @@ -19,6 +19,7 @@ wasm-bindgen = "0.2.84" # code size when deploying. plantarium = { version = "0.1.0", path = "../../../../packages/plantarium" } serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0", default-features = false, features = ["alloc"] } serde-wasm-bindgen = "0.4" console_error_panic_hook = { version = "0.1.7", optional = true } diff --git a/nodes/max/plantarium/output/src/lib.rs b/nodes/max/plantarium/output/src/lib.rs index ed8d935..8bb4c90 100644 --- a/nodes/max/plantarium/output/src/lib.rs +++ b/nodes/max/plantarium/output/src/lib.rs @@ -1,5 +1,5 @@ mod utils; -use plantarium::unwrap_string; +use plantarium::evaluate_parameters; use wasm_bindgen::prelude::*; // lifted from the `console_log` example @@ -14,11 +14,6 @@ pub fn get_outputs() -> Vec { vec![] } -#[wasm_bindgen] -pub fn get_id() -> String { - "float".to_string() -} - #[wasm_bindgen] pub fn get_input_types() -> String { utils::set_panic_hook(); @@ -27,14 +22,11 @@ pub fn get_input_types() -> String { }"# .to_string() } - #[wasm_bindgen] -pub fn execute(var_value: JsValue) -> String { +pub fn execute(var_value: JsValue) -> f64 { utils::set_panic_hook(); - let str = unwrap_string(var_value); + let res = evaluate_parameters(var_value); - log(&format!("str: {}", str)); - - return str; + return res; } diff --git a/nodes/max/plantarium/random/src/lib.rs b/nodes/max/plantarium/random/src/lib.rs index 06889ae..67398ef 100644 --- a/nodes/max/plantarium/random/src/lib.rs +++ b/nodes/max/plantarium/random/src/lib.rs @@ -1,16 +1,19 @@ mod utils; +use plantarium::{unwrap_int, unwrap_string}; use wasm_bindgen::prelude::*; +// lifted from the `console_log` example +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} + #[wasm_bindgen] pub fn get_outputs() -> Vec { vec!["float".to_string()] } -#[wasm_bindgen] -pub fn get_id() -> String { - "random".to_string() -} - #[wasm_bindgen] pub fn get_input_types() -> String { utils::set_panic_hook(); @@ -23,13 +26,36 @@ pub fn get_input_types() -> String { } #[wasm_bindgen] -pub fn execute(var_min: String, var_max: String, var_seed: i32) -> String { +pub fn execute(var_min: JsValue, var_max: JsValue, var_seed: JsValue) -> String { utils::set_panic_hook(); + let min: String; + if var_min.is_string() { + min = unwrap_string(var_min); + } else { + min = unwrap_int(var_min).to_string(); + } + + let max: String; + if var_max.is_string() { + max = unwrap_string(var_max); + } else { + max = unwrap_int(var_max).to_string(); + } + + let seed: String; + if var_seed.is_string() { + seed = unwrap_string(var_seed); + } else { + seed = unwrap_int(var_seed).to_string(); + } + + log(&format!("min: {}, max: {}, seed: {}", min, max, seed)); + // Interpolate strings into JSON format let json_string = format!( - r#"{{"parameter": "random", "min": {}, "max": {}, "seed": {}}}"#, - var_min, var_max, var_seed + r#"{{"__type": "random", "min": {}, "max": {}, "seed": {}}}"#, + min, max, seed ); json_string diff --git a/packages/node-registry/src/lib/registry.ts b/packages/node-registry/src/lib/registry.ts index 0bef403..d3e4656 100644 --- a/packages/node-registry/src/lib/registry.ts +++ b/packages/node-registry/src/lib/registry.ts @@ -35,10 +35,9 @@ export async function getNode(id: `${string}/${string}/${string}`) { const wrapper = await getNodeWasm(id); - const node_id = wrapper.get_id(); const outputs = wrapper.get_outputs(); const inputTypes = JSON.parse(wrapper.get_input_types()); - return { id: node_id, outputs, inputs: inputTypes } + return { id, outputs, inputs: inputTypes } } diff --git a/packages/plantarium/Cargo.toml b/packages/plantarium/Cargo.toml index f06193a..cded29d 100644 --- a/packages/plantarium/Cargo.toml +++ b/packages/plantarium/Cargo.toml @@ -5,3 +5,5 @@ edition = "2021" [dependencies] wasm-bindgen = "0.2.92" +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0", default-features = false, features = ["alloc"] } diff --git a/packages/plantarium/src/helpers.rs b/packages/plantarium/src/helpers.rs index e277cdc..4a0e6c4 100644 --- a/packages/plantarium/src/helpers.rs +++ b/packages/plantarium/src/helpers.rs @@ -1,10 +1,13 @@ +use std::cell::RefCell; + +use serde_json::Value; use wasm_bindgen::prelude::*; -pub fn unwrap_int(val: JsValue) -> u8 { +pub fn unwrap_int(val: JsValue) -> i32 { if val.is_undefined() || val.is_null() { panic!("Value is undefined"); } - return val.as_f64().unwrap() as u8; + return val.as_f64().unwrap() as i32; } pub fn unwrap_float(val: JsValue) -> f64 { @@ -21,6 +24,55 @@ pub fn unwrap_string(val: JsValue) -> String { return val.as_string().unwrap(); } -pub fn evaluate_parameter(_val: String) -> i32 { - return 2; +pub fn evaluate_parameters(val: JsValue) -> f64 { + let str = unwrap_string(val); + let v: Value = serde_json::from_str(&str).unwrap(); + let index = RefCell::new(0.0); + return walk_json(&v, &index); +} + +fn walk_json(value: &Value, depth: &RefCell) -> f64 { + *depth.borrow_mut() += 1.0; + match value { + // If it's an object, recursively walk through its fields + Value::Object(obj) => { + let obj_type = obj.get("__type").unwrap(); + if obj_type == "random" { + let min = walk_json(obj.get("min").unwrap(), depth); + let max = walk_json(obj.get("max").unwrap(), depth); + let seed = (obj.get("seed").unwrap().as_f64().unwrap() + *depth.borrow() * 2000.0) + / 1000000.0; + let range = max - min; + let seed = seed % range; + return seed - min; + } else if obj_type == "math" { + let a = walk_json(obj.get("a").unwrap(), depth); + let b = walk_json(obj.get("b").unwrap(), depth); + let op_type = obj.get("op_type").unwrap(); + if op_type == 0 { + return a + b; + } else if op_type == 1 { + return a - b; + } else if op_type == 2 { + return a * b; + } else if op_type == 3 { + return a / b; + } + } + return 0.0; + } + Value::Array(arr) => { + for val in arr { + walk_json(val, depth); + } + return 0.0; + } + Value::Number(num) => { + return num.as_f64().unwrap(); + } + // If it's a primitive value, print it + _ => { + return 0.0; + } + } } diff --git a/packages/types/inputs.ts b/packages/types/inputs.ts index 1f2f7a0..c387e38 100644 --- a/packages/types/inputs.ts +++ b/packages/types/inputs.ts @@ -24,13 +24,17 @@ type NodeInputSelect = { value?: number; } +type NodeInputSeed = { + type: "seed" +} + type DefaultOptions = { internal?: boolean; external?: boolean; - title?: string; + label?: string; } -export type NodeInput = (NodeInputBoolean | NodeInputFloat | NodeInputInteger | NodeInputSelect) & DefaultOptions; +export type NodeInput = (NodeInputSeed | NodeInputBoolean | NodeInputFloat | NodeInputInteger | NodeInputSelect) & DefaultOptions; export type NodeInputType> = {