mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 23:48:11 +08:00
Instance tables refactor part 4: replace ArtboardGroups with multi-row Instances<Artboard> (#2265)
* Clean up dyn_any usages * Migrate ArtboardGroup to ArtboardGroupTable (not yet flattened) * Reorder graphical data imports * Flatten and remove ArtboardGroup in favor of ArtboardGroupTable * Fix test
This commit is contained in:
@@ -2,18 +2,17 @@ use crate::application_io::{ImageTexture, TextureFrameTable};
|
||||
use crate::raster::image::{Image, ImageFrameTable};
|
||||
use crate::raster::Pixel;
|
||||
use crate::transform::{Transform, TransformMut};
|
||||
use crate::uuid::NodeId;
|
||||
use crate::vector::{InstanceId, VectorData, VectorDataTable};
|
||||
use crate::{AlphaBlending, GraphicElement, GraphicGroup, GraphicGroupTable, RasterFrame};
|
||||
|
||||
use dyn_any::StaticType;
|
||||
|
||||
use glam::{DAffine2, DVec2};
|
||||
use std::hash::Hash;
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Instances<T>
|
||||
where
|
||||
T: Into<GraphicElement> + StaticType + 'static,
|
||||
{
|
||||
pub struct Instances<T> {
|
||||
id: Vec<InstanceId>,
|
||||
#[serde(alias = "instances")]
|
||||
instance: Vec<T>,
|
||||
@@ -21,15 +20,44 @@ where
|
||||
transform: Vec<DAffine2>,
|
||||
#[serde(default = "one_alpha_blending_default")]
|
||||
alpha_blending: Vec<AlphaBlending>,
|
||||
#[serde(default = "one_source_node_id_default")]
|
||||
source_node_id: Vec<Option<NodeId>>,
|
||||
}
|
||||
|
||||
impl<T: Into<GraphicElement> + StaticType + 'static> Instances<T> {
|
||||
impl<T> Instances<T> {
|
||||
pub fn new(instance: T) -> Self {
|
||||
Self {
|
||||
id: vec![InstanceId::generate()],
|
||||
instance: vec![instance],
|
||||
transform: vec![DAffine2::IDENTITY],
|
||||
alpha_blending: vec![AlphaBlending::default()],
|
||||
source_node_id: vec![None],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
id: Vec::new(),
|
||||
instance: Vec::new(),
|
||||
transform: Vec::new(),
|
||||
alpha_blending: Vec::new(),
|
||||
source_node_id: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(&mut self, instance: T) -> InstanceMut<T> {
|
||||
self.id.push(InstanceId::generate());
|
||||
self.instance.push(instance);
|
||||
self.transform.push(DAffine2::IDENTITY);
|
||||
self.alpha_blending.push(AlphaBlending::default());
|
||||
self.source_node_id.push(None);
|
||||
|
||||
InstanceMut {
|
||||
id: self.id.last_mut().expect("Shouldn't be empty"),
|
||||
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"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +67,7 @@ impl<T: Into<GraphicElement> + StaticType + 'static> Instances<T> {
|
||||
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())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,47 +79,52 @@ impl<T: Into<GraphicElement> + StaticType + 'static> Instances<T> {
|
||||
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 Iterator<Item = Instance<T>> {
|
||||
assert!(self.instance.len() == 1, "ONE INSTANCE EXPECTED, FOUND {} (instances)", self.instance.len());
|
||||
// assert!(self.instance.len() == 1, "ONE INSTANCE EXPECTED, FOUND {} (instances)", self.instance.len());
|
||||
self.id
|
||||
.iter()
|
||||
.zip(self.instance.iter())
|
||||
.zip(self.transform.iter())
|
||||
.zip(self.alpha_blending.iter())
|
||||
.map(|(((id, instance), transform), alpha_blending)| Instance {
|
||||
.zip(self.source_node_id.iter())
|
||||
.map(|((((id, instance), transform), alpha_blending), source_node_id)| Instance {
|
||||
id,
|
||||
instance,
|
||||
transform,
|
||||
alpha_blending,
|
||||
source_node_id,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn instances_mut(&mut self) -> impl Iterator<Item = InstanceMut<T>> {
|
||||
assert!(self.instance.len() == 1, "ONE INSTANCE EXPECTED, FOUND {} (instances_mut)", self.instance.len());
|
||||
// assert!(self.instance.len() == 1, "ONE INSTANCE EXPECTED, FOUND {} (instances_mut)", self.instance.len());
|
||||
self.id
|
||||
.iter_mut()
|
||||
.zip(self.instance.iter_mut())
|
||||
.zip(self.transform.iter_mut())
|
||||
.zip(self.alpha_blending.iter_mut())
|
||||
.map(|(((id, instance), transform), alpha_blending)| InstanceMut {
|
||||
.zip(self.source_node_id.iter_mut())
|
||||
.map(|((((id, instance), transform), alpha_blending), source_node_id)| InstanceMut {
|
||||
id,
|
||||
instance,
|
||||
transform,
|
||||
alpha_blending,
|
||||
source_node_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<GraphicElement> + Default + Hash + StaticType + 'static> Default for Instances<T> {
|
||||
impl<T: Default + Hash> Default for Instances<T> {
|
||||
fn default() -> Self {
|
||||
Self::new(T::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<GraphicElement> + Hash + StaticType + 'static> core::hash::Hash for Instances<T> {
|
||||
impl<T: Hash> core::hash::Hash for Instances<T> {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
self.id.hash(state);
|
||||
for instance in &self.instance {
|
||||
@@ -99,13 +133,14 @@ impl<T: Into<GraphicElement> + Hash + StaticType + 'static> core::hash::Hash for
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<GraphicElement> + PartialEq + StaticType + 'static> PartialEq for Instances<T> {
|
||||
impl<T: PartialEq> PartialEq for Instances<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id && self.instance.len() == other.instance.len() && { self.instance.iter().zip(other.instance.iter()).all(|(a, b)| a == b) }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Into<GraphicElement> + StaticType + 'static> dyn_any::StaticType for Instances<T> {
|
||||
#[cfg(feature = "dyn-any")]
|
||||
unsafe impl<T: StaticType + 'static> StaticType for Instances<T> {
|
||||
type Static = Instances<T>;
|
||||
}
|
||||
|
||||
@@ -115,6 +150,9 @@ fn one_daffine2_default() -> Vec<DAffine2> {
|
||||
fn one_alpha_blending_default() -> Vec<AlphaBlending> {
|
||||
vec![AlphaBlending::default()]
|
||||
}
|
||||
fn one_source_node_id_default() -> Vec<Option<NodeId>> {
|
||||
vec![None]
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Instance<'a, T> {
|
||||
@@ -122,6 +160,7 @@ pub struct Instance<'a, T> {
|
||||
pub instance: &'a T,
|
||||
pub transform: &'a DAffine2,
|
||||
pub alpha_blending: &'a AlphaBlending,
|
||||
pub source_node_id: &'a Option<NodeId>,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct InstanceMut<'a, T> {
|
||||
@@ -129,6 +168,7 @@ 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<NodeId>,
|
||||
}
|
||||
|
||||
// GRAPHIC ELEMENT
|
||||
@@ -235,8 +275,6 @@ impl<P: Pixel> TransformMut for InstanceMut<'_, Image<P>> {
|
||||
// IMAGE FRAME TABLE
|
||||
impl<P: Pixel> Transform for ImageFrameTable<P>
|
||||
where
|
||||
P: dyn_any::StaticType,
|
||||
P::Static: Pixel,
|
||||
GraphicElement: From<Image<P>>,
|
||||
{
|
||||
fn transform(&self) -> DAffine2 {
|
||||
@@ -245,8 +283,6 @@ where
|
||||
}
|
||||
impl<P: Pixel> TransformMut for ImageFrameTable<P>
|
||||
where
|
||||
P: dyn_any::StaticType,
|
||||
P::Static: Pixel,
|
||||
GraphicElement: From<Image<P>>,
|
||||
{
|
||||
fn transform_mut(&mut self) -> &mut DAffine2 {
|
||||
|
||||
Reference in New Issue
Block a user