<commit_before>
use gfx;
use gfx::DeviceHelper;
use graphics::{
    BackEnd,
};

use Texture;

static BUFFER_SIZE: uint = 1024;

static VERTEX_SHADER: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
attribute vec2 pos;
attribute vec4 color;
varying vec4 v_Color;
void main() {
    v_Color = color;
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
    GLSL_150: b"
#version 150 core
in vec2 pos;
in vec4 color;
out vec4 v_Color;
void main() {
    v_Color = color;
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
};

static FRAGMENT_SHADER: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
varying vec4 v_Color;
void main() {
    gl_FragColor = v_Color;
}
"
    GLSL_150: b"
#version 150 core
in vec4 v_Color;
out vec4 o_Color;
void main() {
    o_Color = v_Color;
}
"
};

static VERTEX_SHADER_UV: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
attribute vec2 pos;
attribute vec4 color;
attribute vec2 uv;
uniform sampler2D s_texture;
varying vec4 v_Color;
varying vec2 v_UV;
void main() {
    v_UV = uv;
    v_Color = color;
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
    GLSL_150: b"
#version 150 core
in vec2 pos;
in vec4 color;
in vec2 uv;
uniform sampler2D s_texture;
out vec4 v_Color;
out vec2 v_UV;
void main() {
    v_UV = uv;
    v_Color = color;
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
};

static FRAGMENT_SHADER_UV: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
uniform sampler2D s_texture;
varying vec2 v_UV;
varying vec4 v_Color;
void main()
{
    gl_FragColor = texture2D(s_texture, v_UV) * v_Color;
}
"
    GLSL_150: b"
#version 150 core
out vec4 o_Color;
uniform sampler2D s_texture;
in vec2 v_UV;
in vec4 v_Color;
void main()
{
    o_Color = texture(s_texture, v_UV) * v_Color;
}
"
};

#[vertex_format]
struct Vertex {
    pos: [f32, ..2],
    color: [f32, ..4],
}

impl Vertex {
    fn new(pos: [f32, ..2], color: [f32, ..4]) -> Vertex {
        Vertex {
            pos: pos,
            color: color,
        }
    }
}

#[vertex_format]
struct VertexUV {
    pos: [f32, ..2],
    color: [f32, ..4],
    uv: [f32, ..2],
}

impl VertexUV {
    fn new(pos: [f32, ..2], color: [f32, ..4], uv: [f32, ..2]) -> VertexUV {
        VertexUV {
            pos: pos,
            color: color,
            uv: uv,
        }
    }
}

#[shader_param(BatchUV, OwnedBatchUV)]
struct ParamsUV {
    s_texture: gfx::shade::TextureParam,
}

/// The graphics back-end.
pub struct Gfx2d<C: gfx::CommandBuffer> {
    buffer: gfx::BufferHandle<Vertex>,
    buffer_uv: gfx::BufferHandle<VertexUV>,
    batch: gfx::batch::OwnedBatch<(), ()>,
    batch_uv: OwnedBatchUV,
}

impl<C: gfx::CommandBuffer> Gfx2d<C> {
    /// Creates a new Gfx2d object.
    pub fn new<D: gfx::Device<C>>(device: &mut D) -> Gfx2d<C> {
        let program = device.link_program(
                VERTEX_SHADER.clone(),
                FRAGMENT_SHADER.clone()
            ).unwrap();
        let program_uv = device.link_program(
                VERTEX_SHADER_UV.clone(),
                FRAGMENT_SHADER_UV.clone()
            ).unwrap();
        let buffer = device.create_buffer(BUFFER_SIZE, gfx::UsageDynamic);
        let buffer_uv = device.create_buffer(BUFFER_SIZE, gfx::UsageDynamic);
        let mesh = gfx::Mesh::from_format(buffer, BUFFER_SIZE as u32);
        let mesh_uv = gfx::Mesh::from_format(buffer_uv, BUFFER_SIZE as u32);
        let batch = gfx::batch::OwnedBatch::new(mesh, program, ()).unwrap();

        let sampler = device.create_sampler(
                gfx::tex::SamplerInfo::new(gfx::tex::Trilinear,
                                           gfx::tex::Clamp)
            );

        // Create a dummy texture
        let texture_info = gfx::tex::TextureInfo {
            width: 1,
            height: 1,
            depth: 1,
            levels: 1,
            kind: gfx::tex::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = device.create_texture(texture_info).unwrap();
        device.update_texture(&texture, &image_info,
                &vec![0x20u8, 0xA0u8, 0xC0u8, 0x00u8].as_slice())
            .unwrap();
        let params_uv = ParamsUV {
            s_texture: (texture, Some(sampler))
        };

        let batch_uv = gfx::batch::OwnedBatch::new(
            mesh_uv, program_uv, params_uv).unwrap();

        Gfx2d {
            buffer: buffer,
            buffer_uv: buffer_uv,
            batch: batch,
            batch_uv: batch_uv,
        }
    }
}

/// Used for rendering 2D graphics.
pub struct RenderContext<'a, C: 'a + gfx::CommandBuffer> {
    renderer: &'a mut gfx::Renderer<C>,
    frame: &'a gfx::Frame,
    gfx2d: &'a mut Gfx2d<C>,
}

impl<'a, C: gfx::CommandBuffer> RenderContext<'a, C> {
    /// Creates a new object for rendering 2D graphics.
    pub fn new(renderer: &'a mut gfx::Renderer<C>,
               frame: &'a gfx::Frame,
               gfx2d: &'a mut Gfx2d<C>) -> RenderContext<'a, C> {
        RenderContext {
            renderer: renderer,
            frame: frame,
            gfx2d: gfx2d
        }
    }
}

impl<'a, C: gfx::CommandBuffer> BackEnd<Texture>
for RenderContext<'a, C> {
    fn supports_clear_rgba(&self) -> bool { true }

    fn clear_rgba(&mut self, r: f32, g: f32, b: f32, a: f32) {
        let &RenderContext {
            ref mut renderer,
            frame,
            ..
        } = self;
        renderer.clear(
                gfx::ClearData {
                    color: [r, g, b, a],
                    depth: 0.0,
                    stencil: 0,
                },
                gfx::Color,
                frame
            );
    }

    fn enable_alpha_blend(&mut self) {
        use std::default::Default;
        use gfx::state::{Normal, Inverse, Factor};

        self.gfx2d.batch.state.blend = Some(gfx::state::Blend {
                value: [1.0, 1.0, 1.0, 1.0],
                color: gfx::state::BlendChannel {
                        equation: gfx::state::FuncAdd,
                        source: Factor(Normal, gfx::state::SourceAlpha),
                        destination: Factor(Inverse, gfx::state::SourceAlpha)
                    },
                alpha: Default::default()
            })
    }

    fn disable_alpha_blend(&mut self) {
        self.gfx2d.batch.state.blend = None;
    }

    fn supports_tri_list_xy_f32_rgba_f32(&self) -> bool { true }

    fn tri_list_xy_f32_rgba_f32(
        &mut self,
        vertices: &[f32],
        colors: &[f32]
    ) {
        let &RenderContext {
            ref mut renderer,
            ref frame,
            gfx2d: &Gfx2d {
                ref mut buffer,
                ref mut batch,
                ..
            }
        } = self;
        let mut vertex_data = Vec::new();
        let n = vertices.len() / 2;
        for i in range(0, n) {
            vertex_data.push(
                Vertex::new(
                    [vertices[2 * i], vertices[2 * i + 1]],
                    [
                        colors[4 * i],
                        colors[4 * i + 1],
                        colors[4 * i + 2],
                        colors[4 * i + 3]
                    ]
                )
            );
        }

        let n = vertex_data.len();
        renderer.update_buffer_vec(*buffer, vertex_data, 0);
        batch.slice = gfx::VertexSlice(gfx::TriangleList, 0, n as u32);
        renderer.draw(&*batch, *frame);
    }

    fn supports_single_texture(&self) -> bool { true }

    fn enable_single_texture(&mut self, texture: &Texture) {
        let ParamsUV {
            s_texture: (ref mut s_texture, _)
        } = self.gfx2d.batch_uv.param;
        *s_texture = texture.handle;
    }

    fn disable_single_texture(&mut self) {}

    // Assume all textures has alpha channel for now.
    fn has_texture_alpha(&self, _texture: &Texture) -> bool { true }

    fn supports_tri_list_xy_f32_rgba_f32_uv_f32(&self) -> bool { true }

