Skip to content

Commit

Permalink
wip: multi animation support
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelOsborne committed Jan 12, 2024
1 parent ce90be3 commit d73b9c4
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 100 deletions.
4 changes: 3 additions & 1 deletion dotlottie-ffi/src/dotlottie_player.udl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ interface DotLottiePlayer {
void frame(f32 no);
boolean load_animation([ByRef] string animation_data, u32 width, u32 height);
boolean load_animation_from_path([ByRef] string path, u32 width, u32 height);
boolean load_dotlottie([ByRef] bytes file_data);
boolean load_dotlottie([ByRef] bytes file_data, u32 width, u32 height);
boolean next_animation(u32 width, u32 height);
boolean previous_animation(u32 width, u32 height);
void clear();
i64 get_buffer();
i64 get_buffer_size();
Expand Down
147 changes: 81 additions & 66 deletions dotlottie-fms/src/dolottie_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub struct DotLottieManager {
manifest: Manifest,
zip_data: Vec<u8>,
animation_settings_cache: HashMap<String, ManifestAnimation>,
animation_data_cache: HashMap<String, String>,
}

impl DotLottieManager {
Expand All @@ -29,57 +30,20 @@ impl DotLottieManager {
manifest,
zip_data: dotlottie,
animation_settings_cache: HashMap::new(),
animation_data_cache: HashMap::new(),
}
} else {
DotLottieManager {
current_animation_id: String::new(),
manifest: Manifest::new(),
zip_data: vec![],
animation_settings_cache: HashMap::new(),
animation_data_cache: HashMap::new(),
}
}

// // Initialize the manager with the dotLottie file
// let manifest = get_manifest(&dotlottie).unwrap();
// let mut id = String::new();

// if let Some(first_animation) = &manifest.active_animation_id {
// id = first_animation.clone();
// } else if let Ok(animations) = manifest.animations.lock() {
// id = animations.index(0).id.clone();
// } else {
// panic!("No animations found in dotLottie file");
// }

// DotLottieManager {
// current_animation_id: String::new(),
// manifest: Manifest::new(),
// zip_data: vec![],
// animation_settings_cache: HashMap::new(),
// }
}

// pub fn new() -> Self {
// Initialize the manager with the dotLottie file
// let manifest = get_manifest(&dotlottie).unwrap();
// let mut id = String::new();

// if let Some(first_animation) = &manifest.active_animation_id {
// id = first_animation.clone();
// } else if let Ok(animations) = manifest.animations.lock() {
// id = animations.index(0).id.clone();
// } else {
// panic!("No animations found in dotLottie file");
// }
// DotLottieManager {
// current_animation_id: String::new(),
// manifest: Manifest::new(),
// zip_data: vec![],
// animation_settings_cache: HashMap::new(),
// }
// }

