<commit_before>use vecmath::Matrix4;
use gfx;
use gfx::{Device, DeviceHelper, ToSlice};
use device;
use device::draw::CommandBuffer;
use render;

static VERTEX: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120
    uniform mat4 projection, view;

    attribute vec2 tex_coord;
    attribute vec3 color, position;

    varying vec2 v_tex_coord;
    varying vec3 v_color;

    void main() {
        v_tex_coord = tex_coord;
        v_color = color;
        gl_Position = projection * view * vec4(position, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    uniform mat4 projection, view;

    in vec2 tex_coord;
    in vec3 color, position;

    out vec2 v_tex_coord;
    out vec3 v_color;

    void main() {
        v_tex_coord = tex_coord;
        v_color = color;
        gl_Position = projection * view * vec4(position, 1.0);
    }
"
};

static FRAGMENT: gfx::ShaderSource = shaders!{
GLSL_120: b"
    #version 120

    uniform sampler2D s_texture;

    varying vec2 v_tex_coord;
    varying vec3 v_color;

    void main() {
        vec4 tex_color = texture2D(s_texture, v_tex_coord);
        if(tex_color.a == 0.0) // Discard transparent pixels.
            discard;
        gl_FragColor = tex_color * vec4(v_color, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    out vec4 out_color;

    uniform sampler2D s_texture;

    in vec2 v_tex_coord;
    in vec3 v_color;

    void main() {
        vec4 tex_color = texture(s_texture, v_tex_coord);
        if(tex_color.a == 0.0) // Discard transparent pixels.
            discard;
        out_color = tex_color * vec4(v_color, 1.0);
    }
"
};

#[shader_param(Program)]
pub struct ShaderParam {
    pub projection: [[f32, ..4], ..4],
    pub view: [[f32, ..4], ..4],
    pub s_texture: gfx::shade::TextureParam,
}

#[vertex_format]
pub struct Vertex {
    #[name="position"]
    pub xyz: [f32, ..3],
    #[name="tex_coord"]
    pub uv: [f32, ..2],
    #[name="color"]
    pub rgb: [f32, ..3],
}

impl Clone for Vertex {
    fn clone(&self) -> Vertex {
        *self
    }
}

pub struct Buffer {
    buf: gfx::BufferHandle<Vertex>,
    batch: render::batch::RefBatch<_ShaderParamLink, ShaderParam>
}

pub struct Renderer<D: Device<C>, C: CommandBuffer> {
    graphics: gfx::Graphics<D, C>,
    params: ShaderParam,
    frame: gfx::Frame,
    cd: gfx::ClearData,
    prog: device::Handle<u32, device::shade::ProgramInfo>,
    drawstate: gfx::DrawState
}

impl<D: Device<C>, C: CommandBuffer> Renderer<D, C> {
    pub fn new(mut device: D, frame: gfx::Frame, tex: gfx::TextureHandle) -> Renderer<D, C> {
        let sam = device.create_sampler(gfx::tex::SamplerInfo::new(gfx::tex::Scale, gfx::tex::Tile));
        let mut graphics = gfx::Graphics::new(device);

        let params = ShaderParam {
            projection: [[0.0, ..4], ..4],
            view: [[0.0, ..4], ..4],
            s_texture: (tex, Some(sam))
        };
        let prog = graphics.device.link_program(VERTEX.clone(), FRAGMENT.clone()).unwrap();
        let mut drawstate = gfx::DrawState::new().depth(gfx::state::LessEqual, true);
        drawstate.primitive.front_face = gfx::state::Clockwise;

        Renderer {
            graphics: graphics,
            params: params,
            frame: frame,
            cd: gfx::ClearData {
                color: [0.81, 0.8, 1.0, 1.0],
                depth: 1.0,
                stencil: 0,
            },
            prog: prog,
            drawstate: drawstate,
        }
    }

    pub fn set_projection(&mut self, proj_mat: Matrix4<f32>) {
        self.params.projection = proj_mat;
    }

    pub fn set_view(&mut self, view_mat: Matrix4<f32>) {
        self.params.view = view_mat;
    }

    pub fn clear(&mut self) {
        self.graphics.clear(self.cd, gfx::COLOR | gfx::DEPTH, &self.frame);
    }

    pub fn create_buffer(&mut self, data: &[Vertex]) -> Buffer {
        let buf = self.graphics.device.create_buffer(data.len(), gfx::UsageStatic);
        self.graphics.device.update_buffer(buf, data, 0);
        let mesh = gfx::Mesh::from_format(buf, data.len() as u32);
        Buffer {
            buf: buf,
            batch: self.graphics.make_batch(&self.prog, &mesh, mesh.to_slice(gfx::TriangleList),
                                            &self.drawstate).unwrap()
        }
    }

    pub fn delete_buffer(&mut self, buf: Buffer) {
        self.graphics.device.delete_buffer(buf.buf);
    }

    pub fn render(&mut self, buffer: Buffer) {
        self.graphics.draw(&buffer.batch, &self.params, &self.frame);
    }

    pub fn end_frame(&mut self) {
        self.graphics.end_frame();
    }
}
<commit_msg>Renamed `sam` to `sampler`<commit_after>use vecmath::Matrix4;
use gfx;
use gfx::{Device, DeviceHelper, ToSlice};
use device;
use device::draw::CommandBuffer;
use render;

static VERTEX: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120
    uniform mat4 projection, view;

    attribute vec2 tex_coord;
    attribute vec3 color, position;

    varying vec2 v_tex_coord;
    varying vec3 v_color;

    void main() {
        v_tex_coord = tex_coord;
        v_color = color;
        gl_Position = projection * view * vec4(position, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    uniform mat4 projection, view;

    in vec2 tex_coord;
    in vec3 color, position;

    out vec2 v_tex_coord;
    out vec3 v_color;

    void main() {
        v_tex_coord = tex_coord;
        v_color = color;
        gl_Position = projection * view * vec4(position, 1.0);
    }
"
};

static FRAGMENT: gfx::ShaderSource = shaders!{
GLSL_120: b"
    #version 120

    uniform sampler2D s_texture;

    varying vec2 v_tex_coord;
    varying vec3 v_color;

    void main() {
        vec4 tex_color = texture2D(s_texture, v_tex_coord);
        if(tex_color.a == 0.0) // Discard transparent pixels.
            discard;
        gl_FragColor = tex_color * vec4(v_color, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    out vec4 out_color;

    uniform sampler2D s_texture;

    in vec2 v_tex_coord;
    in vec3 v_color;

    void main() {
        vec4 tex_color = texture(s_texture, v_tex_coord);
        if(tex_color.a == 0.0) // Discard transparent pixels.
            discard;
        out_color = tex_color * vec4(v_color, 1.0);
    }
"
};

#[shader_param(Program)]
pub struct ShaderParam {
    pub projection: [[f32, ..4], ..4],
    pub view: [[f32, ..4], ..4],
    pub s_texture: gfx::shade::TextureParam,
}

#[vertex_format]
pub struct Vertex {
    #[name="position"]
    pub xyz: [f32, ..3],
    #[name="tex_coord"]
    pub uv: [f32, ..2],
    #[name="color"]
    pub rgb: [f32, ..3],
}

impl Clone for Vertex {
    fn clone(&self) -> Vertex {
        *self
    }
}

pub struct Buffer {
    buf: gfx::BufferHandle<Vertex>,
    batch: render::batch::RefBatch<_ShaderParamLink, ShaderParam>
}

pub struct Renderer<D: Device<C>, C: CommandBuffer> {
    graphics: gfx::Graphics<D, C>,
    params: ShaderParam,
    frame: gfx::Frame,
    cd: gfx::ClearData,
    prog: device::Handle<u32, device::shade::ProgramInfo>,
    drawstate: gfx::DrawState
}

impl<D: Device<C>, C: CommandBuffer> Renderer<D, C> {
    pub fn new(mut device: D, frame: gfx::Frame, tex: gfx::TextureHandle) -> Renderer<D, C> {
        let sampler = device.create_sampler(gfx::tex::SamplerInfo::new(gfx::tex::Scale, gfx::tex::Tile));
        let mut graphics = gfx::Graphics::new(device);

        let params = ShaderParam {
            projection: [[0.0, ..4], ..4],
            view: [[0.0, ..4], ..4],
            s_texture: (tex, Some(sampler))
        };
        let prog = graphics.device.link_program(VERTEX.clone(), FRAGMENT.clone()).unwrap();
        let mut drawstate = gfx::DrawState::new().depth(gfx::state::LessEqual, true);
        drawstate.primitive.front_face = gfx::state::Clockwise;

        Renderer {
            graphics: graphics,
            params: params,
            frame: frame,
            cd: gfx::ClearData {
                color: [0.81, 0.8, 1.0, 1.0],
                depth: 1.0,
                stencil: 0,
            },
            prog: prog,
            drawstate: drawstate,
        }
    }

    pub fn set_projection(&mut self, proj_mat: Matrix4<f32>) {
        self.params.projection = proj_mat;
    }

    pub fn set_view(&mut self, view_mat: Matrix4<f32>) {
        self.params.view = view_mat;
    }

    pub fn clear(&mut self) {
        self.graphics.clear(self.cd, gfx::COLOR | gfx::DEPTH, &self.frame);
    }

    pub fn create_buffer(&mut self, data: &[Vertex]) -> Buffer {
        let buf = self.graphics.device.create_buffer(data.len(), gfx::UsageStatic);
        self.graphics.device.update_buffer(buf, data, 0);
        let mesh = gfx::Mesh::from_format(buf, data.len() as u32);
        Buffer {
            buf: buf,
            batch: self.graphics.make_batch(&self.prog, &mesh, mesh.to_slice(gfx::TriangleList),
                                            &self.drawstate).unwrap()
        }
    }

    pub fn delete_buffer(&mut self, buf: Buffer) {
        self.graphics.device.delete_buffer(buf.buf);
    }

    pub fn render(&mut self, buffer: Buffer) {
        self.graphics.draw(&buffer.batch, &self.params, &self.frame);
    }

    pub fn end_frame(&mut self) {
        self.graphics.end_frame();
    }
}
<|endoftext|>


<commit_before>use std::slice::Iter;
use std::convert::Into;
use calx::{color, V2, Dir6, Rgba, clamp};
use calx::backend::{Canvas, CanvasUtil, RenderTarget, mesh};
use world::{Location, Unchart};
use viewutil::{FX_Z, chart_to_screen};
use tilecache;
use tilecache::tile;

trait WorldSprite {
    fn update(&mut self);
    fn is_alive(&self) -> bool;

    fn footprint<'a>(&'a self) -> Iter<'a, Location>;
    // XXX: Locked to the type of iterator Vecs return for now. It's assumed
    // that implementers use a Vec to cache the footprint points internally.

    fn draw(&self, chart: &Location, ctx: &mut Canvas);
    // XXX: Can't parametrize to Unchart since trait objects can't have
    // parameterized methods.
}

pub struct WorldSprites {
    sprites: Vec<Box<WorldSprite + 'static>>,
}

impl WorldSprites {
    pub fn new() -> WorldSprites {
        WorldSprites { sprites: vec!() }
    }

    pub fn add(&mut self, spr: Box<WorldSprite + 'static>) {
        self.sprites.push(spr);
    }

    pub fn draw<F>(&self, is_visible: F, chart: &Location, ctx: &mut Canvas)
        where F: Fn(V2<i32>) -> bool
    {
        // XXX: Ineffective if there are many sprites outside the visible
        // area.
        for s in self.sprites.iter() {
            for &loc in s.footprint() {
                if chart.chart_pos(loc).map_or(false, |p| is_visible(p)) {
                    s.draw(chart, ctx);
                    break;
                }
            }
        }
    }

    pub fn update(&mut self) {
        for spr in self.sprites.iter_mut() {
            spr.update();
        }
        self.sprites.retain(|spr| spr.is_alive());
    }
}

pub struct BeamSprite {
    p1: Location,
    p2: Location,
    life: i32,
    footprint: Vec<Location>,
}

impl BeamSprite {
    pub fn new(p1: Location, p2: Location, life: i32) -> BeamSprite {
        BeamSprite {
            p1: p1,
            p2: p2,
            life: life,
            // TODO: Generate intervening points into the footprint. With this
            // footprint you can't see the beam unless either the start or the
            // end point is visible.
            footprint: vec![p1, p2],
        }
    }
}

impl WorldSprite for BeamSprite {
    fn update(&mut self) {
        self.life -= 1;
    }
    fn is_alive(&self) -> bool {
        self.life >= 0
    }
    fn footprint<'a>(&'a self) -> Iter<'a, Location> {
        self.footprint.iter()
    }
    fn draw(&self, chart: &Location, ctx: &mut Canvas) {
        if let (Some(p1), Some(p2)) = (chart.chart_pos(self.p1), chart.chart_pos(self.p2)) {
            let pixel_adjust = V2(0.0, -2.0);
            ctx.draw_line(2.0,
                          chart_to_screen(p1) + pixel_adjust,
                          chart_to_screen(p2) + pixel_adjust,
                          FX_Z,
                          color::ORANGE);
        }
    }
}

pub struct GibSprite {
    loc: Location,
    life: i32,
    footprint: Vec<Location>,
}

impl GibSprite {
    pub fn new(loc: Location) -> GibSprite {
        GibSprite {
            loc: loc,
            life: 11,
            footprint: vec![loc],
        }
    }
}

impl WorldSprite for GibSprite {
    fn update(&mut self) {
        self.life -= 1;
    }
    fn is_alive(&self) -> bool {
        self.life >= 0
    }
    fn footprint<'a>(&'a self) -> Iter<'a, Location> {
        self.footprint.iter()
    }
    fn draw(&self, chart: &Location, ctx: &mut Canvas) {
        if let Some(p) = chart.chart_pos(self.loc) {
            // TODO: Robust anim cycle with clamping.
            let idx = tile::SPLATTER + ((11 - self.life) / 3) as usize;
            ctx.draw_image(tilecache::get(idx),
                           chart_to_screen(p),
                           FX_Z,
                           color::RED,
                           color::BLACK);
        }
    }
}

pub struct ExplosionSprite {
    loc: Location,
    life: i32,
    footprint: Vec<Location>,
}

impl ExplosionSprite {
    pub fn new(loc: Location) -> ExplosionSprite {
        ExplosionSprite {
            loc: loc,
            life: 12,
            footprint: Dir6::iter().map(|d| loc + d.to_v2()).chain(Some(loc).into_iter()).collect(),
        }
    }
}

impl WorldSprite for ExplosionSprite {
    fn update(&mut self) {
        self.life -= 1;
    }
    fn is_alive(&self) -> bool {
        self.life >= 0
    }
    fn footprint<'a>(&'a self) -> Iter<'a, Location> {
        self.footprint.iter()
    }
    fn draw(&self, chart: &Location, ctx: &mut Canvas) {
        if let Some(p) = chart.chart_pos(self.loc) {
            let center = chart_to_screen(p);

            // Growing in [0.0, 1.0].
            let t = clamp(0.0, 1.0, (12 - self.life) as f32 / 4.0);
            let t2 = clamp(0.0, 1.0, (8 - self.life) as f32 / 4.0);

            hexagon(ctx,
                    center,
                    FX_Z,
                    color::ORANGE,
                    color::RED,
                    t2 * 1.8,
                    t * 2.0);
        }
    }
}

