mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 07:18:04 +08:00
Implement dynamic table attributes to generalize the graphic-specific Table type (#4050)
* Feature-gate serde derives behind cfg_attr in all runtime node graph type crates * Refactor Table to move its hard-coded fields into an attributes field * Encapsulate TableRow/TableRowRef/TableRowMut attribute fields behind accessor methods * Remove TaggedValue::GraphicUnused * Refactor Table<T> to use dynamic attributes instead fixed names * Fix code review soundness concerns * Add todo work * Replace row-oriented Table<T> API with column-oriented access * Fix attribute propagation bugs ---------
This commit is contained in:
@@ -14,24 +14,25 @@ use std::sync::{Arc, Mutex};
|
||||
// TODO: This is a temporary hack, be sure to not reuse this when the brush system is replaced/rewritten.
|
||||
static NEXT_BRUSH_CACHE_IMPL_ID: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
#[derive(Clone, Debug, DynAny, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, Debug, DynAny)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
struct BrushCacheImpl {
|
||||
#[serde(default = "new_unique_id")]
|
||||
#[cfg_attr(feature = "serde", serde(default = "new_unique_id"))]
|
||||
unique_id: u64,
|
||||
// The full previous input that was cached.
|
||||
#[serde(default)]
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
prev_input: Vec<BrushStroke>,
|
||||
|
||||
// The strokes that have been fully processed and blended into the background.
|
||||
#[serde(default, deserialize_with = "raster_types::image::migrate_image_frame_row")]
|
||||
#[cfg_attr(feature = "serde", serde(default, deserialize_with = "raster_types::image::migrate_image_frame_row"))]
|
||||
background: TableRow<Raster<CPU>>,
|
||||
#[serde(default, deserialize_with = "raster_types::image::migrate_image_frame_row")]
|
||||
#[cfg_attr(feature = "serde", serde(default, deserialize_with = "raster_types::image::migrate_image_frame_row"))]
|
||||
blended_image: TableRow<Raster<CPU>>,
|
||||
#[serde(default, deserialize_with = "raster_types::image::migrate_image_frame_row")]
|
||||
#[cfg_attr(feature = "serde", serde(default, deserialize_with = "raster_types::image::migrate_image_frame_row"))]
|
||||
last_stroke_texture: TableRow<Raster<CPU>>,
|
||||
|
||||
// A cache for brush textures.
|
||||
#[serde(skip)]
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
brush_texture_cache: HashMap<CacheHashWrapper<BrushStyle>, Raster<CPU>>,
|
||||
}
|
||||
|
||||
@@ -63,11 +64,10 @@ impl BrushCacheImpl {
|
||||
background = std::mem::take(&mut self.blended_image);
|
||||
|
||||
// Check if the first non-blended stroke is an extension of the last one.
|
||||
let mut first_stroke_texture = TableRow {
|
||||
element: Raster::<CPU>::default(),
|
||||
transform: glam::DAffine2::ZERO,
|
||||
..Default::default()
|
||||
};
|
||||
let mut first_stroke_texture = TableRow::new_from_element(Raster::<CPU>::default())
|
||||
.with_attribute("transform", glam::DAffine2::ZERO)
|
||||
.with_attribute("alpha_blending", core_types::AlphaBlending::default())
|
||||
.with_attribute("source_node_id", None::<core_types::uuid::NodeId>);
|
||||
let mut first_stroke_point_skip = 0;
|
||||
let strokes = input[num_blended_strokes..].to_vec();
|
||||
if !strokes.is_empty() && self.prev_input.len() > num_blended_strokes {
|
||||
@@ -135,7 +135,8 @@ pub struct BrushPlan {
|
||||
pub first_stroke_point_skip: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, DynAny, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Debug, Default, DynAny)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct BrushCache(Arc<Mutex<BrushCacheImpl>>);
|
||||
|
||||
// A bit of a cursed implementation to work around the current node system.
|
||||
|
||||
Reference in New Issue
Block a user