<commit_before>#![deny(missing_docs)]

//! A Glutin window back-end for the Piston game engine.

extern crate glutin;
extern crate gl;
extern crate input;
extern crate window;
extern crate shader_version;

// External crates.
use input::{
    keyboard,
    MouseButton,
    Button,
    Input,
};
use window::{
    BuildFromWindowSettings,
    OpenGLWindow,
    Window,
    AdvancedWindow,
    ProcAddress,
    WindowSettings,
    Size,
    Position,
};
use glutin::{ Api, GlRequest };

pub use shader_version::OpenGL;

/// Contains stuff for game window.
pub struct GlutinWindow {
    /// The window.
    pub window: glutin::Window,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
    should_close: bool,
    // Used to detect enter/leave cursor events.
    has_cursor: bool,
    // Used to fake capturing of cursor,
    // to get relative mouse events.
    is_capturing_cursor: bool,
    // Stores the last known cursor position.
    last_cursor_pos: Option<[i32; 2]>,
    // Stores relative coordinates to emit on next poll.
    mouse_relative: Option<(f64, f64)>,
    // Used to emit cursor event after enter/leave.
    cursor_pos: Option<[f64; 2]>,
}

fn builder_from_settings(settings: &WindowSettings) -> glutin::WindowBuilder {
    let opengl = settings.get_maybe_opengl().unwrap_or(OpenGL::V3_2);
    let (major, minor) = opengl.get_major_minor();
    let size = settings.get_size();
    let mut builder = glutin::WindowBuilder::new()
        .with_dimensions(size.width, size.height)
        .with_decorations(settings.get_decorated())
        .with_multitouch()
        .with_gl(GlRequest::Specific(Api::OpenGl, (major as u8, minor as u8)))
        .with_title(settings.get_title())
        .with_srgb(Some(settings.get_srgb()));
    let samples = settings.get_samples();
    if settings.get_fullscreen() {
        builder = builder.with_fullscreen(glutin::get_primary_monitor());
    }
    if settings.get_vsync() {
        builder = builder.with_vsync();
    }
    if samples != 0 {
        builder = builder.with_multisampling(samples as u16);
    }
    builder
}

impl GlutinWindow {

    /// Creates a new game window for Glutin.
    pub fn new(settings: &WindowSettings) -> Result<Self, String> {
        use std::error::Error;
        use glutin::ContextError;

        let title = settings.get_title();
        let exit_on_esc = settings.get_exit_on_esc();
        let window = builder_from_settings(&settings).build();
        let window = match window {
                Ok(window) => window,
                Err(_) => {
                    try!(builder_from_settings(&settings.clone().samples(0)).build()
                        .map_err(|e| String::from(e.description()))
                    )
                }
            };
        unsafe { try!(window.make_current().map_err(|e|
                // This can be simplified in next version of Glutin.
                match e {
                    ContextError::IoError(ref err) => {
                        String::from(err.description())
                    }
                    ContextError::ContextLost => {
                        String::from("Context lost")
                    }
                }
            )); }

        // Load the OpenGL function pointers.
        gl::load_with(|s| window.get_proc_address(s) as *const _);

        Ok(GlutinWindow {
            window: window,
            title: title,
            exit_on_esc: exit_on_esc,
            should_close: false,
            has_cursor: true,
            cursor_pos: None,
            is_capturing_cursor: false,
            last_cursor_pos: None,
            mouse_relative: None,
        })
    }