fn hexagon<C: Into<Rgba> + Copy>(ctx: &mut Canvas,
                                 center: V2<f32>,
                                 z: f32,
                                 color_inner: C,
                                 color_outer: C,
                                 inner_radius: f32,
                                 outer_radius: f32) {
    let tex = ctx.solid_tex_coord();
    static HEXAGON: [V2<f32>; 6] = [V2(-8.0, -4.0), V2(0.0, -8.0), V2(8.0, -4.0), V2(8.0, 4.0), V2(0.0, 8.0), V2(-8.0, 4.0)];

    let mut vertices = Vec::new();

    let color_inner: Rgba = color_inner.into();
    let color_outer: Rgba = color_outer.into();

    // Inner vertices
    for p in HEXAGON.iter() {
        vertices.push(mesh::Vertex::new(center + (*p * inner_radius),
                                        z,
                                        tex,
                                        color_inner,
                                        color::BLACK));
    }

    // Outer vertices
    for p in HEXAGON.iter() {
        vertices.push(mesh::Vertex::new(center + (*p * outer_radius),
                                        z,
                                        tex,
                                        color_outer,
                                        color::BLACK));
    }

    let mut faces = Vec::new();
    for i in 0..6 {
        let i2 = (i + 1) % 6;
        faces.push([i, 6 + i2, i2]);
        faces.push([i, 6 + i, 6 + i2]);
    }

    ctx.add_mesh(vertices, faces);
}
<commit_msg>Fix trait visibility<commit_after>use std::slice::Iter;
use std::convert::Into;
use calx::{color, V2, Dir6, Rgba, clamp};
use calx::backend::{Canvas, CanvasUtil, RenderTarget, mesh};
use world::{Location, Unchart};
use viewutil::{FX_Z, chart_to_screen};
use tilecache;
use tilecache::tile;

pub trait WorldSprite {
    fn update(&mut self);
    fn is_alive(&self) -> bool;

    fn footprint<'a>(&'a self) -> Iter<'a, Location>;
    // XXX: Locked to the type of iterator Vecs return for now. It's assumed
    // that implementers use a Vec to cache the footprint points internally.

    fn draw(&self, chart: &Location, ctx: &mut Canvas);
    // XXX: Can't parametrize to Unchart since trait objects can't have
    // parameterized methods.
}

pub struct WorldSprites {
    sprites: Vec<Box<WorldSprite + 'static>>,
}

impl WorldSprites {
    pub fn new() -> WorldSprites {
        WorldSprites { sprites: vec!() }
    }

    pub fn add(&mut self, spr: Box<WorldSprite + 'static>) {
        self.sprites.push(spr);
    }

    pub fn draw<F>(&self, is_visible: F, chart: &Location, ctx: &mut Canvas)
        where F: Fn(V2<i32>) -> bool
    {
        // XXX: Ineffective if there are many sprites outside the visible
        // area.
        for s in self.sprites.iter() {
            for &loc in s.footprint() {
                if chart.chart_pos(loc).map_or(false, |p| is_visible(p)) {
                    s.draw(chart, ctx);
                    break;
                }
            }
        }
    }

    pub fn update(&mut self) {
        for spr in self.sprites.iter_mut() {
            spr.update();
        }
        self.sprites.retain(|spr| spr.is_alive());
    }
}

pub struct BeamSprite {
    p1: Location,
    p2: Location,
    life: i32,
    footprint: Vec<Location>,
}

impl BeamSprite {
    pub fn new(p1: Location, p2: Location, life: i32) -> BeamSprite {
        BeamSprite {
            p1: p1,
            p2: p2,
            life: life,
            // TODO: Generate intervening points into the footprint. With this
            // footprint you can't see the beam unless either the start or the
            // end point is visible.
            footprint: vec![p1, p2],
        }
    }
}

impl WorldSprite for BeamSprite {
    fn update(&mut self) {
        self.life -= 1;
    }
    fn is_alive(&self) -> bool {
        self.life >= 0
    }
    fn footprint<'a>(&'a self) -> Iter<'a, Location> {
        self.footprint.iter()
    }
    fn draw(&self, chart: &Location, ctx: &mut Canvas) {
        if let (Some(p1), Some(p2)) = (chart.chart_pos(self.p1), chart.chart_pos(self.p2)) {
            let pixel_adjust = V2(0.0, -2.0);
            ctx.draw_line(2.0,
                          chart_to_screen(p1) + pixel_adjust,
                          chart_to_screen(p2) + pixel_adjust,
                          FX_Z,
                          color::ORANGE);
        }
    }
}

pub struct GibSprite {
    loc: Location,
    life: i32,
    footprint: Vec<Location>,
}

