use crate::prelude::*;
use crate::shared::typed_ids::BindingId;
#[derive(Copy, Clone, PartialEq)]
pub enum BranchingKind {
Single,
Double,
}
#[derive(Copy, Clone, PartialEq)]
pub enum BranchingPath {
A,
B,
}
struct BranchingBinding {
activated: bool,
path_a: bool,
path_b: bool,
}
struct Branching {
bindings: UnorderedMap<BindingId, BranchingBinding>,
kind: BranchingKind,
current_path: BranchingPath,
}
impl Branching {
fn new(kind: BranchingKind) -> Self {
Self {
bindings: UnorderedMap::new(),
kind,
current_path: BranchingPath::A,
}
}
}
pub struct BindingState {
branchings: Vec<Branching>,
}
impl BindingState {
pub fn new() -> Self {
Self { branchings: Vec::new() }
}
pub fn push(self: &mut Self, kind: BranchingKind) {
self.branchings.push(Branching::new(kind));
}
pub fn set_path(self: &mut Self, path: BranchingPath) {
self.branchings.last_mut().unwrap().current_path = path;
}
pub fn pop(self: &mut Self) {
let branch = self.branchings.pop().unwrap();
for (binding_id, binding_state) in branch.bindings {
let init_parent = binding_state.path_a && (branch.kind == BranchingKind::Single || (branch.kind == BranchingKind::Double && binding_state.path_b));
if init_parent && self.branchings.len() > 0 {
self.initialize(binding_id);
}
}
}
pub fn activate(self: &mut Self, binding_id: BindingId) {
self.current_mut(binding_id).activated = true;
}
pub fn activated(self: &Self, binding_id: BindingId) -> bool {
let branching = self.branchings.last().unwrap();
match branching.bindings.get(&binding_id) {
Some(binding) => binding.activated,
_ => false
}
}
pub fn initialize(self: &mut Self, binding_id: BindingId) {
match self.branchings.last().unwrap().current_path {
BranchingPath::A => self.current_mut(binding_id).path_a = true,
BranchingPath::B => self.current_mut(binding_id).path_b = true,
}
}
pub fn initialized(self: &Self, binding_id: BindingId) -> bool {
for branching in self.branchings.iter().rev() {
if let Some(binding) = branching.bindings.get(&binding_id) {
if match branching.current_path {
BranchingPath::A => binding.path_a,
BranchingPath::B => binding.path_b,
} { return true; } }
}
return false;
}
fn current_mut(self: &mut Self, binding_id: BindingId) -> &mut BranchingBinding {
self.branchings.last_mut().unwrap().bindings.entry(binding_id).or_insert(BranchingBinding { activated: false, path_a: false, path_b: false })
}
}