    fn poll_event(&mut self) -> Option<Input> {
        use glutin::Event as E;
        use glutin::MouseScrollDelta;
        use input::{ Key, Input, Motion };

        // Check for a pending mouse cursor move event.
        if let Some(pos) = self.cursor_pos {
            self.cursor_pos = None;
            return Some(Input::Move(Motion::MouseCursor(pos[0], pos[1])));
        }

        // Check for a pending relative mouse move event.
        if let Some((x, y)) = self.mouse_relative {
            self.mouse_relative = None;
            return Some(Input::Move(Motion::MouseRelative(x, y)));
        }

        let mut ev = self.window.poll_events().next();

        if self.is_capturing_cursor &&
           self.last_cursor_pos.is_none() {
            if let Some(E::MouseMoved(x, y)) = ev {
                // Ignore this event since mouse positions
                // should not be emitted when capturing cursor.
                self.last_cursor_pos = Some([x, y]);
                ev = self.window.poll_events().next();
            }
        }

        match ev {
            None => {
                if self.is_capturing_cursor {
                    self.fake_capture();<commit_msg>Add blocking wait_event method<commit_after>#![deny(missing_docs)]

//! A Glutin window back-end for the Piston game engine.

extern crate glutin;
extern crate gl;
extern crate input;
extern crate window;
extern crate shader_version;

// External crates.
use input::{
    keyboard,
    MouseButton,
    Button,
    Input,
};
use window::{
    BuildFromWindowSettings,
    OpenGLWindow,
    Window,
    AdvancedWindow,
    ProcAddress,
    WindowSettings,
    Size,
    Position,
};
use glutin::{ Api, GlRequest };

pub use shader_version::OpenGL;

/// Contains stuff for game window.
pub struct GlutinWindow {
    /// The window.
    pub window: glutin::Window,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
    should_close: bool,
    // Used to detect enter/leave cursor events.
    has_cursor: bool,
    // Used to fake capturing of cursor,
    // to get relative mouse events.
    is_capturing_cursor: bool,
    // Stores the last known cursor position.
    last_cursor_pos: Option<[i32; 2]>,
    // Stores relative coordinates to emit on next poll.
    mouse_relative: Option<(f64, f64)>,
    // Used to emit cursor event after enter/leave.
    cursor_pos: Option<[f64; 2]>,
}

fn builder_from_settings(settings: &WindowSettings) -> glutin::WindowBuilder {
    let opengl = settings.get_maybe_opengl().unwrap_or(OpenGL::V3_2);
    let (major, minor) = opengl.get_major_minor();
    let size = settings.get_size();
    let mut builder = glutin::WindowBuilder::new()
        .with_dimensions(size.width, size.height)
        .with_decorations(settings.get_decorated())
        .with_multitouch()
        .with_gl(GlRequest::Specific(Api::OpenGl, (major as u8, minor as u8)))
        .with_title(settings.get_title())
        .with_srgb(Some(settings.get_srgb()));
    let samples = settings.get_samples();
    if settings.get_fullscreen() {
        builder = builder.with_fullscreen(glutin::get_primary_monitor());
    }
    if settings.get_vsync() {
        builder = builder.with_vsync();
    }
    if samples != 0 {
        builder = builder.with_multisampling(samples as u16);
    }
    builder
}

impl GlutinWindow {

    /// Creates a new game window for Glutin.
    pub fn new(settings: &WindowSettings) -> Result<Self, String> {
        use std::error::Error;
        use glutin::ContextError;

        let title = settings.get_title();
        let exit_on_esc = settings.get_exit_on_esc();
        let window = builder_from_settings(&settings).build();
        let window = match window {
                Ok(window) => window,
                Err(_) => {
                    try!(builder_from_settings(&settings.clone().samples(0)).build()
                        .map_err(|e| String::from(e.description()))
                    )
                }
            };
        unsafe { try!(window.make_current().map_err(|e|
                // This can be simplified in next version of Glutin.
                match e {
                    ContextError::IoError(ref err) => {
                        String::from(err.description())
                    }
                    ContextError::ContextLost => {
                        String::from("Context lost")
                    }
                }
            )); }

        // Load the OpenGL function pointers.
        gl::load_with(|s| window.get_proc_address(s) as *const _);

        Ok(GlutinWindow {
            window: window,
            title: title,
            exit_on_esc: exit_on_esc,
            should_close: false,
            has_cursor: true,
            cursor_pos: None,
            is_capturing_cursor: false,
            last_cursor_pos: None,
            mouse_relative: None,
        })
    }

    /// Wait for an event to be received by the window.
    /// Blocks the current thread until one arrives.
    pub fn wait_event(&mut self) -> Option<Input> {
        // First check for and handle any pending events.
        if let Some(event) = self.poll_event() {
            Some(event)
        } else {
            let event = self.window.wait_events().next();
            self.handle_event(event)
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        use glutin::Event as E;
        use input::{ Input, Motion };
        // Check for a pending mouse cursor move event.
        if let Some(pos) = self.cursor_pos {
            self.cursor_pos = None;
            return Some(Input::Move(Motion::MouseCursor(pos[0], pos[1])));
        }

        // Check for a pending relative mouse move event.
        if let Some((x, y)) = self.mouse_relative {
            self.mouse_relative = None;
            return Some(Input::Move(Motion::MouseRelative(x, y)));
        }

        let mut ev = self.window.poll_events().next();

        if self.is_capturing_cursor &&
           self.last_cursor_pos.is_none() {
            if let Some(E::MouseMoved(x, y)) = ev {
                // Ignore this event since mouse positions
                // should not be emitted when capturing cursor.
                self.last_cursor_pos = Some([x, y]);
                ev = self.window.poll_events().next();
            }
        }
        self.handle_event(ev)
    }

    /// Convert an incoming Glutin event to Piston input.
    /// Update cursor state if necessary.
    fn handle_event(&mut self, ev: Option<glutin::Event>) -> Option<Input> {
        use glutin::Event as E;
        use glutin::MouseScrollDelta;
        use input::{ Key, Input, Motion };

        match ev {
            None => {
                if self.is_capturing_cursor {
                    self.fake_capture();
{'fraction_non_alphanumeric': 0.11132273116846014, 'fraction_numerical': 0.00380916103228264, 'mean_word_length': 2.0022870211549457, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6143472', 'n_tokens_mistral': 3111, 'n_tokens_neox': 2968, 'n_words': 766}