There's probably a more elegant way to do this. I have a queue (crossbeam_channel) of these things:
/// Queue item sent to the the render land queue.
pub enum RenderHeightQueueItem {
/// Update to this region's land height map.
ApplyPatch(RenderHeightMap),
/// Region with this region box wants to be told about edges.
RequestEdge(RegionBox)
}
When processing the queue, I need to process all of one type in the enum before processing the other type. So I need to split the vector into two vectors, based on enum type. Here's the obvious solution, with a for loop and push calls. Is there a cleaner way to do a split like this?
let requests: Vec<RenderHeightQueueItem> = land_queue_receiver.try_iter().collect();
// Separate patch requests from edge requests.
let mut patches = Vec::new();
let mut edge_requests = Vec::new();
for request in requests {
match request {
RenderHeightQueueItem::ApplyPatch(patch) => patches.push(patch),
RenderHeightQueueItem::RequestEdge(region_box) => edge_requests.push(region_box),
}
}
// Handle patches first.
if !patches.is_empty() {
self.combine_height_maps(&height_mesh, patches, scene_link, land_object_link);
}
// Then edge requests.
for region_box in edge_requests {
self.handle_edge_request(region_box);
}
Use case: this is part of a metaverse client. The server is sending land patches, providing elevation data for a small area. Those have to be assembled into a height map, from which a mesh is generated and drawn. There are multiple big land squares with edges in common, and when a new square goes live, it needs edge info for adjacent squares.