Change events.iter(&mut reader) to reader.iter(&events)

This commit is contained in:
Carter Anderson 2020-04-28 10:59:42 -07:00
parent 92182060a9
commit 9a3700d8f1
14 changed files with 102 additions and 95 deletions

View file

@ -35,12 +35,12 @@ enum State {
/// events.send(MyEvent { value: 1 });
///
/// // somewhere else: read the events
/// for event in events.iter(&mut reader) {
/// for event in reader.iter(&events) {
/// assert_eq!(event.value, 1)
/// }
///
/// // events are only processed once per reader
/// assert_eq!(events.iter(&mut reader).count(), 0);
/// assert_eq!(reader.iter(&events).count(), 0);
/// ```
///
/// # Details
@ -93,6 +93,81 @@ pub struct EventReader<T> {
_marker: PhantomData<T>,
}
impl<T> EventReader<T>
where
T: Send + Sync + 'static,
{
/// Iterates over the events this EventReader has not seen yet. This updates the EventReader's
/// event counter, which means subsequent event reads will not include events that happened before now.
pub fn iter<'a>(&mut self, events: &'a Events<T>) -> impl DoubleEndedIterator<Item = &'a 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
let a_index = if self.last_event_count > events.a_start_event_count {
self.last_event_count - events.a_start_event_count
} else {
0
};
let b_index = if self.last_event_count > events.b_start_event_count {
self.last_event_count - events.b_start_event_count
} else {
0
};
self.last_event_count = events.event_count;
match events.state {
State::A => events
.events_b
.get(b_index..)
.unwrap_or_else(|| &[])
.iter()
.map(map_event_instance)
.chain(
events
.events_a
.get(a_index..)
.unwrap_or_else(|| &[])
.iter()
.map(map_event_instance),
),
State::B => events
.events_a
.get(a_index..)
.unwrap_or_else(|| &[])
.iter()
.map(map_event_instance)
.chain(
events
.events_b
.get(b_index..)
.unwrap_or_else(|| &[])
.iter()
.map(map_event_instance),
),
}
}
/// Retrieves the latest event that this EventReader hasn't seen yet. This updates the EventReader's
/// event counter, which means subsequent event reads will not include events that happened before now.
pub fn latest<'a>(&mut self, events: &'a Events<T>) -> Option<&'a T> {
self.iter(events).rev().next()
}
/// Retrieves the latest event that matches the given `predicate` that this reader hasn't seen yet. This updates the EventReader's
/// event counter, which means subsequent event reads will not include events that happened before now.
pub fn find_latest<'a>(
&mut self,
events: &'a Events<T>,
predicate: impl FnMut(&&T) -> bool,
) -> Option<&'a T> {
self.iter(events).rev().filter(predicate).next()
}
/// Retrieves the earliest event in `events` that this reader hasn't seen yet. This updates the EventReader's
/// event counter, which means subsequent event reads will not include events that happened before now.
pub fn earliest<'a>(&mut self, events: &'a Events<T>) -> Option<&'a T> {
self.iter(events).next()
}
}
impl<T> Events<T>
where
T: Send + Sync + 'static,
@ -112,74 +187,6 @@ where
self.event_count += 1;
}
/// 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
let a_index = if event_reader.last_event_count > self.a_start_event_count {
event_reader.last_event_count - self.a_start_event_count
} else {
0
};
let b_index = if event_reader.last_event_count > self.b_start_event_count {
event_reader.last_event_count - self.b_start_event_count
} else {
0
};
event_reader.last_event_count = self.event_count;
match self.state {
State::A => self
.events_b
.get(b_index..)
.unwrap_or_else(|| &[])
.iter()
.map(map_event_instance)
.chain(
self.events_a
.get(a_index..)
.unwrap_or_else(|| &[])
.iter()
.map(map_event_instance),
),
State::B => self
.events_a
.get(a_index..)
.unwrap_or_else(|| &[])
.iter()
.map(map_event_instance)
.chain(
self.events_b
.get(b_index..)
.unwrap_or_else(|| &[])
.iter()
.map(map_event_instance),
),
}
}
/// 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 {
@ -342,6 +349,6 @@ mod tests {
events: &Events<TestEvent>,
reader: &mut EventReader<TestEvent>,
) -> Vec<TestEvent> {
events.iter(reader).cloned().collect::<Vec<TestEvent>>()
reader.iter(events).cloned().collect::<Vec<TestEvent>>()
}
}

View file

