1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
pub struct RT {
    pub name: String,
    pub aliases: std::collections::BTreeMap<String, String>,
    pub bag: std::collections::BTreeMap<String, ftd::p2::Thing>,
    pub instructions: Vec<ftd::Instruction>,
}

impl RT {
    pub fn from(
        name: &str,
        aliases: std::collections::BTreeMap<String, String>,
        bag: std::collections::BTreeMap<String, ftd::p2::Thing>,
        instructions: Vec<ftd::Instruction>,
    ) -> Self {
        Self {
            name: name.to_string(),
            aliases,
            bag,
            instructions,
        }
    }

    // pub fn set_bool(&mut self, variable: &str, value: bool, doc_id: &str) -> ftd::p1::Result<bool> {
    //     match self.bag.get(variable) {
    //         Some(ftd::p2::Thing::Variable(v)) => match v.value {
    //             ftd::Value::Boolean { value: old } => {
    //                 let conditions = v.conditions.to_vec();
    //                 self.bag.insert(
    //                     variable.to_string(),
    //                     ftd::p2::Thing::Variable(ftd::Variable {
    //                         name: variable.to_string(),
    //                         value: ftd::Value::Boolean { value },
    //                         conditions,
    //                     }),
    //                 );
    //                 Ok(old)
    //             }
    //             ref t => ftd::e2(
    //                 format!("{} is not a boolean", variable),
    //                 format!("{:?}", t).as_str(),
    //             ),
    //         },
    //         Some(t) => ftd::e2(
    //             format!("{} is not a variable", variable),
    //             format!("{:?}", t).as_str(),
    //         ),
    //         None => ftd::e2(format!("{} not found", variable), doc_id),
    //     }
    // }

    pub fn render(&mut self) -> ftd::p1::Result<ftd::Column> {
        let mut main = self.render_();
        if let Ok(main) = &mut main {
            ftd::Element::set_id(&mut main.container.children, &[], None);
        }
        main
    }

    pub fn render_(&mut self) -> ftd::p1::Result<ftd::Column> {
        let mut main = ftd::p2::interpreter::default_column();
        let mut invocations = Default::default();
        let mut element = ftd::execute_doc::ExecuteDoc {
            name: self.name.as_str(),
            aliases: &self.aliases,
            bag: &self.bag,
            instructions: &self.instructions,
            arguments: &Default::default(),
            invocations: &mut invocations,
            root_name: None,
        }
        .execute(&[], &mut Default::default(), None)?
        .children;

        ftd::Element::renesting_on_region(&mut element);
        ftd::p2::document::set_region_id(&mut element);
        ftd::p2::document::default_scene_children_position(&mut element);

        main.container.children = element;
        store_invocations(&mut self.bag, invocations);
        Ok(main)
    }
}

pub(crate) fn store_invocations(
    bag: &mut std::collections::BTreeMap<String, ftd::p2::Thing>,
    invocations: std::collections::BTreeMap<
        String,
        Vec<std::collections::BTreeMap<String, ftd::Value>>,
    >,
) {
    for (k, v) in invocations.into_iter() {
        match bag.get_mut(k.as_str()).unwrap() {
            ftd::p2::Thing::Component(ref mut c) => {
                if !c.kernel {
                    c.invocations.extend(v)
                }
            }
            _ => unreachable!(),
        }
    }
}