Projektmodule und vollständiges TBC-Kompilat umsetzen und Change archivieren

This commit is contained in:
2026-09-05 23:06:56 +02:00
parent 58b1f620ea
commit 815825dde7
40 changed files with 4177 additions and 555 deletions

View File

@@ -56,9 +56,7 @@ impl FormFile {
} else {
let array = forms::property(node.class, "INDEX")
.and_then(|(property, _)| node.properties.get(&property))
.is_some_and(
|value| matches!(value, PropertyValue::Integer(index) if *index != 0),
);
.is_some();
catalog.add(&node.name, node.class, parent, array);
}
for child in &node.children {
@@ -70,44 +68,99 @@ impl FormFile {
catalog
}
pub fn apply(&self, model: &mut FormsModel) -> Result<(), tb_runtime::errors::RuntimeError> {
fn apply_node(
pub fn code_line(&self) -> u32 {
self.original.as_ref().map_or(1, |original| {
original.bytes[..original.bytes.len() - original.code.len()]
.bytes()
.filter(|b| *b == b'\n')
.count() as u32
+ 1
})
}
pub fn initial_values(
&self,
catalog: &FormCatalog,
) -> Result<Vec<FormInitial>, tb_runtime::errors::RuntimeError> {
fn collect(
node: &FormNode,
model: &mut FormsModel,
menu_depth: usize,
parent: Option<u16>,
catalog: &FormCatalog,
out: &mut Vec<FormInitial>,
depth: usize,
) -> Result<(), tb_runtime::errors::RuntimeError> {
let menu_depth = if node.class == ObjectClass::Menu {
menu_depth + 1
} else {
menu_depth
};
if menu_depth > 6 {
return Err(tb_runtime::errors::RuntimeError::ILLEGAL_FUNCTION_CALL);
let depth = depth + usize::from(node.class == ObjectClass::Menu);
if depth > 6 {
return Err(tb_runtime::errors::RuntimeError(5));
}
let object = model
let object = catalog
.objects
.iter()
.position(|candidate| candidate.description.name.eq_ignore_ascii_case(&node.name))
.position(|o| {
o.name.eq_ignore_ascii_case(&node.name)
&& o.parent == parent
&& o.class == node.class
})
.ok_or(tb_runtime::errors::RuntimeError(420))? as u16;
let index = forms::property(node.class, "INDEX")
.and_then(|(property, _)| node.properties.get(&property))
.and_then(|value| match value {
PropertyValue::Integer(value) => Some(*value),
_ => None,
.and_then(|(id, _)| node.properties.get(&id))
.and_then(|v| {
if let PropertyValue::Integer(n) = v {
Some(*n)
} else {
None
}
})
.unwrap_or(0);
if index != 0 && !model.is_loaded_at(object, Some(index)) {
model.load_design_array(object, index)?;
}
for (property, value) in &node.properties {
model.set_initial_at(object, Some(index), *property, value.clone())?;
if out.iter().any(|v| v.object == object && v.index == index) {
return Err(tb_runtime::errors::RuntimeError(5));
}
out.push(FormInitial {
object,
index,
properties: node.properties.clone(),
});
for child in &node.children {
apply_node(child, model, menu_depth)?;
collect(child, Some(object), catalog, out, depth)?;
}
Ok(())
}
apply_node(&self.root, model, 0)
let mut values = Vec::new();
collect(&self.root, None, catalog, &mut values, 0)?;
Ok(values)
}
pub fn apply(&self, model: &mut FormsModel) -> Result<(), tb_runtime::errors::RuntimeError> {
let catalog = FormCatalog {
objects: model
.objects
.iter()
.map(|o| o.description.clone())
.collect(),
};
for initial in self.initial_values(&catalog)? {
initial.apply(model)?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct FormInitial {
pub object: u16,
pub index: i32,
pub properties: BTreeMap<u16, PropertyValue>,
}
impl FormInitial {
pub fn apply(&self, model: &mut FormsModel) -> Result<(), tb_runtime::errors::RuntimeError> {
if self.index != 0 && !model.is_loaded_at(self.object, Some(self.index)) {
model.load_design_array(self.object, self.index)?;
}
for (property, value) in &self.properties {
model.set_initial_at(self.object, Some(self.index), *property, value.clone())?;
}
Ok(())
}
}