use std::fmt;
use std::any::Any;
use std::ops::{ Deref, DerefMut };
use portable_intertrait::CastFrom;
use crate::structs::{ node_base::NodeBase, node_tree_base::{ ProcessMode, TerminationReason } };
use super::registered::Registered;
use super::instanceable::Instanceable;
pub trait NodeAbstract: Deref<Target = NodeBase> + DerefMut + Any + fmt::Debug {
fn base(&self) -> &NodeBase;
fn base_mut(&mut self) -> &mut NodeBase;
fn as_dyn(&self) -> &dyn Node;
fn as_dyn_mut(&mut self) -> &mut dyn Node;
fn as_dyn_raw(&self) -> *const dyn Node;
fn as_dyn_raw_mut(&mut self) -> *mut dyn Node;
fn to_dyn_box(self) -> Box<dyn Node>;
fn as_any_ref(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
fn clone_as_instance(&self) -> Box<dyn Node>;
fn name_as_type(&self) -> String;
}
pub trait Node: NodeAbstract + Registered + CastFrom {
fn loaded(&mut self) {}
fn ready(&mut self) {}
fn process(&mut self, _delta: f32) {}
fn terminal(&mut self, _reason: TerminationReason) {}
fn process_mode(&self) -> ProcessMode {
ProcessMode::Inherit
}
}
impl <N: Node> Instanceable for N {
fn iterate<F: FnMut(Option<*mut dyn Node>, *mut dyn Node, bool)>(self, mut iterator: F) {
iterator(None, Box::into_raw(self.to_dyn_box()), false);
}
}