use std::cell::RefCell;
use crate::prelude::*;
pub struct Inlet {
name: String,
source_connections: Vec<Box<dyn SourceConnection>>,
default_value: CapsulePtr,
buffer: RefCell<Option<CapsulePtr>>,
}
impl std::fmt::Debug for Inlet {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Inlet").field("name", &self.name).field("default_value", &self.default_value).field("buffer", &self.buffer).finish()
}
}
impl Inlet {
pub fn new(name: &str, default_value: Value) -> Inlet {
Inlet{
name: name.to_owned(),
default_value: default_value.into(),
source_connections: Vec::new(),
buffer: RefCell::new(None),
}
}
pub fn name(&self) -> &String {
&self.name
}
pub fn source_connections(&self) -> &Vec<Box<dyn SourceConnection>> {
return &self.source_connections
}
#[allow(unused)]
pub fn profile_full(&self) -> JuizResult<Value> {
Ok(jvalue!({
"name": self.name,
"source_connections": self.source_connections.iter().map(|sc| -> Value {
sc.profile().into()
}).collect::<Vec<Value>>()
}).into())
}
pub fn is_updated(&self) -> JuizResult<bool> {
for sc in self.source_connections.iter() {
if sc.is_source_updated()? {
return Ok(true);
}
}
Ok(false)
}
pub fn collect_value(&self) -> CapsulePtr {
log::trace!("Inlet({})::collect_value() called", self.name());
for sc in self.source_connections.iter() {
if sc.connection_type() == ConnectionType::Pull {
match sc.pull() {
Err(e) => {
log::error!("Pull data via Connection({}) in Inlet({})::collect_value() failed. Error: {:}", sc.identifier(), self.name(), e);
},
Ok(output) => {
self.buffer.replace(Some(output.clone()));
}
}
}
}
if self.buffer.borrow().is_none() {
self.default_value.clone()
} else {
self.buffer.borrow().clone().unwrap()
}
}
pub(crate) fn insert(&mut self, con: Box<dyn SourceConnection + 'static>) {
self.source_connections.push(con);
}
pub fn bind(&mut self, value: CapsulePtr) -> JuizResult<CapsulePtr> {
if self.buffer.borrow().is_none() {
self.buffer.replace(Some(value.clone()));
}
Ok(value)
}
}