#[doc(inline)]
pub use crate::visit::{self, Visitor};
#[doc(inline)]
pub use conns::Conns;
pub use expr::{Expr, ExprError};
pub use graph::GraphNode;
pub use pull::{Pull, WithPullEval};
pub use push::{Push, WithPushEval};
use serde::{Deserialize, Serialize};
pub use state::{NodeState, State, WithStateType};
use steel::{parser::ast::ExprKind, steel_vm::engine::Engine};
mod conns;
pub mod expr;
pub mod graph;
pub mod pull;
pub mod push;
pub mod state;
pub trait Node {
fn n_inputs(&self) -> usize {
0
}
fn n_outputs(&self) -> usize {
0
}
fn branches(&self) -> Vec<EvalConf> {
vec![]
}
fn expr(&self, ctx: ExprCtx) -> ExprKind;
fn push_eval(&self) -> Vec<EvalConf> {
vec![]
}
fn pull_eval(&self) -> Vec<EvalConf> {
vec![]
}
fn inlet(&self) -> bool {
false
}
fn outlet(&self) -> bool {
false
}
fn stateful(&self) -> bool {
false
}
fn register(&self, _path: &[Id], _vm: &mut Engine) {}
fn visit(&self, _ctx: visit::Ctx, _visitor: &mut dyn Visitor) {}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub enum EvalConf {
#[default]
All,
Set(Conns),
}
pub type Id = usize;
pub struct ExprCtx<'a> {
path: &'a [Id],
inputs: &'a [Option<String>],
outputs: &'a [bool],
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct EvalFn;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Input(pub u16);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Output(pub u16);
impl<'a> ExprCtx<'a> {
pub(crate) fn new(path: &'a [Id], inputs: &'a [Option<String>], outputs: &'a [bool]) -> Self {
Self {
path,
inputs,
outputs,
}
}
pub fn path(&self) -> &[Id] {
self.path
}
pub fn inputs(&self) -> &[Option<String>] {
self.inputs
}
pub fn outputs(&self) -> &[bool] {
self.outputs
}
}
impl<'a, N> Node for &'a N
where
N: ?Sized + Node,
{
fn n_inputs(&self) -> usize {
(**self).n_inputs()
}
fn n_outputs(&self) -> usize {
(**self).n_outputs()
}
fn branches(&self) -> Vec<EvalConf> {
(**self).branches()
}
fn expr(&self, ctx: ExprCtx) -> ExprKind {
(**self).expr(ctx)
}
fn push_eval(&self) -> Vec<EvalConf> {
(**self).push_eval()
}
fn pull_eval(&self) -> Vec<EvalConf> {
(**self).pull_eval()
}
fn inlet(&self) -> bool {
(**self).inlet()
}
fn outlet(&self) -> bool {
(**self).outlet()
}
fn stateful(&self) -> bool {
(**self).stateful()
}
fn register(&self, path: &[Id], vm: &mut Engine) {
(**self).register(path, vm)
}
fn visit(&self, ctx: visit::Ctx, visitor: &mut dyn Visitor) {
(**self).visit(ctx, visitor)
}
}
macro_rules! impl_node_for_ptr {
($($Ty:ident)::*) => {
impl<T> Node for $($Ty)::*<T>
where
T: ?Sized + Node,
{
fn n_inputs(&self) -> usize {
(**self).n_inputs()
}
fn n_outputs(&self) -> usize {
(**self).n_outputs()
}
fn branches(&self) -> Vec<EvalConf> {
(**self).branches()
}
fn expr(&self, ctx: ExprCtx) -> ExprKind {
(**self).expr(ctx)
}
fn push_eval(&self) -> Vec<EvalConf> {
(**self).push_eval()
}
fn pull_eval(&self) -> Vec<EvalConf> {
(**self).pull_eval()
}
fn inlet(&self) -> bool {
(**self).inlet()
}
fn outlet(&self) -> bool {
(**self).outlet()
}
fn stateful(&self) -> bool {
(**self).stateful()
}
fn register(&self, path: &[Id], vm: &mut Engine) {
(**self).register(path, vm)
}
fn visit(&self, ctx: visit::Ctx, visitor: &mut dyn Visitor) {
(**self).visit(ctx, visitor)
}
}
};
}
impl_node_for_ptr!(Box);
impl_node_for_ptr!(std::rc::Rc);
impl_node_for_ptr!(std::sync::Arc);
impl From<u16> for Input {
fn from(u: u16) -> Self {
Input(u)
}
}
impl From<u16> for Output {
fn from(u: u16) -> Self {
Output(u)
}
}
pub fn expr(expr: impl Into<String>) -> Result<Expr, ExprError> {
Expr::new(expr)
}
pub fn visit(ctx: visit::Ctx, node: &dyn Node, visitor: &mut dyn Visitor) {
visitor.visit_pre(ctx, node);
node.visit(ctx, visitor);
visitor.visit_post(ctx, node);
}
pub fn register(ctx: visit::Ctx, node: &dyn Node, vm: &mut Engine) {
visit(ctx, node, &mut visit::Register(vm));
}