<commit_before>#![feature(libc)]
#![feature(collections)]
#![feature(std_misc)]
//! Simple [libtecla](http://www.astro.caltech.edu/~mcs/tecla/libtecla.html) wrapper.

extern crate libc;
use libc::{c_char, c_int, size_t};

use std::ffi::{CString, CStr};
use std::string::as_string;
use std::str::from_utf8_unchecked;
use std::ptr;

pub type CplMatchFn = fn(*mut WordCompletion, *mut c_char, *const c_char, c_int) -> c_int;

#[repr(C)]
pub struct GetLine;
#[repr(C)]
pub struct ExpandFile;
/*pub struct FileExpansion {
    exists: c_int,
    nfile: c_int,
    files: *mut char,
}*/
#[repr(C)]
pub struct WordCompletion;

// will add functions as needed
#[link(name = "tecla")]
extern {
    fn new_GetLine(linelen: size_t, histlen: size_t) -> *mut GetLine;
    fn del_GetLine(gl: *mut GetLine) -> *mut GetLine;
    fn gl_get_line(gl: *mut GetLine,
                   prompt: *const c_char,
                   start_line: *const c_char,
                   start_pos: c_int) -> *const c_char;
    fn gl_query_char(gl: *mut GetLine, prompt: *const c_char, defchar: c_char) -> c_int;
    fn new_ExpandFile() -> *mut ExpandFile;
    fn del_ExpandFile(ef: *mut ExpandFile) -> *mut ExpandFile;
    // fn ef_expand_file(ef: *mut ExpandFile,
    //                  path: *const c_char,
    //                  pathlen: c_int) -> *mut FileExpansion;
    // fn el_list_expansions(result: *mut FileExpansion,
    //                      fp: *mut FILE,
    //                      term_width: c_int) -> c_int;
    // fn ef_last_error(ef: *mut ExpandFile) -> *const c_char;
    fn new_WordCompletion() -> *mut WordCompletion;
    fn del_WordCompletion(cpl: *mut WordCompletion) -> WordCompletion;
    /*fn gl_completion_action(gl: *mut GetLine,
                            data: *const void,
                            match_fn: CplMatchFn,
                            list_only: c_int,
                            name: *const c_char,
                            keyseq: *const c_char) -> c_int;*/
    fn gl_customize_completion(gl: *mut GetLine,
                               data: *const c_char,
                               match_fn: &CplMatchFn) -> c_int;
    fn gl_save_history(gl: *mut GetLine,
                       filename: *const c_char,
                       comment: *const c_char,
                       max_lines: c_int);
    fn gl_load_history(gl: *mut GetLine,
                       filename: *const c_char,
                       comment: *const c_char);
    fn gl_ignore_signal(gl: *mut GetLine, signo: c_int);
    fn gl_erase_terminal(gl: *mut GetLine) -> c_int;
    fn cpl_file_completions(cpl: *mut WordCompletion,
                            data: *const c_char,
                            line: *const c_char,
                            word_end: c_int) -> c_int;
    fn cpl_add_completion(cpl: *mut WordCompletion,
                          line: *const c_char,
                          word_start: c_int,
                          word_end: c_int,
                          suffix: *const c_char,
                          type_suffix: *const c_char,
                          cont_suffix: *const c_char) -> c_int;
}

///Creates new GetLine object
pub fn new_gl(linelen: u64, histlen: u64) -> *mut GetLine {
    let mut res: *mut GetLine;
    unsafe {
        res = new_GetLine(linelen, histlen);
    }
    res
}

///Deletes GetLine object
pub fn del_gl(gl: *mut GetLine) -> *mut GetLine {
    unsafe {
        del_GetLine(gl)
    }
}

///Creates new WordCompletion object
pub fn new_wc() -> *mut WordCompletion {
    unsafe {
        new_WordCompletion()
    }
}

///Deletes WordCompletion object
pub fn del_wc(cpl: *mut WordCompletion) -> WordCompletion {
    unsafe {
        del_WordCompletion(cpl)
    }
}

///Creates new ExpandFile object
pub fn new_ef() -> *mut ExpandFile {
    unsafe {
        new_ExpandFile()
    }
}

///Deletes ExpandFile object
pub fn del_ef(ef: *mut ExpandFile) -> *mut ExpandFile {
    unsafe {
        del_ExpandFile(ef)
    }
}

///Gets line from user using GetLine object
pub fn get_line(gl: *mut GetLine, prompt: &str) -> String {
    let c_prompt = CString::new(prompt.as_bytes()).unwrap();
    let start: *const i8 = ptr::null();
    let mut res: &str;
    unsafe {
        let out = CStr::from_ptr(gl_get_line(gl, c_prompt.as_ptr(), start, -1));
        res = from_utf8_unchecked(out.to_bytes());
    }
    as_string(res).clone()
}

///Returns the character read, or 0 if unreadable
pub fn query_char(gl: *mut GetLine, prompt: &str, defchar: char) -> char {
    let c_prompt = CString::new(prompt.as_bytes()).unwrap();
    let mut res: u8;
    unsafe {
        let out = gl_query_char(gl, c_prompt.as_ptr(), defchar as c_char);
        if out > 0 {
            res = out as u8;
        } else {
            res = 0;
        }
    }
    res as char
}

///Saves history to a file
pub fn save_history(gl: *mut GetLine, file: &str, comment: &str, max: usize) {
    let c_file = CString::new(file.as_bytes()).unwrap();
    let c_comment = CString::new(comment.as_bytes()).unwrap();
    let c_max = max as c_int;
    unsafe {
        gl_save_history(gl, c_file.as_ptr(), c_comment.as_ptr(), c_max)
    }
}

///Loads history from a file
pub fn load_history(gl: *mut GetLine, file: &str, comment: &str) {
    let c_file = CString::new(file.as_bytes()).unwrap();
    let c_comment = CString::new(comment.as_bytes()).unwrap();
    unsafe {
        gl_load_history(gl, c_file.as_ptr(), c_comment.as_ptr())
    }
}

///Ignore specified signal
pub fn ignore(gl: *mut GetLine, sig: isize) {
    unsafe {
        gl_ignore_signal(gl, sig as c_int)
    }
}

///Clear screen
pub fn clear(gl: *mut GetLine) -> i32 {
    unsafe {
        gl_erase_terminal(gl)
    }
}

///Sets the completion function
pub fn custom_complete(gl: *mut GetLine, data: &mut str, func: CplMatchFn) -> i32 {
    let c_data = CString::new(data.as_bytes()).unwrap();
    unsafe {
        gl_customize_completion(gl, c_data.as_ptr(), &func)
    }
}

///Calls built-in libtecla file completion function
pub fn builtin_complete(cpl: *mut WordCompletion, data: &mut str, line: &str, word_end: i32) -> i32 {
    let c_line = CString::new(line.as_bytes()).unwrap();
    let c_data = CString::new(data.as_bytes()).unwrap();
    unsafe {
        cpl_file_completions(cpl, c_data.as_ptr(), c_line.as_ptr(), word_end)
    }
}

///Calls cpl_add_completion
pub fn add_completion(wc: *mut WordCompletion,
                      line: *const c_char,
                      word_start: c_int,
                      word_end: c_int,
                      suffix: *const c_char,
                      type_suffix: *const c_char,
                      cont_suffix: *const c_char) -> c_int {
    unsafe {
        cpl_add_completion(wc, line, word_start, word_end, suffix, type_suffix, cont_suffix)
    }
}
<commit_msg>modified to work with callback type<commit_after>#![feature(libc)]
#![feature(collections)]
#![feature(std_misc)]
//! Simple [libtecla](http://www.astro.caltech.edu/~mcs/tecla/libtecla.html) wrapper.

extern crate libc;
use libc::{c_char, c_int, size_t};

use std::ffi::{CString, CStr};
use std::string::as_string;
use std::str::from_utf8_unchecked;
use std::ptr;

pub type CplMatchFn = fn(*mut WordCompletion, *mut c_char, *const c_char, c_int) -> c_int;

#[repr(C)]
pub struct GetLine;
#[repr(C)]
pub struct ExpandFile;
/*pub struct FileExpansion {
    exists: c_int,
    nfile: c_int,
    files: *mut char,
}*/
#[repr(C)]
pub struct WordCompletion;