    fn tri_list_xy_f32_rgba_f32_uv_f32(
        &mut self,
        vertices: &[f32],
        colors: &[f32],
        texture_coords: &[f32]
    ) {
        let &RenderContext {
            ref mut renderer,
            ref frame,
            gfx2d: &Gfx2d {
                ref mut buffer_uv,
                ref mut batch_uv,
                ..
            }
        } = self;
        let mut vertex_data = Vec::new();
        let n = vertices.len() / 2;
        for i in range(0, n) {
            vertex_data.push(
                VertexUV::new(
                    [vertices[2 * i], vertices[2 * i + 1]],
                    [
                        colors[4 * i],
                        colors[4 * i + 1],
                        colors[4 * i + 2],
                        colors[4 * i + 3]
                    ],
                    [
                        texture_coords[2 * i],
                        texture_coords[2 * i + 1]
                    ]
                )
            );
        }

        let n = vertex_data.len();
        renderer.update_buffer_vec(*buffer_uv, vertex_data, 0);
        batch_uv.slice = gfx::VertexSlice(gfx::TriangleList, 0, n as u32);
        renderer.draw(&*batch_uv, *frame);
    }
}
<commit_msg>Initialize Vec directly<commit_after>
use gfx;
use gfx::DeviceHelper;
use graphics::{
    BackEnd,
};

use Texture;

static BUFFER_SIZE: uint = 1024;

static VERTEX_SHADER: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
attribute vec2 pos;
attribute vec4 color;
varying vec4 v_Color;
void main() {
    v_Color = color;
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
    GLSL_150: b"
#version 150 core
in vec2 pos;
in vec4 color;
out vec4 v_Color;
void main() {
    v_Color = color;
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
};

static FRAGMENT_SHADER: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
varying vec4 v_Color;
void main() {
    gl_FragColor = v_Color;
}
"
    GLSL_150: b"
#version 150 core
in vec4 v_Color;
out vec4 o_Color;
void main() {
    o_Color = v_Color;
}
"
};

static VERTEX_SHADER_UV: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
attribute vec2 pos;
attribute vec4 color;
attribute vec2 uv;
uniform sampler2D s_texture;
varying vec4 v_Color;
varying vec2 v_UV;
void main() {
    v_UV = uv;
    v_Color = color;
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
    GLSL_150: b"
#version 150 core
in vec2 pos;
in vec4 color;
in vec2 uv;
uniform sampler2D s_texture;
out vec4 v_Color;
out vec2 v_UV;
void main() {
    v_UV = uv;
    v_Color = color;
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
};

static FRAGMENT_SHADER_UV: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
uniform sampler2D s_texture;
varying vec2 v_UV;
varying vec4 v_Color;
void main()
{
    gl_FragColor = texture2D(s_texture, v_UV) * v_Color;
}
"
    GLSL_150: b"
#version 150 core
out vec4 o_Color;
uniform sampler2D s_texture;
in vec2 v_UV;
in vec4 v_Color;
void main()
{
    o_Color = texture(s_texture, v_UV) * v_Color;
}
"
};

#[vertex_format]
struct Vertex {
    pos: [f32, ..2],
    color: [f32, ..4],
}

impl Vertex {
    fn new(pos: [f32, ..2], color: [f32, ..4]) -> Vertex {
        Vertex {
            pos: pos,
            color: color,
        }
    }
}

#[vertex_format]
struct VertexUV {
    pos: [f32, ..2],
    color: [f32, ..4],
    uv: [f32, ..2],
}

impl VertexUV {
    fn new(pos: [f32, ..2], color: [f32, ..4], uv: [f32, ..2]) -> VertexUV {
        VertexUV {
            pos: pos,
            color: color,
            uv: uv,
        }
    }
}

#[shader_param(BatchUV, OwnedBatchUV)]
struct ParamsUV {
    s_texture: gfx::shade::TextureParam,
}

/// The graphics back-end.
pub struct Gfx2d<C: gfx::CommandBuffer> {
    buffer: gfx::BufferHandle<Vertex>,
    buffer_uv: gfx::BufferHandle<VertexUV>,
    batch: gfx::batch::OwnedBatch<(), ()>,
    batch_uv: OwnedBatchUV,
}

impl<C: gfx::CommandBuffer> Gfx2d<C> {
    /// Creates a new Gfx2d object.
    pub fn new<D: gfx::Device<C>>(device: &mut D) -> Gfx2d<C> {
        let program = device.link_program(
                VERTEX_SHADER.clone(),
                FRAGMENT_SHADER.clone()
            ).unwrap();
        let program_uv = device.link_program(
                VERTEX_SHADER_UV.clone(),
                FRAGMENT_SHADER_UV.clone()
            ).unwrap();
        let buffer = device.create_buffer(BUFFER_SIZE, gfx::UsageDynamic);
        let buffer_uv = device.create_buffer(BUFFER_SIZE, gfx::UsageDynamic);
        let mesh = gfx::Mesh::from_format(buffer, BUFFER_SIZE as u32);
        let mesh_uv = gfx::Mesh::from_format(buffer_uv, BUFFER_SIZE as u32);
        let batch = gfx::batch::OwnedBatch::new(mesh, program, ()).unwrap();

        let sampler = device.create_sampler(
                gfx::tex::SamplerInfo::new(gfx::tex::Trilinear,
                                           gfx::tex::Clamp)
            );

        // Create a dummy texture
        let texture_info = gfx::tex::TextureInfo {
            width: 1,
            height: 1,
            depth: 1,
            levels: 1,
            kind: gfx::tex::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = device.create_texture(texture_info).unwrap();
        device.update_texture(&texture, &image_info,
                &vec![0x20u8, 0xA0u8, 0xC0u8, 0x00u8].as_slice())
            .unwrap();
        let params_uv = ParamsUV {
            s_texture: (texture, Some(sampler))
        };

        let batch_uv = gfx::batch::OwnedBatch::new(
            mesh_uv, program_uv, params_uv).unwrap();

        Gfx2d {
            buffer: buffer,
            buffer_uv: buffer_uv,
            batch: batch,
            batch_uv: batch_uv,
        }
    }
}

/// Used for rendering 2D graphics.
pub struct RenderContext<'a, C: 'a + gfx::CommandBuffer> {
    renderer: &'a mut gfx::Renderer<C>,
    frame: &'a gfx::Frame,
    gfx2d: &'a mut Gfx2d<C>,
}

impl<'a, C: gfx::CommandBuffer> RenderContext<'a, C> {
    /// Creates a new object for rendering 2D graphics.
    pub fn new(renderer: &'a mut gfx::Renderer<C>,
               frame: &'a gfx::Frame,
               gfx2d: &'a mut Gfx2d<C>) -> RenderContext<'a, C> {
        RenderContext {
            renderer: renderer,
            frame: frame,
            gfx2d: gfx2d
        }
    }
}

impl<'a, C: gfx::CommandBuffer> BackEnd<Texture>
for RenderContext<'a, C> {
    fn supports_clear_rgba(&self) -> bool { true }

    fn clear_rgba(&mut self, r: f32, g: f32, b: f32, a: f32) {
        let &RenderContext {
            ref mut renderer,
            frame,
            ..
        } = self;
        renderer.clear(
                gfx::ClearData {
                    color: [r, g, b, a],
                    depth: 0.0,
                    stencil: 0,
                },
                gfx::Color,
                frame
            );
    }

    fn enable_alpha_blend(&mut self) {
        use std::default::Default;
        use gfx::state::{Normal, Inverse, Factor};

        self.gfx2d.batch.state.blend = Some(gfx::state::Blend {
                value: [1.0, 1.0, 1.0, 1.0],
                color: gfx::state::BlendChannel {
                        equation: gfx::state::FuncAdd,
                        source: Factor(Normal, gfx::state::SourceAlpha),
                        destination: Factor(Inverse, gfx::state::SourceAlpha)
                    },
                alpha: Default::default()
            })
    }

    fn disable_alpha_blend(&mut self) {
        self.gfx2d.batch.state.blend = None;
    }

    fn supports_tri_list_xy_f32_rgba_f32(&self) -> bool { true }

    fn tri_list_xy_f32_rgba_f32(
        &mut self,
        vertices: &[f32],
        colors: &[f32]
    ) {
        let &RenderContext {
            ref mut renderer,
            ref frame,
            gfx2d: &Gfx2d {
                ref mut buffer,
                ref mut batch,
                ..
            }
        } = self;
        let n = vertices.len() / 2;
        let mut vertex_data = Vec::with_capacity(n);
        for i in range(0, n) {
            vertex_data.push(
                Vertex::new(
                    [vertices[2 * i], vertices[2 * i + 1]],
                    [
                        colors[4 * i],
                        colors[4 * i + 1],
                        colors[4 * i + 2],
                        colors[4 * i + 3]
                    ]
                )
            );
        }

        let n = vertex_data.len();
        renderer.update_buffer_vec(*buffer, vertex_data, 0);
        batch.slice = gfx::VertexSlice(gfx::TriangleList, 0, n as u32);
        renderer.draw(&*batch, *frame);
    }

    fn supports_single_texture(&self) -> bool { true }

    fn enable_single_texture(&mut self, texture: &Texture) {
        let ParamsUV {
            s_texture: (ref mut s_texture, _)
        } = self.gfx2d.batch_uv.param;
        *s_texture = texture.handle;
    }

    fn disable_single_texture(&mut self) {}

    // Assume all textures has alpha channel for now.
    fn has_texture_alpha(&self, _texture: &Texture) -> bool { true }

    fn supports_tri_list_xy_f32_rgba_f32_uv_f32(&self) -> bool { true }

    fn tri_list_xy_f32_rgba_f32_uv_f32(
        &mut self,
        vertices: &[f32],
        colors: &[f32],
        texture_coords: &[f32]
    ) {
        let &RenderContext {
            ref mut renderer,
            ref frame,
            gfx2d: &Gfx2d {
                ref mut buffer_uv,
                ref mut batch_uv,
                ..
            }
        } = self;
        let n = vertices.len() / 2;
        let mut vertex_data = Vec::with_capacity(n);
        for i in range(0, n) {
            vertex_data.push(
                VertexUV::new(
                    [vertices[2 * i], vertices[2 * i + 1]],
                    [
                        colors[4 * i],
                        colors[4 * i + 1],
                        colors[4 * i + 2],
                        colors[4 * i + 3]
                    ],
                    [
                        texture_coords[2 * i],
                        texture_coords[2 * i + 1]
                    ]
                )
            );
        }

        let n = vertex_data.len();
        renderer.update_buffer_vec(*buffer_uv, vertex_data, 0);
        batch_uv.slice = gfx::VertexSlice(gfx::TriangleList, 0, n as u32);
        renderer.draw(&*batch_uv, *frame);
    }
}
<|endoftext|>


<commit_before>
use gfx;
use gfx::DeviceHelper;
use graphics::{
    BackEnd,
};

use Texture;

static BUFFER_SIZE: uint = 1024;

static VERTEX_SHADER: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
attribute vec2 pos;
attribute vec3 color;
varying vec4 v_Color;
void main() {
    v_Color = vec4(color, 1.0);
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
    GLSL_150: b"
#version 150 core
in vec2 pos;
in vec3 color;
out vec4 v_Color;
void main() {
    v_Color = vec4(color, 1.0);
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
};

static FRAGMENT_SHADER: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
varying vec4 v_Color;
void main() {
    gl_FragColor = v_Color;
}
"
    GLSL_150: b"
#version 150 core
in vec4 v_Color;
out vec4 o_Color;
void main() {
    o_Color = v_Color;
}
"
};

static VERTEX_SHADER_UV: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
attribute vec2 pos;
attribute vec3 color;
attribute vec2 uv;
uniform sampler2D s_texture;
varying vec4 v_Color;
varying vec2 v_UV;
void main() {
    v_UV = uv;
    v_Color = color;
    gl_Position = a_v4Position;
}
"
    GLSL_150: b"
#version 150 core
in vec2 pos;
in vec3 color;
in vec2 uv;
uniform sampler2D s_texture;
out vec4 v_Color;
out vec2 v_UV;
void main() {
    v_UV = uv;
    v_Color = color;
    gl_Position = a_v4Position;
}
"
};

static FRAGMENT_SHADER_UV: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
uniform sampler2D s_texture;
varying vec2 v_UV;
varying vec4 v_Color;
void main()
{
    gl_FragColor = texture(s_texture, v_UV) * v_Color;
}
"
    GLSL_150: b"
#version 150 core
out vec4 o_Color;
uniform sampler2D s_texture;
in vec2 v_UV;
in vec4 v_Color;
void main()
{
    o_Color = texture(s_texture, v_UV) * v_Color;
}
"
};

#[vertex_format]
struct Vertex {
    pos: [f32, ..2],
    color: [f32, ..4],
}

impl Vertex {
    fn new(pos: [f32, ..2], color: [f32, ..4], uv: [f32, ..2]) -> Vertex {
        Vertex {
            pos: pos,
            color: color,
        }
    }
}

#[vertex_format]
struct VertexUV {
    pos: [f32, ..2],
    color: [f32, ..4],
    uv: [f32, ..2],
}

impl VertexUV {
    fn new(pos: [f32, ..2], color: [f32, ..4], uv: [f32, ..2]) -> VertexUV {
        VertexUV {
            pos: pos,
            color: color,
            uv: uv,
        }
    }
}

#[shader_param(ProgramUV)]
struct ParamsUV {
    s_texture: gfx::shade::TextureParam,
}

/// The graphics back-end.
pub struct Gfx2d {
    state: gfx::DrawState,
    program: gfx::shade::EmptyProgram,
    program_uv: ProgramUV,
    vertex_data: Vec<Vertex>,
    vertex_data_uv: Vec<VertexUV>,
}

impl Gfx2d {
    /// Creates a new Gfx2d object.
    pub fn new<D: gfx::Device>(device: &mut D) -> Gfx2d {
        Gfx2d {
            state: gfx::DrawState::new(),
            program: device.link_program(
                    VERTEX_SHADER.clone(),
                    FRAGMENT_SHADER.clone()
                ).unwrap(),
            program_uv: device.link_program(
                    VERTEX_SHADER_UV.clone(),
                    FRAGMENT_SHADER_UV.clone()
                ).unwrap(),
            vertex_data: Vec::with_capacity(BUFFER_SIZE),
            vertex_data_uv: Vec::with_capacity(BUFFER_SIZE)
        }
    }
}

impl BackEnd<Texture> for Gfx2d {

}
<commit_msg>Added renderer<commit_after>
use gfx;
use gfx::DeviceHelper;
use graphics::{
    BackEnd,
};

use Texture;

static BUFFER_SIZE: uint = 1024;

static VERTEX_SHADER: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
attribute vec2 pos;
attribute vec3 color;
varying vec4 v_Color;
void main() {
    v_Color = vec4(color, 1.0);
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
    GLSL_150: b"
#version 150 core
in vec2 pos;
in vec3 color;
out vec4 v_Color;
void main() {
    v_Color = vec4(color, 1.0);
    gl_Position = vec4(pos, 0.0, 1.0);
}
"
};

