use std::collections;
use specs;
use specs_visitor;
use ir::component::element;
use ir::component::layout;
use ir::component::replacement;
use ir::component::symbol;
use ir::component::ty;
pub struct System;
struct ReplacementEntityVisitor {
replacements: collections::HashMap<specs::Entity, specs::Entity>,
}
impl<'a> specs::System<'a> for System {
type SystemData = (
specs::Entities<'a>,
specs::ReadStorage<'a, replacement::Replacement>,
specs::WriteStorage<'a, element::Element>,
specs::WriteStorage<'a, layout::Layout>,
specs::WriteStorage<'a, symbol::Symbol>,
specs::WriteStorage<'a, ty::Type>,
);
fn run(
&mut self,
(entities, replacements, mut elements, mut layouts, mut symbols, mut types): Self::SystemData,
) {
use specs::prelude::ParallelIterator;
use specs::ParJoin;
(&entities, &replacements)
.par_join()
.for_each(|(entity, _)| {
entities.delete(entity).unwrap();
});
let replacements = (&entities, &replacements)
.par_join()
.map(|(entity, replacement)| (entity, replacement.to))
.collect();
let visitor = ReplacementEntityVisitor { replacements };
(&mut elements).par_join().for_each(|element| {
use specs_visitor::VisitEntities;
element.accept_mut(&visitor);
});
(&mut layouts).par_join().for_each(|layout| {
use specs_visitor::VisitEntities;
layout.accept_mut(&visitor);
});
(&mut symbols).par_join().for_each(|symbol| {
use specs_visitor::VisitEntities;
symbol.accept_mut(&visitor);
});
(&mut types).par_join().for_each(|ty| {
use specs_visitor::VisitEntities;
ty.accept_mut(&visitor);
});
}
}
impl specs_visitor::EntityVisitorMut for ReplacementEntityVisitor {
fn visit_entity_mut(&self, from: &mut specs::Entity) {
if let Some(to) = self.replacements.get(from) {
trace!("applying replacement from {:?} to {:?}", from, to);
*from = *to;
}
}
}