use crate::AlphaBlending; use crate::uuid::NodeId; 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 push(&mut self, instance: Instance) { self.instance.push(instance.instance); self.transform.push(instance.transform); self.alpha_blending.push(instance.alpha_blending); self.source_node_id.push(instance.source_node_id); } pub fn extend(&mut self, instances: Instances) { self.instance.extend(instances.instance); self.transform.extend(instances.transform); self.alpha_blending.extend(instances.alpha_blending); self.source_node_id.extend(instances.source_node_id); } pub fn instance_iter(self) -> impl DoubleEndedIterator> { self.instance .into_iter() .zip(self.transform) .zip(self.alpha_blending) .zip(self.source_node_id) .map(|(((instance, transform), alpha_blending), source_node_id)| Instance { instance, transform, alpha_blending, source_node_id, }) } pub fn instance_ref_iter(&self) -> impl DoubleEndedIterator> + Clone { 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)| InstanceRef { instance, transform, alpha_blending, source_node_id, }) } pub fn instance_mut_iter(&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(InstanceRef { 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 { Self { instance: Vec::new(), transform: Vec::new(), alpha_blending: Vec::new(), source_node_id: Vec::new(), } } } impl 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) } } } 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, PartialEq)] pub struct InstanceRef<'a, T> { pub instance: &'a T, pub transform: &'a DAffine2, pub alpha_blending: &'a AlphaBlending, pub source_node_id: &'a Option, } impl InstanceRef<'_, T> { pub fn to_instance_cloned(self) -> Instance where T: Clone, { Instance { instance: self.instance.clone(), transform: *self.transform, alpha_blending: *self.alpha_blending, source_node_id: *self.source_node_id, } } } #[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, } #[derive(Copy, Clone, Default, Debug, PartialEq, serde::Serialize, serde::Deserialize)] pub struct Instance { pub instance: T, pub transform: DAffine2, pub alpha_blending: AlphaBlending, pub source_node_id: Option, } impl Instance { pub fn to_graphic_element(self) -> Instance where T: Into, { Instance { instance: self.instance.into(), transform: self.transform, alpha_blending: self.alpha_blending, source_node_id: self.source_node_id, } } pub fn to_instance_ref(&self) -> InstanceRef<'_, T> { InstanceRef { instance: &self.instance, transform: &self.transform, alpha_blending: &self.alpha_blending, source_node_id: &self.source_node_id, } } pub fn to_instance_mut(&mut self) -> InstanceMut<'_, T> { InstanceMut { instance: &mut self.instance, transform: &mut self.transform, alpha_blending: &mut self.alpha_blending, source_node_id: &mut self.source_node_id, } } pub fn to_table(self) -> Instances { Instances { instance: vec![self.instance], transform: vec![self.transform], alpha_blending: vec![self.alpha_blending], source_node_id: vec![self.source_node_id], } } }