Extract gapplication_io from gcore (#2742)

move `gcore::application_io` into the new crate `gapplication-io`, remove features `wasm` and `wgpu` from `gcore`
This commit is contained in:
Firestar99 2025-06-23 11:35:14 +02:00 committed by GitHub
parent ae88f4a3de
commit 0e8eb481bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 84 additions and 44 deletions

View file

@ -0,0 +1,25 @@
[package]
name = "graphene-application-io"
version = "0.1.0"
edition = "2024"
description = "graphene application io interface"
authors = ["Graphite Authors <contact@graphite.rs>"]
license = "MIT OR Apache-2.0"
[features]
wasm = ["dep:web-sys"]
wgpu = ["dep:wgpu"]
[dependencies]
# Local dependencies
dyn-any = { workspace = true }
graphene-core = { workspace = true }
# Workspace dependencies
glam = { workspace = true }
serde = { workspace = true }
log = { workspace = true }
# Optional workspace dependencies
web-sys = { workspace = true, optional = true }
wgpu = { workspace = true, optional = true }

View file

@ -1,8 +1,8 @@
use crate::text::FontCache;
use crate::transform::Footprint;
use crate::vector::style::ViewMode;
use dyn_any::{DynAny, StaticType, StaticTypeSized};
use glam::{DAffine2, UVec2};
use graphene_core::text::FontCache;
use graphene_core::transform::Footprint;
use graphene_core::vector::style::ViewMode;
use std::fmt::Debug;
use std::future::Future;
use std::hash::{Hash, Hasher};
@ -131,6 +131,11 @@ unsafe impl<T: 'static> StaticType for SurfaceHandleFrame<T> {
type Static = SurfaceHandleFrame<T>;
}
#[cfg(feature = "wasm")]
pub type WasmSurfaceHandle = SurfaceHandle<web_sys::HtmlCanvasElement>;
#[cfg(feature = "wasm")]
pub type WasmSurfaceHandleFrame = SurfaceHandleFrame<web_sys::HtmlCanvasElement>;
// TODO: think about how to automatically clean up memory
/*
impl<'a, Surface> Drop for SurfaceHandle<'a, Surface> {

View file

@ -7,10 +7,9 @@ authors = ["Graphite Authors <contact@graphite.rs>"]
license = "MIT OR Apache-2.0"
[features]
default = ["serde", "wasm"]
default = ["serde"]
nightly = []
type_id_logging = []
wasm = ["web-sys"]
wgpu = ["dep:wgpu"]
vello = ["dep:vello", "bezier-rs/kurbo", "wgpu"]
dealloc_nodes = []
@ -47,7 +46,6 @@ base64 = { workspace = true }
serde = { workspace = true, optional = true }
vello = { workspace = true, optional = true }
wgpu = { workspace = true, optional = true }
web-sys = { workspace = true, optional = true }
[dev-dependencies]
# Workspace dependencies

View file

@ -299,7 +299,7 @@ impl Default for SvgRender {
#[derive(Clone, Debug, Default)]
pub struct RenderContext {
#[cfg(feature = "wgpu")]
#[cfg(feature = "vello")]
pub resource_overrides: HashMap<u64, std::sync::Arc<wgpu::Texture>>,
}

View file

@ -28,8 +28,6 @@ mod graphic_element;
pub use graphic_element::*;
pub mod vector;
pub mod application_io;
pub mod registry;
pub use context::*;
@ -140,12 +138,6 @@ impl<'i, I, O: 'i> Node<'i, I> for Pin<&'i (dyn NodeIO<'i, I, Output = O> + 'i)>
}
}
pub use crate::application_io::{SurfaceFrame, SurfaceId};
#[cfg(feature = "wasm")]
pub type WasmSurfaceHandle = application_io::SurfaceHandle<web_sys::HtmlCanvasElement>;
#[cfg(feature = "wasm")]
pub type WasmSurfaceHandleFrame = application_io::SurfaceHandleFrame<web_sys::HtmlCanvasElement>;
pub trait InputAccessorSource<'a, T>: InputAccessorSourceIdentifier + std::fmt::Debug {
fn get_input(&'a self, index: usize) -> Option<&'a T>;
fn set_input(&'a mut self, index: usize, value: T);

View file

@ -16,6 +16,7 @@ loading = ["serde_json"]
# Local dependencies
dyn-any = { workspace = true }
graphene-core = { workspace = true }
graphene-application-io = { workspace = true }
# Workspace dependencies
log = { workspace = true }

View file

@ -4,6 +4,7 @@ use crate::wasm_application_io::WasmEditorApi;
use dyn_any::DynAny;
pub use dyn_any::StaticType;
pub use glam::{DAffine2, DVec2, IVec2, UVec2};
use graphene_application_io::SurfaceFrame;
use graphene_core::raster::brush_cache::BrushCache;
use graphene_core::raster::{BlendMode, LuminanceCalculation};
use graphene_core::raster_types::CPU;
@ -30,7 +31,7 @@ macro_rules! tagged_value {
None,
$( $(#[$meta] ) *$identifier( $ty ), )*
RenderOutput(RenderOutput),
SurfaceFrame(graphene_core::SurfaceFrame),
SurfaceFrame(SurfaceFrame),
#[serde(skip)]
EditorApi(Arc<WasmEditorApi>)
}
@ -76,7 +77,7 @@ macro_rules! tagged_value {
Self::None => concrete!(()),
$( Self::$identifier(_) => concrete!($ty), )*
Self::RenderOutput(_) => concrete!(RenderOutput),
Self::SurfaceFrame(_) => concrete!(graphene_core::SurfaceFrame),
Self::SurfaceFrame(_) => concrete!(SurfaceFrame),
Self::EditorApi(_) => concrete!(&WasmEditorApi)
}
}
@ -89,7 +90,7 @@ macro_rules! tagged_value {
x if x == TypeId::of::<()>() => Ok(TaggedValue::None),
$( x if x == TypeId::of::<$ty>() => Ok(TaggedValue::$identifier(*downcast(input).unwrap())), )*
x if x == TypeId::of::<RenderOutput>() => Ok(TaggedValue::RenderOutput(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::SurfaceFrame>() => Ok(TaggedValue::SurfaceFrame(*downcast(input).unwrap())),
x if x == TypeId::of::<SurfaceFrame>() => Ok(TaggedValue::SurfaceFrame(*downcast(input).unwrap())),
_ => Err(format!("Cannot convert {:?} to TaggedValue", DynAny::type_name(input.as_ref()))),
@ -103,7 +104,7 @@ macro_rules! tagged_value {
x if x == TypeId::of::<()>() => Ok(TaggedValue::None),
$( x if x == TypeId::of::<$ty>() => Ok(TaggedValue::$identifier(<$ty as Clone>::clone(input.downcast_ref().unwrap()))), )*
x if x == TypeId::of::<RenderOutput>() => Ok(TaggedValue::RenderOutput(RenderOutput::clone(input.downcast_ref().unwrap()))),
x if x == TypeId::of::<graphene_core::SurfaceFrame>() => Ok(TaggedValue::SurfaceFrame(graphene_core::SurfaceFrame::clone(input.downcast_ref().unwrap()))),
x if x == TypeId::of::<SurfaceFrame>() => Ok(TaggedValue::SurfaceFrame(SurfaceFrame::clone(input.downcast_ref().unwrap()))),
_ => Err(format!("Cannot convert {:?} to TaggedValue",std::any::type_name_of_val(input))),
}
}
@ -430,7 +431,7 @@ pub struct RenderOutput {
#[derive(Debug, Clone, PartialEq, dyn_any::DynAny, Hash, serde::Serialize, serde::Deserialize)]
pub enum RenderOutputType {
CanvasFrame(graphene_core::SurfaceFrame),
CanvasFrame(SurfaceFrame),
Svg(String),
Image(Vec<u8>),
}

View file

@ -1,5 +1,5 @@
use dyn_any::StaticType;
use graphene_core::application_io::{ApplicationError, ApplicationIo, ResourceFuture, SurfaceHandle, SurfaceId};
use graphene_application_io::{ApplicationError, ApplicationIo, ResourceFuture, SurfaceHandle, SurfaceId};
#[cfg(target_arch = "wasm32")]
use js_sys::{Object, Reflect};
use std::collections::HashMap;
@ -168,7 +168,7 @@ impl<'a> From<&'a WasmApplicationIo> for &'a WgpuExecutor {
}
}
pub type WasmEditorApi = graphene_core::application_io::EditorApi<WasmApplicationIo>;
pub type WasmEditorApi = graphene_application_io::EditorApi<WasmApplicationIo>;
impl ApplicationIo for WasmApplicationIo {
#[cfg(target_arch = "wasm32")]
@ -208,7 +208,7 @@ impl ApplicationIo for WasmApplicationIo {
// Use Reflect API to set property
Reflect::set(&canvases, &js_key, &js_value)?;
Ok::<_, JsValue>(SurfaceHandle {
window_id: graphene_core::SurfaceId(id),
window_id: SurfaceId(id),
surface: canvas,
})
};
@ -313,7 +313,7 @@ impl ApplicationIo for WasmApplicationIo {
#[cfg(feature = "wgpu")]
pub type WasmSurfaceHandle = SurfaceHandle<wgpu_executor::Window>;
#[cfg(feature = "wgpu")]
pub type WasmSurfaceHandleFrame = graphene_core::application_io::SurfaceHandleFrame<wgpu_executor::Window>;
pub type WasmSurfaceHandleFrame = graphene_application_io::SurfaceHandleFrame<wgpu_executor::Window>;
#[derive(Clone, Debug, PartialEq, Hash, specta::Type, serde::Serialize, serde::Deserialize)]
pub struct EditorPreferences {
@ -321,7 +321,7 @@ pub struct EditorPreferences {
pub use_vello: bool,
}
impl graphene_core::application_io::GetEditorPreferences for EditorPreferences {
impl graphene_application_io::GetEditorPreferences for EditorPreferences {
// fn hostname(&self) -> &str {
// &self.imaginate_hostname
// }

View file

@ -6,8 +6,8 @@ use graph_craft::graphene_compiler::{Compiler, Executor};
use graph_craft::proto::ProtoNetwork;
use graph_craft::util::load_network;
use graph_craft::wasm_application_io::EditorPreferences;
use graphene_core::application_io::{ApplicationIo, NodeGraphUpdateSender};
use graphene_core::text::FontCache;
use graphene_std::application_io::{ApplicationIo, NodeGraphUpdateMessage, NodeGraphUpdateSender, RenderConfig};
use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi};
use interpreted_executor::dynamic_executor::DynamicExecutor;
use interpreted_executor::util::wrap_network_in_scope;
@ -18,7 +18,7 @@ use std::sync::Arc;
struct UpdateLogger {}
impl NodeGraphUpdateSender for UpdateLogger {
fn send(&self, message: graphene_core::application_io::NodeGraphUpdateMessage) {
fn send(&self, message: NodeGraphUpdateMessage) {
println!("{message:?}");
}
}
@ -115,7 +115,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
}
});
let executor = create_executor(proto_graph)?;
let render_config = graphene_core::application_io::RenderConfig::default();
let render_config = RenderConfig::default();
loop {
let result = (&executor).execute(render_config).await?;

View file

@ -9,8 +9,8 @@ license = "MIT OR Apache-2.0"
[features]
default = ["wasm", "imaginate"]
gpu = []
wgpu = ["gpu", "graph-craft/wgpu"]
wasm = ["wasm-bindgen", "web-sys"]
wgpu = ["gpu", "graph-craft/wgpu", "graphene-application-io/wgpu"]
wasm = ["wasm-bindgen", "web-sys", "graphene-application-io/wasm"]
imaginate = ["image/png", "base64", "web-sys", "wasm-bindgen-futures"]
image-compare = []
vello = ["dep:vello", "gpu", "graphene-core/vello"]
@ -23,6 +23,7 @@ dyn-any = { workspace = true }
graph-craft = { workspace = true }
wgpu-executor = { workspace = true }
graphene-core = { workspace = true }
graphene-application-io = { workspace = true }
# Workspace dependencies
fastnoise-lite = { workspace = true }

View file

@ -10,4 +10,5 @@ pub mod vector;
#[cfg(feature = "wasm")]
pub mod wasm_application_io;
pub use graphene_application_io as application_io;
pub use graphene_core::*;

View file

@ -1,9 +1,7 @@
use graph_craft::document::value::RenderOutput;
pub use graph_craft::document::value::RenderOutputType;
pub use graph_craft::wasm_application_io::*;
#[cfg(target_arch = "wasm32")]
use graphene_core::application_io::SurfaceHandle;
use graphene_core::application_io::{ApplicationIo, ExportFormat, RenderConfig};
use graphene_application_io::{ApplicationIo, ExportFormat, RenderConfig};
#[cfg(target_arch = "wasm32")]
use graphene_core::instances::Instances;
#[cfg(target_arch = "wasm32")]
@ -127,7 +125,7 @@ async fn render_canvas(
surface_handle: wgpu_executor::WgpuSurface,
render_params: RenderParams,
) -> RenderOutputType {
use graphene_core::SurfaceFrame;
use graphene_application_io::SurfaceFrame;
let footprint = render_config.viewport;
let Some(exec) = editor.application_io.as_ref().unwrap().gpu_executor() else {
@ -172,7 +170,7 @@ async fn rasterize<T: WasmNotSend + 'n>(
)]
mut data: Instances<T>,
footprint: Footprint,
surface_handle: Arc<SurfaceHandle<HtmlCanvasElement>>,
surface_handle: Arc<graphene_application_io::SurfaceHandle<HtmlCanvasElement>>,
) -> RasterDataTable<CPU>
where
Instances<T>: GraphicElementRendered,

View file

@ -13,7 +13,7 @@ use graphene_core::{fn_type_fut, future};
use graphene_std::Context;
use graphene_std::GraphicElement;
use graphene_std::any::{ComposeTypeErased, DowncastBothNode, DynAnyNode, IntoTypeErasedNode};
use graphene_std::application_io::ImageTexture;
use graphene_std::application_io::{ImageTexture, SurfaceFrame};
use graphene_std::wasm_application_io::*;
use node_registry_macros::{async_node, into_node};
use once_cell::sync::Lazy;
@ -80,8 +80,8 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => WindowHandle]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Option<WgpuSurface>]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => WindowHandle]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => graphene_std::SurfaceFrame]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: UVec2, fn_params: [UVec2 => graphene_std::SurfaceFrame]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => SurfaceFrame]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: UVec2, fn_params: [UVec2 => SurfaceFrame]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => f64]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => String]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => RenderOutput]),

View file

@ -11,7 +11,8 @@ passthrough = []
[dependencies]
# Local dependencies
graphene-core = { workspace = true, features = ["wgpu"] }
graphene-core = { workspace = true, features = ["wgpu", "vello"] }
graphene-application-io = { workspace = true, features = ["wgpu"] }
dyn-any = { workspace = true }
node-macro = { workspace = true }

View file

@ -4,7 +4,7 @@ use anyhow::Result;
pub use context::Context;
use dyn_any::StaticType;
use glam::UVec2;
use graphene_core::application_io::{ApplicationIo, EditorApi, SurfaceHandle};
use graphene_application_io::{ApplicationIo, EditorApi, SurfaceHandle};
use graphene_core::{Color, Ctx};
use std::sync::Arc;
use vello::{AaConfig, AaSupport, RenderParams, Renderer, RendererOptions, Scene};
@ -31,7 +31,7 @@ impl<'a, T: ApplicationIo<Executor = WgpuExecutor>> From<&'a EditorApi<T>> for &
pub type WgpuSurface = Arc<SurfaceHandle<Surface>>;
pub type WgpuWindow = Arc<SurfaceHandle<WindowHandle>>;
impl graphene_core::application_io::Size for Surface {
impl graphene_application_io::Size for Surface {
fn size(&self) -> UVec2 {
self.resolution
}
@ -104,7 +104,7 @@ impl WgpuExecutor {
}
#[cfg(target_arch = "wasm32")]
pub fn create_surface(&self, canvas: graphene_core::WasmSurfaceHandle) -> Result<SurfaceHandle<Surface>> {
pub fn create_surface(&self, canvas: graphene_application_io::WasmSurfaceHandle) -> Result<SurfaceHandle<Surface>> {
let surface = self.context.instance.create_surface(wgpu::SurfaceTarget::Canvas(canvas.surface))?;
Ok(SurfaceHandle {