Skip to content

Commit

Permalink
Merge branch 'main' into chore/wasm-artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
theashraf authored Jun 26, 2024
2 parents 552d326 + 9c11212 commit aeac3b6
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 54 deletions.
8 changes: 6 additions & 2 deletions dotlottie-ffi/emscripten_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ EMSCRIPTEN_BINDINGS(DotLottiePlayer)
// .function("onStateExit", &StateMachineObserver::on_state_exit);

class_<DotLottiePlayer>("DotLottiePlayer")
.smart_ptr<std::shared_ptr<DotLottiePlayer> >("DotLottiePlayer")
.smart_ptr<std::shared_ptr<DotLottiePlayer>>("DotLottiePlayer")
.constructor(&DotLottiePlayer::init, allow_raw_pointers())
.function("buffer", &buffer)
.function("clear", &DotLottiePlayer::clear)
Expand Down Expand Up @@ -157,7 +157,11 @@ EMSCRIPTEN_BINDINGS(DotLottiePlayer)
.function("startStateMachine", &DotLottiePlayer::start_state_machine)
.function("stopStateMachine", &DotLottiePlayer::stop_state_machine)
.function("postEventPayload", &DotLottiePlayer::post_serialized_event)
.function("stateMachineFrameworkSetup", &DotLottiePlayer::state_machine_framework_setup);
.function("stateMachineFrameworkSetup", &DotLottiePlayer::state_machine_framework_setup)
.function("setStateMachineNumericContext", &DotLottiePlayer::set_state_machine_numeric_context)
.function("setStateMachineStringContext", &DotLottiePlayer::set_state_machine_string_context)
.function("setStateMachineBooleanContext", &DotLottiePlayer::set_state_machine_boolean_context)
.function("loadStateMachineData", &DotLottiePlayer::load_state_machine_data);
// .function("state_machine_subscribe", &DotLottiePlayer::state_machine_subscribe)
// .function("state_machine_unsubscribe", &DotLottiePlayer::state_machine_unsubscribe)
}
4 changes: 4 additions & 0 deletions dotlottie-ffi/src/dotlottie_player.udl
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,9 @@ interface DotLottiePlayer {
boolean post_event([ByRef] Event event);
boolean state_machine_subscribe(StateMachineObserver observer);
boolean state_machine_unsubscribe(StateMachineObserver observer);
boolean set_state_machine_numeric_context([ByRef] string key, f32 value);
boolean set_state_machine_string_context([ByRef] string key, [ByRef] string value);
boolean set_state_machine_boolean_context([ByRef] string key, boolean value);
sequence<string> state_machine_framework_setup();
boolean load_state_machine_data([ByRef] string state_machine);
};
1 change: 1 addition & 0 deletions dotlottie-ffi/src/dotlottie_player_cpp.udl
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,5 @@ interface DotLottiePlayer {
boolean stop_state_machine();
boolean post_serialized_event(string event);
sequence<string> state_machine_framework_setup();
boolean load_state_machine_data([ByRef] string state_machine);
};
83 changes: 61 additions & 22 deletions dotlottie-rs/src/dotlottie_player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1312,8 +1312,7 @@ impl DotLottiePlayer {
}
}

