feat: did some stuff
This commit is contained in:
parent
8035b26750
commit
b3780fdf96
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -1626,6 +1626,18 @@ dependencies = [
|
|||||||
"cfb",
|
"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]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
@ -2214,6 +2226,18 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "output"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"console_error_panic_hook",
|
||||||
|
"plantarium",
|
||||||
|
"serde",
|
||||||
|
"serde-wasm-bindgen",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-test",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "overload"
|
name = "overload"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -5,17 +5,19 @@
|
|||||||
|
|
||||||
export let node: Node;
|
export let node: Node;
|
||||||
export let input: NodeInput;
|
export let input: NodeInput;
|
||||||
export let label: string;
|
export let id: string;
|
||||||
|
export let label: string | undefined;
|
||||||
|
|
||||||
const graph = getGraphManager();
|
const graph = getGraphManager();
|
||||||
|
|
||||||
let value = node?.props?.[label] ?? input.value;
|
let value = node?.props?.[id] ?? input.value;
|
||||||
|
|
||||||
$: if (node?.props?.[label] !== value) {
|
$: if (node?.props?.[id] !== value) {
|
||||||
node.props = { ...node.props, [label]: value };
|
node.props = { ...node.props, [id]: value };
|
||||||
|
graph.save();
|
||||||
graph.execute();
|
graph.execute();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label for="asd">{label}</label>
|
<label for="asd">{label || id}</label>
|
||||||
<Input {input} bind:value />
|
<Input {input} bind:value />
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
import { possibleSocketIds } from "../graph/stores";
|
import { possibleSocketIds } from "../graph/stores";
|
||||||
import { getGraphManager } from "../graph/context";
|
import { getGraphManager } from "../graph/context";
|
||||||
import NodeInput from "./NodeInput.svelte";
|
import NodeInput from "./NodeInput.svelte";
|
||||||
|
import Node from "./Node.svelte";
|
||||||
|
|
||||||
export let node: Node;
|
export let node: Node;
|
||||||
export let input: NodeInputType;
|
export let input: NodeInputType;
|
||||||
@ -68,9 +69,11 @@
|
|||||||
class:disabled={$possibleSocketIds && !$possibleSocketIds.has(socketId)}
|
class:disabled={$possibleSocketIds && !$possibleSocketIds.has(socketId)}
|
||||||
>
|
>
|
||||||
{#key id && graphId}
|
{#key id && graphId}
|
||||||
<div class="content" class:disabled={$inputSockets.has(socketId)}>
|
{#if node?.tmp?.type?.inputs?.[id]?.external !== true}
|
||||||
<NodeInput {node} {input} label={input?.title || id} />
|
<div class="content" class:disabled={$inputSockets.has(socketId)}>
|
||||||
</div>
|
<NodeInput {node} {input} {id} label={input.title} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if node?.tmp?.type?.inputs?.[id]?.internal !== true}
|
{#if node?.tmp?.type?.inputs?.[id]?.internal !== true}
|
||||||
<div
|
<div
|
||||||
|
@ -145,7 +145,8 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
|||||||
this.status.set("loading");
|
this.status.set("loading");
|
||||||
this.id.set(graph.id);
|
this.id.set(graph.id);
|
||||||
|
|
||||||
this.nodeRegistry.load();
|
const nodeIds = Array.from(new Set([...graph.nodes.map(n => n.type)]));
|
||||||
|
await this.nodeRegistry.load(nodeIds);
|
||||||
|
|
||||||
for (const node of this.graph.nodes) {
|
for (const node of this.graph.nodes) {
|
||||||
const nodeType = this.nodeRegistry.getNode(node.type);
|
const nodeType = this.nodeRegistry.getNode(node.type);
|
||||||
|
@ -33,7 +33,7 @@ export function grid(width: number, height: number) {
|
|||||||
visible: false,
|
visible: false,
|
||||||
},
|
},
|
||||||
position: [width * 30, (height - 1) * 40],
|
position: [width * 30, (height - 1) * 40],
|
||||||
type: "output",
|
type: "max/plantarium/output",
|
||||||
props: {},
|
props: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ export function tree(depth: number): Graph {
|
|||||||
const nodes: Node[] = [
|
const nodes: Node[] = [
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
type: "output",
|
type: "max/plantarium/output",
|
||||||
position: [0, 0]
|
position: [0, 0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import type { NodeRegistry, NodeType } from "@nodes/types";
|
import type { NodeRegistry, NodeType } from "@nodes/types";
|
||||||
|
|
||||||
import * as d from "plantarium-nodes-math";
|
import * as d from "plantarium-nodes-math";
|
||||||
|
import { createLogger } from "./helpers";
|
||||||
|
|
||||||
const nodeTypes: NodeType[] = [
|
const nodeTypes: NodeType[] = [
|
||||||
{
|
{
|
||||||
@ -9,7 +10,7 @@ const nodeTypes: NodeType[] = [
|
|||||||
"value": { type: "float", value: 0.1, internal: true },
|
"value": { type: "float", value: 0.1, internal: true },
|
||||||
},
|
},
|
||||||
outputs: ["float"],
|
outputs: ["float"],
|
||||||
execute: ({ value }) => { return [0, value] }
|
execute: (value) => { return value; }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "max/plantarium/math",
|
id: "max/plantarium/math",
|
||||||
@ -19,7 +20,7 @@ const nodeTypes: NodeType[] = [
|
|||||||
"b": { type: "float" },
|
"b": { type: "float" },
|
||||||
},
|
},
|
||||||
outputs: ["float"],
|
outputs: ["float"],
|
||||||
execute: ({ op_type, a, b }: { op_type: number, a: number, b: number }) => {
|
execute: (op_type: number, a: number, b: number) => {
|
||||||
switch (op_type) {
|
switch (op_type) {
|
||||||
case 0: return a + b;
|
case 0: return a + b;
|
||||||
case 1: return a - b;
|
case 1: return a - b;
|
||||||
@ -29,7 +30,7 @@ const nodeTypes: NodeType[] = [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "output",
|
id: "max/plantarium/output",
|
||||||
inputs: {
|
inputs: {
|
||||||
"input": { type: "float" },
|
"input": { type: "float" },
|
||||||
},
|
},
|
||||||
@ -37,6 +38,8 @@ const nodeTypes: NodeType[] = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
const log = createLogger("node-registry");
|
||||||
export class RemoteNodeRegistry implements NodeRegistry {
|
export class RemoteNodeRegistry implements NodeRegistry {
|
||||||
|
|
||||||
private nodes: Map<string, NodeType> = new Map();
|
private nodes: Map<string, NodeType> = new Map();
|
||||||
@ -44,13 +47,39 @@ export class RemoteNodeRegistry implements NodeRegistry {
|
|||||||
constructor(private url: string) { }
|
constructor(private url: string) { }
|
||||||
|
|
||||||
async load(nodeIds: string[]) {
|
async load(nodeIds: string[]) {
|
||||||
|
const a = performance.now();
|
||||||
for (const id of nodeIds) {
|
for (const id of nodeIds) {
|
||||||
const response = await fetch(`${this.url}/nodes/${id}`);
|
const nodeUrl = `${this.url}/n/${id}`;
|
||||||
const node = this.getNode(id);
|
const response = await fetch(nodeUrl);
|
||||||
if (node) {
|
const wasmResponse = await fetch(`${nodeUrl}/wasm`);
|
||||||
this.nodes.set(id, node);
|
const wrapperReponse = await fetch(`${nodeUrl}/wrapper`);
|
||||||
|
if (!wrapperReponse.ok) {
|
||||||
|
throw new Error(`Failed to load node ${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let wrapperCode = await wrapperReponse.text();
|
||||||
|
wrapperCode = wrapperCode.replace("wasm = val;", `if(wasm) return;
|
||||||
|
wasm = val;`);
|
||||||
|
const wasmWrapper = await import(/*@vite-ignore*/`data:text/javascript;base64,${btoa(wrapperCode)}`);
|
||||||
|
|
||||||
|
const module = new WebAssembly.Module(await wasmResponse.arrayBuffer());
|
||||||
|
const instance = new WebAssembly.Instance(module, { ["./index_bg.js"]: wasmWrapper });
|
||||||
|
wasmWrapper.__wbg_set_wasm(instance.exports);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
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)
|
||||||
|
};
|
||||||
|
this.nodes.set(id, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const duration = performance.now() - a;
|
||||||
|
|
||||||
|
log.log("loaded nodes in", duration, "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
getNode(id: string) {
|
getNode(id: string) {
|
||||||
|
@ -23,7 +23,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
// First, lets check if all nodes have a type
|
// First, lets check if all nodes have a type
|
||||||
const typeMap = this.getNodeTypes(graph);
|
const typeMap = this.getNodeTypes(graph);
|
||||||
|
|
||||||
const outputNode = graph.nodes.find(node => node.type === "output");
|
const outputNode = graph.nodes.find(node => node.type.endsWith("/output"));
|
||||||
if (!outputNode) {
|
if (!outputNode) {
|
||||||
throw new Error("No output node found");
|
throw new Error("No output node found");
|
||||||
}
|
}
|
||||||
@ -125,13 +125,13 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// execute the node and store the result
|
// execute the node and store the result
|
||||||
results[node.id] = node.tmp.type.execute(inputs) as number;;
|
results[node.id] = node.tmp.type.execute(...Object.values(inputs)) as number;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the result of the parent of the output node
|
// return the result of the parent of the output node
|
||||||
const res = results[outputNode.tmp?.parents?.[0].id as number] as string
|
const res = results[outputNode.id] as string
|
||||||
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
import { GraphManager } from "$lib/graph-manager";
|
import { GraphManager } from "$lib/graph-manager";
|
||||||
import Graph from "$lib/components/graph/Graph.svelte";
|
import Graph from "$lib/components/graph/Graph.svelte";
|
||||||
import { MemoryRuntimeExecutor } from "$lib/runtime-executor";
|
import { MemoryRuntimeExecutor } from "$lib/runtime-executor";
|
||||||
import { MemoryNodeRegistry } from "$lib/node-registry";
|
import { MemoryNodeRegistry, RemoteNodeRegistry } from "$lib/node-registry";
|
||||||
import { LinearSRGBColorSpace } from "three";
|
import { LinearSRGBColorSpace } from "three";
|
||||||
import Details from "$lib/components/Details.svelte";
|
import Details from "$lib/components/Details.svelte";
|
||||||
import { JsonView } from "@zerodevx/svelte-json-view";
|
import { JsonView } from "@zerodevx/svelte-json-view";
|
||||||
|
|
||||||
const nodeRegistry = new MemoryNodeRegistry();
|
const memNodeRegistry = new MemoryNodeRegistry();
|
||||||
|
const nodeRegistry = new RemoteNodeRegistry("http://localhost:5174");
|
||||||
|
|
||||||
const runtimeExecutor = new MemoryRuntimeExecutor(nodeRegistry);
|
const runtimeExecutor = new MemoryRuntimeExecutor(nodeRegistry);
|
||||||
|
|
||||||
const graphManager = new GraphManager(nodeRegistry, runtimeExecutor);
|
const graphManager = new GraphManager(nodeRegistry, runtimeExecutor);
|
||||||
|
6
nodes/max/plantarium/input-float/.gitignore
vendored
Normal file
6
nodes/max/plantarium/input-float/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
||||||
|
bin/
|
||||||
|
pkg/
|
||||||
|
wasm-pack.log
|
30
nodes/max/plantarium/input-float/Cargo.toml
Normal file
30
nodes/max/plantarium/input-float/Cargo.toml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
[package]
|
||||||
|
name = "input-float"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Max Richter <jim-x@web.de>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["console_error_panic_hook"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wasm-bindgen = "0.2.84"
|
||||||
|
|
||||||
|
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||||
|
# logging them with `console.error`. This is great for development, but requires
|
||||||
|
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
||||||
|
# code size when deploying.
|
||||||
|
plantarium = { version = "0.1.0", path = "../../../../packages/plantarium" }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde-wasm-bindgen = "0.4"
|
||||||
|
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen-test = "0.3.34"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
# Tell `rustc` to optimize for small code size.
|
||||||
|
opt-level = "s"
|
5
nodes/max/plantarium/input-float/package.json
Normal file
5
nodes/max/plantarium/input-float/package.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"build": "wasm-pack build --release --out-name index --no-default-features"
|
||||||
|
}
|
||||||
|
}
|
29
nodes/max/plantarium/input-float/src/lib.rs
Normal file
29
nodes/max/plantarium/input-float/src/lib.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
mod utils;
|
||||||
|
use plantarium::unwrap_float;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn get_outputs() -> Vec<String> {
|
||||||
|
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();
|
||||||
|
r#"{
|
||||||
|
"value": { "type": "float", "value": 0.1, "internal": true }
|
||||||
|
}"#
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn execute(var_value: JsValue) -> f64 {
|
||||||
|
utils::set_panic_hook();
|
||||||
|
|
||||||
|
return unwrap_float(var_value);
|
||||||
|
}
|
10
nodes/max/plantarium/input-float/src/utils.rs
Normal file
10
nodes/max/plantarium/input-float/src/utils.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
pub fn set_panic_hook() {
|
||||||
|
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||||
|
// `set_panic_hook` function at least once during initialization, and then
|
||||||
|
// we will get better error messages if our code ever panics.
|
||||||
|
//
|
||||||
|
// For more details see
|
||||||
|
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||||
|
#[cfg(feature = "console_error_panic_hook")]
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
}
|
13
nodes/max/plantarium/input-float/tests/web.rs
Normal file
13
nodes/max/plantarium/input-float/tests/web.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//! Test suite for the Web and headless browsers.
|
||||||
|
|
||||||
|
#![cfg(target_arch = "wasm32")]
|
||||||
|
|
||||||
|
extern crate wasm_bindgen_test;
|
||||||
|
use wasm_bindgen_test::*;
|
||||||
|
|
||||||
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn pass() {
|
||||||
|
assert_eq!(1 + 1, 2);
|
||||||
|
}
|
@ -24,13 +24,28 @@ pub fn get_input_types() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn execute(var_op_type: u8, var_a: String, var_b: String) -> String {
|
pub fn execute(var_op_type: u8, var_a: JsValue, var_b: JsValue) -> String {
|
||||||
utils::set_panic_hook();
|
utils::set_panic_hook();
|
||||||
|
|
||||||
|
let a: String;
|
||||||
|
let b: String;
|
||||||
|
|
||||||
|
if var_a.is_string() {
|
||||||
|
a = unwrap_string(var_a);
|
||||||
|
} else {
|
||||||
|
a = unwrap_float(var_a).to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
if var_b.is_string() {
|
||||||
|
b = unwrap_string(var_b);
|
||||||
|
} else {
|
||||||
|
b = unwrap_float(var_b).to_string();
|
||||||
|
}
|
||||||
|
|
||||||
// Interpolate strings into JSON format
|
// Interpolate strings into JSON format
|
||||||
let json_string = format!(
|
let json_string = format!(
|
||||||
r#"{{"parameter": "math", "op_type": {}, "a": {}, "b": {}}}"#,
|
r#"{{"parameter": "math", "op_type": {}, "a": {}, "b": {}}}"#,
|
||||||
var_op_type, var_a, var_b
|
var_op_type, a, b
|
||||||
);
|
);
|
||||||
|
|
||||||
json_string
|
json_string
|
||||||
|
6
nodes/max/plantarium/output/.gitignore
vendored
Normal file
6
nodes/max/plantarium/output/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
||||||
|
bin/
|
||||||
|
pkg/
|
||||||
|
wasm-pack.log
|
30
nodes/max/plantarium/output/Cargo.toml
Normal file
30
nodes/max/plantarium/output/Cargo.toml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
[package]
|
||||||
|
name = "output"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Max Richter <jim-x@web.de>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["console_error_panic_hook"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wasm-bindgen = "0.2.84"
|
||||||
|
|
||||||
|
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||||
|
# logging them with `console.error`. This is great for development, but requires
|
||||||
|
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
||||||
|
# code size when deploying.
|
||||||
|
plantarium = { version = "0.1.0", path = "../../../../packages/plantarium" }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde-wasm-bindgen = "0.4"
|
||||||
|
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen-test = "0.3.34"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
# Tell `rustc` to optimize for small code size.
|
||||||
|
opt-level = "s"
|
5
nodes/max/plantarium/output/package.json
Normal file
5
nodes/max/plantarium/output/package.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"build": "wasm-pack build --release --out-name index --no-default-features"
|
||||||
|
}
|
||||||
|
}
|
40
nodes/max/plantarium/output/src/lib.rs
Normal file
40
nodes/max/plantarium/output/src/lib.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
mod utils;
|
||||||
|
use plantarium::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<String> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn get_id() -> String {
|
||||||
|
"float".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn get_input_types() -> String {
|
||||||
|
utils::set_panic_hook();
|
||||||
|
r#"{
|
||||||
|
"input": { "type": "float", "value": 0.0, "external": true }
|
||||||
|
}"#
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn execute(var_value: JsValue) -> String {
|
||||||
|
utils::set_panic_hook();
|
||||||
|
|
||||||
|
let str = unwrap_string(var_value);
|
||||||
|
|
||||||
|
log(&format!("str: {}", str));
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
10
nodes/max/plantarium/output/src/utils.rs
Normal file
10
nodes/max/plantarium/output/src/utils.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
pub fn set_panic_hook() {
|
||||||
|
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||||
|
// `set_panic_hook` function at least once during initialization, and then
|
||||||
|
// we will get better error messages if our code ever panics.
|
||||||
|
//
|
||||||
|
// For more details see
|
||||||
|
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||||
|
#[cfg(feature = "console_error_panic_hook")]
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
}
|
13
nodes/max/plantarium/output/tests/web.rs
Normal file
13
nodes/max/plantarium/output/tests/web.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//! Test suite for the Web and headless browsers.
|
||||||
|
|
||||||
|
#![cfg(target_arch = "wasm32")]
|
||||||
|
|
||||||
|
extern crate wasm_bindgen_test;
|
||||||
|
use wasm_bindgen_test::*;
|
||||||
|
|
||||||
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn pass() {
|
||||||
|
assert_eq!(1 + 1, 2);
|
||||||
|
}
|
@ -17,5 +17,5 @@
|
|||||||
{:else if input.type === "boolean"}
|
{:else if input.type === "boolean"}
|
||||||
<Checkbox bind:value />
|
<Checkbox bind:value />
|
||||||
{:else if input.type === "select"}
|
{:else if input.type === "select"}
|
||||||
<Select labels={input.labels} bind:value />
|
<Select bind:value labels={input.labels} />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -7,3 +7,13 @@
|
|||||||
|
|
||||||
<input type="number" bind:value {min} {max} {step} />
|
<input type="number" bind:value {min} {max} {step} />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
background: var(--background-color-lighter);
|
||||||
|
color: var(--text-color);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
padding: 0.8em 1em;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,16 +1,25 @@
|
|||||||
export async function getNodeWrapper(id: `${string}/${string}/${string}`) {
|
export async function getNodeWrapper(id: `${string}/${string}/${string}`) {
|
||||||
|
|
||||||
let wrapperCode = await (await fetch(`/${id}/wrapper`)).text();
|
const wrapperReponse = await fetch(`/n/${id}/wrapper`);
|
||||||
|
if (!wrapperReponse.ok) {
|
||||||
|
throw new Error(`Failed to load node ${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let wrapperCode = await wrapperReponse.text();
|
||||||
wrapperCode = wrapperCode.replace("wasm = val;", `if(wasm) return;
|
wrapperCode = wrapperCode.replace("wasm = val;", `if(wasm) return;
|
||||||
wasm = val;`);
|
wasm = val;`);
|
||||||
const wasmWrapper = await import(/*vite-ignore*/`data:text/javascript;base64,${btoa(wrapperCode)}`);
|
const wasmWrapper = await import(/*@vite-ignore*/`data:text/javascript;base64,${btoa(wrapperCode)}`);
|
||||||
|
|
||||||
return wasmWrapper;
|
return wasmWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNodeWasm(id: `${string}/${string}/${string}`): Promise<WebAssembly.Instance> {
|
export async function getNodeWasm(id: `${string}/${string}/${string}`): Promise<WebAssembly.Instance> {
|
||||||
|
|
||||||
const wasmResponse = await fetch(`/${id}/wasm`);
|
const wasmResponse = await fetch(`/n/${id}/wasm`);
|
||||||
|
|
||||||
|
if (!wasmResponse.ok) {
|
||||||
|
throw new Error(`Failed to load node ${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
const wasmWrapper = await getNodeWrapper(id);
|
const wasmWrapper = await getNodeWrapper(id);
|
||||||
|
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import { json } from "@sveltejs/kit";
|
|
||||||
import type { RequestHandler } from "./$types";
|
|
||||||
|
|
||||||
export const GET: RequestHandler = async function GET({ fetch, params }) {
|
|
||||||
const wasmResponse = await fetch(`/${params.user}/${params.collection}/${params.node}/wasm`);
|
|
||||||
|
|
||||||
let wrapperCode = await (await fetch(`/${params.user}/${params.collection}/${params.node}/wrapper`)).text();
|
|
||||||
wrapperCode = wrapperCode.replace("wasm = val;", `if(wasm) return;
|
|
||||||
wasm = val;`);
|
|
||||||
const wasmWrapper = await import(`data:text/javascript;base64,${btoa(wrapperCode)}`);
|
|
||||||
|
|
||||||
const module = new WebAssembly.Module(await wasmResponse.arrayBuffer());
|
|
||||||
const instance = new WebAssembly.Instance(module, { ["./index_bg.js"]: wasmWrapper });
|
|
||||||
wasmWrapper.__wbg_set_wasm(instance.exports);
|
|
||||||
const id = wasmWrapper.get_id();
|
|
||||||
const outputs = wasmWrapper.get_outputs();
|
|
||||||
const inputTypes = JSON.parse(wasmWrapper.get_input_types());
|
|
||||||
return json({ id, outputs, inputs: inputTypes, });
|
|
||||||
}
|
|
@ -0,0 +1,17 @@
|
|||||||
|
import { json } from "@sveltejs/kit";
|
||||||
|
import type { RequestHandler } from "./$types";
|
||||||
|
import { getNode } from "$lib/registry";
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async function GET({ fetch, params }) {
|
||||||
|
globalThis.fetch = fetch;
|
||||||
|
|
||||||
|
const nodeId = `${params.user}/${params.collection}/${params.node}` as const;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const node = await getNode(nodeId);
|
||||||
|
return json(node);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return new Response("Not found", { status: 404 });
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,12 @@ export const GET: RequestHandler = async function GET({ fetch, params }) {
|
|||||||
|
|
||||||
const filePath = path.resolve(`../../nodes/${params.user}/${params.collection}/${params.node}/pkg/index_bg.wasm`);
|
const filePath = path.resolve(`../../nodes/${params.user}/${params.collection}/${params.node}/pkg/index_bg.wasm`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.access(filePath);
|
||||||
|
} catch (e) {
|
||||||
|
return new Response("Not found", { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
const file = await fs.readFile(filePath);
|
const file = await fs.readFile(filePath);
|
||||||
|
|
||||||
const bytes = new Uint8Array(file);
|
const bytes = new Uint8Array(file);
|
@ -6,6 +6,13 @@ export const GET: RequestHandler = async function GET({ params }) {
|
|||||||
|
|
||||||
const filePath = path.resolve(`../../nodes/${params.user}/${params.collection}/${params.node}/pkg/index_bg.js`);
|
const filePath = path.resolve(`../../nodes/${params.user}/${params.collection}/${params.node}/pkg/index_bg.js`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.access(filePath);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Not Found", filePath);
|
||||||
|
return new Response("Not found", { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
const file = await fs.readFile(filePath);
|
const file = await fs.readFile(filePath);
|
||||||
|
|
||||||
return new Response(file, { status: 200, headers: { "Content-Type": "text/javascript" } });
|
return new Response(file, { status: 200, headers: { "Content-Type": "text/javascript" } });
|
@ -21,9 +21,6 @@ pub fn unwrap_string(val: JsValue) -> String {
|
|||||||
return val.as_string().unwrap();
|
return val.as_string().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate_parameter(val: JsValue) -> String {
|
pub fn evaluate_parameter(_val: String) -> i32 {
|
||||||
if val.is_undefined() || val.is_null() {
|
return 2;
|
||||||
panic!("Value is undefined");
|
|
||||||
}
|
|
||||||
return val.as_string().unwrap();
|
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ export type NodeType = {
|
|||||||
meta?: {
|
meta?: {
|
||||||
title?: string;
|
title?: string;
|
||||||
},
|
},
|
||||||
execute?: (inputs: Record<string, string | number | boolean>) => unknown;
|
execute?: (...args: (string | number | boolean)[]) => unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Socket = {
|
export type Socket = {
|
||||||
|
@ -26,6 +26,7 @@ type NodeInputSelect = {
|
|||||||
|
|
||||||
type DefaultOptions = {
|
type DefaultOptions = {
|
||||||
internal?: boolean;
|
internal?: boolean;
|
||||||
|
external?: boolean;
|
||||||
title?: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user