impl GibSprite {
    pub fn new(loc: Location) -> GibSprite {
        GibSprite {
            loc: loc,
            life: 11,
            footprint: vec![loc],
        }
    }
}

impl WorldSprite for GibSprite {
    fn update(&mut self) {
        self.life -= 1;
    }
    fn is_alive(&self) -> bool {
        self.life >= 0
    }
    fn footprint<'a>(&'a self) -> Iter<'a, Location> {
        self.footprint.iter()
    }
    fn draw(&self, chart: &Location, ctx: &mut Canvas) {
        if let Some(p) = chart.chart_pos(self.loc) {
            // TODO: Robust anim cycle with clamping.
            let idx = tile::SPLATTER + ((11 - self.life) / 3) as usize;
            ctx.draw_image(tilecache::get(idx),
                           chart_to_screen(p),
                           FX_Z,
                           color::RED,
                           color::BLACK);
        }
    }
}

pub struct ExplosionSprite {
    loc: Location,
    life: i32,
    footprint: Vec<Location>,
}

impl ExplosionSprite {
    pub fn new(loc: Location) -> ExplosionSprite {
        ExplosionSprite {
            loc: loc,
            life: 12,
            footprint: Dir6::iter().map(|d| loc + d.to_v2()).chain(Some(loc).into_iter()).collect(),
        }
    }
}

impl WorldSprite for ExplosionSprite {
    fn update(&mut self) {
        self.life -= 1;
    }
    fn is_alive(&self) -> bool {
        self.life >= 0
    }
    fn footprint<'a>(&'a self) -> Iter<'a, Location> {
        self.footprint.iter()
    }
    fn draw(&self, chart: &Location, ctx: &mut Canvas) {
        if let Some(p) = chart.chart_pos(self.loc) {
            let center = chart_to_screen(p);

            // Growing in [0.0, 1.0].
            let t = clamp(0.0, 1.0, (12 - self.life) as f32 / 4.0);
            let t2 = clamp(0.0, 1.0, (8 - self.life) as f32 / 4.0);

            hexagon(ctx,
                    center,
                    FX_Z,
                    color::ORANGE,
                    color::RED,
                    t2 * 1.8,
                    t * 2.0);
        }
    }
}

fn hexagon<C: Into<Rgba> + Copy>(ctx: &mut Canvas,
                                 center: V2<f32>,
                                 z: f32,
                                 color_inner: C,
                                 color_outer: C,
                                 inner_radius: f32,
                                 outer_radius: f32) {
    let tex = ctx.solid_tex_coord();
    static HEXAGON: [V2<f32>; 6] = [V2(-8.0, -4.0), V2(0.0, -8.0), V2(8.0, -4.0), V2(8.0, 4.0), V2(0.0, 8.0), V2(-8.0, 4.0)];

    let mut vertices = Vec::new();

    let color_inner: Rgba = color_inner.into();
    let color_outer: Rgba = color_outer.into();

    // Inner vertices
    for p in HEXAGON.iter() {
        vertices.push(mesh::Vertex::new(center + (*p * inner_radius),
                                        z,
                                        tex,
                                        color_inner,
                                        color::BLACK));
    }

    // Outer vertices
    for p in HEXAGON.iter() {
        vertices.push(mesh::Vertex::new(center + (*p * outer_radius),
                                        z,
                                        tex,
                                        color_outer,
                                        color::BLACK));
    }

    let mut faces = Vec::new();
    for i in 0..6 {
        let i2 = (i + 1) % 6;
        faces.push([i, 6 + i2, i2]);
        faces.push([i, 6 + i, 6 + i2]);
    }

    ctx.add_mesh(vertices, faces);
}
<|endoftext|>


<commit_before>use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo};
use frame::frame_parser;
use utility::{
  ErrorKind, ByteStream, ReadStream, Sample, SampleSize, StreamProducer,
  many_metadata,
};

use std::io;
use std::usize;
use std::fs::File;

/// FLAC stream that decodes and hold file information.
pub struct Stream
 {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  producer: P,
}

/// Alias for a FLAC stream produced from `Read`.
pub type StreamReader<R>  = Stream<ReadStream<R>>;

/// Alias for a FLAC stream produced from a byte stream buffer.
pub type StreamBuffer<'a> = Stream<ByteStream<'a>>;

