use crate::application_io::TextureFrameTable; use crate::raster::Pixel; use crate::raster::image::{Image, ImageFrameTable}; use crate::transform::{Transform, TransformMut}; use crate::uuid::NodeId; use crate::vector::VectorDataTable; use crate::{AlphaBlending, GraphicElement, RasterFrame}; use dyn_any::StaticType; use glam::DAffine2; use std::hash::Hash; #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct Instances { #[serde(alias = "instances")] instance: Vec, #[serde(default = "one_daffine2_default")] transform: Vec, #[serde(default = "one_alpha_blending_default")] alpha_blending: Vec, #[serde(default = "one_source_node_id_default")] source_node_id: Vec>, } impl Instances { pub fn new(instance: T) -> Self { Self { instance: vec![instance], transform: vec![DAffine2::IDENTITY], alpha_blending: vec![AlphaBlending::default()], source_node_id: vec![None], } } pub fn empty() -> Self { Self { instance: Vec::new(), transform: Vec::new(), alpha_blending: Vec::new(), source_node_id: Vec::new(), } } pub fn push(&mut self, instance: T) -> InstanceMut { self.instance.push(instance); self.transform.push(DAffine2::IDENTITY); self.alpha_blending.push(AlphaBlending::default()); self.source_node_id.push(None); InstanceMut { instance: self.instance.last_mut().expect("Shouldn't be empty"), transform: self.transform.last_mut().expect("Shouldn't be empty"), alpha_blending: self.alpha_blending.last_mut().expect("Shouldn't be empty"), source_node_id: self.source_node_id.last_mut().expect("Shouldn't be empty"), } } pub fn push_instance(&mut self, instance: Instance) -> InstanceMut where T: Clone, { self.instance.push(instance.instance.clone()); self.transform.push(*instance.transform); self.alpha_blending.push(*instance.alpha_blending); self.source_node_id.push(*instance.source_node_id); InstanceMut { instance: self.instance.last_mut().expect("Shouldn't be empty"), transform: self.transform.last_mut().expect("Shouldn't be empty"), alpha_blending: self.alpha_blending.last_mut().expect("Shouldn't be empty"), source_node_id: self.source_node_id.last_mut().expect("Shouldn't be empty"), } } pub fn one_instance(&self) -> Instance { Instance { instance: self.instance.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())), transform: self.transform.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())), alpha_blending: self.alpha_blending.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())), source_node_id: self.source_node_id.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())), } } pub fn one_instance_mut(&mut self) -> InstanceMut { let length = self.instance.len(); InstanceMut { instance: self.instance.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)), transform: self.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)), alpha_blending: self.alpha_blending.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)), source_node_id: self.source_node_id.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)), } } pub fn instances(&self) -> impl DoubleEndedIterator> { self.instance .iter() .zip(self.transform.iter()) .zip(self.alpha_blending.iter()) .zip(self.source_node_id.iter()) .map(|(((instance, transform), alpha_blending), source_node_id)| Instance { instance, transform, alpha_blending, source_node_id, }) } pub fn instances_mut(&mut self) -> impl DoubleEndedIterator> { self.instance .iter_mut() .zip(self.transform.iter_mut()) .zip(self.alpha_blending.iter_mut()) .zip(self.source_node_id.iter_mut()) .map(|(((instance, transform), alpha_blending), source_node_id)| InstanceMut { instance, transform, alpha_blending, source_node_id, }) } pub fn get(&self, index: usize) -> Option> { if index >= self.instance.len() { return None; } Some(Instance { instance: &self.instance[index], transform: &self.transform[index], alpha_blending: &self.alpha_blending[index], source_node_id: &self.source_node_id[index], }) } pub fn get_mut(&mut self, index: usize) -> Option> { if index >= self.instance.len() { return None; } Some(InstanceMut { instance: &mut self.instance[index], transform: &mut self.transform[index], alpha_blending: &mut self.alpha_blending[index], source_node_id: &mut self.source_node_id[index], }) } pub fn len(&self) -> usize { self.instance.len() } pub fn is_empty(&self) -> bool { self.instance.is_empty() } } impl Default for Instances { fn default() -> Self { // TODO: Remove once all types have been converted to tables let converted_to_tables = [TypeId::of::(), TypeId::of::()]; use core::any::TypeId; if converted_to_tables.contains(&TypeId::of::()) { // TODO: Remove the 'static trait bound when this special casing is removed by making all types return empty Self::empty() } else { Self::new(T::default()) } } } impl core::hash::Hash for Instances { fn hash(&self, state: &mut H) { for instance in &self.instance { instance.hash(state); } } } impl PartialEq for Instances { fn eq(&self, other: &Self) -> bool { self.instance.len() == other.instance.len() && { self.instance.iter().zip(other.instance.iter()).all(|(a, b)| a == b) } } } #[cfg(feature = "dyn-any")] unsafe impl StaticType for Instances { type Static = Instances; } fn one_daffine2_default() -> Vec { vec![DAffine2::IDENTITY] } fn one_alpha_blending_default() -> Vec { vec![AlphaBlending::default()] } fn one_source_node_id_default() -> Vec> { vec![None] } #[derive(Copy, Clone, Debug)] pub struct Instance<'a, T> { pub instance: &'a T, pub transform: &'a DAffine2, pub alpha_blending: &'a AlphaBlending, pub source_node_id: &'a Option, } #[derive(Debug)] pub struct InstanceMut<'a, T> { pub instance: &'a mut T, pub transform: &'a mut DAffine2, pub alpha_blending: &'a mut AlphaBlending, pub source_node_id: &'a mut Option, } // VECTOR DATA TABLE impl Transform for VectorDataTable { fn transform(&self) -> DAffine2 { *self.one_instance().transform } } impl TransformMut for VectorDataTable { fn transform_mut(&mut self) -> &mut DAffine2 { self.one_instance_mut().transform } } // TEXTURE FRAME TABLE impl Transform for TextureFrameTable { fn transform(&self) -> DAffine2 { *self.one_instance().transform } } impl TransformMut for TextureFrameTable { fn transform_mut(&mut self) -> &mut DAffine2 { self.one_instance_mut().transform } } // IMAGE FRAME TABLE impl Transform for ImageFrameTable

where GraphicElement: From>, { fn transform(&self) -> DAffine2 { *self.one_instance().transform } } impl TransformMut for ImageFrameTable

where GraphicElement: From>, { fn transform_mut(&mut self) -> &mut DAffine2 { self.one_instance_mut().transform } } // RASTER FRAME impl Transform for RasterFrame { fn transform(&self) -> DAffine2 { match self { RasterFrame::ImageFrame(image_frame) => image_frame.transform(), RasterFrame::TextureFrame(texture_frame) => texture_frame.transform(), } } } impl TransformMut for RasterFrame { fn transform_mut(&mut self) -> &mut DAffine2 { match self { RasterFrame::ImageFrame(image_frame) => image_frame.transform_mut(), RasterFrame::TextureFrame(texture_frame) => texture_frame.transform_mut(), } } }