mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-04 06:18:11 +08:00
Reshape the extent trait to a written extent_at and a derived composite
This commit is contained in:
@@ -176,6 +176,26 @@ impl Extent {
|
|||||||
(Extent::Exactly(n), Extent::Exactly(m)) => GPoll::fallback(Extent::Exactly(n.min(m)), "extent mismatch"),
|
(Extent::Exactly(n), Extent::Exactly(m)) => GPoll::fallback(Extent::Exactly(n.min(m)), "extent mismatch"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The product of two extents, used to compose nested-level counts; an
|
||||||
|
/// unbounded operand leaves the product unbounded.
|
||||||
|
pub fn mul(a: GPoll<Extent>, b: GPoll<Extent>) -> GPoll<Extent> {
|
||||||
|
a.zip(b).map(|(a, b)| match (a, b) {
|
||||||
|
(Extent::Exactly(n), Extent::Exactly(m)) => Extent::Exactly(n * m),
|
||||||
|
_ => Extent::Free,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A query over a node's nesting levels: one level, the product below or above
|
||||||
|
/// it, or the whole domain. The composite [`Node::extent`](crate::node::Node::extent)
|
||||||
|
/// derives these from the per-level [`extent_at`](crate::node::Node::extent_at).
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum Level {
|
||||||
|
At(u8),
|
||||||
|
Below(u8),
|
||||||
|
Above(u8),
|
||||||
|
Total,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::context::InjectIndex;
|
use crate::context::InjectIndex;
|
||||||
use crate::gpoll::{Extent, Finality, GPoll, GraphError, Interrupt};
|
use crate::gpoll::{Extent, Finality, GPoll, GraphError, Interrupt, Level};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
@@ -177,18 +177,27 @@ pub trait Node<Input> {
|
|||||||
|
|
||||||
fn eval(&self, input: &Input) -> GPoll<Self::Output>;
|
fn eval(&self, input: &Input) -> GPoll<Self::Output>;
|
||||||
|
|
||||||
fn extent(&self, _input: &Input) -> GPoll<Extent> {
|
|
||||||
GPoll::Final(Extent::Free)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The count of items at one absolute nesting level (innermost `0`). The
|
/// The count of items at one absolute nesting level (innermost `0`). The
|
||||||
/// leveled primitive a structure node overrides to report a pushed level's
|
/// leveled primitive a structure node overrides to report a pushed level's
|
||||||
/// size; the scalar base is one item at every level. Uncertainty rides the
|
/// size; the scalar base is one item at every level. Uncertainty rides the
|
||||||
/// `GPoll` status axis, as with [`extent`](Node::extent).
|
/// `GPoll` status axis.
|
||||||
fn extent_at(&self, _input: &Input, _level: u8) -> GPoll<Extent> {
|
fn extent_at(&self, _input: &Input, _level: u8) -> GPoll<Extent> {
|
||||||
GPoll::Final(Extent::Exactly(1))
|
GPoll::Final(Extent::Exactly(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The composite domain query derived from [`extent_at`](Node::extent_at):
|
||||||
|
/// one level, the product of the levels below or above it, or the whole
|
||||||
|
/// domain's flat count. Consumers query this; nodes only write `extent_at`.
|
||||||
|
fn extent(&self, input: &Input, at: Level) -> GPoll<Extent> {
|
||||||
|
let product = |range: core::ops::Range<u8>| range.fold(GPoll::Final(Extent::Exactly(1)), |acc, level| Extent::mul(acc, self.extent_at(input, level)));
|
||||||
|
match at {
|
||||||
|
Level::At(level) => self.extent_at(input, level),
|
||||||
|
Level::Below(level) => product(0..level),
|
||||||
|
Level::Above(level) => product((level + 1)..self.depth()),
|
||||||
|
Level::Total => product(0..self.depth()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The node's domain depth (number of nesting levels; `0` = scalar), baked
|
/// The node's domain depth (number of nesting levels; `0` = scalar), baked
|
||||||
/// into the record layout at wiring.
|
/// into the record layout at wiring.
|
||||||
fn depth(&self) -> u8 {
|
fn depth(&self) -> u8 {
|
||||||
@@ -262,10 +271,6 @@ where
|
|||||||
(**self).eval(input)
|
(**self).eval(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extent(&self, input: &Input) -> GPoll<Extent> {
|
|
||||||
(**self).extent(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extent_at(&self, input: &Input, level: u8) -> GPoll<Extent> {
|
fn extent_at(&self, input: &Input, level: u8) -> GPoll<Extent> {
|
||||||
(**self).extent_at(input, level)
|
(**self).extent_at(input, level)
|
||||||
}
|
}
|
||||||
@@ -296,10 +301,6 @@ where
|
|||||||
(**self).eval(input)
|
(**self).eval(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extent(&self, input: &Input) -> GPoll<Extent> {
|
|
||||||
(**self).extent(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extent_at(&self, input: &Input, level: u8) -> GPoll<Extent> {
|
fn extent_at(&self, input: &Input, level: u8) -> GPoll<Extent> {
|
||||||
(**self).extent_at(input, level)
|
(**self).extent_at(input, level)
|
||||||
}
|
}
|
||||||
@@ -330,10 +331,6 @@ where
|
|||||||
(**self).eval(input)
|
(**self).eval(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extent(&self, input: &Input) -> GPoll<Extent> {
|
|
||||||
(**self).extent(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extent_at(&self, input: &Input, level: u8) -> GPoll<Extent> {
|
fn extent_at(&self, input: &Input, level: u8) -> GPoll<Extent> {
|
||||||
(**self).extent_at(input, level)
|
(**self).extent_at(input, level)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,11 +165,6 @@ where
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extent(&self, input: &Input) -> crate::gpoll::GPoll<crate::gpoll::Extent> {
|
|
||||||
// SAFETY: as in eval.
|
|
||||||
unsafe { self.ptr.as_ref() }.extent(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extent_at(&self, input: &Input, level: u8) -> crate::gpoll::GPoll<crate::gpoll::Extent> {
|
fn extent_at(&self, input: &Input, level: u8) -> crate::gpoll::GPoll<crate::gpoll::Extent> {
|
||||||
// SAFETY: as in eval.
|
// SAFETY: as in eval.
|
||||||
unsafe { self.ptr.as_ref() }.extent_at(input, level)
|
unsafe { self.ptr.as_ref() }.extent_at(input, level)
|
||||||
|
|||||||
@@ -1214,31 +1214,16 @@ pub(crate) fn generate_node_impl(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let value_field_names: Vec<&Ident> = regular_fields
|
// The extent override is the leveled `extent_at`; consumers query the
|
||||||
.iter()
|
// composite `extent(ctx, Level)`, which the trait derives from it. A node
|
||||||
.filter(|field| matches!(field.ty, ParsedFieldType::Regular(_)))
|
// without `extent = fn` keeps the scalar default (one item at every level).
|
||||||
.map(|field| &field.pat_ident.ident)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let extent_impl = match &parsed.attributes.extent {
|
let extent_impl = match &parsed.attributes.extent {
|
||||||
Some(path) => quote! {
|
Some(path) => quote! {
|
||||||
fn extent(&self, __input: &#ctx_ident) -> #core_types::gpoll::GPoll<#core_types::gpoll::Extent> {
|
fn extent_at(&self, __input: &#ctx_ident, __level: u8) -> #core_types::gpoll::GPoll<#core_types::gpoll::Extent> {
|
||||||
#path(self, __input)
|
#path(self, __input, __level)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None if value_field_names.is_empty() => quote!(),
|
None => quote!(),
|
||||||
None => {
|
|
||||||
let first = value_field_names[0];
|
|
||||||
let mut meet = quote!(self.#first.extent(__input));
|
|
||||||
for name in &value_field_names[1..] {
|
|
||||||
meet = quote!(#core_types::gpoll::Extent::meet(#meet, self.#name.extent(__input)));
|
|
||||||
}
|
|
||||||
quote! {
|
|
||||||
fn extent(&self, __input: &#ctx_ident) -> #core_types::gpoll::GPoll<#core_types::gpoll::Extent> {
|
|
||||||
#meet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let serialize_impl = match &parsed.attributes.serialize {
|
let serialize_impl = match &parsed.attributes.serialize {
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ fn memoize<'e>(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn memoize_extent<C, NodeContent>(node: &MemoizeNode<NodeContent>, ctx: &C) -> GPoll<Extent>
|
fn memoize_extent<C, NodeContent>(node: &MemoizeNode<NodeContent>, ctx: &C, level: u8) -> GPoll<Extent>
|
||||||
where
|
where
|
||||||
NodeContent: Node<C>,
|
NodeContent: Node<C>,
|
||||||
{
|
{
|
||||||
node.content.extent(ctx)
|
node.content.extent_at(ctx, level)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[node_macro::node(category(""), path(graphene_core::memo), extent(frame_memo_extent))]
|
#[node_macro::node(category(""), path(graphene_core::memo), extent(frame_memo_extent))]
|
||||||
@@ -95,11 +95,11 @@ fn frame_memo<'e>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frame_memo_extent<C, NodeContent>(node: &FrameMemoNode<NodeContent>, ctx: &C) -> GPoll<Extent>
|
fn frame_memo_extent<C, NodeContent>(node: &FrameMemoNode<NodeContent>, ctx: &C, level: u8) -> GPoll<Extent>
|
||||||
where
|
where
|
||||||
NodeContent: Node<C>,
|
NodeContent: Node<C>,
|
||||||
{
|
{
|
||||||
node.content.extent(ctx)
|
node.content.extent_at(ctx, level)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MonitorValue = Arc<Mutex<Option<IORecord<CtxSnapshot, RecordCapture>>>>;
|
type MonitorValue = Arc<Mutex<Option<IORecord<CtxSnapshot, RecordCapture>>>>;
|
||||||
|
|||||||
Reference in New Issue
Block a user