Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

begin stub for math component #3

Draft
wants to merge 2 commits into
base: attributes
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use crate::dast::{
Position as DastPosition,
};
use crate::state::{
StateVar, StateVarName, StateVarReadOnlyView, StateVarReadOnlyViewTyped, StateVarValue,
MathExpression, StateVar, StateVarName, StateVarReadOnlyView, StateVarReadOnlyViewTyped,
StateVarValue,
};
use crate::{ComponentIdx, ComponentPointerTextOrMacro, ExtendSource};

Expand Down Expand Up @@ -283,6 +284,7 @@ pub enum ComponentProfile {
Number,
Integer,
Boolean,
Math,
}

/// When a component designates a component profile state variable,
Expand All @@ -302,6 +304,7 @@ pub enum ComponentProfileStateVariable {
Number(StateVarReadOnlyViewTyped<f64>, StateVarName),
Integer(StateVarReadOnlyViewTyped<i64>, StateVarName),
Boolean(StateVarReadOnlyViewTyped<bool>, StateVarName),
Math(StateVarReadOnlyViewTyped<MathExpression>, StateVarName),
}

// TODO: derive these with macro?
Expand All @@ -315,6 +318,7 @@ impl ComponentProfileStateVariable {
ComponentProfileStateVariable::Number(..) => ComponentProfile::Number,
ComponentProfileStateVariable::Integer(..) => ComponentProfile::Integer,
ComponentProfileStateVariable::Boolean(..) => ComponentProfile::Boolean,
ComponentProfileStateVariable::Math(..) => ComponentProfile::Math,
}
}

Expand Down Expand Up @@ -348,6 +352,10 @@ impl ComponentProfileStateVariable {
StateVarReadOnlyView::Boolean(sv.create_new_read_only_view()),
name,
),
ComponentProfileStateVariable::Math(sv, name) => (
StateVarReadOnlyView::Math(sv.create_new_read_only_view()),
name,
),
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod document;
pub mod math;
pub mod p;
pub mod section;
pub mod text;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;

use crate::components::prelude::*;
use crate::state::MathExpression;
use crate::state_var_interfaces::math_state_var_interfaces::GeneralMathStateVarInterface;

#[derive(Debug, Default, ComponentNode, RenderedComponentNode)]
pub struct Math {
pub common: ComponentCommonData,

pub value_state_var_view: StateVarReadOnlyViewTyped<MathExpression>,

pub renderer_data: TextRendererData,
}

// TODO: implement RenderedComponentNode rather than deriving it

#[derive(Debug, Default)]
pub struct TextRendererData {
pub id: ComponentIdx,
pub value: String,
}

