mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 00:58:11 +08:00
Migrate test sources and assertions onto the safe record builders
This commit is contained in:
@@ -274,11 +274,10 @@ mod tests {
|
||||
let io = handle.serialize().expect("the eval landed a snapshot");
|
||||
let snapshot = io.downcast_ref::<CtxSnapshot>().expect("the monitor serializes its context snapshot");
|
||||
let ctx = snapshot.rehydrate(&scope).expect("the arena holds the chains");
|
||||
let GPoll::Final(value) = edge.eval(&ctx) else {
|
||||
let GPoll::Final(served) = core_types::record::capture(&edge, &ctx) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
// SAFETY: the eval produced a live record of the edge's layout.
|
||||
assert_eq!(unsafe { layout.rec(&value).element::<u32>() }, 11);
|
||||
assert_eq!(served.element::<u32>(), 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -226,7 +226,7 @@ mod tests {
|
||||
use core_types::context::{ContextImpl, EvalScope, ExtractArena, ExtractIndices};
|
||||
use core_types::list::{Item, List};
|
||||
use core_types::node::Node;
|
||||
use core_types::record::{self, Layout, Rec, RecordSource, RecordValue, stack};
|
||||
use core_types::record::{self, Layout, RecordSource, RecordValue, stack};
|
||||
|
||||
struct ValueNode<T>(T);
|
||||
|
||||
@@ -248,15 +248,11 @@ mod tests {
|
||||
|
||||
fn eval(&self, input: &ContextImpl<'e>) -> GPoll<RecordValue<'e>> {
|
||||
let (graphic, transform) = &self.rows[input.innermost_index() as usize % self.rows.len()];
|
||||
let dst = stack::push(self.layout.frame_bytes());
|
||||
if unsafe { record::write_element(dst, graphic.clone(), input.arena()) }.is_none() {
|
||||
return GPoll::arena_exhausted();
|
||||
}
|
||||
unsafe {
|
||||
dst.add(self.layout.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap()).cast::<DAffine2>().write(*transform);
|
||||
}
|
||||
stack::pop(dst);
|
||||
GPoll::Final(RecordValue::spilled(unsafe { Rec::new(dst.cast_const()) }))
|
||||
let mut frame = record::FrameBuilder::new(&self.layout, input.arena());
|
||||
frame.element(graphic.clone());
|
||||
frame.attr::<Transform>(*transform);
|
||||
let Some(value) = frame.finish() else { return GPoll::arena_exhausted() };
|
||||
GPoll::Final(value)
|
||||
}
|
||||
|
||||
fn extent_at(&self, _input: &ContextImpl<'e>, _level: u8) -> GPoll<Extent> {
|
||||
@@ -380,15 +376,11 @@ mod tests {
|
||||
let lane = input.innermost_index();
|
||||
let graphic = text(&format!("{label}{lane}"));
|
||||
let translated = DAffine2::from_translation(glam::DVec2::new(lane as f64, 0.));
|
||||
let dst = stack::push(self.layout.frame_bytes());
|
||||
if unsafe { record::write_element(dst, graphic, input.arena()) }.is_none() {
|
||||
return GPoll::arena_exhausted();
|
||||
}
|
||||
unsafe {
|
||||
dst.add(self.layout.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap()).cast::<DAffine2>().write(translated);
|
||||
}
|
||||
stack::pop(dst);
|
||||
GPoll::Final(RecordValue::spilled(unsafe { Rec::new(dst.cast_const()) }))
|
||||
let mut frame = record::FrameBuilder::new(&self.layout, input.arena());
|
||||
frame.element(graphic);
|
||||
frame.attr::<Transform>(translated);
|
||||
let Some(value) = frame.finish() else { return GPoll::arena_exhausted() };
|
||||
GPoll::Final(value)
|
||||
}
|
||||
|
||||
fn extent_at(&self, input: &ContextImpl<'e>, _level: u8) -> GPoll<Extent> {
|
||||
@@ -453,17 +445,13 @@ mod tests {
|
||||
assert_eq!(node.extent_at(&ctx, 0), GPoll::Final(Extent::AtLeast(0)));
|
||||
|
||||
let head = ctx.index_head();
|
||||
let offset = out.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap();
|
||||
for (lane, &(label, x)) in RAGGED_FLAT.iter().enumerate() {
|
||||
let mark = stack::sp();
|
||||
let GPoll::Final(value) = node.eval(&ctx.promoted(&head, lane as u64)) else {
|
||||
let GPoll::Final(record) = record::capture(&node, &ctx.promoted(&head, lane as u64)) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = out.rec(&value);
|
||||
assert_eq!(text_of(unsafe { record::borrow_element::<Graphic>(rec) }), label, "lane {lane}");
|
||||
let transform: DAffine2 = unsafe { rec.read(offset) };
|
||||
assert_eq!(text_of(&record.element::<Graphic>()), label, "lane {lane}");
|
||||
let transform: DAffine2 = record.attr::<Transform>();
|
||||
assert_eq!(transform.translation.x, x, "lane {lane}");
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,23 +508,20 @@ mod tests {
|
||||
assert_eq!(composed.extent_at(&ctx, 0), GPoll::Final(Extent::AtLeast(0)));
|
||||
|
||||
let head = ctx.index_head();
|
||||
let offset = flat_out.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap();
|
||||
for (lane, &(label, x)) in RAGGED_FLAT.iter().enumerate() {
|
||||
let mark = stack::sp();
|
||||
let scoped = ctx.promoted(&head, lane as u64);
|
||||
let GPoll::Final(direct) = flat.eval(&scoped) else {
|
||||
let GPoll::Final(direct) = record::capture(&flat, &scoped) else {
|
||||
panic!("expected a final record from flat_map");
|
||||
};
|
||||
let direct_label = text_of(unsafe { record::borrow_element::<Graphic>(flat_out.rec(&direct)) }).to_string();
|
||||
let direct_x: DAffine2 = unsafe { flat_out.rec(&direct).read(offset) };
|
||||
let GPoll::Final(value) = composed.eval(&scoped) else {
|
||||
let direct_label = text_of(&direct.element::<Graphic>()).to_string();
|
||||
let direct_x: DAffine2 = direct.attr::<Transform>();
|
||||
let GPoll::Final(value) = record::capture(&composed, &scoped) else {
|
||||
panic!("expected a final record from flatten(map)");
|
||||
};
|
||||
assert_eq!(text_of(unsafe { record::borrow_element::<Graphic>(composed_out.rec(&value)) }), direct_label, "lane {lane}");
|
||||
let composed_x: DAffine2 = unsafe { composed_out.rec(&value).read(offset) };
|
||||
assert_eq!(text_of(&value.element::<Graphic>()), direct_label, "lane {lane}");
|
||||
let composed_x: DAffine2 = value.attr::<Transform>();
|
||||
assert_eq!(composed_x, direct_x, "lane {lane}");
|
||||
assert_eq!((direct_label.as_str(), direct_x.translation.x), (label, x), "lane {lane}");
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,17 +574,14 @@ mod tests {
|
||||
assert_eq!(batch.len(), 5);
|
||||
let offset = out.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap();
|
||||
for lane in 0..5 {
|
||||
let mark = stack::sp();
|
||||
let GPoll::Final(value) = node.eval(&ctx.promoted(&head, lane as u64)) else {
|
||||
let GPoll::Final(record) = record::capture(&node, &ctx.promoted(&head, lane as u64)) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = out.rec(&value);
|
||||
let single = text_of(unsafe { record::borrow_element::<Graphic>(rec) }).to_string();
|
||||
let single = text_of(&record.element::<Graphic>()).to_string();
|
||||
assert_eq!(text_of(unsafe { record::borrow_element::<Graphic>(batch.get(lane).rec()) }), single, "lane {lane}");
|
||||
let batched: DAffine2 = unsafe { batch.get(lane).rec().read(offset) };
|
||||
let direct: DAffine2 = unsafe { rec.read(offset) };
|
||||
let direct: DAffine2 = record.attr::<Transform>();
|
||||
assert_eq!(batched, direct, "lane {lane}");
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,27 +599,21 @@ mod tests {
|
||||
assert_eq!(node.extent_at(&ctx, 0), GPoll::Final(Extent::Exactly(3)));
|
||||
|
||||
let head = ctx.index_head();
|
||||
let offset = out.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap();
|
||||
// Lane 2 is the unexpanded subgroup H, riding as a leaf at G's depth.
|
||||
let expected: [(&str, f64); 2] = [("a", 1.), ("b", 20.5)];
|
||||
for (lane, &(label, x)) in expected.iter().enumerate() {
|
||||
let mark = stack::sp();
|
||||
let GPoll::Final(value) = node.eval(&ctx.promoted(&head, lane as u64)) else {
|
||||
let GPoll::Final(record) = record::capture(&node, &ctx.promoted(&head, lane as u64)) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = out.rec(&value);
|
||||
assert_eq!(text_of(unsafe { record::borrow_element::<Graphic>(rec) }), label, "lane {lane}");
|
||||
let transform: DAffine2 = unsafe { rec.read(offset) };
|
||||
assert_eq!(text_of(&record.element::<Graphic>()), label, "lane {lane}");
|
||||
let transform: DAffine2 = record.attr::<Transform>();
|
||||
assert_eq!(transform.translation.x, x, "lane {lane}");
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
|
||||
let mark = stack::sp();
|
||||
let GPoll::Final(value) = node.eval(&ctx.promoted(&head, 2)) else {
|
||||
let GPoll::Final(record) = record::capture(&node, &ctx.promoted(&head, 2)) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = out.rec(&value);
|
||||
let Graphic::Graphic(children) = (unsafe { record::borrow_element::<Graphic>(rec) }) else {
|
||||
let Graphic::Graphic(children) = record.element::<Graphic>() else {
|
||||
panic!("lane 2 keeps the subgroup element");
|
||||
};
|
||||
assert_eq!(children.len(), 1);
|
||||
@@ -647,9 +623,8 @@ mod tests {
|
||||
300.,
|
||||
"embedded transforms ride untouched"
|
||||
);
|
||||
let transform: DAffine2 = unsafe { rec.read(offset) };
|
||||
let transform: DAffine2 = record.attr::<Transform>();
|
||||
assert_eq!(transform.translation.x, 4000.5);
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -777,10 +752,10 @@ mod tests {
|
||||
|
||||
fn eval(&self, input: &ContextImpl<'e>) -> GPoll<RecordValue<'e>> {
|
||||
let color = self.colors[input.innermost_index() as usize];
|
||||
let dst = stack::push(self.layout.frame_bytes());
|
||||
unsafe { dst.cast::<Color>().write(color) };
|
||||
stack::pop(dst);
|
||||
GPoll::Final(RecordValue::spilled(unsafe { Rec::new(dst.cast_const()) }))
|
||||
let mut frame = record::FrameBuilder::new(&self.layout, input.arena());
|
||||
frame.element(color);
|
||||
let Some(value) = frame.finish() else { return GPoll::arena_exhausted() };
|
||||
GPoll::Final(value)
|
||||
}
|
||||
|
||||
fn extent_at(&self, _input: &ContextImpl<'e>, _level: u8) -> GPoll<Extent> {
|
||||
@@ -802,10 +777,10 @@ mod tests {
|
||||
let build = |colors: Vec<Color>| install_flip(ToGradientNode::new(RecordSource::new(ColorSource { layout: layout.clone(), colors }, &layout, &layout), &layout), &out);
|
||||
let stops_of = |colors: Vec<Color>| {
|
||||
let node = build(colors);
|
||||
let GPoll::Final(value) = node.eval(&ctx) else {
|
||||
let GPoll::Final(record) = record::capture(&node, &ctx) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
unsafe { record::borrow_element::<GradientStops>(out.rec(&value)) }.clone()
|
||||
record.element::<GradientStops>()
|
||||
};
|
||||
|
||||
let three = stops_of(vec![Color::BLACK, Color::WHITE, Color::BLACK]);
|
||||
@@ -880,21 +855,16 @@ mod tests {
|
||||
// One row holding the wrapped group flattens back to the lanes, the
|
||||
// group's identity transform composed onto each child's.
|
||||
let node = build!(layout, vec![(group, DAffine2::IDENTITY)], false);
|
||||
let out = Node::<ContextImpl>::layout(&node).clone();
|
||||
assert_eq!(node.extent_at(&ctx, 0), GPoll::Final(Extent::Exactly(2)));
|
||||
|
||||
let head = ctx.index_head();
|
||||
let offset = out.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap();
|
||||
for (lane, &(label, x)) in [("a", 1.), ("b", 2.)].iter().enumerate() {
|
||||
let mark = stack::sp();
|
||||
let GPoll::Final(value) = node.eval(&ctx.promoted(&head, lane as u64)) else {
|
||||
let GPoll::Final(record) = record::capture(&node, &ctx.promoted(&head, lane as u64)) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = out.rec(&value);
|
||||
assert_eq!(text_of(unsafe { record::borrow_element::<Graphic>(rec) }), label, "lane {lane}");
|
||||
let transform: DAffine2 = unsafe { rec.read(offset) };
|
||||
assert_eq!(text_of(&record.element::<Graphic>()), label, "lane {lane}");
|
||||
let transform: DAffine2 = record.attr::<Transform>();
|
||||
assert_eq!(transform.translation.x, x, "lane {lane}");
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -909,22 +879,17 @@ mod tests {
|
||||
rows.push((group(vec![]), translation(9.)));
|
||||
let layout = graphic_layout();
|
||||
let node = build!(layout, rows, true);
|
||||
let out = Node::<ContextImpl>::layout(&node).clone();
|
||||
assert_eq!(node.extent_at(&ctx, 0), GPoll::Final(Extent::Exactly(3)), "the empty group contributes no leaves");
|
||||
|
||||
let head = ctx.index_head();
|
||||
let offset = out.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap();
|
||||
let expected: [(&str, f64); 3] = [("a", 1.), ("b", 20.5), ("c", 4300.5)];
|
||||
for (lane, &(label, x)) in expected.iter().enumerate() {
|
||||
let mark = stack::sp();
|
||||
let GPoll::Final(value) = node.eval(&ctx.promoted(&head, lane as u64)) else {
|
||||
let GPoll::Final(record) = record::capture(&node, &ctx.promoted(&head, lane as u64)) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = out.rec(&value);
|
||||
assert_eq!(text_of(unsafe { record::borrow_element::<Graphic>(rec) }), label, "lane {lane}");
|
||||
let transform: DAffine2 = unsafe { rec.read(offset) };
|
||||
assert_eq!(text_of(&record.element::<Graphic>()), label, "lane {lane}");
|
||||
let transform: DAffine2 = record.attr::<Transform>();
|
||||
assert_eq!(transform.translation.x, x, "lane {lane}");
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -949,17 +914,14 @@ mod tests {
|
||||
assert_eq!(batch.len(), 3);
|
||||
let offset = out.offset_of(<Transform as AttributeMarker>::NAME, 0).unwrap();
|
||||
for lane in 0..3 {
|
||||
let mark = stack::sp();
|
||||
let GPoll::Final(value) = node.eval(&ctx.promoted(&head, lane as u64)) else {
|
||||
let GPoll::Final(record) = record::capture(&node, &ctx.promoted(&head, lane as u64)) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = out.rec(&value);
|
||||
let single = text_of(unsafe { record::borrow_element::<Graphic>(rec) }).to_string();
|
||||
let single = text_of(&record.element::<Graphic>()).to_string();
|
||||
assert_eq!(text_of(unsafe { record::borrow_element::<Graphic>(batch.get(lane).rec()) }), single, "lane {lane}");
|
||||
let batched: DAffine2 = unsafe { batch.get(lane).rec().read(offset) };
|
||||
let direct: DAffine2 = unsafe { rec.read(offset) };
|
||||
let direct: DAffine2 = record.attr::<Transform>();
|
||||
assert_eq!(batched, direct, "lane {lane}");
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,13 +562,10 @@ mod tests {
|
||||
#[test]
|
||||
fn the_native_flatten_reads_lanes_groups_and_reach() {
|
||||
let inner_vector = square(DVec2::ZERO);
|
||||
let inner_layout = core_types::record::Layout::default().with_writes(0, core_types::record::element_write_hashed::<Vector>(), &[]);
|
||||
let mut inner_bytes = vec![0u8; inner_layout.lane_stride()];
|
||||
// SAFETY: `inner_bytes` is one lane of `inner_layout`; a parked element
|
||||
// stores its reference.
|
||||
unsafe { inner_bytes.as_mut_ptr().cast::<&Vector>().write(&inner_vector) };
|
||||
// SAFETY: `inner_bytes` holds one lane of `inner_layout` at its stride.
|
||||
let inner_item = unsafe { core_types::record::GroupItem::from_resident(core_types::node::RecordBatch::new(inner_bytes.as_ptr(), 1, &inner_layout)) };
|
||||
let arena = core_types::arena::Arena::new(1 << 16).unwrap();
|
||||
let mut builder = core_types::record::RunBuilder::new(&arena, core_types::record::element_write_hashed::<Vector>(), &[], 1).unwrap();
|
||||
builder.push(inner_vector.clone()).unwrap();
|
||||
let inner_item = builder.finish();
|
||||
|
||||
let mut top = List::new();
|
||||
top.push(Item::new_from_element(Graphic::Vector(square(DVec2::ZERO))));
|
||||
|
||||
@@ -181,10 +181,9 @@ mod test {
|
||||
use super::*;
|
||||
use core_types::SourceId;
|
||||
use core_types::arena::Arena;
|
||||
use core_types::attribute::Attribute as AttributeMarker;
|
||||
use core_types::context::{ContextImpl, EvalScope};
|
||||
use core_types::node::Node;
|
||||
use core_types::record::{FieldWrite, Layout, Rec, RecordSource, RecordValue, element_write, stack};
|
||||
use core_types::record::{FieldWrite, FrameBuilder, Layout, RecordSource, RecordValue, capture, element_write, stack};
|
||||
use vector_types::subpath::Subpath;
|
||||
|
||||
struct ValueNode<T>(T);
|
||||
@@ -206,14 +205,13 @@ mod test {
|
||||
impl<'e> Node<ContextImpl<'e>> for TransformSource {
|
||||
type Output = RecordValue<'e>;
|
||||
|
||||
fn eval(&self, _input: &ContextImpl<'e>) -> GPoll<RecordValue<'e>> {
|
||||
let dst = stack::push(self.layout.frame_bytes());
|
||||
unsafe {
|
||||
dst.cast::<f64>().write(self.element);
|
||||
dst.add(self.layout.offset_of(TransformAttr::NAME, 0).unwrap()).cast::<DAffine2>().write(self.transform);
|
||||
}
|
||||
stack::pop(dst);
|
||||
GPoll::Final(RecordValue::spilled(unsafe { Rec::new(dst.cast_const()) }))
|
||||
fn eval(&self, input: &ContextImpl<'e>) -> GPoll<RecordValue<'e>> {
|
||||
use core_types::context::ExtractArena;
|
||||
let mut frame = FrameBuilder::new(&self.layout, input.arena());
|
||||
frame.element(self.element);
|
||||
frame.attr::<TransformAttr>(self.transform);
|
||||
let Some(value) = frame.finish() else { return GPoll::arena_exhausted() };
|
||||
GPoll::Final(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,16 +231,11 @@ mod test {
|
||||
fn eval(&self, input: &ContextImpl<'e>) -> GPoll<RecordValue<'e>> {
|
||||
use core_types::context::{ExtractArena, ExtractIndices};
|
||||
let (vector, transform) = &self.rows[input.innermost_index() as usize % self.rows.len()];
|
||||
let dst = stack::push(self.layout.frame_bytes());
|
||||
// SAFETY: dst is the claimed frame of this layout; offsets are the layout's own.
|
||||
unsafe {
|
||||
if core_types::record::write_element(dst, vector.clone(), input.arena()).is_none() {
|
||||
return GPoll::Error(Box::new(core_types::gpoll::GraphError::new("arena exhausted")));
|
||||
}
|
||||
core_types::record::write_field(dst, self.layout.offset_of(<TransformAttr as AttributeMarker>::NAME, 0).unwrap(), *transform);
|
||||
}
|
||||
stack::pop(dst);
|
||||
GPoll::Final(RecordValue::spilled(unsafe { Rec::new(dst.cast_const()) }))
|
||||
let mut frame = FrameBuilder::new(&self.layout, input.arena());
|
||||
frame.element(vector.clone());
|
||||
frame.attr::<TransformAttr>(*transform);
|
||||
let Some(value) = frame.finish() else { return GPoll::arena_exhausted() };
|
||||
GPoll::Final(value)
|
||||
}
|
||||
|
||||
fn extent_at(&self, _input: &ContextImpl<'e>, _level: u8) -> GPoll<Extent> {
|
||||
@@ -266,16 +259,13 @@ mod test {
|
||||
type Output = RecordValue<'e>;
|
||||
|
||||
fn eval(&self, input: &ContextImpl<'e>) -> GPoll<RecordValue<'e>> {
|
||||
use core_types::context::ExtractPosition;
|
||||
use core_types::context::{ExtractArena, ExtractPosition};
|
||||
let position = input.try_position().and_then(|mut positions| positions.next()).unwrap_or(DVec2::ZERO);
|
||||
let dst = stack::push(self.layout.frame_bytes());
|
||||
// SAFETY: dst is the claimed frame of this layout; offsets are the layout's own.
|
||||
unsafe {
|
||||
dst.cast::<f64>().write(position.x);
|
||||
core_types::record::write_field(dst, self.layout.offset_of(<TransformAttr as AttributeMarker>::NAME, 0).unwrap(), DAffine2::IDENTITY);
|
||||
}
|
||||
stack::pop(dst);
|
||||
GPoll::Final(RecordValue::spilled(unsafe { Rec::new(dst.cast_const()) }))
|
||||
let mut frame = FrameBuilder::new(&self.layout, input.arena());
|
||||
frame.element(position.x);
|
||||
frame.attr::<TransformAttr>(DAffine2::IDENTITY);
|
||||
let Some(value) = frame.finish() else { return GPoll::arena_exhausted() };
|
||||
GPoll::Final(value)
|
||||
}
|
||||
|
||||
fn layout(&self) -> &Layout {
|
||||
@@ -315,19 +305,15 @@ mod test {
|
||||
|
||||
let head = ctx.index_head();
|
||||
for copy in 0..3u64 {
|
||||
let mark = stack::sp();
|
||||
let lane = ctx.promoted(&head, copy);
|
||||
let GPoll::Final(value) = node.eval(&lane) else {
|
||||
let GPoll::Final(record) = capture(&node, &lane) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = leveled.rec(&value);
|
||||
assert_eq!(unsafe { rec.element::<f64>() }, 7.);
|
||||
assert_eq!(record.element::<f64>(), 7.);
|
||||
// Zero angle, direction (10, 0), count 3: copy `j` steps j * (5, 0)
|
||||
// past the row's own (5, 5) translation.
|
||||
let composed: DAffine2 = unsafe { rec.read(leveled.offset_of(TransformAttr::NAME, 0).unwrap()) };
|
||||
let composed: DAffine2 = record.attr::<TransformAttr>();
|
||||
assert_eq!(composed, DAffine2::from_translation(DVec2::new(5. + copy as f64 * 5., 5.)));
|
||||
// SAFETY: the element and transform were read out above, so no borrow into this lane's frames remains.
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,25 +334,20 @@ mod test {
|
||||
|
||||
let mut node = RepeatRadialNode::new(RecordSource::new(content, &layout, &layout), ValueNode(90.0f64), ValueNode(2.0f64), ValueNode(4u32), &layout);
|
||||
Node::<ContextImpl>::set_layout(&mut node, repeat_radial_layout_meta().resolve(&[Some(&layout)]));
|
||||
let leveled = Node::<ContextImpl>::layout(&node).clone();
|
||||
assert_eq!(node.extent_at(&ctx, 0), GPoll::Final(Extent::Exactly(4)));
|
||||
|
||||
let head = ctx.index_head();
|
||||
for copy in 0..4u64 {
|
||||
let mark = stack::sp();
|
||||
let lane = ctx.promoted(&head, copy);
|
||||
let GPoll::Final(value) = node.eval(&lane) else {
|
||||
let GPoll::Final(record) = capture(&node, &lane) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = leveled.rec(&value);
|
||||
assert_eq!(unsafe { rec.element::<f64>() }, 7.);
|
||||
assert_eq!(record.element::<f64>(), 7.);
|
||||
// The kernel's own formula, so the float operations match exactly.
|
||||
let step = DAffine2::from_angle((TAU / 4.) * copy as f64 + 90.0f64.to_radians()) * DAffine2::from_translation(2. * DVec2::Y);
|
||||
let expected = DAffine2::from_translation(local.translation) * step * DAffine2::from_mat2(local.matrix2);
|
||||
let composed: DAffine2 = unsafe { rec.read(leveled.offset_of(TransformAttr::NAME, 0).unwrap()) };
|
||||
let composed: DAffine2 = record.attr::<TransformAttr>();
|
||||
assert_eq!(composed, expected);
|
||||
// SAFETY: the element and transform were read out above, so no borrow into this lane's frames remains.
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,18 +381,14 @@ mod test {
|
||||
|
||||
let head = ctx.index_head();
|
||||
for (flat, &point) in expected.iter().enumerate() {
|
||||
let mark = stack::sp();
|
||||
let lane = ctx.promoted(&head, flat as u64);
|
||||
let GPoll::Final(value) = node.eval(&lane) else {
|
||||
let GPoll::Final(record) = capture(&node, &lane) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let rec = leveled.rec(&value);
|
||||
// The content saw the pushed position, and the output transform lands on it.
|
||||
assert_eq!(unsafe { rec.element::<f64>() }, point.x);
|
||||
let composed: DAffine2 = unsafe { rec.read(leveled.offset_of(<TransformAttr as AttributeMarker>::NAME, 0).unwrap()) };
|
||||
assert_eq!(record.element::<f64>(), point.x);
|
||||
let composed: DAffine2 = record.attr::<TransformAttr>();
|
||||
assert_eq!(composed.translation, point);
|
||||
// SAFETY: the element and transform were read out above, so no borrow into this lane's frames remains.
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,21 +409,17 @@ mod test {
|
||||
|
||||
let mut node = RepeatOnPointsNode::new(RecordSource::new(content, &content_layout, &content_layout), points, ValueNode(true), &content_layout);
|
||||
Node::<ContextImpl>::set_layout(&mut node, repeat_on_points_layout_meta().resolve(&[Some(&content_layout)]));
|
||||
let leveled = Node::<ContextImpl>::layout(&node).clone();
|
||||
|
||||
let mut expected = positions.clone();
|
||||
expected.reverse();
|
||||
let head = ctx.index_head();
|
||||
for (flat, &point) in expected.iter().enumerate() {
|
||||
let mark = stack::sp();
|
||||
let lane = ctx.promoted(&head, flat as u64);
|
||||
let GPoll::Final(value) = node.eval(&lane) else {
|
||||
let GPoll::Final(record) = capture(&node, &lane) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
let composed: DAffine2 = unsafe { leveled.rec(&value).read(leveled.offset_of(<TransformAttr as AttributeMarker>::NAME, 0).unwrap()) };
|
||||
let composed: DAffine2 = record.attr::<TransformAttr>();
|
||||
assert_eq!(composed.translation, point);
|
||||
// SAFETY: the transform was read out above, so no borrow into this lane's frames remains.
|
||||
unsafe { stack::rewind(mark) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user