aboutsummaryrefslogtreecommitdiffstats
path: root/src/node.rs
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2026-01-17 12:34:26 +0000
committers-ol <s+removethis@s-ol.nu>2026-01-17 12:34:26 +0000
commit87fecd4c87a3b4f33c795beead1b8f9f19fd7e47 (patch)
tree2ce0f0f107ced3547a8e1ebecdd2bab3e82b0518 /src/node.rs
parentVector combine (diff)
downloadnodetoy-87fecd4c87a3b4f33c795beead1b8f9f19fd7e47.tar.gz
nodetoy-87fecd4c87a3b4f33c795beead1b8f9f19fd7e47.zip
split main into smaller modules
Diffstat (limited to 'src/node.rs')
-rw-r--r--src/node.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/node.rs b/src/node.rs
new file mode 100644
index 0000000..859799b
--- /dev/null
+++ b/src/node.rs
@@ -0,0 +1,75 @@
+use enum_dispatch::enum_dispatch;
+use std::fmt;
+
+use crate::library;
+use crate::library::*;
+use crate::types::{Type, TypeSignature};
+
+/// an instantiable Node, parametrized by its connected input types
+#[enum_dispatch]
+pub trait ConcreteNode {
+ fn max_inputs(&self) -> usize;
+
+ // set of possible input type combinations given current connections
+ fn signatures_matching(&self, connected: &[Option<Type>]) -> Vec<TypeSignature>;
+
+ fn signature(&self, connected: &[Option<Type>]) -> TypeSignature;
+
+ fn compile(
+ &self,
+ signature: TypeSignature,
+ inputs: Vec<String>,
+ outputs: Vec<String>,
+ f: &mut dyn fmt::Write,
+ ) -> fmt::Result;
+
+ fn show_body(&mut self, ui: &mut egui::Ui) -> egui::Response {
+ ui.response()
+ }
+}
+
+#[enum_dispatch(ConcreteNode)]
+#[derive(Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub enum AnyNode {
+ Constant(library::AnyConstant),
+ Conversion(library::Conversion),
+ Input(library::Input),
+ Builtin(library::BuiltinFunction),
+ Output(library::Output),
+}
+
+impl NodeIndex for AnyNode {
+ const TITLE: &'static str = "";
+
+ fn all() -> impl Iterator<Item = Self> {
+ (library::AnyConstant::all().map(AnyNode::from))
+ .chain(library::Conversion::all().map(AnyNode::from))
+ .chain(library::Input::all().map(AnyNode::from))
+ .chain(library::Output::all().map(AnyNode::from))
+ .chain(library::BuiltinFunction::all().map(AnyNode::from))
+ }
+
+ fn pick_node(ui: &mut egui::Ui) -> Option<Self> {
+ ui.label("Add node");
+
+ let a = library::AnyConstant::pick_node(ui).map(AnyNode::from);
+ let b = library::Conversion::pick_node(ui).map(AnyNode::from);
+ let c = library::Input::pick_node(ui).map(AnyNode::from);
+ let d = library::Output::pick_node(ui).map(AnyNode::from);
+ let e = library::BuiltinFunction::pick_node(ui).map(AnyNode::from);
+
+ a.or(b).or(c).or(d).or(e)
+ }
+}
+
+impl fmt::Display for AnyNode {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::Constant(x) => fmt::Display::fmt(x, f),
+ Self::Conversion(x) => fmt::Display::fmt(x, f),
+ Self::Input(x) => fmt::Display::fmt(x, f),
+ Self::Builtin(x) => fmt::Display::fmt(x, f),
+ Self::Output(x) => fmt::Display::fmt(x, f),
+ }
+ }
+}