impl ComponentNodeStateVariables for Math {
fn initialize_state_variables(&mut self) {
self.common.state_variables = Vec::new();

///////////////////////
// Value state variable
///////////////////////

let value_state_variable = StateVarTyped::new(
Box::new(GeneralMathStateVarInterface::default()),
StateVarParameters {
for_renderer: true,
name: "value",
dependency_instruction_hint: Some(DependencyInstruction::Child {
match_profiles: vec![ComponentProfile::Math, ComponentProfile::String],
exclude_if_prefer_profiles: vec![],
}),
create_dependency_from_extend_source: true,
is_primary_state_variable_for_shadowing_extend_source: true,
is_public: true,
..Default::default()
},
Default::default(),
);

// save a view to field for easy access when create flat dast
self.value_state_var_view = value_state_variable.create_new_read_only_view();

// Use the value state variable for fulling the text component profile
self.common.component_profile_state_variables = vec![ComponentProfileStateVariable::Math(
value_state_variable.create_new_read_only_view(),
"value",
)];
self.common
.state_variables
.push(StateVar::Math(value_state_variable));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,11 @@ impl<T: Default + Clone> StateVarTyped<T> {
// Particularly useful for having vectors of mixed type
///////////////////////////////////////////////////////////////////////

/// Place holder for a Math type.
/// TODO: determine how this should work
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, PartialEq)]
pub struct MathExpression(pub f64);

/// The base structure for a state variable.
///
/// Provides access to the `StateVarInterface` methods
Expand All @@ -757,6 +762,7 @@ pub enum StateVar {
Integer(StateVarTyped<i64>),
String(StateVarTyped<String>),
Boolean(StateVarTyped<bool>),
Math(StateVarTyped<MathExpression>),
}

/// An untyped, mutable view of the value of the state variable.
Expand All @@ -767,6 +773,7 @@ pub enum StateVarMutableView {
Integer(StateVarMutableViewTyped<i64>),
String(StateVarMutableViewTyped<String>),
Boolean(StateVarMutableViewTyped<bool>),
Math(StateVarMutableViewTyped<MathExpression>),
}

/// An untyped, read-only view of the value of the state variable.
Expand All @@ -777,6 +784,7 @@ pub enum StateVarReadOnlyView {
Integer(StateVarReadOnlyViewTyped<i64>),
String(StateVarReadOnlyViewTyped<String>),
Boolean(StateVarReadOnlyViewTyped<bool>),
Math(StateVarReadOnlyViewTyped<MathExpression>),
}

/// This can contain the value of a state variable of any type,
Expand All @@ -788,6 +796,7 @@ pub enum StateVarValue {
Number(f64),
Integer(i64),
Boolean(bool),
Math(MathExpression),
}

impl StateVar {
Expand All @@ -801,6 +810,7 @@ impl StateVar {
StateVar::Integer(_) => "number",
StateVar::String(_) => "text",
StateVar::Boolean(_) => "boolean",
StateVar::Math(_) => "math",
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use crate::{
components::prelude::{
Dependency, DependencyInstruction, DependencyValueUpdateRequest, StateVarInterface,
StateVarMutableViewTyped, StateVarParameters, StateVarReadOnlyView,
StateVarReadOnlyViewTyped,
},
state::MathExpression,
ExtendSource,
};

use super::common::create_dependency_instruction_from_extend_source;

#[derive(Debug)]
enum MathOrStringValues {
Math(StateVarReadOnlyViewTyped<MathExpression>),
String(StateVarReadOnlyViewTyped<String>),
}

impl Default for MathOrStringValues {
fn default() -> Self {
MathOrStringValues::String(StateVarReadOnlyViewTyped::default())
}
}

#[derive(Debug, Default)]
pub struct GeneralMathStateVarInterface {
math_string_dependency_values: Vec<MathOrStringValues>,
}

impl StateVarInterface<MathExpression> for GeneralMathStateVarInterface {
fn return_dependency_instructions(
&self,
extend_source: Option<&ExtendSource>,
parameters: &StateVarParameters,
) -> Vec<DependencyInstruction> {
let mut dep_instructs: Vec<DependencyInstruction> = Vec::with_capacity(2);

if parameters.create_dependency_from_extend_source {
if let Some(dep_inst) =
create_dependency_instruction_from_extend_source(extend_source, parameters)
{
dep_instructs.push(dep_inst)
}
}

if let Some(dependency_instruction) = &parameters.dependency_instruction_hint {
dep_instructs.push(dependency_instruction.clone());
}

dep_instructs
}

fn save_dependencies_for_value_calculation(
&mut self,
dependencies: &Vec<Vec<Dependency>>,
) -> () {
let num_dependencies = dependencies.iter().fold(0, |a, c| a + c.len());

let mut math_or_string_vals = Vec::with_capacity(num_dependencies);

for instruction in dependencies.iter() {
for Dependency {
value: dep_value, ..
} in instruction.iter()
{
match dep_value {
StateVarReadOnlyView::Math(dep_math_value) => math_or_string_vals.push(
MathOrStringValues::Math(dep_math_value.create_new_read_only_view()),
),
StateVarReadOnlyView::String(dep_string_value) => math_or_string_vals.push(
MathOrStringValues::String(dep_string_value.create_new_read_only_view()),
),
_ => {
panic!(
"Got a non-math or string value for a dependency for a GeneralMathStateVarInterface"
);
}
}
}
}

self.math_string_dependency_values = math_or_string_vals;
}

fn calculate_state_var_from_dependencies_and_mark_fresh(
&self,
state_var: &StateVarMutableViewTyped<MathExpression>,
) -> () {
// TODO: implement an algorithm that concatenates the strings along with codes for the math expressions,
// parses the resulting string with math-expressions parser (text or latex, depending on parameters that don't have yet)
// then substitutes the values of the math components into the variables corresponding to the codes.

// Setting value to 0 for now!!!
state_var.set_value(MathExpression(0.0));
}
}