use std::cell::RefCell;
use crate::{
animation::{AnimationCell, CoreItemAnimation},
core_item::{AnyExtractCoreItem, CoreItem, mesh_item::MeshItem, vitem::VItem},
prelude::CameraFrame,
};
#[derive(Default)]
pub struct AnimationStore {
anims: RefCell<Vec<Box<dyn CoreItemAnimation>>>,
}
impl AnimationStore {
pub fn new() -> Self {
Self::default()
}
pub fn push_animation<T: AnyExtractCoreItem>(
&self,
anim: AnimationCell<T>,
) -> &AnimationCell<T> {
let boxed = Box::new(anim);
let ptr = Box::into_raw(boxed);
let boxed_concrete: Box<AnimationCell<T>> = unsafe { Box::from_raw(ptr) };
let boxed_trait: Box<dyn CoreItemAnimation> = boxed_concrete;
self.anims.borrow_mut().push(boxed_trait);
unsafe { &*ptr }
}
}
#[derive(Default, Clone)]
pub struct CoreItemStore {
pub camera_frame_ids: Vec<(usize, usize)>,
pub camera_frames: Vec<CameraFrame>,
pub vitem_ids: Vec<(usize, usize)>,
pub vitems: Vec<VItem>,
pub mesh_item_ids: Vec<(usize, usize)>,
pub mesh_items: Vec<MeshItem>,
}
impl CoreItemStore {
pub fn new() -> Self {
Self::default()
}
pub fn update(&mut self, items: impl Iterator<Item = ((usize, usize), CoreItem)>) {
self.camera_frame_ids.clear();
self.camera_frames.clear();
self.vitem_ids.clear();
self.vitems.clear();
self.mesh_item_ids.clear();
self.mesh_items.clear();
for (id, item) in items {
match item {
CoreItem::CameraFrame(x) => {
self.camera_frame_ids.push(id);
self.camera_frames.push(x);
}
CoreItem::VItem(x) => {
self.vitem_ids.push(id);
self.vitems.push(x);
}
CoreItem::MeshItem(x) => {
self.mesh_item_ids.push(id);
self.mesh_items.push(x);
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_animation_store() {
use crate::animation::Eval;
use std::marker::PhantomData;
#[derive(Default)]
struct A<T: Default> {
_phantom: PhantomData<T>,
}
impl<T: Default> Eval<T> for A<T> {
fn eval_alpha(&self, _alpha: f64) -> T {
T::default()
}
}
let store = AnimationStore::new();
let anim = store.push_animation(A::<VItem>::default().into_animation_cell());
assert_eq!(anim.eval_alpha(0.0), VItem::default());
assert_eq!(
anim.eval_alpha_core_item(0.0),
vec![CoreItem::VItem(VItem::default())]
);
drop(store);
}
}