static FRAGMENT_SHADER: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
varying vec4 v_Color;
void main() {
    gl_FragColor = v_Color;
}
"
    GLSL_150: b"
#version 150 core
in vec4 v_Color;
out vec4 o_Color;
void main() {
    o_Color = v_Color;
}
"
};

static VERTEX_SHADER_UV: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
attribute vec2 pos;
attribute vec3 color;
attribute vec2 uv;
uniform sampler2D s_texture;
varying vec4 v_Color;
varying vec2 v_UV;
void main() {
    v_UV = uv;
    v_Color = color;
    gl_Position = a_v4Position;
}
"
    GLSL_150: b"
#version 150 core
in vec2 pos;
in vec3 color;
in vec2 uv;
uniform sampler2D s_texture;
out vec4 v_Color;
out vec2 v_UV;
void main() {
    v_UV = uv;
    v_Color = color;
    gl_Position = a_v4Position;
}
"
};

static FRAGMENT_SHADER_UV: gfx::ShaderSource = shaders!{
    GLSL_120: b"
#version 120
uniform sampler2D s_texture;
varying vec2 v_UV;
varying vec4 v_Color;
void main()
{
    gl_FragColor = texture(s_texture, v_UV) * v_Color;
}
"
    GLSL_150: b"
#version 150 core
out vec4 o_Color;
uniform sampler2D s_texture;
in vec2 v_UV;
in vec4 v_Color;
void main()
{
    o_Color = texture(s_texture, v_UV) * v_Color;
}
"
};

#[vertex_format]
struct Vertex {
    pos: [f32, ..2],
    color: [f32, ..4],
}

impl Vertex {
    fn new(pos: [f32, ..2], color: [f32, ..4], uv: [f32, ..2]) -> Vertex {
        Vertex {
            pos: pos,
            color: color,
        }
    }
}

#[vertex_format]
struct VertexUV {
    pos: [f32, ..2],
    color: [f32, ..4],
    uv: [f32, ..2],
}

impl VertexUV {
    fn new(pos: [f32, ..2], color: [f32, ..4], uv: [f32, ..2]) -> VertexUV {
        VertexUV {
            pos: pos,
            color: color,
            uv: uv,
        }
    }
}

#[shader_param(ProgramUV)]
struct ParamsUV {
    s_texture: gfx::shade::TextureParam,
}

/// The graphics back-end.
pub struct Gfx2d {
    state: gfx::DrawState,
    program: gfx::shade::EmptyProgram,
    program_uv: ProgramUV,
    vertex_data: Vec<Vertex>,
    vertex_data_uv: Vec<VertexUV>,
    renderer: gfx::Renderer,
}

impl Gfx2d {
    /// Creates a new Gfx2d object.
    pub fn new<D: gfx::Device>(device: &mut D) -> Gfx2d {
        Gfx2d {
            state: gfx::DrawState::new(),
            program: device.link_program(
                    VERTEX_SHADER.clone(),
                    FRAGMENT_SHADER.clone()
                ).unwrap(),
            program_uv: device.link_program(
                    VERTEX_SHADER_UV.clone(),
                    FRAGMENT_SHADER_UV.clone()
                ).unwrap(),
            vertex_data: Vec::with_capacity(BUFFER_SIZE),
            vertex_data_uv: Vec::with_capacity(BUFFER_SIZE),
            renderer: device.create_renderer(),
        }
    }
}

impl BackEnd<Texture> for Gfx2d {

}
<|endoftext|>


<commit_before>use std::ops::{BitXorAssign, MulAssign, ShrAssign};
use byteorder::{BigEndian, ByteOrder};

const R: GFBlock = GFBlock([0xe1 << 56, 0]);

#[derive(Clone, Copy)]
struct GFBlock([u64; 2]);

pub fn ghash(hash_key: &[u8], bytes: &[u8]) -> [u8; 16] {
    let h = GFBlock::new(hash_key);
    let mut y = GFBlock([0; 2]);
    for chunk in bytes.chunks(16) {
        y ^= GFBlock::new(chunk);
        y *= h;
    }
    y.into()
}

impl GFBlock {
    fn new(bytes: &[u8]) -> Self {
        assert_eq!(16, bytes.len());
        let mut longs = [0; 2];
        for (long, chunk) in longs.iter_mut().zip(bytes.chunks(8)) {
            *long = BigEndian::read_u64(chunk);
        }
        GFBlock(longs)
    }
}

impl From<GFBlock> for [u8; 16] {
    fn from(block: GFBlock) -> Self {
        let mut bytes = [0; 16];
        for (chunk, &long) in bytes.chunks_mut(8).zip(&block.0) {
            BigEndian::write_u64(chunk, long);
        }
        bytes
    }
}

impl BitXorAssign for GFBlock {
    fn bitxor_assign(&mut self, rhs: Self) {
        self.0[0] ^= rhs.0[0];
        self.0[1] ^= rhs.0[1];
    }
}

impl MulAssign for GFBlock {
    fn mul_assign(&mut self, rhs: Self) {
        let mut z = GFBlock([0; 2]);
        let mut v = rhs;
        for xp in self.0.iter_mut() {
            for _ in 0..64 {
                if *xp & (1 << 63) != 0 {
                    z ^= v;
                }
                *xp <<= 1;
                let h = v.0[1] & 1;
                v >>= 1;
                if h == 1 {
                    v ^= R;
                }
            }
        }
        self.0 = z.0;
    }
}

impl ShrAssign<usize> for GFBlock {
    fn shr_assign(&mut self, rhs: usize) {
        if rhs < 64 {
            self.0[1] >>= rhs;
            self.0[1] |= self.0[0] << (64 - rhs);
            self.0[0] >>= rhs;
        } else {
            self.0[1] = self.0[0] >> (rhs - 64);
            self.0[0] = 0;
        }
    }
}

#[cfg(test)]
mod tests {
    use ghash::*;

    #[test]
    fn test_ghash() {
        let h = [
            0x66,
            0xe9,
            0x4b,
            0xd4,
            0xef,
            0x8a,
            0x2c,
            0x3b,
            0x88,
            0x4c,
            0xfa,
            0x59,
            0xca,
            0x34,
            0x2b,
            0x2e,
        ];
        assert_eq!([0; 16], ghash(&h, &[0; 16]));

        let c = [
            0x03,
            0x88,
            0xda,
            0xce,
            0x60,
            0xb6,
            0xa3,
            0x92,
            0xf3,
            0x28,
            0xc2,
            0xb9,
            0x71,
            0xb2,
            0xfe,
            0x78,
        ];
        let mut bytes = [0; 32];
        bytes[..16].copy_from_slice(&c);
        bytes[31] = 0x80;
        let expected = [
            0xf3,
            0x8c,
            0xbb,
            0x1a,
            0xd6,
            0x92,
            0x23,
            0xdc,
            0xc3,
            0x45,
            0x7a,
            0xe5,
            0xb6,
            0xb0,
            0xf8,
            0x85,
        ];
        assert_eq!(expected, ghash(&h, &bytes));
    }
}
<commit_msg>ghash: ghash() -> h_xpoly(), key_hash -> key<commit_after>use std::ops::{BitXorAssign, MulAssign, ShrAssign};
use byteorder::{BigEndian, ByteOrder};

const R: GFBlock = GFBlock([0xe1 << 56, 0]);

#[derive(Clone, Copy)]
struct GFBlock([u64; 2]);

pub fn h_xpoly(key: &[u8], bytes: &[u8]) -> [u8; 16] {
    let h = GFBlock::new(key);
    let mut y = GFBlock([0; 2]);
    for chunk in bytes.chunks(16) {
        y ^= GFBlock::new(chunk);
        y *= h;
    }
    y.into()
}

impl GFBlock {
    fn new(bytes: &[u8]) -> Self {
        assert_eq!(16, bytes.len());
        let mut longs = [0; 2];
        for (long, chunk) in longs.iter_mut().zip(bytes.chunks(8)) {
            *long = BigEndian::read_u64(chunk);
        }
        GFBlock(longs)
    }
}

impl From<GFBlock> for [u8; 16] {
    fn from(block: GFBlock) -> Self {
        let mut bytes = [0; 16];
        for (chunk, &long) in bytes.chunks_mut(8).zip(&block.0) {
            BigEndian::write_u64(chunk, long);
        }
        bytes
    }
}

impl BitXorAssign for GFBlock {
    fn bitxor_assign(&mut self, rhs: Self) {
        self.0[0] ^= rhs.0[0];
        self.0[1] ^= rhs.0[1];
    }
}

impl MulAssign for GFBlock {
    fn mul_assign(&mut self, rhs: Self) {
        let mut z = GFBlock([0; 2]);
        let mut v = rhs;
        for xp in self.0.iter_mut() {
            for _ in 0..64 {
                if *xp & (1 << 63) != 0 {
                    z ^= v;
                }
                *xp <<= 1;
                let h = v.0[1] & 1;
                v >>= 1;
                if h == 1 {
                    v ^= R;
                }
            }
        }
        self.0 = z.0;
    }
}

impl ShrAssign<usize> for GFBlock {
    fn shr_assign(&mut self, rhs: usize) {
        if rhs < 64 {
            self.0[1] >>= rhs;
            self.0[1] |= self.0[0] << (64 - rhs);
            self.0[0] >>= rhs;
        } else {
            self.0[1] = self.0[0] >> (rhs - 64);
            self.0[0] = 0;
        }
    }
}

#[cfg(test)]
mod tests {
    use ghash::*;

    #[test]
    fn test_ghash() {
        let h = [
            0x66,
            0xe9,
            0x4b,
            0xd4,
            0xef,
            0x8a,
            0x2c,
            0x3b,
            0x88,
            0x4c,
            0xfa,
            0x59,
            0xca,
            0x34,
            0x2b,
            0x2e,
        ];
        assert_eq!([0; 16], h_xpoly(&h, &[0; 16]));

        let c = [
            0x03,
            0x88,
            0xda,
            0xce,
            0x60,
            0xb6,
            0xa3,
            0x92,
            0xf3,
            0x28,
            0xc2,
            0xb9,
            0x71,
            0xb2,
            0xfe,
            0x78,
        ];
        let mut bytes = [0; 32];
        bytes[..16].copy_from_slice(&c);
        bytes[31] = 0x80;
        let expected = [
            0xf3,
            0x8c,
            0xbb,
            0x1a,
            0xd6,
            0x92,
            0x23,
            0xdc,
            0xc3,
            0x45,
            0x7a,
            0xe5,
            0xb6,
            0xb0,
            0xf8,
            0x85,
        ];
        assert_eq!(expected, h_xpoly(&h, &bytes));
    }
}
<|endoftext|>


<commit_before>/// Incremental Graph Representations

use std::fmt::Debug;
use std::hash::Hash;
use std::rc::Rc;

use adapton::engine::{cell, ns, name_of_str, name_unit, Name};
use adapton::collections::{list_of_tree, tree_fold_seq, tree_of_list, Dir2, List, ListIntro,
                           MapIntro, MapElim, SetIntro, Tree, TreeIntro};
use adapton::collections::trie::{trie_fold_seq, Set, Trie, TrieIntro};

/// Representation of a graph as a list of edges, where edges are
/// a pair of node ids.
#[derive(Debug,PartialEq,Eq,Hash,Clone)]
pub struct Graph<Node> {
    edge_tree: Tree<(Node, Node)>,
}

