standing_relations/core/
output.rs

1use std::{
2    cell::{Ref, RefCell},
3    collections::HashMap,
4};
5
6use super::{
7    dirty::DirtyReceive, relation::RelationInner, ContextTracker, CountMap, CreationContext,
8    ExecutionContext, Op, Relation, TrackingIndex,
9};
10
11impl<C: Op> Relation<C> {
12    pub fn into_output_<M: CountMap<C::D>>(self, context: &CreationContext) -> Output<C::D, C, M> {
13        assert_eq!(&self.context_tracker, context.tracker(), "Context mismatch");
14        Output {
15            context_tracker: self.context_tracker,
16            tracking_index: self.tracking_index,
17            dirty: RefCell::new(self.dirty.into_receive()),
18            inner: RefCell::new(self.inner),
19            data: RefCell::new(M::empty()),
20        }
21    }
22}
23
24pub struct Output<D, C: Op<D = D>, M: CountMap<D> = HashMap<D, isize>> {
25    context_tracker: ContextTracker,
26    tracking_index: TrackingIndex,
27    dirty: RefCell<DirtyReceive>,
28    inner: RefCell<RelationInner<C>>,
29    data: RefCell<M>,
30}
31
32impl<C: Op, M: CountMap<C::D>> Output<C::D, C, M> {
33    pub fn get<'a>(&'a self, context: &'a ExecutionContext<'_>) -> Ref<'a, M> {
34        assert_eq!(&self.context_tracker, context.tracker(), "Context mismatch");
35        if self.dirty.borrow_mut().take_status() {
36            let mut m = self.data.borrow_mut();
37            self.inner.borrow_mut().foreach(|(k, v)| {
38                m.add(k, v);
39            })
40        }
41        self.data.borrow()
42    }
43    pub fn add_listener(&mut self, context: &CreationContext<'_>, f: impl FnMut() + 'static) {
44        assert_eq!(&self.context_tracker, context.tracker(), "Context mismatch");
45        self.dirty.borrow_mut().add_listener(f)
46    }
47    pub fn tracking_index(&self) -> TrackingIndex {
48        self.tracking_index
49    }
50}