Instance tables refactor part 1: wrap graphical data in the new Instances<T> struct (#2230)

* Port VectorData to Instances<VectorData>

* Port ImageFrame<P> and TextureFrame to Instances<ImageFrame<P>> and Instances<TextureFrame>

* Avoid mutation with the TransformMut trait

* Port GraphicGroup to Instances<GraphicGroup>

* It compiles!

* Organize debugging

* Document upgrading

* Fix Brush node

* Restore TransformMut in lieu of TransformSet trait

* Fix tests

* Final code review
This commit is contained in:
Keavon Chambers
2025-01-28 23:51:12 -08:00
committed by GitHub
parent 408f9bffa1
commit eb0ff20d3c
43 changed files with 1855 additions and 1221 deletions

View File

@@ -1,8 +1,9 @@
use crate::application_io::TextureFrame;
use crate::application_io::{TextureFrame, TextureFrameTable};
use crate::raster::bbox::AxisAlignedBbox;
use crate::raster::{ImageFrame, Pixel};
use crate::vector::VectorData;
use crate::{Artboard, ArtboardGroup, Color, GraphicElement, GraphicGroup};
use crate::raster::image::{ImageFrame, ImageFrameTable};
use crate::raster::Pixel;
use crate::vector::{VectorData, VectorDataTable};
use crate::{Artboard, ArtboardGroup, Color, GraphicElement, GraphicGroup, GraphicGroupTable};
use glam::{DAffine2, DVec2};
@@ -19,12 +20,6 @@ pub trait Transform {
}
}
impl<T: Transform> Transform for &T {
fn transform(&self) -> DAffine2 {
(*self).transform()
}
}
pub trait TransformMut: Transform {
fn transform_mut(&mut self) -> &mut DAffine2;
fn translate(&mut self, offset: DVec2) {
@@ -32,6 +27,14 @@ pub trait TransformMut: Transform {
}
}
// Implementation for references to anything that implements Transform
impl<T: Transform> Transform for &T {
fn transform(&self) -> DAffine2 {
(*self).transform()
}
}
// Implementations for ImageFrame<P>
impl<P: Pixel> Transform for ImageFrame<P> {
fn transform(&self) -> DAffine2 {
self.transform
@@ -45,6 +48,54 @@ impl<P: Pixel> TransformMut for ImageFrame<P> {
&mut self.transform
}
}
// Implementations for ImageFrameTable<P>
impl<P: Pixel> Transform for ImageFrameTable<P>
where
P: dyn_any::StaticType,
P::Static: Pixel,
GraphicElement: From<ImageFrame<P>>,
{
fn transform(&self) -> DAffine2 {
let image_frame = self.one_item();
image_frame.transform
}
fn local_pivot(&self, pivot: DVec2) -> DVec2 {
let image_frame = self.one_item();
image_frame.local_pivot(pivot)
}
}
impl<P: Pixel> TransformMut for ImageFrameTable<P>
where
P: dyn_any::StaticType,
P::Static: Pixel,
GraphicElement: From<ImageFrame<P>>,
{
fn transform_mut(&mut self) -> &mut DAffine2 {
let image_frame = self.one_item_mut();
&mut image_frame.transform
}
}
// Implementations for TextureTable
impl Transform for TextureFrameTable {
fn transform(&self) -> DAffine2 {
let image_frame = self.one_item();
image_frame.transform
}
fn local_pivot(&self, pivot: DVec2) -> DVec2 {
let image_frame = self.one_item();
image_frame.local_pivot(pivot)
}
}
impl TransformMut for TextureFrameTable {
fn transform_mut(&mut self) -> &mut DAffine2 {
let image_frame = self.one_item_mut();
&mut image_frame.transform
}
}
// Implementations for GraphicGroup
impl Transform for GraphicGroup {
fn transform(&self) -> DAffine2 {
self.transform
@@ -55,19 +106,35 @@ impl TransformMut for GraphicGroup {
&mut self.transform
}
}
// Implementations for GraphicGroupTable
impl Transform for GraphicGroupTable {
fn transform(&self) -> DAffine2 {
let graphic_group = self.one_item();
graphic_group.transform
}
}
impl TransformMut for GraphicGroupTable {
fn transform_mut(&mut self) -> &mut DAffine2 {
let graphic_group = self.one_item_mut();
&mut graphic_group.transform
}
}
// Implementations for GraphicElement
impl Transform for GraphicElement {
fn transform(&self) -> DAffine2 {
match self {
GraphicElement::VectorData(vector_shape) => vector_shape.transform(),
GraphicElement::GraphicGroup(graphic_group) => graphic_group.transform(),
GraphicElement::Raster(raster) => raster.transform(),
GraphicElement::RasterFrame(raster) => raster.transform(),
}
}
fn local_pivot(&self, pivot: DVec2) -> DVec2 {
match self {
GraphicElement::VectorData(vector_shape) => vector_shape.local_pivot(pivot),
GraphicElement::GraphicGroup(graphic_group) => graphic_group.local_pivot(pivot),
GraphicElement::Raster(raster) => raster.local_pivot(pivot),
GraphicElement::RasterFrame(raster) => raster.local_pivot(pivot),
}
}
}
@@ -76,11 +143,12 @@ impl TransformMut for GraphicElement {
match self {
GraphicElement::VectorData(vector_shape) => vector_shape.transform_mut(),
GraphicElement::GraphicGroup(graphic_group) => graphic_group.transform_mut(),
GraphicElement::Raster(raster) => raster.transform_mut(),
GraphicElement::RasterFrame(raster) => raster.transform_mut(),
}
}
}
// Implementations for VectorData
impl Transform for VectorData {
fn transform(&self) -> DAffine2 {
self.transform
@@ -95,6 +163,25 @@ impl TransformMut for VectorData {
}
}
// Implementations for VectorDataTable
impl Transform for VectorDataTable {
fn transform(&self) -> DAffine2 {
let vector_data = self.one_item();
vector_data.transform
}
fn local_pivot(&self, pivot: DVec2) -> DVec2 {
let vector_data = self.one_item();
vector_data.local_pivot(pivot)
}
}
impl TransformMut for VectorDataTable {
fn transform_mut(&mut self) -> &mut DAffine2 {
let vector_data = self.one_item_mut();
&mut vector_data.transform
}
}
// Implementations for Artboard
impl Transform for Artboard {
fn transform(&self) -> DAffine2 {
DAffine2::from_translation(self.location.as_dvec2())
@@ -104,6 +191,7 @@ impl Transform for Artboard {
}
}
// Implementations for DAffine2
impl Transform for DAffine2 {
fn transform(&self) -> DAffine2 {
*self
@@ -115,6 +203,18 @@ impl TransformMut for DAffine2 {
}
}
// Implementations for Footprint
impl Transform for Footprint {
fn transform(&self) -> DAffine2 {
self.transform
}
}
impl TransformMut for Footprint {
fn transform_mut(&mut self) -> &mut DAffine2 {
&mut self.transform
}
}
#[derive(Debug, Clone, Copy, dyn_any::DynAny, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum RenderQuality {
@@ -177,7 +277,7 @@ impl From<()> for Footprint {
}
#[node_macro::node(category("Debug"))]
fn cull<T>(_footprint: Footprint, #[implementations(VectorData, GraphicGroup, Artboard, ImageFrame<Color>, ArtboardGroup)] data: T) -> T {
fn cull<T>(_footprint: Footprint, #[implementations(VectorDataTable, GraphicGroupTable, Artboard, ImageFrameTable<Color>, ArtboardGroup)] data: T) -> T {
data
}
@@ -188,17 +288,6 @@ impl core::hash::Hash for Footprint {
}
}
impl Transform for Footprint {
fn transform(&self) -> DAffine2 {
self.transform
}
}
impl TransformMut for Footprint {
fn transform_mut(&mut self) -> &mut DAffine2 {
&mut self.transform
}
}
pub trait ApplyTransform {
fn apply_transform(&mut self, modification: &DAffine2);
}
@@ -222,13 +311,13 @@ async fn transform<I: Into<Footprint> + 'n + ApplyTransform + Clone + Send + Syn
)]
mut input: I,
#[implementations(
() -> VectorData,
() -> GraphicGroup,
() -> ImageFrame<Color>,
() -> VectorDataTable,
() -> GraphicGroupTable,
() -> ImageFrameTable<Color>,
() -> TextureFrame,
Footprint -> VectorData,
Footprint -> GraphicGroup,
Footprint -> ImageFrame<Color>,
Footprint -> VectorDataTable,
Footprint -> GraphicGroupTable,
Footprint -> ImageFrameTable<Color>,
Footprint -> TextureFrame,
)]
transform_target: impl Node<I, Output = T>,
@@ -255,7 +344,7 @@ async fn transform<I: Into<Footprint> + 'n + ApplyTransform + Clone + Send + Syn
#[node_macro::node(category(""))]
fn replace_transform<Data: TransformMut, TransformInput: Transform>(
_: (),
#[implementations(VectorData, ImageFrame<Color>, GraphicGroup)] mut data: Data,
#[implementations(VectorDataTable, ImageFrameTable<Color>, GraphicGroupTable)] mut data: Data,
#[implementations(DAffine2)] transform: TransformInput,
) -> Data {
let data_transform = data.transform_mut();