/// Representation of a graph as finite map from node ids to
/// an outgoing adjacency list of node ids.
#[derive(Debug,PartialEq,Eq,Hash,Clone)]
pub struct AdjacencyGraph<Node>
    where Node: Debug + Clone + Hash + PartialEq + Eq + 'static
{
    adjacency_map: Trie<(Node, Tree<Node>)>,
}

/// Produce a graph.
pub trait GraphIntro<Node>: Debug + Clone + Hash + PartialEq + Eq {
    /// Yields an empty graph, i.e. no vertices or edges.
    fn empty() -> Self;
    /// Adds the edge `(src, dst)` named `nm` to the graph `graph`.
    fn add_edge(graph: Self, nm: Name, src: Node, dst: Node) -> Self;
}

/// Reduce a graph to a value.
pub trait GraphElim<Node>: Debug + Clone + Hash + PartialEq + Eq {
    /// Returns a set of the edges in the graph `graph`.
    fn edges(graph: &Self) -> Set<(Node, Node)>;
    /// Returns a set of the vertices of the graph `graph`.
    fn vertices(graph: &Self) -> Set<Node>;
}

impl<Node: Debug + Clone + Hash + PartialEq + Eq + 'static> GraphIntro<Node> for Graph<Node> {
    fn empty() -> Graph<Node> {
        Graph::<Node> { edge_tree: Tree::nil() }
    }

    fn add_edge(graph: Graph<Node>, nm: Name, src: Node, dst: Node) -> Graph<Node> {
        let edge_list = ns(name_of_str("list_of_tree"),
                           move || list_of_tree(graph.edge_tree, Dir2::Left));
        let el = List::name_art(Some(nm), edge_list);
        let el = List::cons((src, dst), el);
        let edge_tree = ns(name_of_str("tree_of_list"),
                           || tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, el));
        Graph::<Node> { edge_tree: edge_tree }
    }
}

impl<Node: Debug + Clone + Hash + PartialEq + Eq + 'static> GraphElim<Node> for Graph<Node> {
    fn edges(graph: &Graph<Node>) -> Set<(Node, Node)> {
        tree_fold_seq(graph.edge_tree.clone(),
                      Dir2::Left,
                      SetIntro::empty(),
                      Rc::new(|e, set| SetIntro::add(set, e)),
                      Rc::new(|_, set| set),
                      Rc::new(|nm: Name, _, set| {
                          TrieIntro::name(nm.clone(), TrieIntro::art(cell(nm, set)))
                      }))
    }

    fn vertices(graph: &Graph<Node>) -> Set<Node> {
        let edge_trie = ns(name_of_str("edge_trie_vertices"), || Self::edges(graph));
        trie_fold_seq(edge_trie,
                      SetIntro::empty(),
                      Rc::new(|((src,dst), ()), set| {
                          let add_src = SetIntro::add(set, src);
                          SetIntro::add(add_src, dst)
                      }),
                      Rc::new(move |set| set),
                      Rc::new(move |n: Name, set| {
                          Set::name(n.clone(), Set::art(cell(n, set)))
                      }))
    }
}

impl<Node: Debug + Clone + Hash + PartialEq + Eq + 'static>
    GraphIntro<Node> for AdjacencyGraph<Node> {
        fn empty() -> AdjacencyGraph<Node> {
            AdjacencyGraph::<Node> {
                adjacency_map: MapIntro::empty(),
            }
        }

        fn add_edge(graph: AdjacencyGraph<Node>,
                    nm: Name, src: Node, dst: Node) -> AdjacencyGraph<Node> {
            let src_adj_list = MapElim::find(&graph.adjacency_map, &src);
            match src_adj_list {
                None => {
                    // let adj = List::name_art(Some(nm.clone()), List::nil());
                    let adj = List::cons(dst, List::nil());
                    let edge_tree = tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, adj);
                    AdjacencyGraph::<Node> {
                        adjacency_map: TrieIntro::extend(nm, graph.adjacency_map,
                                                         (src, edge_tree)),
                    }
                }
                Some(adj_nodes) => {
                    let adj = list_of_tree(adj_nodes, Dir2::Left);
                    // let adj = List::name_art(Some(nm.clone()), adj);
                    let adj = List::cons(dst, adj);
                    let edge_tree = tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, adj);
                    AdjacencyGraph::<Node> {
                        adjacency_map: TrieIntro::extend(nm, graph.adjacency_map,
                                                         (src, edge_tree)),
                    }
                }
            }
        }
    }

impl<Node: Debug + Copy + Clone + Hash + PartialEq + Eq + 'static>
    GraphElim<Node> for AdjacencyGraph<Node> {
        fn edges(graph: &AdjacencyGraph<Node>) -> Set<(Node, Node)> {
            trie_fold_seq(graph.adjacency_map.clone(), SetIntro::empty(),
                          Rc::new(|(src, dsts), set|
                                  tree_fold_seq(dsts, Dir2::Left, set,
                                                Rc::new(move |dst, set|
                                                        SetIntro::add(set, (src, dst))),
                                                Rc::new(|_, set| set),
                                                Rc::new(|nm: Name, _, set| {
                                                    TrieIntro::name(nm.clone(),
                                                                    TrieIntro::art(cell(nm,
                                                                                set)))
                                                }))),
                          Rc::new(|set| set),
                          Rc::new(|nm: Name, set|
                                  TrieIntro::name(nm.clone(),
                                                  TrieIntro::art(cell(nm, set)))))
        }

        fn vertices(graph: &AdjacencyGraph<Node>) -> Set<Node> {
            trie_fold_seq(graph.adjacency_map.clone(), SetIntro::empty(),
                          Rc::new(|(src, dsts), set| {
                              let src_set = SetIntro::add(set, src);
                              tree_fold_seq(dsts, Dir2::Left, src_set,
                                            Rc::new(|dst, set| SetIntro::add(set, dst)),
                                            Rc::new(|_, set| set),
                                            Rc::new(|nm: Name, _, set|
                                                    TrieIntro::name(nm.clone(),
                                                                    TrieIntro::art(cell(nm, set)))))
                          }),
                          Rc::new(|set| set),
                          Rc::new(|nm: Name, set| TrieIntro::name(nm.clone(),
                                                                  TrieIntro::art(cell(nm, set)))))
        }
    }

pub fn adjacency_of_edge_list<X: Hash + Clone + Debug + PartialEq + Eq>(el_graph: &Graph<X>)
                                                                        -> AdjacencyGraph<X> {
    let adj_graph = AdjacencyGraph::empty();
    tree_fold_seq(el_graph.edge_tree.clone(),
                  Dir2::Left,
                  adj_graph,
                  Rc::new(|(src, dst), g| AdjacencyGraph::add_edge(g, name_unit(), src, dst)),
                  Rc::new(|_, set| set),
                  Rc::new(|nm: Name, _, g: AdjacencyGraph<_>| {
                      let adj = TrieIntro::name(nm.clone(),
                                                TrieIntro::art(cell(nm, g.adjacency_map)));
                      AdjacencyGraph { adjacency_map: adj }
                  }))
}

pub fn edge_list_of_adjacency<X: Hash + Clone + Debug + PartialEq + Eq>(adj_graph: &AdjacencyGraph<X>)
                                                                        -> Graph<X> {
    let edge_list = Graph::empty();
    trie_fold_seq(adj_graph.adjacency_map.clone(),
                  edge_list,
                  Rc::new(|(src, dsts): (X, Tree<X>), graph: Graph<X>| {
                      let edge_tree = tree_fold_seq(dsts, Dir2::Left, graph.edge_tree,
                                                    Rc::new(move |dst, g| {
                                                        let edge_list = ns(name_of_str("list_of_tree"),
                                                                           move || list_of_tree(g, Dir2::Left));
                                                        let el = List::cons((src.clone(), dst), edge_list);
                                                        ns(name_of_str("tree_of_list"),
                                                           || tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, el))
                                                    }),
                                                    Rc::new(|_, g| g),
                                                    Rc::new(|nm: Name, _, g| {
                                                        let edge_list = ns(name_of_str("list_of_tree"),
                                                                           move || list_of_tree(g, Dir2::Left));
                                                        let el = List::name_art(Some(nm), edge_list);
                                                        ns(name_of_str("tree_of_list"),
                                                           || tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, el))
                                                    }));
                      Graph::<X> { edge_tree: edge_tree }
                  }),
                  Rc::new(|g| g),
                  Rc::new(|nm: Name, g: Graph<X>| {
                      let edge_list = ns(name_of_str("list_of_tree"),
                                         move || list_of_tree(g.edge_tree, Dir2::Left));
                      let el = List::name_art(Some(nm), edge_list);
                      let edge_tree = ns(name_of_str("tree_of_list"),
                                         || tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, el));
                      Graph::<X> { edge_tree: edge_tree }
                  }))
}
<commit_msg>rustfmt<commit_after>/// Incremental Graph Representations

use std::fmt::Debug;
use std::hash::Hash;
use std::rc::Rc;

use adapton::engine::{cell, ns, name_of_str, name_unit, Name};
use adapton::collections::{list_of_tree, tree_fold_seq, tree_of_list, Dir2, List, ListIntro,
                           MapIntro, MapElim, SetIntro, Tree, TreeIntro};
use adapton::collections::trie::{trie_fold_seq, Set, Trie, TrieIntro};

/// Representation of a graph as a list of edges, where edges are
/// a pair of node ids.
#[derive(Debug,PartialEq,Eq,Hash,Clone)]
pub struct Graph<Node> {
    edge_tree: Tree<(Node, Node)>,
}

/// Representation of a graph as finite map from node ids to
/// an outgoing adjacency list of node ids.
#[derive(Debug,PartialEq,Eq,Hash,Clone)]
pub struct AdjacencyGraph<Node>
    where Node: Debug + Clone + Hash + PartialEq + Eq + 'static
{
    adjacency_map: Trie<(Node, Tree<Node>)>,
}

/// Produce a graph.
pub trait GraphIntro<Node>: Debug + Clone + Hash + PartialEq + Eq {
    /// Yields an empty graph, i.e. no vertices or edges.
    fn empty() -> Self;
    /// Adds the edge `(src, dst)` named `nm` to the graph `graph`.
    fn add_edge(graph: Self, nm: Name, src: Node, dst: Node) -> Self;
}

/// Reduce a graph to a value.
pub trait GraphElim<Node>: Debug + Clone + Hash + PartialEq + Eq {
    /// Returns a set of the edges in the graph `graph`.
    fn edges(graph: &Self) -> Set<(Node, Node)>;
    /// Returns a set of the vertices of the graph `graph`.
    fn vertices(graph: &Self) -> Set<Node>;
}

impl<Node: Debug + Clone + Hash + PartialEq + Eq + 'static> GraphIntro<Node> for Graph<Node> {
    fn empty() -> Graph<Node> {
        Graph::<Node> { edge_tree: Tree::nil() }
    }

    fn add_edge(graph: Graph<Node>, nm: Name, src: Node, dst: Node) -> Graph<Node> {
        let edge_list = ns(name_of_str("list_of_tree"),
                           move || list_of_tree(graph.edge_tree, Dir2::Left));
        let el = List::name_art(Some(nm), edge_list);
        let el = List::cons((src, dst), el);
        let edge_tree = ns(name_of_str("tree_of_list"),
                           || tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, el));
        Graph::<Node> { edge_tree: edge_tree }
    }
}