// todo: Once lister actions are implemented, remove this fn
pub fn tmp_set_state_machine_context(&self, key: &str, value: f32) -> bool {
pub fn set_state_machine_numeric_context(&self, key: &str, value: f32) -> bool {
match self.state_machine.try_read() {
Ok(state_machine) => {
if state_machine.is_none() {
Expand All @@ -1323,17 +1322,21 @@ impl DotLottiePlayer {
Err(_) => return false,
}

self.state_machine
.write()
.unwrap()
.as_mut()
.unwrap()
.set_numeric_context(key, value);
let sm_write = self.state_machine.try_write();

match sm_write {
Ok(mut state_machine) => {
if let Some(sm) = state_machine.as_mut() {
sm.set_numeric_context(key, value);
}
}
Err(_) => return false,
}

true
}

pub fn tmp_set_state_machine_string_context(&self, key: &str, value: &str) -> bool {
pub fn set_state_machine_string_context(&self, key: &str, value: &str) -> bool {
match self.state_machine.try_read() {
Ok(state_machine) => {
if state_machine.is_none() {
Expand All @@ -1343,17 +1346,21 @@ impl DotLottiePlayer {
Err(_) => return false,
}

self.state_machine
.write()
.unwrap()
.as_mut()
.unwrap()
.set_string_context(key, value);
let sm_write = self.state_machine.try_write();

match sm_write {
Ok(mut state_machine) => {
if let Some(sm) = state_machine.as_mut() {
sm.set_string_context(key, value);
}
}
Err(_) => return false,
}

true
}

pub fn tmp_set_state_machine_bool_context(&self, key: &str, value: bool) -> bool {
pub fn set_state_machine_boolean_context(&self, key: &str, value: bool) -> bool {
match self.state_machine.try_read() {
Ok(state_machine) => {
if state_machine.is_none() {
Expand All @@ -1363,12 +1370,16 @@ impl DotLottiePlayer {
Err(_) => return false,
}

self.state_machine
.write()
.unwrap()
.as_mut()
.unwrap()
.set_bool_context(key, value);
let sm_write = self.state_machine.try_write();

match sm_write {
Ok(mut state_machine) => {
if let Some(sm) = state_machine.as_mut() {
sm.set_bool_context(key, value);
}
}
Err(_) => return false,
}

true
}
Expand Down Expand Up @@ -1770,6 +1781,34 @@ impl DotLottiePlayer {
self.player.write().unwrap().load_theme(theme_id)
}

pub fn load_state_machine_data(&self, state_machine: &str) -> bool {
let state_machine = StateMachine::new(state_machine, self.player.clone());

if state_machine.is_ok() {
match self.state_machine.try_write() {
Ok(mut sm) => {
sm.replace(state_machine.unwrap());
}
Err(_) => {
return false;
}
}

let player = self.player.try_write();

match player {
Ok(mut player) => {
player.state_machine = self.state_machine.clone();
}
Err(_) => {
return false;
}
}
}

false
}

pub fn load_state_machine(&self, state_machine_id: &str) -> bool {
let state_machine_string = self
.player
Expand Down
80 changes: 80 additions & 0 deletions dotlottie-rs/tests/fixtures/pigeon_fsm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"descriptor": {
"id": "multi_animation_slideshow",
"initial": 0
},
"states": [
{
"name": "pigeon",
"type": "PlaybackState",
"loop": true,
"autoplay": true,
"mode": "forward",
"speed": 1,
"marker": "bird",
"segment": [],
"frame_interpolation": true,
"entry_actions": [
{
"type": "LogAction",
"message": "Howdy partner!"
}
],
"exit_actions": [],
"reset_context": "*"
},
{
"name": "explosion",
"type": "PlaybackState",
"loop": false,
"autoplay": true,
"mode": "forward",
"speed": 0.5,
"marker": "explosion",
"segment": [],
"frame_interpolation": true,
"entry_actions": [],
"exit_actions": []
},
{
"name": "feather",
"type": "PlaybackState",
"loop": false,
"autoplay": true,
"mode": "forward",
"speed": 1,
"marker": "feather",
"segment": [],
"frame_interpolation": true,
"entry_actions": [],
"exit_actions": []
}
],
"transitions": [
{
"type": "Transition",
"from_state": 0,
"to_state": 1,
"on_pointer_down_event": {}
},
{
"type": "Transition",
"from_state": 1,
"to_state": 2,
"on_pointer_down_event": {}
},
{
"type": "Transition",
"from_state": 2,
"to_state": 0,
"on_pointer_down_event": {}
}
],
"listeners": [
{
"type": "PointerDown"
}
],
"context_variables": [
]
}
90 changes: 86 additions & 4 deletions dotlottie-rs/tests/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod tests {

use dotlottie_player_core::{
listeners::ListenerTrait,
states::StateTrait,
transitions::{Transition::Transition, TransitionTrait},
StateMachineObserver,
};
Expand Down Expand Up @@ -249,15 +250,15 @@ mod tests {
assert_eq!(*observer.custom_data.read().unwrap(), "No event so far");

// First test that the event doesn't fire if the guard is not met
player.tmp_set_state_machine_context("counter_0", 5.0);
player.set_state_machine_numeric_context("counter_0", 5.0);
player.post_event(&Event::String {
value: "explosion".to_string(),
});

// Should stay the same value we initialized it at
assert_eq!(*observer.custom_data.read().unwrap(), "No event so far");

player.tmp_set_state_machine_context("counter_0", 18.0);
player.set_state_machine_numeric_context("counter_0", 18.0);
player.post_event(&Event::String {
value: "explosion".to_string(),
});
Expand All @@ -274,7 +275,7 @@ mod tests {
// Should stay the same value we initialized it at
assert_eq!(*observer2.custom_data.read().unwrap(), "No event so far");

player.tmp_set_state_machine_string_context("counter_1", "not_the_same");
player.set_state_machine_string_context("counter_1", "not_the_same");
player.post_event(&Event::String {
value: "complete".to_string(),
});
Expand All @@ -288,7 +289,7 @@ mod tests {
// Should stay the same value we initialized it at
assert_eq!(*observer3.custom_data.read().unwrap(), "No event so far");

player.tmp_set_state_machine_bool_context("counter_2", false);
player.set_state_machine_boolean_context("counter_2", false);
player.post_event(&Event::String {
value: "done".to_string(),
});
Expand All @@ -297,6 +298,87 @@ mod tests {
assert_eq!(*observer3.custom_data.read().unwrap(), "\"feather\"");
}

#[test]
fn state_machine_from_data_test() {
let pigeon_fsm = include_str!("fixtures/pigeon_fsm.json");

let player = DotLottiePlayer::new(Config::default());

player.load_dotlottie_data(include_bytes!("fixtures/exploding_pigeon.lottie"), 100, 100);

player.load_state_machine_data(pigeon_fsm);
player.start_state_machine();

match player.get_state_machine().read().unwrap().as_ref() {
Some(sm) => {
assert_eq!(sm.states.len(), 3);
}
None => {
panic!("State machine is not loaded");
}
}

match player.get_state_machine().read().unwrap().as_ref() {
Some(sm) => {
let cs = sm.get_current_state();

match cs {
Some(sm) => match sm.try_read() {
Ok(state) => {
assert_eq!(state.get_name(), "pigeon");
}
Err(_) => panic!("State is not readable"),
},
None => panic!("Failed to get current state"),
}
}
None => {
panic!("State machine is not loaded");
}
}

player.post_event(&Event::OnPointerDown { x: 0.0, y: 0.0 });

match player.get_state_machine().read().unwrap().as_ref() {
Some(sm) => {
let cs = sm.get_current_state();

match cs {
Some(sm) => match sm.try_read() {
Ok(state) => {
assert_eq!(state.get_name(), "explosion");
}
Err(_) => panic!("State is not readable"),
},
None => panic!("Failed to get current state"),
}
}
None => {
panic!("State machine is not loaded");
}
}
player.post_event(&Event::OnPointerDown { x: 0.0, y: 0.0 });

match player.get_state_machine().read().unwrap().as_ref() {
Some(sm) => {
let cs = sm.get_current_state();

match cs {
Some(sm) => match sm.try_read() {
Ok(state) => {
assert_eq!(state.get_name(), "feather");
}
Err(_) => panic!("State is not readable"),
},
None => panic!("Failed to get current state"),
}
}
None => {
panic!("State machine is not loaded");
}
}
}

#[test]
fn state_machine_listener_test() {
let player = DotLottiePlayer::new(Config::default());
Expand Down
Loading

0 comments on commit aeac3b6

Please sign in to comment.