// will add functions as needed
#[link(name = "tecla")]
extern {
    fn new_GetLine(linelen: size_t, histlen: size_t) -> *mut GetLine;
    fn del_GetLine(gl: *mut GetLine) -> *mut GetLine;
    fn gl_get_line(gl: *mut GetLine,
                   prompt: *const c_char,
                   start_line: *const c_char,
                   start_pos: c_int) -> *const c_char;
    fn gl_query_char(gl: *mut GetLine, prompt: *const c_char, defchar: c_char) -> c_int;
    fn new_ExpandFile() -> *mut ExpandFile;
    fn del_ExpandFile(ef: *mut ExpandFile) -> *mut ExpandFile;
    // fn ef_expand_file(ef: *mut ExpandFile,
    //                  path: *const c_char,
    //                  pathlen: c_int) -> *mut FileExpansion;
    // fn el_list_expansions(result: *mut FileExpansion,
    //                      fp: *mut FILE,
    //                      term_width: c_int) -> c_int;
    // fn ef_last_error(ef: *mut ExpandFile) -> *const c_char;
    fn new_WordCompletion() -> *mut WordCompletion;
    fn del_WordCompletion(cpl: *mut WordCompletion) -> WordCompletion;
    /*fn gl_completion_action(gl: *mut GetLine,
                            data: *const void,
                            match_fn: CplMatchFn,
                            list_only: c_int,
                            name: *const c_char,
                            keyseq: *const c_char) -> c_int;*/
    fn gl_customize_completion(gl: *mut GetLine,
                               data: *const c_char,
                               match_fn: &CplMatchFn) -> c_int;
    fn gl_save_history(gl: *mut GetLine,
                       filename: *const c_char,
                       comment: *const c_char,
                       max_lines: c_int);
    fn gl_load_history(gl: *mut GetLine,
                       filename: *const c_char,
                       comment: *const c_char);
    fn gl_ignore_signal(gl: *mut GetLine, signo: c_int);
    fn gl_erase_terminal(gl: *mut GetLine) -> c_int;
    fn cpl_file_completions(cpl: *mut WordCompletion,
                            data: *const c_char,
                            line: *const c_char,
                            word_end: c_int) -> c_int;
    fn cpl_add_completion(cpl: *mut WordCompletion,
                          line: *const c_char,
                          word_start: c_int,
                          word_end: c_int,
                          suffix: *const c_char,
                          type_suffix: *const c_char,
                          cont_suffix: *const c_char) -> c_int;
}

///Creates new GetLine object
pub fn new_gl(linelen: u64, histlen: u64) -> *mut GetLine {
    let mut res: *mut GetLine;
    unsafe {
        res = new_GetLine(linelen, histlen);
    }
    res
}

///Deletes GetLine object
pub fn del_gl(gl: *mut GetLine) -> *mut GetLine {
    unsafe {
        del_GetLine(gl)
    }
}

///Creates new WordCompletion object
pub fn new_wc() -> *mut WordCompletion {
    unsafe {
        new_WordCompletion()
    }
}

///Deletes WordCompletion object
pub fn del_wc(cpl: *mut WordCompletion) -> WordCompletion {
    unsafe {
        del_WordCompletion(cpl)
    }
}

///Creates new ExpandFile object
pub fn new_ef() -> *mut ExpandFile {
    unsafe {
        new_ExpandFile()
    }
}

///Deletes ExpandFile object
pub fn del_ef(ef: *mut ExpandFile) -> *mut ExpandFile {
    unsafe {
        del_ExpandFile(ef)
    }
}

///Gets line from user using GetLine object
pub fn get_line(gl: *mut GetLine, prompt: &str) -> String {
    let c_prompt = CString::new(prompt.as_bytes()).unwrap();
    let start: *const i8 = ptr::null();
    let mut res: &str;
    unsafe {
        let out = CStr::from_ptr(gl_get_line(gl, c_prompt.as_ptr(), start, -1));
        res = from_utf8_unchecked(out.to_bytes());
    }
    as_string(res).clone()
}

///Returns the character read, or 0 if unreadable
pub fn query_char(gl: *mut GetLine, prompt: &str, defchar: char) -> char {
    let c_prompt = CString::new(prompt.as_bytes()).unwrap();
    let mut res: u8;
    unsafe {
        let out = gl_query_char(gl, c_prompt.as_ptr(), defchar as c_char);
        if out > 0 {
            res = out as u8;
        } else {
            res = 0;
        }
    }
    res as char
}

///Saves history to a file
pub fn save_history(gl: *mut GetLine, file: &str, comment: &str, max: usize) {
    let c_file = CString::new(file.as_bytes()).unwrap();
    let c_comment = CString::new(comment.as_bytes()).unwrap();
    let c_max = max as c_int;
    unsafe {
        gl_save_history(gl, c_file.as_ptr(), c_comment.as_ptr(), c_max)
    }
}

///Loads history from a file
pub fn load_history(gl: *mut GetLine, file: &str, comment: &str) {
    let c_file = CString::new(file.as_bytes()).unwrap();
    let c_comment = CString::new(comment.as_bytes()).unwrap();
    unsafe {
        gl_load_history(gl, c_file.as_ptr(), c_comment.as_ptr())
    }
}

///Ignore specified signal
pub fn ignore(gl: *mut GetLine, sig: isize) {
    unsafe {
        gl_ignore_signal(gl, sig as c_int)
    }
}

///Clear screen
pub fn clear(gl: *mut GetLine) -> i32 {
    unsafe {
        gl_erase_terminal(gl)
    }
}

///Sets the completion function
pub fn custom_complete(gl: *mut GetLine, data: &mut str, func: CplMatchFn) -> i32 {
    let c_data = CString::new(data.as_bytes()).unwrap();
    unsafe {
        gl_customize_completion(gl, c_data.as_ptr(), &func)
    }
}

///Calls built-in libtecla file completion function
pub fn builtin_complete(cpl: *mut WordCompletion,
                        data: *mut c_char,
                        line: *const c_char,
                        word_end: i32) -> i32 {
    unsafe {
        cpl_file_completions(cpl, data, line, word_end)
    }
}

///Calls cpl_add_completion
pub fn add_completion(wc: *mut WordCompletion,
                      line: *const c_char,
                      word_start: c_int,
                      word_end: c_int,
                      suffix: *const c_char,
                      type_suffix: *const c_char,
                      cont_suffix: *const c_char) -> c_int {
    unsafe {
        cpl_add_completion(wc, line, word_start, word_end, suffix, type_suffix, cont_suffix)
    }
}
<|endoftext|>


<commit_before>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
extern crate opengl_graphics;
extern crate sdl2;
extern crate sdl2_window;

// Crates used to reexport.
extern crate "ai_behavior" as ai_behavior_lib;
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "window" as window_lib;
extern crate "cam" as cam_lib;
extern crate "current" as current_lib;
extern crate "quack" as quack_lib;
extern crate "fps_counter" as fps_counter_lib;
extern crate "drag_controller" as drag_controller_lib;
extern crate "read_color" as read_color_lib;
extern crate "select_color" as select_color_lib;

// Reexports.
pub use current_lib as current;
pub use quack_lib as quack;
pub use ai_behavior_lib as ai_behavior;
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use window_lib as window;
pub use cam_lib as cam;
pub use fps_counter_lib as fps_counter;
pub use drag_controller_lib as drag_controller;

pub use sdl2_window::Sdl2Window as WindowBackEnd;
pub use event::{
    Event,
    Events,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    WindowSettings,
};

pub use quack::{
    Action,
    ActOn,
    Get,
    GetFrom,
    Set,
    SetAt,
};
pub use current::{
    Current,
    CurrentGuard,
};

#[cfg(feature = "include_gfx")]
use gfx_graphics::G2D;
#[cfg(feature = "include_gfx")]
use gfx::{ DeviceHelper };
use opengl_graphics::Gl;
use fps_counter::FPSCounter;

use std::rc::Rc;
use std::cell::RefCell;

pub mod color {
    //! Rexported libraries for working with colors
    pub use read_color_lib as read_color;
    pub use select_color_lib as select_color;
}

fn start_window(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    let mut window = Rc::new(RefCell::new(WindowBackEnd::new(
        opengl,
        window_settings,
    )));
    let mut gl = Rc::new(RefCell::new(Gl::new(opengl)));
    let mut fps_counter = Rc::new(RefCell::new(FPSCounter::new()));

    let window_guard = CurrentGuard::new(&mut window);
    let gl_guard = CurrentGuard::new(&mut gl);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(gl_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_gfx")]
fn start_gfx(f: ||) {
    let window = current_window();

    let mut device = Rc::new(RefCell::new(gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    })));
    let mut g2d = Rc::new(RefCell::new(G2D::new(device.borrow_mut().deref_mut())));
    let mut renderer = Rc::new(RefCell::new(device.borrow_mut().create_renderer()));
    let event::window::Size([w, h]) = window.get();
    let mut frame = Rc::new(RefCell::new(gfx::Frame::new(w as u16, h as u16)));

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx(f: ||) {
    f();
}

/// Initializes window and sets up current objects.
pub fn start(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    start_window(opengl, window_settings, || {
        if cfg!(feature = "include_gfx") {
            start_gfx(|| f());
        } else {
            f();
        }
    });
}

/// The current window
pub fn current_window() -> Rc<RefCell<WindowBackEnd>> {
    unsafe {
        Current::<Rc<RefCell<WindowBackEnd>>>::new().clone()
    }
}
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub fn current_gfx_device() -> Rc<RefCell<gfx::GlDevice>> {
    unsafe {
        Current::<Rc<RefCell<gfx::GlDevice>>>::new().clone()
    }
}
/// The current opengl_graphics back-end
pub fn current_gl() -> Rc<RefCell<Gl>> {
    unsafe {
        Current::<Rc<RefCell<Gl>>>::new().clone()
    }
}
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub fn current_g2d() -> Rc<RefCell<G2D>> {
    unsafe {
        Current::<Rc<RefCell<G2D>>>::new().clone()
    }
}
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub fn current_renderer() -> Rc<RefCell<gfx::Renderer<gfx::GlCommandBuffer>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Renderer<gfx::GlCommandBuffer>>>>::new().clone()
    }
}
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub fn current_frame() -> Rc<RefCell<gfx::Frame>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Frame>>>::new().clone()
    }
}
/// The current FPS counter
pub fn current_fps_counter() -> Rc<RefCell<FPSCounter>> {
    unsafe {
        Current::<Rc<RefCell<FPSCounter>>>::new().clone()
    }
}

