use crate::data::scaled::{level_scale, ScaleKind}; use std::sync::Arc; use titan::{CsvRow, CsvTable, GlobalId}; #[derive(Debug, Clone)] pub struct LogicData { csv_table: Arc, row_index: usize, global_id: GlobalId, name: String, } impl LogicData { pub fn new(csv_table: Arc, row_index: usize, table_index: i32) -> Self { let name = csv_table .row_at(row_index) .map(|row| row.string(0).to_owned()) .unwrap_or_default(); Self { csv_table, row_index, global_id: GlobalId::new(table_index, row_index as i32), name, } } pub fn name(&self) -> &str { &self.name } pub fn global_id(&self) -> GlobalId { self.global_id } pub fn table_index(&self) -> i32 { self.global_id.class_id } pub fn instance_id(&self) -> i32 { self.global_id.instance_id } pub fn row_index(&self) -> usize { self.row_index } pub fn csv_table(&self) -> &Arc { &self.csv_table } pub fn row(&self) -> Option<&CsvRow> { self.csv_table.row_at(self.row_index) } pub fn array_size(&self) -> usize { self.row().map(CsvRow::array_size).unwrap_or_default() } fn column(&self, name: &str) -> Option { self.csv_table.column_index(name) } pub fn int(&self, column: &str) -> i32 { match (self.row(), self.column(column)) { (Some(row), Some(index)) => row.int(index), _ => 0, } } pub fn int_at(&self, column: &str, level: usize) -> i32 { match (self.row(), self.column(column)) { (Some(row), Some(index)) => row.scaled_int(index, level), _ => 0, } } pub fn scaled_value(&self, column: &str, level: i32, kind: ScaleKind) -> i32 { let (Some(row), Some(index)) = (self.row(), self.column(column)) else { return 0; }; let count = row.value_count(index); if count == 0 { return 0; } if count == 1 { return row .int(index) .wrapping_mul(level_scale(kind.percent(), level)) / 100; } let index_at = if count < 8 { level.min(count as i32 - 1) } else { level }; if index_at < 0 { return 0; } row.int_at(index, index_at as usize) } pub fn string_at(&self, column: &str, index: usize) -> &str { match (self.row(), self.column(column)) { (Some(row), Some(column)) => row.string_at(column, index), _ => "", } } pub fn value_count(&self, column: &str) -> usize { match (self.row(), self.column(column)) { (Some(row), Some(column)) => row.value_count(column), _ => 0, } } pub fn string(&self, column: &str) -> &str { match (self.row(), self.column(column)) { (Some(row), Some(index)) => row.string(index), _ => "", } } pub fn boolean(&self, column: &str) -> bool { match (self.row(), self.column(column)) { (Some(row), Some(index)) => row.boolean(index), _ => false, } } }