use std::collections::{HashMap, VecDeque};
use std::sync::Arc;
use crate::context::global::Global;
use crate::component::{Id, Type};
use crate::error::{FlowError, Result};
use crate::package::Package;
use crate::ports::PortId;
use crate::prelude::Component;
pub struct Ctx<G: Send + Sync> {
pub(crate) id: Id,
pub(crate) ty: Type,
pub(crate) send: HashMap<PortId, VecDeque<Package>>,
pub(crate) receive: HashMap<PortId, VecDeque<Package>>,
pub(crate) consumed: bool,
global: Arc<Global<G>>,
}
impl<G> Ctx<G>
where G: Send + Sync + 'static
{
pub(crate) fn from(component: &Component<G>, global: &Arc<Global<G>>) -> Self {
let send = HashMap::from_iter(
component.data.outputs().0.iter().map(|port| (port.port, VecDeque::new()))
);
let receive = HashMap::from_iter(
component.data.inputs().0.iter().map(|port| (port.port, VecDeque::new()))
);
Self {
id: component.id,
ty: component.ty,
send,
receive,
consumed: false,
global: global.clone(),
}
}
pub fn receive(&mut self, in_port: PortId) -> Option<Package> {
let package = self.receive.get_mut(&in_port)
.ok_or(FlowError::QueueNotCreated {
component: self.id, port: in_port
})
.unwrap()
.pop_front();
self.consumed = true;
package
}
pub fn send(&mut self, out_port: PortId, package: Package) {
self.send.get_mut(&out_port)
.ok_or(FlowError::QueueNotCreated {
component: self.id, port: out_port
})
.unwrap()
.push_front(package);
}
pub fn with_global<R>(&self, call: impl FnOnce(&G) -> R) -> Result<R> {
self.global.with_global(call)
}
pub fn with_mut_global<R>(&self, call: impl FnOnce(&mut G) -> R) -> Result<R> {
self.global.with_mut_global(call)
}
}