1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
/* * // Copyright (c) 2021 Feng Yang * // * // I am making my contributions/submissions to this project solely in my * // personal capacity and am not conveying any rights to any intellectual * // property of any third parties. */ use std::sync::{RwLock, Arc}; use log::info; use std::time::SystemTime; /// /// # Representation of an animation frame. /// /// This struct holds current animation frame index and frame interval in /// seconds. /// #[derive(Clone)] pub struct Frame { /// Frame index. pub index: isize, /// Time interval in seconds between two adjacent frames. pub time_interval_in_seconds: f64, } impl Frame { /// Constructs Frame instance with 1/60 seconds time interval. pub fn new_default() -> Frame { return Frame { index: 0, time_interval_in_seconds: 1.0 / 60.0, }; } /// Constructs Frame instance with given time interval. pub fn new(new_index: isize, new_time_interval_in_seconds: f64) -> Frame { return Frame { index: new_index, time_interval_in_seconds: new_time_interval_in_seconds, }; } /// Returns the elapsed time in seconds. pub fn time_in_seconds(&self) -> f64 { return self.index as f64 * self.time_interval_in_seconds; } /// Advances single frame. pub fn advance_single(&mut self) { self.index += 1; } /// Advances multiple frames. /// - parameter: delta Number of frames to advance. pub fn advance_multi(&mut self, delta: isize) { self.index += delta; } } //-------------------------------------------------------------------------------------------------- /// /// # Abstract base class for animation-related class. /// /// This class represents the animation logic in very abstract level. /// Generally animation is a function of time and/or its previous state. /// This base class provides a virtual function update() which can be /// overridden by its sub-classes to implement their own state update logic. /// pub trait Animation { /// /// ## Updates animation state for given frame. /// /// This function updates animation state by calling Animation::on_update /// function. /// fn update(&mut self, frame: &Frame) { let now = SystemTime::now(); info!("Begin updating frame: {} timeIntervalInSeconds: {} (1/{}) seconds", frame.index, frame.time_interval_in_seconds, 1.0 / frame.time_interval_in_seconds); self.on_update(frame); info!("End updating frame (took {} seconds)", now.elapsed().unwrap().as_secs_f64()); } /// /// ## The implementation of this function should update the animation state for given Frame instance **frame**. /// /// This function is called from Animation::update when state of this class /// instance needs to be updated. Thus, the inherited class should override /// this function and implement its logic for updating the animation state. /// fn on_update(&mut self, frame: &Frame); } /// Shared pointer for the Animation type. pub type AnimationPtr = Arc<RwLock<dyn Animation>>;