mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-08 00:05:00 +00:00
Add monitor node for graph introspection
Adds a `serialize` function on Node which can be implemented by nodes to allow introspecting their content. This pr also adds a Monitor Node that always caches the last value it was evaluated with. Test Plan: - Reviewers: 0HyperCube Reviewed By: 0HyperCube Pull Request: https://github.com/GraphiteEditor/Graphite/pull/1165
This commit is contained in:
parent
9cf93a9156
commit
271f9d5158
6 changed files with 41 additions and 8 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -3,8 +3,6 @@ name: Continuous Integration
|
|||
on:
|
||||
push:
|
||||
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
|
|
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1671,6 +1671,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn 1.0.109",
|
||||
"tempfile",
|
||||
"vulkan-executor",
|
||||
|
|
|
@ -37,6 +37,10 @@ pub trait Node<'i, Input: 'i>: 'i {
|
|||
type Output: 'i;
|
||||
fn eval(&'i self, input: Input) -> Self::Output;
|
||||
fn reset(self: Pin<&mut Self>) {}
|
||||
#[cfg(feature = "alloc")]
|
||||
fn serialize(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
|
|
|
@ -11,12 +11,7 @@ license = "MIT OR Apache-2.0"
|
|||
[features]
|
||||
memoization = ["once_cell"]
|
||||
default = ["memoization"]
|
||||
gpu = [
|
||||
"graphene-core/gpu",
|
||||
"gpu-compiler-bin-wrapper",
|
||||
"compilation-client",
|
||||
"gpu-executor",
|
||||
]
|
||||
gpu = ["graphene-core/gpu", "gpu-compiler-bin-wrapper", "compilation-client", "gpu-executor"]
|
||||
vulkan = ["gpu", "vulkan-executor"]
|
||||
wgpu = ["gpu", "wgpu-executor"]
|
||||
quantization = ["autoquant"]
|
||||
|
@ -63,6 +58,7 @@ glam = { version = "0.22", features = ["serde"] }
|
|||
node-macro = { path = "../node-macro" }
|
||||
boxcar = "0.1.0"
|
||||
xxhash-rust = { workspace = true }
|
||||
serde_json = "1.0.96"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use graphene_core::Node;
|
||||
use serde::Serialize;
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::Mutex;
|
||||
use xxhash_rust::xxh3::Xxh3;
|
||||
|
||||
/// Caches the output of a given Node and acts as a proxy
|
||||
|
@ -49,6 +51,37 @@ impl<T, CachedNode> CacheNode<T, CachedNode> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Caches the output of the last graph evaluation for introspection
|
||||
#[derive(Default)]
|
||||
pub struct MonitorNode<T, CachedNode> {
|
||||
output: Mutex<Option<T>>,
|
||||
node: CachedNode,
|
||||
}
|
||||
impl<'i, T: 'i + Serialize + Clone, I: 'i + Hash, CachedNode: 'i> Node<'i, I> for MonitorNode<T, CachedNode>
|
||||
where
|
||||
CachedNode: for<'any_input> Node<'any_input, I, Output = T>,
|
||||
{
|
||||
type Output = T;
|
||||
fn eval(&'i self, input: I) -> Self::Output {
|
||||
let output = self.node.eval(input);
|
||||
*self.output.lock().unwrap() = Some(output.clone());
|
||||
output
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Option<String> {
|
||||
let output = self.output.lock().unwrap();
|
||||
(&*output).as_ref().map(|output| serde_json::to_string(output).ok()).flatten()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, CachedNode> std::marker::Unpin for MonitorNode<T, CachedNode> {}
|
||||
|
||||
impl<T, CachedNode> MonitorNode<T, CachedNode> {
|
||||
pub const fn new(node: CachedNode) -> MonitorNode<T, CachedNode> {
|
||||
MonitorNode { output: Mutex::new(None), node }
|
||||
}
|
||||
}
|
||||
|
||||
/// Caches the output of a given Node and acts as a proxy
|
||||
/// It provides two modes of operation, it can either be set
|
||||
/// when calling the node with a `Some<T>` variant or the last
|
||||
|
|
|
@ -153,6 +153,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||
register_node!(graphene_std::raster::MaskImageNode<_, _, _>, input: ImageFrame<Color>, params: [ImageFrame<Color>]),
|
||||
register_node!(graphene_std::raster::MaskImageNode<_, _, _>, input: ImageFrame<Color>, params: [ImageFrame<Luma>]),
|
||||
register_node!(graphene_std::raster::EmptyImageNode<_, _>, input: DAffine2, params: [Color]),
|
||||
register_node!(graphene_std::memo::MonitorNode<_, _>, input: (), params: [ImageFrame<Color>]),
|
||||
#[cfg(feature = "gpu")]
|
||||
register_node!(graphene_std::executor::MapGpuSingleImageNode<_>, input: Image<Color>, params: [String]),
|
||||
vec![(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue