standing_relations/core/
output.rs1use 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}