use std::cell::RefCell;
use std::sync::Arc;
use crate::boundary::BindingBoundary;
use crate::handle::NodeId;
use crate::node::{Core, Sink, SubscriptionId};
use crate::topology::{TopologySink, TopologySubscriptionId};
pub struct OwnedCore {
core: Core,
subs: RefCell<Vec<(NodeId, SubscriptionId)>>,
topo_subs: RefCell<Vec<TopologySubscriptionId>>,
}
impl OwnedCore {
#[must_use]
pub fn new(binding: Arc<dyn BindingBoundary>) -> Self {
Self::with_core(Core::new(binding))
}
#[must_use]
pub fn with_core(core: Core) -> Self {
Self {
core,
subs: RefCell::new(Vec::new()),
topo_subs: RefCell::new(Vec::new()),
}
}
#[must_use]
#[inline]
pub fn core(&self) -> &Core {
&self.core
}
#[must_use]
#[inline]
pub fn binding(&self) -> Arc<dyn BindingBoundary> {
self.core.binding()
}
pub fn track_subscribe(&self, node_id: NodeId, sink: Sink) -> SubscriptionId {
let sub_id = self.core.subscribe(node_id, sink);
self.subs.borrow_mut().push((node_id, sub_id));
sub_id
}
pub fn track_subscribe_topology(&self, sink: TopologySink) -> TopologySubscriptionId {
let id = self.core.subscribe_topology(sink);
self.topo_subs.borrow_mut().push(id);
id
}
pub fn unsubscribe(&self, node_id: NodeId, sub_id: SubscriptionId) {
self.subs
.borrow_mut()
.retain(|&(n, s)| !(n == node_id && s == sub_id));
self.core.unsubscribe(node_id, sub_id);
}
pub fn unsubscribe_topology(&self, id: TopologySubscriptionId) {
self.topo_subs.borrow_mut().retain(|&i| i != id);
self.core.unsubscribe_topology(id);
}
}
impl Drop for OwnedCore {
fn drop(&mut self) {
while let Some(id) = pop(&self.topo_subs) {
self.core.unsubscribe_topology(id);
}
while let Some((node_id, sub_id)) = pop(&self.subs) {
self.core.unsubscribe(node_id, sub_id);
}
}
}
#[inline]
fn pop<T>(c: &RefCell<Vec<T>>) -> Option<T> {
c.borrow_mut().pop()
}