impl<Node: Debug + Clone + Hash + PartialEq + Eq + 'static> GraphElim<Node> for Graph<Node> {
    fn edges(graph: &Graph<Node>) -> Set<(Node, Node)> {
        tree_fold_seq(graph.edge_tree.clone(),
                      Dir2::Left,
                      SetIntro::empty(),
                      Rc::new(|e, set| SetIntro::add(set, e)),
                      Rc::new(|_, set| set),
                      Rc::new(|nm: Name, _, set| {
                          TrieIntro::name(nm.clone(), TrieIntro::art(cell(nm, set)))
                      }))
    }

    fn vertices(graph: &Graph<Node>) -> Set<Node> {
        let edge_trie = ns(name_of_str("edge_trie_vertices"), || Self::edges(graph));
        trie_fold_seq(edge_trie,
                      SetIntro::empty(),
                      Rc::new(|((src,dst), ()), set| {
                          let add_src = SetIntro::add(set, src);
                          SetIntro::add(add_src, dst)
                      }),
                      Rc::new(move |set| set),
                      Rc::new(move |n: Name, set| {
                          Set::name(n.clone(), Set::art(cell(n, set)))
                      }))
    }
}

impl<Node: Debug + Clone + Hash + PartialEq + Eq + 'static>
    GraphIntro<Node> for AdjacencyGraph<Node> {
        fn empty() -> AdjacencyGraph<Node> {
            AdjacencyGraph::<Node> {
                adjacency_map: MapIntro::empty(),
            }
        }

        fn add_edge(graph: AdjacencyGraph<Node>,
                    nm: Name, src: Node, dst: Node) -> AdjacencyGraph<Node> {
            let src_adj_list = MapElim::find(&graph.adjacency_map, &src);
            match src_adj_list {
                None => {
                    // let adj = List::name_art(Some(nm.clone()), List::nil());
                    let adj = List::cons(dst, List::nil());
                    let edge_tree = tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, adj);
                    AdjacencyGraph::<Node> {
                        adjacency_map: TrieIntro::extend(nm, graph.adjacency_map,
                                                         (src, edge_tree)),
                    }
                }
                Some(adj_nodes) => {
                    let adj = list_of_tree(adj_nodes, Dir2::Left);
                    // let adj = List::name_art(Some(nm.clone()), adj);
                    let adj = List::cons(dst, adj);
                    let edge_tree = tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, adj);
                    AdjacencyGraph::<Node> {
                        adjacency_map: TrieIntro::extend(nm, graph.adjacency_map,
                                                         (src, edge_tree)),
                    }
                }
            }
        }
    }

impl<Node: Debug + Copy + Clone + Hash + PartialEq + Eq + 'static>
    GraphElim<Node> for AdjacencyGraph<Node> {
        fn edges(graph: &AdjacencyGraph<Node>) -> Set<(Node, Node)> {
            trie_fold_seq(graph.adjacency_map.clone(), SetIntro::empty(),
                          Rc::new(|(src, dsts), set|
                                  tree_fold_seq(dsts, Dir2::Left, set,
                                                Rc::new(move |dst, set|
                                                        SetIntro::add(set, (src, dst))),
                                                Rc::new(|_, set| set),
                                                Rc::new(|nm: Name, _, set| {
                                                    TrieIntro::name(nm.clone(),
                                                                    TrieIntro::art(cell(nm,
                                                                                set)))
                                                }))),
                          Rc::new(|set| set),
                          Rc::new(|nm: Name, set|
                                  TrieIntro::name(nm.clone(),
                                                  TrieIntro::art(cell(nm, set)))))
        }

        fn vertices(graph: &AdjacencyGraph<Node>) -> Set<Node> {
            trie_fold_seq(graph.adjacency_map.clone(), SetIntro::empty(),
                          Rc::new(|(src, dsts), set| {
                              let src_set = SetIntro::add(set, src);
                              tree_fold_seq(dsts, Dir2::Left, src_set,
                                            Rc::new(|dst, set| SetIntro::add(set, dst)),
                                            Rc::new(|_, set| set),
                                            Rc::new(|nm: Name, _, set|
                                                    TrieIntro::name(nm.clone(),
                                                                    TrieIntro::art(cell(nm, set)))))
                          }),
                          Rc::new(|set| set),
                          Rc::new(|nm: Name, set| TrieIntro::name(nm.clone(),
                                                                  TrieIntro::art(cell(nm, set)))))
        }
    }

pub fn adjacency_of_edge_list<X: Hash + Clone + Debug + PartialEq + Eq>(el_graph: &Graph<X>)
                                                                        -> AdjacencyGraph<X> {
    let adj_graph = AdjacencyGraph::empty();
    tree_fold_seq(el_graph.edge_tree.clone(),
                  Dir2::Left,
                  adj_graph,
                  Rc::new(|(src, dst), g| AdjacencyGraph::add_edge(g, name_unit(), src, dst)),
                  Rc::new(|_, set| set),
                  Rc::new(|nm: Name, _, g: AdjacencyGraph<_>| {
                      let adj = TrieIntro::name(nm.clone(),
                                                TrieIntro::art(cell(nm, g.adjacency_map)));
                      AdjacencyGraph { adjacency_map: adj }
                  }))
}

pub fn edge_list_of_adjacency
    <X: Hash + Clone + Debug + PartialEq + Eq>(adj_graph: &AdjacencyGraph<X>)
                                               -> Graph<X> {
    let edge_list = Graph::empty();
    trie_fold_seq(adj_graph.adjacency_map.clone(),
                  edge_list,
                  Rc::new(|(src, dsts): (X, Tree<X>), graph: Graph<X>| {
        let edge_tree = tree_fold_seq(dsts,
                                      Dir2::Left,
                                      graph.edge_tree,
                                      Rc::new(move |dst, g| {
            let edge_list = ns(name_of_str("list_of_tree"),
                               move || list_of_tree(g, Dir2::Left));
            let el = List::cons((src.clone(), dst), edge_list);
            ns(name_of_str("tree_of_list"),
               || tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, el))
        }),
                                      Rc::new(|_, g| g),
                                      Rc::new(|nm: Name, _, g| {
            let edge_list = ns(name_of_str("list_of_tree"),
                               move || list_of_tree(g, Dir2::Left));
            let el = List::name_art(Some(nm), edge_list);
            ns(name_of_str("tree_of_list"),
               || tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, el))
        }));
        Graph::<X> { edge_tree: edge_tree }
    }),
                  Rc::new(|g| g),
                  Rc::new(|nm: Name, g: Graph<X>| {
        let edge_list = ns(name_of_str("list_of_tree"),
                           move || list_of_tree(g.edge_tree, Dir2::Left));
        let el = List::name_art(Some(nm), edge_list);
        let edge_tree = ns(name_of_str("tree_of_list"),
                           || tree_of_list::<_, _, Tree<_>, _>(Dir2::Left, el));
        Graph::<X> { edge_tree: edge_tree }
    }))
}
<|endoftext|>


<commit_before>use std::collections::{HashSet, RingBuf, Deque};

struct GraphError {
    error_type: GraphErrorType,
}

impl GraphError {
    fn invalid_index(ind: NodeIndex) -> GraphError {
        GraphError { error_type: InvalidNodeIndex(ind) }
    }
}

enum GraphErrorType {
    InvalidNodeIndex(NodeIndex),
}

type NodeIndex = uint;

struct Graph<S> {
    nodes: Vec<Node<S>>,
    adj: Vec<HashSet<NodeIndex>>,
    num_nodes: uint,
}

#[deriving(Show)]
struct Node<S> {
    data: S,
    index: NodeIndex,
}

impl<S> Graph<S> {
    pub fn new() -> Graph<S> {
        Graph { nodes: vec!(), adj: vec!(), num_nodes: 0 }
    }

    /// Insert a new node, returning its index
    pub fn add_node(&mut self, val: S) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.push(Node { data: val, index: ind });
        self.adj.push(HashSet::new());
        self.num_nodes += 1;
        ind
    }

    pub fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> Result<bool, GraphError> {
        if i >= self.num_nodes {
            Err(GraphError::invalid_index(i))
        } else if j >= self.num_nodes {
            Err(GraphError::invalid_index(j))
        } else {
            if self.adj[i].contains(&j) {
                Ok(false)
            } else {
                self.adj.get_mut(i).insert(j);
                self.adj.get_mut(j).insert(i);
                Ok(true)
            }
        }
    }

    pub fn degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.adj[ind].len())
        }
    }

    pub fn bfs(&self) -> Digraph<NodeIndex> {
        let mut tree = Digraph::new();

        if self.num_nodes == 0 {
            return tree;
        }

        let mut visited = HashSet::new();
        let mut ondeck = RingBuf::new();

        ondeck.push_back((0, None));
        loop {
            match ondeck.pop_front() {
                None => break,
                Some((ind, parent)) => {
                    tree.add_node(ind);
                    if parent.is_some() {
                        tree.add_edge(parent.unwrap(), ind);
                    }
                    visited.insert(ind);

                    for i in self.adj[ind].iter() {
                        if !visited.contains(i) {
                            ondeck.push_back((*i, Some(ind)));
                        }
                    }
                }
            }
        }
        return tree;
    }
}

#[deriving(Show)]
struct Digraph<S> {
    nodes: Vec<Node<S>>,
    in_adj: Vec<HashSet<NodeIndex>>,
    out_adj: Vec<HashSet<NodeIndex>>,
    num_nodes: uint,
}

impl<S> Digraph<S> {
    pub fn new() -> Digraph<S> {
        Digraph { nodes: vec!(), in_adj: vec!(), out_adj: vec!(), num_nodes: 0 }
    }

    /// Insert a new node, returning its index
    pub fn add_node(&mut self, val: S) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.push(Node { data: val, index: ind });
        self.in_adj.push(HashSet::new());
        self.out_adj.push(HashSet::new());
        self.num_nodes += 1;
        ind
    }

    pub fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> Result<bool, GraphError> {
        if i >= self.num_nodes {
            Err(GraphError::invalid_index(i))
        } else if j >= self.num_nodes {
            Err(GraphError::invalid_index(j))
        } else {
            if self.out_adj[i].contains(&j) {
                Ok(false)
            } else {
                self.out_adj.get_mut(i).insert(j);
                self.in_adj.get_mut(j).insert(i);
                Ok(true)
            }
        }
    }

    pub fn out_degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.out_adj[ind].len())
        }
    }

    pub fn in_degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.in_adj[ind].len())
        }
    }

    pub fn bfs(&self) -> Digraph<NodeIndex> {
        let mut tree = Digraph::new();

        if self.num_nodes == 0 {
            return tree;
        }

        let mut visited = HashSet::new();
        let mut ondeck = RingBuf::new();

        ondeck.push_back((0, None));
        loop {
            match ondeck.pop_front() {
                None => break,
                Some((ind, parent)) => {
                    tree.add_node(ind);
                    if parent.is_some() {
                        tree.add_edge(parent.unwrap(), ind);
                    }
                    visited.insert(ind);

                    for i in self.out_adj[ind].iter() {
                        if !visited.contains(i) {
                            ondeck.push_back((*i, Some(ind)));
                        }
                    }
                }
            }
        }
        return tree;
    }
}
<commit_msg>Add a Graph trait so we can have one implementation of BFS. REname Graph type to UnGraph.<commit_after>use std::collections::{HashSet, RingBuf, Deque};
use std::collections::hashmap::SetItems;

trait Graph<T> {
    /// Insert a new node, returning its index
    fn add_node(&mut self, val: T) -> NodeIndex;

    /// Insert a new edge, returning an error if one of the indices is invalid
    /// and a result otherwise
    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool>;

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a>;

    /// Return the number of nodes in the graph
    fn num_nodes(&self) -> uint;