/// Returns an event iterator for the event loop
pub fn events<E>() -> event::Events<Rc<RefCell<WindowBackEnd>>, E> {
    Events::new(current_window())
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> uint {
    current_fps_counter().borrow_mut().tick()
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    current_window().set_mut(window::Title(text));
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use window::ShouldClose;
    let ShouldClose(val) = current_window().get();
    val
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx(
    bg_color: Option<[f32; 4]>,
    f: |graphics::Context,
        &mut gfx_graphics::GraphicsBackEnd<gfx::GlCommandBuffer>|
) {
    use gfx::Device;

    let renderer = current_renderer();
    let mut renderer = renderer.borrow_mut();
    let renderer = renderer.deref_mut();
    current_g2d().borrow_mut().draw(
        renderer,
        current_frame().borrow_mut().deref_mut(),
        |c, g| {
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    current_gfx_device().borrow_mut().submit(renderer.as_buffer());
    renderer.reset();
}

/// Renders 2D graphics using OpenGL.
///
/// Panics if called nested within the closure
/// to prevent mutable aliases to the graphics back-end.
pub fn render_2d_opengl(
    bg_color: Option<[f32; 4]>,
    f: |graphics::Context,
        &mut opengl_graphics::Gl|
) {
    use std::ops::Deref;

    let window::Size([w, h]) = current_window().borrow().deref().get();
    current_gl().borrow_mut().draw([0, 0, w as i32, h as i32], |c, g| {
        use graphics::*;
        if let Some(bg_color) = bg_color {
            graphics::clear(bg_color, g);
        }
        f(c, g);
    });
}

<commit_msg>Use `Event` from piston-event<commit_after>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
extern crate opengl_graphics;
extern crate sdl2;
extern crate sdl2_window;

// Crates used to reexport.
extern crate "ai_behavior" as ai_behavior_lib;
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "window" as window_lib;
extern crate "cam" as cam_lib;
extern crate "current" as current_lib;
extern crate "quack" as quack_lib;
extern crate "fps_counter" as fps_counter_lib;
extern crate "drag_controller" as drag_controller_lib;
extern crate "read_color" as read_color_lib;
extern crate "select_color" as select_color_lib;

// Reexports.
pub use current_lib as current;
pub use quack_lib as quack;
pub use ai_behavior_lib as ai_behavior;
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use window_lib as window;
pub use cam_lib as cam;
pub use fps_counter_lib as fps_counter;
pub use drag_controller_lib as drag_controller;

pub use sdl2_window::Sdl2Window as WindowBackEnd;
pub use event::{
    Event,
    Events,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    WindowSettings,
};

pub use quack::{
    Action,
    ActOn,
    Get,
    GetFrom,
    Set,
    SetAt,
};
pub use current::{
    Current,
    CurrentGuard,
};

#[cfg(feature = "include_gfx")]
use gfx_graphics::G2D;
#[cfg(feature = "include_gfx")]
use gfx::{ DeviceHelper };
use opengl_graphics::Gl;
use fps_counter::FPSCounter;

use std::rc::Rc;
use std::cell::RefCell;

pub mod color {
    //! Rexported libraries for working with colors
    pub use read_color_lib as read_color;
    pub use select_color_lib as select_color;
}

fn start_window(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    let mut window = Rc::new(RefCell::new(WindowBackEnd::new(
        opengl,
        window_settings,
    )));
    let mut gl = Rc::new(RefCell::new(Gl::new(opengl)));
    let mut fps_counter = Rc::new(RefCell::new(FPSCounter::new()));

    let window_guard = CurrentGuard::new(&mut window);
    let gl_guard = CurrentGuard::new(&mut gl);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(gl_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_gfx")]
fn start_gfx(f: ||) {
    let window = current_window();

    let mut device = Rc::new(RefCell::new(gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    })));
    let mut g2d = Rc::new(RefCell::new(G2D::new(device.borrow_mut().deref_mut())));
    let mut renderer = Rc::new(RefCell::new(device.borrow_mut().create_renderer()));
    let event::window::Size([w, h]) = window.get();
    let mut frame = Rc::new(RefCell::new(gfx::Frame::new(w as u16, h as u16)));

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx(f: ||) {
    f();
}

/// Initializes window and sets up current objects.
pub fn start(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    start_window(opengl, window_settings, || {
        if cfg!(feature = "include_gfx") {
            start_gfx(|| f());
        } else {
            f();
        }
    });
}

/// The current window
pub fn current_window() -> Rc<RefCell<WindowBackEnd>> {
    unsafe {
        Current::<Rc<RefCell<WindowBackEnd>>>::new().clone()
    }
}
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub fn current_gfx_device() -> Rc<RefCell<gfx::GlDevice>> {
    unsafe {
        Current::<Rc<RefCell<gfx::GlDevice>>>::new().clone()
    }
}
/// The current opengl_graphics back-end
pub fn current_gl() -> Rc<RefCell<Gl>> {
    unsafe {
        Current::<Rc<RefCell<Gl>>>::new().clone()
    }
}
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub fn current_g2d() -> Rc<RefCell<G2D>> {
    unsafe {
        Current::<Rc<RefCell<G2D>>>::new().clone()
    }
}
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub fn current_renderer() -> Rc<RefCell<gfx::Renderer<gfx::GlCommandBuffer>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Renderer<gfx::GlCommandBuffer>>>>::new().clone()
    }
}
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub fn current_frame() -> Rc<RefCell<gfx::Frame>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Frame>>>::new().clone()
    }
}
/// The current FPS counter
pub fn current_fps_counter() -> Rc<RefCell<FPSCounter>> {
    unsafe {
        Current::<Rc<RefCell<FPSCounter>>>::new().clone()
    }
}

/// Returns an event iterator for the event loop
pub fn events() -> event::Events<Rc<RefCell<WindowBackEnd>>, event::Event> {
    event::events(current_window())
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> uint {
    current_fps_counter().borrow_mut().tick()
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    current_window().set_mut(window::Title(text));
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use window::ShouldClose;
    let ShouldClose(val) = current_window().get();
    val
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx(
    bg_color: Option<[f32; 4]>,
    f: |graphics::Context,
        &mut gfx_graphics::GraphicsBackEnd<gfx::GlCommandBuffer>|
) {
    use gfx::Device;

    let renderer = current_renderer();
    let mut renderer = renderer.borrow_mut();
    let renderer = renderer.deref_mut();
    current_g2d().borrow_mut().draw(
        renderer,
        current_frame().borrow_mut().deref_mut(),
        |c, g| {
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    current_gfx_device().borrow_mut().submit(renderer.as_buffer());
    renderer.reset();
}

/// Renders 2D graphics using OpenGL.
///
/// Panics if called nested within the closure
/// to prevent mutable aliases to the graphics back-end.
pub fn render_2d_opengl(
    bg_color: Option<[f32; 4]>,
    f: |graphics::Context,
        &mut opengl_graphics::Gl|
) {
    use std::ops::Deref;

    let window::Size([w, h]) = current_window().borrow().deref().get();
    current_gl().borrow_mut().draw([0, 0, w as i32, h as i32], |c, g| {
        use graphics::*;
        if let Some(bg_color) = bg_color {
            graphics::clear(bg_color, g);
        }
        f(c, g);
    });
}

<|endoftext|>


<commit_before>#![crate_id = "readline"]
#![crate_type = "lib"]

use std::c_str;

mod ext_readline {
    use std::libc::c_char;
    #[link(name = "readline")]
    extern {
        pub fn add_history (line: *c_char);
        pub fn readline (p: *c_char) -> * c_char;
    }
}

pub fn add_history(line: &str) {
    let c_line = line.to_c_str();
    c_line.with_ref(|c_buf| {
        unsafe {
            ext_readline::add_history(c_buf);
        }
    });
}

pub fn readline (prompt: &str) -> Option<~str> {
    let cprmt = prompt.to_c_str();
    cprmt.with_ref(|c_buf| {
        unsafe {
            let ret = c_str::CString::new (ext_readline::readline (c_buf), true);
            if ret.is_null() {  // user pressed Ctrl-D
                None
            }
            else {
                ret.as_str().map(|ret| ret.to_owned())
            }
        }
    })
}
<commit_msg>Update to latest Rust<commit_after>#![crate_type = "lib"]
extern crate libc;

use std::c_str;

mod ext_readline {
    use libc::c_char;
    #[link(name = "readline")]
    extern {
        pub fn add_history(line: *const c_char);
        pub fn readline(p: *const c_char) -> *const c_char;
    }
}

pub fn add_history(line: &str) {
    unsafe {
        ext_readline::add_history(line.to_c_str().as_ptr());
    }
}

pub fn readline(prompt: &str) -> Option<String> {
    let cprmt = prompt.to_c_str();
    unsafe {
        let ret = ext_readline::readline(cprmt.as_ptr());
        if ret.is_null() {  // user pressed Ctrl-D
            None
        }
        else {
            c_str::CString::new(ret, true).as_str().map(|ret| ret.to_string())
        }
    }
}
<|endoftext|>


<commit_before>//   Copyright 2017 James Duley
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

#![feature(proc_macro)]

extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;
use std::str::FromStr;
use syn::{parse_token_trees, Token, TokenTree, Lit, Delimited, DelimToken, StrStyle, Mac, Path};
use quote::{Tokens, ToTokens};

#[proc_macro]
pub fn gcc_asm(token_stream: TokenStream) -> TokenStream {
    let tokens = token_stream.to_string();
    let token_trees = parse_token_trees(&tokens).unwrap();
    let mut parts = split_on_token(token_trees.as_slice(), &Token::Colon);

    let template = parts
        .next()
        .expect("error: template missing")
        .iter()
        .map(get_string_literal)
        // support C-style string literal concatenation
        .fold(String::new(), |acc, ref x| acc + &*x);
    let output_operands = parts.next().unwrap_or(&[]);
    let input_operands = parts.next().unwrap_or(&[]);
    let clobbers = parts.next().unwrap_or(&[]);

    assert!(
        clobbers.len() == 0usize,
        "error: clobbers not supported yet"
    );
    assert!(parts.next().is_none(), "error: extra tokens after clobbers");

    let mut symbolic_names = Vec::new();
    let (new_output_operands, tied_input_operands) = split_on_token(output_operands, &Token::Comma)
        .map(|tts| extract_symbolic_name(&mut symbolic_names, tts))
        .enumerate()
        .map(extract_tied_operands)
        .fold((Vec::new(), Vec::new()), |mut acc, x| {
            acc.0.push(x.0);
            if let Some(t) = x.1 {
                acc.1.push(t)
            };
            acc
        });
    let new_input_operands = split_on_token(input_operands, &Token::Comma)
        .map(|tts| extract_symbolic_name(&mut symbolic_names, tts))
        .collect::<Vec<_>>();
    let new_template = replace_template(template, symbolic_names.as_slice());
    let all_new_input_operands = new_input_operands.iter().chain(tied_input_operands.iter());

    // println!(
    //     "out: {:?}\nin: {:?}\ntied: {:?}",
    //     new_output_operands,
    //     new_input_operands,
    //     tied_input_operands
    // );

    let new_tokens =
        quote! {
        asm!(#new_template : #(#(#new_output_operands)*),* : #(#(#all_new_input_operands)*),*)
    };
    // println!("{}", new_tokens);
    TokenStream::from_str(new_tokens.as_str()).unwrap()
}

fn split_on_token<'a>(
    token_trees: &'a [TokenTree],
    separator: &'a Token,
) -> Box<Iterator<Item = &'a [TokenTree]> + 'a> {
    if token_trees.is_empty() {
        Box::new(std::iter::empty())
    } else {
        Box::new(token_trees.split(move |tt| match *tt {
            TokenTree::Token(ref token) => token == separator,
            _ => false,
        }))
    }
}

fn replace_template(template: String, symbolic_names: &[Option<String>]) -> String {
    let with_dollars = template.replace("$", "\u{80}").replace("%", "$").replace(
        "$$",
        "%",
    );

    symbolic_names
        .iter()
        .enumerate()
        .fold(with_dollars, |acc, ref number_and_name| {
            if let Some(ref x) = *number_and_name.1 {
                acc.replace(
                    &("$[".to_string() + &x + "]"),
                    &("$".to_string() + &number_and_name.0.to_string()),
                )
            } else {
                acc
            }
        })
        .replace("$=", "${:uid}")
        .replace("\u{80}", "$$")
}

fn extract_symbolic_name(
    ordered_list: &mut Vec<Option<String>>,
    tts: &[TokenTree],
) -> Vec<TokenTree> {
    let name_and_remaining = match *tts.first().expect("error: empty operand") {
        TokenTree::Delimited(ref d) => {
            assert!(d.delim == DelimToken::Bracket, "error: bad operand");
            let name = if d.tts.len() == 1usize {
                match d.tts[0] {
                    TokenTree::Token(Token::Ident(ref name)) => Some(name.to_string()),
                    _ => None,
                }
            } else {
                None
            };
            assert!(name.is_some(), "error: bad symbolic name");
            (name, tts.split_at(1).1)
        }
        _ => (None, tts),
    };
    ordered_list.push(name_and_remaining.0);
    let mut without_name = Vec::new();
    without_name.extend_from_slice(name_and_remaining.1);
    without_name
}

fn extract_tied_operands(
    pos_and_tts: (usize, Vec<TokenTree>),
) -> (Vec<TokenTree>, Option<Vec<TokenTree>>) {
    {
        let constraint = get_string_literal(pos_and_tts.1.first().expect("error: empty operand"));
        if constraint.starts_with("+") {
            let lvalue = pos_and_tts.1.split_at(1).1;

            let new_input_constraint = pos_and_tts.0.to_string();
            let mut input = Vec::new();
            input.push(make_string_literal(new_input_constraint));
            input.extend_from_slice(lvalue);

            let new_output_constraint = constraint.replace("+", "=");
            let mut output = Vec::new();
            output.push(make_string_literal(new_output_constraint));
            output.extend_from_slice(lvalue);

            return (output, Some(input));
        }
    }
    (pos_and_tts.1, None)
}

fn get_string_literal(tt: &TokenTree) -> &String {
    match *tt {
        TokenTree::Token(Token::Literal(Lit::Str(ref string, _))) => string,
        _ => {
            panic!(format!(
                "error: expected a string literal but found {:?}",
                tt
            ))
        }
    }
}

fn make_string_literal(string: String) -> TokenTree {
    TokenTree::Token(Token::Literal(Lit::Str(string, StrStyle::Cooked)))
}
<commit_msg>Add implicit volatile when no outputs<commit_after>//   Copyright 2017 James Duley
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

#![feature(proc_macro)]

extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;
use std::str::FromStr;
use syn::{parse_token_trees, Token, TokenTree, Lit, DelimToken, StrStyle};

#[proc_macro]
pub fn gcc_asm(token_stream: TokenStream) -> TokenStream {
    let tokens = token_stream.to_string();
    let token_trees = parse_token_trees(&tokens).unwrap();
    let mut parts = split_on_token(token_trees.as_slice(), &Token::Colon);

    let template = parts
        .next()
        .expect("error: template missing")
        .iter()
        .map(get_string_literal)
        // support C-style string literal concatenation
        .fold(String::new(), |acc, ref x| acc + &*x);
    let output_operands = parts.next().unwrap_or(&[]);
    let input_operands = parts.next().unwrap_or(&[]);
    let clobbers = parts.next().unwrap_or(&[]);

    assert!(
        clobbers.len() == 0usize,
        "error: clobbers not supported yet"
    );
    assert!(parts.next().is_none(), "error: extra tokens after clobbers");

    let mut symbolic_names = Vec::new();
    let (new_output_operands, tied_input_operands) = split_on_token(output_operands, &Token::Comma)
        .map(|tts| extract_symbolic_name(&mut symbolic_names, tts))
        .enumerate()
        .map(extract_tied_operands)
        .fold((Vec::new(), Vec::new()), |mut acc, x| {
            acc.0.push(x.0);
            if let Some(t) = x.1 {
                acc.1.push(t)
            };
            acc
        });
    let new_input_operands = split_on_token(input_operands, &Token::Comma)
        .map(|tts| extract_symbolic_name(&mut symbolic_names, tts))
        .collect::<Vec<_>>();
    let new_template = replace_template(template, symbolic_names.as_slice());
    let all_new_input_operands = new_input_operands.iter().chain(tied_input_operands.iter());

    let is_volatile = new_output_operands.len() == 0;

    let mut options = Vec::new();
    if is_volatile {
        options.push("volatile");
    }

    // println!(
    //     "out: {:?}\nin: {:?}\ntied: {:?}",
    //     new_output_operands,
    //     new_input_operands,
    //     tied_input_operands
    // );

    let new_tokens =
        quote! {
        asm!(
            #new_template :
            #(#(#new_output_operands)*),* :
            #(#(#all_new_input_operands)*),* :
            :
            #(#options),*
        )
    };
    // println!("{}", new_tokens);
    TokenStream::from_str(new_tokens.as_str()).unwrap()
}

fn split_on_token<'a>(
    token_trees: &'a [TokenTree],
    separator: &'a Token,
) -> Box<Iterator<Item = &'a [TokenTree]> + 'a> {
    if token_trees.is_empty() {
        Box::new(std::iter::empty())
    } else {
        Box::new(token_trees.split(move |tt| match *tt {
            TokenTree::Token(ref token) => token == separator,
            _ => false,
        }))
    }
}

fn replace_template(template: String, symbolic_names: &[Option<String>]) -> String {
    let with_dollars = template.replace("$", "\u{80}").replace("%", "$").replace(
        "$$",
        "%",
    );

    symbolic_names
        .iter()
        .enumerate()
        .fold(with_dollars, |acc, ref number_and_name| {
            if let Some(ref x) = *number_and_name.1 {
                acc.replace(
                    &("$[".to_string() + &x + "]"),
                    &("$".to_string() + &number_and_name.0.to_string()),
                )
            } else {
                acc
            }
        })
        .replace("$=", "${:uid}")
        .replace("\u{80}", "$$")
}

fn extract_symbolic_name(
    ordered_list: &mut Vec<Option<String>>,
    tts: &[TokenTree],
) -> Vec<TokenTree> {
    let name_and_remaining = match *tts.first().expect("error: empty operand") {
        TokenTree::Delimited(ref d) => {
            assert!(d.delim == DelimToken::Bracket, "error: bad operand");
            let name = if d.tts.len() == 1usize {
                match d.tts[0] {
                    TokenTree::Token(Token::Ident(ref name)) => Some(name.to_string()),
                    _ => None,
                }
            } else {
                None
            };
            assert!(name.is_some(), "error: bad symbolic name");
            (name, tts.split_at(1).1)
        }
        _ => (None, tts),
    };
    ordered_list.push(name_and_remaining.0);
    let mut without_name = Vec::new();
    without_name.extend_from_slice(name_and_remaining.1);
    without_name
}

fn extract_tied_operands(
    pos_and_tts: (usize, Vec<TokenTree>),
) -> (Vec<TokenTree>, Option<Vec<TokenTree>>) {
    {
        let constraint = get_string_literal(pos_and_tts.1.first().expect("error: empty operand"));
        if constraint.starts_with("+") {
            let lvalue = pos_and_tts.1.split_at(1).1;

            let new_input_constraint = pos_and_tts.0.to_string();
            let mut input = Vec::new();
            input.push(make_string_literal(new_input_constraint));
            input.extend_from_slice(lvalue);

            let new_output_constraint = constraint.replace("+", "=");
            let mut output = Vec::new();
            output.push(make_string_literal(new_output_constraint));
            output.extend_from_slice(lvalue);

            return (output, Some(input));
        }
    }
    (pos_and_tts.1, None)
}

fn get_string_literal(tt: &TokenTree) -> &String {
    match *tt {
        TokenTree::Token(Token::Literal(Lit::Str(ref string, _))) => string,
        _ => {
            panic!(format!(
                "error: expected a string literal but found {:?}",
                tt
            ))
        }
    }
}

fn make_string_literal(string: String) -> TokenTree {
    TokenTree::Token(Token::Literal(Lit::Str(string, StrStyle::Cooked)))
}
<|endoftext|>


<commit_before>#![crate_id="sha"]

static MAGIC_VALUES_SHA256: [u32, ..8] = [
    0x6a09e667,
    0xbb67ae85,
    0x3c6ef372,
    0xa54ff53a,
    0x510e527f,
    0x9b05688c,
    0x1f83d9ab,
    0x5be0cd19
];

static ROUND_CONSTANTS: [u32, ..64] = [
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];

struct Sha256<'a> {
    state: &'a [u32, ..8],
    buffer: Vec<u8>
}

impl<'a> Sha256<'a> {
    fn new() -> Sha256<'a> {
        Sha256 {
            state: MAGIC_VALUES_SHA256.clone(),
            buffer: Vec::with_capacity(512)
        }
    }

}

#[cfg(test)]
mod test {

    use super::Sha256;

    #[test]
    fn test_sha256() {
        let hasher = Sha256::new();
    }
}

<commit_msg>new work<commit_after>#![feature(asm)]
#![crate_id="sha"]

use std::slice::bytes::copy_memory;

static MAGIC_VALUES_SHA256: [u32, ..8] = [
    0x6a09e667,
    0xbb67ae85,
    0x3c6ef372,
    0xa54ff53a,
    0x510e527f,
    0x9b05688c,
    0x1f83d9ab,
    0x5be0cd19
];

static ROUND_CONSTANTS: [u32, ..64] = [
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];

pub struct Sha256<'a> {
    state: &'a [u32],
    position: uint,
    buffer: Vec<u8>
}

impl<'a> Sha256<'a> {
    pub fn new() -> Sha256<'a> {
        let mut buffer = Vec::with_capacity(64);
        unsafe { buffer.set_len(64); }
        Sha256 {
            state: MAGIC_VALUES_SHA256.clone(),
            buffer: buffer,
            position: 0,
        }
    }

    //
    // Adds the message to the buffer and hashes when the
    // buffer is full
    // TODO: refactor
    //
    pub fn update(&mut self, message: &[u8]) {

        let mut position: uint = 0;

        if self.position > 0 {
            let space = 64 - self.position;
            if space > message.len() {
                {
                    let destination = self.buffer.mut_slice_from(self.position);
                    copy_memory(destination, message);
                }
                self.position += message.len();
                return;
            } else if space == message.len() {
                {
                    let destination = self.buffer.mut_slice_from(self.position);
                    copy_memory(destination, message);
                }
                self.hash();
                return;
            } else {
                {
                    let destination = self.buffer.mut_slice_from(self.position);
                    let source = message.slice_to(space);
                    copy_memory(destination, source);
                }
                self.hash();
                position += space;
            }
        }

        while position < message.len() {
            let end = position + 64;
            if end <= message.len() {
                {
                    let destination = self.buffer.as_mut_slice();
                    let source = message.slice(position, end);
                    copy_memory(destination, source);
                }
                self.hash();
                position = end;

            // final iteration
            } else {
                {
                    let destination = self.buffer.as_mut_slice();
                    let source = message.slice_from(position);
                    copy_memory(destination, source);
                }
                self.position = message.len() - position;
                break;
            }
        }

    }

    fn hash(&mut self) {
        //TODO: inline assembly?
        //

        let mut first: u32;
        unsafe {
            asm!(
                "movl $a, $b"
                :"=r"(first)
                :"a"(self.state),
                :
            )
        }
    }

}

