mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Add support for opening GDD documents from the CLI (#4262)
* Wire document-format into graphene-cli * Support loading both legacy and new graphite files in the cli * Address PR review: propagate CLI errors and use dyn resolver * Fix CLI network wrap + preprocessor ordering * Cleanup preprocessor * Remove unused import
This commit is contained in:
84
Cargo.lock
generated
84
Cargo.lock
generated
@@ -209,9 +209,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-rs"
|
||||
version = "1.16.2"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc"
|
||||
checksum = "d9a7b350e3bb1767102698302bc37256cbd48422809984b98d292c40e2579aa9"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"zeroize",
|
||||
@@ -219,9 +219,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-sys"
|
||||
version = "0.39.0"
|
||||
version = "0.37.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a"
|
||||
checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cmake",
|
||||
@@ -354,7 +354,7 @@ version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
|
||||
dependencies = [
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -421,9 +421,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.1"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
@@ -582,7 +582,7 @@ dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
"libloading 0.9.0",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-io-surface",
|
||||
"objc2-metal 0.3.2",
|
||||
@@ -1120,9 +1120,9 @@ checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.5.8"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
|
||||
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
@@ -1213,7 +1213,7 @@ dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2 0.6.2",
|
||||
"libc",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1994,6 +1994,8 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"document-container",
|
||||
"document-format",
|
||||
"fern",
|
||||
"futures",
|
||||
"graph-craft",
|
||||
@@ -2142,7 +2144,7 @@ dependencies = [
|
||||
"interprocess",
|
||||
"lzma-rust2",
|
||||
"muda",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
"open",
|
||||
@@ -3282,7 +3284,7 @@ dependencies = [
|
||||
"crossbeam-channel",
|
||||
"dpi",
|
||||
"keyboard-types",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
@@ -3451,9 +3453,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.2.0"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
@@ -3525,9 +3527,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
version = "0.6.4"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f"
|
||||
checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05"
|
||||
dependencies = [
|
||||
"objc2-encode",
|
||||
]
|
||||
@@ -3556,7 +3558,7 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2 0.6.2",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
]
|
||||
@@ -3582,7 +3584,7 @@ dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2 0.6.2",
|
||||
"dispatch2",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3646,7 +3648,7 @@ dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2 0.6.2",
|
||||
"libc",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
@@ -3658,7 +3660,7 @@ checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"libc",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
]
|
||||
@@ -3684,7 +3686,7 @@ dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2 0.6.2",
|
||||
"dispatch2",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-io-surface",
|
||||
@@ -3710,7 +3712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-metal 0.3.2",
|
||||
@@ -3723,7 +3725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
]
|
||||
@@ -4500,7 +4502,7 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135"
|
||||
dependencies = [
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-quartz-core 0.3.2",
|
||||
@@ -4699,7 +4701,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"libc",
|
||||
"log",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
@@ -4843,9 +4845,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.37"
|
||||
version = "0.23.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
|
||||
checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
@@ -4917,9 +4919,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.10"
|
||||
version = "0.103.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
|
||||
checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"ring",
|
||||
@@ -5702,30 +5704,30 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.47"
|
||||
version = "0.3.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde_core",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.8"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.27"
|
||||
version = "0.2.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
|
||||
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
@@ -6784,7 +6786,7 @@ dependencies = [
|
||||
"log",
|
||||
"naga",
|
||||
"ndk-sys",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-metal 0.3.2",
|
||||
@@ -7390,7 +7392,7 @@ dependencies = [
|
||||
"block2 0.6.2",
|
||||
"dispatch2",
|
||||
"dpi",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-core-graphics",
|
||||
@@ -7409,7 +7411,7 @@ version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
dependencies = [
|
||||
"memmap2 0.9.10",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"smol_str",
|
||||
"tracing",
|
||||
@@ -7457,7 +7459,7 @@ dependencies = [
|
||||
"block2 0.6.2",
|
||||
"dispatch2",
|
||||
"dpi",
|
||||
"objc2 0.6.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-ui-kit",
|
||||
|
||||
@@ -7,8 +7,8 @@ members = [
|
||||
"desktop/platform/linux",
|
||||
"desktop/platform/mac",
|
||||
"desktop/platform/win",
|
||||
"document/container",
|
||||
"document/graph-storage",
|
||||
"document/container",
|
||||
"document/document-format",
|
||||
"editor",
|
||||
"frontend/wrapper",
|
||||
@@ -106,6 +106,7 @@ rustc-hash = "2.0"
|
||||
bytemuck = { version = "1.13", features = ["derive", "min_const_generics"] }
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
serde_json = "1.0"
|
||||
rmp-serde = "1.3"
|
||||
serde_bytes = "0.11"
|
||||
serde-wasm-bindgen = "0.6"
|
||||
reqwest = { version = "0.13", features = ["blocking", "json"] }
|
||||
@@ -172,7 +173,6 @@ color = "0.3"
|
||||
# Linebender ecosystem (END)
|
||||
rand = { version = "0.9", default-features = false, features = ["std_rng"] }
|
||||
rand_chacha = "0.9"
|
||||
rmp-serde = "1.3"
|
||||
glam = { version = "0.32.1", default-features = false, features = [
|
||||
"nostd-libm",
|
||||
"scalar-math",
|
||||
|
||||
@@ -348,7 +348,7 @@ impl NodeRuntime {
|
||||
async fn update_network(&mut self, graph: NodeNetwork) -> Result<ResolvedDocumentNodeTypesDelta, (ResolvedDocumentNodeTypesDelta, String)> {
|
||||
let mut scoped_network = wrap_network_in_scope(graph, self.editor_api.clone());
|
||||
|
||||
if let Err(e) = self.preprocessor.preprocess(&mut scoped_network, &self.resources) {
|
||||
if let Err(e) = self.preprocessor.preprocess(&mut scoped_network, &|resource_id| self.resources.hash(&resource_id)) {
|
||||
return Err((ResolvedDocumentNodeTypesDelta::default(), e.to_string()));
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ pub use core_types::{ProtoNodeIdentifier, Type, TypeDescriptor, concrete, descri
|
||||
|
||||
pub mod application_io;
|
||||
pub mod document;
|
||||
pub use document::{DocumentNode, NodeNetwork};
|
||||
pub mod graphene_compiler;
|
||||
pub mod proto;
|
||||
#[cfg(feature = "loading")]
|
||||
|
||||
@@ -17,6 +17,8 @@ graphene-std = { workspace = true }
|
||||
interpreted-executor = { workspace = true }
|
||||
graph-craft = { workspace = true, features = ["loading"] }
|
||||
preprocessor = { workspace = true }
|
||||
document-format = { workspace = true, features = ["zip", "xz"] }
|
||||
document-container = { workspace = true, features = ["zip", "xz"] }
|
||||
|
||||
# Workspace dependencies
|
||||
log = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
mod export;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use document_container::AnyContainer;
|
||||
use document_container::backends::memory::MemoryBackend;
|
||||
use document_format::{GddV1, GddV1Layout};
|
||||
use fern::colors::{Color, ColoredLevelConfig};
|
||||
use futures::executor::block_on;
|
||||
use graph_craft::application_io::EditorPreferences;
|
||||
@@ -84,6 +87,11 @@ enum Command {
|
||||
duration: Option<f64>,
|
||||
},
|
||||
ListNodeIdentifiers,
|
||||
|
||||
/// Extract embedded legacy .graphite file from the new .gdd file
|
||||
ExtractLegacyDoc {
|
||||
document: PathBuf,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@@ -104,6 +112,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let document_path = match app.command {
|
||||
Command::Compile { ref document, .. } => document,
|
||||
Command::Export { ref document, .. } => document,
|
||||
Command::ExtractLegacyDoc { ref document } => document,
|
||||
Command::ListNodeIdentifiers => {
|
||||
let mut nodes: Vec<_> = graphene_std::registry::NODE_METADATA.lock().unwrap().keys().cloned().collect();
|
||||
nodes.sort_by_key(|x| x.as_str().to_string());
|
||||
@@ -114,10 +123,51 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
};
|
||||
|
||||
let document_string = std::fs::read_to_string(document_path).expect("Failed to read document");
|
||||
// Load the document by extension: `.gdd` opens the new archive format, anything else is treated as a
|
||||
// legacy `.graphite` document. The legacy path has no `Gdd`, so resources fall back to the default registry.
|
||||
let is_gdd = document_path.extension().is_some_and(|extension| extension.eq_ignore_ascii_case("gdd"));
|
||||
|
||||
let gdd = if is_gdd {
|
||||
let archive = std::fs::read(document_path).map_err(|error| format!("Failed to read document {}: {error}", document_path.display()))?;
|
||||
let container = AnyContainer::Memory(MemoryBackend::new());
|
||||
let gdd = document_format::Gdd::open_from_archive(archive.as_ref(), container, GddV1Layout)
|
||||
.await
|
||||
.map_err(|error| format!("Failed to open document: {error}"))?;
|
||||
Some(gdd)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Command::ExtractLegacyDoc { ref document } = app.command {
|
||||
let Some(gdd) = &gdd else { return Err("ExtractLegacyDoc requires a .gdd document".into()) };
|
||||
let Some(legacy_doc) = gdd.read_legacy_document().await else {
|
||||
return Err("gdd file did not contain a legacy .graphite document".into());
|
||||
};
|
||||
let mut new_path = document.clone();
|
||||
new_path.set_extension("graphite");
|
||||
std::fs::write(&new_path, legacy_doc).map_err(|error| format!("Failed to write .graphite file: {error}"))?;
|
||||
eprintln!("Saved file to {}", new_path.to_string_lossy());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Build the runtime network: from the `.gdd` registry, or by loading a legacy `.graphite` document.
|
||||
let node_network = match &gdd {
|
||||
Some(gdd) => {
|
||||
let declarations = gdd.declarations(gdd).await;
|
||||
let (node_network, _metadata) = gdd.registry().to_runtime_with_metadata(&declarations)?;
|
||||
node_network
|
||||
}
|
||||
None => {
|
||||
let document_string = std::fs::read_to_string(document_path).map_err(|error| format!("Failed to read document {}: {error}", document_path.display()))?;
|
||||
load_network(&document_string)
|
||||
}
|
||||
};
|
||||
|
||||
log::info!("Creating GPU context");
|
||||
let application_io = block_on(PlatformApplicationIo::new());
|
||||
let mut application_io = PlatformApplicationIo::new().await;
|
||||
if let Some(gdd) = &gdd {
|
||||
application_io.inject_resource_proxy(Box::new(gdd.resource_proxy()));
|
||||
}
|
||||
|
||||
// Convert application_io to Arc first
|
||||
let application_io_arc = Arc::new(application_io);
|
||||
@@ -137,8 +187,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
node_graph_message_sender: Box::new(UpdateLogger {}),
|
||||
editor_preferences: Box::new(preferences),
|
||||
});
|
||||
|
||||
let proto_graph = compile_graph(document_string, editor_api)?;
|
||||
let proto_graph = compile_graph(node_network, editor_api, gdd.as_ref())?;
|
||||
|
||||
match app.command {
|
||||
Command::Compile { print_proto, .. } => {
|
||||
@@ -218,37 +267,22 @@ fn init_logging(log_level: u8) {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Migrations are done in the editor which is unfortunately not available here.
|
||||
// TODO: remove this and share migrations between the editor and the CLI.
|
||||
fn fix_nodes(network: &mut NodeNetwork) {
|
||||
for node in network.nodes.values_mut() {
|
||||
match &mut node.implementation {
|
||||
// Recursively fix
|
||||
DocumentNodeImplementation::Network(network) => fix_nodes(network),
|
||||
// This replicates the migration from the editor linked:
|
||||
// https://github.com/GraphiteEditor/Graphite/blob/d68f91ccca69e90e6d2df78d544d36cd1aaf348e/editor/src/messages/portfolio/portfolio_message_handler.rs#L535
|
||||
// Since the CLI doesn't have the document node definitions, a less robust method of just patching the inputs is used.
|
||||
DocumentNodeImplementation::ProtoNode(proto_node_identifier)
|
||||
if (proto_node_identifier.as_str().starts_with("graphene_core::ConstructLayerNode") || proto_node_identifier.as_str().starts_with("graphene_core::AddArtboardNode"))
|
||||
&& node.inputs.len() < 3 =>
|
||||
{
|
||||
node.inputs.push(NodeInput::Reflection(DocumentNodeMetadata::DocumentNodePath));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn compile_graph(document_string: String, editor_api: Arc<PlatformEditorApi>) -> Result<ProtoNetwork, Box<dyn Error>> {
|
||||
let mut network = load_network(&document_string);
|
||||
fix_nodes(&mut network);
|
||||
|
||||
let mut wrapped_network = wrap_network_in_scope(network, editor_api);
|
||||
|
||||
fn compile_graph(network: NodeNetwork, editor_api: Arc<PlatformEditorApi>, gdd: Option<&GddV1>) -> Result<ProtoNetwork, Box<dyn Error>> {
|
||||
let preprocessor = preprocessor::Preprocessor::new();
|
||||
preprocessor.preprocess(&mut wrapped_network, &ResourceRegistry::default()).expect("Failed to expand network"); // TODO: actually load the resources from the document
|
||||
|
||||
let mut network = wrap_network_in_scope(network, editor_api);
|
||||
|
||||
// A `.gdd` resolves resource hashes from its registry; a legacy `.graphite` has no resource store, so it
|
||||
// preprocesses against an empty registry (matching the pre-`.gdd` CLI behavior).
|
||||
match gdd {
|
||||
Some(gdd) => preprocessor
|
||||
.preprocess(&mut network, &|resource_id| gdd.registry().resources.get(&resource_id).and_then(|r| r.hash))
|
||||
.expect("Failed to expand network"),
|
||||
None => { preprocessor.preprocess(&mut network, &|_| None) }.expect("Failed to expand network"),
|
||||
}
|
||||
|
||||
let compiler = Compiler {};
|
||||
compiler.compile_single(wrapped_network).map_err(|x| x.into())
|
||||
compiler.compile_single(network).map_err(|x| x.into())
|
||||
}
|
||||
|
||||
fn create_executor(proto_network: ProtoNetwork) -> Result<DynamicExecutor, Box<dyn Error>> {
|
||||
|
||||
@@ -4,7 +4,6 @@ use futures::executor::block_on;
|
||||
use graph_craft::proto::ProtoNetwork;
|
||||
use graph_craft::util::{DEMO_ART, compile, load_from_name};
|
||||
use graphene_std::application_io::EditorApi;
|
||||
use graphene_std::application_io::resource::ResourceRegistry;
|
||||
use interpreted_executor::dynamic_executor::DynamicExecutor;
|
||||
use interpreted_executor::util::wrap_network_in_scope;
|
||||
|
||||
@@ -13,7 +12,7 @@ pub fn setup_network(name: &str) -> (DynamicExecutor, ProtoNetwork) {
|
||||
let editor_api = std::sync::Arc::new(EditorApi::default());
|
||||
let mut network = wrap_network_in_scope(network, editor_api);
|
||||
let preprocessor = preprocessor::Preprocessor::new();
|
||||
preprocessor.preprocess(&mut network, &ResourceRegistry::default()).unwrap();
|
||||
preprocessor.preprocess(&mut network, &|_| None).unwrap();
|
||||
let proto_network = compile(network);
|
||||
let executor = block_on(DynamicExecutor::new(proto_network.clone())).unwrap();
|
||||
(executor, proto_network)
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
extern crate log;
|
||||
|
||||
use graph_craft::Type;
|
||||
use graph_craft::application_io::resource::{ResourceId, ResourceRegistry};
|
||||
use graph_craft::application_io::resource::ResourceId;
|
||||
use graph_craft::document::value::*;
|
||||
use graph_craft::document::*;
|
||||
use graph_craft::proto::RegistryValueSource;
|
||||
use graph_craft::{ProtoNodeIdentifier, concrete};
|
||||
use graphene_std::platform_application_io::ResourceHash;
|
||||
use graphene_std::registry::*;
|
||||
use graphene_std::*;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@@ -19,9 +20,9 @@ pub struct Preprocessor {
|
||||
}
|
||||
|
||||
impl Preprocessor {
|
||||
pub fn preprocess(&self, network: &mut NodeNetwork, resources: &ResourceRegistry) -> Result<(), PreprocessorError> {
|
||||
pub fn preprocess(&self, network: &mut NodeNetwork, resolve_resource: &dyn Fn(ResourceId) -> Option<ResourceHash>) -> Result<(), PreprocessorError> {
|
||||
self.insert_inject_scopes(network);
|
||||
self.replace_resource_inputs(network, resources)?;
|
||||
self.replace_resource_inputs(network, resolve_resource)?;
|
||||
self.expand_network(network);
|
||||
Ok(())
|
||||
}
|
||||
@@ -41,13 +42,13 @@ impl Preprocessor {
|
||||
}
|
||||
|
||||
/// Replace every `TaggedValue::Resource(hash)` input with a reference to a freshly inserted `resource` proto node.
|
||||
fn replace_resource_inputs(&self, network: &mut NodeNetwork, resources: &ResourceRegistry) -> Result<(), PreprocessorError> {
|
||||
fn replace_resource_inputs(&self, network: &mut NodeNetwork, resolve_resource: &dyn Fn(ResourceId) -> Option<ResourceHash>) -> Result<(), PreprocessorError> {
|
||||
let mut hash_to_node_id: HashMap<graph_craft::application_io::resource::ResourceHash, NodeId> = HashMap::new();
|
||||
let mut new_resource_nodes: Vec<(NodeId, DocumentNode)> = Vec::new();
|
||||
|
||||
for node in network.nodes.values_mut() {
|
||||
if let DocumentNodeImplementation::Network(nested) = &mut node.implementation {
|
||||
self.replace_resource_inputs(nested, resources)?;
|
||||
self.replace_resource_inputs(nested, resolve_resource)?;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -59,7 +60,7 @@ impl Preprocessor {
|
||||
let NodeInput::Value { tagged_value, .. } = input else { continue };
|
||||
let TaggedValue::Resource(resource_id) = **tagged_value else { continue };
|
||||
|
||||
let Some(hash) = resources.hash(&resource_id) else {
|
||||
let Some(hash) = resolve_resource(resource_id) else {
|
||||
return Err(PreprocessorError::ResourceNotFound(resource_id));
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user