mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-07 15:55:00 +00:00
Bulk gcore
cleanup, replace core
and alloc
with std
(#2735)
* gcore: replace `core` and `alloc` paths with `std` * node-graph: remove unnecessary path prefix * gcore: remove most `#[cfg(target_arch = "spirv")]`, keep some potentially useful ones --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
301368a0df
commit
990d5b37cf
46 changed files with 287 additions and 313 deletions
|
@ -1,22 +1,22 @@
|
|||
use crate::text::FontCache;
|
||||
use crate::transform::Footprint;
|
||||
use crate::vector::style::ViewMode;
|
||||
use alloc::sync::Arc;
|
||||
use core::fmt::Debug;
|
||||
use core::future::Future;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::pin::Pin;
|
||||
use core::ptr::addr_of;
|
||||
use core::time::Duration;
|
||||
use dyn_any::{DynAny, StaticType, StaticTypeSized};
|
||||
use glam::{DAffine2, UVec2};
|
||||
use std::fmt::Debug;
|
||||
use std::future::Future;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::pin::Pin;
|
||||
use std::ptr::addr_of;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct SurfaceId(pub u64);
|
||||
|
||||
impl core::fmt::Display for SurfaceId {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
impl std::fmt::Display for SurfaceId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!("{}", self.0))
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ impl<Io> PartialEq for EditorApi<Io> {
|
|||
}
|
||||
|
||||
impl<T> Debug for EditorApi<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("EditorApi").field("font_cache", &self.font_cache).finish()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::transform::Footprint;
|
||||
use core::any::Any;
|
||||
use core::borrow::Borrow;
|
||||
use core::panic::Location;
|
||||
use std::any::Any;
|
||||
use std::borrow::Borrow;
|
||||
use std::panic::Location;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait Ctx: Clone + Send {}
|
||||
|
@ -240,7 +240,7 @@ type DynBox = Box<dyn Any + Send + Sync>;
|
|||
|
||||
#[derive(dyn_any::DynAny)]
|
||||
pub struct OwnedContextImpl {
|
||||
footprint: Option<crate::transform::Footprint>,
|
||||
footprint: Option<Footprint>,
|
||||
varargs: Option<Arc<[DynBox]>>,
|
||||
parent: Option<Arc<dyn ExtractVarArgs + Sync + Send>>,
|
||||
// This could be converted into a single enum to save extra bytes
|
||||
|
@ -249,8 +249,8 @@ pub struct OwnedContextImpl {
|
|||
animation_time: Option<f64>,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for OwnedContextImpl {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
impl std::fmt::Debug for OwnedContextImpl {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("OwnedContextImpl")
|
||||
.field("footprint", &self.footprint)
|
||||
.field("varargs", &self.varargs)
|
||||
|
@ -269,8 +269,8 @@ impl Default for OwnedContextImpl {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::hash::Hash for OwnedContextImpl {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for OwnedContextImpl {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.footprint.hash(state);
|
||||
self.varargs.as_ref().map(|x| Arc::as_ptr(x).addr()).hash(state);
|
||||
self.parent.as_ref().map(|x| Arc::as_ptr(x).addr()).hash(state);
|
||||
|
@ -348,7 +348,7 @@ impl OwnedContextImpl {
|
|||
|
||||
#[derive(Default, Clone, Copy, dyn_any::DynAny)]
|
||||
pub struct ContextImpl<'a> {
|
||||
pub(crate) footprint: Option<&'a crate::transform::Footprint>,
|
||||
pub(crate) footprint: Option<&'a Footprint>,
|
||||
varargs: Option<&'a [DynRef<'a>]>,
|
||||
// This could be converted into a single enum to save extra bytes
|
||||
index: Option<usize>,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::Node;
|
||||
use core::marker::PhantomData;
|
||||
use std::marker::PhantomData;
|
||||
#[derive(Clone)]
|
||||
pub struct FnNode<T: Fn(I) -> O, I, O>(T, PhantomData<(I, O)>);
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ impl Default for AlphaBlending {
|
|||
Self::new()
|
||||
}
|
||||
}
|
||||
impl core::hash::Hash for AlphaBlending {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl Hash for AlphaBlending {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.opacity.to_bits().hash(state);
|
||||
self.fill.to_bits().hash(state);
|
||||
self.blend_mode.hash(state);
|
||||
|
|
|
@ -39,7 +39,7 @@ impl FreePoint {
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ClickTargetType {
|
||||
Subpath(bezier_rs::Subpath<PointId>),
|
||||
Subpath(Subpath<PointId>),
|
||||
FreePoint(FreePoint),
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ impl MaskType {
|
|||
}
|
||||
|
||||
impl ClickTarget {
|
||||
pub fn new_with_subpath(subpath: bezier_rs::Subpath<PointId>, stroke_width: f64) -> Self {
|
||||
pub fn new_with_subpath(subpath: Subpath<PointId>, stroke_width: f64) -> Self {
|
||||
let bounding_box = subpath.loose_bounding_box();
|
||||
Self {
|
||||
target_type: ClickTargetType::Subpath(subpath),
|
||||
|
@ -300,7 +300,7 @@ impl Default for SvgRender {
|
|||
#[derive(Clone, Debug, Default)]
|
||||
pub struct RenderContext {
|
||||
#[cfg(feature = "wgpu")]
|
||||
pub resource_overrides: std::collections::HashMap<u64, alloc::sync::Arc<wgpu::Texture>>,
|
||||
pub resource_overrides: HashMap<u64, std::sync::Arc<wgpu::Texture>>,
|
||||
}
|
||||
|
||||
/// Static state used whilst rendering
|
||||
|
@ -468,7 +468,7 @@ impl GraphicElementRendered for GraphicGroupTable {
|
|||
peniko::BlendMode::new(blend_mode, peniko::Compose::SrcOver),
|
||||
opacity,
|
||||
kurbo::Affine::IDENTITY,
|
||||
&vello::kurbo::Rect::new(bounds[0].x, bounds[0].y, bounds[1].x, bounds[1].y),
|
||||
&kurbo::Rect::new(bounds[0].x, bounds[0].y, bounds[1].x, bounds[1].y),
|
||||
);
|
||||
layer = true;
|
||||
}
|
||||
|
@ -756,9 +756,9 @@ impl GraphicElementRendered for VectorDataTable {
|
|||
let outline_stroke = kurbo::Stroke {
|
||||
width: LAYER_OUTLINE_STROKE_WEIGHT,
|
||||
miter_limit: 4.,
|
||||
join: kurbo::Join::Miter,
|
||||
start_cap: kurbo::Cap::Butt,
|
||||
end_cap: kurbo::Cap::Butt,
|
||||
join: Join::Miter,
|
||||
start_cap: Cap::Butt,
|
||||
end_cap: Cap::Butt,
|
||||
dash_pattern: Default::default(),
|
||||
dash_offset: 0.,
|
||||
};
|
||||
|
@ -913,7 +913,7 @@ impl GraphicElementRendered for VectorDataTable {
|
|||
if let Some(element_id) = element_id {
|
||||
let stroke_width = instance.style.stroke().as_ref().map_or(0., Stroke::weight);
|
||||
let filled = instance.style.fill() != &Fill::None;
|
||||
let fill = |mut subpath: bezier_rs::Subpath<_>| {
|
||||
let fill = |mut subpath: Subpath<_>| {
|
||||
if filled {
|
||||
subpath.set_closed(true);
|
||||
}
|
||||
|
@ -953,7 +953,7 @@ impl GraphicElementRendered for VectorDataTable {
|
|||
for instance in self.instance_ref_iter() {
|
||||
let stroke_width = instance.instance.style.stroke().as_ref().map_or(0., Stroke::weight);
|
||||
let filled = instance.instance.style.fill() != &Fill::None;
|
||||
let fill = |mut subpath: bezier_rs::Subpath<_>| {
|
||||
let fill = |mut subpath: Subpath<_>| {
|
||||
if filled {
|
||||
subpath.set_closed(true);
|
||||
}
|
||||
|
@ -1186,10 +1186,10 @@ impl GraphicElementRendered for RasterDataTable<CPU> {
|
|||
if image.data.is_empty() {
|
||||
return;
|
||||
}
|
||||
let image = vello::peniko::Image::new(image.to_flat_u8().0.into(), peniko::Format::Rgba8, image.width, image.height).with_extend(peniko::Extend::Repeat);
|
||||
let image = peniko::Image::new(image.to_flat_u8().0.into(), peniko::Format::Rgba8, image.width, image.height).with_extend(peniko::Extend::Repeat);
|
||||
let transform = transform * *instance.transform * DAffine2::from_scale(1. / DVec2::new(image.width as f64, image.height as f64));
|
||||
|
||||
scene.draw_image(&image, vello::kurbo::Affine::new(transform.to_cols_array()));
|
||||
scene.draw_image(&image, kurbo::Affine::new(transform.to_cols_array()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1385,7 +1385,7 @@ impl GraphicElementRendered for GraphicElement {
|
|||
}
|
||||
|
||||
/// Used to stop rust complaining about upstream traits adding display implementations to `Option<Color>`. This would not be an issue as we control that crate.
|
||||
trait Primitive: core::fmt::Display {}
|
||||
trait Primitive: std::fmt::Display {}
|
||||
impl Primitive for String {}
|
||||
impl Primitive for bool {}
|
||||
impl Primitive for f32 {}
|
||||
|
|
|
@ -143,7 +143,7 @@ impl Quad {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::ops::Mul<Quad> for DAffine2 {
|
||||
impl std::ops::Mul<Quad> for DAffine2 {
|
||||
type Output = Quad;
|
||||
|
||||
fn mul(self, rhs: Quad) -> Self::Output {
|
||||
|
|
|
@ -97,21 +97,21 @@ impl Rect {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::ops::Mul<Rect> for DAffine2 {
|
||||
type Output = super::Quad;
|
||||
impl std::ops::Mul<Rect> for DAffine2 {
|
||||
type Output = Quad;
|
||||
|
||||
fn mul(self, rhs: Rect) -> Self::Output {
|
||||
self * super::Quad::from_box(rhs.0)
|
||||
self * Quad::from_box(rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::Index<usize> for Rect {
|
||||
impl std::ops::Index<usize> for Rect {
|
||||
type Output = DVec2;
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
&self.0[index]
|
||||
}
|
||||
}
|
||||
impl core::ops::IndexMut<usize> for Rect {
|
||||
impl std::ops::IndexMut<usize> for Rect {
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
&mut self.0[index]
|
||||
}
|
||||
|
|
|
@ -128,8 +128,8 @@ impl<T> Default for Instances<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Hash> core::hash::Hash for Instances<T> {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl<T: Hash> Hash for Instances<T> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
for instance in &self.instance {
|
||||
instance.hash(state);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
extern crate alloc;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
pub use crate as graphene_core;
|
||||
pub use num_traits;
|
||||
|
||||
pub use crate as graphene_core;
|
||||
pub use ctor;
|
||||
pub use num_traits;
|
||||
|
||||
pub mod animation;
|
||||
pub mod consts;
|
||||
|
@ -35,12 +33,12 @@ pub mod application_io;
|
|||
pub mod registry;
|
||||
|
||||
pub use context::*;
|
||||
use core::any::TypeId;
|
||||
use core::future::Future;
|
||||
use core::pin::Pin;
|
||||
pub use dyn_any::{StaticTypeSized, WasmNotSend, WasmNotSync};
|
||||
pub use memo::MemoHash;
|
||||
pub use raster::Color;
|
||||
use std::any::TypeId;
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
pub use types::Cow;
|
||||
|
||||
// pub trait Node: for<'n> NodeIO<'n> {
|
||||
|
@ -54,11 +52,11 @@ pub trait Node<'i, Input> {
|
|||
fn reset(&self) {}
|
||||
/// Returns the name of the node for diagnostic purposes.
|
||||
fn node_name(&self) -> &'static str {
|
||||
core::any::type_name::<Self>()
|
||||
std::any::type_name::<Self>()
|
||||
}
|
||||
/// Serialize the node which is used for the `introspect` function which can retrieve values from monitor nodes.
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn core::any::Any + Send + Sync>> {
|
||||
log::warn!("Node::serialize not implemented for {}", core::any::type_name::<Self>());
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn std::any::Any + Send + Sync>> {
|
||||
log::warn!("Node::serialize not implemented for {}", std::any::type_name::<Self>());
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -75,13 +73,13 @@ where
|
|||
TypeId::of::<Input::Static>()
|
||||
}
|
||||
fn input_type_name(&self) -> &'static str {
|
||||
core::any::type_name::<Input>()
|
||||
std::any::type_name::<Input>()
|
||||
}
|
||||
fn output_type(&self) -> core::any::TypeId {
|
||||
fn output_type(&self) -> TypeId {
|
||||
TypeId::of::<<Self::Output as StaticTypeSized>::Static>()
|
||||
}
|
||||
fn output_type_name(&self) -> &'static str {
|
||||
core::any::type_name::<Self::Output>()
|
||||
std::any::type_name::<Self::Output>()
|
||||
}
|
||||
fn to_node_io(&self, inputs: Vec<Type>) -> NodeIOTypes {
|
||||
NodeIOTypes {
|
||||
|
@ -122,7 +120,7 @@ impl<'i, I: 'i, O: 'i, N: Node<'i, I, Output = O> + ?Sized> Node<'i, I> for Box<
|
|||
(**self).eval(input)
|
||||
}
|
||||
}
|
||||
impl<'i, I: 'i, O: 'i, N: Node<'i, I, Output = O> + ?Sized> Node<'i, I> for alloc::sync::Arc<N> {
|
||||
impl<'i, I: 'i, O: 'i, N: Node<'i, I, Output = O> + ?Sized> Node<'i, I> for std::sync::Arc<N> {
|
||||
type Output = O;
|
||||
fn eval(&'i self, input: I) -> O {
|
||||
(**self).eval(input)
|
||||
|
@ -148,7 +146,7 @@ pub type WasmSurfaceHandle = application_io::SurfaceHandle<web_sys::HtmlCanvasEl
|
|||
#[cfg(feature = "wasm")]
|
||||
pub type WasmSurfaceHandleFrame = application_io::SurfaceHandleFrame<web_sys::HtmlCanvasElement>;
|
||||
|
||||
pub trait InputAccessorSource<'a, T>: InputAccessorSourceIdentifier + core::fmt::Debug {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -3,15 +3,14 @@ use crate::{Color, Context, Ctx};
|
|||
use glam::{DAffine2, DVec2};
|
||||
|
||||
#[node_macro::node(category("Debug"))]
|
||||
fn log_to_console<T: core::fmt::Debug>(_: impl Ctx, #[implementations(String, bool, f64, u32, u64, DVec2, VectorDataTable, DAffine2, Color, Option<Color>)] value: T) -> T {
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
fn log_to_console<T: std::fmt::Debug>(_: impl Ctx, #[implementations(String, bool, f64, u32, u64, DVec2, VectorDataTable, DAffine2, Color, Option<Color>)] value: T) -> T {
|
||||
// KEEP THIS `debug!()` - It acts as the output for the debug node itself
|
||||
log::debug!("{:#?}", value);
|
||||
value
|
||||
}
|
||||
|
||||
#[node_macro::node(category("Text"))]
|
||||
fn to_string<T: core::fmt::Debug>(_: impl Ctx, #[implementations(String, bool, f64, u32, u64, DVec2, VectorDataTable, DAffine2)] value: T) -> String {
|
||||
fn to_string<T: std::fmt::Debug>(_: impl Ctx, #[implementations(String, bool, f64, u32, u64, DVec2, VectorDataTable, DAffine2)] value: T) -> String {
|
||||
format!("{:?}", value)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::{Node, WasmNotSend};
|
||||
use alloc::sync::Arc;
|
||||
use core::future::Future;
|
||||
use core::ops::Deref;
|
||||
use dyn_any::DynFuture;
|
||||
use std::future::Future;
|
||||
use std::hash::DefaultHasher;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// Caches the output of a given Node and acts as a proxy
|
||||
|
@ -15,7 +15,7 @@ pub struct MemoNode<T, CachedNode> {
|
|||
impl<'i, I: Hash + 'i, T: 'i + Clone + WasmNotSend, CachedNode: 'i> Node<'i, I> for MemoNode<T, CachedNode>
|
||||
where
|
||||
CachedNode: for<'any_input> Node<'any_input, I>,
|
||||
for<'a> <CachedNode as Node<'a, I>>::Output: core::future::Future<Output = T> + WasmNotSend,
|
||||
for<'a> <CachedNode as Node<'a, I>>::Output: Future<Output = T> + WasmNotSend,
|
||||
{
|
||||
// TODO: This should return a reference to the cached cached_value
|
||||
// but that requires a lot of lifetime magic <- This was suggested by copilot but is pretty accurate xD
|
||||
|
@ -63,7 +63,7 @@ pub struct ImpureMemoNode<I, T, CachedNode> {
|
|||
impl<'i, I: 'i, T: 'i + Clone + WasmNotSend, CachedNode: 'i> Node<'i, I> for ImpureMemoNode<I, T, CachedNode>
|
||||
where
|
||||
CachedNode: for<'any_input> Node<'any_input, I>,
|
||||
for<'a> <CachedNode as Node<'a, I>>::Output: core::future::Future<Output = T> + WasmNotSend,
|
||||
for<'a> <CachedNode as Node<'a, I>>::Output: Future<Output = T> + WasmNotSend,
|
||||
{
|
||||
// TODO: This should return a reference to the cached cached_value
|
||||
// but that requires a lot of lifetime magic <- This was suggested by copilot but is pretty accurate xD
|
||||
|
@ -93,7 +93,7 @@ impl<T, I, CachedNode> ImpureMemoNode<I, T, CachedNode> {
|
|||
ImpureMemoNode {
|
||||
cache: Default::default(),
|
||||
node,
|
||||
_phantom: core::marker::PhantomData,
|
||||
_phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,9 +130,9 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Option<Arc<dyn core::any::Any + Send + Sync>> {
|
||||
fn serialize(&self) -> Option<Arc<dyn std::any::Any + Send + Sync>> {
|
||||
let io = self.io.lock().unwrap();
|
||||
(io).as_ref().map(|output| output.clone() as Arc<dyn core::any::Any + Send + Sync>)
|
||||
(io).as_ref().map(|output| output.clone() as Arc<dyn std::any::Any + Send + Sync>)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ impl<I, T, N> MonitorNode<I, T, N> {
|
|||
}
|
||||
}
|
||||
|
||||
use core::hash::{Hash, Hasher};
|
||||
use std::hash::{Hash, Hasher};
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
pub struct MemoHash<T: Hash> {
|
||||
hash: u64,
|
||||
|
@ -179,7 +179,7 @@ impl<T: Hash> MemoHash<T> {
|
|||
}
|
||||
|
||||
fn calc_hash(data: &T) -> u64 {
|
||||
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
||||
let mut hasher = DefaultHasher::new();
|
||||
data.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ impl<T: Hash> Hash for MemoHash<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Hash> core::ops::Deref for MemoHash<T> {
|
||||
impl<T: Hash> Deref for MemoHash<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
@ -218,14 +218,14 @@ pub struct MemoHashGuard<'a, T: Hash> {
|
|||
inner: &'a mut MemoHash<T>,
|
||||
}
|
||||
|
||||
impl<T: Hash> core::ops::Drop for MemoHashGuard<'_, T> {
|
||||
impl<T: Hash> Drop for MemoHashGuard<'_, T> {
|
||||
fn drop(&mut self) {
|
||||
let hash = MemoHash::<T>::calc_hash(&self.inner.value);
|
||||
self.inner.hash = hash;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Hash> core::ops::Deref for MemoHashGuard<'_, T> {
|
||||
impl<T: Hash> Deref for MemoHashGuard<'_, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
@ -233,7 +233,7 @@ impl<T: Hash> core::ops::Deref for MemoHashGuard<'_, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Hash> core::ops::DerefMut for MemoHashGuard<'_, T> {
|
||||
impl<T: Hash> std::ops::DerefMut for MemoHashGuard<'_, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner.value
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ use crate::raster_types::{CPU, RasterDataTable};
|
|||
use crate::registry::types::{Fraction, Percentage};
|
||||
use crate::vector::style::GradientStops;
|
||||
use crate::{Color, Node};
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::{Add, Div, Mul, Rem, Sub};
|
||||
use dyn_any::DynAny;
|
||||
use glam::{DVec2, IVec2, UVec2};
|
||||
use math_parser::ast;
|
||||
|
@ -13,9 +11,8 @@ use math_parser::context::{EvalContext, NothingMap, ValueProvider};
|
|||
use math_parser::value::{Number, Value};
|
||||
use num_traits::Pow;
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
#[cfg(target_arch = "spirv")]
|
||||
use spirv_std::num_traits::float::Float;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Add, Div, Mul, Rem, Sub};
|
||||
|
||||
/// The struct that stores the context for the maths parser.
|
||||
/// This is currently just limited to supplying `a` and `b` until we add better node graph support and UI for variadic inputs.
|
||||
|
@ -252,7 +249,7 @@ impl TangentInverse for f64 {
|
|||
if radians { self.atan() } else { self.atan().to_degrees() }
|
||||
}
|
||||
}
|
||||
impl TangentInverse for glam::DVec2 {
|
||||
impl TangentInverse for DVec2 {
|
||||
type Output = f64;
|
||||
fn atan(self, radians: bool) -> Self::Output {
|
||||
if radians { self.y.atan2(self.x) } else { self.y.atan2(self.x).to_degrees() }
|
||||
|
@ -325,19 +322,19 @@ fn absolute_value<U: num_traits::float::Float>(_: impl Ctx, #[implementations(f6
|
|||
|
||||
/// The minimum function (min) picks the smaller of two numbers.
|
||||
#[node_macro::node(category("Math: Numeric"))]
|
||||
fn min<T: core::cmp::PartialOrd>(_: impl Ctx, #[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] value: T, #[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] other_value: T) -> T {
|
||||
fn min<T: std::cmp::PartialOrd>(_: impl Ctx, #[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] value: T, #[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] other_value: T) -> T {
|
||||
if value < other_value { value } else { other_value }
|
||||
}
|
||||
|
||||
/// The maximum function (max) picks the larger of two numbers.
|
||||
#[node_macro::node(category("Math: Numeric"))]
|
||||
fn max<T: core::cmp::PartialOrd>(_: impl Ctx, #[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] value: T, #[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] other_value: T) -> T {
|
||||
fn max<T: std::cmp::PartialOrd>(_: impl Ctx, #[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] value: T, #[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] other_value: T) -> T {
|
||||
if value > other_value { value } else { other_value }
|
||||
}
|
||||
|
||||
/// The clamp function (clamp) restricts a number to a specified range between a minimum and maximum value. The minimum and maximum values are automatically swapped if they are reversed.
|
||||
#[node_macro::node(category("Math: Numeric"))]
|
||||
fn clamp<T: core::cmp::PartialOrd>(
|
||||
fn clamp<T: std::cmp::PartialOrd>(
|
||||
_: impl Ctx,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] value: T,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32, &str)] min: T,
|
||||
|
@ -355,7 +352,7 @@ fn clamp<T: core::cmp::PartialOrd>(
|
|||
|
||||
/// The equality operation (==) compares two values and returns true if they are equal, or false if they are not.
|
||||
#[node_macro::node(category("Math: Logic"))]
|
||||
fn equals<U: core::cmp::PartialEq<T>, T>(
|
||||
fn equals<U: std::cmp::PartialEq<T>, T>(
|
||||
_: impl Ctx,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32, DVec2, &DVec2, &str)] value: T,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32, DVec2, &DVec2, &str)] other_value: U,
|
||||
|
@ -365,7 +362,7 @@ fn equals<U: core::cmp::PartialEq<T>, T>(
|
|||
|
||||
/// The inequality operation (!=) compares two values and returns true if they are not equal, or false if they are.
|
||||
#[node_macro::node(category("Math: Logic"))]
|
||||
fn not_equals<U: core::cmp::PartialEq<T>, T>(
|
||||
fn not_equals<U: std::cmp::PartialEq<T>, T>(
|
||||
_: impl Ctx,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32, DVec2, &DVec2, &str)] value: T,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32, DVec2, &DVec2, &str)] other_value: U,
|
||||
|
@ -376,7 +373,7 @@ fn not_equals<U: core::cmp::PartialEq<T>, T>(
|
|||
/// The less-than operation (<) compares two values and returns true if the first value is less than the second, or false if it is not.
|
||||
/// If enabled with "Or Equal", the less-than-or-equal operation (<=) will be used instead.
|
||||
#[node_macro::node(category("Math: Logic"))]
|
||||
fn less_than<T: core::cmp::PartialOrd<T>>(
|
||||
fn less_than<T: std::cmp::PartialOrd<T>>(
|
||||
_: impl Ctx,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32)] value: T,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32)] other_value: T,
|
||||
|
@ -388,7 +385,7 @@ fn less_than<T: core::cmp::PartialOrd<T>>(
|
|||
/// The greater-than operation (>) compares two values and returns true if the first value is greater than the second, or false if it is not.
|
||||
/// If enabled with "Or Equal", the greater-than-or-equal operation (>=) will be used instead.
|
||||
#[node_macro::node(category("Math: Logic"))]
|
||||
fn greater_than<T: core::cmp::PartialOrd<T>>(
|
||||
fn greater_than<T: std::cmp::PartialOrd<T>>(
|
||||
_: impl Ctx,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32)] value: T,
|
||||
#[implementations(f64, &f64, f32, &f32, u32, &u32)] other_value: T,
|
||||
|
@ -566,7 +563,7 @@ where
|
|||
self.0.reset();
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn core::any::Any + Send + Sync>> {
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn std::any::Any + Send + Sync>> {
|
||||
self.0.serialize()
|
||||
}
|
||||
}
|
||||
|
@ -586,7 +583,7 @@ impl<'i, N: for<'a> Node<'a, I> + Copy, I: 'i> Copy for TypeNode<N, I, <N as Nod
|
|||
pub struct IntoNode<O>(PhantomData<O>);
|
||||
impl<O> IntoNode<O> {
|
||||
pub const fn new() -> Self {
|
||||
Self(core::marker::PhantomData)
|
||||
Self(PhantomData)
|
||||
}
|
||||
}
|
||||
impl<O> Default for IntoNode<O> {
|
||||
|
@ -598,7 +595,7 @@ impl<'input, I: 'input, O: 'input> Node<'input, I> for IntoNode<O>
|
|||
where
|
||||
I: Into<O> + Sync + Send,
|
||||
{
|
||||
type Output = ::dyn_any::DynFuture<'input, O>;
|
||||
type Output = dyn_any::DynFuture<'input, O>;
|
||||
|
||||
#[inline]
|
||||
fn eval(&'input self, input: I) -> Self::Output {
|
||||
|
@ -613,8 +610,8 @@ mod test {
|
|||
|
||||
#[test]
|
||||
pub fn dot_product_function() {
|
||||
let vector_a = glam::DVec2::new(1., 2.);
|
||||
let vector_b = glam::DVec2::new(3., 4.);
|
||||
let vector_a = DVec2::new(1., 2.);
|
||||
let vector_b = DVec2::new(3., 4.);
|
||||
assert_eq!(dot_product((), vector_a, vector_b), 11.);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,18 +5,16 @@ use crate::raster_types::{CPU, RasterDataTable};
|
|||
use crate::registry::types::Percentage;
|
||||
use crate::vector::VectorDataTable;
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use core::fmt::Debug;
|
||||
use glam::DVec2;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[cfg(target_arch = "spirv")]
|
||||
use spirv_std::num_traits::float::Float;
|
||||
|
||||
pub mod adjustments;
|
||||
pub mod bbox;
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
pub mod brush_cache;
|
||||
pub mod color;
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
pub mod curve;
|
||||
pub mod discrete_srgb;
|
||||
|
||||
|
@ -30,9 +28,9 @@ pub trait Linear {
|
|||
fn lerp(self, other: Self, value: Self) -> Self
|
||||
where
|
||||
Self: Sized + Copy,
|
||||
Self: core::ops::Sub<Self, Output = Self>,
|
||||
Self: core::ops::Mul<Self, Output = Self>,
|
||||
Self: core::ops::Add<Self, Output = Self>,
|
||||
Self: std::ops::Sub<Self, Output = Self>,
|
||||
Self: std::ops::Mul<Self, Output = Self>,
|
||||
Self: std::ops::Add<Self, Output = Self>,
|
||||
{
|
||||
self + (other - self) * value
|
||||
}
|
||||
|
@ -134,7 +132,7 @@ pub trait Pixel: Clone + Pod + Zeroable + Default {
|
|||
}
|
||||
|
||||
fn byte_size() -> usize {
|
||||
core::mem::size_of::<Self>()
|
||||
size_of::<Self>()
|
||||
}
|
||||
}
|
||||
pub trait RGB: Pixel {
|
||||
|
|
|
@ -10,12 +10,9 @@ use crate::vector::VectorDataTable;
|
|||
use crate::vector::style::GradientStops;
|
||||
use crate::{Ctx, Node};
|
||||
use crate::{GraphicElement, GraphicGroupTable};
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt::Debug;
|
||||
use dyn_any::DynAny;
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(target_arch = "spirv")]
|
||||
use spirv_std::num_traits::float::Float;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::Debug;
|
||||
|
||||
// TODO: Implement the following:
|
||||
// Color Balance
|
||||
|
@ -183,8 +180,8 @@ impl BlendMode {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for BlendMode {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
impl std::fmt::Display for BlendMode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
// Normal group
|
||||
BlendMode::Normal => write!(f, "Normal"),
|
||||
|
@ -346,7 +343,7 @@ fn brightness_contrast<T: Adjust<Color>>(
|
|||
let brightness = brightness as f32 / 255.;
|
||||
|
||||
let contrast = contrast as f32 / 100.;
|
||||
let contrast = if contrast > 0. { (contrast * core::f32::consts::FRAC_PI_2 - 0.01).tan() } else { contrast };
|
||||
let contrast = if contrast > 0. { (contrast * std::f32::consts::FRAC_PI_2 - 0.01).tan() } else { contrast };
|
||||
|
||||
let offset = brightness * contrast + brightness - contrast / 2.;
|
||||
|
||||
|
@ -368,13 +365,13 @@ fn brightness_contrast<T: Adjust<Color>>(
|
|||
y: [0., 130. + brightness * 51., 233. + brightness * 10., 255.].map(|x| x / 255.),
|
||||
};
|
||||
let brightness_curve_solutions = brightness_curve_points.solve();
|
||||
let mut brightness_lut: [f32; WINDOW_SIZE] = core::array::from_fn(|i| {
|
||||
let mut brightness_lut: [f32; WINDOW_SIZE] = std::array::from_fn(|i| {
|
||||
let x = i as f32 / (WINDOW_SIZE as f32 - 1.);
|
||||
brightness_curve_points.interpolate(x, &brightness_curve_solutions)
|
||||
});
|
||||
// Special handling for when brightness is negative
|
||||
if brightness_is_negative {
|
||||
brightness_lut = core::array::from_fn(|i| {
|
||||
brightness_lut = std::array::from_fn(|i| {
|
||||
let mut x = i;
|
||||
while x > 1 && brightness_lut[x] > i as f32 / WINDOW_SIZE as f32 {
|
||||
x -= 1;
|
||||
|
@ -393,7 +390,7 @@ fn brightness_contrast<T: Adjust<Color>>(
|
|||
y: [0., 64. - contrast * 30., 192. + contrast * 30., 255.].map(|x| x / 255.),
|
||||
};
|
||||
let contrast_curve_solutions = contrast_curve_points.solve();
|
||||
let contrast_lut: [f32; WINDOW_SIZE] = core::array::from_fn(|i| {
|
||||
let contrast_lut: [f32; WINDOW_SIZE] = std::array::from_fn(|i| {
|
||||
let x = i as f32 / (WINDOW_SIZE as f32 - 1.);
|
||||
contrast_curve_points.interpolate(x, &contrast_curve_solutions)
|
||||
});
|
||||
|
@ -1419,7 +1416,7 @@ fn generate_curves<C: Channel + crate::raster::Linear>(_: impl Ctx, curve: Curve
|
|||
anchor: [1.; 2],
|
||||
handles: [curve.last_handle, [0.; 2]],
|
||||
};
|
||||
for sample in curve.manipulator_groups.iter().chain(core::iter::once(&end)) {
|
||||
for sample in curve.manipulator_groups.iter().chain(std::iter::once(&end)) {
|
||||
let [x0, y0, x1, y1, x2, y2, x3, y3] = [pos[0], pos[1], param[0], param[1], sample.handles[0][0], sample.handles[0][1], sample.anchor[0], sample.anchor[1]].map(f64::from);
|
||||
|
||||
let bezier = Bezier::from_cubic_coordinates(x0, y0, x1, y1, x2, y2, x3, y3);
|
||||
|
@ -1511,7 +1508,7 @@ mod test {
|
|||
pub struct FutureWrapperNode<T: Clone>(T);
|
||||
|
||||
impl<'i, T: 'i + Clone + Send> Node<'i, ()> for FutureWrapperNode<T> {
|
||||
type Output = Pin<Box<dyn core::future::Future<Output = T> + 'i + Send>>;
|
||||
type Output = Pin<Box<dyn Future<Output = T> + 'i + Send>>;
|
||||
fn eval(&'i self, _input: ()) -> Self::Output {
|
||||
let value = self.0.clone();
|
||||
Box::pin(async move { value })
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use dyn_any::DynAny;
|
||||
use glam::{DAffine2, DVec2};
|
||||
|
||||
#[cfg_attr(not(target_arch = "spirv"), derive(Debug))]
|
||||
#[derive(Clone, DynAny)]
|
||||
#[derive(Clone, Debug, DynAny)]
|
||||
pub struct AxisAlignedBbox {
|
||||
pub start: DVec2,
|
||||
pub end: DVec2,
|
||||
|
@ -60,8 +59,7 @@ impl From<(DVec2, DVec2)> for AxisAlignedBbox {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(not(target_arch = "spirv"), derive(Debug))]
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Bbox {
|
||||
pub top_left: DVec2,
|
||||
pub top_right: DVec2,
|
||||
|
|
|
@ -3,9 +3,9 @@ use crate::raster_types::CPU;
|
|||
use crate::raster_types::Raster;
|
||||
use crate::vector::brush_stroke::BrushStroke;
|
||||
use crate::vector::brush_stroke::BrushStyle;
|
||||
use core::hash::Hash;
|
||||
use dyn_any::DynAny;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
|
@ -53,7 +53,7 @@ impl BrushCacheImpl {
|
|||
|
||||
// Take our previous blended image (and invalidate the cache).
|
||||
// Since we're about to replace our cache anyway, this saves a clone.
|
||||
background = core::mem::take(&mut self.blended_image);
|
||||
background = std::mem::take(&mut self.blended_image);
|
||||
|
||||
// Check if the first non-blended stroke is an extension of the last one.
|
||||
let mut first_stroke_texture = Instance {
|
||||
|
@ -70,7 +70,7 @@ impl BrushCacheImpl {
|
|||
let new_points = strokes[0].compute_blit_points();
|
||||
let is_point_prefix = new_points.get(..prev_points.len()) == Some(&prev_points);
|
||||
if same_style && is_point_prefix {
|
||||
first_stroke_texture = core::mem::take(&mut self.last_stroke_texture);
|
||||
first_stroke_texture = std::mem::take(&mut self.last_stroke_texture);
|
||||
first_stroke_point_skip = prev_points.len();
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ impl BrushCacheImpl {
|
|||
|
||||
impl Hash for BrushCacheImpl {
|
||||
// Zero hash.
|
||||
fn hash<H: core::hash::Hasher>(&self, _state: &mut H) {}
|
||||
fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
|
@ -151,7 +151,7 @@ impl PartialEq for BrushCache {
|
|||
}
|
||||
|
||||
impl Hash for BrushCache {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.inner.lock().unwrap().hash(state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use super::discrete_srgb::{float_to_srgb_u8, srgb_u8_to_float};
|
||||
use super::{Alpha, AlphaMut, AssociatedAlpha, Luminance, LuminanceMut, Pixel, RGB, RGBMut, Rec709Primaries, SRGB};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use core::hash::Hash;
|
||||
use dyn_any::DynAny;
|
||||
use half::f16;
|
||||
#[cfg(target_arch = "spirv")]
|
||||
use spirv_std::num_traits::Euclid;
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(target_arch = "spirv")]
|
||||
use spirv_std::num_traits::float::Float;
|
||||
use std::hash::Hash;
|
||||
|
||||
#[repr(C)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
|
@ -217,7 +216,7 @@ pub struct Color {
|
|||
|
||||
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||
impl Hash for Color {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.red.to_bits().hash(state);
|
||||
self.green.to_bits().hash(state);
|
||||
self.blue.to_bits().hash(state);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::{Channel, Linear, LuminanceMut};
|
||||
use crate::Node;
|
||||
use core::ops::{Add, Mul, Sub};
|
||||
use dyn_any::{DynAny, StaticType, StaticTypeSized};
|
||||
use std::ops::{Add, Mul, Sub};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, DynAny, specta::Type)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
|
@ -95,12 +95,7 @@ impl CubicSplines {
|
|||
// Gaussian elimination: forward elimination
|
||||
for row in 0..4 {
|
||||
let pivot_row_index = (row..4)
|
||||
.max_by(|&a_row, &b_row| {
|
||||
augmented_matrix[a_row][row]
|
||||
.abs()
|
||||
.partial_cmp(&augmented_matrix[b_row][row].abs())
|
||||
.unwrap_or(core::cmp::Ordering::Equal)
|
||||
})
|
||||
.max_by(|&a_row, &b_row| augmented_matrix[a_row][row].abs().partial_cmp(&augmented_matrix[b_row][row].abs()).unwrap_or(std::cmp::Ordering::Equal))
|
||||
.unwrap();
|
||||
|
||||
// Swap the current row with the row that has the largest pivot element
|
||||
|
|
|
@ -69,7 +69,7 @@ pub fn float_to_srgb_u8(mut f: f32) -> u8 {
|
|||
// We clamped f to [0, 1], and the integer representations
|
||||
// of the positive finite non-NaN floats are monotonic.
|
||||
// This makes the later LUT lookup panicless.
|
||||
unsafe { core::hint::unreachable_unchecked() }
|
||||
unsafe { std::hint::unreachable_unchecked() }
|
||||
}
|
||||
|
||||
// Compute a piecewise linear interpolation that is always
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
use crate::{
|
||||
AlphaBlending,
|
||||
instances::{Instance, Instances},
|
||||
raster_types::Raster,
|
||||
};
|
||||
|
||||
use super::Color;
|
||||
use super::discrete_srgb::float_to_srgb_u8;
|
||||
use alloc::vec::Vec;
|
||||
use crate::AlphaBlending;
|
||||
use crate::instances::{Instance, Instances};
|
||||
use crate::raster_types::Raster;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use dyn_any::{DynAny, StaticType};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use std::vec::Vec;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
mod base64_serde {
|
||||
|
@ -56,7 +53,7 @@ pub struct Image<P: Pixel> {
|
|||
}
|
||||
|
||||
impl<P: Pixel + Debug> Debug for Image<P> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let length = self.data.len();
|
||||
f.debug_struct("Image")
|
||||
.field("width", &self.width)
|
||||
|
@ -203,7 +200,7 @@ where
|
|||
|
||||
impl<P: Pixel> IntoIterator for Image<P> {
|
||||
type Item = P;
|
||||
type IntoIter = alloc::vec::IntoIter<P>;
|
||||
type IntoIter = std::vec::IntoIter<P>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.data.into_iter()
|
||||
}
|
||||
|
|
|
@ -108,10 +108,10 @@ pub static NODE_REGISTRY: NodeRegistry = LazyLock::new(|| Mutex::new(HashMap::ne
|
|||
pub static NODE_METADATA: LazyLock<Mutex<HashMap<String, NodeMetadata>>> = LazyLock::new(|| Mutex::new(HashMap::new()));
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub type DynFuture<'n, T> = Pin<Box<dyn core::future::Future<Output = T> + 'n + Send>>;
|
||||
pub type DynFuture<'n, T> = Pin<Box<dyn Future<Output = T> + 'n + Send>>;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub type DynFuture<'n, T> = Pin<Box<dyn core::future::Future<Output = T> + 'n>>;
|
||||
pub type LocalFuture<'n, T> = Pin<Box<dyn core::future::Future<Output = T> + 'n>>;
|
||||
pub type DynFuture<'n, T> = Pin<Box<dyn std::future::Future<Output = T> + 'n>>;
|
||||
pub type LocalFuture<'n, T> = Pin<Box<dyn Future<Output = T> + 'n>>;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub type Any<'n> = Box<dyn DynAny<'n> + 'n + Send>;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
|
@ -169,8 +169,8 @@ impl Drop for NodeContainer {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for NodeContainer {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
impl std::fmt::Debug for NodeContainer {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("NodeContainer").finish()
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ impl NodeContainer {
|
|||
#[cfg(feature = "dealloc_nodes")]
|
||||
unsafe fn dealloc_unchecked(&mut self) {
|
||||
unsafe {
|
||||
std::mem::drop(Box::from_raw(self.node as *mut TypeErasedNode));
|
||||
drop(Box::from_raw(self.node as *mut TypeErasedNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ where
|
|||
self.node.reset();
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn core::any::Any + Send + Sync>> {
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn std::any::Any + Send + Sync>> {
|
||||
self.node.serialize()
|
||||
}
|
||||
}
|
||||
|
@ -227,8 +227,8 @@ impl<I, O> DowncastBothNode<I, O> {
|
|||
pub const fn new(node: SharedNodeContainer) -> Self {
|
||||
Self {
|
||||
node,
|
||||
_i: core::marker::PhantomData,
|
||||
_o: core::marker::PhantomData,
|
||||
_i: PhantomData,
|
||||
_o: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ where
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn core::any::Any + Send + Sync>> {
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn std::any::Any + Send + Sync>> {
|
||||
self.node.serialize()
|
||||
}
|
||||
}
|
||||
|
@ -271,14 +271,14 @@ pub struct DynAnyNode<I, O, Node> {
|
|||
|
||||
impl<'input, I, O, N> Node<'input, Any<'input>> for DynAnyNode<I, O, N>
|
||||
where
|
||||
I: 'input + dyn_any::StaticType + WasmNotSend,
|
||||
O: 'input + dyn_any::StaticType + WasmNotSend,
|
||||
I: 'input + StaticType + WasmNotSend,
|
||||
O: 'input + StaticType + WasmNotSend,
|
||||
N: 'input + Node<'input, I, Output = DynFuture<'input, O>>,
|
||||
{
|
||||
type Output = FutureAny<'input>;
|
||||
#[inline]
|
||||
fn eval(&'input self, input: Any<'input>) -> Self::Output {
|
||||
let node_name = core::any::type_name::<N>();
|
||||
let node_name = std::any::type_name::<N>();
|
||||
let output = |input| {
|
||||
let result = self.node.eval(input);
|
||||
async move { Box::new(result.await) as Any<'input> }
|
||||
|
@ -293,21 +293,21 @@ where
|
|||
self.node.reset();
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn core::any::Any + Send + Sync>> {
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn std::any::Any + Send + Sync>> {
|
||||
self.node.serialize()
|
||||
}
|
||||
}
|
||||
impl<'input, I, O, N> DynAnyNode<I, O, N>
|
||||
where
|
||||
I: 'input + dyn_any::StaticType,
|
||||
O: 'input + dyn_any::StaticType,
|
||||
I: 'input + StaticType,
|
||||
O: 'input + StaticType,
|
||||
N: 'input + Node<'input, I, Output = DynFuture<'input, O>>,
|
||||
{
|
||||
pub const fn new(node: N) -> Self {
|
||||
Self {
|
||||
node,
|
||||
_i: core::marker::PhantomData,
|
||||
_o: core::marker::PhantomData,
|
||||
_i: PhantomData,
|
||||
_o: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::Node;
|
||||
use core::marker::PhantomData;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// This is how we can generically define composition of two nodes.
|
||||
/// This is done generically as shown: <https://files.keavon.com/-/SurprisedGaseousAnhinga/capture.png>
|
||||
|
@ -58,10 +58,10 @@ pub struct AsyncComposeNode<First, Second, I> {
|
|||
impl<'i, Input: 'static, First, Second> Node<'i, Input> for AsyncComposeNode<First, Second, Input>
|
||||
where
|
||||
First: Node<'i, Input>,
|
||||
First::Output: core::future::Future,
|
||||
Second: Node<'i, <<First as Node<'i, Input>>::Output as core::future::Future>::Output> + 'i,
|
||||
First::Output: Future,
|
||||
Second: Node<'i, <<First as Node<'i, Input>>::Output as Future>::Output> + 'i,
|
||||
{
|
||||
type Output = core::pin::Pin<Box<dyn core::future::Future<Output = <Second as Node<'i, <<First as Node<'i, Input>>::Output as core::future::Future>::Output>>::Output> + 'i>>;
|
||||
type Output = std::pin::Pin<Box<dyn Future<Output = <Second as Node<'i, <<First as Node<'i, Input>>::Output as Future>::Output>>::Output> + 'i>>;
|
||||
fn eval(&'i self, input: Input) -> Self::Output {
|
||||
Box::pin(async move {
|
||||
let arg = self.first.eval(input).await;
|
||||
|
@ -73,8 +73,8 @@ where
|
|||
impl<'i, First, Second, Input: 'i> AsyncComposeNode<First, Second, Input>
|
||||
where
|
||||
First: Node<'i, Input>,
|
||||
First::Output: core::future::Future,
|
||||
Second: Node<'i, <<First as Node<'i, Input>>::Output as core::future::Future>::Output> + 'i,
|
||||
First::Output: Future,
|
||||
Second: Node<'i, <<First as Node<'i, Input>>::Output as Future>::Output> + 'i,
|
||||
{
|
||||
pub const fn new(first: First, second: Second) -> Self {
|
||||
AsyncComposeNode::<First, Second, Input> { first, second, phantom: PhantomData }
|
||||
|
@ -97,8 +97,8 @@ pub trait AndThen<'i, Input: 'i>: Sized {
|
|||
fn and_then<Second>(self, second: Second) -> AsyncComposeNode<Self, Second, Input>
|
||||
where
|
||||
Self: Node<'i, Input>,
|
||||
Self::Output: core::future::Future,
|
||||
Second: Node<'i, <<Self as Node<'i, Input>>::Output as core::future::Future>::Output> + 'i,
|
||||
Self::Output: Future,
|
||||
Second: Node<'i, <<Self as Node<'i, Input>>::Output as Future>::Output> + 'i,
|
||||
{
|
||||
AsyncComposeNode::new(self, second)
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ impl FontCache {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::hash::Hash for FontCache {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for FontCache {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.preview_urls.len().hash(state);
|
||||
self.preview_urls.iter().for_each(|(font, url)| {
|
||||
font.hash(state);
|
||||
|
|
|
@ -136,8 +136,8 @@ impl From<()> for Footprint {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::hash::Hash for Footprint {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for Footprint {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.transform.to_cols_array().iter().for_each(|x| x.to_le_bytes().hash(state));
|
||||
self.resolution.hash(state)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use core::any::TypeId;
|
||||
use std::any::TypeId;
|
||||
|
||||
pub use std::borrow::Cow;
|
||||
|
||||
|
@ -6,20 +6,20 @@ pub use std::borrow::Cow;
|
|||
macro_rules! concrete {
|
||||
($type:ty) => {
|
||||
$crate::Type::Concrete($crate::TypeDescriptor {
|
||||
id: Some(core::any::TypeId::of::<$type>()),
|
||||
name: $crate::Cow::Borrowed(core::any::type_name::<$type>()),
|
||||
id: Some(std::any::TypeId::of::<$type>()),
|
||||
name: $crate::Cow::Borrowed(std::any::type_name::<$type>()),
|
||||
alias: None,
|
||||
size: core::mem::size_of::<$type>(),
|
||||
align: core::mem::align_of::<$type>(),
|
||||
size: std::mem::size_of::<$type>(),
|
||||
align: std::mem::align_of::<$type>(),
|
||||
})
|
||||
};
|
||||
($type:ty, $name:ty) => {
|
||||
$crate::Type::Concrete($crate::TypeDescriptor {
|
||||
id: Some(core::any::TypeId::of::<$type>()),
|
||||
name: $crate::Cow::Borrowed(core::any::type_name::<$type>()),
|
||||
id: Some(std::any::TypeId::of::<$type>()),
|
||||
name: $crate::Cow::Borrowed(std::any::type_name::<$type>()),
|
||||
alias: Some($crate::Cow::Borrowed(stringify!($name))),
|
||||
size: core::mem::size_of::<$type>(),
|
||||
align: core::mem::align_of::<$type>(),
|
||||
size: std::mem::size_of::<$type>(),
|
||||
align: std::mem::align_of::<$type>(),
|
||||
})
|
||||
};
|
||||
}
|
||||
|
@ -28,11 +28,11 @@ macro_rules! concrete {
|
|||
macro_rules! concrete_with_name {
|
||||
($type:ty, $name:expr_2021) => {
|
||||
$crate::Type::Concrete($crate::TypeDescriptor {
|
||||
id: Some(core::any::TypeId::of::<$type>()),
|
||||
id: Some(std::any::TypeId::of::<$type>()),
|
||||
name: $crate::Cow::Borrowed($name),
|
||||
alias: None,
|
||||
size: core::mem::size_of::<$type>(),
|
||||
align: core::mem::align_of::<$type>(),
|
||||
size: std::mem::size_of::<$type>(),
|
||||
align: std::mem::align_of::<$type>(),
|
||||
})
|
||||
};
|
||||
}
|
||||
|
@ -114,8 +114,8 @@ impl NodeIOTypes {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for NodeIOTypes {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
impl std::fmt::Debug for NodeIOTypes {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!(
|
||||
"node({}) → {}",
|
||||
[&self.call_argument].into_iter().chain(&self.inputs).map(|input| input.to_string()).collect::<Vec<_>>().join(", "),
|
||||
|
@ -141,7 +141,7 @@ fn migrate_type_descriptor_names<'de, D: serde::Deserializer<'de>>(deserializer:
|
|||
let name = String::deserialize(deserializer)?;
|
||||
let name = match name.as_str() {
|
||||
"f32" => "f64".to_string(),
|
||||
"graphene_core::transform::Footprint" => "core::option::Option<alloc::sync::Arc<graphene_core::context::OwnedContextImpl>>".to_string(),
|
||||
"graphene_core::transform::Footprint" => "std::option::Option<std::sync::Arc<graphene_core::context::OwnedContextImpl>>".to_string(),
|
||||
"graphene_core::graphic_element::GraphicGroup" => "graphene_core::instances::Instances<graphene_core::graphic_element::GraphicGroup>".to_string(),
|
||||
"graphene_core::vector::vector_data::VectorData" => "graphene_core::instances::Instances<graphene_core::vector::vector_data::VectorData>".to_string(),
|
||||
"graphene_core::raster::image::ImageFrame<Color>"
|
||||
|
@ -172,8 +172,8 @@ pub struct TypeDescriptor {
|
|||
pub align: usize,
|
||||
}
|
||||
|
||||
impl core::hash::Hash for TypeDescriptor {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for TypeDescriptor {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.name.hash(state);
|
||||
}
|
||||
}
|
||||
|
@ -264,10 +264,10 @@ impl Type {
|
|||
pub fn new<T: dyn_any::StaticType + Sized>() -> Self {
|
||||
Self::Concrete(TypeDescriptor {
|
||||
id: Some(TypeId::of::<T::Static>()),
|
||||
name: Cow::Borrowed(core::any::type_name::<T::Static>()),
|
||||
name: Cow::Borrowed(std::any::type_name::<T::Static>()),
|
||||
alias: None,
|
||||
size: core::mem::size_of::<T>(),
|
||||
align: core::mem::align_of::<T>(),
|
||||
size: size_of::<T>(),
|
||||
align: align_of::<T>(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -318,8 +318,8 @@ fn format_type(ty: &str) -> String {
|
|||
.join("<")
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for Type {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
impl std::fmt::Debug for Type {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let result = match self {
|
||||
Self::Generic(name) => name.to_string(),
|
||||
#[cfg(feature = "type_id_logging")]
|
||||
|
|
|
@ -43,9 +43,9 @@ mod u64_string {
|
|||
}
|
||||
|
||||
mod uuid_generation {
|
||||
use core::cell::Cell;
|
||||
use rand_chacha::ChaCha20Rng;
|
||||
use rand_chacha::rand_core::{RngCore, SeedableRng};
|
||||
use std::cell::Cell;
|
||||
use std::sync::Mutex;
|
||||
|
||||
static RNG: Mutex<Option<ChaCha20Rng>> = Mutex::new(None);
|
||||
|
@ -79,8 +79,8 @@ impl NodeId {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for NodeId {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
impl std::fmt::Display for NodeId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::Node;
|
||||
use core::cell::{Cell, RefCell, RefMut};
|
||||
use core::marker::PhantomData;
|
||||
use std::cell::{Cell, RefCell, RefMut};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct IntNode<const N: u32>;
|
||||
|
|
|
@ -108,7 +108,7 @@ pub fn t_value_to_parametric(bezpath: &BezPath, t: f64, euclidian: bool, segment
|
|||
|
||||
/// Finds the t value of point on the given path segment i.e fractional distance along the segment's total length.
|
||||
/// It uses a binary search to find the value `t` such that the ratio `length_up_to_t / total_length` approximates the input `distance`.
|
||||
pub fn eval_pathseg_euclidean(path_segment: kurbo::PathSeg, distance: f64, accuracy: f64) -> f64 {
|
||||
pub fn eval_pathseg_euclidean(path_segment: PathSeg, distance: f64, accuracy: f64) -> f64 {
|
||||
let mut low_t = 0.;
|
||||
let mut mid_t = 0.5;
|
||||
let mut high_t = 1.;
|
||||
|
@ -139,7 +139,7 @@ pub fn eval_pathseg_euclidean(path_segment: kurbo::PathSeg, distance: f64, accur
|
|||
/// Converts from a bezpath (composed of multiple segments) to a point along a certain segment represented.
|
||||
/// The returned tuple represents the segment index and the `t` value along that segment.
|
||||
/// Both the input global `t` value and the output `t` value are in euclidean space, meaning there is a constant rate of change along the arc length.
|
||||
fn global_euclidean_to_local_euclidean(bezpath: &kurbo::BezPath, global_t: f64, lengths: &[f64], total_length: f64) -> (usize, f64) {
|
||||
fn global_euclidean_to_local_euclidean(bezpath: &BezPath, global_t: f64, lengths: &[f64], total_length: f64) -> (usize, f64) {
|
||||
let mut accumulator = 0.;
|
||||
for (index, length) in lengths.iter().enumerate() {
|
||||
let length_ratio = length / total_length;
|
||||
|
@ -158,7 +158,7 @@ enum BezPathTValue {
|
|||
|
||||
/// Convert a [BezPathTValue] to a parametric `(segment_index, t)` tuple.
|
||||
/// - Asserts that `t` values contained within the `SubpathTValue` argument lie in the range [0, 1].
|
||||
fn bezpath_t_value_to_parametric(bezpath: &kurbo::BezPath, t: BezPathTValue, precomputed_segments_length: Option<&[f64]>) -> (usize, f64) {
|
||||
fn bezpath_t_value_to_parametric(bezpath: &BezPath, t: BezPathTValue, precomputed_segments_length: Option<&[f64]>) -> (usize, f64) {
|
||||
let segment_count = bezpath.segments().count();
|
||||
assert!(segment_count >= 1);
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ mod test {
|
|||
pub struct FutureWrapperNode<T: Clone>(T);
|
||||
|
||||
impl<'i, I: Ctx, T: 'i + Clone + Send> Node<'i, I> for FutureWrapperNode<T> {
|
||||
type Output = Pin<Box<dyn core::future::Future<Output = T> + 'i + Send>>;
|
||||
type Output = Pin<Box<dyn Future<Output = T> + 'i + Send>>;
|
||||
fn eval(&'i self, _input: I) -> Self::Output {
|
||||
let value = self.0.clone();
|
||||
Box::pin(async move { value })
|
||||
|
|
|
@ -8,7 +8,7 @@ const CUBIC_TO_BEZPATH_ACCURACY: f64 = 1e-3;
|
|||
/// Constant used to determine if `f64`s are equivalent.
|
||||
pub const MAX_ABSOLUTE_DIFFERENCE: f64 = 1e-3;
|
||||
|
||||
fn segment_to_bezier(seg: kurbo::PathSeg) -> bezier_rs::Bezier {
|
||||
fn segment_to_bezier(seg: kurbo::PathSeg) -> Bezier {
|
||||
match seg {
|
||||
kurbo::PathSeg::Line(line) => Bezier::from_linear_coordinates(line.p0.x, line.p0.y, line.p1.x, line.p1.y),
|
||||
kurbo::PathSeg::Quad(quad_bez) => Bezier::from_quadratic_coordinates(quad_bez.p0.x, quad_bez.p0.y, quad_bez.p1.x, quad_bez.p1.y, quad_bez.p1.x, quad_bez.p1.y),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use core::f64;
|
||||
use glam::DVec2;
|
||||
use std::collections::HashMap;
|
||||
use std::f64;
|
||||
|
||||
const DEEPEST_SUBDIVISION_LEVEL_BEFORE_DISCARDING: usize = 8;
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub fn poisson_disk_sample(
|
|||
// - Dividing into an integer number of cells across the dartboard domain, to avoid wastefully throwing darts beyond the width and height of the dartboard domain
|
||||
// - Being fully covered by the radius around a dart thrown anywhere in its area, where the worst-case is a corner which has a distance of sqrt(2) to the opposite corner
|
||||
let greater_dimension = width.max(height);
|
||||
let base_level_grid_size = greater_dimension / (greater_dimension * std::f64::consts::SQRT_2 / (diameter / 2.)).ceil();
|
||||
let base_level_grid_size = greater_dimension / (greater_dimension * f64::consts::SQRT_2 / (diameter / 2.)).ceil();
|
||||
|
||||
// Initialize the problem by including all base-level squares in the active list since they're all part of the yet-to-be-targetted dartboard domain
|
||||
let base_level = ActiveListLevel::new_filled(base_level_grid_size, offset, width, height, &point_in_shape_checker, &line_intersect_shape_checker);
|
||||
|
|
|
@ -22,7 +22,7 @@ pub enum GradientType {
|
|||
pub struct GradientStops(Vec<(f64, Color)>);
|
||||
|
||||
impl std::hash::Hash for GradientStops {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.len().hash(state);
|
||||
self.0.iter().for_each(|(position, color)| {
|
||||
position.to_bits().hash(state);
|
||||
|
@ -146,8 +146,8 @@ impl Default for Gradient {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::hash::Hash for Gradient {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for Gradient {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.stops.0.len().hash(state);
|
||||
[].iter()
|
||||
.chain(self.start.to_array().iter())
|
||||
|
@ -611,8 +611,8 @@ pub struct Stroke {
|
|||
pub paint_order: PaintOrder,
|
||||
}
|
||||
|
||||
impl core::hash::Hash for Stroke {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for Stroke {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.color.hash(state);
|
||||
self.weight.to_bits().hash(state);
|
||||
{
|
||||
|
@ -850,8 +850,8 @@ pub struct PathStyle {
|
|||
fill: Fill,
|
||||
}
|
||||
|
||||
impl core::hash::Hash for PathStyle {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for PathStyle {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.stroke.hash(state);
|
||||
self.fill.hash(state);
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@ use crate::renderer::{ClickTargetType, FreePoint};
|
|||
use crate::{AlphaBlending, Color, GraphicGroupTable};
|
||||
pub use attributes::*;
|
||||
use bezier_rs::ManipulatorGroup;
|
||||
use core::borrow::Borrow;
|
||||
use dyn_any::DynAny;
|
||||
use glam::{DAffine2, DVec2};
|
||||
pub use indexed::VectorDataIndex;
|
||||
use kurbo::{Affine, Rect, Shape};
|
||||
pub use modification::*;
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// TODO: Eventually remove this migration document upgrade code
|
||||
|
@ -105,8 +105,8 @@ impl Default for VectorData {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::hash::Hash for VectorData {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for VectorData {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.point_domain.hash(state);
|
||||
self.segment_domain.hash(state);
|
||||
self.region_domain.hash(state);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::vector::misc::dvec2_to_point;
|
||||
use crate::vector::vector_data::{HandleId, VectorData};
|
||||
use bezier_rs::{BezierHandles, ManipulatorGroup};
|
||||
use core::iter::zip;
|
||||
use dyn_any::DynAny;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::zip;
|
||||
|
||||
/// A simple macro for creating strongly typed ids (to avoid confusion when passing around ids).
|
||||
macro_rules! create_ids {
|
||||
|
@ -53,7 +53,7 @@ create_ids! { InstanceId, PointId, SegmentId, RegionId, StrokeId, FillId }
|
|||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub struct NoHash(Option<u64>);
|
||||
|
||||
impl core::hash::Hasher for NoHash {
|
||||
impl Hasher for NoHash {
|
||||
fn finish(&self) -> u64 {
|
||||
self.0.unwrap()
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ impl core::hash::Hasher for NoHash {
|
|||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub struct NoHashBuilder;
|
||||
|
||||
impl core::hash::BuildHasher for NoHashBuilder {
|
||||
impl std::hash::BuildHasher for NoHashBuilder {
|
||||
type Hasher = NoHash;
|
||||
fn build_hasher(&self) -> Self::Hasher {
|
||||
NoHash::default()
|
||||
|
@ -86,8 +86,8 @@ pub struct PointDomain {
|
|||
pub(crate) position: Vec<DVec2>,
|
||||
}
|
||||
|
||||
impl core::hash::Hash for PointDomain {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl Hash for PointDomain {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.id.hash(state);
|
||||
self.position.iter().for_each(|pos| pos.to_array().map(|v| v.to_bits()).hash(state));
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ pub struct SegmentDomain {
|
|||
id: Vec<SegmentId>,
|
||||
start_point: Vec<usize>,
|
||||
end_point: Vec<usize>,
|
||||
handles: Vec<bezier_rs::BezierHandles>,
|
||||
handles: Vec<BezierHandles>,
|
||||
stroke: Vec<StrokeId>,
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,7 @@ impl SegmentDomain {
|
|||
self.end_point[segment_index] = new;
|
||||
}
|
||||
|
||||
pub fn handles(&self) -> &[bezier_rs::BezierHandles] {
|
||||
pub fn handles(&self) -> &[BezierHandles] {
|
||||
&self.handles
|
||||
}
|
||||
|
||||
|
@ -301,7 +301,7 @@ impl SegmentDomain {
|
|||
&self.stroke
|
||||
}
|
||||
|
||||
pub(crate) fn push(&mut self, id: SegmentId, start: usize, end: usize, handles: bezier_rs::BezierHandles, stroke: StrokeId) {
|
||||
pub(crate) fn push(&mut self, id: SegmentId, start: usize, end: usize, handles: BezierHandles, stroke: StrokeId) {
|
||||
debug_assert!(!self.id.contains(&id), "Tried to push an existing point to a point domain");
|
||||
|
||||
self.id.push(id);
|
||||
|
@ -319,12 +319,12 @@ impl SegmentDomain {
|
|||
self.id.iter().copied().zip(self.end_point.iter_mut())
|
||||
}
|
||||
|
||||
pub(crate) fn handles_mut(&mut self) -> impl Iterator<Item = (SegmentId, &mut bezier_rs::BezierHandles, usize, usize)> {
|
||||
pub(crate) fn handles_mut(&mut self) -> impl Iterator<Item = (SegmentId, &mut BezierHandles, usize, usize)> {
|
||||
let nested = self.id.iter().zip(&mut self.handles).zip(&self.start_point).zip(&self.end_point);
|
||||
nested.map(|(((&a, b), &c), &d)| (a, b, c, d))
|
||||
}
|
||||
|
||||
pub(crate) fn handles_and_points_mut(&mut self) -> impl Iterator<Item = (&mut bezier_rs::BezierHandles, &mut usize, &mut usize)> {
|
||||
pub(crate) fn handles_and_points_mut(&mut self) -> impl Iterator<Item = (&mut BezierHandles, &mut usize, &mut usize)> {
|
||||
let nested = self.handles.iter_mut().zip(&mut self.start_point).zip(&mut self.end_point);
|
||||
nested.map(|((a, b), c)| (a, b, c))
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ impl SegmentDomain {
|
|||
self.id.iter().position(|&check_id| check_id == id)
|
||||
}
|
||||
|
||||
fn resolve_range(&self, range: &core::ops::RangeInclusive<SegmentId>) -> Option<core::ops::RangeInclusive<usize>> {
|
||||
fn resolve_range(&self, range: &std::ops::RangeInclusive<SegmentId>) -> Option<std::ops::RangeInclusive<usize>> {
|
||||
match (self.id_to_index(*range.start()), self.id_to_index(*range.end())) {
|
||||
(Some(start), Some(end)) if start.max(end) < self.handles.len().min(self.id.len()).min(self.start_point.len()).min(self.end_point.len()) => Some(start..=end),
|
||||
_ => {
|
||||
|
@ -446,7 +446,7 @@ impl SegmentDomain {
|
|||
pub struct RegionDomain {
|
||||
#[serde(alias = "ids")]
|
||||
id: Vec<RegionId>,
|
||||
segment_range: Vec<core::ops::RangeInclusive<SegmentId>>,
|
||||
segment_range: Vec<std::ops::RangeInclusive<SegmentId>>,
|
||||
fill: Vec<FillId>,
|
||||
}
|
||||
|
||||
|
@ -476,7 +476,7 @@ impl RegionDomain {
|
|||
/// Like [`Self::retain`] but also gives the function access to the segment range.
|
||||
///
|
||||
/// Note that this function requires an allocation that `retain` avoids.
|
||||
pub fn retain_with_region(&mut self, f: impl Fn(&RegionId, &core::ops::RangeInclusive<SegmentId>) -> bool) {
|
||||
pub fn retain_with_region(&mut self, f: impl Fn(&RegionId, &std::ops::RangeInclusive<SegmentId>) -> bool) {
|
||||
let keep = self.id.iter().zip(self.segment_range.iter()).map(|(id, range)| f(id, range)).collect::<Vec<_>>();
|
||||
let mut iter = keep.iter().copied();
|
||||
self.segment_range.retain(|_| iter.next().unwrap());
|
||||
|
@ -486,7 +486,7 @@ impl RegionDomain {
|
|||
self.id.retain(|_| iter.next().unwrap());
|
||||
}
|
||||
|
||||
pub fn push(&mut self, id: RegionId, segment_range: core::ops::RangeInclusive<SegmentId>, fill: FillId) {
|
||||
pub fn push(&mut self, id: RegionId, segment_range: std::ops::RangeInclusive<SegmentId>, fill: FillId) {
|
||||
if self.id.contains(&id) {
|
||||
warn!("Duplicate region");
|
||||
return;
|
||||
|
@ -504,7 +504,7 @@ impl RegionDomain {
|
|||
self.id.iter().copied().max_by(|a, b| a.0.cmp(&b.0)).map(|mut id| id.next_id()).unwrap_or(RegionId::ZERO)
|
||||
}
|
||||
|
||||
pub fn segment_range_mut(&mut self) -> impl Iterator<Item = (RegionId, &mut core::ops::RangeInclusive<SegmentId>)> {
|
||||
pub fn segment_range_mut(&mut self) -> impl Iterator<Item = (RegionId, &mut std::ops::RangeInclusive<SegmentId>)> {
|
||||
self.id.iter().copied().zip(self.segment_range.iter_mut())
|
||||
}
|
||||
|
||||
|
@ -516,7 +516,7 @@ impl RegionDomain {
|
|||
&self.id
|
||||
}
|
||||
|
||||
pub fn segment_range(&self) -> &[core::ops::RangeInclusive<SegmentId>] {
|
||||
pub fn segment_range(&self) -> &[std::ops::RangeInclusive<SegmentId>] {
|
||||
&self.segment_range
|
||||
}
|
||||
|
||||
|
@ -545,7 +545,7 @@ impl RegionDomain {
|
|||
/// Iterates over regions in the domain.
|
||||
///
|
||||
/// Tuple is: (id, segment_range, fill)
|
||||
pub fn iter(&self) -> impl Iterator<Item = (RegionId, core::ops::RangeInclusive<SegmentId>, FillId)> + '_ {
|
||||
pub fn iter(&self) -> impl Iterator<Item = (RegionId, std::ops::RangeInclusive<SegmentId>, FillId)> + '_ {
|
||||
let ids = self.id.iter().copied();
|
||||
let segment_range = self.segment_range.iter().cloned();
|
||||
let fill = self.fill.iter().copied();
|
||||
|
@ -643,7 +643,7 @@ impl FoundSubpath {
|
|||
|
||||
impl VectorData {
|
||||
/// Construct a [`bezier_rs::Bezier`] curve spanning from the resolved position of the start and end points with the specified handles.
|
||||
fn segment_to_bezier_with_index(&self, start: usize, end: usize, handles: bezier_rs::BezierHandles) -> bezier_rs::Bezier {
|
||||
fn segment_to_bezier_with_index(&self, start: usize, end: usize, handles: BezierHandles) -> bezier_rs::Bezier {
|
||||
let start = self.point_domain.positions()[start];
|
||||
let end = self.point_domain.positions()[end];
|
||||
bezier_rs::Bezier { start, end, handles }
|
||||
|
@ -752,15 +752,15 @@ impl VectorData {
|
|||
}
|
||||
|
||||
/// Construct a [`bezier_rs::Bezier`] curve from an iterator of segments with (handles, start point, end point) independently of discontinuities.
|
||||
pub fn subpath_from_segments_ignore_discontinuities(&self, segments: impl Iterator<Item = (bezier_rs::BezierHandles, usize, usize)>) -> Option<bezier_rs::Subpath<PointId>> {
|
||||
pub fn subpath_from_segments_ignore_discontinuities(&self, segments: impl Iterator<Item = (BezierHandles, usize, usize)>) -> Option<bezier_rs::Subpath<PointId>> {
|
||||
let mut first_point = None;
|
||||
let mut groups = Vec::new();
|
||||
let mut last: Option<(usize, bezier_rs::BezierHandles)> = None;
|
||||
let mut last: Option<(usize, BezierHandles)> = None;
|
||||
|
||||
for (handle, start, end) in segments {
|
||||
first_point = Some(first_point.unwrap_or(start));
|
||||
|
||||
groups.push(bezier_rs::ManipulatorGroup {
|
||||
groups.push(ManipulatorGroup {
|
||||
anchor: self.point_domain.positions()[start],
|
||||
in_handle: last.and_then(|(_, handle)| handle.end()),
|
||||
out_handle: handle.start(),
|
||||
|
@ -776,7 +776,7 @@ impl VectorData {
|
|||
if closed {
|
||||
groups[0].in_handle = last_handle.end();
|
||||
} else {
|
||||
groups.push(bezier_rs::ManipulatorGroup {
|
||||
groups.push(ManipulatorGroup {
|
||||
anchor: self.point_domain.positions()[end],
|
||||
in_handle: last_handle.end(),
|
||||
out_handle: None,
|
||||
|
@ -789,10 +789,10 @@ impl VectorData {
|
|||
}
|
||||
|
||||
/// Construct a [`bezier_rs::Bezier`] curve from an iterator of segments with (handles, start point, end point). Returns None if any ids are invalid or if the segments are not continuous.
|
||||
fn subpath_from_segments(&self, segments: impl Iterator<Item = (bezier_rs::BezierHandles, usize, usize)>) -> Option<bezier_rs::Subpath<PointId>> {
|
||||
fn subpath_from_segments(&self, segments: impl Iterator<Item = (BezierHandles, usize, usize)>) -> Option<bezier_rs::Subpath<PointId>> {
|
||||
let mut first_point = None;
|
||||
let mut groups = Vec::new();
|
||||
let mut last: Option<(usize, bezier_rs::BezierHandles)> = None;
|
||||
let mut last: Option<(usize, BezierHandles)> = None;
|
||||
|
||||
for (handle, start, end) in segments {
|
||||
if last.is_some_and(|(previous_end, _)| previous_end != start) {
|
||||
|
@ -801,7 +801,7 @@ impl VectorData {
|
|||
}
|
||||
first_point = Some(first_point.unwrap_or(start));
|
||||
|
||||
groups.push(bezier_rs::ManipulatorGroup {
|
||||
groups.push(ManipulatorGroup {
|
||||
anchor: self.point_domain.positions()[start],
|
||||
in_handle: last.and_then(|(_, handle)| handle.end()),
|
||||
out_handle: handle.start(),
|
||||
|
@ -817,7 +817,7 @@ impl VectorData {
|
|||
if closed {
|
||||
groups[0].in_handle = last_handle.end();
|
||||
} else {
|
||||
groups.push(bezier_rs::ManipulatorGroup {
|
||||
groups.push(ManipulatorGroup {
|
||||
anchor: self.point_domain.positions()[end],
|
||||
in_handle: last_handle.end(),
|
||||
out_handle: None,
|
||||
|
@ -908,13 +908,13 @@ impl VectorData {
|
|||
})
|
||||
}
|
||||
|
||||
/// Construct an iterator [`bezier_rs::ManipulatorGroup`] for stroke.
|
||||
pub fn manipulator_groups(&self) -> impl Iterator<Item = bezier_rs::ManipulatorGroup<PointId>> + '_ {
|
||||
/// Construct an iterator [`ManipulatorGroup`] for stroke.
|
||||
pub fn manipulator_groups(&self) -> impl Iterator<Item = ManipulatorGroup<PointId>> + '_ {
|
||||
self.stroke_bezier_paths().flat_map(|mut path| std::mem::take(path.manipulator_groups_mut()))
|
||||
}
|
||||
|
||||
/// Get manipulator by id
|
||||
pub fn manipulator_group_id(&self, id: impl Into<PointId>) -> Option<bezier_rs::ManipulatorGroup<PointId>> {
|
||||
pub fn manipulator_group_id(&self, id: impl Into<PointId>) -> Option<ManipulatorGroup<PointId>> {
|
||||
let id = id.into();
|
||||
self.manipulator_groups().find(|group| group.id == id)
|
||||
}
|
||||
|
@ -994,7 +994,7 @@ pub struct StrokePathIter<'a> {
|
|||
}
|
||||
|
||||
impl Iterator for StrokePathIter<'_> {
|
||||
type Item = (Vec<bezier_rs::ManipulatorGroup<PointId>>, bool);
|
||||
type Item = (Vec<ManipulatorGroup<PointId>>, bool);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let current_start = if let Some((index, _)) = self.points.iter().enumerate().skip(self.skip).find(|(_, val)| val.connected() == 1) {
|
||||
|
@ -1016,7 +1016,7 @@ impl Iterator for StrokePathIter<'_> {
|
|||
loop {
|
||||
let Some(val) = self.points[point_index].take_first() else {
|
||||
// Dead end
|
||||
groups.push(bezier_rs::ManipulatorGroup {
|
||||
groups.push(ManipulatorGroup {
|
||||
anchor: self.vector_data.point_domain.positions()[point_index],
|
||||
in_handle,
|
||||
out_handle: None,
|
||||
|
@ -1035,7 +1035,7 @@ impl Iterator for StrokePathIter<'_> {
|
|||
} else {
|
||||
self.vector_data.segment_domain.end_point()[val.segment_index]
|
||||
};
|
||||
groups.push(bezier_rs::ManipulatorGroup {
|
||||
groups.push(ManipulatorGroup {
|
||||
anchor: self.vector_data.point_domain.positions()[point_index],
|
||||
in_handle,
|
||||
out_handle: handles.start(),
|
||||
|
|
|
@ -3,10 +3,10 @@ use crate::Ctx;
|
|||
use crate::instances::Instance;
|
||||
use crate::uuid::generate_uuid;
|
||||
use bezier_rs::BezierHandles;
|
||||
use core::hash::BuildHasher;
|
||||
use dyn_any::DynAny;
|
||||
use kurbo::{BezPath, PathEl, Point};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::hash::BuildHasher;
|
||||
|
||||
/// Represents a procedural change to the [`PointDomain`] in [`VectorData`].
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
|
@ -260,7 +260,7 @@ pub struct RegionModification {
|
|||
add: Vec<RegionId>,
|
||||
remove: HashSet<RegionId>,
|
||||
#[serde(serialize_with = "serialize_hashmap", deserialize_with = "deserialize_hashmap")]
|
||||
segment_range: HashMap<RegionId, core::ops::RangeInclusive<SegmentId>>,
|
||||
segment_range: HashMap<RegionId, std::ops::RangeInclusive<SegmentId>>,
|
||||
#[serde(serialize_with = "serialize_hashmap", deserialize_with = "deserialize_hashmap")]
|
||||
fill: HashMap<RegionId, FillId>,
|
||||
}
|
||||
|
@ -416,8 +416,8 @@ impl VectorModification {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::hash::Hash for VectorModification {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl Hash for VectorModification {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
generate_uuid().hash(state)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@ use crate::vector::style::{PaintOrder, StrokeAlign, StrokeCap, StrokeJoin};
|
|||
use crate::vector::{FillId, PointDomain, RegionId};
|
||||
use crate::{CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicElement, GraphicGroupTable, OwnedContextImpl};
|
||||
use bezier_rs::{Join, ManipulatorGroup, Subpath};
|
||||
use core::f64::consts::PI;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use kurbo::{Affine, BezPath, DEFAULT_ACCURACY, ParamCurve, PathEl, PathSeg, Point, Shape};
|
||||
use rand::{Rng, SeedableRng};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::f64::consts::PI;
|
||||
use std::f64::consts::TAU;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
/// Implemented for types that can be converted to an iterator of vector data.
|
||||
/// Used for the fill and stroke node so they can be used on VectorData or GraphicGroup
|
||||
|
@ -1949,7 +1949,7 @@ mod test {
|
|||
pub struct FutureWrapperNode<T: Clone>(T);
|
||||
|
||||
impl<'i, T: 'i + Clone + Send> Node<'i, Footprint> for FutureWrapperNode<T> {
|
||||
type Output = Pin<Box<dyn core::future::Future<Output = T> + 'i + Send>>;
|
||||
type Output = Pin<Box<dyn Future<Output = T> + 'i + Send>>;
|
||||
fn eval(&'i self, _input: Footprint) -> Self::Output {
|
||||
let value = self.0.clone();
|
||||
Box::pin(async move { value })
|
||||
|
@ -2011,7 +2011,7 @@ mod test {
|
|||
// Test a VectorData with non-zero rotation
|
||||
let square = VectorData::from_subpath(Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE));
|
||||
let mut square = VectorDataTable::new(square);
|
||||
*square.get_mut(0).unwrap().transform *= DAffine2::from_angle(core::f64::consts::FRAC_PI_4);
|
||||
*square.get_mut(0).unwrap().transform *= DAffine2::from_angle(std::f64::consts::FRAC_PI_4);
|
||||
let bounding_box = BoundingBoxNode {
|
||||
vector_data: FutureWrapperNode(square),
|
||||
}
|
||||
|
@ -2111,7 +2111,7 @@ mod test {
|
|||
}
|
||||
|
||||
#[track_caller]
|
||||
fn contains_segment(vector: VectorData, target: bezier_rs::Bezier) {
|
||||
fn contains_segment(vector: VectorData, target: Bezier) {
|
||||
let segments = vector.segment_bezier_iter().map(|x| x.1);
|
||||
let count = segments.filter(|bezier| bezier.abs_diff_eq(&target, 0.01) || bezier.reversed().abs_diff_eq(&target, 0.01)).count();
|
||||
assert_eq!(
|
||||
|
@ -2132,16 +2132,16 @@ mod test {
|
|||
assert_eq!(beveled.segment_domain.ids().len(), 8);
|
||||
|
||||
// Segments
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(5., 0.), DVec2::new(95., 0.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(5., 100.), DVec2::new(95., 100.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(0., 5.), DVec2::new(0., 95.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 5.), DVec2::new(100., 95.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(5., 0.), DVec2::new(95., 0.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(5., 100.), DVec2::new(95., 100.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(0., 5.), DVec2::new(0., 95.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 5.), DVec2::new(100., 95.)));
|
||||
|
||||
// Joins
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(5., 0.), DVec2::new(0., 5.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(95., 0.), DVec2::new(100., 5.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 95.), DVec2::new(95., 100.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(5., 100.), DVec2::new(0., 95.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(5., 0.), DVec2::new(0., 5.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(95., 0.), DVec2::new(100., 5.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 95.), DVec2::new(95., 100.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(5., 100.), DVec2::new(0., 95.)));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -2155,12 +2155,12 @@ mod test {
|
|||
assert_eq!(beveled.segment_domain.ids().len(), 3);
|
||||
|
||||
// Segments
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(-100., 0.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(-100., 0.)));
|
||||
let trimmed = curve.trim(bezier_rs::TValue::Euclidean(5. / curve.length(Some(0.00001))), bezier_rs::TValue::Parametric(1.));
|
||||
contains_segment(beveled.clone(), trimmed);
|
||||
|
||||
// Join
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -2179,12 +2179,12 @@ mod test {
|
|||
assert_eq!(beveled.segment_domain.ids().len(), 3);
|
||||
|
||||
// Segments
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(-10., 0.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(-10., 0.)));
|
||||
let trimmed = curve.trim(bezier_rs::TValue::Euclidean(5. / curve.length(Some(0.00001))), bezier_rs::TValue::Parametric(1.));
|
||||
contains_segment(beveled.clone(), trimmed);
|
||||
|
||||
// Join
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -2197,13 +2197,13 @@ mod test {
|
|||
assert_eq!(beveled.segment_domain.ids().len(), 5);
|
||||
|
||||
// Segments
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(0., 0.), DVec2::new(50., 0.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(100., 50.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(0., 0.), DVec2::new(50., 0.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(100., 50.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
|
||||
|
||||
// Joins
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(50., 0.), DVec2::new(100., 50.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(50., 0.), DVec2::new(100., 50.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -2218,11 +2218,11 @@ mod test {
|
|||
assert_eq!(beveled.segment_domain.ids().len(), 5);
|
||||
|
||||
// Segments
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-100., 0.), DVec2::new(-5., 0.)));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(0., 0.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-100., 0.), DVec2::new(-5., 0.)));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(0., 0.)));
|
||||
contains_segment(beveled.clone(), point);
|
||||
let [start, end] = curve.split(bezier_rs::TValue::Euclidean(5. / curve.length(Some(0.00001))));
|
||||
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(start.start, start.end));
|
||||
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(start.start, start.end));
|
||||
contains_segment(beveled.clone(), end);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ pub struct DocumentNode {
|
|||
#[cfg_attr(feature = "serde", serde(default = "return_true"))]
|
||||
pub visible: bool,
|
||||
/// When two different proto nodes hash to the same value (e.g. two value nodes each containing `2_u32` or two multiply nodes that have the same node IDs as input), the duplicates are removed.
|
||||
/// See [`crate::proto::ProtoNetwork::generate_stable_node_ids`] for details.
|
||||
/// See [`ProtoNetwork::generate_stable_node_ids`] for details.
|
||||
/// However sometimes this is not desirable, for example in the case of a [`graphene_core::memo::MonitorNode`] that needs to be accessed outside of the graph.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub skip_deduplication: bool,
|
||||
|
@ -602,7 +602,7 @@ pub struct OldDocumentNode {
|
|||
/// Metadata about the node including its position in the graph UI. Ensure the click target in the encapsulating network is updated when the node moves by using network.update_click_target(node_id).
|
||||
pub metadata: OldDocumentNodeMetadata,
|
||||
/// When two different proto nodes hash to the same value (e.g. two value nodes each containing `2_u32` or two multiply nodes that have the same node IDs as input), the duplicates are removed.
|
||||
/// See [`crate::proto::ProtoNetwork::generate_stable_node_ids`] for details.
|
||||
/// See [`ProtoNetwork::generate_stable_node_ids`] for details.
|
||||
/// However sometimes this is not desirable, for example in the case of a [`graphene_core::memo::MonitorNode`] that needs to be accessed outside of the graph.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub skip_deduplication: bool,
|
||||
|
@ -710,8 +710,8 @@ pub struct NodeNetwork {
|
|||
pub scope_injections: FxHashMap<String, (NodeId, Type)>,
|
||||
}
|
||||
|
||||
impl std::hash::Hash for NodeNetwork {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
impl Hash for NodeNetwork {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.exports.hash(state);
|
||||
let mut nodes: Vec<_> = self.nodes.iter().collect();
|
||||
nodes.sort_by_key(|(id, _)| *id);
|
||||
|
|
|
@ -373,7 +373,7 @@ impl ProtoNetwork {
|
|||
(inwards_edges, id_map)
|
||||
}
|
||||
|
||||
/// Inserts a [`graphene_core::structural::ComposeNode`] for each node that has a [`ProtoNodeInput::Node`]. The compose node evaluates the first node, and then sends the result into the second node.
|
||||
/// Inserts a [`structural::ComposeNode`] for each node that has a [`ProtoNodeInput::Node`]. The compose node evaluates the first node, and then sends the result into the second node.
|
||||
pub fn resolve_inputs(&mut self) -> Result<(), String> {
|
||||
// Perform topological sort once
|
||||
self.reorder_ids()?;
|
||||
|
@ -542,7 +542,7 @@ pub enum GraphErrorType {
|
|||
InvalidImplementations { inputs: String, error_inputs: Vec<Vec<(usize, (Type, Type))>> },
|
||||
MultipleImplementations { inputs: String, valid: Vec<NodeIOTypes> },
|
||||
}
|
||||
impl core::fmt::Debug for GraphErrorType {
|
||||
impl Debug for GraphErrorType {
|
||||
// TODO: format with the document graph context so the input index is the same as in the graph UI.
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
@ -603,7 +603,7 @@ impl GraphError {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl core::fmt::Debug for GraphError {
|
||||
impl Debug for GraphError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("NodeGraphError")
|
||||
.field("path", &self.node_path.iter().map(|id| id.0).collect::<Vec<_>>())
|
||||
|
|
|
@ -174,7 +174,7 @@ fn fix_nodes(network: &mut NodeNetwork) {
|
|||
if (proto_node_identifier.name.starts_with("graphene_core::ConstructLayerNode") || proto_node_identifier.name.starts_with("graphene_core::AddArtboardNode"))
|
||||
&& node.inputs.len() < 3 =>
|
||||
{
|
||||
node.inputs.push(NodeInput::Reflection(graph_craft::document::DocumentNodeMetadata::DocumentNodePath));
|
||||
node.inputs.push(NodeInput::Reflection(DocumentNodeMetadata::DocumentNodePath));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -280,7 +280,7 @@ fn to_path(vector: &VectorData, transform: DAffine2) -> Vec<path_bool::PathSegme
|
|||
path
|
||||
}
|
||||
|
||||
fn to_path_segments(path: &mut Vec<path_bool::PathSegment>, subpath: &bezier_rs::Subpath<PointId>, transform: DAffine2) {
|
||||
fn to_path_segments(path: &mut Vec<path_bool::PathSegment>, subpath: &Subpath<PointId>, transform: DAffine2) {
|
||||
use path_bool::PathSegment;
|
||||
let mut global_start = None;
|
||||
let mut global_end = DVec2::ZERO;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use dyn_any::StaticType;
|
||||
use glam::{DVec2, UVec2};
|
||||
use glam::{DVec2, IVec2, UVec2};
|
||||
use graph_craft::document::value::RenderOutput;
|
||||
use graph_craft::proto::{NodeConstructor, TypeErasedBox};
|
||||
use graphene_core::raster::color::Color;
|
||||
|
@ -46,8 +46,8 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => RasterDataTable<GPU>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_core::instances::Instances<Artboard>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => String]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => glam::IVec2]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => glam::DVec2]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => IVec2]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => DVec2]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => bool]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => f64]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => u32]),
|
||||
|
@ -57,7 +57,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => BlendMode]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_std::transform::ReferencePoint]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_core::vector::misc::BooleanOperation]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Option<graphene_core::Color>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Option<Color>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_core::vector::style::Fill]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_core::vector::style::StrokeCap]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_core::vector::style::StrokeJoin]),
|
||||
|
@ -67,7 +67,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_core::vector::style::Gradient]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_core::vector::style::GradientStops]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Vec<graphene_core::uuid::NodeId>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_core::Color]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Color]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Box<graphene_core::vector::VectorModification>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_std::vector::misc::CentroidType]),
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Image<Color>]),
|
||||
|
@ -77,8 +77,8 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Vec<DVec2>]),
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Arc<WasmSurfaceHandle>]),
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => WindowHandle]),
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Option<wgpu_executor::WgpuSurface>]),
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => wgpu_executor::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 => f64]),
|
||||
|
@ -108,7 +108,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
),
|
||||
),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => wgpu_executor::WgpuSurface]),
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => WgpuSurface]),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(graphene_core::memo::ImpureMemoNode<_, _, _>, input: Context, fn_params: [Context => RasterDataTable<GPU>]),
|
||||
#[cfg(feature = "gpu")]
|
||||
|
@ -122,7 +122,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
Box::pin(async move {
|
||||
let editor_api: DowncastBothNode<Context, &WasmEditorApi> = DowncastBothNode::new(args[0].clone());
|
||||
let node = <wgpu_executor::CreateGpuSurfaceNode<_>>::new(editor_api);
|
||||
let any: DynAnyNode<Context, _, _> = graphene_std::any::DynAnyNode::new(node);
|
||||
let any: DynAnyNode<Context, _, _> = DynAnyNode::new(node);
|
||||
Box::new(any) as TypeErasedBox
|
||||
})
|
||||
},
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn wrap_network_in_scope(mut network: NodeNetwork, editor_api: Arc<WasmEdito
|
|||
// .node_template_input_override(vec![Some(NodeInput::node(NodeId(1), 0)), Some(NodeInput::node(NodeId(0), 1))])
|
||||
// .document_node;
|
||||
|
||||
let render_node = graph_craft::document::DocumentNode {
|
||||
let render_node = DocumentNode {
|
||||
inputs: vec![NodeInput::node(NodeId(0), 0), NodeInput::node(NodeId(2), 0)],
|
||||
implementation: DocumentNodeImplementation::Network(NodeNetwork {
|
||||
exports: vec![NodeInput::node(NodeId(2), 0)],
|
||||
|
|
|
@ -56,7 +56,7 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
|
|||
.zip(field_names.iter())
|
||||
.map(|zipped| match zipped {
|
||||
(Some(name), _) => name.value(),
|
||||
(_, name) => name.to_string().to_case(convert_case::Case::Title),
|
||||
(_, name) => name.to_string().to_case(Case::Title),
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
@ -510,7 +510,7 @@ fn generate_phantom_data<'a>(fn_generics: impl Iterator<Item = &'a crate::Generi
|
|||
(fn_generic_params, phantom_data_declerations)
|
||||
}
|
||||
|
||||
fn generate_register_node_impl(parsed: &ParsedNodeFn, field_names: &[&Ident], struct_name: &Ident, identifier: &TokenStream2) -> Result<TokenStream2, syn::Error> {
|
||||
fn generate_register_node_impl(parsed: &ParsedNodeFn, field_names: &[&Ident], struct_name: &Ident, identifier: &TokenStream2) -> Result<TokenStream2, Error> {
|
||||
if parsed.attributes.skip_impl {
|
||||
return Ok(quote!());
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ struct LifetimeReplacer(&'static str);
|
|||
|
||||
impl VisitMut for LifetimeReplacer {
|
||||
fn visit_lifetime_mut(&mut self, lifetime: &mut Lifetime) {
|
||||
lifetime.ident = syn::Ident::new(self.0, lifetime.ident.span());
|
||||
lifetime.ident = Ident::new(self.0, lifetime.ident.span());
|
||||
}
|
||||
|
||||
fn visit_type_mut(&mut self, ty: &mut Type) {
|
||||
|
@ -662,7 +662,7 @@ struct FilterUsedGenerics {
|
|||
}
|
||||
|
||||
impl VisitMut for FilterUsedGenerics {
|
||||
fn visit_lifetime_mut(&mut self, used_lifetime: &mut syn::Lifetime) {
|
||||
fn visit_lifetime_mut(&mut self, used_lifetime: &mut Lifetime) {
|
||||
for (generic, used) in self.all.iter().zip(self.used.iter_mut()) {
|
||||
let crate::GenericParam::Lifetime(lifetime_param) = generic else { continue };
|
||||
if used_lifetime == &lifetime_param.lifetime {
|
||||
|
|
|
@ -111,12 +111,8 @@ fn derive_enum(enum_attributes: &[Attribute], name: Ident, input: syn::DataEnum)
|
|||
})
|
||||
.collect();
|
||||
|
||||
let crate_name = proc_macro_crate::crate_name("graphene-core").map_err(|e| {
|
||||
syn::Error::new(
|
||||
proc_macro2::Span::call_site(),
|
||||
format!("Failed to find location of graphene_core. Make sure it is imported as a dependency: {}", e),
|
||||
)
|
||||
})?;
|
||||
let crate_name = proc_macro_crate::crate_name("graphene-core")
|
||||
.map_err(|e| syn::Error::new(Span::call_site(), format!("Failed to find location of graphene_core. Make sure it is imported as a dependency: {}", e)))?;
|
||||
let crate_name = match crate_name {
|
||||
proc_macro_crate::FoundCrate::Itself => quote!(crate),
|
||||
proc_macro_crate::FoundCrate::Name(name) => {
|
||||
|
@ -144,19 +140,19 @@ fn derive_enum(enum_attributes: &[Attribute], name: Ident, input: syn::DataEnum)
|
|||
let docstring = match &variant.basic_item.description {
|
||||
Some(s) => {
|
||||
let s = s.trim();
|
||||
quote! { Some(::alloc::borrow::Cow::Borrowed(#s)) }
|
||||
quote! { Some(::std::borrow::Cow::Borrowed(#s)) }
|
||||
}
|
||||
None => quote! { None },
|
||||
};
|
||||
let icon = match &variant.basic_item.icon {
|
||||
Some(s) => quote! { Some(::alloc::borrow::Cow::Borrowed(#s)) },
|
||||
Some(s) => quote! { Some(::std::borrow::Cow::Borrowed(#s)) },
|
||||
None => quote! { None },
|
||||
};
|
||||
quote! {
|
||||
(
|
||||
#name::#vname, #crate_name::registry::VariantMetadata {
|
||||
name: ::alloc::borrow::Cow::Borrowed(#vname_str),
|
||||
label: ::alloc::borrow::Cow::Borrowed(#label),
|
||||
name: ::std::borrow::Cow::Borrowed(#vname_str),
|
||||
label: ::std::borrow::Cow::Borrowed(#label),
|
||||
docstring: #docstring,
|
||||
icon: #icon,
|
||||
}
|
||||
|
|
|
@ -88,10 +88,10 @@ impl Parse for ParsedWidgetOverride {
|
|||
let lit: LitStr = input.parse()?;
|
||||
Ok(ParsedWidgetOverride::Custom(lit))
|
||||
}
|
||||
_ => Err(syn::Error::new(variant.span(), "Unknown ParsedWidgetOverride variant")),
|
||||
_ => Err(Error::new(variant.span(), "Unknown ParsedWidgetOverride variant")),
|
||||
}
|
||||
} else {
|
||||
Err(syn::Error::new(input.span(), "Expected ParsedWidgetOverride::<variant>"))
|
||||
Err(Error::new(input.span(), "Expected ParsedWidgetOverride::<variant>"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1214,7 +1214,7 @@ mod tests {
|
|||
let attr = quote!(category("Test"));
|
||||
|
||||
// Use quote_spanned! to attach a specific span to the problematic part
|
||||
let problem_span = proc_macro2::Span::call_site(); // You could create a custom span here if needed
|
||||
let problem_span = Span::call_site(); // You could create a custom span here if needed
|
||||
let tuples = quote_spanned!(problem_span=> () ());
|
||||
let input = quote! {
|
||||
fn test_node(
|
||||
|
|
|
@ -16,7 +16,7 @@ impl Context {
|
|||
backends: wgpu::Backends::all(),
|
||||
..Default::default()
|
||||
};
|
||||
let instance = wgpu::Instance::new(instance_descriptor);
|
||||
let instance = Instance::new(instance_descriptor);
|
||||
|
||||
let adapter_options = wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::HighPerformance,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue