mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-28 18:08:11 +08:00
Re-derive the shared edge pointer and type-check the paint transmute
This commit is contained in:
@@ -124,6 +124,13 @@ impl<N: ?Sized> SharedEdge<N> {
|
|||||||
pub fn share(&self) -> Self {
|
pub fn share(&self) -> Self {
|
||||||
Self { ptr: self.ptr, own: self.own.clone() }
|
Self { ptr: self.ptr, own: self.own.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Re-derives the cached pointer from the owned payload. An exclusive
|
||||||
|
/// re-borrow of the payload invalidates the pointer taken before it, so
|
||||||
|
/// every mutation through `own` ends here.
|
||||||
|
pub fn rederive(&mut self) {
|
||||||
|
self.ptr = std::ptr::NonNull::from(&*self.own);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: `ptr` is derived from the owned Arc and never mutated through, so the edge is exactly as
|
// SAFETY: `ptr` is derived from the owned Arc and never mutated through, so the edge is exactly as
|
||||||
@@ -222,6 +229,7 @@ impl EdgeHandle {
|
|||||||
let shared = edge.downcast_mut::<SharedEdge<N>>().expect("set_layout hook matches the stored edge type");
|
let shared = edge.downcast_mut::<SharedEdge<N>>().expect("set_layout hook matches the stored edge type");
|
||||||
let node = std::sync::Arc::get_mut(&mut shared.own).expect("layout is installed before the node is shared");
|
let node = std::sync::Arc::get_mut(&mut shared.own).expect("layout is installed before the node is shared");
|
||||||
Node::<ContextImpl>::set_layout(node, layout);
|
Node::<ContextImpl>::set_layout(node, layout);
|
||||||
|
shared.rederive();
|
||||||
},
|
},
|
||||||
ty,
|
ty,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -378,9 +378,21 @@ fn forced_paint<'a, A: Attribute>(paint: LanePaint<'a>) -> Option<A::Value<'a>>
|
|||||||
name if name == Stroke::NAME => paint.stroke,
|
name if name == Stroke::NAME => paint.stroke,
|
||||||
_ => None,
|
_ => None,
|
||||||
}?;
|
}?;
|
||||||
|
assert_eq!(
|
||||||
|
std::any::TypeId::of::<A::Value<'static>>(),
|
||||||
|
std::any::TypeId::of::<Option<&'static List<Graphic<'static>>>>(),
|
||||||
|
"attribute `{}` is declared at another value type than this crate's paint form",
|
||||||
|
A::NAME
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
size_of::<A::Value<'a>>(),
|
||||||
|
size_of::<Option<&'a List<Graphic<'a>>>>(),
|
||||||
|
"the paint value form must span the marker's value"
|
||||||
|
);
|
||||||
// SAFETY: the census admits one value type per attribute name and panics on
|
// SAFETY: the census admits one value type per attribute name and panics on
|
||||||
// a conflict at registration, so a marker named `fill` or `stroke` carries
|
// a conflict at registration, and the asserts above re-check it, so a marker
|
||||||
// this crate's `Option<&List<Graphic>>` value form.
|
// named `fill` or `stroke` carries this crate's `Option<&List<Graphic>>`
|
||||||
|
// value form at the same size.
|
||||||
Some(unsafe { std::mem::transmute_copy::<Option<&'a List<Graphic>>, A::Value<'a>>(&Some(slot)) })
|
Some(unsafe { std::mem::transmute_copy::<Option<&'a List<Graphic>>, A::Value<'a>>(&Some(slot)) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user