impl
 Stream
 where P: StreamProducer {
  /// Constructor for the default state of a FLAC stream.
  #[inline]
  pub fn new<R: io::Read>(reader: R) -> Result<StreamReader<R>, ErrorKind> {
    let producer = ReadStream::new(reader);

    Stream::from_stream_producer(producer)
  }

  /// Returns information for the current stream.
  #[inline]
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  #[inline]
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::NotFound)` is returned when the given
  ///   filename isn't found.
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_file(filename: &str) -> Result<StreamReader<File>, ErrorKind> {
    File::open(filename).map_err(|e| ErrorKind::IO(e.kind()))
                        .and_then(|file| {
      let producer = ReadStream::new(file);

      Stream::from_stream_producer(producer)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_buffer(buffer: &[u8]) -> Result<StreamBuffer, ErrorKind> {
    let producer = ByteStream::new(buffer);

    Stream::from_stream_producer(producer)
  }

  fn from_stream_producer(mut producer: P) -> Result<Self, ErrorKind> {
    let mut stream_info = Default::default();
    let mut metadata    = Vec::new();

    many_metadata(&mut producer, |block| {
      if let metadata::Data::StreamInfo(info) = block.data {
        stream_info = info;
      } else {
        metadata.push(block);
      }
    }).map(|_| {
      Stream {
        info: stream_info,
        metadata: metadata,
        producer: producer,
      }
    })
  }

  /// Returns an iterator over the decoded samples.
  #[inline]
  pub fn iter<S: SampleSize>(&mut self) -> Iter
 {
    let samples_left = self.info.total_samples;
    let channels     = self.info.channels as usize;
    let block_size   = self.info.max_block_size as usize;
    let buffer_size  = block_size * channels;

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
      buffer: vec![S::Extended::from_i8(0); buffer_size]
    }
  }

  fn next_frame<S>(&mut self, buffer: &mut [S]) -> Option<usize>
   where S: Sample {
    let stream_info = &self.info;

    loop {
      match self.producer.parse(|i| frame_parser(i, stream_info, buffer)) {
        Ok(frame)                => {
          let channels    = frame.header.channels as usize;
          let block_size  = frame.header.block_size as usize;
          let mut channel = 0;

          for subframe in &frame.subframes[0..channels] {
            let start  = channel * block_size;
            let end    = (channel + 1) * block_size;
            let output = &mut buffer[start..end];

            subframe::decode(&subframe, block_size, output);

            channel += 1;
          }

          frame::decode(frame.header.channel_assignment, buffer);

          return Some(block_size);
        }
        Err(ErrorKind::Continue) => continue,
        Err(_)                   => return None,
      }
    }
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P, S>
 where P: 'a + StreamProducer,
       S: Sample{
  stream: &'a mut Stream
,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
  buffer: Vec<S>,
}

impl<'a, P, S> Iterator for Iter<'a, P, S>
 where P: StreamProducer,
       S: Sample {
  type Item = S::Normal;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      let buffer = &mut self.buffer;

      if let Some(block_size) = self.stream.next_frame(buffer) {
        self.sample_index = 0;
        self.block_size   = block_size;
      } else {
        return None;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = unsafe { *self.buffer.get_unchecked(index) };

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    S::to_normal(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

//impl<'a, P, S> IntoIterator for &'a mut Stream

// where P: StreamProducer,
//       S: Sample {
//  type Item     = S::Normal;
//  type IntoIter = Iter<'a, P, S>;
//
//  #[inline]
//  fn into_iter(self) -> Self::IntoIter {
//    self.iter()
//  }
//}
<commit_msg>Change loop over subframes into a single iterator<commit_after>use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo};
use frame::frame_parser;
use utility::{
  ErrorKind, ByteStream, ReadStream, Sample, SampleSize, StreamProducer,
  many_metadata,
};

use std::io;
use std::usize;
use std::fs::File;

/// FLAC stream that decodes and hold file information.
pub struct Stream
 {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  producer: P,
}

/// Alias for a FLAC stream produced from `Read`.
pub type StreamReader<R>  = Stream<ReadStream<R>>;

/// Alias for a FLAC stream produced from a byte stream buffer.
pub type StreamBuffer<'a> = Stream<ByteStream<'a>>;

impl
 Stream
 where P: StreamProducer {
  /// Constructor for the default state of a FLAC stream.
  #[inline]
  pub fn new<R: io::Read>(reader: R) -> Result<StreamReader<R>, ErrorKind> {
    let producer = ReadStream::new(reader);

    Stream::from_stream_producer(producer)
  }

  /// Returns information for the current stream.
  #[inline]
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  #[inline]
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::NotFound)` is returned when the given
  ///   filename isn't found.
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_file(filename: &str) -> Result<StreamReader<File>, ErrorKind> {
    File::open(filename).map_err(|e| ErrorKind::IO(e.kind()))
                        .and_then(|file| {
      let producer = ReadStream::new(file);

      Stream::from_stream_producer(producer)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_buffer(buffer: &[u8]) -> Result<StreamBuffer, ErrorKind> {
    let producer = ByteStream::new(buffer);

    Stream::from_stream_producer(producer)
  }

  fn from_stream_producer(mut producer: P) -> Result<Self, ErrorKind> {
    let mut stream_info = Default::default();
    let mut metadata    = Vec::new();

    many_metadata(&mut producer, |block| {
      if let metadata::Data::StreamInfo(info) = block.data {
        stream_info = info;
      } else {
        metadata.push(block);
      }
    }).map(|_| {
      Stream {
        info: stream_info,
        metadata: metadata,
        producer: producer,
      }
    })
  }

  /// Returns an iterator over the decoded samples.
  #[inline]
  pub fn iter<S: SampleSize>(&mut self) -> Iter
 {
    let samples_left = self.info.total_samples;
    let channels     = self.info.channels as usize;
    let block_size   = self.info.max_block_size as usize;
    let buffer_size  = block_size * channels;

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
      buffer: vec![S::Extended::from_i8(0); buffer_size]
    }
  }

  fn next_frame<S>(&mut self, buffer: &mut [S]) -> Option<usize>
   where S: Sample {
    let stream_info = &self.info;

    loop {
      match self.producer.parse(|i| frame_parser(i, stream_info, buffer)) {
        Ok(frame)                => {
          let channels   = frame.header.channels as usize;
          let block_size = frame.header.block_size as usize;
          let subframes  = frame.subframes[0..channels].iter();

          for (channel, subframe) in subframes.enumerate() {
            let start  = channel * block_size;
            let end    = (channel + 1) * block_size;
            let output = &mut buffer[start..end];

            subframe::decode(&subframe, block_size, output);
          }

          frame::decode(frame.header.channel_assignment, buffer);

          return Some(block_size);
        }
        Err(ErrorKind::Continue) => continue,
        Err(_)                   => return None,
      }
    }
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P, S>
 where P: 'a + StreamProducer,
       S: Sample{
  stream: &'a mut Stream
,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
  buffer: Vec<S>,
}

impl<'a, P, S> Iterator for Iter<'a, P, S>
 where P: StreamProducer,
       S: Sample {
  type Item = S::Normal;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      let buffer = &mut self.buffer;

      if let Some(block_size) = self.stream.next_frame(buffer) {
        self.sample_index = 0;
        self.block_size   = block_size;
      } else {
        return None;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = unsafe { *self.buffer.get_unchecked(index) };

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    S::to_normal(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

//impl<'a, P, S> IntoIterator for &'a mut Stream

// where P: StreamProducer,
//       S: Sample {
//  type Item     = S::Normal;
//  type IntoIter = Iter<'a, P, S>;
//
//  #[inline]
//  fn into_iter(self) -> Self::IntoIter {
//    self.iter()
//  }
//}
<|endoftext|>


<commit_before>use std::os::raw::{c_int, c_double, c_void};

use ffi;
use base::*;

extern "C" fn wrapper<T: Fn(OutStream, i32, i32)>(raw_out: *mut ffi::SoundIoOutStream,
                                                  min: c_int,
                                                  max: c_int) {
    let out = OutStream::new(raw_out);
    let cb_ptr = unsafe { (*out.stream).userdata as *const *const T };
    let cb: &T = unsafe { &*(*cb_ptr) };
    cb(out, min, max);
}

pub struct OutStream {
    // TODO: make this private again
    // - add a struct that contains the registered callback closures, this could look like this:
    // struct Callbacks<W: Fn(OutStream, i32, i32), U: Fn(OutStream), E: Fn(OutStream, SioError)> {
    //      // maybe Option<Box<W>>
    //      write_callback: Option<W>,
    //      underflow_callback: Option<U>,
    //      error_callback: Option<E>,
    // }
    // impl Default for Callbacks<W: Fn(OutStream, i32, i32), U: Fn(OutStream), E: Fn(OutStream, SioError)> {
    //      fn default() -> Self {
    //          Callbacks {
    //              write_callback: None,
    //              underflow_callback: None,
    //              error_callback: None,
    //          }
    //      }
    // }
    pub stream: *mut ffi::SoundIoOutStream,
}
impl OutStream {
    pub fn new(raw_stream: *mut ffi::SoundIoOutStream) -> Self {
        OutStream { stream: raw_stream }
    }

    pub fn open(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_open(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn start(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_start(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn register_write_callback<T: Fn(OutStream, i32, i32)>(&mut self, callback: Box<T>) {
        let userdata = &*callback as *const T as *mut c_void;
        unsafe {
            (*self.stream).userdata = userdata;
            (*self.stream).write_callback = Some(wrapper::<T>);
        }
    }

    pub fn begin_write(&self,
                       areas: *mut *mut ffi::SoundIoChannelArea,
                       frame_count: *mut c_int)
                       -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_begin_write(self.stream, areas, frame_count) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn end_write(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_end_write(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn clear_buffer(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_clear_buffer(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn pause(&self, pause: bool) -> Option<ffi::SioError> {
        let pause_c_bool = match pause {
            true => 1u8,
            false => 0u8,
        };
        match unsafe { ffi::soundio_outstream_pause(self.stream, pause_c_bool) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn get_latency(&self) -> Result<f64, ffi::SioError> {
        let mut latency = 0.0f64;
        match unsafe {
            ffi::soundio_outstream_get_latency(self.stream, &mut latency as *mut c_double)
        } {
            ffi::SioError::None => Ok(latency),
            err @ _ => Err(err),
        }

    }

    pub fn current_format(&self) -> Result<ffi::SioFormat, ffi::SioError> {
        match unsafe { (*self.stream).format } {
            ffi::SioFormat::Invalid => Err(ffi::SioError::Invalid),
            fmt @ _ => Ok(fmt),
        }
    }

    pub fn get_layout(&self) -> ChannelLayout {
        ChannelLayout::new(unsafe { &(*self.stream).layout })
    }

    pub fn get_sample_rate(&self) -> i32 {
        unsafe { (*self.stream).sample_rate as i32 }
    }

    pub fn get_device(&self) -> Device {
        let dev = Device::new(unsafe { (*self.stream).device });
        dev.inc_ref();
        dev
    }

    pub fn destroy(&self) {
        unsafe { ffi::soundio_outstream_destroy(self.stream) }
    }
}
impl Drop for OutStream {
    fn drop(&mut self) {
        // TODO: call destroy manually.
        // OutStream will get dropped each time a new
        // struct is created from the same *mut pointer.
    }
}
<commit_msg>Fix callback closure by removing unnecessary casts<commit_after>use std::os::raw::{c_int, c_double, c_void};

use ffi;
use base::*;

extern "C" fn wrapper<T: Fn(OutStream, i32, i32)>(raw_out: *mut ffi::SoundIoOutStream,
                                                  min: c_int,
                                                  max: c_int) {
    let out = OutStream::new(raw_out);
    let cb_ptr = unsafe { (*out.stream).userdata as *const T };
    let cb: &T = unsafe { &*cb_ptr };
    cb(out, min, max);
}

pub struct OutStream {
    // TODO: make this private again
    // - add a struct that contains the registered callback closures, this could look like this:
    // struct Callbacks<W: Fn(OutStream, i32, i32), U: Fn(OutStream), E: Fn(OutStream, SioError)> {
    //      // maybe Option<Box<W>>
    //      write_callback: Option<W>,
    //      underflow_callback: Option<U>,
    //      error_callback: Option<E>,
    // }
    // impl Default for Callbacks<W: Fn(OutStream, i32, i32), U: Fn(OutStream), E: Fn(OutStream, SioError)> {
    //      fn default() -> Self {
    //          Callbacks {
    //              write_callback: None,
    //              underflow_callback: None,
    //              error_callback: None,
    //          }
    //      }
    // }
    pub stream: *mut ffi::SoundIoOutStream,
}
impl OutStream {
    pub fn new(raw_stream: *mut ffi::SoundIoOutStream) -> Self {
        OutStream { stream: raw_stream }
    }

    pub fn open(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_open(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn start(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_start(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn register_write_callback<T: Fn(OutStream, i32, i32)>(&mut self, callback: Box<T>) {
        let userdata = &*callback as *const T as *mut c_void;
        unsafe {
            (*self.stream).userdata = userdata;
            (*self.stream).write_callback = Some(wrapper::<T>);
        }
    }

    pub fn begin_write(&self,
                       areas: *mut *mut ffi::SoundIoChannelArea,
                       frame_count: *mut c_int)
                       -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_begin_write(self.stream, areas, frame_count) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn end_write(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_end_write(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn clear_buffer(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_clear_buffer(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn pause(&self, pause: bool) -> Option<ffi::SioError> {
        let pause_c_bool = match pause {
            true => 1u8,
            false => 0u8,
        };
        match unsafe { ffi::soundio_outstream_pause(self.stream, pause_c_bool) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn get_latency(&self) -> Result<f64, ffi::SioError> {
        let mut latency = 0.0f64;
        match unsafe {
            ffi::soundio_outstream_get_latency(self.stream, &mut latency as *mut c_double)
        } {
            ffi::SioError::None => Ok(latency),
            err @ _ => Err(err),
        }

    }

    pub fn current_format(&self) -> Result<ffi::SioFormat, ffi::SioError> {
        match unsafe { (*self.stream).format } {
            ffi::SioFormat::Invalid => Err(ffi::SioError::Invalid),
            fmt @ _ => Ok(fmt),
        }
    }

    pub fn get_layout(&self) -> ChannelLayout {
        ChannelLayout::new(unsafe { &(*self.stream).layout })
    }

    pub fn get_sample_rate(&self) -> i32 {
        unsafe { (*self.stream).sample_rate as i32 }
    }

    pub fn get_device(&self) -> Device {
        let dev = Device::new(unsafe { (*self.stream).device });
        dev.inc_ref();
        dev
    }

    pub fn destroy(&self) {
        unsafe { ffi::soundio_outstream_destroy(self.stream) }
    }
}
impl Drop for OutStream {
    fn drop(&mut self) {
        // TODO: call destroy manually.
        // OutStream will get dropped each time a new
        // struct is created from the same *mut pointer.
    }
}
<|endoftext|>


<commit_before>
use color::Color;
use dimensions::Dimensions;
use mouse::Mouse;
use point::Point;
use rectangle;
use graphics::Graphics;
use graphics::character::CharacterCache;
use ui_context::{ UIID, UiContext };
use widget::Widget;

/// Represents the state of the Toggle widget.
#[derive(PartialEq, Clone, Copy)]
pub enum State {
    Normal,
    Highlighted,
    Clicked,
}

impl State {
    /// Return the associated Rectangle state.
    fn as_rectangle_state(&self) -> rectangle::State {
        match self {
            &State::Normal => rectangle::State::Normal,
            &State::Highlighted => rectangle::State::Highlighted,
            &State::Clicked => rectangle::State::Clicked,
        }
    }
}

widget_fns!(Toggle, State, Widget::Toggle(State::Normal));

/// Check the current state of the button.
fn get_new_state(is_over: bool,
                 prev: State,
                 mouse: Mouse) -> State {
    use mouse::ButtonState::{Down, Up};
    use self::State::{Normal, Highlighted, Clicked};
    match (is_over, prev, mouse.left) {
        (true,  Normal,  Down) => Normal,
        (true,  _,       Down) => Clicked,
        (true,  _,       Up)   => Highlighted,
        (false, Clicked, Down) => Clicked,
        _                      => Normal,
    }
}

/// A context on which the builder pattern can be implemented.
pub struct Toggle<'a, F> {
    ui_id: UIID,
    pos: Point,
    dim: Dimensions,
    maybe_callback: Option<F>,
    maybe_color: Option<Color>,
    maybe_frame: Option<f64>,
    maybe_frame_color: Option<Color>,
    maybe_label: Option<&'a str>,
    maybe_label_color: Option<Color>,
    maybe_label_font_size: Option<u32>,
    value: bool,
}

impl<'a, F> Toggle<'a, F> {

    /// Create a toggle context to be built upon.
    pub fn new(ui_id: UIID, value: bool) -> Toggle<'a, F> {
        Toggle {
            ui_id: ui_id,
            pos: [0.0, 0.0],
            dim: [64.0, 64.0],
            maybe_callback: None,
            maybe_color: None,
            maybe_frame: None,
            maybe_frame_color: None,
            maybe_label: None,
            maybe_label_color: None,
            maybe_label_font_size: None,
            value: value,
        }
    }

}

/*
quack! {
    toggle: Toggle['a, F]
    get:
        fn () -> Size [] { Size(toggle.dim) }
        fn () -> DefaultWidgetState [] {
            DefaultWidgetState(Widget::Toggle(State::Normal))
        }
        fn () -> Id [] { Id(toggle.ui_id) }
    set:
        fn (val: Color) [] { toggle.maybe_color = Some(val) }
        fn (val: Callback<F>) [where F: FnMut(bool) + 'a] {
            toggle.maybe_callback = Some(val.0)
        }
        fn (val: FrameColor) [] { toggle.maybe_frame_color = Some(val.0) }
        fn (val: FrameWidth) [] { toggle.maybe_frame = Some(val.0) }
        fn (val: LabelText<'a>) [] { toggle.maybe_label = Some(val.0) }
        fn (val: LabelColor) [] { toggle.maybe_label_color = Some(val.0) }
        fn (val: LabelFontSize) [] {
            toggle.maybe_label_font_size = Some(val.0)
        }
        fn (val: Position) [] { toggle.pos = val.0 }
        fn (val: Size) [] { toggle.dim = val.0 }
    action:
}
*/

impl<'a, F> ::draw::Drawable for Toggle<'a, F> where F: FnMut(bool) + 'a {
    fn draw<B, C>(&mut self, uic: &mut UiContext<C>, graphics: &mut B)
        where
            B: Graphics<Texture = <C as CharacterCache>::Texture>,
            C: CharacterCache
    {
        let color = self.maybe_color.unwrap_or(uic.theme.shape_color);
        let color = match self.value {
            true => color,
            false => color * Color::new(0.1, 0.1, 0.1, 1.0)
        };
        let state = *get_state(uic, self.ui_id);
        let mouse = uic.get_mouse_state();
        let is_over = rectangle::is_over(self.pos, mouse.pos, self.dim);
        let new_state = get_new_state(is_over, state, mouse);
        let rect_state = new_state.as_rectangle_state();
        match self.maybe_callback {
            Some(ref mut callback) => {
                match (is_over, state, new_state) {
                    (true, State::Clicked, State::Highlighted) =>
                        (*callback)(match self.value { true => false, false => true }),
                    _ => (),
                }
            }, None => (),
        }
        let frame_w = self.maybe_frame.unwrap_or(uic.theme.frame_width);
        let maybe_frame = match frame_w > 0.0 {
            true => Some((frame_w, self.maybe_frame_color.unwrap_or(uic.theme.frame_color))),
            false => None,
        };
        match self.maybe_label {
            None => {
                rectangle::draw(
                    uic.win_w, uic.win_h, graphics, rect_state, self.pos,
                    self.dim, maybe_frame, color
                )
            },
            Some(text) => {
                let text_color = self.maybe_label_color.unwrap_or(uic.theme.label_color);
                let size = self.maybe_label_font_size.unwrap_or(uic.theme.font_size_medium);
                rectangle::draw_with_centered_label(
                    uic.win_w, uic.win_h, graphics, uic, rect_state,
                    self.pos, self.dim, maybe_frame, color,
                    text, size, text_color
                )
            },
        }

        set_state(uic, self.ui_id, Widget::Toggle(new_state), self.pos, self.dim);

    }
}
<commit_msg>Implemented `Colorable` for `Toggle`<commit_after>
use color::{ Color, Colorable };
use dimensions::Dimensions;
use mouse::Mouse;
use point::Point;
use rectangle;
use graphics::Graphics;
use graphics::character::CharacterCache;
use ui_context::{ UIID, UiContext };
use widget::Widget;

/// Represents the state of the Toggle widget.
#[derive(PartialEq, Clone, Copy)]
pub enum State {
    Normal,
    Highlighted,
    Clicked,
}

impl State {
    /// Return the associated Rectangle state.
    fn as_rectangle_state(&self) -> rectangle::State {
        match self {
            &State::Normal => rectangle::State::Normal,
            &State::Highlighted => rectangle::State::Highlighted,
            &State::Clicked => rectangle::State::Clicked,
        }
    }
}

widget_fns!(Toggle, State, Widget::Toggle(State::Normal));

/// Check the current state of the button.
fn get_new_state(is_over: bool,
                 prev: State,
                 mouse: Mouse) -> State {
    use mouse::ButtonState::{Down, Up};
    use self::State::{Normal, Highlighted, Clicked};
    match (is_over, prev, mouse.left) {
        (true,  Normal,  Down) => Normal,
        (true,  _,       Down) => Clicked,
        (true,  _,       Up)   => Highlighted,
        (false, Clicked, Down) => Clicked,
        _                      => Normal,
    }
}

/// A context on which the builder pattern can be implemented.
pub struct Toggle<'a, F> {
    ui_id: UIID,
    pos: Point,
    dim: Dimensions,
    maybe_callback: Option<F>,
    maybe_color: Option<Color>,
    maybe_frame: Option<f64>,
    maybe_frame_color: Option<Color>,
    maybe_label: Option<&'a str>,
    maybe_label_color: Option<Color>,
    maybe_label_font_size: Option<u32>,
    value: bool,
}

impl<'a, F> Toggle<'a, F> {

    /// Create a toggle context to be built upon.
    pub fn new(ui_id: UIID, value: bool) -> Toggle<'a, F> {
        Toggle {
            ui_id: ui_id,
            pos: [0.0, 0.0],
            dim: [64.0, 64.0],
            maybe_callback: None,
            maybe_color: None,
            maybe_frame: None,
            maybe_frame_color: None,
            maybe_label: None,
            maybe_label_color: None,
            maybe_label_font_size: None,
            value: value,
        }
    }

}

impl<'a, F> Colorable for Toggle<'a, F> {
    fn color(mut self, color: Color) -> Self {
        self.maybe_color = Some(color);
        self
    }
}

/*
quack! {
    toggle: Toggle['a, F]
    get:
        fn () -> Size [] { Size(toggle.dim) }
        fn () -> DefaultWidgetState [] {
            DefaultWidgetState(Widget::Toggle(State::Normal))
        }
        fn () -> Id [] { Id(toggle.ui_id) }
    set:
        fn (val: Callback<F>) [where F: FnMut(bool) + 'a] {
            toggle.maybe_callback = Some(val.0)
        }
        fn (val: FrameColor) [] { toggle.maybe_frame_color = Some(val.0) }
        fn (val: FrameWidth) [] { toggle.maybe_frame = Some(val.0) }
        fn (val: LabelText<'a>) [] { toggle.maybe_label = Some(val.0) }
        fn (val: LabelColor) [] { toggle.maybe_label_color = Some(val.0) }
        fn (val: LabelFontSize) [] {
            toggle.maybe_label_font_size = Some(val.0)
        }
        fn (val: Position) [] { toggle.pos = val.0 }
        fn (val: Size) [] { toggle.dim = val.0 }
    action:
}
*/

impl<'a, F> ::draw::Drawable for Toggle<'a, F> where F: FnMut(bool) + 'a {
    fn draw<B, C>(&mut self, uic: &mut UiContext<C>, graphics: &mut B)
        where
            B: Graphics<Texture = <C as CharacterCache>::Texture>,
            C: CharacterCache
    {
        let color = self.maybe_color.unwrap_or(uic.theme.shape_color);
        let color = match self.value {
            true => color,
            false => color * Color::new(0.1, 0.1, 0.1, 1.0)
        };
        let state = *get_state(uic, self.ui_id);
        let mouse = uic.get_mouse_state();
        let is_over = rectangle::is_over(self.pos, mouse.pos, self.dim);
        let new_state = get_new_state(is_over, state, mouse);
        let rect_state = new_state.as_rectangle_state();
        match self.maybe_callback {
            Some(ref mut callback) => {
                match (is_over, state, new_state) {
                    (true, State::Clicked, State::Highlighted) =>
                        (*callback)(match self.value { true => false, false => true }),
                    _ => (),
                }
            }, None => (),
        }
        let frame_w = self.maybe_frame.unwrap_or(uic.theme.frame_width);
        let maybe_frame = match frame_w > 0.0 {
            true => Some((frame_w, self.maybe_frame_color.unwrap_or(uic.theme.frame_color))),
            false => None,
        };
        match self.maybe_label {
            None => {
                rectangle::draw(
                    uic.win_w, uic.win_h, graphics, rect_state, self.pos,
                    self.dim, maybe_frame, color
                )
            },
            Some(text) => {
                let text_color = self.maybe_label_color.unwrap_or(uic.theme.label_color);
                let size = self.maybe_label_font_size.unwrap_or(uic.theme.font_size_medium);
                rectangle::draw_with_centered_label(
                    uic.win_w, uic.win_h, graphics, uic, rect_state,
                    self.pos, self.dim, maybe_frame, color,
                    text, size, text_color
                )
            },
        }

        set_state(uic, self.ui_id, Widget::Toggle(new_state), self.pos, self.dim);

    }
}
<|endoftext|>


<commit_before>extern crate libc;

use std::io::{IoResult, IoError, File, Open, ReadWrite};
use std::os::unix::prelude::AsRawFd;
use std::string::String;
use self::libc::funcs::bsd44::ioctl;
use self::libc::types::os::common::bsd44::in6_addr;
use self::libc::consts::os::bsd44::{AF_INET6, SOCK_DGRAM};
use self::libc::funcs::bsd43::socket;
use self::libc::funcs::posix88::unistd::close;
use c_interop::*;

const DEVICE_PATH: &'static str = "/dev/net/tun";

// TODO Make not a constant
const MTU_SIZE: uint = 1500;

#[deriving(Copy, Clone, Eq, PartialEq, Hash)]
pub enum TunTapType {
	Tun,
	Tap
}

pub struct TunTap {
	pub file: File,
	sock: libc::c_int,
	if_name: [u8; IFNAMSIZ],
	if_index: libc::c_int
}

impl Drop for TunTap {
	fn drop(&mut self) {
		unsafe { close(self.sock) };
	}
}

impl TunTap {
	pub fn create(typ: TunTapType) -> TunTap {
		TunTap::create_named(typ, "")
	}

	pub fn create_named(typ: TunTapType, name: &str) -> TunTap {
		let (file, if_name) = TunTap::create_if(typ, name);
		let (sock, if_index) = TunTap::create_socket(if_name);

		TunTap {
			file: file,
			sock: sock,
			if_name: if_name,
			if_index: if_index
		}
	}

	fn create_if(typ: TunTapType, name: &str) -> (File, [u8; IFNAMSIZ]) {
		if name.len() >= IFNAMSIZ {
			panic!("Interface name too long, max length is {}", IFNAMSIZ - 1);
		}

		let path = Path::new(DEVICE_PATH);
		let file = match File::open_mode(&path, Open, ReadWrite) {
			Err(why) => panic!("Couldn't open tun device '{}': {}", path.display(), why.desc),
			Ok(file) => file,
		};

		let mut req = ioctl_flags_data {
			ifr_name: str_as_buffer(name),
			ifr_flags: match typ {
				TunTapType::Tun => IFF_TUN,
				TunTapType::Tap => IFF_TAP
			}
		};

		let res = unsafe { ioctl(file.as_raw_fd(), TUNSETIFF, &mut req) };
		if res < 0 {
			panic!("{}", IoError::last_error());
		}

		(file, req.ifr_name)
	}

	fn create_socket(if_name: [u8; IFNAMSIZ]) -> (libc::c_int, libc::c_int) {
		let sock = unsafe { socket(AF_INET6, SOCK_DGRAM, 0) };
		if sock < 0 {
			panic!("{}", IoError::last_error());
		}

		let mut req = ioctl_ifindex_data {
			ifr_name: if_name,
			ifr_ifindex: -1
		};

		let res = unsafe { ioctl(sock, SIOCGIFINDEX, &mut req) };
		if res < 0 {
			let err = IoError::last_error();
			unsafe { close(sock) };
			panic!("{}", err);
		}

		(sock, req.ifr_ifindex)
	}

	pub fn get_name(&self) -> String {
		unsafe { String::from_raw_buf_len(self.if_name.as_ptr(), IFNAMSIZ) }
	}

	pub fn up(&self) {
		let mut req = ioctl_flags_data {
			ifr_name: self.if_name,
			ifr_flags: 0
		};

		let res = unsafe { ioctl(self.sock, SIOCGIFFLAGS, &mut req) };
		if res < 0 {
			panic!("{}", IoError::last_error());
		}

		if req.ifr_flags & IFF_UP & IFF_RUNNING != 0 {
			// Already up
			return;
		}

		req.ifr_flags |= IFF_UP | IFF_RUNNING;

		let res = unsafe { ioctl(self.sock, SIOCSIFFLAGS, &mut req) };
		if res < 0 {
			panic!("{}", IoError::last_error());
		}
	}

	pub fn add_address(&self, ip: &[u8]) {
		self.up();

		if ip.len() == 4 {
			panic!("IPv4 not implemented");
		}
		else if ip.len() == 16 {
			let mut req = in6_ifreq {
				ifr6_addr: in6_addr {s6_addr: [
					ip[ 1] as u16 << 8 | ip[ 0] as u16,
					ip[ 3] as u16 << 8 | ip[ 2] as u16,
					ip[ 5] as u16 << 8 | ip[ 4] as u16,
					ip[ 7] as u16 << 8 | ip[ 6] as u16,
					ip[ 9] as u16 << 8 | ip[ 8] as u16,
					ip[11] as u16 << 8 | ip[10] as u16,
					ip[13] as u16 << 8 | ip[12] as u16,
					ip[15] as u16 << 8 | ip[14] as u16
				]},
				ifr6_prefixlen: 8,
				ifr6_ifindex: self.if_index
			};

			let res = unsafe { ioctl(self.sock, SIOCSIFADDR, &mut req) };
			if res < 0 {
				panic!("{}", IoError::last_error());
			}
		}
		else {
			panic!("IP length must be either 4 or 16 bytes, got {}", ip.len());
		}
	}

	pub fn read<'a>(&mut self, buffer: &'a mut [u8]) -> IoResult<&'a [u8]> {
		assert!(buffer.len() >= MTU_SIZE);

		let len = try!(self.file.read(buffer));
		Ok(buffer.slice_to(len))
	}

	pub fn write(&mut self, data: &[u8]) -> IoResult<()> {
		self.file.write(data)
	}
}
<commit_msg>deriving -> derive fallout<commit_after>extern crate libc;

use std::io::{IoResult, IoError, File, Open, ReadWrite};
use std::os::unix::prelude::AsRawFd;
use std::string::String;
use self::libc::funcs::bsd44::ioctl;
use self::libc::types::os::common::bsd44::in6_addr;
use self::libc::consts::os::bsd44::{AF_INET6, SOCK_DGRAM};
use self::libc::funcs::bsd43::socket;
use self::libc::funcs::posix88::unistd::close;
use c_interop::*;

const DEVICE_PATH: &'static str = "/dev/net/tun";

// TODO Make not a constant
const MTU_SIZE: uint = 1500;

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub enum TunTapType {
	Tun,
	Tap
}

pub struct TunTap {
	pub file: File,
	sock: libc::c_int,
	if_name: [u8; IFNAMSIZ],
	if_index: libc::c_int
}

impl Drop for TunTap {
	fn drop(&mut self) {
		unsafe { close(self.sock) };
	}
}

impl TunTap {
	pub fn create(typ: TunTapType) -> TunTap {
		TunTap::create_named(typ, "")
	}

	pub fn create_named(typ: TunTapType, name: &str) -> TunTap {
		let (file, if_name) = TunTap::create_if(typ, name);
		let (sock, if_index) = TunTap::create_socket(if_name);

		TunTap {
			file: file,
			sock: sock,
			if_name: if_name,
			if_index: if_index
		}
	}

	fn create_if(typ: TunTapType, name: &str) -> (File, [u8; IFNAMSIZ]) {
		if name.len() >= IFNAMSIZ {
			panic!("Interface name too long, max length is {}", IFNAMSIZ - 1);
		}

		let path = Path::new(DEVICE_PATH);
		let file = match File::open_mode(&path, Open, ReadWrite) {
			Err(why) => panic!("Couldn't open tun device '{}': {}", path.display(), why.desc),
			Ok(file) => file,
		};

		let mut req = ioctl_flags_data {
			ifr_name: str_as_buffer(name),
			ifr_flags: match typ {
				TunTapType::Tun => IFF_TUN,
				TunTapType::Tap => IFF_TAP
			}
		};

		let res = unsafe { ioctl(file.as_raw_fd(), TUNSETIFF, &mut req) };
		if res < 0 {
			panic!("{}", IoError::last_error());
		}

		(file, req.ifr_name)
	}

	fn create_socket(if_name: [u8; IFNAMSIZ]) -> (libc::c_int, libc::c_int) {
		let sock = unsafe { socket(AF_INET6, SOCK_DGRAM, 0) };
		if sock < 0 {
			panic!("{}", IoError::last_error());
		}

		let mut req = ioctl_ifindex_data {
			ifr_name: if_name,
			ifr_ifindex: -1
		};

		let res = unsafe { ioctl(sock, SIOCGIFINDEX, &mut req) };
		if res < 0 {
			let err = IoError::last_error();
			unsafe { close(sock) };
			panic!("{}", err);
		}

		(sock, req.ifr_ifindex)
	}

	pub fn get_name(&self) -> String {
		unsafe { String::from_raw_buf_len(self.if_name.as_ptr(), IFNAMSIZ) }
	}

	pub fn up(&self) {
		let mut req = ioctl_flags_data {
			ifr_name: self.if_name,
			ifr_flags: 0
		};

		let res = unsafe { ioctl(self.sock, SIOCGIFFLAGS, &mut req) };
		if res < 0 {
			panic!("{}", IoError::last_error());
		}

		if req.ifr_flags & IFF_UP & IFF_RUNNING != 0 {
			// Already up
			return;
		}

		req.ifr_flags |= IFF_UP | IFF_RUNNING;

		let res = unsafe { ioctl(self.sock, SIOCSIFFLAGS, &mut req) };
		if res < 0 {
			panic!("{}", IoError::last_error());
		}
	}

	pub fn add_address(&self, ip: &[u8]) {
		self.up();

		if ip.len() == 4 {
			panic!("IPv4 not implemented");
		}
		else if ip.len() == 16 {
			let mut req = in6_ifreq {
				ifr6_addr: in6_addr {s6_addr: [
					ip[ 1] as u16 << 8 | ip[ 0] as u16,
					ip[ 3] as u16 << 8 | ip[ 2] as u16,
					ip[ 5] as u16 << 8 | ip[ 4] as u16,
					ip[ 7] as u16 << 8 | ip[ 6] as u16,
					ip[ 9] as u16 << 8 | ip[ 8] as u16,
					ip[11] as u16 << 8 | ip[10] as u16,
					ip[13] as u16 << 8 | ip[12] as u16,
					ip[15] as u16 << 8 | ip[14] as u16
				]},
				ifr6_prefixlen: 8,
				ifr6_ifindex: self.if_index
			};

			let res = unsafe { ioctl(self.sock, SIOCSIFADDR, &mut req) };
			if res < 0 {
				panic!("{}", IoError::last_error());
			}
		}
		else {
			panic!("IP length must be either 4 or 16 bytes, got {}", ip.len());
		}
	}

	pub fn read<'a>(&mut self, buffer: &'a mut [u8]) -> IoResult<&'a [u8]> {
		assert!(buffer.len() >= MTU_SIZE);

		let len = try!(self.file.read(buffer));
		Ok(buffer.slice_to(len))
	}

	pub fn write(&mut self, data: &[u8]) -> IoResult<()> {
		self.file.write(data)
	}
}
<|endoftext|>


<commit_before>use std::collections::vec_deque::IntoIter as VecDequeIter;

use CreationError;
use CursorState;
use EventsLoop;
use MouseCursor;
use Window;
use WindowBuilder;
use WindowId;
use native_monitor::NativeMonitorId;

use libc;
use platform;

impl WindowBuilder {
    /// Initializes a new `WindowBuilder` with default values.
    #[inline]
    pub fn new() -> WindowBuilder {
        WindowBuilder {
            window: Default::default(),
            platform_specific: Default::default(),
        }
    }

    /// Requests the window to be of specific dimensions.
    ///
    /// Width and height are in pixels.
    #[inline]
    pub fn with_dimensions(mut self, width: u32, height: u32) -> WindowBuilder {
        self.window.dimensions = Some((width, height));
        self
    }

    /// Sets a minimum dimension size for the window
    ///
    /// Width and height are in pixels.
    #[inline]
    pub fn with_min_dimensions(mut self, width: u32, height: u32) -> WindowBuilder {
        self.window.min_dimensions = Some((width, height));
        self
    }

    /// Sets a maximum dimension size for the window
    ///
    /// Width and height are in pixels.
    #[inline]
    pub fn with_max_dimensions(mut self, width: u32, height: u32) -> WindowBuilder {
        self.window.max_dimensions = Some((width, height));
        self
    }

    /// Requests a specific title for the window.
    #[inline]
    pub fn with_title<T: Into<String>>(mut self, title: T) -> WindowBuilder {
        self.window.title = title.into();
        self
    }

    /// Requests fullscreen mode.
    ///
    /// If you don't specify dimensions for the window, it will match the monitor's.
    #[inline]
    pub fn with_fullscreen(mut self, monitor: MonitorId) -> WindowBuilder {
        let MonitorId(monitor) = monitor;
        self.window.monitor = Some(monitor);
        self
    }

    /// Sets whether the window will be initially hidden or visible.
    #[inline]
    pub fn with_visibility(mut self, visible: bool) -> WindowBuilder {
        self.window.visible = visible;
        self
    }

    /// Sets whether the background of the window should be transparent.
    #[inline]
    pub fn with_transparency(mut self, transparent: bool) -> WindowBuilder {
        self.window.transparent = transparent;
        self
    }

    /// Sets whether the window should have a border, a title bar, etc.
    #[inline]
    pub fn with_decorations(mut self, decorations: bool) -> WindowBuilder {
        self.window.decorations = decorations;
        self
    }

    /// Enables multitouch
    #[inline]
    pub fn with_multitouch(mut self) -> WindowBuilder {
        self.window.multitouch = true;
        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(mut self, events_loop: &EventsLoop) -> Result<Window, CreationError> {
        // resizing the window to the dimensions of the monitor when fullscreen
        if self.window.dimensions.is_none() && self.window.monitor.is_some() {
            self.window.dimensions = Some(self.window.monitor.as_ref().unwrap().get_dimensions())
        }

        // default dimensions
        if self.window.dimensions.is_none() {
            self.window.dimensions = Some((1024, 768));
        }

        // building
        let w = try!(platform::Window2::new(events_loop.events_loop.clone(), &self.window, &self.platform_specific));

        Ok(Window { window: w })
    }
}

impl Window {
    /// Creates a new OpenGL context, and a Window for platforms where this is appropriate.
    ///
    /// This function is equivalent to `WindowBuilder::new().build(events_loop)`.
    ///
    /// Error should be very rare and only occur in case of permission denied, incompatible system,
    ///  out of memory, etc.
    #[inline]
    pub fn new(events_loop: &EventsLoop) -> Result<Window, CreationError> {
        let builder = WindowBuilder::new();
        builder.build(events_loop)
    }

    /// Modifies the title of the window.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_title(&self, title: &str) {
        self.window.set_title(title)
    }

    /// Shows the window if it was hidden.
    ///
    /// ## Platform-specific
    ///
    /// - Has no effect on Android
    ///
    #[inline]
    pub fn show(&self) {
        self.window.show()
    }

    /// Hides the window if it was visible.
    ///
    /// ## Platform-specific
    ///
    /// - Has no effect on Android
    ///
    #[inline]
    pub fn hide(&self) {
        self.window.hide()
    }

    /// Returns the position of the top-left hand corner of the window relative to the
    ///  top-left hand corner of the desktop.
    ///
    /// Note that the top-left hand corner of the desktop is not necessarily the same as
    ///  the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
    ///  of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
    ///
    /// The coordinates can be negative if the top-left hand corner of the window is outside
    ///  of the visible screen region.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_position(&self) -> Option<(i32, i32)> {
        self.window.get_position()
    }

    /// Modifies the position of the window.
    ///
    /// See `get_position` for more informations about the coordinates.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_position(&self, x: i32, y: i32) {
        self.window.set_position(x, y)
    }

    /// Returns the size in points of the client area of the window.
    ///
    /// The client area is the content of the window, excluding the title bar and borders.
    /// To get the dimensions of the frame buffer when calling `glViewport`, multiply with hidpi factor.
    ///
    /// Returns `None` if the window no longer exists.
    ///
    /// DEPRECATED
    #[inline]
    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        self.window.get_inner_size()
    }

    /// Returns the size in points of the client area of the window.
    ///
    /// The client area is the content of the window, excluding the title bar and borders.
    /// To get the dimensions of the frame buffer when calling `glViewport`, multiply with hidpi factor.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_inner_size_points(&self) -> Option<(u32, u32)> {
        self.window.get_inner_size()
    }

    /// Returns the size in pixels of the client area of the window.
    ///
    /// The client area is the content of the window, excluding the title bar and borders.
    /// These are the dimensions of the frame buffer, and the dimensions that you should use
    ///  when you call `glViewport`.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_inner_size_pixels(&self) -> Option<(u32, u32)> {
        self.window.get_inner_size().map(|(x, y)| {
            let hidpi = self.hidpi_factor();
            ((x as f32 * hidpi) as u32, (y as f32 * hidpi) as u32)
        })
    }

    /// Returns the size in pixels of the window.
    ///
    /// These dimensions include title bar and borders. If you don't want these, you should use
    ///  use `get_inner_size` instead.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.window.get_outer_size()
    }

    /// Modifies the inner size of the window.
    ///
    /// See `get_inner_size` for more informations about the values.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_inner_size(&self, x: u32, y: u32) {
        self.window.set_inner_size(x, y)
    }

    /// DEPRECATED. Gets the native platform specific display for this window.
    /// This is typically only required when integrating with
    /// other libraries that need this information.
    #[deprecated]
    #[inline]
    pub unsafe fn platform_display(&self) -> *mut libc::c_void {
        self.window.platform_display()
    }

    /// DEPRECATED. Gets the native platform specific window handle. This is
    /// typically only required when integrating with other libraries
    /// that need this information.
    #[deprecated]
    #[inline]
    pub unsafe fn platform_window(&self) -> *mut libc::c_void {
        self.window.platform_window()
    }

    /// Modifies the mouse cursor of the window.
    /// Has no effect on Android.
    pub fn set_cursor(&self, cursor: MouseCursor) {
        self.window.set_cursor(cursor);
    }

    /// Returns the ratio between the backing framebuffer resolution and the
    /// window size in screen pixels. This is typically one for a normal display
    /// and two for a retina display.
    #[inline]
    pub fn hidpi_factor(&self) -> f32 {
        self.window.hidpi_factor()
    }

    /// Changes the position of the cursor in window coordinates.
    #[inline]
    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        self.window.set_cursor_position(x, y)
    }

    /// Sets how glutin handles the cursor. See the documentation of `CursorState` for details.
    ///
    /// Has no effect on Android.
    #[inline]
    pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
        self.window.set_cursor_state(state)
    }

    #[inline]
    pub fn id(&self) -> WindowId {
        WindowId(self.window.id())
    }
}

/// 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.
pub struct AvailableMonitorsIter {
    data: VecDequeIter<platform::MonitorId>,
}

impl Iterator for AvailableMonitorsIter {
    type Item = MonitorId;

    #[inline]
    fn next(&mut self) -> Option<MonitorId> {
        self.data.next().map(|id| MonitorId(id))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.data.size_hint()
    }
}

/// Returns the list of all available monitors.
#[inline]
pub fn get_available_monitors() -> AvailableMonitorsIter {
    let data = platform::get_available_monitors();
    AvailableMonitorsIter{ data: data.into_iter() }
}

/// Returns the primary monitor of the system.
#[inline]
pub fn get_primary_monitor() -> MonitorId {
    MonitorId(platform::get_primary_monitor())
}

/// Identifier for a monitor.
pub struct MonitorId(platform::MonitorId);

impl MonitorId {
    /// Returns a human-readable name of the monitor.
    #[inline]
    pub fn get_name(&self) -> Option<String> {
        let &MonitorId(ref id) = self;
        id.get_name()
    }

    /// Returns the native platform identifier for this monitor.
    #[inline]
    pub fn get_native_identifier(&self) -> NativeMonitorId {
        let &MonitorId(ref id) = self;
        id.get_native_identifier()
    }

    /// Returns the number of pixels currently displayed on the monitor.
    #[inline]
    pub fn get_dimensions(&self) -> (u32, u32) {
        let &MonitorId(ref id) = self;
        id.get_dimensions()
    }
}
<commit_msg>Fixed obsolete comments<commit_after>use std::collections::vec_deque::IntoIter as VecDequeIter;

use CreationError;
use CursorState;
use EventsLoop;
use MouseCursor;
use Window;
use WindowBuilder;
use WindowId;
use native_monitor::NativeMonitorId;

use libc;
use platform;

impl WindowBuilder {
    /// Initializes a new `WindowBuilder` with default values.
    #[inline]
    pub fn new() -> WindowBuilder {
        WindowBuilder {
            window: Default::default(),
            platform_specific: Default::default(),
        }
    }

    /// Requests the window to be of specific dimensions.
    ///
    /// Width and height are in pixels.
    #[inline]
    pub fn with_dimensions(mut self, width: u32, height: u32) -> WindowBuilder {
        self.window.dimensions = Some((width, height));
        self
    }

    /// Sets a minimum dimension size for the window
    ///
    /// Width and height are in pixels.
    #[inline]
    pub fn with_min_dimensions(mut self, width: u32, height: u32) -> WindowBuilder {
        self.window.min_dimensions = Some((width, height));
        self
    }

    /// Sets a maximum dimension size for the window
    ///
    /// Width and height are in pixels.
    #[inline]
    pub fn with_max_dimensions(mut self, width: u32, height: u32) -> WindowBuilder {
        self.window.max_dimensions = Some((width, height));
        self
    }

    /// Requests a specific title for the window.
    #[inline]
    pub fn with_title<T: Into<String>>(mut self, title: T) -> WindowBuilder {
        self.window.title = title.into();
        self
    }

    /// Requests fullscreen mode.
    ///
    /// If you don't specify dimensions for the window, it will match the monitor's.
    #[inline]
    pub fn with_fullscreen(mut self, monitor: MonitorId) -> WindowBuilder {
        let MonitorId(monitor) = monitor;
        self.window.monitor = Some(monitor);
        self
    }

    /// Sets whether the window will be initially hidden or visible.
    #[inline]
    pub fn with_visibility(mut self, visible: bool) -> WindowBuilder {
        self.window.visible = visible;
        self
    }

    /// Sets whether the background of the window should be transparent.
    #[inline]
    pub fn with_transparency(mut self, transparent: bool) -> WindowBuilder {
        self.window.transparent = transparent;
        self
    }

    /// Sets whether the window should have a border, a title bar, etc.
    #[inline]
    pub fn with_decorations(mut self, decorations: bool) -> WindowBuilder {
        self.window.decorations = decorations;
        self
    }

    /// Enables multitouch
    #[inline]
    pub fn with_multitouch(mut self) -> WindowBuilder {
        self.window.multitouch = true;
        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(mut self, events_loop: &EventsLoop) -> Result<Window, CreationError> {
        // resizing the window to the dimensions of the monitor when fullscreen
        if self.window.dimensions.is_none() && self.window.monitor.is_some() {
            self.window.dimensions = Some(self.window.monitor.as_ref().unwrap().get_dimensions())
        }

        // default dimensions
        if self.window.dimensions.is_none() {
            self.window.dimensions = Some((1024, 768));
        }

        // building
        let w = try!(platform::Window2::new(events_loop.events_loop.clone(), &self.window, &self.platform_specific));

        Ok(Window { window: w })
    }
}

impl Window {
    /// Creates a new Window for platforms where this is appropriate.
    ///
    /// This function is equivalent to `WindowBuilder::new().build(events_loop)`.
    ///
    /// Error should be very rare and only occur in case of permission denied, incompatible system,
    ///  out of memory, etc.
    #[inline]
    pub fn new(events_loop: &EventsLoop) -> Result<Window, CreationError> {
        let builder = WindowBuilder::new();
        builder.build(events_loop)
    }

    /// Modifies the title of the window.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_title(&self, title: &str) {
        self.window.set_title(title)
    }

    /// Shows the window if it was hidden.
    ///
    /// ## Platform-specific
    ///
    /// - Has no effect on Android
    ///
    #[inline]
    pub fn show(&self) {
        self.window.show()
    }

    /// Hides the window if it was visible.
    ///
    /// ## Platform-specific
    ///
    /// - Has no effect on Android
    ///
    #[inline]
    pub fn hide(&self) {
        self.window.hide()
    }

    /// Returns the position of the top-left hand corner of the window relative to the
    ///  top-left hand corner of the desktop.
    ///
    /// Note that the top-left hand corner of the desktop is not necessarily the same as
    ///  the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
    ///  of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
    ///
    /// The coordinates can be negative if the top-left hand corner of the window is outside
    ///  of the visible screen region.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_position(&self) -> Option<(i32, i32)> {
        self.window.get_position()
    }

    /// Modifies the position of the window.
    ///
    /// See `get_position` for more informations about the coordinates.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_position(&self, x: i32, y: i32) {
        self.window.set_position(x, y)
    }

    /// Returns the size in points of the client area of the window.
    ///
    /// The client area is the content of the window, excluding the title bar and borders.
    /// To get the dimensions of the frame buffer when calling `glViewport`, multiply with hidpi factor.
    ///
    /// Returns `None` if the window no longer exists.
    ///
    /// DEPRECATED
    #[inline]
    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        self.window.get_inner_size()
    }

    /// Returns the size in points of the client area of the window.
    ///
    /// The client area is the content of the window, excluding the title bar and borders.
    /// To get the dimensions of the frame buffer when calling `glViewport`, multiply with hidpi factor.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_inner_size_points(&self) -> Option<(u32, u32)> {
        self.window.get_inner_size()
    }

    /// Returns the size in pixels of the client area of the window.
    ///
    /// The client area is the content of the window, excluding the title bar and borders.
    /// These are the dimensions of the frame buffer, and the dimensions that you should use
    ///  when you call `glViewport`.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_inner_size_pixels(&self) -> Option<(u32, u32)> {
        self.window.get_inner_size().map(|(x, y)| {
            let hidpi = self.hidpi_factor();
            ((x as f32 * hidpi) as u32, (y as f32 * hidpi) as u32)
        })
    }

    /// Returns the size in pixels of the window.
    ///
    /// These dimensions include title bar and borders. If you don't want these, you should use
    ///  use `get_inner_size` instead.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.window.get_outer_size()
    }

    /// Modifies the inner size of the window.
    ///
    /// See `get_inner_size` for more informations about the values.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_inner_size(&self, x: u32, y: u32) {
        self.window.set_inner_size(x, y)
    }

    /// DEPRECATED. Gets the native platform specific display for this window.
    /// This is typically only required when integrating with
    /// other libraries that need this information.
    #[deprecated]
    #[inline]
    pub unsafe fn platform_display(&self) -> *mut libc::c_void {
        self.window.platform_display()
    }

    /// DEPRECATED. Gets the native platform specific window handle. This is
    /// typically only required when integrating with other libraries
    /// that need this information.
    #[deprecated]
    #[inline]
    pub unsafe fn platform_window(&self) -> *mut libc::c_void {
        self.window.platform_window()
    }

    /// Modifies the mouse cursor of the window.
    /// Has no effect on Android.
    pub fn set_cursor(&self, cursor: MouseCursor) {
        self.window.set_cursor(cursor);
    }

    /// Returns the ratio between the backing framebuffer resolution and the
    /// window size in screen pixels. This is typically one for a normal display
    /// and two for a retina display.
    #[inline]
    pub fn hidpi_factor(&self) -> f32 {
        self.window.hidpi_factor()
    }

    /// Changes the position of the cursor in window coordinates.
    #[inline]
    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        self.window.set_cursor_position(x, y)
    }

    /// Sets how winit handles the cursor. See the documentation of `CursorState` for details.
    ///
    /// Has no effect on Android.
    #[inline]
    pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
        self.window.set_cursor_state(state)
    }

    #[inline]
    pub fn id(&self) -> WindowId {
        WindowId(self.window.id())
    }
}