#[cfg(test)]
mod test {
    #![feature(phase)]

    use super::Sha256;
    use std::string::String;

    macro_rules! rotate_right_32 (
        ($value:expr, $shift:expr) => (
            ($value >> $shift) | ($value << (32 - $shift))
        )
    )

    #[test]
    fn test_sha256() {
        let mut hasher = Sha256::new();
        let message = String::from_str("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ");

        hasher.update(message.as_bytes());

        assert!(hasher.position == 63 && message.len() == 63);
        hasher.update("a".as_bytes());
        assert!(hasher.position == 0);
    }

    #[test]
    fn test_right_rotate() {
        let five: u32 = 5;

        let shifted: u32 = 2147483650;

        assert_eq!(shifted, rotate_right_32!(five, 1));

    }
}

<|endoftext|>


<commit_before>use std::os;
use std::io::fs::PathExtensions;

/// Probe the system for the directory in which CA certificates should likely be
/// found.
///
/// This will only search known system locations.
pub fn find_certs_dirs() -> Vec<Path> {
    // see http://gagravarr.org/writing/openssl-certs/others.shtml
    [
        "/var/ssl",
        "/usr/share/ssl",
        "/usr/local/ssl",
        "/usr/local/openssl",
        "/usr/lib/ssl",
        "/usr/ssl",
        "/etc/openssl",
        "/etc/pki/tls",
        "/etc/ssl",
    ].iter().map(|s| Path::new(*s)).filter(|p| {
        p.exists()
    }).collect()
}

