mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Remove unsafe code and clean up the code base in general (#1263)
* Remove unsafe code * Make node graph test syncronous * Add miri step to ci * Remove unsafe from node graph evaluation * Replace operation pseudo_hash with hash based on discriminant * Fix test * Move memo module to core and make it safe * Fix formatting * Remove unused stuff from gstd * Use safe casting for creating key variants * Fix memo node types * Fix ref node * "fix" ub * Use correct input types for ExtractImageFrame * Fix types for async nodes * Fix missing implementation * Manually override output type for async nodes * Fix types for EditorApi * Fix output type for WasmSurfaceHandle * Remove unused miri.yml * Fix incorrect type for cache node
This commit is contained in:
committed by
Keavon Chambers
parent
259dcdc628
commit
4e1bfddcd8
@@ -6,9 +6,8 @@ use crate::proto::{Any as DAny, FutureAny};
|
||||
use graphene_core::raster::{to_primtive_string, BlendMode, LuminanceCalculation};
|
||||
use graphene_core::{Color, Node, Type};
|
||||
|
||||
use dyn_any::DynAny;
|
||||
pub use dyn_any::StaticType;
|
||||
use dyn_any::{DynAny, Upcast};
|
||||
use dyn_clone::DynClone;
|
||||
pub use glam::{DAffine2, DVec2};
|
||||
use std::hash::Hash;
|
||||
pub use std::sync::Arc;
|
||||
@@ -245,56 +244,60 @@ impl<'a> TaggedValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_from_any(input: Box<dyn DynAny<'a> + 'a>) -> Option<Self> {
|
||||
pub fn try_from_any(input: Box<dyn DynAny<'a> + 'a>) -> Result<Self, String> {
|
||||
use dyn_any::downcast;
|
||||
use std::any::TypeId;
|
||||
|
||||
match DynAny::type_id(input.as_ref()) {
|
||||
x if x == TypeId::of::<()>() => Some(TaggedValue::None),
|
||||
x if x == TypeId::of::<String>() => Some(TaggedValue::String(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<u32>() => Some(TaggedValue::U32(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<f32>() => Some(TaggedValue::F32(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<f64>() => Some(TaggedValue::F64(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<bool>() => Some(TaggedValue::Bool(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<DVec2>() => Some(TaggedValue::DVec2(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Option<DVec2>>() => Some(TaggedValue::OptionalDVec2(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::Image<Color>>() => Some(TaggedValue::Image(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Option<Arc<graphene_core::raster::Image<Color>>>>() => Some(TaggedValue::RcImage(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::ImageFrame<Color>>() => Some(TaggedValue::ImageFrame(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::Color>() => Some(TaggedValue::Color(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>>() => Some(TaggedValue::Subpaths(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Arc<bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>>() => Some(TaggedValue::RcSubpath(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<BlendMode>() => Some(TaggedValue::BlendMode(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<ImaginateSamplingMethod>() => Some(TaggedValue::ImaginateSamplingMethod(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<ImaginateMaskStartingFill>() => Some(TaggedValue::ImaginateMaskStartingFill(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<ImaginateStatus>() => Some(TaggedValue::ImaginateStatus(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Option<Vec<u64>>>() => Some(TaggedValue::LayerPath(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<DAffine2>() => Some(TaggedValue::DAffine2(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<LuminanceCalculation>() => Some(TaggedValue::LuminanceCalculation(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::VectorData>() => Some(TaggedValue::VectorData(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::Fill>() => Some(TaggedValue::Fill(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::Stroke>() => Some(TaggedValue::Stroke(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<f32>>() => Some(TaggedValue::VecF32(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::RedGreenBlue>() => Some(TaggedValue::RedGreenBlue(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::RelativeAbsolute>() => Some(TaggedValue::RelativeAbsolute(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::SelectiveColorChoice>() => Some(TaggedValue::SelectiveColorChoice(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::LineCap>() => Some(TaggedValue::LineCap(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::LineJoin>() => Some(TaggedValue::LineJoin(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::FillType>() => Some(TaggedValue::FillType(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::GradientType>() => Some(TaggedValue::GradientType(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<(f64, Option<graphene_core::Color>)>>() => Some(TaggedValue::GradientPositions(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::quantization::QuantizationChannels>() => Some(TaggedValue::Quantization(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Option<graphene_core::Color>>() => Some(TaggedValue::OptionalColor(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<graphene_core::uuid::ManipulatorGroupId>>() => Some(TaggedValue::ManipulatorGroupIds(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::text::Font>() => Some(TaggedValue::Font(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<graphene_core::vector::brush_stroke::BrushStroke>>() => Some(TaggedValue::BrushStrokes(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::IndexNode<Vec<graphene_core::raster::ImageFrame<Color>>>>() => Some(TaggedValue::Segments(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<crate::document::DocumentNode>() => Some(TaggedValue::DocumentNode(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::GraphicGroup>() => Some(TaggedValue::GraphicGroup(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::Artboard>() => Some(TaggedValue::Artboard(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<glam::IVec2>() => Some(TaggedValue::IVec2(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::SurfaceFrame>() => Some(TaggedValue::SurfaceFrame(*downcast(input).unwrap())),
|
||||
_ => None,
|
||||
x if x == TypeId::of::<()>() => Ok(TaggedValue::None),
|
||||
x if x == TypeId::of::<String>() => Ok(TaggedValue::String(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<u32>() => Ok(TaggedValue::U32(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<f32>() => Ok(TaggedValue::F32(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<f64>() => Ok(TaggedValue::F64(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<bool>() => Ok(TaggedValue::Bool(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<DVec2>() => Ok(TaggedValue::DVec2(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Option<DVec2>>() => Ok(TaggedValue::OptionalDVec2(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::Image<Color>>() => Ok(TaggedValue::Image(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Option<Arc<graphene_core::raster::Image<Color>>>>() => Ok(TaggedValue::RcImage(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::ImageFrame<Color>>() => Ok(TaggedValue::ImageFrame(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::Color>() => Ok(TaggedValue::Color(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>>() => Ok(TaggedValue::Subpaths(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Arc<bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>>() => Ok(TaggedValue::RcSubpath(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<BlendMode>() => Ok(TaggedValue::BlendMode(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<ImaginateSamplingMethod>() => Ok(TaggedValue::ImaginateSamplingMethod(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<ImaginateMaskStartingFill>() => Ok(TaggedValue::ImaginateMaskStartingFill(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<ImaginateStatus>() => Ok(TaggedValue::ImaginateStatus(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Option<Vec<u64>>>() => Ok(TaggedValue::LayerPath(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<DAffine2>() => Ok(TaggedValue::DAffine2(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<LuminanceCalculation>() => Ok(TaggedValue::LuminanceCalculation(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::VectorData>() => Ok(TaggedValue::VectorData(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::Fill>() => Ok(TaggedValue::Fill(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::Stroke>() => Ok(TaggedValue::Stroke(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<f32>>() => Ok(TaggedValue::VecF32(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::RedGreenBlue>() => Ok(TaggedValue::RedGreenBlue(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::RelativeAbsolute>() => Ok(TaggedValue::RelativeAbsolute(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::SelectiveColorChoice>() => Ok(TaggedValue::SelectiveColorChoice(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::LineCap>() => Ok(TaggedValue::LineCap(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::LineJoin>() => Ok(TaggedValue::LineJoin(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::FillType>() => Ok(TaggedValue::FillType(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::vector::style::GradientType>() => Ok(TaggedValue::GradientType(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<(f64, Option<graphene_core::Color>)>>() => Ok(TaggedValue::GradientPositions(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::quantization::QuantizationChannels>() => Ok(TaggedValue::Quantization(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Option<graphene_core::Color>>() => Ok(TaggedValue::OptionalColor(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<graphene_core::uuid::ManipulatorGroupId>>() => Ok(TaggedValue::ManipulatorGroupIds(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::text::Font>() => Ok(TaggedValue::Font(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<Vec<graphene_core::vector::brush_stroke::BrushStroke>>() => Ok(TaggedValue::BrushStrokes(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::raster::IndexNode<Vec<graphene_core::raster::ImageFrame<Color>>>>() => Ok(TaggedValue::Segments(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<crate::document::DocumentNode>() => Ok(TaggedValue::DocumentNode(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::GraphicGroup>() => Ok(TaggedValue::GraphicGroup(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::Artboard>() => Ok(TaggedValue::Artboard(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<glam::IVec2>() => Ok(TaggedValue::IVec2(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::SurfaceFrame>() => Ok(TaggedValue::SurfaceFrame(*downcast(input).unwrap())),
|
||||
x if x == TypeId::of::<graphene_core::wasm_application_io::WasmSurfaceHandleFrame>() => {
|
||||
let frame = *downcast::<graphene_core::wasm_application_io::WasmSurfaceHandleFrame>(input).unwrap();
|
||||
Ok(TaggedValue::SurfaceFrame(frame.into()))
|
||||
}
|
||||
_ => Err(format!("Cannot convert {:?} to TaggedValue", DynAny::type_name(input.as_ref()))),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,82 +317,3 @@ impl UpcastNode {
|
||||
Self { value }
|
||||
}
|
||||
}
|
||||
|
||||
pub type Value<'a> = Box<dyn for<'i> ValueTrait<'i> + 'a>;
|
||||
|
||||
pub trait ValueTrait<'a>: DynAny<'a> + Upcast<dyn DynAny<'a> + 'a> + std::fmt::Debug + DynClone + Sync + Send + 'a {}
|
||||
|
||||
pub trait IntoValue<'a>: Sized + for<'i> ValueTrait<'i> + 'a {
|
||||
fn into_any(self) -> Value<'a> {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'a + StaticType + Upcast<dyn DynAny<'a> + 'a> + std::fmt::Debug + PartialEq + Clone + Sync + Send + 'a> ValueTrait<'a> for T {}
|
||||
|
||||
impl<'a, T: for<'i> ValueTrait<'i> + 'a> IntoValue<'a> for T {}
|
||||
|
||||
#[repr(C)]
|
||||
pub(crate) struct Vtable {
|
||||
pub(crate) destructor: unsafe fn(*mut ()),
|
||||
pub(crate) size: usize,
|
||||
pub(crate) align: usize,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub(crate) struct TraitObject {
|
||||
pub(crate) self_ptr: *mut u8,
|
||||
pub(crate) vtable: &'static Vtable,
|
||||
}
|
||||
|
||||
impl<'a> PartialEq for Box<dyn for<'i> ValueTrait<'i> + 'a> {
|
||||
#[cfg_attr(miri, ignore)]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.type_id() != other.type_id() {
|
||||
return false;
|
||||
}
|
||||
let self_trait_object = unsafe { std::mem::transmute::<&dyn ValueTrait, TraitObject>(self.as_ref()) };
|
||||
let other_trait_object = unsafe { std::mem::transmute::<&dyn ValueTrait, TraitObject>(other.as_ref()) };
|
||||
let size = self_trait_object.vtable.size;
|
||||
let self_mem = unsafe { std::slice::from_raw_parts(self_trait_object.self_ptr, size) };
|
||||
let other_mem = unsafe { std::slice::from_raw_parts(other_trait_object.self_ptr, size) };
|
||||
self_mem == other_mem
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hash for Value<'a> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
let self_trait_object = unsafe { std::mem::transmute::<&dyn ValueTrait, TraitObject>(self.as_ref()) };
|
||||
let size = self_trait_object.vtable.size;
|
||||
let self_mem = unsafe { std::slice::from_raw_parts(self_trait_object.self_ptr, size) };
|
||||
self_mem.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Clone for Value<'a> {
|
||||
fn clone(&self) -> Self {
|
||||
let self_trait_object = unsafe { std::mem::transmute::<&dyn ValueTrait, TraitObject>(self.as_ref()) };
|
||||
let size = self_trait_object.vtable.size;
|
||||
let self_mem = unsafe { std::slice::from_raw_parts(self_trait_object.self_ptr, size) }.to_owned();
|
||||
let ptr = Vec::leak(self_mem);
|
||||
unsafe {
|
||||
std::mem::transmute(TraitObject {
|
||||
self_ptr: ptr as *mut [u8] as *mut u8,
|
||||
vtable: self_trait_object.vtable,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(miri, ignore)]
|
||||
fn test_any_src() {
|
||||
assert!(2_u32.into_any() == 2_u32.into_any());
|
||||
assert!(2_u32.into_any() != 3_u32.into_any());
|
||||
assert!(2_u32.into_any() != 3_i32.into_any());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user