pub fn init(dotlottie: Vec<u8>) -> Self {
pub fn init(&mut self, dotlottie: Vec<u8>) {
// Initialize the manager with the dotLottie file
let manifest = get_manifest(&dotlottie).unwrap();
let mut id = String::new();
Expand All @@ -92,49 +56,75 @@ impl DotLottieManager {
panic!("No animations found in dotLottie file");
}

DotLottieManager {
current_animation_id: id,
manifest,
zip_data: dotlottie,
animation_settings_cache: HashMap::new(),
}
self.current_animation_id = id;
self.manifest = manifest;
self.zip_data = dotlottie;
}

/// Advances to the next animation and returns it's animation data as a string.
pub fn next_animation(&mut self) -> Result<String, DotLottieError> {
let mut i = 0;
let mut new_current_animation_id = self.current_animation_id.clone();
let animations = self.manifest.animations.lock().unwrap();

if let Ok(animations) = self.manifest.animations.lock() {
for anim in animations.iter() {
if anim.id == self.current_animation_id {
// return Result::Ok(true);
if i + 1 < animations.len() {
self.current_animation_id = animations[i + 1].id.clone();
}
// match animations {
// Ok(animations) => {
for anim in animations.iter() {
println!("Animation ID {}", anim.id);

if anim.id == self.current_animation_id {
// return Result::Ok(true);
if i + 1 < animations.len() {
self.current_animation_id = animations[i + 1].id.clone();

new_current_animation_id = animations[i + 1].id.clone();
std::mem::drop(animations);

println!("Found next animation : {}", new_current_animation_id);

return self.get_animation(&new_current_animation_id);
}
i += 1;
}
i += 1;
}

self.get_animation(&self.current_animation_id)
std::mem::drop(animations);

let current_animation_id = self.current_animation_id.clone();

return self.get_animation(&current_animation_id);
}

/// Reverses to the previous animation and returns it's animation data as a string.
pub fn previous_animation(&mut self) -> Result<String, DotLottieError> {
if let Ok(animations) = self.manifest.animations.lock() {
let mut i = animations.len();
let mut new_current_animation_id = self.current_animation_id.clone();
let animations = self.manifest.animations.lock().unwrap();
let mut i = 0;

for anim in animations.iter() {
if anim.id == self.current_animation_id {
if i - 1 > 0 {
self.current_animation_id = animations[i + 1].id.clone();
}
for anim in animations.iter() {
println!("Animation ID {}", anim.id);

if anim.id == self.current_animation_id {
// return Result::Ok(true);
if i > 0 {
self.current_animation_id = animations[i - 1].id.clone();

new_current_animation_id = animations[i - 1].id.clone();
std::mem::drop(animations);

println!("Found next animation : {}", new_current_animation_id);

return self.get_animation(&new_current_animation_id);
}
i -= 1;
}
i += 1;
}
std::mem::drop(animations);

self.get_animation(&self.current_animation_id)
let current_animation_id = self.current_animation_id.clone();

println!("PREVIOUS ANIMATION ID {}", current_animation_id);
self.get_animation(&current_animation_id)
}

/// Returns the playback settings for the animation with the given ID.
Expand Down Expand Up @@ -177,6 +167,12 @@ impl DotLottieManager {
return Result::Err(DotLottieError::MutexLockError);
}

pub fn get_current_animation(&mut self) -> Result<String, DotLottieError> {
let current_animation_id = self.current_animation_id.clone();

self.get_animation(&current_animation_id)
}

pub fn current_animation_playback_settings(
&mut self,
) -> Result<ManifestAnimation, DotLottieError> {
Expand All @@ -185,8 +181,27 @@ impl DotLottieManager {
self.get_playback_settings(&animation_id)
}

pub fn get_animation(&self, animation_id: &str) -> Result<String, DotLottieError> {
crate::get_animation(&self.zip_data, animation_id)
/// Returns the animation data for the animation with the given ID.
/// Memoizes the animation data in a HashMap for faster access.
pub fn get_animation(&mut self, animation_id: &str) -> Result<String, DotLottieError> {
if let Some(animation) = self.animation_data_cache.get(animation_id) {
let cloned_animation = animation.clone(); // Clone the value

return Result::Ok(cloned_animation);
} else {
let animation = crate::get_animation(&self.zip_data, animation_id);

if let Ok(animation) = animation {
self.animation_data_cache
.insert(animation_id.to_string().clone(), animation.clone());

return Result::Ok(animation);
} else {
return Result::Err(DotLottieError::AnimationNotFound {
animation_id: animation_id.to_string(),
});
}
}
}

pub fn get_animations(&self) -> Result<Vec<Animation>, DotLottieError> {
Expand Down
10 changes: 10 additions & 0 deletions dotlottie-fms/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,13 @@ pub fn get_manifest(bytes: &Vec<u8>) -> Result<Manifest, DotLottieError> {

Ok(manifest)
}

/// Get the width and height of a dotLottie file.
pub fn get_width_height(animation_data: &str) -> (u32, u32) {
let lottie_animation: Value = serde_json::from_str(animation_data).unwrap();

let width = lottie_animation["w"].as_u64().unwrap() as u32;
let height = lottie_animation["h"].as_u64().unwrap() as u32;

(width, height)
}
Loading

0 comments on commit d73b9c4

Please sign in to comment.