pub fn init_ssl_cert_env_vars() {
    for certs_dir in find_certs_dirs().iter() {
        // cert.pem looks to be an openssl 1.0.1 thing, while
        // certs/ca-certificates.crt appears to be a 0.9.8 thing
        try("SSL_CERT_FILE", certs_dir.join("cert.pem"));
        try("SSL_CERT_FILE", certs_dir.join("certs/ca-certificates.crt"));

        try("SSL_CERT_DIR", certs_dir.join("certs"));
    }
}

fn try(var: &str, val: Path) {
    if !val.exists() { return }
    match os::getenv(var) {
        // Someone else has already got this, they probably know what
        // they're doing more than we do
        Some(..) => {},
        None => os::setenv(var, val),
    }
}
<commit_msg>Add cert path for FreeBSD<commit_after>use std::os;
use std::io::fs::PathExtensions;

/// Probe the system for the directory in which CA certificates should likely be
/// found.
///
/// This will only search known system locations.
pub fn find_certs_dirs() -> Vec<Path> {
    // see http://gagravarr.org/writing/openssl-certs/others.shtml
    [
        "/var/ssl",
        "/usr/share/ssl",
        "/usr/local/ssl",
        "/usr/local/openssl",
        "/usr/local/share",
        "/usr/lib/ssl",
        "/usr/ssl",
        "/etc/openssl",
        "/etc/pki/tls",
        "/etc/ssl",
    ].iter().map(|s| Path::new(*s)).filter(|p| {
        p.exists()
    }).collect()
}

