mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-24 05:28:11 +08:00
Cut over to the graphene execution model
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use core_types::gpoll::Interrupt;
|
||||
use core_types::list::{Item, List};
|
||||
use core_types::transform::TransformMut;
|
||||
use core_types::{ATTR_BACKGROUND, ATTR_CLIP, ATTR_DIMENSIONS, ATTR_LOCATION, CloneVarArgs, Color, Context, Ctx, ExtractAll, OwnedContextImpl};
|
||||
use core_types::{ATTR_BACKGROUND, ATTR_CLIP, ATTR_DIMENSIONS, ATTR_LOCATION, Color, Context, Ctx, DeriveCtx, ModifyFootprint};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphic_types::graphic::{Graphic, IntoGraphicList};
|
||||
use graphic_types::{Artboard, Vector};
|
||||
@@ -9,8 +10,8 @@ use vector_types::GradientStops;
|
||||
|
||||
/// Constructs a single-element `Artboard[]` with the given content and metadata stored as row attributes.
|
||||
#[node_macro::node(category(""))]
|
||||
pub async fn create_artboard<T: IntoGraphicList>(
|
||||
ctx: impl ExtractAll + CloneVarArgs + Ctx,
|
||||
pub fn create_artboard<T: IntoGraphicList>(
|
||||
ctx: impl Ctx + DeriveCtx + ModifyFootprint,
|
||||
/// Graphics to include within the artboard.
|
||||
#[implementations(
|
||||
Context -> List<Graphic>,
|
||||
@@ -22,7 +23,7 @@ pub async fn create_artboard<T: IntoGraphicList>(
|
||||
Context -> List<GradientStops>,
|
||||
Context -> DAffine2,
|
||||
)]
|
||||
content: impl Node<Context<'static>, Output = T>,
|
||||
content: impl Node<Context<'_>, Output = T>,
|
||||
/// Coordinate of the top-left corner of the artboard within the document.
|
||||
location: DVec2,
|
||||
/// Width and height of the artboard within the document.
|
||||
@@ -32,14 +33,9 @@ pub async fn create_artboard<T: IntoGraphicList>(
|
||||
/// Whether to cut off the contained content that extends outside the artboard, or keep it visible.
|
||||
#[default(true)]
|
||||
clip: bool,
|
||||
) -> List<Artboard> {
|
||||
let footprint = ctx.try_footprint().copied();
|
||||
let mut new_ctx = OwnedContextImpl::from(ctx);
|
||||
if let Some(mut footprint) = footprint {
|
||||
footprint.translate(location);
|
||||
new_ctx = new_ctx.with_footprint(footprint);
|
||||
}
|
||||
let content = content.eval(new_ctx.into_context()).await.into_graphic_list();
|
||||
) -> Result<List<Artboard>, Interrupt> {
|
||||
let translated = ctx.modify_footprint(|footprint| footprint.translate(location));
|
||||
let content = content.eval(&translated.ctx())?.into_graphic_list();
|
||||
|
||||
// Normalize so `location` is the top-left corner and `dimensions` are positive (allowing negative input
|
||||
// dimensions to represent dragging from the opposite corner). Compute the corner using the raw signed
|
||||
@@ -50,11 +46,11 @@ pub async fn create_artboard<T: IntoGraphicList>(
|
||||
let background = background.element(0).copied().unwrap_or(Color::WHITE);
|
||||
|
||||
// Name is not stored here, it's resolved live from the parent layer's display name
|
||||
List::new_from_item(
|
||||
Ok(List::new_from_item(
|
||||
Item::new_from_element(Artboard::new(content))
|
||||
.with_attribute(ATTR_LOCATION, normalized_location)
|
||||
.with_attribute(ATTR_DIMENSIONS, normalized_dimensions)
|
||||
.with_attribute(ATTR_BACKGROUND, background)
|
||||
.with_attribute(ATTR_CLIP, clip),
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use core_types::bounds::{BoundingBox, RenderBoundingBox};
|
||||
use core_types::gpoll::Interrupt;
|
||||
use core_types::list::{AttributeDyn, AttributeValueDyn, Item, List, ListDyn};
|
||||
use core_types::registry::types::{Angle, SignedInteger};
|
||||
use core_types::uuid::NodeId;
|
||||
use core_types::{ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_TRANSFORM, AnyHash, BlendMode, CacheHash, CloneVarArgs, Color, Context, Ctx, ExtractAll, OwnedContextImpl};
|
||||
use core_types::{ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_TRANSFORM, AnyHash, BlendMode, CacheHash, Color, Context, Ctx, DeriveCtx};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphic_types::graphic::{Graphic, IntoGraphicList};
|
||||
use graphic_types::{Artboard, Vector};
|
||||
@@ -108,8 +109,8 @@ pub fn extract_element<T: Clone + Default + Send + Sync + 'static>(
|
||||
}
|
||||
|
||||
#[node_macro::node(category("General"))]
|
||||
async fn map<Item: AnyHash + Send + Sync + CacheHash>(
|
||||
ctx: impl Ctx + CloneVarArgs + ExtractAll,
|
||||
fn map<Item: AnyHash + Clone + Send + Sync + CacheHash>(
|
||||
ctx: impl Ctx + DeriveCtx,
|
||||
#[implementations(
|
||||
List<Graphic>,
|
||||
List<Vector>,
|
||||
@@ -127,23 +128,24 @@ async fn map<Item: AnyHash + Send + Sync + CacheHash>(
|
||||
Context -> List<GradientStops>,
|
||||
Context -> List<String>,
|
||||
)]
|
||||
mapped: impl Node<Context<'static>, Output = List<Item>>,
|
||||
) -> List<Item> {
|
||||
mapped: impl Node<Context<'_>, Output = List<Item>>,
|
||||
) -> Result<List<Item>, Interrupt> {
|
||||
let spilled = ctx.index_head();
|
||||
let mut rows = List::new();
|
||||
|
||||
for (i, row) in content.into_iter().enumerate() {
|
||||
let owned_ctx = OwnedContextImpl::from(ctx.clone());
|
||||
let owned_ctx = owned_ctx.with_vararg(Box::new(List::new_from_item(row))).with_index(i);
|
||||
let list = mapped.eval(owned_ctx.into_context()).await;
|
||||
let item = List::new_from_item(row);
|
||||
let scoped = ctx.push_vararg(&item);
|
||||
let list = mapped.eval(&scoped.ctx().promoted(&spilled, i as u64))?;
|
||||
|
||||
rows.extend(list);
|
||||
}
|
||||
|
||||
rows
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
#[node_macro::node(category("General"))]
|
||||
async fn mirror<T: 'n + Send + Clone>(
|
||||
fn mirror<T: Send + Clone>(
|
||||
_: impl Ctx,
|
||||
#[implementations(
|
||||
List<Graphic>,
|
||||
@@ -229,8 +231,8 @@ pub fn path_of_subgraph(_: impl Ctx, node_path: List<NodeId>) -> List<NodeId> {
|
||||
/// The value is type-erased into an `AttributeValueDyn` by an auto-inserted convert node, so this node only
|
||||
/// monomorphizes over `T` instead of the cartesian product `(T, U)`.
|
||||
#[node_macro::node(category("Attributes: Write"))]
|
||||
async fn write_attribute<T: AnyHash + Clone + Send + Sync + CacheHash>(
|
||||
ctx: impl ExtractAll + CloneVarArgs + Ctx,
|
||||
fn write_attribute<T: AnyHash + Clone + Send + Sync + CacheHash>(
|
||||
ctx: impl Ctx + DeriveCtx,
|
||||
/// The `List` to set the named attribute on (one value per item).
|
||||
#[implementations(
|
||||
List<Artboard>,
|
||||
@@ -252,15 +254,17 @@ async fn write_attribute<T: AnyHash + Clone + Send + Sync + CacheHash>(
|
||||
name: String,
|
||||
/// The node that produces the attribute value for each item. Called once per item with the item's index in context.
|
||||
#[implementations(Context -> AttributeValueDyn)]
|
||||
value: impl Node<'n, Context<'static>, Output = AttributeValueDyn>,
|
||||
) -> List<T> {
|
||||
value: impl Node<Context<'_>, Output = AttributeValueDyn>,
|
||||
) -> Result<List<T>, Interrupt> {
|
||||
let spilled = ctx.index_head();
|
||||
for index in 0..content.len() {
|
||||
let row = content.clone_item(index).expect("index is within bounds");
|
||||
let owned_ctx = OwnedContextImpl::from(ctx.clone()).with_vararg(Box::new(List::new_from_item(row))).with_index(index);
|
||||
let v = value.eval(owned_ctx.into_context()).await;
|
||||
let item = List::new_from_item(row);
|
||||
let scoped = ctx.push_vararg(&item);
|
||||
let v = value.eval(&scoped.ctx().promoted(&spilled, index as u64))?;
|
||||
content.set_attribute_value_dyn(&name, index, v);
|
||||
}
|
||||
content
|
||||
Ok(content)
|
||||
}
|
||||
|
||||
/// Sets a named attribute on the primary list, with each value taken from the corresponding item's element in the source list (paired by index, wrapping if the source has fewer items).
|
||||
@@ -497,7 +501,7 @@ fn read_attribute_raster(
|
||||
|
||||
/// Joins two `List`s of the same type, extending the base `List` with the items from the new `List`.
|
||||
#[node_macro::node(category("General"))]
|
||||
pub async fn extend<T: 'n + Send + Clone>(
|
||||
pub fn extend<T: Send + Clone>(
|
||||
_: impl Ctx,
|
||||
/// The `List` whose items will appear at the start of the extended `List`.
|
||||
#[implementations(List<Artboard>, List<Graphic>, List<Vector>, List<String>, List<Raster<CPU>>, List<Raster<GPU>>, List<Color>, List<GradientStops>)]
|
||||
@@ -517,7 +521,7 @@ pub async fn extend<T: 'n + Send + Clone>(
|
||||
/// Performs an obsolete function as part of a migration from an older document format.
|
||||
/// Users are advised to delete this node and replace it with a new one.
|
||||
#[node_macro::node(category(""))]
|
||||
pub async fn legacy_layer_extend<T: 'n + Send + Clone>(
|
||||
pub fn legacy_layer_extend<T: Send + Clone>(
|
||||
_: impl Ctx,
|
||||
#[implementations(List<Artboard>, List<Graphic>, List<Vector>, List<String>, List<Raster<CPU>>, List<Raster<GPU>>, List<Color>, List<GradientStops>)] base: List<T>,
|
||||
#[expose]
|
||||
@@ -544,7 +548,7 @@ pub async fn legacy_layer_extend<T: 'n + Send + Clone>(
|
||||
/// Nests the input graphical content in a wrapper graphic. This essentially "groups" the input.
|
||||
/// The inverse of this node is 'Flatten Graphic'.
|
||||
#[node_macro::node(category("General"))]
|
||||
pub async fn wrap_graphic<T: Into<Graphic> + 'n>(
|
||||
pub fn wrap_graphic<T: Into<Graphic>>(
|
||||
_: impl Ctx,
|
||||
#[implementations(
|
||||
List<Graphic>,
|
||||
@@ -565,7 +569,7 @@ pub async fn wrap_graphic<T: Into<Graphic> + 'n>(
|
||||
/// Converts a list of graphical content into a `Graphic[]` by placing it into an element of a new wrapper `Graphic[]`.
|
||||
/// If it is already a `Graphic[]`, it is not wrapped again. Use the 'Wrap Graphic' node if wrapping is always desired.
|
||||
#[node_macro::node(category("General"))]
|
||||
pub async fn to_graphic<T: IntoGraphicList>(
|
||||
pub fn to_graphic<T: IntoGraphicList>(
|
||||
_: impl Ctx,
|
||||
#[implementations(
|
||||
List<Graphic>,
|
||||
@@ -583,7 +587,7 @@ pub async fn to_graphic<T: IntoGraphicList>(
|
||||
|
||||
/// Removes a level of nesting from a `Graphic[]`, or all nesting if "Fully Flatten" is enabled.
|
||||
#[node_macro::node(category("General"))]
|
||||
pub async fn flatten_graphic(_: impl Ctx, content: List<Graphic>, fully_flatten: bool) -> List<Graphic> {
|
||||
pub fn flatten_graphic(_: impl Ctx, content: List<Graphic>, fully_flatten: bool) -> List<Graphic> {
|
||||
// TODO: Avoid mutable reference, instead return a new List<Graphic>?
|
||||
fn flatten_list(output_graphic_list: &mut List<Graphic>, current_graphic_list: List<Graphic>, fully_flatten: bool, recursion_depth: usize) {
|
||||
for index in 0..current_graphic_list.len() {
|
||||
@@ -620,7 +624,7 @@ pub async fn flatten_graphic(_: impl Ctx, content: List<Graphic>, fully_flatten:
|
||||
|
||||
/// Converts a `Graphic[]` into a `Vector[]` by deeply flattening any vector content it contains, and discarding any non-vector content.
|
||||
#[node_macro::node(category("Vector"))]
|
||||
pub async fn flatten_vector<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Vector>)] content: T) -> List<Vector> {
|
||||
pub fn flatten_vector<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Vector>)] content: T) -> List<Vector> {
|
||||
let graphic_list = content.into_graphic_list();
|
||||
let mut output: List<Vector> = graphic_list.clone().into_flattened_list();
|
||||
|
||||
@@ -653,19 +657,19 @@ pub async fn flatten_vector<T: IntoGraphicList>(_: impl Ctx, #[implementations(L
|
||||
|
||||
/// Converts a `Graphic[]` into a `Raster[]` by deeply flattening any raster content it contains, and discarding any non-raster content.
|
||||
#[node_macro::node(category("Raster"))]
|
||||
pub async fn flatten_raster<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Raster<CPU>>)] content: T) -> List<Raster<CPU>> {
|
||||
pub fn flatten_raster<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Raster<CPU>>)] content: T) -> List<Raster<CPU>> {
|
||||
content.into_flattened_list()
|
||||
}
|
||||
|
||||
/// Converts a `Graphic[]` into a `Color[]` by deeply flattening any color content it contains, and discarding any non-color content.
|
||||
#[node_macro::node(category("General"))]
|
||||
pub async fn flatten_color<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Color>)] content: T) -> List<Color> {
|
||||
pub fn flatten_color<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Color>)] content: T) -> List<Color> {
|
||||
content.into_flattened_list()
|
||||
}
|
||||
|
||||
/// Converts a `Graphic[]` into a `GradientStops[]` by deeply flattening any gradient content it contains, and discarding any non-gradient content.
|
||||
#[node_macro::node(category("General"))]
|
||||
pub async fn flatten_gradient<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<GradientStops>)] content: T) -> List<GradientStops> {
|
||||
pub fn flatten_gradient<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<GradientStops>)] content: T) -> List<GradientStops> {
|
||||
content.into_flattened_list()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user