    fn bfs(&self) -> Digraph<NodeIndex> {
        let mut tree = Digraph::new();

        if self.num_nodes() == 0 {
            return tree;
        }

        let mut visited = HashSet::new();
        let mut ondeck = RingBuf::new();

        ondeck.push_back((0, None));
        loop {
            match ondeck.pop_front() {
                None => break,
                Some((ind, parent)) => {
                    tree.add_node(ind);
                    if parent.is_some() {
                        tree.add_edge(parent.unwrap(), ind);
                    }
                    visited.insert(ind);

                    for i in self.adj(ind) {
                        if !visited.contains(i) {
                            ondeck.push_back((*i, Some(ind)));
                        }
                    }
                }
            }
        }
        return tree;
    }
}

struct GraphError {
    error_type: GraphErrorType,
}

impl GraphError {
    fn invalid_index(ind: NodeIndex) -> GraphError {
        GraphError { error_type: InvalidNodeIndex(ind) }
    }
}

type GraphResult<T> = Result<T, GraphError>;

enum GraphErrorType {
    InvalidNodeIndex(NodeIndex),
}

type NodeIndex = uint;

#[deriving(Show)]
struct Node<T> {
    data: T,
    index: NodeIndex,
}

/// Undirected graph. Allows loops.
#[deriving(Show)]
struct UnGraph<T> {
    nodes: Vec<Node<T>>,
    adj: Vec<HashSet<NodeIndex>>,
    num_nodes: uint,
}

/// Directed graph. Allows loops.
#[deriving(Show)]
struct Digraph<T> {
    nodes: Vec<Node<T>>,
    in_adj: Vec<HashSet<NodeIndex>>,
    out_adj: Vec<HashSet<NodeIndex>>,
    num_nodes: uint,
}

impl<T> UnGraph<T> {
    pub fn new() -> UnGraph<T> {
        UnGraph { nodes: vec!(), adj: vec!(), num_nodes: 0 }
    }

    pub fn degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.adj[ind].len())
        }
    }
}

impl<T> Graph<T> for UnGraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.push(Node { data: val, index: ind });
        self.adj.push(HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if i >= self.num_nodes {
            Err(GraphError::invalid_index(i))
        } else if j >= self.num_nodes {
            Err(GraphError::invalid_index(j))
        } else {
            if self.adj[i].contains(&j) {
                Ok(false)
            } else {
                self.adj.get_mut(i).insert(j);
                self.adj.get_mut(j).insert(i);
                Ok(true)
            }
        }
    }

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a> {
        NodeIndices::from_set(&self.adj[i])
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }
}

impl<T> Digraph<T> {
    pub fn new() -> Digraph<T> {
        Digraph { nodes: vec!(), in_adj: vec!(), out_adj: vec!(), num_nodes: 0 }
    }

    pub fn out_degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.out_adj[ind].len())
        }
    }

    pub fn in_degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.in_adj[ind].len())
        }
    }
}

impl<T> Graph<T> for Digraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.push(Node { data: val, index: ind });
        self.in_adj.push(HashSet::new());
        self.out_adj.push(HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if i >= self.num_nodes {
            Err(GraphError::invalid_index(i))
        } else if j >= self.num_nodes {
            Err(GraphError::invalid_index(j))
        } else {
            if self.out_adj[i].contains(&j) {
                Ok(false)
            } else {
                self.out_adj.get_mut(i).insert(j);
                self.in_adj.get_mut(j).insert(i);
                Ok(true)
            }
        }
    }

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a> {
        NodeIndices::from_set(&self.out_adj[i])
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }
}

struct NodeIndices<'a> {
    indices: SetItems<'a, NodeIndex>,
}

impl<'a> Iterator<&'a NodeIndex> for NodeIndices<'a> {
    fn next(&mut self) -> Option<&'a NodeIndex> {
        self.indices.next()
    }
}