pub fn init_ssl_cert_env_vars() {
    for certs_dir in find_certs_dirs().iter() {
        // cert.pem looks to be an openssl 1.0.1 thing, while
        // certs/ca-certificates.crt appears to be a 0.9.8 thing
        try("SSL_CERT_FILE", certs_dir.join("cert.pem"));
        try("SSL_CERT_FILE", certs_dir.join("certs/ca-certificates.crt"));
        try("SSL_CERT_FILE", certs_dir.join("certs/ca-root-nss.crt"));

        try("SSL_CERT_DIR", certs_dir.join("certs"));
    }
}

fn try(var: &str, val: Path) {
    if !val.exists() { return }
    match os::getenv(var) {
        // Someone else has already got this, they probably know what
        // they're doing more than we do
        Some(..) => {},
        None => os::setenv(var, val),
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![allow(unknown_lints)]

//! glTF 2.0 loader
//!
//! This crate is intended to load [glTF 2.0], a file format designed for the
//! efficient runtime transmission of 3D scenes. The crate aims to provide
//! rustic utilities that make working with glTF simple and intuitive.
//!
//! [glTF 2.0]: https://www.khronos.org/gltf
//!
//! ## Installation
//!
//! Add `gltf` version 0.9 to your `Cargo.toml`.
//!
//! ```toml
//! [dependencies.gltf]
//! version = "0.9"
//! ```
//!
//! ## Examples
//!
//! ### Walking the node hierarchy
//!
//! Below demonstates visiting the root [`Node`]s of every [`Scene`], printing the
//! number of children each node has.
//!
//! [`Node`]: scene/struct.Node.html
//! [`Scene`]: scene/struct.Scene.html
//! ```
//! # fn run() -> Result<(), Box<std::error::Error>> {
//! # use std::{fs, io};
//! # let path = "examples/Box.gltf";
//! use gltf::Gltf;
//! let file = fs::File::open(path)?;
//! let gltf = Gltf::from_reader(io::BufReader::new(file))?.validate_minimally()?;
//! for scene in gltf.scenes() {
//!     for node in scene.nodes() {
//!         // Do something with this node.
//!         println!(
//!             "Node {} has {} children",
//!             node.index(),
//!             node.children().count(),
//!         );
//!     }
//! }
//! # Ok(())
//! # }
//! # fn main() {
//! #    let _ = run().expect("No runtime errors");
//! # }
//! ```

#[cfg(test)]
#[macro_use]
extern crate approx;
extern crate byteorder;
extern crate cgmath;
#[macro_use]
extern crate lazy_static;

/// Contains (de)serializable data structures that match the glTF JSON text.
#[deprecated(since = "0.9.1", note = "Will be removed in 1.0.0")]
#[doc(hidden)]
pub extern crate gltf_json as json;

/// Accessors for reading vertex attributes from buffer views.
pub mod accessor;

/// Animations, their channels, targets, and samplers.
pub mod animation;

/// Buffers and buffer views.
pub mod buffer;

/// Cameras and their projections.
pub mod camera;

/// Primitives for working with binary glTF.
pub mod glb;

/// **The main module - start here.**
pub mod gltf;

/// Images that may be used by textures.
pub mod image;

/// Material properties of primitives.
pub mod material;

/// Meshes and their primitives.
pub mod mesh;

/// The glTF node heirarchy.
pub mod scene;

/// Mesh skinning primitives.
pub mod skin;

/// Textures and their samplers.
pub mod texture;

pub use self::animation::Animation;
pub use self::accessor::Accessor;
pub use self::buffer::Buffer;
pub use self::camera::Camera;
pub use self::glb::Glb;
pub use self::gltf::{Gltf, Unvalidated};
pub use self::image::Image;
pub use self::material::Material;
pub use self::mesh::{Attribute, Mesh, Primitive, Semantic};
pub use self::scene::{Node, Scene};
pub use self::skin::Skin;
pub use self::texture::Texture;

/// Represents a runtime error.
#[derive(Debug)]
pub enum Error {
    /// JSON deserialization error.
    Deserialize(json::Error),
    /// GLB parsing error.
    Glb(self::glb::Error),
    /// `glTF` validation error.
    Validation(Vec<(json::Path, json::validation::Error)>),
}

/// Returns `true` if the slice begins with the `b"glTF"` magic string, indicating
/// a binary `glTF` asset.
///
/// # Examples
///
/// ```rust
/// assert_eq!(true, gltf::is_binary(b"glTF..."));
/// assert_eq!(false, gltf::is_binary(b"{...}"));
/// ```
pub fn is_binary(slice: &[u8]) -> bool {
    slice.starts_with(b"glTF")
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        use std::error::Error;
        write!(f, "{}", self.description())
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
         match *self {
             Error::Deserialize(_) => "deserialization error",
             Error::Glb(ref e) => e.description(),
             Error::Validation(_) => "invalid glTF JSON",
        }
    }
}

impl From<self::glb::Error> for Error {
    fn from(err: self::glb::Error) -> Self {
        Error::Glb(err)
    }
}

impl From<json::Error> for Error {
    fn from(err: json::Error) -> Self {
        Error::Deserialize(err)
    }
}

impl From<Vec<(json::Path, json::validation::Error)>> for Error {
    fn from(errs: Vec<(json::Path, json::validation::Error)>) -> Self {
        Error::Validation(errs)
    }
}
<commit_msg>Inline top-level re-exports<commit_after>#![deny(missing_docs)]
#![allow(unknown_lints)]

//! glTF 2.0 loader
//!
//! This crate is intended to load [glTF 2.0], a file format designed for the
//! efficient runtime transmission of 3D scenes. The crate aims to provide
//! rustic utilities that make working with glTF simple and intuitive.
//!
//! [glTF 2.0]: https://www.khronos.org/gltf
//!
//! ## Installation
//!
//! Add `gltf` version 0.9 to your `Cargo.toml`.
//!
//! ```toml
//! [dependencies.gltf]
//! version = "0.9"
//! ```
//!
//! ## Examples
//!
//! ### Walking the node hierarchy
//!
//! Below demonstates visiting the root [`Node`]s of every [`Scene`], printing the
//! number of children each node has.
//!
//! [`Node`]: scene/struct.Node.html
//! [`Scene`]: scene/struct.Scene.html
//! ```
//! # fn run() -> Result<(), Box<std::error::Error>> {
//! # use std::{fs, io};
//! # let path = "examples/Box.gltf";
//! use gltf::Gltf;
//! let file = fs::File::open(path)?;
//! let gltf = Gltf::from_reader(io::BufReader::new(file))?.validate_minimally()?;
//! for scene in gltf.scenes() {
//!     for node in scene.nodes() {
//!         // Do something with this node.
//!         println!(
//!             "Node {} has {} children",
//!             node.index(),
//!             node.children().count(),
//!         );
//!     }
//! }
//! # Ok(())
//! # }
//! # fn main() {
//! #    let _ = run().expect("No runtime errors");
//! # }
//! ```

#[cfg(test)]
#[macro_use]
extern crate approx;
extern crate byteorder;
extern crate cgmath;
#[macro_use]
extern crate lazy_static;

/// Contains (de)serializable data structures that match the glTF JSON text.
#[deprecated(since = "0.9.1", note = "Will be removed in 1.0.0")]
#[doc(hidden)]
pub extern crate gltf_json as json;

/// Accessors for reading vertex attributes from buffer views.
pub mod accessor;

/// Animations, their channels, targets, and samplers.
pub mod animation;

/// Buffers and buffer views.
pub mod buffer;

/// Cameras and their projections.
pub mod camera;

/// Primitives for working with binary glTF.
pub mod glb;

/// **The main module - start here.**
pub mod gltf;

/// Images that may be used by textures.
pub mod image;

/// Material properties of primitives.
pub mod material;

/// Meshes and their primitives.
pub mod mesh;

/// The glTF node heirarchy.
pub mod scene;

/// Mesh skinning primitives.
pub mod skin;

/// Textures and their samplers.
pub mod texture;

#[doc(inline)]
pub use self::animation::Animation;
#[doc(inline)]
pub use self::accessor::Accessor;
#[doc(inline)]
pub use self::buffer::Buffer;
#[doc(inline)]
pub use self::camera::Camera;
#[doc(inline)]
pub use self::glb::Glb;
#[doc(inline)]
pub use self::gltf::{Gltf, Unvalidated};
#[doc(inline)]
pub use self::image::Image;
#[doc(inline)]
pub use self::material::Material;
#[doc(inline)]
pub use self::mesh::{Attribute, Mesh, Primitive, Semantic};
#[doc(inline)]
pub use self::scene::{Node, Scene};
#[doc(inline)]
pub use self::skin::Skin;
#[doc(inline)]
pub use self::texture::Texture;

/// Represents a runtime error.
#[derive(Debug)]
pub enum Error {
    /// JSON deserialization error.
    Deserialize(json::Error),
    /// GLB parsing error.
    Glb(self::glb::Error),
    /// `glTF` validation error.
    Validation(Vec<(json::Path, json::validation::Error)>),
}

/// Returns `true` if the slice begins with the `b"glTF"` magic string, indicating
/// a binary `glTF` asset.
///
/// # Examples
///
/// ```rust
/// assert_eq!(true, gltf::is_binary(b"glTF..."));
/// assert_eq!(false, gltf::is_binary(b"{...}"));
/// ```
pub fn is_binary(slice: &[u8]) -> bool {
    slice.starts_with(b"glTF")
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        use std::error::Error;
        write!(f, "{}", self.description())
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
         match *self {
             Error::Deserialize(_) => "deserialization error",
             Error::Glb(ref e) => e.description(),
             Error::Validation(_) => "invalid glTF JSON",
        }
    }
}

