better batch iteration (no allocations + abstracted out)

This commit is contained in:
Carter Anderson 2020-03-22 01:06:38 -07:00
parent c9aec26f88
commit cfc7aae413
2 changed files with 54 additions and 63 deletions

View file

@ -265,49 +265,45 @@ impl AssetBatchers {
.flatten()
}
pub fn get_batcher_indices<T>(&self) -> impl Iterator<Item = &usize>
pub fn get_handle_batches<T>(&self) -> Option<impl Iterator<Item = &Batch>>
where
T: 'static,
{
let handle_type = TypeId::of::<T>();
self.handle_batchers.get(&handle_type).unwrap().iter()
if let Some(batcher_indices) = self.handle_batchers.get(&handle_type) {
Some(
// NOTE: it would be great to use batcher_indices.iter().map(|i| self.asset_batchers[*i].get_batches()) here
// but unfortunately the lifetimes don't work out for some reason
self.asset_batchers
.iter()
.enumerate()
.filter(move |(index, _a)| batcher_indices.contains(index))
.map(|(_index, a)| a.get_batches())
.flatten(),
)
} else {
None
}
}
pub fn get_batches_from_batcher(&self, index: usize) -> impl Iterator<Item = &Batch> {
self.asset_batchers[index].get_batches()
pub fn get_handle_batches_mut<T>(&mut self) -> Option<impl Iterator<Item = &mut Batch>>
where
T: 'static,
{
let handle_type = TypeId::of::<T>();
if let Some(batcher_indices) = self.handle_batchers.get(&handle_type) {
Some(
self.asset_batchers
.iter_mut()
.enumerate()
.filter(move |(index, _a)| batcher_indices.contains(index))
.map(|(_index, a)| a.get_batches_mut())
.flatten(),
)
} else {
None
}
}
pub fn get_batches_from_batcher_mut(
&mut self,
index: usize,
) -> impl Iterator<Item = &mut Batch> {
self.asset_batchers[index].get_batches_mut()
}
// pub fn get_handle_batches<T>(&self) -> Option<impl Iterator<Item = &Batch>>
// where
// T: 'static,
// {
// let handle_type = TypeId::of::<T>();
// if let Some(batcher_indices) = self.handle_batchers.get(&handle_type) {
// Some(
// self.asset_batchers
// .iter()
// .enumerate()
// .filter(|(index, a)| {
// let handle_type = TypeId::of::<T>();
// self.handle_batchers
// .get(&handle_type)
// .unwrap()
// .contains(index)
// })
// .map(|(index, a)| a.get_batches())
// .flatten(),
// )
// } else {
// None
// }
// }
}
#[cfg(test)]

View file

@ -546,39 +546,34 @@ where
_world: &mut World,
resources: &Resources,
) {
// update batch resources. this needs to run in "finish_update" because batches aren't finalized across
// all members of the batch until "UniformResourceProvider.update" has run for all members of the batch
if let Some(asset_storage) = resources.get::<AssetStorage<T>>() {
let handle_type = std::any::TypeId::of::<T>();
let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap();
let mut render_resource_assignments_provider = resources
.get_mut::<RenderResourceAssignmentsProvider>()
.unwrap();
// TODO: work out lifetime issues here so allocation isn't necessary
for index in asset_batchers
.get_batcher_indices::<T>()
.map(|i| *i)
.collect::<Vec<usize>>()
{
for batch in asset_batchers.get_batches_from_batcher_mut(index) {
let handle: Handle<T> = batch
.handles
.iter()
.find(|h| h.type_id == handle_type)
.map(|h| (*h).into())
.unwrap();
let handle_type = std::any::TypeId::of::<T>();
for batch in asset_batchers.get_handle_batches_mut::<T>().unwrap() {
let handle: Handle<T> = batch
.handles
.iter()
.find(|h| h.type_id == handle_type)
.map(|h| (*h).into())
.unwrap();
let render_resource_assignments = batch
.render_resource_assignments
.get_or_insert_with(|| render_resource_assignments_provider.next());
if let Some(uniforms) = asset_storage.get(&handle) {
self.setup_uniform_resources(
uniforms,
renderer,
resources,
render_resource_assignments,
false,
Some(handle),
);
}
let render_resource_assignments = batch
.render_resource_assignments
.get_or_insert_with(|| render_resource_assignments_provider.next());
if let Some(uniforms) = asset_storage.get(&handle) {
self.setup_uniform_resources(
uniforms,
renderer,
resources,
render_resource_assignments,
false,
Some(handle),
);
}
}
}