Lift the run to owned legacy list bridge into core-types

This commit is contained in:
Dennis Kobert
2026-09-08 20:19:12 +00:00
parent 296185b7fc
commit e322d8957d
3 changed files with 22 additions and 15 deletions

View File

@@ -31,6 +31,6 @@ pub use layout::{
pub use owned::{OwnedRecord, deepen_field_value, has_deep_element_glue, register_deep_element_clone, register_deep_field_value, replay_field_value};
pub use promote::{Promotion, assert_promoted, register_element_promote, register_field_promote, register_retained_heap};
pub use route::{RecordSource, SourcePlan};
pub use run::{Group, GroupItem, RunBuilder, RunColumn, RunView};
pub use run::{Group, GroupItem, RunBuilder, RunColumn, RunView, run_to_owned_list};
pub use serve::{FrameClaim, MaterializedSpan, Served, SlotRun, serve_input};
pub use testkit::{LiftedSource, ServedRecord, capture, test_frames};

View File

@@ -480,6 +480,25 @@ impl<'e> GroupItem<'e> {
}
}
/// One typed run as an owned legacy list, elements cloned and every attribute
/// copied through its erased read. The owned result outlives the evaluation the
/// run was materialized in, so an async source can carry it across its await.
pub fn run_to_owned_list<T: Clone + Send + Sync + dyn_any::StaticTypeSized>(item: &GroupItem) -> Option<crate::list::List<T>> {
let lanes = item.typed_lanes::<T>()?;
let mut list = crate::list::List::new();
for lane in 0..lanes.len() {
list.push(crate::list::Item::new_from_element(lanes.element_ref(lane).clone()));
}
for field in &item.layout().fields {
for lane in 0..lanes.len() {
// SAFETY: the offset comes from the item's own layout.
let value = unsafe { (field.read_erased)(item.lanes().get(lane).rec().ptr().add(field.offset)) };
list.set_attribute_value_dyn(field.name, lane, crate::list::AttributeValueDyn(value));
}
}
Some(list)
}
/// A run read at its element type. Record fields hold each marker's value
/// verbatim, so lane reads are plain typed reads at a hoisted offset.
pub struct RunView<'a, T> {

View File

@@ -4,7 +4,7 @@ use super::walk::push_lane_paint_into_interiors;
use super::{Graphic, detable_items};
use crate::markers::{ATTR_FILL, ATTR_STROKE};
use core_types::Color;
use core_types::list::{AttributeValueDyn, Item, List};
use core_types::list::{Item, List};
use raster_types::{CPU, GPU, Raster};
use vector_types::{GradientStops, Vector};
@@ -12,19 +12,7 @@ use vector_types::{GradientStops, Vector};
/// through its erased read. Content keeps its native form; the legacy
/// conversions layer their mapping on top.
pub fn run_to_list<T: Clone + Send + Sync + dyn_any::StaticTypeSized>(item: &core_types::record::GroupItem) -> Option<List<T>> {
let lanes = item.typed_lanes::<T>()?;
let mut list = List::new();
for lane in 0..lanes.len() {
list.push(Item::new_from_element(lanes.element_ref(lane).clone()));
}
for field in &item.layout().fields {
for lane in 0..lanes.len() {
// SAFETY: the offset comes from the item's own layout.
let value = unsafe { (field.read_erased)(item.lanes().get(lane).rec().ptr().add(field.offset)) };
list.set_attribute_value_dyn(field.name, lane, AttributeValueDyn(value));
}
}
Some(list)
core_types::record::run_to_owned_list(item)
}
/// Converts the group content of the list's paint attribute values to legacy