impl From<self::glb::Error> for Error {
    fn from(err: self::glb::Error) -> Self {
        Error::Glb(err)
    }
}

impl From<json::Error> for Error {
    fn from(err: json::Error) -> Self {
        Error::Deserialize(err)
    }
}

impl From<Vec<(json::Path, json::validation::Error)>> for Error {
    fn from(errs: Vec<(json::Path, json::validation::Error)>) -> Self {
        Error::Validation(errs)
    }
}
<|endoftext|>


<commit_before>#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results)]

#![feature(into_cow)]

extern crate oauth_client as oauth;

use std::borrow::{Cow, IntoCow};
use std::collections::HashMap;
use oauth::Token;

mod api_twitter_oauth {
    pub const REQUEST_TOKEN: &'static str   = "https://api.twitter.com/oauth/request_token";
    pub const AUTHORIZE: &'static str       = "https://api.twitter.com/oauth/authorize";
    pub const ACCESS_TOKEN: &'static str    = "https://api.twitter.com/oauth/access_token";
}

mod api_twitter_soft {
    pub const UPDATE_STATUS: &'static str = "https://api.twitter.com/1.1/statuses/update.json";
    pub const HOME_TIMELINE: &'static str = "https://api.twitter.com/1.1/statuses/home_timeline.json";
}

fn split_query<'a>(query: &'a str) -> HashMap<Cow<'a, str>, Cow<'a, str>> {
    let mut param = HashMap::new();
    for q in query.split('&') {
        let mut s = q.splitn(2, '=');
        let k = s.next().unwrap();
        let v = s.next().unwrap();
        let _ = param.insert(k.into_cow(), v.into_cow());
    }
    param
}

pub fn get_request_token(consumer: &Token) -> Token<'static> {
    let resp = oauth::get(api_twitter_oauth::REQUEST_TOKEN, consumer, None, None);
    let param = split_query(&resp);
    Token::new(param.get("oauth_token").unwrap().to_string(),
               param.get("oauth_token_secret").unwrap().to_string())
}

pub fn get_authorize_url(request: &Token) -> String {
    format!("{}?oauth_token={}", api_twitter_oauth::AUTHORIZE, request.key)
}

pub fn get_access_token(consumer: &Token, request: &Token, pin: &str) -> Token<'static> {
    let mut param = HashMap::new();
    let _ = param.insert("oauth_verifier".into_cow(), pin.into_cow());
    let resp = oauth::get(api_twitter_oauth::ACCESS_TOKEN, consumer, Some(request), Some(&param));
    let param = split_query(&resp);
    Token::new(param.get("oauth_token").unwrap().to_string(),
               param.get("oauth_token_secret").unwrap().to_string())
}

/// function to update the status
/// This function takes as arguments the consumer key, the access key, and the status (obviously)
pub fn update_status(consumer: &Token, access: &Token, status: &str) {
    let mut param = HashMap::new();
    let _ = param.insert("status".into_cow(), status.into_cow());
    let _ = oauth::post(api_twitter_soft::UPDATE_STATUS, consumer, Some(access), Some(&param));
}
}
<commit_msg>src/lib.rs : Get the last tweets in your console<commit_after>#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results)]

#![feature(into_cow)]

extern crate oauth_client as oauth;

use std::borrow::{Cow, IntoCow};
use std::collections::HashMap;
use oauth::Token;

mod api_twitter_oauth {
    pub const REQUEST_TOKEN: &'static str   = "https://api.twitter.com/oauth/request_token";
    pub const AUTHORIZE: &'static str       = "https://api.twitter.com/oauth/authorize";
    pub const ACCESS_TOKEN: &'static str    = "https://api.twitter.com/oauth/access_token";
}

mod api_twitter_soft {
    pub const UPDATE_STATUS: &'static str = "https://api.twitter.com/1.1/statuses/update.json";
    pub const HOME_TIMELINE: &'static str = "https://api.twitter.com/1.1/statuses/home_timeline.json";
}

fn split_query<'a>(query: &'a str) -> HashMap<Cow<'a, str>, Cow<'a, str>> {
    let mut param = HashMap::new();
    for q in query.split('&') {
        let mut s = q.splitn(2, '=');
        let k = s.next().unwrap();
        let v = s.next().unwrap();
        let _ = param.insert(k.into_cow(), v.into_cow());
    }
    param
}

pub fn get_request_token(consumer: &Token) -> Token<'static> {
    let resp = oauth::get(api_twitter_oauth::REQUEST_TOKEN, consumer, None, None);
    let param = split_query(&resp);
    Token::new(param.get("oauth_token").unwrap().to_string(),
               param.get("oauth_token_secret").unwrap().to_string())
}

pub fn get_authorize_url(request: &Token) -> String {
    format!("{}?oauth_token={}", api_twitter_oauth::AUTHORIZE, request.key)
}

pub fn get_access_token(consumer: &Token, request: &Token, pin: &str) -> Token<'static> {
    let mut param = HashMap::new();
    let _ = param.insert("oauth_verifier".into_cow(), pin.into_cow());
    let resp = oauth::get(api_twitter_oauth::ACCESS_TOKEN, consumer, Some(request), Some(&param));
    let param = split_query(&resp);
    Token::new(param.get("oauth_token").unwrap().to_string(),
               param.get("oauth_token_secret").unwrap().to_string())
}

/// function to update the status
/// This function takes as arguments the consumer key, the access key, and the status (obviously)
pub fn update_status(consumer: &Token, access: &Token, status: &str) {
    let mut param = HashMap::new();
    let _ = param.insert("status".into_cow(), status.into_cow());
    let _ = oauth::post(api_twitter_soft::UPDATE_STATUS, consumer, Some(access), Some(&param));
}

