Skip to content

Commit

Permalink
refctor: added state machine parsing and creation (#232)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelOsborne committed Sep 23, 2024
1 parent 5f78ace commit bfcd58b
Show file tree
Hide file tree
Showing 9 changed files with 1,266 additions and 1,617 deletions.
44 changes: 26 additions & 18 deletions dotlottie-rs/src/dotlottie_player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1357,17 +1357,25 @@ impl DotLottiePlayer {
let listeners = sm.get_listeners();

for listener in listeners {
match listener.try_read() {
Ok(listener) => {
let unwrapped_listener = &*listener;

if !listener_types
.contains(&unwrapped_listener.get_type().to_string())
{
listener_types.push(unwrapped_listener.get_type().to_string());
}
match listener {
crate::listeners::Listener::PointerUp { .. } => {
listener_types.push("PointerUp".to_string())
}
crate::listeners::Listener::PointerDown { .. } => {
listener_types.push("PointerDown".to_string())
}
crate::listeners::Listener::PointerEnter { .. } => {
listener_types.push("PointerEnter".to_string())
}
crate::listeners::Listener::PointerMove { .. } => {
listener_types.push("PointerMove".to_string())
}
crate::listeners::Listener::PointerExit { .. } => {
listener_types.push("PointerExit".to_string())
}
crate::listeners::Listener::OnComplete { .. } => {
listener_types.push("OnComplete".to_string())
}
Err(_) => return vec![],
}
}
listener_types
Expand All @@ -1379,7 +1387,7 @@ impl DotLottiePlayer {
}
}

pub fn set_state_machine_numeric_context(&self, key: &str, value: f32) -> bool {
pub fn set_numeric_trigger(&self, key: &str, value: f32) -> bool {
match self.state_machine.try_read() {
Ok(state_machine) => {
if state_machine.is_none() {
Expand All @@ -1394,7 +1402,7 @@ impl DotLottiePlayer {
match sm_write {
Ok(mut state_machine) => {
if let Some(sm) = state_machine.as_mut() {
sm.set_numeric_context(key, value);
sm.set_numeric_trigger(key, value);
}
}
Err(_) => return false,
Expand All @@ -1403,7 +1411,7 @@ impl DotLottiePlayer {
true
}

pub fn set_state_machine_string_context(&self, key: &str, value: &str) -> bool {
pub fn set_string_trigger(&self, key: &str, value: &str) -> bool {
match self.state_machine.try_read() {
Ok(state_machine) => {
if state_machine.is_none() {
Expand All @@ -1418,7 +1426,7 @@ impl DotLottiePlayer {
match sm_write {
Ok(mut state_machine) => {
if let Some(sm) = state_machine.as_mut() {
sm.set_string_context(key, value);
sm.set_string_trigger(key, value);
}
}
Err(_) => return false,
Expand All @@ -1427,7 +1435,7 @@ impl DotLottiePlayer {
true
}

pub fn set_state_machine_boolean_context(&self, key: &str, value: bool) -> bool {
pub fn set_bool_trigger(&self, key: &str, value: bool) -> bool {
match self.state_machine.try_read() {
Ok(state_machine) => {
if state_machine.is_none() {
Expand All @@ -1442,7 +1450,7 @@ impl DotLottiePlayer {
match sm_write {
Ok(mut state_machine) => {
if let Some(sm) = state_machine.as_mut() {
sm.set_bool_context(key, value);
sm.set_bool_trigger(key, value);
}
}
Err(_) => return false,
Expand Down Expand Up @@ -1655,7 +1663,7 @@ impl DotLottiePlayer {
}

#[cfg(not(target_arch = "wasm32"))]
pub fn state_machine_subscribe(&self, observer: Arc<dyn StateMachineObserver>) -> bool {
pub fn state_machine_subscribe(&self, observer: Rc<dyn StateMachineObserver>) -> bool {
let mut sm = self.state_machine.write().unwrap();

if sm.is_none() {
Expand All @@ -1667,7 +1675,7 @@ impl DotLottiePlayer {
}

#[cfg(not(target_arch = "wasm32"))]
pub fn state_machine_unsubscribe(&self, observer: Arc<dyn StateMachineObserver>) -> bool {
pub fn state_machine_unsubscribe(&self, observer: Rc<dyn StateMachineObserver>) -> bool {
let mut sm = self.state_machine.write().unwrap();

if sm.is_none() {
Expand Down
227 changes: 227 additions & 0 deletions dotlottie-rs/src/state_machine/actions/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
use thiserror::Error;

use std::{collections::HashMap, rc::Rc, sync::RwLock};

use crate::DotLottiePlayerContainer;

#[derive(Error, Debug)]
pub enum StateMachineActionError {
#[error("Error executing action: {0}")]
ExecuteError(String),
}

pub trait ActionTrait {
fn execute(
&self,
player: &Rc<RwLock<DotLottiePlayerContainer>>,
string_trigger: &mut HashMap<String, String>,
bool_trigger: &mut HashMap<String, bool>,
numeric_trigger: &mut HashMap<String, f32>,
event_trigger: &HashMap<String, String>,
) -> Result<(), StateMachineActionError>;
}

#[derive(Clone, Debug)]
pub enum Action {
Increment {
trigger_name: String,
value: Option<f32>,
},
Decrement {
trigger_name: String,
value: Option<f32>,
},
Toggle {
trigger_name: String,
},
SetBoolean {
trigger_name: String,
value: bool,
},
SetNumeric {
trigger_name: String,
value: f32,
},
SetString {
trigger_name: String,
value: String,
},
Fire {
trigger_name: String,
},
Reset {
trigger_name: String,
},
SetExpression {
layer_name: String,
property_index: u32,
var_name: String,
value: f32,
},
SetTheme {
theme_id: String,
},
SetFrame {
value: f32,
},
SetSlot {
value: String,
},
OpenUrl {
url: String,
},
FireCustomEvent {
value: String,
},
}

impl ActionTrait for Action {
fn execute(
&self,
player: &Rc<RwLock<DotLottiePlayerContainer>>,
string_trigger: &mut HashMap<String, String>,
bool_trigger: &mut HashMap<String, bool>,
numeric_trigger: &mut HashMap<String, f32>,
event_trigger: &HashMap<String, String>,
) -> Result<(), StateMachineActionError> {
match self {
Action::Increment {
trigger_name,
value,
} => {
println!("Incrementing trigger {} by {:?}", trigger_name, value);

if let Some(value) = value {
numeric_trigger.insert(
trigger_name.to_string(),
numeric_trigger.get(trigger_name).unwrap_or(&0.0) + value,
);
} else {
numeric_trigger.insert(
trigger_name.to_string(),
numeric_trigger.get(trigger_name).unwrap_or(&0.0) + 1.0,
);
}
Ok(())
}
Action::Decrement {
trigger_name,
value,
} => {
println!("Decrementing trigger {} by {:?}", trigger_name, value);

if let Some(value) = value {
numeric_trigger.insert(
trigger_name.to_string(),
numeric_trigger.get(trigger_name).unwrap_or(&0.0) - value,
);
} else {
numeric_trigger.insert(
trigger_name.to_string(),
numeric_trigger.get(trigger_name).unwrap_or(&0.0) - 1.0,
);
}
Ok(())
}
Action::Toggle { trigger_name } => {
println!("Toggling trigger {}", trigger_name);
bool_trigger.insert(
trigger_name.to_string(),
!bool_trigger.get(trigger_name).unwrap_or(&false),
);

Ok(())
}
Action::SetBoolean {
trigger_name,
value,
} => {
println!("Setting trigger {} to {}", trigger_name, value);
bool_trigger.insert(trigger_name.to_string(), *value);
Ok(())
}
Action::SetNumeric {
trigger_name,
value,
} => {
println!("Setting trigger {} to {}", trigger_name, value);
numeric_trigger.insert(trigger_name.to_string(), *value);
Ok(())
}
Action::SetString {
trigger_name,
value,
} => {
println!("Setting trigger {} to {}", trigger_name, value);
string_trigger.insert(trigger_name.to_string(), value.to_string());

Ok(())
}
Action::Fire { trigger_name } => {
println!("Firing trigger {}", trigger_name);
Ok(())
}
Action::Reset { trigger_name } => {
println!("Resetting trigger {}", trigger_name);
Ok(())
}
Action::SetExpression {
layer_name,
property_index,
var_name,
value,
} => {
println!(
"Setting expression {} on layer {} property {} to {}",
var_name, layer_name, property_index, value
);
Ok(())
}
Action::SetTheme { theme_id } => {
println!("Setting theme to {}", theme_id);
Ok(())
}
Action::SetSlot { value } => {
println!("Setting slot to {}", value);
let read_lock = player.read();

match read_lock {
Ok(player) => {
player.load_theme_data(&value);
}
Err(_) => {
return Err(StateMachineActionError::ExecuteError(
"Error getting read lock on player".to_string(),
));
}
}

Ok(())
}
Action::OpenUrl { url } => {
println!("Opening URL {}", url);
Ok(())
}
Action::FireCustomEvent { value } => {
println!("Firing custom event {}", value);

Ok(())
}
Action::SetFrame { value } => {
let read_lock = player.read();

match read_lock {
Ok(player) => {
player.set_frame(*value);
Ok(())
}
Err(_) => {
return Err(StateMachineActionError::ExecuteError(
"Error getting read lock on player".to_string(),
));
}
}
}
}
}
}
2 changes: 2 additions & 0 deletions dotlottie-rs/src/state_machine/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod actions;
pub mod errors;
pub mod events;
pub mod listeners;
Expand All @@ -6,6 +7,7 @@ pub mod state_machine;
pub mod states;
pub mod transitions;

pub use crate::actions::*;
pub use crate::errors::*;
pub use crate::events::*;
pub use crate::listeners::*;
Expand Down
Loading

0 comments on commit bfcd58b

Please sign in to comment.