synthphonia/forward/data/
contains.rs

1use std::{cell::UnsafeCell, collections::HashMap, hash::{DefaultHasher, Hash, Hasher}};
2
3use futures::StreamExt;
4use itertools::Itertools;
5use simple_rc_async::sync::broadcast::{self, Sender};
6
7use crate::{utils::UnsafeCellExt, value::{Type, Value}};
8
9
10pub type ListStr = &'static [&'static str];
11/// Determines whether all elements of the first sequence appear in order within the second sequence. 
12/// 
13/// The function iterates over the second sequence while maintaining an iterator over the first sequence. 
14/// For each element encountered in the second sequence, if it matches the next expected element from the first sequence, the iterator advances. 
15/// The process terminates early and returns true if all elements of the first sequence have been matched; otherwise, it returns false.
16/// 
17pub fn listsubseq(that: ListStr, this: ListStr) -> bool {
18    let mut iter = that.iter().peekable();
19    for item in this {
20        match iter.peek() {
21            Some(i)  if i == &item => { iter.next(); }
22            Some(_) => (),
23            None => return true,
24        }
25    }
26    return iter.peek() == None;
27}
28
29pub type ListData = HashMap<String, Vec<broadcast::Sender<Value>>>;
30
31/// Term dispatcher for contains
32pub struct Data(UnsafeCell<Vec<ListData>>);
33
34impl Data {
35
36    pub fn new(len: usize, ty: Type) -> Option<Self> {
37        if let Type::ListStr = ty {
38            Some(Data(vec![HashMap::new(); len].into()))
39        } else { None }
40    }
41    fn get(&self) -> &mut Vec<ListData> {
42        unsafe { self.0.as_mut() }
43    }
44    pub fn update(&self, value: Value) -> () {
45        if let Value::ListStr(ls) = value {
46            let mut iter = ls.iter().zip(self.get().iter());
47            let mut senders = HashMap::<broadcast::Sender<Value>, usize>::new();
48            let (sl0, data0) = iter.next().unwrap();
49            let mut position = 1;
50            for s in sl0.iter() {
51                if let Some(a) = data0.get(*s) {
52                    for sd in a {
53                        senders.insert(sd.clone(), position);
54                    }
55                }
56            }
57            if senders.is_empty() { return; }
58            
59            for (sl, data) in iter {
60                position <<= 1;
61                for s in sl.iter() {
62                    if let Some(a) = data.get(*s) {
63                        for sd in a {
64                            if let Some(mask) = senders.get_mut(sd) {
65                                *mask |= position;
66                            }
67                        }
68                    }
69                }
70            }
71
72            for (sd, mask) in senders {
73                if mask >= (1 << ls.len()) - 1 {
74                    sd.send(value);
75                }
76            }
77        }
78    }
79
80    pub fn listen_at(&self, value: Value) -> broadcast::Reciever<Value> {
81        if let Value::ListStr(ls) = value {
82            let sd = broadcast::channel();
83            for (sl, data) in ls.iter().zip(self.get().iter_mut()) {
84                for s in sl.iter() {
85                    if let Some(a) = data.get_mut(*s) {
86                        a.push(sd.clone());
87                    } else {
88                        data.insert((*s).to_string(), vec![sd.clone()]);
89                    }
90                }
91            }
92            sd.reciever()
93        } else if let Value::Str(s) = value {
94            let sd = broadcast::channel();
95            for (s, data) in s.iter().zip(self.get().iter_mut()) {
96                if let Some(a) = data.get_mut(*s) {
97                    a.push(sd.clone());
98                } else {
99                    data.insert(s.to_string(), vec![sd.clone()]);
100                }
101            }
102            sd.reciever()
103        } else { panic!("Unsupported Type for Contains") }
104    }
105
106    #[inline(always)]
107    pub async fn listen_for_each<T>(&self, value: Value, mut f: impl FnMut(Value) -> Option<T>) -> T {
108        let mut rv = self.listen_at(value);
109        loop {
110            if let Some(t) = f(rv.next().await.unwrap()) { return t; }
111        }
112    }
113}
114
115
116