Changeset - ba68b3aa475d
[Not reviewed]
0 1 0
Christopher Esterhuyse - 5 years ago 2020-02-13 16:38:56
christopheresterhuyse@gmail.com
fiddling
1 file changed with 33 insertions and 10 deletions:
0 comments (0 inline, 0 general)
src/runtime/ecs.rs
Show inline comments
 
@@ -224,12 +224,13 @@ enum Entity {
 
struct Ecs {
 
    component_info: Vec<(Arc<Protocol>, HashSet<ChannelId>)>,
 
    entities: Vec<Entity>,
 
    round_solution: Vec<(ChannelId, bool)>, // encodes an ASSIGNMENT
 
    ekey_channel_ids: Vec<ChannelId>,       // all channel Ids for local keys
 
    flags: EntityFlags,
 
    ekey_to_channel_id: HashMap<Key, ChannelId>,
 
}
 
#[derive(Default)]
 
struct EntityFlags {
 
    assignments: HashMap<(ChannelId, bool), BitSet>,
 
    payloads: BitSet,
 
    ekeys: HashMap<Key, BitSet>,
 
@@ -259,13 +260,13 @@ impl Ecs {
 
        self.flags.to_run_w.clear();
 
        self.flags.sync_ended.clear();
 

	
 
        // 2. We discard all payloads; they are all stale now.
 
        //    All machines are contiguous in the vector
 
        self.entities
 
            .retain(|entity| if let Entity::Machine { .. } = entity { true } else { false });
 
            .retain(move |entity| if let Entity::Machine { .. } = entity { true } else { false });
 

	
 
        // 3. initially, all the components need a chance to run in MONO mode
 
        self.flags.to_run_r.set_ones_until(self.entities.len());
 

	
 
        // 4. INVARIANT established:
 
        //    for all State variants in self.entities,
 
@@ -289,13 +290,13 @@ impl Ecs {
 
            // 1. check if this message is redundant, i.e., there is already an equivalent payload with predicate >= this one.
 
            //    ie. starting from all payloads
 

	
 
            // 2. try and find a payload whose predicate is the same or more general than this one
 
            //    if it exists, drop the message; it is uninteresting.
 
            let ekey_bitset = self.flags.ekeys.get(&ekey);
 
            if let Some(_eid) = ekey_bitset.map(|ekey_bitset| {
 
            if let Some(_eid) = ekey_bitset.map(move |ekey_bitset| {
 
                let mut slice_builder = vec![];
 
                // collect CONFLICTING assignments into slice_builder
 
                for &(channel_id, boolean) in msg.assignments.iter() {
 
                    if let Some(bitset) = self.flags.assignments.get(&(channel_id, !boolean)) {
 
                        slice_builder.push(bitset.as_slice());
 
                    }
 
@@ -307,13 +308,13 @@ impl Ecs {
 
                // _eid is a payload whose predicate is at least as general
 
                // drop this message!
 
                continue 'recv_loop;
 
            }
 

	
 
            // 3. insert this payload as an entity, overwriting an existing LESS GENERAL payload if it exists.
 
            let payload_eid: usize = if let Some(eid) = ekey_bitset.and_then(|ekey_bitset| {
 
            let payload_eid: usize = if let Some(eid) = ekey_bitset.and_then(move |ekey_bitset| {
 
                let mut slice_builder = vec![];
 
                slice_builder.push(ekey_bitset.as_slice());
 
                for assignment in msg.assignments.iter() {
 
                    if let Some(bitset) = self.flags.assignments.get(assignment) {
 
                        slice_builder.push(bitset.as_slice());
 
                    }
 
@@ -338,24 +339,46 @@ impl Ecs {
 
            self.feed_msg(payload_eid, ekey);
 
        }
 
    }
 

	
 
    fn run_poly_p(&mut self, machine_eid: usize) {
 
        match self.entities.get_mut(machine_eid) {
 
            Some(Entity::Machine { component_index, .. }) => {
 
            Some(Entity::Machine { component_index, state }) => {
 
                // TODO run the machine
 
                // DEBUG: testing the closing of all silent ports
 
                use PolyBlocker as Pb;
 
                let blocker: Pb = todo!();
 
                match blocker {
 
                    Pb::Inconsistent => self.flags.inconsistent.set(machine_eid),
 
                    Pb::CouldntCheckFiring(key) => {
 
                        let &channel_id = self.ekey_to_channel_id.get(&key).unwrap();
 
                        let state_true = state.clone();
 
                        let assignments: Vec<(ChannelId, bool)> = self
 
                            .flags
 
                            .assignments
 
                            .iter()
 
                            .filter_map(move |(&assignment, bitset)| {
 
                                match bitset.test(machine_eid) {
 
                                    true => Some(assignment),
 
                                    false => None,
 
                                }
 
                            })
 
                            .collect();
 

	
 
                        // FORK! this machine becomes FALSE
 
                    }
 
                    _ => todo!(),
 
                }
 

	
 
                // 1. make the assignment of this machine concrete WRT its ports
 
                let component_info = self.component_info.get(*component_index).unwrap();
 
                for &channel_id in component_info.1.iter() {
 
                    let test = self
 
                        .flags
 
                        .assignments
 
                        .get(&(channel_id, true))
 
                        .map(|bitset| bitset.test(machine_eid))
 
                        .map(move |bitset| bitset.test(machine_eid))
 
                        .unwrap_or(false);
 
                    if !test {
 
                        // TRUE assignment wasn't set
 
                        // so set FALSE assignment (no effect if already set)
 
                        self.flags
 
                            .assignments
 
@@ -417,13 +440,13 @@ impl Ecs {
 
    fn machine_assignment_for(&self, machine_eid: usize, channel_id: ChannelId) -> Option<bool> {
 
        let test = move |bitset: &BitSet| bitset.test(machine_eid);
 
        self.flags
 
            .assignments
 
            .get(&(channel_id, true))
 
            .map(test)
 
            .or_else(|| self.flags.assignments.get(&(channel_id, false)).map(test))
 
            .or_else(move || self.flags.assignments.get(&(channel_id, false)).map(test))
 
    }
 

	
 
    fn feed_msg(&mut self, payload_eid: usize, ekey: Key) {
 
        // 1. identify the component who:
 
        //    * is blocked on this ekey,
 
        //    * and has a predicate at least as strict as that of this payload
 
@@ -460,14 +483,14 @@ impl<'a> InAllExceptIter<'a> {
 
}
 
impl<'a> Iterator for InAllExceptIter<'a> {
 
    type Item = u32;
 
    fn next(&mut self) -> Option<Self::Item> {
 
        let i = self.next_chunk_index;
 
        self.next_chunk_index += 1;
 
        let init = self.except.get(i).map(|&x| !x).or(Some(1));
 
        self.in_all.iter().fold(init, |folding, slice| {
 
        let init = self.except.get(i).map(move |&x| !x).or(Some(1));
 
        self.in_all.iter().fold(init, move |folding, slice| {
 
            let a = folding?;
 
            let b = slice.get(i).copied().unwrap_or(0);
 
            Some(a & !b)
 
        })
 
    }
 
}
 
@@ -485,13 +508,13 @@ impl<'a> InNoneExceptIter<'a> {
 
impl<'a> Iterator for InNoneExceptIter<'a> {
 
    type Item = u32;
 
    fn next(&mut self) -> Option<Self::Item> {
 
        let i = self.next_chunk_index;
 
        self.next_chunk_index += 1;
 
        let init = self.except.get(i).copied()?;
 
        Some(self.in_none.iter().fold(init, |folding, slice| {
 
        Some(self.in_none.iter().fold(init, move |folding, slice| {
 
            let a = folding;
 
            let b = slice.get(i).copied().unwrap_or(0);
 
            a & !b
 
        }))
 
    }
 
}
0 comments (0 inline, 0 general)