Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1786,7 +1786,7 @@ impl DocumentMessageHandler {
pub fn deserialize_document(serialized_content: &str) -> Result<Self, EditorError> {
let document_message_handler = serde_json::from_str::<DocumentMessageHandler>(serialized_content)
.or_else(|e| {
log::warn!("failed to directly load document with the following error: {e}. Trying old DocumentMessageHandler");
log::warn!("Failed to directly load document with the following error: {e}. Trying old DocumentMessageHandler.");
// TODO: Eventually remove this document upgrade code
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct OldDocumentMessageHandler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ pub enum EditorError {
#[error("The operation caused a document error:\n{0:?}")]
Document(String),

#[error("This document was created in an older version of the editor.\n\nBackwards compatibility is, regrettably, not present in the current alpha release.\n\nTechnical details:\n{0:?}")]
#[error(
"This document was created in an older version of the editor.\n\
\n\
Full backwards compatibility is not guaranteed in the current alpha release.\n\
\n\
If this document is critical, ask for support in Graphite's Discord community."
)]
DocumentDeserialization(String),

#[error("{0}")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ impl NodeNetworkInterface {
let skip_footprint = 1;

let Some(input_type) = std::iter::once(node_types.call_argument.clone()).chain(node_types.inputs.clone()).nth(input_index + skip_footprint) else {
log::error!("Could not get type for {node_id_path:?}, input: {input_index}");
// log::warn!("Could not get type for {node_id_path:?}, input: {input_index}");
return (concrete!(()), TypeSource::Error("could not get the protonode's input"));
};

Expand Down Expand Up @@ -2629,7 +2629,7 @@ impl NodeNetworkInterface {
InputConnector::Node { node_id, input_index } => {
let Some(node_metadata) = self.node_metadata_mut(node_id, network_path) else { return };
let Some(input_metadata) = node_metadata.persistent_metadata.input_metadata.get_mut(*input_index) else {
log::error!("Node metadata must exist on node: {input:?}");
// log::warn!("Node metadata must exist on node: {input:?}");
return;
};
let wire_update = WirePathUpdate {
Expand Down Expand Up @@ -2721,7 +2721,7 @@ impl NodeNetworkInterface {
return;
};
let Some(input_metadata) = node_metadata.persistent_metadata.input_metadata.get_mut(*input_index) else {
log::error!("Node metadata must exist on node: {input:?}");
// log::warn!("Node metadata must exist on node: {input:?}");
return;
};
input_metadata.transient_metadata.wire = TransientMetadata::Unloaded;
Expand Down
4 changes: 4 additions & 0 deletions editor/src/messages/portfolio/document_migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
node: graphene_std::math_nodes::root::IDENTIFIER,
aliases: &["graphene_core::ops::RootNode"],
},
NodeReplacement {
node: graphene_std::math_nodes::absolute_value::IDENTIFIER,
aliases: &["graphene_core::ops::AbsoluteValueNode"],
},
NodeReplacement {
node: graphene_std::math_nodes::logarithm::IDENTIFIER,
aliases: &["graphene_core::ops::LogarithmNode"],
Expand Down
1 change: 1 addition & 0 deletions editor/src/messages/portfolio/portfolio_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub enum PortfolioMessage {
document_is_saved: bool,
document_serialized_content: String,
to_front: bool,
select_after_open: bool,
},
ToggleResetNodesToDefinitionsOnOpen,
PasteIntoFolder {
Expand Down
29 changes: 17 additions & 12 deletions editor/src/messages/portfolio/portfolio_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,17 +422,16 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
document_path,
document_serialized_content,
} => {
let document_id = DocumentId(generate_uuid());
responses.add(PortfolioMessage::OpenDocumentFileWithId {
document_id,
document_id: DocumentId(generate_uuid()),
document_name,
document_path,
document_is_auto_saved: false,
document_is_saved: true,
document_serialized_content,
to_front: false,
select_after_open: true,
});
responses.add(PortfolioMessage::SelectDocument { document_id });
}
PortfolioMessage::ToggleResetNodesToDefinitionsOnOpen => {
self.reset_node_definitions_on_open = !self.reset_node_definitions_on_open;
Expand All @@ -446,6 +445,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
document_is_saved,
document_serialized_content,
to_front,
select_after_open,
} => {
// Upgrade the document being opened to use fresh copies of all nodes
let reset_node_definitions_on_open = reset_node_definitions_on_open || document_migration_reset_node_definition(&document_serialized_content);
Expand Down Expand Up @@ -540,6 +540,10 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio

// Load the document into the portfolio so it opens in the editor
self.load_document(document, document_id, self.layers_panel_open, responses, to_front);

if select_after_open {
responses.add(PortfolioMessage::SelectDocument { document_id });
}
}
PortfolioMessage::PasteIntoFolder { clipboard, parent, insert_index } => {
let mut all_new_ids = Vec::new();
Expand Down Expand Up @@ -954,14 +958,15 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
}
PortfolioMessage::SubmitGraphRender { document_id, ignore_hash } => {
let node_to_inspect = self.node_to_inspect();
let result = self.executor.submit_node_graph_evaluation(
self.documents.get_mut(&document_id).expect("Tried to render non-existent document"),
document_id,
ipp.viewport_bounds.size().as_uvec2(),
timing_information,
node_to_inspect,
ignore_hash,
);
let Some(document) = self.documents.get_mut(&document_id) else {
log::error!("Tried to render non-existent document");
return;
};
let viewport_resolution = ipp.viewport_bounds.size().as_uvec2();

let result = self
.executor
.submit_node_graph_evaluation(document, document_id, viewport_resolution, timing_information, node_to_inspect, ignore_hash);

match result {
Err(description) => {
Expand Down Expand Up @@ -1173,7 +1178,7 @@ impl PortfolioMessageHandler {

/// Returns an iterator over the open documents in order.
pub fn ordered_document_iterator(&self) -> impl Iterator<Item = &DocumentMessageHandler> {
self.document_ids.iter().map(|id| self.documents.get(id).expect("document id was not found in the document hashmap"))
self.document_ids.iter().map(|id| self.documents.get(id).expect("Document id was not found in the document hashmap"))
}

fn document_index(&self, document_id: DocumentId) -> usize {
Expand Down
1 change: 1 addition & 0 deletions frontend/wasm/src/editor_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ impl EditorHandle {
document_is_saved,
document_serialized_content,
to_front,
select_after_open: false,
};
self.dispatch(message);
}
Expand Down
16 changes: 11 additions & 5 deletions node-graph/gbrush/src/brush_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,23 @@ use std::hash::Hasher;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, Mutex};

// TODO: This is a temporary hack, be sure to not reuse this when the brush is being rewritten.
// 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)]
struct BrushCacheImpl {
#[serde(default = "new_unique_id")]
unique_id: u64,
// The full previous input that was cached.
#[serde(default)]
prev_input: Vec<BrushStroke>,

// The strokes that have been fully processed and blended into the background.
#[serde(deserialize_with = "graphene_core::raster::image::migrate_image_frame_row")]
#[serde(default, deserialize_with = "graphene_core::raster::image::migrate_image_frame_row")]
background: TableRow<Raster<CPU>>,
#[serde(deserialize_with = "graphene_core::raster::image::migrate_image_frame_row")]
#[serde(default, deserialize_with = "graphene_core::raster::image::migrate_image_frame_row")]
blended_image: TableRow<Raster<CPU>>,
#[serde(deserialize_with = "graphene_core::raster::image::migrate_image_frame_row")]
#[serde(default, deserialize_with = "graphene_core::raster::image::migrate_image_frame_row")]
last_stroke_texture: TableRow<Raster<CPU>>,

// A cache for brush textures.
Expand Down Expand Up @@ -98,7 +100,7 @@ impl BrushCacheImpl {
impl Default for BrushCacheImpl {
fn default() -> Self {
Self {
unique_id: NEXT_BRUSH_CACHE_IMPL_ID.fetch_add(1, Ordering::SeqCst),
unique_id: new_unique_id(),
prev_input: Vec::new(),
background: Default::default(),
blended_image: Default::default(),
Expand All @@ -120,6 +122,10 @@ impl Hash for BrushCacheImpl {
}
}

fn new_unique_id() -> u64 {
NEXT_BRUSH_CACHE_IMPL_ID.fetch_add(1, Ordering::SeqCst)
}

#[derive(Clone, Debug, Default)]
pub struct BrushPlan {
pub strokes: Vec<BrushStroke>,
Expand Down
28 changes: 24 additions & 4 deletions node-graph/gcore/src/artboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,22 @@ pub fn migrate_artboard<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Re

#[derive(serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
enum EitherFormat {
enum ArtboardFormat {
ArtboardGroup(ArtboardGroup),
OldArtboardTable(OldTable<Artboard>),
ArtboardTable(Table<Artboard>),
}

Ok(match EitherFormat::deserialize(deserializer)? {
EitherFormat::ArtboardGroup(artboard_group) => {
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct OldTable<T> {
#[serde(alias = "instances", alias = "instance")]
element: Vec<T>,
transform: Vec<DAffine2>,
alpha_blending: Vec<AlphaBlending>,
}

Ok(match ArtboardFormat::deserialize(deserializer)? {
ArtboardFormat::ArtboardGroup(artboard_group) => {
let mut table = Table::new();
for (artboard, source_node_id) in artboard_group.artboards {
table.push(TableRow {
Expand All @@ -86,7 +95,18 @@ pub fn migrate_artboard<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Re
}
table
}
EitherFormat::ArtboardTable(artboard_table) => artboard_table,
ArtboardFormat::OldArtboardTable(old_table) => old_table
.element
.into_iter()
.zip(old_table.transform.into_iter().zip(old_table.alpha_blending))
.map(|(element, (transform, alpha_blending))| TableRow {
element,
transform,
alpha_blending,
source_node_id: None,
})
.collect(),
ArtboardFormat::ArtboardTable(artboard_table) => artboard_table,
})
}

Expand Down
2 changes: 2 additions & 0 deletions node-graph/gcore/src/context_modification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::context::{CloneVarArgs, Context, ContextFeatures, Ctx, ExtractAll};
use crate::gradient::GradientStops;
use crate::raster_types::{CPU, GPU, Raster};
use crate::table::Table;
use crate::transform::Footprint;
use crate::uuid::NodeId;
use crate::vector::Vector;
use crate::{Graphic, OwnedContextImpl};
Expand All @@ -24,6 +25,7 @@ async fn context_modification<T>(
Context -> f64,
Context -> String,
Context -> DAffine2,
Context -> Footprint,
Context -> DVec2,
Context -> Vec<DVec2>,
Context -> Vec<NodeId>,
Expand Down
63 changes: 59 additions & 4 deletions node-graph/gcore/src/graphic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,15 +507,34 @@ pub fn migrate_graphic<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Res
elements: Vec<(Graphic, Option<NodeId>)>,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct OlderTable<T> {
id: Vec<u64>,
#[serde(alias = "instances", alias = "instance")]
element: Vec<T>,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct OldTable<T> {
id: Vec<u64>,
#[serde(alias = "instances", alias = "instance")]
element: Vec<T>,
transform: Vec<DAffine2>,
alpha_blending: Vec<AlphaBlending>,
}

#[derive(serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
enum EitherFormat {
enum GraphicFormat {
OldGraphicGroup(OldGraphicGroup),
OlderTableOldGraphicGroup(OlderTable<OldGraphicGroup>),
OldTableOldGraphicGroup(OldTable<OldGraphicGroup>),
OldTableGraphicGroup(OldTable<GraphicGroup>),
Table(serde_json::Value),
}

Ok(match EitherFormat::deserialize(deserializer)? {
EitherFormat::OldGraphicGroup(old) => {
Ok(match GraphicFormat::deserialize(deserializer)? {
GraphicFormat::OldGraphicGroup(old) => {
let mut graphic_table = Table::new();
for (graphic, source_node_id) in old.elements {
graphic_table.push(TableRow {
Expand All @@ -527,7 +546,43 @@ pub fn migrate_graphic<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Res
}
graphic_table
}
EitherFormat::Table(value) => {
GraphicFormat::OlderTableOldGraphicGroup(old) => old
.element
.into_iter()
.flat_map(|element| {
element.elements.into_iter().map(move |(graphic, source_node_id)| TableRow {
element: graphic,
transform: element.transform,
alpha_blending: element.alpha_blending,
source_node_id,
})
})
.collect(),
GraphicFormat::OldTableOldGraphicGroup(old) => old
.element
.into_iter()
.flat_map(|element| {
element.elements.into_iter().map(move |(graphic, source_node_id)| TableRow {
element: graphic,
transform: element.transform,
alpha_blending: element.alpha_blending,
source_node_id,
})
})
.collect(),
GraphicFormat::OldTableGraphicGroup(old) => old
.element
.into_iter()
.flat_map(|element| {
element.elements.into_iter().map(move |(graphic, source_node_id)| TableRow {
element: graphic,
transform: Default::default(),
alpha_blending: Default::default(),
source_node_id,
})
})
.collect(),
GraphicFormat::Table(value) => {
// Try to deserialize as either table format
if let Ok(old_table) = serde_json::from_value::<Table<GraphicGroup>>(value.clone()) {
let mut graphic_table = Table::new();
Expand Down
10 changes: 5 additions & 5 deletions node-graph/gcore/src/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,21 @@ pub fn migrate_color<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Resul

#[derive(serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
enum EitherFormat {
enum ColorFormat {
Color(Color),
OptionalColor(Option<Color>),
ColorTable(Table<Color>),
}

Ok(match EitherFormat::deserialize(deserializer)? {
EitherFormat::Color(color) => Table::new_from_element(color),
EitherFormat::OptionalColor(color) => {
Ok(match ColorFormat::deserialize(deserializer)? {
ColorFormat::Color(color) => Table::new_from_element(color),
ColorFormat::OptionalColor(color) => {
if let Some(color) = color {
Table::new_from_element(color)
} else {
Table::new()
}
}
EitherFormat::ColorTable(color_table) => color_table,
ColorFormat::ColorTable(color_table) => color_table,
})
}
Loading
Loading