diff options
author | tomaka <pierre.krieger1708@gmail.com> | 2014-08-02 09:49:54 +0200 |
---|---|---|
committer | tomaka <pierre.krieger1708@gmail.com> | 2014-08-02 09:49:54 +0200 |
commit | af756b9add1afb3c752ee2dec9e2d11fcbf5b2e0 (patch) | |
tree | c087244f783b60dff1baf46d7f7cc6f6d206fc50 | |
parent | 959613870c23e2ca26bee268c46f8062095c2382 (diff) | |
parent | 5dda16702164d59a75d8c36373cf29a8d7f4d58f (diff) | |
download | glutin-af756b9add1afb3c752ee2dec9e2d11fcbf5b2e0.tar.gz glutin-af756b9add1afb3c752ee2dec9e2d11fcbf5b2e0.zip |
Merge pull request #8 from tomaka/breaking-api-changes
Add WindowBuilder and iterators for events
-rw-r--r-- | examples/fullscreen.rs | 11 | ||||
-rw-r--r-- | examples/window.rs | 6 | ||||
-rw-r--r-- | src/hints.rs | 74 | ||||
-rw-r--r-- | src/lib.rs | 147 | ||||
-rw-r--r-- | src/win32/init.rs | 4 | ||||
-rw-r--r-- | src/win32/mod.rs | 6 | ||||
-rw-r--r-- | src/x11/mod.rs | 4 |
7 files changed, 104 insertions, 148 deletions
diff --git a/examples/fullscreen.rs b/examples/fullscreen.rs index b6141a0..80e6089 100644 --- a/examples/fullscreen.rs +++ b/examples/fullscreen.rs @@ -5,8 +5,6 @@ extern crate gl; use std::io::stdio::stdin; fn main() { - use std::default::Default; - // enumerating monitors let monitor = { for (num, monitor) in init::get_available_monitors().enumerate() { @@ -23,8 +21,11 @@ fn main() { monitor }; - let window = init::Window::new(None, "Hello world!", &Default::default(), - Some(monitor)).unwrap(); + let window = init::WindowBuilder::new() + .with_title("Hello world!".to_string()) + .with_monitor(monitor) + .build() + .unwrap(); unsafe { window.make_current() }; @@ -40,7 +41,7 @@ fn main() { gl::ClearColor(0.0, 1.0, 0.0, 1.0); while !window.is_closed() { - println!("{}", window.wait_events()); + println!("{}", window.wait_events().collect::<Vec<init::Event>>()); gl::Clear(gl::COLOR_BUFFER_BIT); diff --git a/examples/window.rs b/examples/window.rs index daa856b..c366ee0 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -3,9 +3,7 @@ extern crate libc; extern crate gl; fn main() { - use std::default::Default; - - let window = init::Window::new(None, "Hello world!", &Default::default(), None).unwrap(); + let window = init::Window::new().unwrap(); unsafe { window.make_current() }; @@ -21,7 +19,7 @@ fn main() { gl::ClearColor(0.0, 1.0, 0.0, 1.0); while !window.is_closed() { - println!("{}", window.wait_events()); + println!("{}", window.wait_events().collect::<Vec<init::Event>>()); gl::Clear(gl::COLOR_BUFFER_BIT); diff --git a/src/hints.rs b/src/hints.rs deleted file mode 100644 index aaa9a80..0000000 --- a/src/hints.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::default::Default; - -#[deriving(Clone,Show)] -#[deprecated = "Will be removed soon (it's not supported anyway)"] -pub struct Hints { - pub resizable: bool, - pub visible: bool, - pub decorated: bool, - pub red_bits: u8, - pub green_bits: u8, - pub blue_bits: u8, - pub alpha_bits: u8, - pub depth_bits: u8, - pub stencil_bits: u8, - pub accum_red_bits: u8, - pub accum_green_bits: u8, - pub accum_blue_bits: u8, - pub accum_alpha_bits: u8, - pub aux_buffers: u8, - pub samples: u8, - pub refresh_rate: u8, - pub stereo: bool, - pub srgb_capable: bool, - pub client_api: ClientAPI, - pub context_version: (u8, u8), - //pub robustness: , - pub opengl_forward_compat: bool, - pub opengl_debug_context: bool, - pub opengl_profile: Profile, -} - -#[deriving(Clone, Show)] -pub enum ClientAPI { - OpenGL, - OpenGLES, -} - -#[deriving(Clone, Show)] -pub enum Profile { - AnyProfile, - CompatProfile, - CoreProfile, -} - -impl Default for Hints { - fn default() -> Hints { - Hints { - resizable: true, - visible: true, - decorated: true, - red_bits: 8, - green_bits: 8, - blue_bits: 8, - alpha_bits: 8, - depth_bits: 24, - stencil_bits: 8, - accum_red_bits: 0, - accum_green_bits: 0, - accum_blue_bits: 0, - accum_alpha_bits: 0, - aux_buffers: 0, - samples: 0, - refresh_rate: 0, - stereo: false, - srgb_capable: false, - client_api: OpenGL, - context_version: (1, 0), - //robustness: , - opengl_forward_compat: false, - opengl_debug_context: false, - opengl_profile: AnyProfile, - } - } -} @@ -5,7 +5,6 @@ extern crate libc; pub use events::*; -pub use hints::{Hints, ClientAPI, Profile}; #[cfg(windows)] use winimpl = win32; @@ -21,19 +20,63 @@ mod x11; //mod egl; mod events; -mod hints; /// Identifier for a monitor. pub struct MonitorID(winimpl::MonitorID); +/// Object that allows you to build windows. +pub struct WindowBuilder { + dimensions: (uint, uint), + title: String, + monitor: Option<winimpl::MonitorID>, +} + +impl WindowBuilder { + /// Initializes a new `WindowBuilder` with default values. + pub fn new() -> WindowBuilder { + WindowBuilder { + dimensions: (1024, 768), + title: String::new(), + monitor: None, + } + } + + pub fn with_dimensions(mut self, width: uint, height: uint) -> WindowBuilder { + self.dimensions = (width, height); + self + } + + pub fn with_title(mut self, title: String) -> WindowBuilder { + self.title = title; + self + } + + pub fn with_monitor(mut self, monitor: MonitorID) -> WindowBuilder { + let MonitorID(monitor) = monitor; + self.monitor = Some(monitor); + self + } + + /// Builds the window. + /// + /// Error should be very rare and only occur in case of permission denied, incompatible system, + /// out of memory, etc. + pub fn build(self) -> Result<Window, String> { + let win = try!(winimpl::Window::new(Some(self.dimensions), + self.title.as_slice(), self.monitor)); + + Ok(Window{ + window: win, + }) + } +} + /// Represents an OpenGL context and the Window or environment around it. /// /// # Example /// /// ``` -/// use std::default::Default; -/// -/// let window = Window::new(None, "Hello world!", &Default::default(), None).unwrap(); +/// let window = Window::new().unwrap(); /// /// unsafe { window.make_current() }; /// @@ -57,43 +100,15 @@ pub struct Window { impl Window { /// Creates a new OpenGL context, and a Window for platforms where this is appropriate. - /// - /// # Parameters - /// - /// The `dimensions` parameter tell the library what the dimensions of the client area - /// of the window must be. If set to `None`, the library will choose or let the O/S choose. - /// - /// The `title` parameter is the title that the window must have. - /// - /// The `hints` parameter must be a `Hint` object which contains hints about how the context - /// must be created. This library will *try* to follow the hints, but will still success - /// even if it could not conform to all of them. - /// - /// The `monitor` parameter is the identifier of the monitor that this window should fill. - /// If `None`, a windowed window will be created. If `Some(_)`, the window will be fullscreen - /// and will fill the given monitor. Note `MonitorID` does not necessarly represent a - /// *physical* monitor. - /// - /// # Return value - /// - /// Returns the `Window` object. /// + /// This function is equivalent to `WindowBuilder::new().build()`. + /// /// Error should be very rare and only occur in case of permission denied, incompatible system, /// out of memory, etc. #[inline] - pub fn new(dimensions: Option<(uint, uint)>, title: &str, - hints: &Hints, monitor: Option<MonitorID>) - -> Result<Window, String> - { - // extracting the monitor ID - let monitor = monitor.map(|id| { let MonitorID(id) = id; id }); - - // creating the window - let win = try!(winimpl::Window::new(dimensions, title, hints, monitor)); - - Ok(Window{ - window: win, - }) + pub fn new() -> Result<Window, String> { + let builder = WindowBuilder::new(); + builder.build() } /// Returns true if the window has previously been closed by the user. @@ -176,32 +191,22 @@ impl Window { self.window.set_inner_size(x, y) } - /// Returns all the events that are currently in window's events queue. + /// Returns an iterator to all the events that are currently in the window's events queue. /// /// Contrary to `wait_events`, this function never blocks. - #[experimental = "Will probably be changed to return an iterator instead of a Vec"] #[inline] - pub fn poll_events(&self) -> Vec<Event> { - self.window.poll_events() + pub fn poll_events(&self) -> PollEventsIterator { + PollEventsIterator { data: self.window.poll_events() } } - /// Returns all the events that are currently in window's events queue. - /// If there are no events in queue, this function will block until there is one. - /// - /// This is equivalent to: - /// - /// ``` - /// loop { - /// let events = poll_events(); - /// if events.len() >= 1 { return events } - /// } - /// ``` - /// - /// ...but without the spinlock. + /// Waits for an event, then returns an iterator to all the events that are currently + /// in the window's events queue. + /// + /// If there are no events in queue when you call the function, + /// this function will block until there is one. #[inline] - #[experimental = "Will probably be changed to return an iterator instead of a Vec"] - pub fn wait_events(&self) -> Vec<Event> { - self.window.wait_events() + pub fn wait_events(&self) -> WaitEventsIterator { + WaitEventsIterator { data: self.window.wait_events() } } /// Sets the context as the current context. @@ -229,6 +234,32 @@ impl Window { } } +/// An iterator for the `poll_events` function. +// Implementation note: we retreive the list once, then serve each element by one by one. +// This may change in the future. +pub struct PollEventsIterator<'a> { + data: Vec<Event>, +} + +impl<'a> Iterator<Event> for PollEventsIterator<'a> { + fn next(&mut self) -> Option<Event> { + self.data.remove(0) + } +} + +/// An iterator for the `wait_events` function. +// Implementation note: we retreive the list once, then serve each element by one by one. +// This may change in the future. +pub struct WaitEventsIterator<'a> { + data: Vec<Event>, +} + +impl<'a> Iterator<Event> for WaitEventsIterator<'a> { + fn next(&mut self) -> Option<Event> { + self.data.remove(0) + } +} + /// An iterator for the list of available monitors. // Implementation note: we retreive the list once, then serve each element by one by one. // This may change in the future. diff --git a/src/win32/init.rs b/src/win32/init.rs index db08a42..ce558dc 100644 --- a/src/win32/init.rs +++ b/src/win32/init.rs @@ -6,7 +6,7 @@ use std::sync::atomics::AtomicBool; use std::ptr; use super::{event, ffi}; use super::{MonitorID, Window}; -use {Event, Hints}; +use Event; /// Stores the current window and its events dispatcher. /// @@ -15,7 +15,7 @@ use {Event, Hints}; local_data_key!(WINDOW: (ffi::HWND, Sender<Event>)) pub fn new_window(dimensions: Option<(uint, uint)>, title: &str, - _hints: &Hints, monitor: Option<MonitorID>) + monitor: Option<MonitorID>) -> Result<Window, String> { use std::mem; diff --git a/src/win32/mod.rs b/src/win32/mod.rs index 7558245..0d44a75 100644 --- a/src/win32/mod.rs +++ b/src/win32/mod.rs @@ -1,6 +1,6 @@ use std::sync::atomics::AtomicBool; use std::ptr; -use {Event, Hints}; +use Event; pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor}; @@ -36,10 +36,10 @@ pub struct Window { impl Window { /// See the docs if the crate root file. pub fn new(dimensions: Option<(uint, uint)>, title: &str, - hints: &Hints, monitor: Option<MonitorID>) + monitor: Option<MonitorID>) -> Result<Window, String> { - init::new_window(dimensions, title, hints, monitor) + init::new_window(dimensions, title, monitor) } /// See the docs if the crate root file. diff --git a/src/x11/mod.rs b/src/x11/mod.rs index 76339f5..bc89aed 100644 --- a/src/x11/mod.rs +++ b/src/x11/mod.rs @@ -1,4 +1,4 @@ -use {Event, Hints}; +use Event; use libc; use std::{mem, ptr}; use std::sync::atomics::AtomicBool; @@ -33,7 +33,7 @@ impl MonitorID { } impl Window { - pub fn new(dimensions: Option<(uint, uint)>, title: &str, hints: &Hints, _: Option<MonitorID>) + pub fn new(dimensions: Option<(uint, uint)>, title: &str, _: Option<MonitorID>) -> Result<Window, String> { // calling XOpenDisplay |