Skip to content

Commit 4b11dce

Browse files
committed
Make Table<T> implement the IntoIterator trait
1 parent 7cb42b9 commit 4b11dce

File tree

23 files changed

+207
-180
lines changed

23 files changed

+207
-180
lines changed

editor/src/messages/portfolio/spreadsheet/spreadsheet_message_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ impl<T: TableRowLayout> TableRowLayout for Table<T> {
288288
}
289289

290290
let mut rows = self
291-
.iter_ref()
291+
.iter()
292292
.enumerate()
293293
.map(|(index, row)| {
294294
let (scale, angle, translation) = row.transform.to_scale_angle_translation();

editor/src/node_graph_executor/runtime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ impl NodeRuntime {
316316
} else if let Some(record) = introspected_data.downcast_ref::<IORecord<Context, Table<Vector>>>() {
317317
let default = TableRow::default();
318318
self.vector_modify
319-
.insert(parent_network_node_id, record.output.iter_ref().next().unwrap_or_else(|| default.as_ref()).element.clone());
319+
.insert(parent_network_node_id, record.output.iter().next().unwrap_or_else(|| default.as_ref()).element.clone());
320320
} else {
321321
log::warn!("Failed to downcast monitor node output {parent_network_node_id:?}");
322322
}

node-graph/gbrush/src/brush.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ where
130130
pub async fn create_brush_texture(brush_style: &BrushStyle) -> Raster<CPU> {
131131
let stamp = brush_stamp_generator(brush_style.diameter, brush_style.color, brush_style.hardness, brush_style.flow);
132132
let transform = DAffine2::from_scale_angle_translation(DVec2::splat(brush_style.diameter), 0., -DVec2::splat(brush_style.diameter / 2.));
133-
let blank_texture = empty_image((), transform, Color::TRANSPARENT).iter().next().unwrap_or_default();
133+
let blank_texture = empty_image((), transform, Color::TRANSPARENT).into_iter().next().unwrap_or_default();
134134
let image = blend_stamp_closure(stamp, blank_texture, |a, b| blend_colors(a, b, BlendMode::Normal, 1.));
135135

136136
image.element
@@ -184,7 +184,7 @@ async fn brush(_: impl Ctx, mut image_frame_table: Table<Raster<CPU>>, strokes:
184184
image_frame_table.push(TableRow::default());
185185
}
186186
// TODO: Find a way to handle more than one row
187-
let table_row = image_frame_table.iter_ref().next().expect("Expected the one row we just pushed").into_cloned();
187+
let table_row = image_frame_table.iter().next().expect("Expected the one row we just pushed").into_cloned();
188188

189189
let [start, end] = Table::new_from_row(table_row.clone()).bounding_box(DAffine2::IDENTITY, false).unwrap_or([DVec2::ZERO, DVec2::ZERO]);
190190
let image_bbox = AxisAlignedBbox { start, end };
@@ -198,7 +198,7 @@ async fn brush(_: impl Ctx, mut image_frame_table: Table<Raster<CPU>>, strokes:
198198
let mut brush_plan = cache.compute_brush_plan(table_row, &draw_strokes);
199199

200200
// TODO: Find a way to handle more than one row
201-
let Some(mut actual_image) = extend_image_to_bounds((), Table::new_from_row(brush_plan.background), background_bounds).iter().next() else {
201+
let Some(mut actual_image) = extend_image_to_bounds((), Table::new_from_row(brush_plan.background), background_bounds).into_iter().next() else {
202202
return Table::new();
203203
};
204204

@@ -246,7 +246,7 @@ async fn brush(_: impl Ctx, mut image_frame_table: Table<Raster<CPU>>, strokes:
246246

247247
let table = blit_node.eval(blit_target).await;
248248
assert_eq!(table.len(), 1);
249-
table.iter().next().unwrap_or_default()
249+
table.into_iter().next().unwrap_or_default()
250250
};
251251

252252
// Cache image before doing final blend, and store final stroke texture.
@@ -285,7 +285,7 @@ async fn brush(_: impl Ctx, mut image_frame_table: Table<Raster<CPU>>, strokes:
285285
FutureWrapperNode::new(ClonedNode::new(positions)),
286286
FutureWrapperNode::new(ClonedNode::new(blend_params)),
287287
);
288-
erase_restore_mask = blit_node.eval(Table::new_from_row(erase_restore_mask)).await.iter().next().unwrap_or_default();
288+
erase_restore_mask = blit_node.eval(Table::new_from_row(erase_restore_mask)).await.into_iter().next().unwrap_or_default();
289289
}
290290
// Yes, this is essentially the same as the above, but we duplicate to inline the blend mode.
291291
BlendMode::Restore => {
@@ -295,7 +295,7 @@ async fn brush(_: impl Ctx, mut image_frame_table: Table<Raster<CPU>>, strokes:
295295
FutureWrapperNode::new(ClonedNode::new(positions)),
296296
FutureWrapperNode::new(ClonedNode::new(blend_params)),
297297
);
298-
erase_restore_mask = blit_node.eval(Table::new_from_row(erase_restore_mask)).await.iter().next().unwrap_or_default();
298+
erase_restore_mask = blit_node.eval(Table::new_from_row(erase_restore_mask)).await.into_iter().next().unwrap_or_default();
299299
}
300300
_ => unreachable!(),
301301
}
@@ -406,6 +406,6 @@ mod test {
406406
BrushCache::default(),
407407
)
408408
.await;
409-
assert_eq!(image.iter_ref().next().unwrap().element.width, 20);
409+
assert_eq!(image.iter().next().unwrap().element.width, 20);
410410
}
411411
}

node-graph/gcore/src/artboard.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub fn migrate_artboard_group<'de, D: serde::Deserializer<'de>>(deserializer: D)
9090

9191
impl BoundingBox for Table<Artboard> {
9292
fn bounding_box(&self, transform: DAffine2, include_stroke: bool) -> Option<[DVec2; 2]> {
93-
self.iter_ref().filter_map(|row| row.element.bounding_box(transform, include_stroke)).reduce(Quad::combine_bounds)
93+
self.iter().filter_map(|row| row.element.bounding_box(transform, include_stroke)).reduce(Quad::combine_bounds)
9494
}
9595
}
9696

node-graph/gcore/src/graphic.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,16 @@ impl Graphic {
155155

156156
pub fn had_clip_enabled(&self) -> bool {
157157
match self {
158-
Graphic::Vector(vector) => vector.iter_ref().all(|row| row.alpha_blending.clip),
159-
Graphic::Group(group) => group.iter_ref().all(|row| row.alpha_blending.clip),
160-
Graphic::RasterCPU(raster) => raster.iter_ref().all(|row| row.alpha_blending.clip),
161-
Graphic::RasterGPU(raster) => raster.iter_ref().all(|row| row.alpha_blending.clip),
158+
Graphic::Vector(vector) => vector.iter().all(|row| row.alpha_blending.clip),
159+
Graphic::Group(group) => group.iter().all(|row| row.alpha_blending.clip),
160+
Graphic::RasterCPU(raster) => raster.iter().all(|row| row.alpha_blending.clip),
161+
Graphic::RasterGPU(raster) => raster.iter().all(|row| row.alpha_blending.clip),
162162
}
163163
}
164164

165165
pub fn can_reduce_to_clip_path(&self) -> bool {
166166
match self {
167-
Graphic::Vector(vector) => vector.iter_ref().all(|row| {
167+
Graphic::Vector(vector) => vector.iter().all(|row| {
168168
let style = &row.element.style;
169169
let alpha_blending = &row.alpha_blending;
170170
(alpha_blending.opacity > 1. - f32::EPSILON) && style.fill().is_opaque() && style.stroke().is_none_or(|stroke| !stroke.has_renderable_stroke())
@@ -187,7 +187,7 @@ impl BoundingBox for Graphic {
187187

188188
impl BoundingBox for Table<Graphic> {
189189
fn bounding_box(&self, transform: DAffine2, include_stroke: bool) -> Option<[DVec2; 2]> {
190-
self.iter_ref()
190+
self.iter()
191191
.filter_map(|element| element.element.bounding_box(transform * *element.transform, include_stroke))
192192
.reduce(Quad::combine_bounds)
193193
}
@@ -246,7 +246,7 @@ async fn to_group<Data: Into<Table<Graphic>> + 'n>(
246246
async fn flatten_group(_: impl Ctx, group: Table<Graphic>, fully_flatten: bool) -> Table<Graphic> {
247247
// TODO: Avoid mutable reference, instead return a new Table<Graphic>?
248248
fn flatten_group(output_group_table: &mut Table<Graphic>, current_group_table: Table<Graphic>, fully_flatten: bool, recursion_depth: usize) {
249-
for current_row in current_group_table.iter_ref() {
249+
for current_row in current_group_table.iter() {
250250
let current_element = current_row.element.clone();
251251
let reference = *current_row.source_node_id;
252252

@@ -285,7 +285,7 @@ async fn flatten_group(_: impl Ctx, group: Table<Graphic>, fully_flatten: bool)
285285
async fn flatten_vector(_: impl Ctx, group: Table<Graphic>) -> Table<Vector> {
286286
// TODO: Avoid mutable reference, instead return a new Table<Graphic>?
287287
fn flatten_group(output_group_table: &mut Table<Vector>, current_group_table: Table<Graphic>) {
288-
for current_graphic_row in current_group_table.iter_ref() {
288+
for current_graphic_row in current_group_table.iter() {
289289
let current_graphic = current_graphic_row.element.clone();
290290
let source_node_id = *current_graphic_row.source_node_id;
291291

@@ -301,7 +301,7 @@ async fn flatten_vector(_: impl Ctx, group: Table<Graphic>) -> Table<Vector> {
301301
}
302302
// Handle any leaf elements we encounter, which can be either non-group elements or groups that we don't want to flatten
303303
Graphic::Vector(vector_table) => {
304-
for current_vector_row in vector_table.iter_ref() {
304+
for current_vector_row in vector_table.iter() {
305305
output_group_table.push(TableRow {
306306
element: current_vector_row.element.clone(),
307307
transform: *current_graphic_row.transform * *current_vector_row.transform,
@@ -367,7 +367,7 @@ impl<T: Clone> AtIndex for Table<T> {
367367

368368
fn at_index(&self, index: usize) -> Option<Self::Output> {
369369
let mut result_table = Self::default();
370-
if let Some(row) = self.iter_ref().nth(index) {
370+
if let Some(row) = self.iter().nth(index) {
371371
result_table.push(row.into_cloned());
372372
Some(result_table)
373373
} else {
@@ -415,7 +415,7 @@ pub fn migrate_group<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Resul
415415
// Try to deserialize as either table format
416416
if let Ok(old_table) = serde_json::from_value::<Table<GraphicGroup>>(value.clone()) {
417417
let mut group_table = Table::new();
418-
for row in old_table.iter_ref() {
418+
for row in old_table.iter() {
419419
for (graphic, source_node_id) in &row.element.elements {
420420
group_table.push(TableRow {
421421
element: graphic.clone(),

node-graph/gcore/src/raster/image.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ pub fn migrate_image_frame<'de, D: serde::Deserializer<'de>>(deserializer: D) ->
256256
fn from(element: GraphicElement) -> Self {
257257
match element {
258258
GraphicElement::RasterFrame(RasterFrame::ImageFrame(image)) => Self {
259-
image: image.iter_ref().next().unwrap().element.clone(),
259+
image: image.iter().next().unwrap().element.clone(),
260260
},
261261
_ => panic!("Expected Image, found {:?}", element),
262262
}
@@ -298,14 +298,14 @@ pub fn migrate_image_frame<'de, D: serde::Deserializer<'de>>(deserializer: D) ->
298298
}
299299
FormatVersions::ImageFrameTable(image_frame) => Table::new_from_element(Raster::new_cpu(
300300
image_frame
301-
.iter_ref()
301+
.iter()
302302
.next()
303-
.unwrap_or(Table::new_from_element(ImageFrame::default()).iter_ref().next().unwrap())
303+
.unwrap_or(Table::new_from_element(ImageFrame::default()).iter().next().unwrap())
304304
.element
305305
.image
306306
.clone(),
307307
)),
308-
FormatVersions::ImageTable(table) => Table::new_from_element(Raster::new_cpu(table.iter_ref().next().unwrap().element.clone())),
308+
FormatVersions::ImageTable(table) => Table::new_from_element(Raster::new_cpu(table.iter().next().unwrap().element.clone())),
309309
FormatVersions::RasterTable(table) => table,
310310
})
311311
}
@@ -354,7 +354,7 @@ pub fn migrate_image_frame_row<'de, D: serde::Deserializer<'de>>(deserializer: D
354354
fn from(element: GraphicElement) -> Self {
355355
match element {
356356
GraphicElement::RasterFrame(RasterFrame::ImageFrame(image)) => Self {
357-
image: image.iter_ref().next().unwrap().element.clone(),
357+
image: image.iter().next().unwrap().element.clone(),
358358
},
359359
_ => panic!("Expected Image, found {:?}", element),
360360
}
@@ -398,10 +398,10 @@ pub fn migrate_image_frame_row<'de, D: serde::Deserializer<'de>>(deserializer: D
398398
source_node_id: None,
399399
},
400400
FormatVersions::ImageFrameTable(image_frame) => TableRow {
401-
element: Raster::new_cpu(image_frame.iter_ref().next().unwrap().element.image.clone()),
401+
element: Raster::new_cpu(image_frame.iter().next().unwrap().element.image.clone()),
402402
..Default::default()
403403
},
404-
FormatVersions::RasterTable(image_frame_table) => image_frame_table.iter().next().unwrap_or_default(),
404+
FormatVersions::RasterTable(image_frame_table) => image_frame_table.into_iter().next().unwrap_or_default(),
405405
FormatVersions::RasterTableRow(image_table_row) => image_table_row,
406406
})
407407
}

node-graph/gcore/src/raster_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ where
204204
Raster<T>: Storage,
205205
{
206206
fn bounding_box(&self, transform: DAffine2, _include_stroke: bool) -> Option<[DVec2; 2]> {
207-
self.iter_ref()
207+
self.iter()
208208
.filter(|row| !row.element.is_empty()) // Eliminate empty images
209209
.flat_map(|row| {
210210
let transform = transform * *row.transform;

node-graph/gcore/src/render_complexity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub trait RenderComplexity {
1212

1313
impl<T: RenderComplexity> RenderComplexity for Table<T> {
1414
fn render_complexity(&self) -> usize {
15-
self.iter_ref().map(|row| row.element.render_complexity()).fold(0, usize::saturating_add)
15+
self.iter().map(|row| row.element.render_complexity()).fold(0, usize::saturating_add)
1616
}
1717
}
1818

node-graph/gcore/src/table.rs

Lines changed: 67 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,42 @@ impl<T> Table<T> {
6060
self.source_node_id.extend(table.source_node_id);
6161
}
6262

63-
pub fn iter(self) -> impl DoubleEndedIterator<Item = TableRow<T>> {
64-
self.element
65-
.into_iter()
66-
.zip(self.transform)
67-
.zip(self.alpha_blending)
68-
.zip(self.source_node_id)
69-
.map(|(((element, transform), alpha_blending), source_node_id)| TableRow {
70-
element,
71-
transform,
72-
alpha_blending,
73-
source_node_id,
74-
})
63+
pub fn get(&self, index: usize) -> Option<TableRowRef<'_, T>> {
64+
if index >= self.element.len() {
65+
return None;
66+
}
67+
68+
Some(TableRowRef {
69+
element: &self.element[index],
70+
transform: &self.transform[index],
71+
alpha_blending: &self.alpha_blending[index],
72+
source_node_id: &self.source_node_id[index],
73+
})
74+
}
75+
76+
pub fn get_mut(&mut self, index: usize) -> Option<TableRowMut<'_, T>> {
77+
if index >= self.element.len() {
78+
return None;
79+
}
80+
81+
Some(TableRowMut {
82+
element: &mut self.element[index],
83+
transform: &mut self.transform[index],
84+
alpha_blending: &mut self.alpha_blending[index],
85+
source_node_id: &mut self.source_node_id[index],
86+
})
87+
}
88+
89+
pub fn len(&self) -> usize {
90+
self.element.len()
91+
}
92+
93+
pub fn is_empty(&self) -> bool {
94+
self.element.is_empty()
7595
}
7696

77-
pub fn iter_ref(&self) -> impl DoubleEndedIterator<Item = TableRowRef<'_, T>> + Clone {
97+
/// Borrows a [`Table`] and returns an iterator of [`TableRowRef`]s, each containing references to the data of the respective row from the table.
98+
pub fn iter(&self) -> impl DoubleEndedIterator<Item = TableRowRef<'_, T>> + Clone {
7899
self.element
79100
.iter()
80101
.zip(self.transform.iter())
@@ -88,6 +109,7 @@ impl<T> Table<T> {
88109
})
89110
}
90111

112+
/// Mutably borrows a [`Table`] and returns an iterator of [`TableRowMut`]s, each containing mutable references to the data of the respective row from the table.
91113
pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = TableRowMut<'_, T>> {
92114
self.element
93115
.iter_mut()
@@ -101,39 +123,44 @@ impl<T> Table<T> {
101123
source_node_id,
102124
})
103125
}
126+
}
104127

105-
pub fn get(&self, index: usize) -> Option<TableRowRef<'_, T>> {
106-
if index >= self.element.len() {
107-
return None;
108-
}
109-
110-
Some(TableRowRef {
111-
element: &self.element[index],
112-
transform: &self.transform[index],
113-
alpha_blending: &self.alpha_blending[index],
114-
source_node_id: &self.source_node_id[index],
115-
})
116-
}
128+
impl<T> IntoIterator for Table<T> {
129+
type Item = TableRow<T>;
130+
type IntoIter = TableRowIter<T>;
117131

118-
pub fn get_mut(&mut self, index: usize) -> Option<TableRowMut<'_, T>> {
119-
if index >= self.element.len() {
120-
return None;
132+
/// Consumes a [`Table`] and returns an iterator of [`TableRow`]s, each containing the owned data of the respective row from the original table.
133+
fn into_iter(self) -> Self::IntoIter {
134+
TableRowIter {
135+
element: self.element.into_iter(),
136+
transform: self.transform.into_iter(),
137+
alpha_blending: self.alpha_blending.into_iter(),
138+
source_node_id: self.source_node_id.into_iter(),
121139
}
122-
123-
Some(TableRowMut {
124-
element: &mut self.element[index],
125-
transform: &mut self.transform[index],
126-
alpha_blending: &mut self.alpha_blending[index],
127-
source_node_id: &mut self.source_node_id[index],
128-
})
129140
}
141+
}
130142

131-
pub fn len(&self) -> usize {
132-
self.element.len()
133-
}
143+
pub struct TableRowIter<T> {
144+
element: std::vec::IntoIter<T>,
145+
transform: std::vec::IntoIter<DAffine2>,
146+
alpha_blending: std::vec::IntoIter<AlphaBlending>,
147+
source_node_id: std::vec::IntoIter<Option<NodeId>>,
148+
}
149+
impl<T> Iterator for TableRowIter<T> {
150+
type Item = TableRow<T>;
134151

135-
pub fn is_empty(&self) -> bool {
136-
self.element.is_empty()
152+
fn next(&mut self) -> Option<Self::Item> {
153+
let element = self.element.next()?;
154+
let transform = self.transform.next()?;
155+
let alpha_blending = self.alpha_blending.next()?;
156+
let source_node_id = self.source_node_id.next()?;
157+
158+
Some(TableRow {
159+
element,
160+
transform,
161+
alpha_blending,
162+
source_node_id,
163+
})
137164
}
138165
}
139166

node-graph/gcore/src/transform_nodes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ async fn extract_transform<T>(
6363
)]
6464
vector: Table<T>,
6565
) -> DAffine2 {
66-
vector.iter_ref().next().map(|row| *row.transform).unwrap_or_default()
66+
vector.iter().next().map(|row| *row.transform).unwrap_or_default()
6767
}
6868

6969
#[node_macro::node(category("Math: Transform"))]

0 commit comments

Comments
 (0)