pub fn get_last_tweets(consumer: &Token, access: &Token) {
    let mut param = HashMap::new();
    println!("{:?}", oauth::get(api_twitter_soft::HOME_TIMELINE, consumer, Some(access), Some(&param)));
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![deny(missing_copy_implementations)]

//! Window abstraction

extern crate libc;
extern crate input;
#[macro_use]
extern crate quack;

use input::Input;
use quack::{ ActOn, Action, Associative, Get, GetFrom, Pair };

/// Required to use the event loop.
pub trait Window {
    /// The event type emitted by `poll_event`
    type Event;

    /// Returns true if window should close.
    fn should_close(&self) -> bool;

    /// Gets the size of the window in user coordinates.
    fn size(&self) -> [u32; 2];

    /// Swaps render buffers.
    fn swap_buffers(&mut self);

    /// Polls event from window.
    fn poll_event(&mut self) -> Option<Self::Event>;
}

impl<T> Window for T
    where
        (PollEvent, T): Pair<Data = PollEvent, Object = T>
            + Associative
            + ActOn<Result = Option<<(PollEvent, T) as quack::Associative>::Type>>,
        (ShouldClose, T): Pair<Data = ShouldClose, Object = T>
            + GetFrom,
        (SwapBuffers, T): Pair<Data = SwapBuffers, Object = T>
            + ActOn,
        (Size, T): Pair<Data = Size, Object = T>
            + GetFrom
{
    type Event = <(PollEvent, T) as Associative>::Type;

    #[inline(always)]
    fn should_close(&self) -> bool {
        let ShouldClose(val) = self.get();
        val
    }

    #[inline(always)]
    fn size(&self) -> [u32; 2] {
        let Size(size) = self.get();
        size
    }

    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.action(SwapBuffers);
    }

    #[inline(always)]
    fn poll_event(&mut self) -> Option<<Self as Window>::Event> {
        self.action(PollEvent)
    }
}

/// Trait for OpenGL specific operations.
pub trait OpenGLWindow: Window {
    /// Returns the address of an OpenGL function if it exist, else returns null pointer.
    fn get_proc_address(&mut self, proc_name: &str) -> *const libc::c_void;

    /// Returns true if this context is the current context.
    fn is_current(&self) -> bool;

    /// Make this context current.
    fn make_current(&mut self);
}

/// Whether window should close or not.
#[derive(Copy)]
pub struct ShouldClose(pub bool);

/// The size of the window.
#[derive(Copy)]
pub struct Size(pub [u32; 2]);

/// Tells window to swap buffers.
///
/// ~~~ignore
/// use current::Action;
///
/// ...
/// window.action(SwapBuffers);
/// ~~~
#[derive(Copy)]
pub struct SwapBuffers;

/// Polls event from window.
///
/// ~~~ignore
/// use current::Action;
///
/// ...
/// let e = window.action(PollEvent);
/// ~~~
#[derive(Copy)]
pub struct PollEvent;

/// The title of the window.
pub struct Title(pub String);

/// The anti-aliasing samples when rendering.
#[derive(Copy)]
pub struct Samples(pub u8);

/// Whether window is opened in full screen mode.
#[derive(Copy)]
pub struct Fullscreen(pub bool);

/// Whether to exit when pressing the Esc keyboard button.
#[derive(Copy)]
pub struct ExitOnEsc(pub bool);

/// Whether to capture the mouse cursor.
#[derive(Copy)]
pub struct CaptureCursor(pub bool);

/// The draw size of the window.
#[derive(Copy)]
pub struct DrawSize(pub [u32; 2]);

/// Settings for window behavior.
pub struct WindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window.
    pub size: [u32; 2],
    /// Number samples per pixel (anti-aliasing).
    pub samples: u8,
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl WindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> WindowSettings {
        WindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    should_close: bool,
    title: String,
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: WindowSettings) -> NoWindow {
        let title = settings.title.clone();
        NoWindow {
            should_close: false,
            title: title,
        }
    }
}

quack! {
_window: NoWindow[]
get:
    fn () -> ShouldClose [] { ShouldClose(_window.should_close) }
    fn () -> Size [] { Size([0, 0]) }
    fn () -> DrawSize [] {
        let Size(val) = _window.get();
        DrawSize(val)
    }
    fn () -> Title [] { Title(_window.title.clone()) }
    fn () -> ExitOnEsc [] { ExitOnEsc(false) }
set:
    fn (__: CaptureCursor) [] {}
    fn (val: ShouldClose) [] { _window.should_close = val.0 }
    fn (val: Title) [] { _window.title = val.0; }
    fn (__: ExitOnEsc) [] {}
action:
    fn (__: SwapBuffers) -> () [] {}
    fn (__: PollEvent) -> Option<Input> [] { None }
}

impl Associative for (PollEvent, NoWindow) {
    type Type = Input;
}
<commit_msg>Add ProcAddress type<commit_after>#![deny(missing_docs)]
#![deny(missing_copy_implementations)]

//! Window abstraction

extern crate libc;
extern crate input;
#[macro_use]
extern crate quack;

use input::Input;
use quack::{ ActOn, Action, Associative, Get, GetFrom, Pair };

/// The type of an OpenGL function address.
pub type ProcAddress = *const libc::c_void;

/// Required to use the event loop.
pub trait Window {
    /// The event type emitted by `poll_event`
    type Event;

    /// Returns true if window should close.
    fn should_close(&self) -> bool;

    /// Gets the size of the window in user coordinates.
    fn size(&self) -> [u32; 2];

    /// Swaps render buffers.
    fn swap_buffers(&mut self);

    /// Polls event from window.
    fn poll_event(&mut self) -> Option<Self::Event>;
}

impl<T> Window for T
    where
        (PollEvent, T): Pair<Data = PollEvent, Object = T>
            + Associative
            + ActOn<Result = Option<<(PollEvent, T) as quack::Associative>::Type>>,
        (ShouldClose, T): Pair<Data = ShouldClose, Object = T>
            + GetFrom,
        (SwapBuffers, T): Pair<Data = SwapBuffers, Object = T>
            + ActOn,
        (Size, T): Pair<Data = Size, Object = T>
            + GetFrom
{
    type Event = <(PollEvent, T) as Associative>::Type;

    #[inline(always)]
    fn should_close(&self) -> bool {
        let ShouldClose(val) = self.get();
        val
    }

    #[inline(always)]
    fn size(&self) -> [u32; 2] {
        let Size(size) = self.get();
        size
    }

    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.action(SwapBuffers);
    }

    #[inline(always)]
    fn poll_event(&mut self) -> Option<<Self as Window>::Event> {
        self.action(PollEvent)
    }
}

/// Trait for OpenGL specific operations.
pub trait OpenGLWindow: Window {
    /// Returns the address of an OpenGL function if it exist, else returns null pointer.
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress;

    /// Returns true if this context is the current context.
    fn is_current(&self) -> bool;

    /// Make this context current.
    fn make_current(&mut self);
}

/// Whether window should close or not.
#[derive(Copy)]
pub struct ShouldClose(pub bool);

/// The size of the window.
#[derive(Copy)]
pub struct Size(pub [u32; 2]);

/// Tells window to swap buffers.
///
/// ~~~ignore
/// use current::Action;
///
/// ...
/// window.action(SwapBuffers);
/// ~~~
#[derive(Copy)]
pub struct SwapBuffers;

/// Polls event from window.
///
/// ~~~ignore
/// use current::Action;
///
/// ...
/// let e = window.action(PollEvent);
/// ~~~
#[derive(Copy)]
pub struct PollEvent;

/// The title of the window.
pub struct Title(pub String);

/// The anti-aliasing samples when rendering.
#[derive(Copy)]
pub struct Samples(pub u8);

/// Whether window is opened in full screen mode.
#[derive(Copy)]
pub struct Fullscreen(pub bool);

/// Whether to exit when pressing the Esc keyboard button.
#[derive(Copy)]
pub struct ExitOnEsc(pub bool);

/// Whether to capture the mouse cursor.
#[derive(Copy)]
pub struct CaptureCursor(pub bool);

/// The draw size of the window.
#[derive(Copy)]
pub struct DrawSize(pub [u32; 2]);

/// Settings for window behavior.
pub struct WindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window.
    pub size: [u32; 2],
    /// Number samples per pixel (anti-aliasing).
    pub samples: u8,
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl WindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> WindowSettings {
        WindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    should_close: bool,
    title: String,
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: WindowSettings) -> NoWindow {
        let title = settings.title.clone();
        NoWindow {
            should_close: false,
            title: title,
        }
    }
}

quack! {
_window: NoWindow[]
get:
    fn () -> ShouldClose [] { ShouldClose(_window.should_close) }
    fn () -> Size [] { Size([0, 0]) }
    fn () -> DrawSize [] {
        let Size(val) = _window.get();
        DrawSize(val)
    }
    fn () -> Title [] { Title(_window.title.clone()) }
    fn () -> ExitOnEsc [] { ExitOnEsc(false) }
set:
    fn (__: CaptureCursor) [] {}
    fn (val: ShouldClose) [] { _window.should_close = val.0 }
    fn (val: Title) [] { _window.title = val.0; }
    fn (__: ExitOnEsc) [] {}
action:
    fn (__: SwapBuffers) -> () [] {}
    fn (__: PollEvent) -> Option<Input> [] { None }
}

impl Associative for (PollEvent, NoWindow) {
    type Type = Input;
}
<|endoftext|>