@ -32,7 +32,7 @@ impl AppPlugin for ScheduleRunnerPlugin {
}
RunMode::Loop { wait } => loop {
if let Some(app_exit_events) = app.resources.get_mut::<Events<AppExit>>() {
if app_exit_events.latest(&mut app_exit_event_reader).is_some() {
if app_exit_event_reader.latest(&app_exit_events).is_some() {
break;
}
}

View file

@ -9,7 +9,7 @@ pub fn exit_on_esc_system(resources: &mut Resources) -> Box<dyn Schedulable> {
.write_resource::<Events<AppExit>>()
.build(
move |_, _, (ref keyboard_input_events, ref mut app_exit_events), _| {
for event in keyboard_input_events.iter(&mut keyboard_input_event_reader) {
for event in keyboard_input_event_reader.iter(keyboard_input_events) {
if let Some(virtual_key_code) = event.virtual_key_code {
if event.state == ElementState::Pressed
&& virtual_key_code == VirtualKeyCode::Escape

View file

@ -126,8 +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| {
let primary_window_resized_event = window_resized_events
.find_latest(&mut window_resized_event_reader, |event| event.is_primary);
let primary_window_resized_event = window_resized_event_reader
.find_latest(&window_resized_events, |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

@ -62,8 +62,8 @@ impl SystemNode for Camera2dNode {
camera_buffer = Some(buffer);
}
let primary_window_resized_event = window_resized_events
.find_latest(&mut window_resized_event_reader, |event| event.is_primary);
let primary_window_resized_event = window_resized_event_reader
.find_latest(&window_resized_events, |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) {

View file

@ -61,8 +61,8 @@ impl SystemNode for CameraNode {
camera_buffer = Some(buffer);
}
let primary_window_resized_event = window_resized_events
.find_latest(&mut window_resized_event_reader, |event| event.is_primary);
let primary_window_resized_event = window_resized_event_reader
.find_latest(&window_resized_events, |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) {

View file

@ -61,11 +61,11 @@ impl Node for WindowSwapChainNode {
let render_resources = render_context.resources_mut();
// create window swapchain when window is resized or created
if window_created_events
.find_latest(&mut self.window_created_event_reader, |e| e.id == window.id)
if self.window_created_event_reader
.find_latest(&window_created_events, |e| e.id == window.id)
.is_some()
|| window_resized_events
.find_latest(&mut self.window_resized_event_reader, |e| e.id == window.id)
|| self.window_resized_event_reader
.find_latest(&window_resized_events, |e| e.id == window.id)
.is_some()
{
render_resources.create_swap_chain(window);

View file

@ -62,11 +62,11 @@ impl Node for WindowTextureNode {
.expect("Received window resized event for non-existent window"),
};
if window_created_events
.find_latest(&mut self.window_created_event_reader, |e| e.id == window.id)
if self.window_created_event_reader
.find_latest(&window_created_events, |e| e.id == window.id)
.is_some()
|| window_resized_events
.find_latest(&mut self.window_resized_event_reader, |e| e.id == window.id)
|| self.window_resized_event_reader
.find_latest(&window_resized_events, |e| e.id == window.id)
.is_some()
{
let render_resources = render_context.resources_mut();

View file

@ -60,7 +60,7 @@ impl WgpuRenderer {
let windows = resources.get::<Windows>().unwrap();
let window_created_events = resources.get::<Events<WindowCreated>>().unwrap();
for window_created_event in
window_created_events.iter(&mut self.window_created_event_reader)
self.window_created_event_reader.iter(&window_created_events)
{
let window = windows
.get(window_created_event.id)

View file

@ -14,7 +14,7 @@ pub fn exit_on_window_close_system(
.build(
move |_, _, (ref window_close_requested_events, ref mut app_exit_events), _| {
for window_close_requested_event in
window_close_requested_events.iter(&mut window_close_requested_event_reader)
window_close_requested_event_reader.iter(window_close_requested_events)
{
match window_id.as_ref() {
Some(window_id) => {

View file

@ -52,7 +52,7 @@ pub fn winit_runner(mut app: App) {
};
if let Some(app_exit_events) = app.resources.get_mut::<Events<AppExit>>() {
if app_exit_events.latest(&mut app_exit_event_reader).is_some() {
if app_exit_event_reader.latest(&app_exit_events).is_some() {
*control_flow = ControlFlow::Exit;
}
}
@ -141,7 +141,7 @@ fn handle_create_window_events(
let mut windows = resources.get_mut::<Windows>().unwrap();
let create_window_events = resources.get::<Events<CreateWindow>>().unwrap();
let mut window_created_events = resources.get_mut::<Events<WindowCreated>>().unwrap();
for create_window_event in create_window_events.iter(create_window_event_reader) {
for create_window_event in create_window_event_reader.iter(&create_window_events) {
let window = Window::new(&create_window_event.descriptor);
winit_windows.create_window(event_loop, &window);
let window_id = window.id;

View file

@ -54,7 +54,7 @@ impl From<&mut Resources> for EventListenerState {
fn event_listener_system(
(state, my_events): &mut (ResourceMut<EventListenerState>, Resource<Events<MyEvent>>),
) {
for my_event in my_events.iter(&mut state.my_event_reader) {
for my_event in state.my_event_reader.iter(&my_events) {
println!("{}", my_event.message);
}
}

View file

@ -22,7 +22,7 @@ pub fn move_on_input_system(resources: &mut Resources) -> Box<dyn Schedulable> {
.with_query(<(Write<Translation>, Read<Handle<Mesh>>)>::query())
.build(
move |_command_buffer, world, (time, keyboard_input_events), mesh_query| {
for event in keyboard_input_events.iter(&mut keyboard_input_event_reader) {
for event in keyboard_input_event_reader.iter(&keyboard_input_events) {
match event {
KeyboardInput {
virtual_key_code: Some(VirtualKeyCode::Left),

View file

@ -22,11 +22,11 @@ pub fn mouse_input_system(resources: &mut Resources) -> Box<dyn Schedulable> {
_world,
(mouse_button_input_events, mouse_motion_events),
_queries| {
for event in mouse_button_input_events.iter(&mut mouse_button_input_event_reader) {
for event in mouse_button_input_event_reader.iter(&mouse_button_input_events) {
println!("{:?}", event);
}
for event in mouse_motion_events.iter(&mut mouse_motion_event_reader) {
for event in mouse_motion_event_reader.iter(&mouse_motion_events) {
println!("{:?}", event);
}
},