dager 0.1.1

Crate to create and execute a graph of nodes.
Documentation
//! Builds a graph and executes it over and over.
//! However, between executions the a printer is put between the calc and the send back, by changing the wirering.
use std::marker::PhantomData;
use std::sync::Arc;
use std::sync::RwLock;

use dager::edge::Edge;
use dager::executor::Executor;
use dager::node::AbstAggregator;
use dager::node::Node;
use dager::node::arc_node;


fn recursion(adder: f32, stage: i32) -> f32{
    if stage <= 0{
	return 1.0;
    }
    adder + recursion(adder, stage - 1) + recursion(adder, stage - 2)
}

struct Calculator;
impl Node for Calculator{
    type InSig = (f32, i32);
    type OutSig = [f32; 1];
    fn process(&mut self, input: Self::InSig) -> Self::OutSig {
	println!("Recursing {} for {}", input.0, input.1);
	[recursion(input.0, input.1)]	
    }
}

struct Add<T>{
    ty: PhantomData<T>
}

impl<A> Add<A>{
    fn new() -> Self{
	Add{
	    ty: PhantomData
	}
    }
}

impl<T> Node for Add<T> where T: std::ops::Add<Output = T>{
    type InSig = (T, T);
    type OutSig = [T;1];
    fn process(&mut self, input: Self::InSig) -> Self::OutSig {
	[input.0 + input.1]
    }
}

struct SendBack{
    sender: Arc<RwLock<Option<f32>>>,
}

impl Node for SendBack{
    type InSig = [f32;1];
    type OutSig = ();

    fn process(&mut self, input: Self::InSig) -> Self::OutSig {
	let [a] = input;
	*self.sender.write().unwrap() = Some(a);
	
    }
}

struct Print;
impl Node for Print{
    type InSig = [f32; 1];
    type OutSig = [f32; 1];
    fn process(&mut self, input: Self::InSig) -> Self::OutSig {
	let [a] = input;
	println!("PRINTER: got: {}", a);
	[a]
    }
}

//GRAPH (executed in a loop)
// Case 1
//______
//  val---|Add1|-\
//        |    |  \
//  5.0---|____|   \   ________    ____________
//                  \--| Calc |----| SendBack |
//                 ____|      |    |__________|
//        ______  /    |______|
//  25----|Add2|-/
//        |    |
//  15----|____|
//
// Case 2
//______
//  val---|Add1|-\
//        |    |  \
//  5.0---|____|   \   ________    _______       ____________
//                  \--| Calc |---| print |------| SendBack |
//                 ____|      |   |_______|      |__________|
//        ______  /    |______|
//  25----|Add2|-/
//        |    |
//  15----|____|
//
pub fn main(){
    let ex = Executor::new();
    
    let add1 = arc_node(Add::<f32>::new());
    let add2 = arc_node(Add::<i32>::new());

    let calc = arc_node(Calculator);

    let printer = arc_node(Print);

    let shared = Arc::new(RwLock::new(None));
    let sender = arc_node(SendBack{sender: shared.clone()});

    Edge::connect(add1.clone(), 0, calc.clone(), 0).expect("Failed add1");
    Edge::connect(add2.clone(), 0, calc.clone(), 1).expect("Failed add2");
    Edge::connect(calc.clone(), 0, sender.clone(), 0).expect("Failed calc");

    let mut counter = 1.0 as f32;
    let mut wireing_step = 0;
    loop{

	//reqire graph
	match wireing_step{
	    0 => {
		//Change to contain the printer
		//This should also remove the edge from the send back
		calc.lock().unwrap().remove_out_edge(0).expect("Failed to remove calc out edge");

		Edge::connect(calc.clone(), 0, printer.clone(), 0).expect("Failed to connect calc to printer");
		Edge::connect(printer.clone(), 0, sender.clone(), 0).expect("Failed to connect calc to printer");
		
		wireing_step = 1;
	    },
	    1 => {
		//Exclude printer
		calc.lock().unwrap().remove_out_edge(0).expect("Failed to disconnect calc and printer");
		printer.lock().unwrap().remove_out_edge(0).expect("Failed to disconnect printer and sender");

		//Reconnect calc and sender
		Edge::connect(calc.clone(), 0, sender.clone(), 0).expect("Failed to reconnect calc and sender");
		

		wireing_step = 0
	    },
	    _ => panic!("Wiring step missmatch"),
	}
	
	
	counter += 1.0;
	let val = counter.sin() * 10.0;
	
	println!("Start graph");
	add1.lock().unwrap().set_in_from_edge(ex.clone(), 0, Box::new(val as f32)).expect("Failed to set add1 0");
	add1.lock().unwrap().set_in_from_edge(ex.clone(), 1, Box::new(5.0 as f32)).expect("Failed to set add1 1");

	add2.lock().unwrap().set_in_from_edge(ex.clone(), 0, Box::new(25 as i32)).expect("Failed to set add2 0");
	add2.lock().unwrap().set_in_from_edge(ex.clone(), 1, Box::new(15 as i32)).expect("Failed to set add2 1");

	println!("Wait");
	//Now wait until the value becomes some
	while shared.read().unwrap().is_none(){
	    std::thread::yield_now();
	}

	println!("Value was: {}\n", shared.write().unwrap().take().unwrap());
    }
}