From 61d93ef156a12a6db2c6bb9da5ac92f7c171ee2b Mon Sep 17 00:00:00 2001 From: Gan Jun Kai Date: Wed, 10 Apr 2024 15:09:24 +0800 Subject: [PATCH 1/5] feat: add active_theme_id --- dotlottie-ffi/emscripten_bindings.cpp | 3 ++- dotlottie-ffi/src/dotlottie_player.udl | 1 + dotlottie-ffi/src/dotlottie_player_cpp.udl | 1 + dotlottie-rs/src/dotlottie_player.rs | 23 ++++++++++++++++++++-- dotlottie-rs/tests/theming.rs | 1 + 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dotlottie-ffi/emscripten_bindings.cpp b/dotlottie-ffi/emscripten_bindings.cpp index e50e811b..7071f65e 100644 --- a/dotlottie-ffi/emscripten_bindings.cpp +++ b/dotlottie-ffi/emscripten_bindings.cpp @@ -141,5 +141,6 @@ EMSCRIPTEN_BINDINGS(DotLottiePlayer) .function("loadTheme", &DotLottiePlayer::load_theme) .function("loadThemeData", &DotLottiePlayer::load_theme_data) .function("markers", &DotLottiePlayer::markers) - .function("activeAnimationId", &DotLottiePlayer::active_animation_id); + .function("activeAnimationId", &DotLottiePlayer::active_animation_id) + .function("activeThemeId", &DotLottiePlayer::active_theme_id); } diff --git a/dotlottie-ffi/src/dotlottie_player.udl b/dotlottie-ffi/src/dotlottie_player.udl index 1346c7a9..e7ab15fe 100644 --- a/dotlottie-ffi/src/dotlottie_player.udl +++ b/dotlottie-ffi/src/dotlottie_player.udl @@ -123,4 +123,5 @@ interface DotLottiePlayer { boolean load_theme_data([ByRef] string theme_data); sequence markers(); string active_animation_id(); + string active_theme_id(); }; diff --git a/dotlottie-ffi/src/dotlottie_player_cpp.udl b/dotlottie-ffi/src/dotlottie_player_cpp.udl index e879e9de..e6d7f5e7 100644 --- a/dotlottie-ffi/src/dotlottie_player_cpp.udl +++ b/dotlottie-ffi/src/dotlottie_player_cpp.udl @@ -126,4 +126,5 @@ interface DotLottiePlayer { boolean load_theme_data([ByRef] string theme_data); sequence markers(); string active_animation_id(); + string active_theme_id(); }; diff --git a/dotlottie-rs/src/dotlottie_player.rs b/dotlottie-rs/src/dotlottie_player.rs index 237eb48e..35a3004e 100644 --- a/dotlottie-rs/src/dotlottie_player.rs +++ b/dotlottie-rs/src/dotlottie_player.rs @@ -94,6 +94,7 @@ struct DotLottieRuntime { direction: Direction, markers: MarkersMap, active_animation_id: String, + active_theme_id: String, } impl DotLottieRuntime { @@ -116,6 +117,7 @@ impl DotLottieRuntime { direction, markers: MarkersMap::new(), active_animation_id: String::new(), + active_theme_id: String::new(), } } @@ -746,11 +748,14 @@ impl DotLottieRuntime { } pub fn load_theme(&mut self, theme_id: &str) -> bool { + self.active_theme_id.clear(); + if theme_id.is_empty() { return self.renderer.load_theme_data("").is_ok(); } - self.manifest() + let ok = self + .manifest() .and_then(|manifest| manifest.themes) .map_or(false, |themes| { themes @@ -774,7 +779,13 @@ impl DotLottieRuntime { }) .is_some() }) - }) + }); + + if ok { + self.active_theme_id = theme_id.to_string(); + } + + ok } pub fn load_theme_data(&mut self, theme_data: &str) -> bool { @@ -784,6 +795,10 @@ impl DotLottieRuntime { pub fn active_animation_id(&self) -> &str { &self.active_animation_id } + + pub fn active_theme_id(&self) -> &str { + &self.active_theme_id + } } pub struct DotLottiePlayer { @@ -1094,6 +1109,10 @@ impl DotLottiePlayer { .active_animation_id() .to_string() } + + pub fn active_theme_id(&self) -> String { + self.runtime.read().unwrap().active_theme_id().to_string() + } } unsafe impl Send for DotLottiePlayer {} diff --git a/dotlottie-rs/tests/theming.rs b/dotlottie-rs/tests/theming.rs index 5cbc1e80..12d3137f 100644 --- a/dotlottie-rs/tests/theming.rs +++ b/dotlottie-rs/tests/theming.rs @@ -24,6 +24,7 @@ mod tests { assert!(player.load_dotlottie_data(include_bytes!("assets/test.lottie"), WIDTH, HEIGHT)); assert!(player.load_theme(valid_theme_id), "Expected theme to load"); + assert_eq!(player.active_theme_id(), valid_theme_id); assert!(player.is_playing()); } From e79482550f3ce2fa2fb0fb823a088669be8739d8 Mon Sep 17 00:00:00 2001 From: Gan Jun Kai Date: Wed, 10 Apr 2024 20:41:52 +0800 Subject: [PATCH 2/5] feat: clear active theme after new animation or dotlottie is loaded --- demo-player/src/main.rs | 6 +-- dotlottie-rs/src/dotlottie_player.rs | 6 +++ dotlottie-rs/tests/theming.rs | 59 ++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/demo-player/src/main.rs b/demo-player/src/main.rs index 90009bca..47e5d6fe 100644 --- a/demo-player/src/main.rs +++ b/demo-player/src/main.rs @@ -143,9 +143,9 @@ fn main() { let mut markers = File::open("src/markers.json").expect("no file found"); let metadatamarkers = fs::metadata("src/markers.json").expect("unable to read metadata"); - let mut markersBuffer = vec![0; metadatamarkers.len() as usize]; - markers.read(&mut markersBuffer).expect("buffer overflow"); - let string = String::from_utf8(markersBuffer.clone()).unwrap(); + let mut markers_buffer = vec![0; metadatamarkers.len() as usize]; + markers.read(&mut markers_buffer).expect("buffer overflow"); + let string = String::from_utf8(markers_buffer.clone()).unwrap(); // lottie_player.load_animation_data(string.as_str(), WIDTH as u32, HEIGHT as u32); // println!("{:?}", Some(lottie_player.manifest())); diff --git a/dotlottie-rs/src/dotlottie_player.rs b/dotlottie-rs/src/dotlottie_player.rs index 35a3004e..229a0b9e 100644 --- a/dotlottie-rs/src/dotlottie_player.rs +++ b/dotlottie-rs/src/dotlottie_player.rs @@ -611,6 +611,8 @@ impl DotLottieRuntime { pub fn load_animation_data(&mut self, animation_data: &str, width: u32, height: u32) -> bool { self.active_animation_id.clear(); + self.active_theme_id.clear(); + self.dotlottie_manager = DotLottieManager::new(None).unwrap(); self.markers = extract_markers(animation_data); @@ -624,6 +626,8 @@ impl DotLottieRuntime { pub fn load_animation_path(&mut self, file_path: &str, width: u32, height: u32) -> bool { self.active_animation_id.clear(); + self.active_theme_id.clear(); + match fs::read_to_string(file_path) { Ok(data) => self.load_animation_data(&data, width, height), Err(_) => false, @@ -632,6 +636,8 @@ impl DotLottieRuntime { pub fn load_dotlottie_data(&mut self, file_data: &[u8], width: u32, height: u32) -> bool { self.active_animation_id.clear(); + self.active_theme_id.clear(); + if self.dotlottie_manager.init(file_data).is_err() { return false; } diff --git a/dotlottie-rs/tests/theming.rs b/dotlottie-rs/tests/theming.rs index 12d3137f..1222f2ec 100644 --- a/dotlottie-rs/tests/theming.rs +++ b/dotlottie-rs/tests/theming.rs @@ -5,6 +5,11 @@ use crate::test_utils::{HEIGHT, WIDTH}; #[cfg(test)] mod tests { + use std::{ + fs::{self, File}, + io::Read, + }; + use super::*; #[test] @@ -22,6 +27,7 @@ mod tests { ); assert!(player.load_dotlottie_data(include_bytes!("assets/test.lottie"), WIDTH, HEIGHT)); + assert!(player.active_theme_id().is_empty()); assert!(player.load_theme(valid_theme_id), "Expected theme to load"); assert_eq!(player.active_theme_id(), valid_theme_id); @@ -80,4 +86,57 @@ mod tests { assert!(player.load_theme(""), "Expected theme to unload"); } + + #[test] + #[ignore = "invalid memory reference"] + fn test_clear_active_theme_id_after_new_animation_data_loaded() { + let player = DotLottiePlayer::new(Config { + autoplay: true, + ..Config::default() + }); + + let valid_theme_id = "test_theme"; + + assert!( + !player.load_theme(valid_theme_id), + "Expected theme to not load" + ); + + assert!(player.load_dotlottie_data(include_bytes!("assets/test.lottie"), WIDTH, HEIGHT)); + + assert!(player.load_theme(valid_theme_id), "Expected theme to load"); + assert_eq!(player.active_theme_id(), valid_theme_id); + + let mut test_json_file = File::open("assets/test.json").expect("no file found"); + let metadata = fs::metadata("assets/test.json").expect("unable to read metadata"); + let mut buffer = vec![0; metadata.len() as usize]; + test_json_file.read(&mut buffer).expect("buffer overflow"); + let string = String::from_utf8(buffer.clone()).unwrap(); + + assert!(player.load_animation_data(&string, WIDTH, HEIGHT)); + assert!(player.active_theme_id().is_empty()); + + assert!(player.is_playing()); + } + + #[test] + fn test_clear_active_theme_id_after_new_dotlottie_loaded() { + let player = DotLottiePlayer::new(Config { + autoplay: true, + ..Config::default() + }); + + let valid_theme_id = "test_theme"; + + assert!(player.load_dotlottie_data(include_bytes!("assets/test.lottie"), WIDTH, HEIGHT)); + assert!(player.active_theme_id().is_empty()); + + assert!(player.load_theme(valid_theme_id), "Expected theme to load"); + assert_eq!(player.active_theme_id(), valid_theme_id); + + assert!(player.load_dotlottie_data(include_bytes!("assets/emoji.lottie"), WIDTH, HEIGHT)); + assert!(player.active_theme_id().is_empty()); + + assert!(player.is_playing()); + } } From fdb76ff984ad8f0c81ba6b9c1fad22e88d2f2d97 Mon Sep 17 00:00:00 2001 From: Gan Jun Kai Date: Wed, 10 Apr 2024 20:49:49 +0800 Subject: [PATCH 3/5] fix: fix file path error --- dotlottie-rs/tests/theming.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dotlottie-rs/tests/theming.rs b/dotlottie-rs/tests/theming.rs index 1222f2ec..cc7dfa93 100644 --- a/dotlottie-rs/tests/theming.rs +++ b/dotlottie-rs/tests/theming.rs @@ -88,8 +88,7 @@ mod tests { } #[test] - #[ignore = "invalid memory reference"] - fn test_clear_active_theme_id_after_new_animation_data_loaded() { + fn test_clear_active_theme_id_after_new_animation_data_is_loaded() { let player = DotLottiePlayer::new(Config { autoplay: true, ..Config::default() @@ -107,8 +106,8 @@ mod tests { assert!(player.load_theme(valid_theme_id), "Expected theme to load"); assert_eq!(player.active_theme_id(), valid_theme_id); - let mut test_json_file = File::open("assets/test.json").expect("no file found"); - let metadata = fs::metadata("assets/test.json").expect("unable to read metadata"); + let mut test_json_file = File::open("tests/assets/test.json").expect("no file found"); + let metadata = fs::metadata("tests/assets/test.json").expect("unable to read metadata"); let mut buffer = vec![0; metadata.len() as usize]; test_json_file.read(&mut buffer).expect("buffer overflow"); let string = String::from_utf8(buffer.clone()).unwrap(); @@ -120,7 +119,7 @@ mod tests { } #[test] - fn test_clear_active_theme_id_after_new_dotlottie_loaded() { + fn test_clear_active_theme_id_after_new_dotlottie_is_loaded() { let player = DotLottiePlayer::new(Config { autoplay: true, ..Config::default() From 62246b640c07eb87078d937174c8724c65aa1a7a Mon Sep 17 00:00:00 2001 From: Gan Jun Kai Date: Wed, 10 Apr 2024 20:52:17 +0800 Subject: [PATCH 4/5] test: add test for load_animation_path --- dotlottie-rs/tests/theming.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dotlottie-rs/tests/theming.rs b/dotlottie-rs/tests/theming.rs index cc7dfa93..546fbf52 100644 --- a/dotlottie-rs/tests/theming.rs +++ b/dotlottie-rs/tests/theming.rs @@ -8,6 +8,7 @@ mod tests { use std::{ fs::{self, File}, io::Read, + path::Path, }; use super::*; @@ -118,6 +119,31 @@ mod tests { assert!(player.is_playing()); } + #[test] + fn test_clear_active_theme_id_after_new_animation_path_is_loaded() { + let player = DotLottiePlayer::new(Config { + autoplay: true, + ..Config::default() + }); + + let valid_theme_id = "test_theme"; + + assert!( + !player.load_theme(valid_theme_id), + "Expected theme to not load" + ); + + assert!(player.load_dotlottie_data(include_bytes!("assets/test.lottie"), WIDTH, HEIGHT)); + + assert!(player.load_theme(valid_theme_id), "Expected theme to load"); + assert_eq!(player.active_theme_id(), valid_theme_id); + + assert!(player.load_animation_path("tests/assets/test.json", WIDTH, HEIGHT)); + assert!(player.active_theme_id().is_empty()); + + assert!(player.is_playing()); + } + #[test] fn test_clear_active_theme_id_after_new_dotlottie_is_loaded() { let player = DotLottiePlayer::new(Config { From 1f6e10c697915aa04cc9c07ae0c6b54462d76bd1 Mon Sep 17 00:00:00 2001 From: Gan Jun Kai Date: Wed, 10 Apr 2024 23:22:56 +0800 Subject: [PATCH 5/5] fix: use str::from_utf8 to read file --- dotlottie-rs/tests/theming.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/dotlottie-rs/tests/theming.rs b/dotlottie-rs/tests/theming.rs index 546fbf52..a2542002 100644 --- a/dotlottie-rs/tests/theming.rs +++ b/dotlottie-rs/tests/theming.rs @@ -107,13 +107,8 @@ mod tests { assert!(player.load_theme(valid_theme_id), "Expected theme to load"); assert_eq!(player.active_theme_id(), valid_theme_id); - let mut test_json_file = File::open("tests/assets/test.json").expect("no file found"); - let metadata = fs::metadata("tests/assets/test.json").expect("unable to read metadata"); - let mut buffer = vec![0; metadata.len() as usize]; - test_json_file.read(&mut buffer).expect("buffer overflow"); - let string = String::from_utf8(buffer.clone()).unwrap(); - - assert!(player.load_animation_data(&string, WIDTH, HEIGHT)); + let data = std::str::from_utf8(include_bytes!("assets/test.json")).expect("Invalid data."); + assert!(player.load_animation_data(data, WIDTH, HEIGHT)); assert!(player.active_theme_id().is_empty()); assert!(player.is_playing());