Add latest and earliest methods to events and begin camera system port

This commit is contained in:
Carter Anderson 2020-04-16 11:16:22 -07:00
parent dcd71d1b72
commit 2eda84a0b8
5 changed files with 100 additions and 16 deletions

View File

@ -112,7 +112,8 @@ where
self.event_count += 1;
}
/// Iterates over the events the `event_reader` has not seen yet.
/// Iterates over the events the `event_reader` has not seen yet. This updates the `event_reader`'s event counter,
/// which means subsequent event reads will not include events that happened before now.
pub fn iter(&self, event_reader: &mut EventReader<T>) -> impl DoubleEndedIterator<Item = &T> {
// if the reader has seen some of the events in a buffer, find the proper index offset.
// otherwise read all events in the buffer
@ -157,6 +158,30 @@ where
}
}
/// Retrieves the latest event. This updates the `event_reader`'s event counter,
/// which means subsequent event reads will not include events that happened before now.
pub fn latest(&self, event_reader: &mut EventReader<T>) -> Option<&T> {
self.iter(event_reader)
.rev()
.next()
}
/// Retrieves the latest event that matches the given `predicate`. This updates the `event_reader`'s event counter,
/// which means subsequent event reads will not include events that happened before now.
pub fn find_latest(&self, event_reader: &mut EventReader<T>, predicate: impl FnMut(&&T) -> bool) -> Option<&T> {
self.iter(event_reader)
.rev()
.filter(predicate)
.next()
}
/// Retrieves the earliest event. This updates the `event_reader`'s event counter,
/// which means subsequent event reads will not include events that happened before now.
pub fn earliest(&self, event_reader: &mut EventReader<T>) -> Option<&T> {
self.iter(event_reader)
.next()
}
/// Gets a new [EventReader]. This will include all events already in the event buffers.
pub fn get_reader(&self) -> EventReader<T> {
EventReader {

View File

@ -126,12 +126,8 @@ pub fn camera_update_system(resources: &mut Resources) -> Box<dyn Schedulable> {
.read_resource::<Events<WindowResized>>()
.with_query(<Write<Camera>>::query())
.build(move |_, world, window_resized_events, query| {
// TODO: refactor this to "window_resized_events.latest()"
let primary_window_resized_event = window_resized_events
.iter(&mut window_resized_event_reader)
.rev()
.filter(|event| event.is_primary)
.next();
.find_latest(&mut window_resized_event_reader, |event| event.is_primary);
if let Some(primary_window_resized_event) = primary_window_resized_event {
for mut camera in query.iter_mut(world) {
camera.update(

View File

@ -56,10 +56,7 @@ impl ResourceProvider for Camera2dResourceProvider {
) {
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
let primary_window_resized_event = window_resized_events
.iter(&mut self.window_resized_event_reader)
.rev()
.filter(|event| event.is_primary)
.next();
.find_latest(&mut self.window_resized_event_reader, |event| event.is_primary);
if let Some(_) = primary_window_resized_event {
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();

View File

@ -5,15 +5,81 @@ use crate::{
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
ResourceProvider,
},
renderer_2::RenderContext,
renderer_2::{GlobalRenderResourceContext, RenderContext},
ActiveCamera, Camera,
};
use bevy_app::{EventReader, Events};
use bevy_app::{EventReader, Events, GetEventReader};
use bevy_transform::prelude::*;
use legion::prelude::*;
use zerocopy::AsBytes;
pub fn camera_resource_provider_system(resources: &mut Resources) -> Box<dyn Schedulable> {
let mut camera_buffer = None;
let mut tmp_buffer = None;
let mut window_resized_event_reader = resources.get_event_reader::<WindowResized>();
SystemBuilder::new("mesh_resource_provider")
.read_resource::<GlobalRenderResourceContext>()
// TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same
.write_resource::<RenderResourceAssignments>()
.read_resource::<Events<WindowResized>>()
.with_query(<(Read<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query())
.build(
move |_,
world,
(
render_resource_context,
ref mut render_resource_assignments,
window_resized_events,
),
query| {
let render_resources = &render_resource_context.context;
if camera_buffer.is_none() {
let buffer = render_resources.create_buffer(BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>(),
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
render_resource_assignments.set(resource_name::uniform::CAMERA, buffer);
camera_buffer = Some(buffer);
}
let primary_window_resized_event = window_resized_events
.find_latest(&mut window_resized_event_reader, |event| event.is_primary);
if let Some(_) = primary_window_resized_event {
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
for (camera, local_to_world, _) in query.iter(world) {
let camera_matrix: [[f32; 4]; 4] =
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
if let Some(old_tmp_buffer) = tmp_buffer {
render_resources.remove_buffer(old_tmp_buffer);
}
tmp_buffer = Some(render_resources.create_buffer_mapped(
BufferInfo {
size: matrix_size,
buffer_usage: BufferUsage::COPY_SRC,
..Default::default()
},
&mut |data, _renderer| {
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
},
));
// render_resources.copy_buffer_to_buffer(
// tmp_buffer.unwrap(),
// 0,
// camera_buffer.unwrap(),
// 0,
// matrix_size as u64,
// );
}
}
},
)
}
pub struct CameraResourceProvider {
pub camera_buffer: Option<RenderResource>,
pub tmp_buffer: Option<RenderResource>,
@ -57,10 +123,9 @@ impl ResourceProvider for CameraResourceProvider {
) {
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
let primary_window_resized_event = window_resized_events
.iter(&mut self.window_resized_event_reader)
.rev()
.filter(|event| event.is_primary)
.next();
.find_latest(&mut self.window_resized_event_reader, |event| {
event.is_primary
});
if let Some(_) = primary_window_resized_event {
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
for (camera, local_to_world, _) in

View File

@ -35,6 +35,7 @@ pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box<dyn Sched
)
} else {
let mesh_asset = meshes.get(&handle).unwrap();
// TODO: use a staging buffer here
let vertex_buffer = render_resources.create_buffer_with_data(
BufferInfo {
buffer_usage: BufferUsage::VERTEX,