/// 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.
pub struct AvailableMonitorsIter {
    data: VecDequeIter<platform::MonitorId>,
}

impl Iterator for AvailableMonitorsIter {
    type Item = MonitorId;

    #[inline]
    fn next(&mut self) -> Option<MonitorId> {
        self.data.next().map(|id| MonitorId(id))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.data.size_hint()
    }
}

/// Returns the list of all available monitors.
#[inline]
pub fn get_available_monitors() -> AvailableMonitorsIter {
    let data = platform::get_available_monitors();
    AvailableMonitorsIter{ data: data.into_iter() }
}

/// Returns the primary monitor of the system.
#[inline]
pub fn get_primary_monitor() -> MonitorId {
    MonitorId(platform::get_primary_monitor())
}

/// Identifier for a monitor.
pub struct MonitorId(platform::MonitorId);

impl MonitorId {
    /// Returns a human-readable name of the monitor.
    #[inline]
    pub fn get_name(&self) -> Option<String> {
        let &MonitorId(ref id) = self;
        id.get_name()
    }

    /// Returns the native platform identifier for this monitor.
    #[inline]
    pub fn get_native_identifier(&self) -> NativeMonitorId {
        let &MonitorId(ref id) = self;
        id.get_native_identifier()
    }

    /// Returns the number of pixels currently displayed on the monitor.
    #[inline]
    pub fn get_dimensions(&self) -> (u32, u32) {
        let &MonitorId(ref id) = self;
        id.get_dimensions()
    }
}
<|endoftext|>