impl<'a> NodeIndices<'a> {
    fn from_set(set: &'a HashSet<NodeIndex>) -> NodeIndices<'a> {
        NodeIndices { indices: set.iter() }
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add, Sub, Mul, Div, Index, IndexMut};

use interpolation::Spatial;

/// A point in 2D space
///
/// # Creating a Point
///
/// Methods like [`Turtle::go_to()`], [`Turtle::turn_towards()`] and [`Drawing::set_center()`]
/// all support any type that can be converted into `Point`. That means that you can pass the
/// same value into those methods in several different ways depending on what you prefer:
///
/// ```rust
/// # extern crate turtle;
/// # use turtle::Turtle;
/// # fn main() {
/// # let mut turtle = Turtle::new();
/// // These are equivalent
/// turtle.go_to([100.0, 40.0]);
/// turtle.go_to((100.0, 40.0));
/// // This is equivalent too, but the above examples are easier to type
/// use turtle::Point;
/// turtle.go_to(Point {x: 100.0, y: 40.0});
/// # }
/// ```
///
/// Each of these different styles works because the methods call
/// [`.into()`](https://doc.rust-lang.org/std/convert/trait.Into.html) internally.
///
/// ```rust
/// # extern crate turtle;
/// # use turtle::Point;
/// # fn main() {
/// assert_eq!(Point {x: 100.0, y: 40.0}, [100.0, 40.0].into());
/// assert_eq!(Point {x: 100.0, y: 40.0}, (100.0, 40.0).into());
/// # }
/// ```
///
/// Notice that we need to convert the right side using `into()` before it can be compared
/// in `assert_eq!()`.
///
/// ```rust,compile_fail,E0308
/// # extern crate turtle;
/// # use turtle::Point;
/// # fn main() {
/// // This will not compile
/// assert_eq!(Point {x: 100.0, y: 40.0}, [100.0, 40.0]);
/// assert_eq!(Point {x: 100.0, y: 40.0}, (100.0, 40.0));
/// # }
/// ```
///
/// # Manipulating Points
///
/// You can add or subtract points and multiply or divide points by scalar (f64) values. There
/// are a variety of [method functions](struct.Point.html#methods) described in the
/// documentation below that provide even more operations.
///
/// ```rust
/// # extern crate turtle;
/// # use turtle::Point;
/// # fn main() {
/// # let a = 320.0; let b = 400.0; let c = 70.0; let d = 95.0;
/// // Let's say you have two points with f64 values a, b, c, and d
/// let pt = Point {x: a, y: b};
/// let pt2 = Point {x: c, y: d};
/// assert_eq!(pt + pt2, Point {x: a + c, y: b + d});
/// assert_eq!(pt - pt2, Point {x: a - c, y: b - d});
/// assert_eq!(pt * 2.0, Point {x: a * 2.0, y: b * 2.0});
/// assert_eq!(pt2 / 5.0, Point {x: c / 5.0, y: d / 5.0});
/// assert_eq!(pt2 * 2.0 - pt, Point {x: c * 2.0 - a, y: d * 2.0 - b});
/// # }
/// ```
///
/// # Accessing Point Components
///
/// `Point` supports either using the `x` and `y` fields to access its components or using
/// indexing if you prefer that style.
///
/// ```rust
/// # extern crate turtle;
/// # use turtle::Point;
/// # fn main() {
/// let p = Point {x: 100.0, y: 120.0};
///
/// // Get x coordinate
/// let x = p.x;
/// assert_eq!(x, 100.0);
/// assert_eq!(p[0], x);
///
/// // Get y coordinate
/// let y = p.y;
/// assert_eq!(y, 120.0);
/// assert_eq!(p[1], y);
///
/// // With pattern matching
/// let Point {x, y} = p;
/// assert_eq!(x, 100.0);
/// assert_eq!(y, 120.0);
///
/// // Modifying x and y
/// let mut pt: Point = [240.0, 430.0].into();
/// # assert_eq!(pt.x, 240.0);
/// # assert_eq!(pt.y, 430.0);
/// pt.x = 73.0;
/// pt.y = 89.0;
/// assert_eq!(pt.x, 73.0);
/// assert_eq!(pt.y, 89.0);
/// // Using indexing
/// let mut pt2: Point = [100.0, 200.0].into();
/// # assert_eq!(pt2.x, 100.0);
/// # assert_eq!(pt2.y, 200.0);
/// pt2[0] = pt.x;
/// pt2[1] = pt.y;
/// assert_eq!(pt2.x, 73.0);
/// assert_eq!(pt2.y, 89.0);
/// # }
/// ```
///
/// [`Turtle::go_to()`]: struct.Turtle.html#method.go_to
/// [`Turtle::turn_towards()`]: struct.Turtle.html#method.turn_towards
/// [`Drawing::set_center()`]: struct.Drawing.html#method.set_center
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Point {
    /// The x-coordinate of the Point
    pub x: f64,
    /// The y-coordinate of the Point
    pub y: f64,
}

impl Point {
    /// Returns a Point that represents the origin of the coordinate system.
    ///
    /// For our "cartesian" coordinate system, this is always (0.0, 0.0)
    pub fn origin() -> Self {
        Point {x: 0.0, y: 0.0}
    }

    /// Returns true if both x and y are finite (neither infinite nor `NaN`).
    pub fn is_finite(self) -> bool {
        self.x.is_finite() && self.y.is_finite()
    }

    /// Returns true if both x and y are neither zero, infinite,
    /// [subnormal](https://en.wikipedia.org/wiki/Denormal_number), or `NaN`.
    pub fn is_normal(self) -> bool {
        self.x.is_normal() && self.y.is_normal()
    }

    /// Returns true if both x and y are either zero, infinite,
    /// [subnormal](https://en.wikipedia.org/wiki/Denormal_number), or `NaN`.
    pub fn is_not_normal(self) -> bool {
        !self.x.is_normal() && !self.y.is_normal()
    }

    /// Computes the absolute value of x and y and returns a new `Point`
    pub fn abs(self) -> Self {
        Point {x: self.x.abs(), y: self.y.abs()}
    }

    /// Returns a new `Point` with x and y set to the nearest integer to each of their values.
    /// Rounds half-way cases away from 0.0.
    pub fn round(self) -> Self {
        Point {x: self.x.round(), y: self.y.round()}
    }

    /// Returns the square of the length of this point.
    ///
    /// The length of a point is defined as `sqrt(x^2 + y^2)`
    pub fn square_len(self) -> f64 {
        self.x.powi(2) + self.y.powi(2)
    }

    /// Returns the length of this point.
    ///
    /// The length of a point is defined as `sqrt(x^2 + y^2)`
    pub fn len(self) -> f64 {
        self.square_len().sqrt()
    }

    /// Computes the four quadrant arctangent of `self.y` and `self.x`.
    pub fn atan2(self) -> f64 {
        self.y.atan2(self.x)
    }
}

impl From<(f64, f64)> for Point {
    fn from(pt: (f64, f64)) -> Self {
        Point {x: pt.0, y: pt.1}
    }
}

impl From<[f64; 2]> for Point {
    fn from(pt: [f64; 2]) -> Self {
        Point {x: pt[0], y: pt[1]}
    }
}

impl From<Point> for [f64; 2] {
    fn from(pt: Point) -> Self {
        [pt.x, pt.y]
    }
}

impl Add for Point {
    type Output = Point;

    fn add(self, other: Self) -> Self::Output {
        Point {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

impl Sub for Point {
    type Output = Point;

    fn sub(self, other: Self) -> Self::Output {
        Point {
            x: self.x - other.x,
            y: self.y - other.y,
        }
    }
}

impl Mul<f64> for Point {
    type Output = Point;

    fn mul(self, other: f64) -> Self::Output {
        Point {
            x: self.x * other,
            y: self.y * other,
        }
    }
}

impl Div<f64> for Point {
    type Output = Point;

    fn div(self, other: f64) -> Self::Output {
        Point {
            x: self.x / other,
            y: self.y / other,
        }
    }
}

impl Index<usize> for Point {
    type Output = f64;

    fn index(&self, index: usize) -> &Self::Output {
        match index {
            0 => &self.x,
            1 => &self.y,
            _ => panic!("Invalid coordinate for Point: {}", index),
        }
    }
}

impl IndexMut<usize> for Point {
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        match index {
            0 => &mut self.x,
            1 => &mut self.y,
            _ => panic!("Invalid coordinate for Point: {}", index),
        }
    }
}

impl Spatial for Point {
    type Scalar = f64;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        *self + *other
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        *self - *other
    }

    #[inline(always)]
    fn scale(&self, scalar: &Self::Scalar) -> Self {
        *self * *scalar
    }
}
<commit_msg>Using Self instead of Point directly<commit_after>use std::ops::{Add, Sub, Mul, Div, Index, IndexMut};

use interpolation::Spatial;

/// A point in 2D space
///
/// # Creating a Point
///
/// Methods like [`Turtle::go_to()`], [`Turtle::turn_towards()`] and [`Drawing::set_center()`]
/// all support any type that can be converted into `Point`. That means that you can pass the
/// same value into those methods in several different ways depending on what you prefer:
///
/// ```rust
/// # extern crate turtle;
/// # use turtle::Turtle;
/// # fn main() {
/// # let mut turtle = Turtle::new();
/// // These are equivalent
/// turtle.go_to([100.0, 40.0]);
/// turtle.go_to((100.0, 40.0));
/// // This is equivalent too, but the above examples are easier to type
/// use turtle::Point;
/// turtle.go_to(Point {x: 100.0, y: 40.0});
/// # }
/// ```
///
/// Each of these different styles works because the methods call
/// [`.into()`](https://doc.rust-lang.org/std/convert/trait.Into.html) internally.
///
/// ```rust
/// # extern crate turtle;
/// # use turtle::Point;
/// # fn main() {
/// assert_eq!(Point {x: 100.0, y: 40.0}, [100.0, 40.0].into());
/// assert_eq!(Point {x: 100.0, y: 40.0}, (100.0, 40.0).into());
/// # }
/// ```
///
/// Notice that we need to convert the right side using `into()` before it can be compared
/// in `assert_eq!()`.
///
/// ```rust,compile_fail,E0308
/// # extern crate turtle;
/// # use turtle::Point;
/// # fn main() {
/// // This will not compile
/// assert_eq!(Point {x: 100.0, y: 40.0}, [100.0, 40.0]);
/// assert_eq!(Point {x: 100.0, y: 40.0}, (100.0, 40.0));
/// # }
/// ```
///
/// # Manipulating Points
///
/// You can add or subtract points and multiply or divide points by scalar (f64) values. There
/// are a variety of [method functions](struct.Point.html#methods) described in the
/// documentation below that provide even more operations.
///
/// ```rust
/// # extern crate turtle;
/// # use turtle::Point;
/// # fn main() {
/// # let a = 320.0; let b = 400.0; let c = 70.0; let d = 95.0;
/// // Let's say you have two points with f64 values a, b, c, and d
/// let pt = Point {x: a, y: b};
/// let pt2 = Point {x: c, y: d};
/// assert_eq!(pt + pt2, Point {x: a + c, y: b + d});
/// assert_eq!(pt - pt2, Point {x: a - c, y: b - d});
/// assert_eq!(pt * 2.0, Point {x: a * 2.0, y: b * 2.0});
/// assert_eq!(pt2 / 5.0, Point {x: c / 5.0, y: d / 5.0});
/// assert_eq!(pt2 * 2.0 - pt, Point {x: c * 2.0 - a, y: d * 2.0 - b});
/// # }
/// ```
///
/// # Accessing Point Components
///
/// `Point` supports either using the `x` and `y` fields to access its components or using
/// indexing if you prefer that style.
///
/// ```rust
/// # extern crate turtle;
/// # use turtle::Point;
/// # fn main() {
/// let p = Point {x: 100.0, y: 120.0};
///
/// // Get x coordinate
/// let x = p.x;
/// assert_eq!(x, 100.0);
/// assert_eq!(p[0], x);
///
/// // Get y coordinate
/// let y = p.y;
/// assert_eq!(y, 120.0);
/// assert_eq!(p[1], y);
///
/// // With pattern matching
/// let Point {x, y} = p;
/// assert_eq!(x, 100.0);
/// assert_eq!(y, 120.0);
///
/// // Modifying x and y
/// let mut pt: Point = [240.0, 430.0].into();
/// # assert_eq!(pt.x, 240.0);
/// # assert_eq!(pt.y, 430.0);
/// pt.x = 73.0;
/// pt.y = 89.0;
/// assert_eq!(pt.x, 73.0);
/// assert_eq!(pt.y, 89.0);
/// // Using indexing
/// let mut pt2: Point = [100.0, 200.0].into();
/// # assert_eq!(pt2.x, 100.0);
/// # assert_eq!(pt2.y, 200.0);
/// pt2[0] = pt.x;
/// pt2[1] = pt.y;
/// assert_eq!(pt2.x, 73.0);
/// assert_eq!(pt2.y, 89.0);
/// # }
/// ```
///
/// [`Turtle::go_to()`]: struct.Turtle.html#method.go_to
/// [`Turtle::turn_towards()`]: struct.Turtle.html#method.turn_towards
/// [`Drawing::set_center()`]: struct.Drawing.html#method.set_center
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Point {
    /// The x-coordinate of the Point
    pub x: f64,
    /// The y-coordinate of the Point
    pub y: f64,
}

impl Point {
    /// Returns a Point that represents the origin of the coordinate system.
    ///
    /// For our "cartesian" coordinate system, this is always (0.0, 0.0)
    pub fn origin() -> Self {
        Self {x: 0.0, y: 0.0}
    }

    /// Returns true if both x and y are finite (neither infinite nor `NaN`).
    pub fn is_finite(self) -> bool {
        self.x.is_finite() && self.y.is_finite()
    }

    /// Returns true if both x and y are neither zero, infinite,
    /// [subnormal](https://en.wikipedia.org/wiki/Denormal_number), or `NaN`.
    pub fn is_normal(self) -> bool {
        self.x.is_normal() && self.y.is_normal()
    }

    /// Returns true if both x and y are either zero, infinite,
    /// [subnormal](https://en.wikipedia.org/wiki/Denormal_number), or `NaN`.
    pub fn is_not_normal(self) -> bool {
        !self.x.is_normal() && !self.y.is_normal()
    }

    /// Computes the absolute value of x and y and returns a new `Point`
    pub fn abs(self) -> Self {
        Self {x: self.x.abs(), y: self.y.abs()}
    }

    /// Returns a new `Point` with x and y set to the nearest integer to each of their values.
    /// Rounds half-way cases away from 0.0.
    pub fn round(self) -> Self {
        Self {x: self.x.round(), y: self.y.round()}
    }

    /// Returns the square of the length of this point.
    ///
    /// The length of a point is defined as `sqrt(x^2 + y^2)`
    pub fn square_len(self) -> f64 {
        self.x.powi(2) + self.y.powi(2)
    }

    /// Returns the length of this point.
    ///
    /// The length of a point is defined as `sqrt(x^2 + y^2)`
    pub fn len(self) -> f64 {
        self.square_len().sqrt()
    }

    /// Computes the four quadrant arctangent of `self.y` and `self.x`.
    pub fn atan2(self) -> f64 {
        self.y.atan2(self.x)
    }
}

impl From<(f64, f64)> for Point {
    fn from(pt: (f64, f64)) -> Self {
        Self {x: pt.0, y: pt.1}
    }
}

impl From<[f64; 2]> for Point {
    fn from(pt: [f64; 2]) -> Self {
        Self {x: pt[0], y: pt[1]}
    }
}

impl From<Point> for [f64; 2] {
    fn from(pt: Point) -> Self {
        [pt.x, pt.y]
    }
}

impl Add for Point {
    type Output = Self;

    fn add(self, other: Self) -> Self::Output {
        Self {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

impl Sub for Point {
    type Output = Self;

    fn sub(self, other: Self) -> Self::Output {
        Self {
            x: self.x - other.x,
            y: self.y - other.y,
        }
    }
}

impl Mul<f64> for Point {
    type Output = Self;

    fn mul(self, other: f64) -> Self::Output {
        Self {
            x: self.x * other,
            y: self.y * other,
        }
    }
}

impl Div<f64> for Point {
    type Output = Self;

    fn div(self, other: f64) -> Self::Output {
        Self {
            x: self.x / other,
            y: self.y / other,
        }
    }
}

impl Index<usize> for Point {
    type Output = f64;

    fn index(&self, index: usize) -> &Self::Output {
        match index {
            0 => &self.x,
            1 => &self.y,
            _ => panic!("Invalid coordinate for Point: {}", index),
        }
    }
}

impl IndexMut<usize> for Point {
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        match index {
            0 => &mut self.x,
            1 => &mut self.y,
            _ => panic!("Invalid coordinate for Point: {}", index),
        }
    }
}

impl Spatial for Point {
    type Scalar = f64;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        *self + *other
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        *self - *other
    }

    #[inline(always)]
    fn scale(&self, scalar: &Self::Scalar) -> Self {
        *self * *scalar
    }
}
<|endoftext|>


<commit_before>#![feature(std_misc)]
#![feature(core)]

extern crate para_bm;

use std::time::Duration;
use std::thread::Thread;
use std::num::Float;

use para_bm::{sleep_ns};

fn fast () {
    sleep_ns(1000);
}

fn slow () {
    sleep_ns(10000000);
}

fn my_bench<F> (f: F) -> f64 where F: Fn() {

    // first "throw away" run
    let mut d = Duration::span(|| {
        f();
    });
    let ns = d.num_nanoseconds().unwrap();
    //println!("num nano seconds first run {}", ns);

    let mut sum = 0;
    // iterate to get more cache hits, etc...
    let iters = 100.0;
    for _ in 0 .. iters as usize {
        d = Duration::span(|| {
            f();
        });
        let ns = d.num_nanoseconds().unwrap();
        sum = sum + ns;
    }

    let avg = (sum as f64) / iters;
    //println!("average after first run {}", avg);

    return avg;
}

fn main () {

    let mut max_ns = 10000000.0;
    let mut min_ns = 0.0;
    //let mut half_ns;
    let mut qurt_ns;
    let mut num_ns = (max_ns + min_ns) / 2.0;

    for power in 0 .. 30 {
        println!("Size.....: {}", num_ns as i64);

        let t_avg = my_bench(||{
            let threads_holder = (0 .. 3).map(|_| {
                Thread::scoped(move || {
                    sleep_ns(num_ns as i64);
                })
            }).collect::<Vec<_>>();
        });
        //println!("Runtime thread....: {}", t_avg);

        let s_avg = my_bench(||{
            let serial_holder = (0 .. 3).map(|_| {
                sleep_ns(num_ns as i64);
            }).collect::<Vec<_>>();
        });
        //println!("Runtime serial....: {}", s_avg);

        println!("s - t .....: {}", s_avg - t_avg);

        if t_avg > s_avg {
            qurt_ns = (max_ns + num_ns) / 2.0;
            min_ns = num_ns;
            num_ns = qurt_ns;
        } else {
            qurt_ns = (min_ns + num_ns) / 2.0;
            max_ns = num_ns;
            num_ns = qurt_ns;
        }

        println!("qurt.....: {}", qurt_ns as i64);
        println!("jump.....: {}", max_ns - min_ns);

        println!("------------------------------------");

        if max_ns - min_ns < 1.0 {

            break;
        }

    }
}
<commit_msg>run sizes in order<commit_after>#![feature(std_misc)]
#![feature(core)]

extern crate para_bm;

use std::time::Duration;
use std::thread::Thread;
use std::num::Float;

use para_bm::{sleep_ns};

fn fast () {
    sleep_ns(1000);
}

fn slow () {
    sleep_ns(10000000);
}

fn my_bench<F> (f: F) -> f64 where F: Fn() {

    // first "throw away" run
    let mut d = Duration::span(|| {
        f();
    });
    let ns = d.num_nanoseconds().unwrap();
    //println!("num nano seconds first run {}", ns);

    let mut sum = 0;
    // iterate to get more cache hits, etc...
    let iters = 100.0;
    for _ in 0 .. iters as usize {
        d = Duration::span(|| {
            f();
        });
        let ns = d.num_nanoseconds().unwrap();
        sum = sum + ns;
    }

    let avg = (sum as f64) / iters;
    //println!("average after first run {}", avg);

    return avg;
}

fn main () {

    let mut max_ns = 10000000.0;
    let mut min_ns = 1.0;

    let num_steps = 100;
    let step_size = (max_ns - min_ns) / num_steps as f64;
    let mut num_ns = min_ns;

    for power in 0 .. num_steps {
        println!("Size.....: {}", num_ns as i64);
        num_ns += step_size;

        let t_avg = my_bench(||{
            let threads_holder = (0 .. 3).map(|_| {
                Thread::scoped(move || {
                    sleep_ns(num_ns as i64);
                })
            }).collect::<Vec<_>>();
        });
        println!("Runtime thread....: {}", t_avg);

        let s_avg = my_bench(||{
            let serial_holder = (0 .. 3).map(|_| {
                sleep_ns(num_ns as i64);
            }).collect::<Vec<_>>();
        });
        println!("Runtime serial....: {}", s_avg);

    }
}
<|endoftext|>


<commit_before>//! Defines the render target for tray, where our image will be written too
//! during rendering
//! TODO: Reconstruction filters

use std::vec::Vec;
use linalg;
use film::Colorf;

/// RenderTarget is a RGBF render target to write our image too while rendering
#[deriving(Clone)]
pub struct RenderTarget {
    width: uint,
    height: uint,
    pixels: Vec<Colorf>,
}

impl RenderTarget {
    /// Create a render target with `width * height` pixels
    pub fn new(width: uint, height: uint) -> RenderTarget {
        RenderTarget { width: width, height: height,
            pixels: Vec::from_fn(width * height, |_| Colorf::broadcast(0f32)),
        }
    }
    /// Write a color value to the image at `(x, y)`
    pub fn write(&mut self, x: f32, y: f32, c: &Colorf) {
        // Compute the discrete pixel coordinates which the sample hits, no filtering for now
        let ix = linalg::clamp(x - 0.5, 0f32, (self.width - 1) as f32) as uint;
        let iy = linalg::clamp(y - 0.5, 0f32, (self.height - 1) as f32) as uint;
        self.pixels[iy * self.width + ix] = *c;
        // Set the filter weight, currently just a box filter with single pixel extent
        self.pixels[iy * self.width + ix].a += 1.0;
    }
    /// Get the dimensions of the render target
    pub fn dimensions(&self) -> (uint, uint) {
        (self.width, self.height)
    }
    /// Convert the floating point color buffer to 24bpp sRGB for output to an image
    pub fn get_render(&self) -> Vec<u8> {
        let mut render = Vec::from_fn(self.width * self.height * 3, |_| 0u8);
        for y in range(0u, self.height) {
            for x in range(0u, self.width) {
                let c = &self.pixels[y * self.width + x];
                if c.a != 0.0 {
                    let cn = (*c / c.a).clamp().to_srgb();
                    for i in range(0u, 3) {
                        render[y * self.width * 3 + x * 3 + i] = (cn[i] * 255.0) as u8;
                    }
                }
            }
        }
        render
    }
}

<commit_msg>Improve initialization of vectors by using the iterator methods<commit_after>//! Defines the render target for tray, where our image will be written too
//! during rendering
//! TODO: Reconstruction filters

use std::vec::Vec;
use std::iter;
use linalg;
use film::Colorf;

/// RenderTarget is a RGBF render target to write our image too while rendering
#[deriving(Clone)]
pub struct RenderTarget {
    width: uint,
    height: uint,
    pixels: Vec<Colorf>,
}

impl RenderTarget {
    /// Create a render target with `width * height` pixels
    pub fn new(width: uint, height: uint) -> RenderTarget {
        RenderTarget { width: width, height: height,
            pixels: iter::repeat(Colorf::broadcast(0f32)).take(width * height).collect(),
        }
    }
    /// Write a color value to the image at `(x, y)`
    pub fn write(&mut self, x: f32, y: f32, c: &Colorf) {
        // Compute the discrete pixel coordinates which the sample hits, no filtering for now
        let ix = linalg::clamp(x - 0.5, 0f32, (self.width - 1) as f32) as uint;
        let iy = linalg::clamp(y - 0.5, 0f32, (self.height - 1) as f32) as uint;
        self.pixels[iy * self.width + ix] = *c;
        // Set the filter weight, currently just a box filter with single pixel extent
        self.pixels[iy * self.width + ix].a += 1.0;
    }
    /// Get the dimensions of the render target
    pub fn dimensions(&self) -> (uint, uint) {
        (self.width, self.height)
    }
    /// Convert the floating point color buffer to 24bpp sRGB for output to an image
    pub fn get_render(&self) -> Vec<u8> {
        let mut render: Vec<u8> = iter::repeat(0u8).take(self.width * self.height * 3).collect();
        for y in range(0u, self.height) {
            for x in range(0u, self.width) {
                let c = &self.pixels[y * self.width + x];
                if c.a != 0.0 {
                    let cn = (*c / c.a).clamp().to_srgb();
                    for i in range(0u, 3) {
                        render[y * self.width * 3 + x * 3 + i] = (cn[i] * 255.0) as u8;
                    }
                }
            }
        }
        render
    }
}

<|endoftext|>


<commit_before>//! The `image` element.

use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::aspect_ratio::AspectRatio;
use crate::bbox::BoundingBox;
use crate::document::AcquiredNodes;
use crate::drawing_ctx::DrawingCtx;
use crate::element::{Draw, ElementResult, SetAttributes};
use crate::error::*;
use crate::href::{is_href, set_href};
use crate::layout::{self, StackingContext};
use crate::length::*;
use crate::node::{CascadedValues, Node, NodeBorrow};
use crate::parsers::ParseValue;
use crate::rect::Rect;
use crate::xml::Attributes;

/// The `<image>` element.
///
/// Note that its x/y/width/height are properties in SVG2, so they are
/// defined as part of [the properties machinery](properties.rs).
#[derive(Default)]
pub struct Image {
    aspect: AspectRatio,
    href: Option<String>,
}

impl SetAttributes for Image {
    fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
        for (attr, value) in attrs.iter() {
            match attr.expanded() {
                expanded_name!("", "preserveAspectRatio") => self.aspect = attr.parse(value)?,

                // "path" is used by some older Adobe Illustrator versions
                ref a if is_href(a) || *a == expanded_name!("", "path") => {
                    set_href(a, &mut self.href, value.to_string())
                }

                _ => (),
            }
        }

        Ok(())
    }
}

impl Draw for Image {
    fn draw(
        &self,
        node: &Node,
        acquired_nodes: &mut AcquiredNodes<'_>,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx,
        clipping: bool,
    ) -> Result<BoundingBox, RenderingError> {
        let surface = match self.href {
            Some(ref url) => match acquired_nodes.lookup_image(url) {
                Ok(surf) => surf,
                Err(e) => {
                    rsvg_log!("could not load image \"{}\": {}", url, e);
                    return Ok(draw_ctx.empty_bbox());
                }
            },
            None => return Ok(draw_ctx.empty_bbox()),
        };

        let values = cascaded.get();

        let view_params = draw_ctx.get_view_params();
        let params = NormalizeParams::new(values, &view_params);

        let x = values.x().0.to_user(&params);
        let y = values.y().0.to_user(&params);

        let w = match values.width().0 {
            LengthOrAuto::Length(l) => l.to_user(&params),
            LengthOrAuto::Auto => surface.width() as f64,
        };
        let h = match values.height().0 {
            LengthOrAuto::Length(l) => l.to_user(&params),
            LengthOrAuto::Auto => surface.height() as f64,
        };

        let is_visible = values.is_visible();

        let rect = Rect::new(x, y, x + w, y + h);

        let overflow = values.overflow();

        let image = layout::Image {
            surface,
            is_visible,
            rect,
            aspect: self.aspect,
            overflow,
        };

        let elt = node.borrow_element();
        let stacking_ctx = StackingContext::new(
            draw_ctx.session(),
            acquired_nodes,
            &elt,
            values.transform(),
            values,
        );

        draw_ctx.draw_image(&image, &stacking_ctx, acquired_nodes, values, clipping)
    }
}
<commit_msg>image.rs: Use a session for logging<commit_after>//! The `image` element.

use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::aspect_ratio::AspectRatio;
use crate::bbox::BoundingBox;
use crate::document::AcquiredNodes;
use crate::drawing_ctx::DrawingCtx;
use crate::element::{Draw, ElementResult, SetAttributes};
use crate::error::*;
use crate::href::{is_href, set_href};
use crate::layout::{self, StackingContext};
use crate::length::*;
use crate::node::{CascadedValues, Node, NodeBorrow};
use crate::parsers::ParseValue;
use crate::rect::Rect;
use crate::xml::Attributes;

/// The `<image>` element.
///
/// Note that its x/y/width/height are properties in SVG2, so they are
/// defined as part of [the properties machinery](properties.rs).
#[derive(Default)]
pub struct Image {
    aspect: AspectRatio,
    href: Option<String>,
}

impl SetAttributes for Image {
    fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
        for (attr, value) in attrs.iter() {
            match attr.expanded() {
                expanded_name!("", "preserveAspectRatio") => self.aspect = attr.parse(value)?,

                // "path" is used by some older Adobe Illustrator versions
                ref a if is_href(a) || *a == expanded_name!("", "path") => {
                    set_href(a, &mut self.href, value.to_string())
                }

                _ => (),
            }
        }

        Ok(())
    }
}

impl Draw for Image {
    fn draw(
        &self,
        node: &Node,
        acquired_nodes: &mut AcquiredNodes<'_>,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx,
        clipping: bool,
    ) -> Result<BoundingBox, RenderingError> {
        let surface = match self.href {
            Some(ref url) => match acquired_nodes.lookup_image(url) {
                Ok(surf) => surf,
                Err(e) => {
                    rsvg_log_session!(
                        draw_ctx.session(),
                        "could not load image \"{}\": {}",
                        url,
                        e
                    );
                    return Ok(draw_ctx.empty_bbox());
                }
            },
            None => return Ok(draw_ctx.empty_bbox()),
        };

        let values = cascaded.get();

        let view_params = draw_ctx.get_view_params();
        let params = NormalizeParams::new(values, &view_params);

        let x = values.x().0.to_user(&params);
        let y = values.y().0.to_user(&params);

        let w = match values.width().0 {
            LengthOrAuto::Length(l) => l.to_user(&params),
            LengthOrAuto::Auto => surface.width() as f64,
        };
        let h = match values.height().0 {
            LengthOrAuto::Length(l) => l.to_user(&params),
            LengthOrAuto::Auto => surface.height() as f64,
        };

        let is_visible = values.is_visible();

        let rect = Rect::new(x, y, x + w, y + h);

        let overflow = values.overflow();

        let image = layout::Image {
            surface,
            is_visible,
            rect,
            aspect: self.aspect,
            overflow,
        };

        let elt = node.borrow_element();
        let stacking_ctx = StackingContext::new(
            draw_ctx.session(),
            acquired_nodes,
            &elt,
            values.transform(),
            values,
        );

        draw_ctx.draw_image(&image, &stacking_ctx, acquired_nodes, values, clipping)
    }
}
<|endoftext|>