Win32: use platform-specific iterators instead

This commit is contained in:
Tomaka17 2014-10-25 11:22:52 +02:00 committed by Pierre Krieger
parent 9884908240
commit 49e3fbdd71
2 changed files with 56 additions and 68 deletions

View file

@ -565,7 +565,7 @@ impl Window {
/// Contrary to `wait_events`, this function never blocks. /// Contrary to `wait_events`, this function never blocks.
#[inline] #[inline]
pub fn poll_events(&self) -> PollEventsIterator { pub fn poll_events(&self) -> PollEventsIterator {
PollEventsIterator { window: self, data: self.window.poll_events().into_iter() } PollEventsIterator(self.window.poll_events())
} }
/// Returns an iterator that returns events one by one, blocking if necessary until one is /// Returns an iterator that returns events one by one, blocking if necessary until one is
@ -574,7 +574,7 @@ impl Window {
/// The iterator never returns `None`. /// The iterator never returns `None`.
#[inline] #[inline]
pub fn wait_events(&self) -> WaitEventsIterator { pub fn wait_events(&self) -> WaitEventsIterator {
WaitEventsIterator { window: self, data: self.window.wait_events().into_iter() } WaitEventsIterator(self.window.wait_events())
} }
/// Sets the context as the current context. /// Sets the context as the current context.
@ -727,24 +727,13 @@ impl gl_common::GlFunctionsSource for HeadlessContext {
// Implementation note: we retreive the list once, then serve each element by one by one. // Implementation note: we retreive the list once, then serve each element by one by one.
// This may change in the future. // This may change in the future.
#[cfg(feature = "window")] #[cfg(feature = "window")]
pub struct PollEventsIterator<'a> { pub struct PollEventsIterator<'a>(winimpl::PollEventsIterator<'a>);
window: &'a Window,
data: RingBufIter<Event>,
}
#[cfg(feature = "window")] #[cfg(feature = "window")]
impl<'a> Iterator for PollEventsIterator<'a> { impl<'a> Iterator for PollEventsIterator<'a> {
type Item = Event; type Item = Event;
fn next(&mut self) -> Option<Event> { fn next(&mut self) -> Option<Event> {
if let Some(ev) = self.data.next() { self.0.next()
return Some(ev);
}
let PollEventsIterator { window, data } = self.window.poll_events();
self.window = window;
self.data = data;
self.data.next()
} }
} }
@ -752,24 +741,13 @@ impl<'a> Iterator for PollEventsIterator<'a> {
// Implementation note: we retreive the list once, then serve each element by one by one. // Implementation note: we retreive the list once, then serve each element by one by one.
// This may change in the future. // This may change in the future.
#[cfg(feature = "window")] #[cfg(feature = "window")]
pub struct WaitEventsIterator<'a> { pub struct WaitEventsIterator<'a>(winimpl::WaitEventsIterator<'a>);
window: &'a Window,
data: RingBufIter<Event>,
}
#[cfg(feature = "window")] #[cfg(feature = "window")]
impl<'a> Iterator for WaitEventsIterator<'a> { impl<'a> Iterator for WaitEventsIterator<'a> {
type Item = Event; type Item = Event;
fn next(&mut self) -> Option<Event> { fn next(&mut self) -> Option<Event> {
if let Some(ev) = self.data.next() { self.0.next()
return Some(ev);
}
let WaitEventsIterator { window, data } = self.window.wait_events();
self.window = window;
self.data = data;
self.next()
} }
} }

View file

@ -205,50 +205,16 @@ impl Window {
} }
/// See the docs in the crate root file. /// See the docs in the crate root file.
// TODO: return iterator pub fn poll_events(&self) -> PollEventsIterator {
pub fn poll_events(&self) -> RingBuf<Event> { PollEventsIterator {
let mut events = RingBuf::new(); window: self,
loop {
match self.events_receiver.try_recv() {
Ok(ev) => events.push_back(ev),
Err(_) => break
}
} }
// if one of the received events is `Closed`, setting `is_closed` to true
if events.iter().any(|e| match e { &::events::Event::Closed => true, _ => false }) {
use std::sync::atomic::Ordering::Relaxed;
self.is_closed.store(true, Relaxed);
}
events
} }
/// See the docs in the crate root file. /// See the docs in the crate root file.
// TODO: return iterator pub fn wait_events(&self) -> WaitEventsIterator {
pub fn wait_events(&self) -> RingBuf<Event> { WaitEventsIterator {
match self.events_receiver.recv() { window: self,
Ok(ev) => {
// if the received event is `Closed`, setting `is_closed` to true
match ev {
::events::Event::Closed => {
use std::sync::atomic::Ordering::Relaxed;
self.is_closed.store(true, Relaxed);
},
_ => ()
};
// looing for other possible events in the queue
let mut result = self.poll_events();
result.insert(0, ev);
result
},
Err(_) => {
use std::sync::atomic::Ordering::Relaxed;
self.is_closed.store(true, Relaxed);
RingBuf::new()
}
} }
} }
@ -298,6 +264,50 @@ impl Window {
} }
} }
pub struct PollEventsIterator<'a> {
window: &'a Window,
}
impl<'a> Iterator for PollEventsIterator<'a> {
type Item = Event;
fn next(&mut self) -> Option<Event> {
use events::Event::Closed;
match self.window.events_receiver.recv() {
Ok(Closed) => {
use std::sync::atomic::Ordering::Relaxed;
self.window.is_closed.store(true, Relaxed);
Some(Closed)
},
Ok(ev) => Some(ev),
Err(_) => None
}
}
}
pub struct WaitEventsIterator<'a> {
window: &'a Window,
}
impl<'a> Iterator for WaitEventsIterator<'a> {
type Item = Event;
fn next(&mut self) -> Option<Event> {
use events::Event::Closed;
match self.window.events_receiver.recv() {
Ok(Closed) => {
use std::sync::atomic::Ordering::Relaxed;
self.window.is_closed.store(true, Relaxed);
Some(Closed)
},
Ok(ev) => Some(ev),
Err(_) => None
}
}
}
#[unsafe_destructor] #[unsafe_destructor]
impl Drop for Window { impl Drop for Window {
fn drop(&mut self) { fn drop(&mut self) {