oxmpl_js/base/
compound_state.rs1use std::{any::Any, sync::Arc};
6
7use oxmpl::base::state::{
8 CompoundState, RealVectorState, SE2State, SE3State, SO2State, SO3State, State,
9};
10use wasm_bindgen::prelude::*;
11
12use crate::base::{JsRealVectorState, JsSE2State, JsSE3State, JsSO2State, JsSO3State};
13
14#[wasm_bindgen(js_name = CompoundState)]
15pub struct JsCompoundState {
16 #[wasm_bindgen(skip)]
17 pub inner: Arc<CompoundState>,
18}
19
20#[wasm_bindgen(js_class = CompoundState)]
21impl JsCompoundState {
22 #[wasm_bindgen(getter = componentCount)]
23 pub fn component_count(&self) -> usize {
24 self.inner.components.len()
25 }
26
27 #[wasm_bindgen(js_name = getComponent)]
28 pub fn get_component(&self, index: usize) -> Result<JsValue, String> {
29 if index >= self.inner.components.len() {
30 return Err("Index out of bounds".to_string());
31 }
32
33 let component = &self.inner.components[index];
34 let component_ref: &dyn State = component.as_ref();
35 let any_ref = component_ref as &dyn Any;
36
37 if let Some(s) = any_ref.downcast_ref::<RealVectorState>() {
38 return Ok(JsValue::from(JsRealVectorState {
39 inner: Arc::new(s.clone()),
40 }));
41 }
42 if let Some(s) = any_ref.downcast_ref::<SO2State>() {
43 return Ok(JsValue::from(JsSO2State::new(s.value)));
44 }
45 if let Some(s) = any_ref.downcast_ref::<SO3State>() {
46 return Ok(JsValue::from(JsSO3State::new(s.x, s.y, s.z, s.w)));
47 }
48 if let Some(s) = any_ref.downcast_ref::<SE2State>() {
49 return Ok(JsValue::from(JsSE2State::new(
50 s.get_x(),
51 s.get_y(),
52 s.get_yaw(),
53 )));
54 }
55 if let Some(s) = any_ref.downcast_ref::<SE3State>() {
56 let rotation = JsSO3State::new(
57 s.get_rotation().x,
58 s.get_rotation().y,
59 s.get_rotation().z,
60 s.get_rotation().w,
61 );
62 return Ok(JsValue::from(JsSE3State::new(
63 s.get_x(),
64 s.get_y(),
65 s.get_z(),
66 rotation,
67 )));
68 }
69 if let Some(s) = any_ref.downcast_ref::<CompoundState>() {
70 return Ok(JsValue::from(JsCompoundState {
71 inner: Arc::new(s.clone()),
72 }));
73 }
74
75 Err("Unknown component state type".to_string())
76 }
77}
78
79#[wasm_bindgen(js_name = CompoundStateBuilder)]
85pub struct JsCompoundStateBuilder {
86 components: Vec<Box<dyn State>>,
87}
88
89impl Default for JsCompoundStateBuilder {
90 fn default() -> Self {
91 Self::new()
92 }
93}
94
95#[wasm_bindgen(js_class = CompoundStateBuilder)]
96impl JsCompoundStateBuilder {
97 #[wasm_bindgen(constructor)]
98 pub fn new() -> Self {
99 Self {
100 components: Vec::new(),
101 }
102 }
103
104 #[wasm_bindgen(js_name = addRealVectorState)]
105 pub fn add_real_vector_state(&mut self, state: &JsRealVectorState) {
106 self.components.push(Box::new((*state.inner).clone()));
107 }
108
109 #[wasm_bindgen(js_name = addSO2State)]
110 pub fn add_so2_state(&mut self, state: &JsSO2State) {
111 self.components.push(Box::new((*state.inner).clone()));
112 }
113
114 #[wasm_bindgen(js_name = addSO3State)]
115 pub fn add_so3_state(&mut self, state: &JsSO3State) {
116 self.components.push(Box::new((*state.inner).clone()));
117 }
118
119 #[wasm_bindgen(js_name = addSE2State)]
120 pub fn add_se2_state(&mut self, state: &JsSE2State) {
121 self.components.push(Box::new((*state.inner).clone()));
122 }
123
124 #[wasm_bindgen(js_name = addSE3State)]
125 pub fn add_se3_state(&mut self, state: &JsSE3State) {
126 self.components.push(Box::new((*state.inner).clone()));
127 }
128
129 #[wasm_bindgen(js_name = addCompoundState)]
130 pub fn add_compound_state(&mut self, state: &JsCompoundState) {
131 self.components.push(Box::new((*state.inner).clone()));
132 }
133
134 pub fn build(self) -> JsCompoundState {
135 JsCompoundState {
136 inner: Arc::new(CompoundState::new(self.components)),
137 }
138 }
139}