<commit_before>use std::fmt::{Error as fmtError, Write};

use colored::Colorize;
use difference::{Changeset, Difference};

pub fn render(&Changeset { ref diffs, .. }: &Changeset) -> Result<String, fmtError> {
    let mut t = String::new();

    for (i, diff) in diffs.iter().enumerate() {
        match *diff {
            Difference::Same(ref x) => {
                writeln!(t, " {}", x)?;
            }
            Difference::Rem(ref x) => {
                writeln!(t, "{}", format!("-{}", x).red())?;
            }
            Difference::Add(ref x) => {
                match diffs[i - 1] {
                    Difference::Rem(ref y) => {
                        write!(t, "{}", "+".green())?;
                        let Changeset { diffs, .. } = Changeset::new(y, x, " ");
                        for c in diffs {
                            match c {
                                Difference::Same(ref z) if !z.is_empty() => {
                                    write!(t, "{}", z.green())?;
                                    write!(t, " ")?;
                                }
                                Difference::Add(ref z) if !z.is_empty() => {
                                    write!(t, "{}", z.green().reverse())?;
                                    write!(t, " ")?;
                                }
                                _ => (),
                            }
                        }
                        writeln!(t, "")?;
                    }
                    _ => {
                        writeln!(t, "{}", format!("+{}", x).green().dimmed())?;
                    }
                };
            }
        }
    }

    Ok(t)
}

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

    #[test]
    fn basic_diff() {
        let diff = Changeset::new("lol", "yay", "\n");
        println!("{}", render(&diff).unwrap());
        assert_eq!(
            render(&diff).unwrap(),
            "\u{1b}[31m-lol\u{1b}[0m\n\u{1b}[32m+\u{1b}[0m\u{1b}[7;32myay\u{1b}[0m \n"
        )
    }

    #[test]
    fn multiline_diff() {
        let diff = Changeset::new(
            "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.",
            "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor **incididunt** ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.",
            "\n",
        );
        println!("{}", render(&diff).unwrap());
        assert_eq!(
            render(&diff).unwrap(),
            " Lorem ipsum dolor sit amet, consectetur adipisicing elit,\n\
             \u{1b}[31m-sed do eiusmod tempor incididunt ut labore et dolore \
             magna\u{1b}[0m\n\u{1b}[32m+\u{1b}[0m\u{1b}[32msed do eiusmod tempor\
             \u{1b}[0m \u{1b}[7;32m**incididunt**\u{1b}[0m \u{1b}[32mut labore \
             et dolore magna\u{1b}[0m \n aliqua. Ut enim ad minim veniam, quis \
             nostrud exercitation\nullamco laboris nisi ut aliquip ex ea \
             commodo consequat.\n"
        );
    }
}
<commit_msg>fix panic on diff when addind new first line<commit_after>use std::fmt::{Error as fmtError, Write};

use colored::Colorize;
use difference::{Changeset, Difference};

pub fn render(&Changeset { ref diffs, .. }: &Changeset) -> Result<String, fmtError> {
    let mut t = String::new();

    for (i, diff) in diffs.iter().enumerate() {
        match *diff {
            Difference::Same(ref x) => {
                writeln!(t, " {}", x)?;
            }
            Difference::Rem(ref x) => {
                writeln!(t, "{}", format!("-{}", x).red())?;
            }
            Difference::Add(ref x) => {
                if i == 0 {
                    writeln!(t, "{}", format!("+{}", x).green())?;
                } else {
                    match diffs[i - 1] {
                        Difference::Rem(ref y) => {
                            write!(t, "{}", "+".green())?;
                            let Changeset { diffs, .. } = Changeset::new(y, x, " ");
                            for c in diffs {
                                match c {
                                    Difference::Same(ref z) if !z.is_empty() => {
                                        write!(t, "{}", z.green())?;
                                        write!(t, " ")?;
                                    }
                                    Difference::Add(ref z) if !z.is_empty() => {
                                        write!(t, "{}", z.green().reverse())?;
                                        write!(t, " ")?;
                                    }
                                    _ => (),
                                }
                            }
                            writeln!(t, "")?;
                        }
                        _ => {
                            writeln!(t, "{}", format!("+{}", x).green().dimmed())?;
                        }
                    };
                }
            }
        }
    }

    Ok(t)
}

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

    #[test]
    fn basic_diff() {
        let diff = Changeset::new("lol", "yay", "\n");
        println!("{}", render(&diff).unwrap());
        assert_eq!(
            render(&diff).unwrap(),
            "\u{1b}[31m-lol\u{1b}[0m\n\u{1b}[32m+\u{1b}[0m\u{1b}[7;32myay\u{1b}[0m \n"
        )
    }

    #[test]
    fn multiline_diff() {
        let diff = Changeset::new(
            "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.",
            "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor **incididunt** ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.",
            "\n",
        );
        println!("{}", render(&diff).unwrap());
        assert_eq!(
            render(&diff).unwrap(),
            " Lorem ipsum dolor sit amet, consectetur adipisicing elit,\n\
             \u{1b}[31m-sed do eiusmod tempor incididunt ut labore et dolore \
             magna\u{1b}[0m\n\u{1b}[32m+\u{1b}[0m\u{1b}[32msed do eiusmod tempor\
             \u{1b}[0m \u{1b}[7;32m**incididunt**\u{1b}[0m \u{1b}[32mut labore \
             et dolore magna\u{1b}[0m \n aliqua. Ut enim ad minim veniam, quis \
             nostrud exercitation\nullamco laboris nisi ut aliquip ex ea \
             commodo consequat.\n"
        );
    }

    #[test]
    fn added_first_line_diff() {
        let diff = Changeset::new(
            "Line 1\nLine 2\nLine 3",
            "Line 0\nLine 1\nLine 2\nLine 3",
            "\n",
        );
        println!("{}", render(&diff).unwrap());
        assert_eq!(
            render(&diff).unwrap(),
            "\u{1b}[32m+Line 0\u{1b}[0m\n Line 1\nLine 2\nLine 3\n"
        );
    }
}
<|endoftext|>


<commit_before>use toml::Value;

use libimagstore::storeid::StoreId;
use libimagstore::hook::Hook;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::accessor::StoreIdAccessor;

#[derive(Debug)]
pub struct RetrieveHook {
    position: HookPosition,
    config: Option<Value>,
}

impl RetrieveHook {

    pub fn new(p: HookPosition) -> RetrieveHook {
        RetrieveHook {
            position: p,
            config: None,
        }
    }

}

impl Hook for RetrieveHook {

    fn name(&self) -> &'static str {
        "stdhook_git_retrieve"
    }

    fn set_config(&mut self, config: &Value) {
        self.config = Some(config.clone());
    }

}

impl HookDataAccessorProvider for RetrieveHook {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl StoreIdAccessor for RetrieveHook {

    fn access(&self, id: &StoreId) -> HookResult<()> {
        debug!("[GIT RETRIEVE HOOK]: {:?}", id);
        Ok(())
    }

}

<commit_msg>Add store path member for retrieve hook<commit_after>use std::path::PathBuf;

use toml::Value;

use libimagstore::storeid::StoreId;
use libimagstore::hook::Hook;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::accessor::StoreIdAccessor;

#[derive(Debug)]
pub struct RetrieveHook<'a> {
    storepath: &'a PathBuf,

    position: HookPosition,
    config: Option<Value>,
}

impl<'a> RetrieveHook<'a> {

    pub fn new(storepath: &'a PathBuf, p: HookPosition) -> RetrieveHook<'a> {
        RetrieveHook {
            storepath: storepath,
            position: p,
            config: None,
        }
    }

}

impl<'a> Hook for RetrieveHook<'a> {

    fn name(&self) -> &'static str {
        "stdhook_git_retrieve"
    }

    fn set_config(&mut self, config: &Value) {
        self.config = Some(config.clone());
    }

}

impl<'a> HookDataAccessorProvider for RetrieveHook<'a> {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl<'a> StoreIdAccessor for RetrieveHook<'a> {

    fn access(&self, id: &StoreId) -> HookResult<()> {
        debug!("[GIT RETRIEVE HOOK]: {:?}", id);
        Ok(())
    }

}

<|endoftext|>


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

//! Command Buffer device interface

use draw_state::target;

use super::{attrib, shade, tex, Resources};

type Offset = u32;
type Size = u32;

/// The place of some data in the data buffer.
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct DataPointer(Offset, Size);

/// A buffer of data accompanying the commands. It can be vertex data, texture
/// updates, uniform blocks, or even some draw states.
pub struct DataBuffer {
    buf: Vec<u8>,
}

impl DataBuffer {
    /// Create a fresh new data buffer.
    pub fn new() -> DataBuffer {
        DataBuffer {
            buf: Vec::new(),
        }
    }

    /// Clear all the data but retain the allocated storage.
    pub fn clear(&mut self) {
        unsafe { self.buf.set_len(0); }
    }

    /// Copy a given structure into the buffer, return the offset and the size.
    #[cfg(unstable)]
    #[inline(always)]
    pub fn add_struct<T: Copy>(&mut self, v: &T) -> DataPointer {
        use std::slice::ref_slice;
        self.add_vec(ref_slice(v))
    }

    /// Copy a given structure into the buffer, return the offset and the size.
    #[cfg(not(unstable))]
    pub fn add_struct<T: Copy>(&mut self, v: &T) -> DataPointer {
        use std::{intrinsics, mem};
        let offset = self.buf.len();
        let size = mem::size_of::<T>();
        self.buf.reserve(size);
        unsafe {
            self.buf.set_len(offset + size);
            intrinsics::copy((v as *const T) as *const u8,
                             &mut self.buf[offset] as *mut u8,
                             size);
        };
        DataPointer(offset as Offset, size as Size)
    }

    /// Copy a given vector slice into the buffer
    pub fn add_vec<T: Copy>(&mut self, v: &[T]) -> DataPointer {
        use std::{intrinsics, mem};
        let offset = self.buf.len();
        let size = mem::size_of::<T>() * v.len();
        self.buf.reserve(size);
        unsafe {
            self.buf.set_len(offset + size);
            intrinsics::copy(v.as_ptr() as *const u8,
                             &mut self.buf[offset] as *mut u8,
                             size);
        }
        DataPointer(offset as Offset, size as Size)
    }

    /// Return a reference to a stored data object.
    pub fn get_ref(&self, data: DataPointer) -> &[u8] {
        let DataPointer(offset, size) = data;
        &self.buf[offset as usize ..offset as usize + size as usize]
    }
}

/// Optional instance parameters
pub type InstanceOption = Option<(super::InstanceCount, super::VertexCount)>;

/// An interface of the abstract command buffer. It collects commands in an
/// efficient API-specific manner, to be ready for execution on the device.
#[allow(missing_docs)]
pub trait CommandBuffer<R: Resources> {
    /// An empty constructor
    fn new() -> Self;
    /// Clear the command buffer contents, retain the allocated storage
    fn clear(&mut self);
    /// Bind a shader program
    fn bind_program(&mut self, R::Program);
    /// Bind an array buffer object
    fn bind_array_buffer(&mut self, R::ArrayBuffer);
    /// Bind a vertex attribute
    fn bind_attribute(&mut self, super::AttributeSlot, R::Buffer, attrib::Format);
    /// Bind an index buffer
    fn bind_index(&mut self, R::Buffer);
    /// Bind a frame buffer object
    fn bind_frame_buffer(&mut self, Access, R::FrameBuffer, Gamma);
    /// Unbind any surface from the specified target slot
    fn unbind_target(&mut self, Access, Target);
    /// Bind a surface to the specified target slot
    fn bind_target_surface(&mut self, Access, Target, R::Surface);
    /// Bind a level of the texture to the specified target slot
    fn bind_target_texture(&mut self, Access, Target, R::Texture,
                           target::Level, Option<target::Layer>);
    /// Bind a uniform block
    fn bind_uniform_block(&mut self, R::Program,
                          super::UniformBufferSlot, super::UniformBlockIndex,
                          R::Buffer);
    /// Bind a single uniform in the default block
    fn bind_uniform(&mut self, shade::Location, shade::UniformValue);
    /// Bind a texture
    fn bind_texture(&mut self, super::TextureSlot, tex::Kind,
                    R::Texture, Option<(R::Sampler, tex::SamplerInfo)>);
    /// Select, which color buffers are going to be targetted by the shader
    fn set_draw_color_buffers(&mut self, usize);
    /// Set primitive topology
    fn set_primitive(&mut self, ::state::Primitive);
    /// Set viewport rectangle
    fn set_viewport(&mut self, target::Rect);
    /// Set multi-sampling state
    fn set_multi_sample(&mut self, Option<::state::MultiSample>);
    /// Set scissor test
    fn set_scissor(&mut self, Option<target::Rect>);
    /// Set depth and stencil states
    fn set_depth_stencil(&mut self, Option<::state::Depth>,
                         Option<::state::Stencil>, ::state::CullFace);
    /// Set blend state
    fn set_blend(&mut self, Option<::state::Blend>);
    /// Set output color mask for all targets
    fn set_color_mask(&mut self, ::state::ColorMask);
    /// Update a vertex/index/uniform buffer
    fn update_buffer(&mut self, R::Buffer, DataPointer, usize);
    /// Update a texture region
    fn update_texture(&mut self, tex::Kind, R::Texture,
                      tex::ImageInfo, DataPointer);
    /// Clear target surfaces
    fn call_clear(&mut self, target::ClearData, target::Mask);
    /// Draw a primitive
    fn call_draw(&mut self, super::PrimitiveType, super::VertexCount,
                 super::VertexCount, InstanceOption);
    /// Draw a primitive with index buffer
    fn call_draw_indexed(&mut self, super::PrimitiveType, super::IndexType,
                         super::VertexCount, super::VertexCount,
                         super::VertexCount, InstanceOption);
    /// Blit from one target to another
    fn call_blit(&mut self, target::Rect, target::Rect, target::Mirror, target::Mask);
}

/// Type of the frame buffer access.
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Access {
    /// Draw access
    Draw,
    /// Read access
    Read,
}

/// Type of the gamma transformation for framebuffer writes.
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Gamma {
    /// Process in linear color space.
    Original,
    /// Convert to sRGB color space.
    Convert,
}

/// When rendering, each "output" of the fragment shader goes to a specific target. A `Plane` can
/// be bound to a target, causing writes to that target to affect the `Plane`.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Target {
    /// Color data.
    ///
    /// # Portability Note
    ///
    /// The device is only required to expose one color target.
    Color(u8),
    /// Depth data.
    Depth,
    /// Stencil data.
    Stencil,
    /// A target for both depth and stencil data at once.
    DepthStencil,
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_data_buffer() {
        let mut buf = super::DataBuffer::new();
        assert_eq!(buf.add_struct(&(0u8, false)), super::DataPointer(0, 2));
        assert_eq!(buf.add_vec(&[5i32, 6i32]), super::DataPointer(2, 8));
    }
}
<commit_msg>Avoid using the std::intrinsics module<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Command Buffer device interface

use draw_state::target;

use super::{attrib, shade, tex, Resources};

type Offset = u32;
type Size = u32;

/// The place of some data in the data buffer.
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct DataPointer(Offset, Size);

/// A buffer of data accompanying the commands. It can be vertex data, texture
/// updates, uniform blocks, or even some draw states.
pub struct DataBuffer {
    buf: Vec<u8>,
}

impl DataBuffer {
    /// Create a fresh new data buffer.
    pub fn new() -> DataBuffer {
        DataBuffer {
            buf: Vec::new(),
        }
    }

    /// Clear all the data but retain the allocated storage.
    pub fn clear(&mut self) {
        unsafe { self.buf.set_len(0); }
    }

    /// Copy a given structure into the buffer, return the offset and the size.
    #[cfg(unstable)]
    #[inline(always)]
    pub fn add_struct<T: Copy>(&mut self, v: &T) -> DataPointer {
        use std::slice::ref_slice;
        self.add_vec(ref_slice(v))
    }

    /// Copy a given structure into the buffer, return the offset and the size.
    #[cfg(not(unstable))]
    pub fn add_struct<T: Copy>(&mut self, v: &T) -> DataPointer {
        use std::{ptr, mem};
        let offset = self.buf.len();
        let size = mem::size_of::<T>();
        self.buf.reserve(size);
        unsafe {
            self.buf.set_len(offset + size);
            ptr::copy((v as *const T) as *const u8,
                             &mut self.buf[offset] as *mut u8,
                             size);
        };
        DataPointer(offset as Offset, size as Size)
    }

    /// Copy a given vector slice into the buffer
    pub fn add_vec<T: Copy>(&mut self, v: &[T]) -> DataPointer {
        use std::{ptr, mem};
        let offset = self.buf.len();
        let size = mem::size_of::<T>() * v.len();
        self.buf.reserve(size);
        unsafe {
            self.buf.set_len(offset + size);
            ptr::copy(v.as_ptr() as *const u8,
                             &mut self.buf[offset] as *mut u8,
                             size);
        }
        DataPointer(offset as Offset, size as Size)
    }

    /// Return a reference to a stored data object.
    pub fn get_ref(&self, data: DataPointer) -> &[u8] {
        let DataPointer(offset, size) = data;
        &self.buf[offset as usize ..offset as usize + size as usize]
    }
}

/// Optional instance parameters
pub type InstanceOption = Option<(super::InstanceCount, super::VertexCount)>;

/// An interface of the abstract command buffer. It collects commands in an
/// efficient API-specific manner, to be ready for execution on the device.
#[allow(missing_docs)]
pub trait CommandBuffer<R: Resources> {
    /// An empty constructor
    fn new() -> Self;
    /// Clear the command buffer contents, retain the allocated storage
    fn clear(&mut self);
    /// Bind a shader program
    fn bind_program(&mut self, R::Program);
    /// Bind an array buffer object
    fn bind_array_buffer(&mut self, R::ArrayBuffer);
    /// Bind a vertex attribute
    fn bind_attribute(&mut self, super::AttributeSlot, R::Buffer, attrib::Format);
    /// Bind an index buffer
    fn bind_index(&mut self, R::Buffer);
    /// Bind a frame buffer object
    fn bind_frame_buffer(&mut self, Access, R::FrameBuffer, Gamma);
    /// Unbind any surface from the specified target slot
    fn unbind_target(&mut self, Access, Target);
    /// Bind a surface to the specified target slot
    fn bind_target_surface(&mut self, Access, Target, R::Surface);
    /// Bind a level of the texture to the specified target slot
    fn bind_target_texture(&mut self, Access, Target, R::Texture,
                           target::Level, Option<target::Layer>);
    /// Bind a uniform block
    fn bind_uniform_block(&mut self, R::Program,
                          super::UniformBufferSlot, super::UniformBlockIndex,
                          R::Buffer);
    /// Bind a single uniform in the default block
    fn bind_uniform(&mut self, shade::Location, shade::UniformValue);
    /// Bind a texture
    fn bind_texture(&mut self, super::TextureSlot, tex::Kind,
                    R::Texture, Option<(R::Sampler, tex::SamplerInfo)>);
    /// Select, which color buffers are going to be targetted by the shader
    fn set_draw_color_buffers(&mut self, usize);
    /// Set primitive topology
    fn set_primitive(&mut self, ::state::Primitive);
    /// Set viewport rectangle
    fn set_viewport(&mut self, target::Rect);
    /// Set multi-sampling state
    fn set_multi_sample(&mut self, Option<::state::MultiSample>);
    /// Set scissor test
    fn set_scissor(&mut self, Option<target::Rect>);
    /// Set depth and stencil states
    fn set_depth_stencil(&mut self, Option<::state::Depth>,
                         Option<::state::Stencil>, ::state::CullFace);
    /// Set blend state
    fn set_blend(&mut self, Option<::state::Blend>);
    /// Set output color mask for all targets
    fn set_color_mask(&mut self, ::state::ColorMask);
    /// Update a vertex/index/uniform buffer
    fn update_buffer(&mut self, R::Buffer, DataPointer, usize);
    /// Update a texture region
    fn update_texture(&mut self, tex::Kind, R::Texture,
                      tex::ImageInfo, DataPointer);
    /// Clear target surfaces
    fn call_clear(&mut self, target::ClearData, target::Mask);
    /// Draw a primitive
    fn call_draw(&mut self, super::PrimitiveType, super::VertexCount,
                 super::VertexCount, InstanceOption);
    /// Draw a primitive with index buffer
    fn call_draw_indexed(&mut self, super::PrimitiveType, super::IndexType,
                         super::VertexCount, super::VertexCount,
                         super::VertexCount, InstanceOption);
    /// Blit from one target to another
    fn call_blit(&mut self, target::Rect, target::Rect, target::Mirror, target::Mask);
}

/// Type of the frame buffer access.
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Access {
    /// Draw access
    Draw,
    /// Read access
    Read,
}

/// Type of the gamma transformation for framebuffer writes.
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Gamma {
    /// Process in linear color space.
    Original,
    /// Convert to sRGB color space.
    Convert,
}

/// When rendering, each "output" of the fragment shader goes to a specific target. A `Plane` can
/// be bound to a target, causing writes to that target to affect the `Plane`.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Target {
    /// Color data.
    ///
    /// # Portability Note
    ///
    /// The device is only required to expose one color target.
    Color(u8),
    /// Depth data.
    Depth,
    /// Stencil data.
    Stencil,
    /// A target for both depth and stencil data at once.
    DepthStencil,
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_data_buffer() {
        let mut buf = super::DataBuffer::new();
        assert_eq!(buf.add_struct(&(0u8, false)), super::DataPointer(0, 2));
        assert_eq!(buf.add_vec(&[5i32, 6i32]), super::DataPointer(2, 8));
    }
}
<|endoftext|>


<commit_before>// XXX(scode): Consider supporting cloning/snapshotting metrics.
// XXX(scode): Missing histograms.
// XXX(scode): Missing meters (questionable).
// XXX(scode): Transition to lock-less where possible.

use std::num::Int;
use std::sync::Arc;
use std::sync::Mutex;

/// A 64 bit signed counter.
pub trait Counter<T: Int> {
    /// Increment the counter by the given delta.
    ///
    // The delta may be negative (for types T where this is possible).
    fn inc(&mut self, delta: T);

    /// Decrement the counter by the given delta.
    ///
    /// The delta may be negative (for types T where this is possible).
    ///
    /// dec(n) is equivalent of dec(-n)
    fn dec(&mut self, delta: T);

    /// Return the current value of the counter.
    fn get(&self) -> T;
}

/// A gauge has a single value at any given moment in time, and can only be
/// updated by providing an entirely new value.
pub trait Gauge<T: Clone> {
    fn set(&mut self, value: Option<T>);
    fn get(&self) -> Option<T>;
}

pub struct SimpleCounter<T: Int> {
    value: T,
}

impl<T: Int> Counter<T> for SimpleCounter<T> {
    fn inc(&mut self, delta: T) {
        self.value = self.value + delta;
    }

    fn dec(&mut self, delta: T) {
        self.value = self.value - delta;
    }

    fn get(&self) -> T {
        self.value
    }
}

pub struct SharedCounter<T: Int + Send> {
    value: Arc<Mutex<T>>,
}

impl<T: Int + Send> Counter<T> for SharedCounter<T> {
    fn inc(&mut self, delta: T) {
        let mut value = self.value.lock().unwrap();

        *value = *value + delta;
    }

    fn dec(&mut self, delta: T) {
        let mut value = self.value.lock().unwrap();

        *value = *value - delta;
    }

    fn get(&self) -> T {
        let value = self.value.lock().unwrap();

        *value
    }
}

pub struct SimpleGauge<T: Clone> {
    value: Option<T>,
}

impl<T: Clone> Gauge<T> for SimpleGauge<T> {
    fn set(&mut self, new_value: Option<T>) {
        self.value = new_value;
    }

    fn get(&self) -> Option<T> {
        self.value.clone()
    }
}

pub struct SharedGauge<T: Send> {
    value: Arc<Mutex<Option<T>>>,
}

impl<T: Clone + Send> Gauge<T> for SharedGauge<T> {
    fn set(&mut self, new_value: Option<T>) {
        *self.value.lock().unwrap() = new_value;
    }

    fn get(&self) -> Option<T> {
        (*self.value.lock().unwrap()).clone()
    }
}

#[cfg(test)]
mod test {
    use std::sync::Arc;
    use std::sync::Mutex;

    #[test]
    fn test_counters() {
        use metrics::Counter;
        use metrics::SharedCounter;
        use metrics::SimpleCounter;

        let mut counters = Vec::<Box<Counter<i64>>>::new();
        counters.push(Box::new(SimpleCounter { value: 0i64, }));
        counters.push(Box::new(SharedCounter { value: Arc::new(Mutex::new(0i64)) }));

        for mut c in counters {
            assert_eq!(c.get(), 0);
            c.inc(1);
            assert_eq!(c.get(), 1);
            c.dec(1);
            assert_eq!(c.get(), 0);

            c.dec(-1);
            assert_eq!(c.get(), 1);
            c.inc(-1);
            assert_eq!(c.get(), 0);
        }
    }

    // TODO(scode): Test gauge.
}

<commit_msg>Remove redundant empty line.<commit_after>// XXX(scode): Consider supporting cloning/snapshotting metrics.
// XXX(scode): Missing histograms.
// XXX(scode): Missing meters (questionable).
// XXX(scode): Transition to lock-less where possible.

use std::num::Int;
use std::sync::Arc;
use std::sync::Mutex;

/// A 64 bit signed counter.
pub trait Counter<T: Int> {
    /// Increment the counter by the given delta.
    ///
    // The delta may be negative (for types T where this is possible).
    fn inc(&mut self, delta: T);

    /// Decrement the counter by the given delta.
    ///
    /// The delta may be negative (for types T where this is possible).
    ///
    /// dec(n) is equivalent of dec(-n)
    fn dec(&mut self, delta: T);

    /// Return the current value of the counter.
    fn get(&self) -> T;
}

/// A gauge has a single value at any given moment in time, and can only be
/// updated by providing an entirely new value.
pub trait Gauge<T: Clone> {
    fn set(&mut self, value: Option<T>);
    fn get(&self) -> Option<T>;
}

pub struct SimpleCounter<T: Int> {
    value: T,
}

impl<T: Int> Counter<T> for SimpleCounter<T> {
    fn inc(&mut self, delta: T) {
        self.value = self.value + delta;
    }

    fn dec(&mut self, delta: T) {
        self.value = self.value - delta;
    }

    fn get(&self) -> T {
        self.value
    }
}

pub struct SharedCounter<T: Int + Send> {
    value: Arc<Mutex<T>>,
}

impl<T: Int + Send> Counter<T> for SharedCounter<T> {
    fn inc(&mut self, delta: T) {
        let mut value = self.value.lock().unwrap();

        *value = *value + delta;
    }

    fn dec(&mut self, delta: T) {
        let mut value = self.value.lock().unwrap();

        *value = *value - delta;
    }

    fn get(&self) -> T {
        let value = self.value.lock().unwrap();

        *value
    }
}

pub struct SimpleGauge<T: Clone> {
    value: Option<T>,
}

impl<T: Clone> Gauge<T> for SimpleGauge<T> {
    fn set(&mut self, new_value: Option<T>) {
        self.value = new_value;
    }

    fn get(&self) -> Option<T> {
        self.value.clone()
    }
}

pub struct SharedGauge<T: Send> {
    value: Arc<Mutex<Option<T>>>,
}

impl<T: Clone + Send> Gauge<T> for SharedGauge<T> {
    fn set(&mut self, new_value: Option<T>) {
        *self.value.lock().unwrap() = new_value;
    }

    fn get(&self) -> Option<T> {
        (*self.value.lock().unwrap()).clone()
    }
}

#[cfg(test)]
mod test {
    use std::sync::Arc;
    use std::sync::Mutex;

    #[test]
    fn test_counters() {
        use metrics::Counter;
        use metrics::SharedCounter;
        use metrics::SimpleCounter;

        let mut counters = Vec::<Box<Counter<i64>>>::new();
        counters.push(Box::new(SimpleCounter { value: 0i64, }));
        counters.push(Box::new(SharedCounter { value: Arc::new(Mutex::new(0i64)) }));

        for mut c in counters {
            assert_eq!(c.get(), 0);
            c.inc(1);
            assert_eq!(c.get(), 1);
            c.dec(1);
            assert_eq!(c.get(), 0);

            c.dec(-1);
            assert_eq!(c.get(), 1);
            c.inc(-1);
            assert_eq!(c.get(), 0);
        }
    }

    // TODO(scode): Test gauge.
}

<|endoftext|>


<commit_before>#![crate_type = "bin"]
extern crate js;
extern crate collections;
use js::lexer::Lexer;
use js::parser::Parser;
use js::exec::{Executor, Interpreter};
use js::ast::{Token, TComment};
use js::stdlib::value::{Value, ResultValue, to_value, from_value};
use collections::treemap::TreeMap;
use std::path::posix::Path;
use std::io::fs::{File, walk_dir};
use std::io::BufferedReader;
fn find_attrs(tokens: Vec<Token>) -> TreeMap<StrBuf, StrBuf> {
	let mut map = TreeMap::new();
	for tk in tokens.iter() {
		match tk.data {
			TComment(ref comm) => {
				let current = comm.as_slice();
				if current.starts_with(" @") {
					let space_ind = current.slice_from(1).find(' ').unwrap() + 1;
					let key = current.slice_chars(2, space_ind);
					let value = current.slice_from(space_ind + 1);
					map.insert(key.into_strbuf(), value.into_strbuf());
				}
			},
			_ => ()
		}
	}
	map
}
fn assert(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	if args.len() < 2 {
		return Err(to_value("'assert' function expects assertion and description arguments"));
	}
	let val : bool = from_value(*args.get(0)).unwrap();
	let desc : Value = *args.get(1);
	if val {
		Ok(desc)
	} else {
		Err(desc)
	}
}
fn main() {
	let mut path = Path::new("tests");
	if !path.is_dir() {
		path = Path::new("../tests");
	}
	if !path.is_dir() {
		fail!("Could not find tests directory");
	}
	for file in walk_dir(&path).unwrap() {
		if file.is_file() && file.extension_str() == Some("js") {
			let file_str = file.as_str().unwrap();
			let mut lexer = Lexer::new(BufferedReader::new(File::open(&file).unwrap()));
			lexer.lex().unwrap();
			let attributes = find_attrs(lexer.tokens.clone());
			let description = match attributes.find(&"description".into_strbuf()) {
				Some(desc) => desc,
				None => fail!("{} does not have @description metadata", file_str)
			};
			let mut parser = Parser::new(lexer.tokens);
			let expr = match parser.parse_all() {
				Ok(v) => v,
				Err(v) => fail!("{}: {}", file_str, v)
			};
			let mut engine : Interpreter = Executor::new();
			engine.set_global("assert".into_strbuf(), to_value(assert));
			let result : Result<Value, Value> = engine.run(&expr);
			match result {
				Ok(_) => println!("{}: All tests passed for {}", file_str, description),
				Err(v) => fail!("{}: Test failed for {} in {}", file_str, v.borrow(), description)
			}
		}
	}
}<commit_msg>Add verbosity option to tester<commit_after>#![crate_type = "bin"]
extern crate js;
extern crate collections;
use js::lexer::Lexer;
use js::parser::Parser;
use js::exec::{Executor, Interpreter};
use js::ast::{Token, TComment};
use js::stdlib::value::{Value, ResultValue, to_value, from_value};
use collections::treemap::TreeMap;
use std::path::posix::Path;
use std::io::fs::{File, walk_dir};
use std::io::BufferedReader;
use std::os;
fn find_attrs(tokens: Vec<Token>) -> TreeMap<StrBuf, StrBuf> {
	let mut map = TreeMap::new();
	for tk in tokens.iter() {
		match tk.data {
			TComment(ref comm) => {
				let current = comm.as_slice();
				if current.starts_with(" @") {
					let space_ind = current.slice_from(1).find(' ').unwrap() + 1;
					let key = current.slice_chars(2, space_ind);
					let value = current.slice_from(space_ind + 1);
					map.insert(key.into_strbuf(), value.into_strbuf());
				}
			},
			_ => ()
		}
	}
	map
}
fn assert(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	if args.len() < 2 {
		return Err(to_value("'assert' function expects assertion and description arguments"));
	}
	let val : bool = from_value(*args.get(0)).unwrap();
	let desc : Value = *args.get(1);
	if val {
		Ok(desc)
	} else {
		Err(desc)
	}
}
fn main() {
	let args = os::args();
	let verbose = args.contains(&"-v".into_strbuf()) || args.contains(&"--verbose".into_strbuf());
	let mut path = Path::new("tests");
	if !path.is_dir() {
		path = Path::new("../tests");
	}
	if !path.is_dir() {
		fail!("Could not find tests directory");
	}
	for file in walk_dir(&path).unwrap() {
		if file.is_file() && file.extension_str() == Some("js") {
			let file_str = file.as_str().unwrap();
			let mut lexer = Lexer::new(BufferedReader::new(File::open(&file).unwrap()));
			lexer.lex().unwrap();
			if verbose {
				println!("{}", lexer.tokens.clone().iter().map(|tk| tk.to_str()).collect::<Vec<StrBuf>>().connect("\n"));
			}
			let attributes = find_attrs(lexer.tokens.clone());
			let description = match attributes.find(&"description".into_strbuf()) {
				Some(desc) => desc,
				None => fail!("{} does not have @description metadata", file_str)
			};
			let mut parser = Parser::new(lexer.tokens);
			let expr = match parser.parse_all() {
				Ok(v) => v,
				Err(v) => fail!("{}: {}", file_str, v)
			};
			let mut engine : Interpreter = Executor::new();
			engine.set_global("assert".into_strbuf(), to_value(assert));
			let result : Result<Value, Value> = engine.run(&expr);
			match result {
				Ok(_) => println!("{}: All tests passed for {}", file_str, description),
				Err(v) => fail!("{}: Test failed for {} in {}", file_str, v.borrow(), description)
			}
		}
	}
}<|endoftext|>


<commit_before>// Copyright © 2018 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

extern crate docopt;
extern crate richter;
#[macro_use]
extern crate serde_derive;

use std::env;
use std::fs;
use std::fs::File;
use std::io::BufWriter;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
use std::process::exit;

use richter::common::pak::Pak;

use docopt::Docopt;

#[derive(Deserialize)]
struct Args {
    arg_source: String,
    arg_dest: Option<String>,
    flag_h: bool,
    flag_help: bool,
    flag_v: bool,
    flag_verbose: bool,
    flag_version: bool,
}

const USAGE: &'static str = "
Usage: unpak <source>
       unpak <source> <dest>

Options:
    -v, --verbose  Produce detailed output.

    -h, --help     Show this message and exit.
        --version  Print version information and exit.
";

const VERSION: &'static str = "
unpak 0.1
Copyright © 2018 Cormac O'Brien
Released under the terms of the MIT License
";

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    if args.flag_help || args.flag_h {
        println!("{}", USAGE);
        exit(0);
    }

    if args.flag_version {
        println!("{}", VERSION);
        exit(0);
    }

    let mut pak = Pak::new();
    match pak.add(&args.arg_source) {
        Ok(p) => p,
        Err(why) => {
            println!("Couldn't open {}: {}", &args.arg_source, why);
            exit(1);
        }
    };

    for (k, v) in pak.iter() {
        let mut path = PathBuf::new();

        if let Some(ref d) = args.arg_dest {
            path.push(d);
        }

        path.push(k);

        if let Some(p) = path.parent() {
            if !p.exists() {
                if let Err(why) = fs::create_dir_all(p) {
                    println!("Couldn't create parent directories: {}", why);
                    exit(1);
                }
            }
        }

        let file = match File::create(&path) {
            Ok(f) => f,
            Err(why) => {
                println!("Couldn't open {}: {}", path.to_str().unwrap(), why);
                exit(1);
            }
        };

        let mut writer = BufWriter::new(file);
        match writer.write_all(v) {
            Ok(_) => (),
            Err(why) => {
                println!("Couldn't write to {}: {}", path.to_str().unwrap(), why);
                exit(1);
            }
        }
    }
}
<commit_msg>Fix unpak<commit_after>// Copyright © 2018 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

extern crate docopt;
extern crate richter;
#[macro_use]
extern crate serde_derive;

use std::env;
use std::fs;
use std::fs::File;
use std::io::BufWriter;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
use std::process::exit;

use richter::common::pak::Pak;

use docopt::Docopt;

#[derive(Deserialize)]
struct Args {
    arg_source: String,
    arg_dest: Option<String>,
    flag_h: bool,
    flag_help: bool,
    flag_v: bool,
    flag_verbose: bool,
    flag_version: bool,
}

const USAGE: &'static str = "
Usage: unpak <source>
       unpak <source> <dest>

Options:
    -v, --verbose  Produce detailed output.

    -h, --help     Show this message and exit.
        --version  Print version information and exit.
";

const VERSION: &'static str = "
unpak 0.1
Copyright © 2018 Cormac O'Brien
Released under the terms of the MIT License
";

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    if args.flag_help || args.flag_h {
        println!("{}", USAGE);
        exit(0);
    }

    if args.flag_version {
        println!("{}", VERSION);
        exit(0);
    }

    let pak = match Pak::new(&args.arg_source) {
        Ok(p) => p,
        Err(why) => {
            println!("Couldn't open {}: {}", &args.arg_source, why);
            exit(1);
        }
    };

    for (k, v) in pak.iter() {
        let mut path = PathBuf::new();

        if let Some(ref d) = args.arg_dest {
            path.push(d);
        }

        path.push(k);

        if let Some(p) = path.parent() {
            if !p.exists() {
                if let Err(why) = fs::create_dir_all(p) {
                    println!("Couldn't create parent directories: {}", why);
                    exit(1);
                }
            }
        }

        let file = match File::create(&path) {
            Ok(f) => f,
            Err(why) => {
                println!("Couldn't open {}: {}", path.to_str().unwrap(), why);
                exit(1);
            }
        };

        let mut writer = BufWriter::new(file);
        match writer.write_all(v.as_ref()) {
            Ok(_) => (),
            Err(why) => {
                println!("Couldn't write to {}: {}", path.to_str().unwrap(), why);
                exit(1);
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::str::raw;
use std::os::getenv;
use std::path::Path;
use std::libc::{c_int, c_char};
use sync::mutex::{StaticMutex, MUTEX_INIT};

static mut LOCK: StaticMutex = MUTEX_INIT;

static mut registered_drivers: bool = false;

struct Dataset {
    c_dataset: *(),
}

struct Driver {
    c_driver: *(),
}

#[link(name = "gdal")]
extern {
    fn GDALVersionInfo(key: *c_char) -> *c_char;
    fn GDALOpen(pszFilename: *c_char, eAccess: c_int) -> *();
    fn GDALClose(hDS: *());
    fn GDALGetDatasetDriver(hDataset: *()) -> *();
    fn GDALGetRasterXSize(hDataset: *()) -> c_int;
    fn GDALGetRasterYSize(hDataset: *()) -> c_int;
    fn GDALGetRasterCount(hDataset: *()) -> c_int;
    fn GDALGetProjectionRef(hDS: *()) -> *c_char;
    fn GDALSetProjection(hDS: *(), pszProjection: *c_char) -> c_int;
    fn GDALAllRegister();
    fn GDALGetDriverByName(pszName: *c_char) -> *();
    fn GDALGetDriverShortName(hDriver: *()) -> *c_char;
    fn GDALGetDriverLongName(hDriver: *()) -> *c_char;
}
static GA_ReadOnly: c_int = 0;
static GA_Update: c_int = 1;

fn register_drivers() {
    unsafe {
        let _g = LOCK.lock();
        if ! registered_drivers {
            GDALAllRegister();
            registered_drivers = true;
        }
    }
}

pub fn version_info(key: &str) -> ~str {
    let info = key.with_c_str(|c_key| {
        unsafe {
            return raw::from_c_str(GDALVersionInfo(c_key));
        };
    });
    return info;
}

pub fn open(path: &Path) -> Option<Dataset> {
    register_drivers();
    let filename = path.as_str().unwrap();
    let c_dataset = filename.with_c_str(|c_filename| {
        unsafe {
            return GDALOpen(c_filename, GA_ReadOnly);
        };
    });
    return match c_dataset.is_null() {
        true  => None,
        false => Some(Dataset{c_dataset: c_dataset}),
    };
}

impl Drop for Dataset {
    fn drop(&mut self) {
        unsafe {
            GDALClose(self.c_dataset);
        }
    }
}

impl Dataset {
    pub fn get_raster_size(&self) -> (int, int) {
        unsafe {
            let size_x = GDALGetRasterXSize(self.c_dataset) as int;
            let size_y = GDALGetRasterYSize(self.c_dataset) as int;
            return (size_x, size_y);
        }
    }

    pub fn get_driver(&self) -> Driver {
        let mut c_driver;
        unsafe {
            c_driver = GDALGetDatasetDriver(self.c_dataset);
        };
        return Driver{c_driver: c_driver};
    }

    pub fn get_raster_count(&self) -> int {
        unsafe {
            return GDALGetRasterCount(self.c_dataset) as int;
        }
    }

    pub fn get_projection(&self) -> ~str {
        unsafe {
            return raw::from_c_str(GDALGetProjectionRef(self.c_dataset));
        }
    }

    pub fn set_projection(&self, projection: &str) {
        projection.with_c_str(|c_projection| {
            unsafe {
                GDALSetProjection(self.c_dataset, c_projection);
            }
        });
    }
}

pub fn get_driver(name: &str) -> Option<Driver> {
    register_drivers();
    let c_driver = name.with_c_str(|c_name| {
        unsafe {
            return GDALGetDriverByName(c_name);
        }
    });
    return match c_driver.is_null() {
        true  => None,
        false => Some(Driver{c_driver: c_driver}),
    };
}

impl Driver {
    pub fn get_short_name(&self) -> ~str {
        unsafe {
            return raw::from_c_str(GDALGetDriverShortName(self.c_driver));
        }
    }

    pub fn get_long_name(&self) -> ~str {
        unsafe {
            return raw::from_c_str(GDALGetDriverLongName(self.c_driver));
        }
    }
}

#[test]
fn test_version_info() {
    let release_date = version_info("RELEASE_DATE");
    let release_name = version_info("RELEASE_NAME");
    let version_text = version_info("--version");

    let expected_text: ~str = "GDAL " + release_name + ", " +
        "released " + release_date.slice(0, 4) + "/" +
        release_date.slice(4, 6) + "/" + release_date.slice(6, 8);

    assert_eq!(version_text.into_owned(), expected_text);
}

fn fixture_path(name: &str) -> Path {
    let envvar = "RUSTILES_TEST_FIXTURES";
    let fixtures = match getenv(envvar) {
        Some(p) => Path::new(p),
        None => fail!("Environment variable {} not set", envvar)
    };
    let rv = fixtures.join(name);
    return rv;
}

#[test]
fn test_open() {
    let dataset = open(&fixture_path("tinymarble.jpeg"));
    assert!(dataset.is_some());

    let missing_dataset = open(&fixture_path("no_such_file.jpeg"));
    assert!(missing_dataset.is_none());
}

#[test]
fn test_get_raster_size() {
    let dataset = open(&fixture_path("tinymarble.jpeg")).unwrap();
    let (size_x, size_y) = dataset.get_raster_size();
    assert_eq!(size_x, 100);
    assert_eq!(size_y, 50);
}

#[test]
fn test_get_raster_count() {
    let dataset = open(&fixture_path("tinymarble.jpeg")).unwrap();
    let count = dataset.get_raster_count();
    assert_eq!(count, 3);
}

#[test]
fn test_get_projection() {
    let dataset = open(&fixture_path("tinymarble.jpeg")).unwrap();
    //dataset.set_projection("WGS84");
    let projection = dataset.get_projection();
    assert_eq!(projection.slice(0, 16), "GEOGCS[\"WGS 84\",");
}

#[test]
fn test_get_dataset_driver() {
    let dataset = open(&fixture_path("tinymarble.jpeg")).unwrap();
    let driver = dataset.get_driver();
    assert_eq!(driver.get_short_name(), ~"JPEG");
    assert_eq!(driver.get_long_name(), ~"JPEG JFIF");
}

#[test]
fn test_get_driver_by_name() {
    let missing_driver = get_driver("wtf");
    assert!(missing_driver.is_none());

    let ok_driver = get_driver("GTiff");
    assert!(ok_driver.is_some());
    let driver = ok_driver.unwrap();
    assert_eq!(driver.get_short_name(), ~"GTiff");
    assert_eq!(driver.get_long_name(), ~"GeoTIFF");
}
<commit_msg>tidy up unsafe code blocks<commit_after>use std::str::raw;
use std::os::getenv;
use std::path::Path;
use std::libc::{c_int, c_char};
use sync::mutex::{StaticMutex, MUTEX_INIT};

static mut LOCK: StaticMutex = MUTEX_INIT;

static mut registered_drivers: bool = false;

struct Dataset {
    c_dataset: *(),
}

struct Driver {
    c_driver: *(),
}

#[link(name = "gdal")]
extern {
    fn GDALVersionInfo(key: *c_char) -> *c_char;
    fn GDALOpen(pszFilename: *c_char, eAccess: c_int) -> *();
    fn GDALClose(hDS: *());
    fn GDALGetDatasetDriver(hDataset: *()) -> *();
    fn GDALGetRasterXSize(hDataset: *()) -> c_int;
    fn GDALGetRasterYSize(hDataset: *()) -> c_int;
    fn GDALGetRasterCount(hDataset: *()) -> c_int;
    fn GDALGetProjectionRef(hDS: *()) -> *c_char;
    fn GDALSetProjection(hDS: *(), pszProjection: *c_char) -> c_int;
    fn GDALAllRegister();
    fn GDALGetDriverByName(pszName: *c_char) -> *();
    fn GDALGetDriverShortName(hDriver: *()) -> *c_char;
    fn GDALGetDriverLongName(hDriver: *()) -> *c_char;
}
static GA_ReadOnly: c_int = 0;
static GA_Update: c_int = 1;

fn register_drivers() {
    unsafe {
        let _g = LOCK.lock();
        if ! registered_drivers {
            GDALAllRegister();
            registered_drivers = true;
        }
    }
}

pub fn version_info(key: &str) -> ~str {
    let info = key.with_c_str(|c_key| {
        unsafe {
            let rv = GDALVersionInfo(c_key);
            return raw::from_c_str(rv);
        };
    });
    return info;
}

pub fn open(path: &Path) -> Option<Dataset> {
    register_drivers();
    let filename = path.as_str().unwrap();
    let c_dataset = filename.with_c_str(|c_filename| {
        return unsafe { GDALOpen(c_filename, GA_ReadOnly) };
    });
    return match c_dataset.is_null() {
        true  => None,
        false => Some(Dataset{c_dataset: c_dataset}),
    };
}

impl Drop for Dataset {
    fn drop(&mut self) {
        unsafe { GDALClose(self.c_dataset); }
    }
}

impl Dataset {
    pub fn get_raster_size(&self) -> (int, int) {
        let size_x = unsafe { GDALGetRasterXSize(self.c_dataset) } as int;
        let size_y = unsafe { GDALGetRasterYSize(self.c_dataset) } as int;
        return (size_x, size_y);
    }

    pub fn get_driver(&self) -> Driver {
        let c_driver = unsafe { GDALGetDatasetDriver(self.c_dataset) };
        return Driver{c_driver: c_driver};
    }

    pub fn get_raster_count(&self) -> int {
        return unsafe { GDALGetRasterCount(self.c_dataset) } as int;
    }

    pub fn get_projection(&self) -> ~str {
        unsafe {
            let rv = GDALGetProjectionRef(self.c_dataset);
            return raw::from_c_str(rv);
        }
    }

    pub fn set_projection(&self, projection: &str) {
        projection.with_c_str(|c_projection| {
            unsafe { GDALSetProjection(self.c_dataset, c_projection) };
        });
    }
}

pub fn get_driver(name: &str) -> Option<Driver> {
    register_drivers();
    let c_driver = name.with_c_str(|c_name| {
        return unsafe { GDALGetDriverByName(c_name) };
    });
    return match c_driver.is_null() {
        true  => None,
        false => Some(Driver{c_driver: c_driver}),
    };
}

impl Driver {
    pub fn get_short_name(&self) -> ~str {
        unsafe {
            let rv = GDALGetDriverShortName(self.c_driver);
            return raw::from_c_str(rv);
        }
    }

    pub fn get_long_name(&self) -> ~str {
        unsafe {
            let rv = GDALGetDriverLongName(self.c_driver);
            return raw::from_c_str(rv);
        }
    }
}

#[test]
fn test_version_info() {
    let release_date = version_info("RELEASE_DATE");
    let release_name = version_info("RELEASE_NAME");
    let version_text = version_info("--version");

    let expected_text: ~str = "GDAL " + release_name + ", " +
        "released " + release_date.slice(0, 4) + "/" +
        release_date.slice(4, 6) + "/" + release_date.slice(6, 8);

    assert_eq!(version_text.into_owned(), expected_text);
}

fn fixture_path(name: &str) -> Path {
    let envvar = "RUSTILES_TEST_FIXTURES";
    let fixtures = match getenv(envvar) {
        Some(p) => Path::new(p),
        None => fail!("Environment variable {} not set", envvar)
    };
    let rv = fixtures.join(name);
    return rv;
}

#[test]
fn test_open() {
    let dataset = open(&fixture_path("tinymarble.jpeg"));
    assert!(dataset.is_some());

    let missing_dataset = open(&fixture_path("no_such_file.jpeg"));
    assert!(missing_dataset.is_none());
}

#[test]
fn test_get_raster_size() {
    let dataset = open(&fixture_path("tinymarble.jpeg")).unwrap();
    let (size_x, size_y) = dataset.get_raster_size();
    assert_eq!(size_x, 100);
    assert_eq!(size_y, 50);
}

#[test]
fn test_get_raster_count() {
    let dataset = open(&fixture_path("tinymarble.jpeg")).unwrap();
    let count = dataset.get_raster_count();
    assert_eq!(count, 3);
}

#[test]
fn test_get_projection() {
    let dataset = open(&fixture_path("tinymarble.jpeg")).unwrap();
    //dataset.set_projection("WGS84");
    let projection = dataset.get_projection();
    assert_eq!(projection.slice(0, 16), "GEOGCS[\"WGS 84\",");
}

#[test]
fn test_get_dataset_driver() {
    let dataset = open(&fixture_path("tinymarble.jpeg")).unwrap();
    let driver = dataset.get_driver();
    assert_eq!(driver.get_short_name(), ~"JPEG");
    assert_eq!(driver.get_long_name(), ~"JPEG JFIF");
}

#[test]
fn test_get_driver_by_name() {
    let missing_driver = get_driver("wtf");
    assert!(missing_driver.is_none());

    let ok_driver = get_driver("GTiff");
    assert!(ok_driver.is_some());
    let driver = ok_driver.unwrap();
    assert_eq!(driver.get_short_name(), ~"GTiff");
    assert_eq!(driver.get_long_name(), ~"GeoTIFF");
}
<|endoftext|>


<commit_before>use super::{Observation, Transition, Domain};

use geometry::{ActionSpace, RegularSpace};
use geometry::dimensions::{Continuous, Discrete};

const X_MIN: f64 = -1.2;
const X_MAX: f64 = 0.6;

const V_MIN: f64 = -0.07;
const V_MAX: f64 = 0.07;

const FORCE_G: f64 = -0.0025;
const FORCE_CAR: f64 = 0.001;

const HILL_FREQ: f64 = 3.0;

const STEP_REWARD: f64 = -1.0;
const GOAL_REWARD: f64 = 0.0;

const ALL_ACTIONS: [f64; 3] = [-1.0, 0.0, 1.0];

pub struct MountainCar {
    state: (f64, f64),
}

impl MountainCar {
    fn new(state: (f64, f64)) -> MountainCar {
        MountainCar {
            state: state
        }
    }

    fn initial_state() -> (f64, f64) {
        (-0.5, 0.0)
    }

    fn dv(x: f64, a: f64) -> f64 {
        FORCE_CAR * a + FORCE_G * (HILL_FREQ * x).cos()
    }

    fn update_state(&mut self, a: usize) {
        let a = ALL_ACTIONS[a];

        let v = clip!(V_MIN, self.state.1 + Self::dv(self.state.0, a), V_MAX);
        let x = clip!(X_MIN, self.state.0 + v, X_MAX);

        self.state = (x, v);
    }
}

impl Default for MountainCar {
    fn default() -> MountainCar {
        MountainCar::new(MountainCar::initial_state())
    }
}

impl Domain for MountainCar {
    type StateSpace = RegularSpace<Continuous>;
    type ActionSpace = ActionSpace;

    fn emit(&self) -> Observation<Self::StateSpace, Self::ActionSpace> {
        if self.is_terminal() {
            Observation::Terminal(vec![self.state.0, self.state.1])
        } else {
            Observation::Full {
                state: vec![self.state.0, self.state.1],
                actions: vec![0, 1, 2]
            }
        }
    }

    fn step(&mut self, a: usize) -> Transition<Self::StateSpace, Self::ActionSpace> {
        let from = self.emit();

        self.update_state(a);
        let to = self.emit();
        let r = self.reward(&from, &to);

        Transition {
            from: from,
            action: a,
            reward: r,
            to: to,
        }
    }

    fn is_terminal(&self) -> bool {
        self.state.0 >= X_MAX
    }

    fn reward(&self,
              _: &Observation<Self::StateSpace, Self::ActionSpace>,
              to: &Observation<Self::StateSpace, Self::ActionSpace>) -> f64
    {
        match to {
            &Observation::Terminal(_) => GOAL_REWARD,
            _ => STEP_REWARD,
        }
    }

    fn state_space(&self) -> Self::StateSpace {
        Self::StateSpace::new()
            .push(Continuous::new(X_MIN, X_MAX))
            .push(Continuous::new(V_MIN, V_MAX))
    }

    fn action_space(&self) -> ActionSpace {
        ActionSpace::new(Discrete::new(3))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use domain::{Observation, Domain};

    #[test]
    fn test_initial_observation() {
        let m = MountainCar::default();

        match m.emit() {
            Observation::Full { ref state, .. } => {
                assert_eq!(state[0], -0.5);
                assert_eq!(state[1], 0.0);
            }
            _ => panic!("Should yield a fully observable state."),
        }
    }

    #[test]
    fn test_is_terminal() {
        assert!(!MountainCar::default().is_terminal());
        assert!(!MountainCar::new((-0.5, 0.0)).is_terminal());

        assert!(MountainCar::new((X_MAX, -0.05)).is_terminal());
        assert!(MountainCar::new((X_MAX, 0.0)).is_terminal());
        assert!(MountainCar::new((X_MAX, 0.05)).is_terminal());

        assert!(!MountainCar::new((X_MAX-0.0001*X_MAX, 0.0)).is_terminal());
        assert!(MountainCar::new((X_MAX+0.0001*X_MAX, 0.0)).is_terminal());
    }

    #[test]
    fn test_reward() {
        let mc = MountainCar::default();

        let s = mc.emit();
        let ns = MountainCar::new((X_MAX, 0.0)).emit();

        assert_eq!(mc.reward(&s, &s), STEP_REWARD);
        assert_eq!(mc.reward(&s, &ns), GOAL_REWARD);
    }
}
<commit_msg>Fixed import error due to last commit<commit_after>use super::{Observation, Transition, Domain};

use geometry::{ActionSpace, RegularSpace};
use geometry::dimensions::{Continuous, Discrete};

const X_MIN: f64 = -1.2;
const X_MAX: f64 = 0.6;

const V_MIN: f64 = -0.07;
const V_MAX: f64 = 0.07;

const FORCE_G: f64 = -0.0025;
const FORCE_CAR: f64 = 0.001;

const HILL_FREQ: f64 = 3.0;

const STEP_REWARD: f64 = -1.0;
const GOAL_REWARD: f64 = 0.0;

const ALL_ACTIONS: [f64; 3] = [-1.0, 0.0, 1.0];

pub struct MountainCar {
    state: (f64, f64),
}

impl MountainCar {
    fn new(state: (f64, f64)) -> MountainCar {
        MountainCar {
            state: state
        }
    }

    fn initial_state() -> (f64, f64) {
        (-0.5, 0.0)
    }

    fn dv(x: f64, a: f64) -> f64 {
        FORCE_CAR * a + FORCE_G * (HILL_FREQ * x).cos()
    }

    fn update_state(&mut self, a: usize) {
        let a = ALL_ACTIONS[a];

        let v = clip!(V_MIN, self.state.1 + Self::dv(self.state.0, a), V_MAX);
        let x = clip!(X_MIN, self.state.0 + v, X_MAX);

        self.state = (x, v);
    }
}

impl Default for MountainCar {
    fn default() -> MountainCar {
        MountainCar::new(MountainCar::initial_state())
    }
}

impl Domain for MountainCar {
    type StateSpace = RegularSpace<Continuous>;
    type ActionSpace = ActionSpace;

    fn emit(&self) -> Observation<Self::StateSpace, Self::ActionSpace> {
        if self.is_terminal() {
            Observation::Terminal(vec![self.state.0, self.state.1])
        } else {
            Observation::Full {
                state: vec![self.state.0, self.state.1],
                actions: vec![0, 1, 2]
            }
        }
    }

    fn step(&mut self, a: usize) -> Transition<Self::StateSpace, Self::ActionSpace> {
        let from = self.emit();

        self.update_state(a);
        let to = self.emit();
        let r = self.reward(&from, &to);

        Transition {
            from: from,
            action: a,
            reward: r,
            to: to,
        }
    }

    fn is_terminal(&self) -> bool {
        self.state.0 >= X_MAX
    }

    fn reward(&self,
              _: &Observation<Self::StateSpace, Self::ActionSpace>,
              to: &Observation<Self::StateSpace, Self::ActionSpace>) -> f64
    {
        match to {
            &Observation::Terminal(_) => GOAL_REWARD,
            _ => STEP_REWARD,
        }
    }

    fn state_space(&self) -> Self::StateSpace {
        Self::StateSpace::new()
            .push(Continuous::new(X_MIN, X_MAX))
            .push(Continuous::new(V_MIN, V_MAX))
    }

    fn action_space(&self) -> ActionSpace {
        ActionSpace::new(Discrete::new(3))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use domains::{Observation, Domain};

    #[test]
    fn test_initial_observation() {
        let m = MountainCar::default();

        match m.emit() {
            Observation::Full { ref state, .. } => {
                assert_eq!(state[0], -0.5);
                assert_eq!(state[1], 0.0);
            }
            _ => panic!("Should yield a fully observable state."),
        }
    }

    #[test]
    fn test_is_terminal() {
        assert!(!MountainCar::default().is_terminal());
        assert!(!MountainCar::new((-0.5, 0.0)).is_terminal());

        assert!(MountainCar::new((X_MAX, -0.05)).is_terminal());
        assert!(MountainCar::new((X_MAX, 0.0)).is_terminal());
        assert!(MountainCar::new((X_MAX, 0.05)).is_terminal());

        assert!(!MountainCar::new((X_MAX-0.0001*X_MAX, 0.0)).is_terminal());
        assert!(MountainCar::new((X_MAX+0.0001*X_MAX, 0.0)).is_terminal());
    }

    #[test]
    fn test_reward() {
        let mc = MountainCar::default();

        let s = mc.emit();
        let ns = MountainCar::new((X_MAX, 0.0)).emit();

        assert_eq!(mc.reward(&s, &s), STEP_REWARD);
        assert_eq!(mc.reward(&s, &ns), GOAL_REWARD);
    }
}
<|endoftext|>


<commit_before>use libc;
use std::os::unix::io::RawFd;
use {Errno, Result};

bitflags!(
    flags EventFdFlag: libc::c_int {
        const EFD_CLOEXEC   = 0o2000000, // Since Linux 2.6.27
        const EFD_NONBLOCK  = 0o0004000, // Since Linux 2.6.27
        const EFD_SEMAPHORE = 0o0000001, // Since Linux 2.6.30
    }
);

mod ffi {
    use libc;

    extern {
        pub fn eventfd(initval: libc::c_uint, flags: libc::c_int) -> libc::c_int;
    }
}

pub fn eventfd(initval: usize, flags: EventFdFlag) -> Result<RawFd> {
    unsafe {
        let res = ffi::eventfd(initval as libc::c_uint, flags.bits());

        Errno::result(res).map(|r| r as RawFd)
    }
}
<commit_msg>eventfd: Follow nix conventions<commit_after>use libc;
use std::os::unix::io::RawFd;
use {Errno, Result};

libc_bitflags! {
    flags EfdFlags: libc::c_int {
        const EFD_CLOEXEC, // Since Linux 2.6.27
        const EFD_NONBLOCK, // Since Linux 2.6.27
        const EFD_SEMAPHORE, // Since Linux 2.6.30
    }
}

pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<RawFd> {
    let res = unsafe { libc::eventfd(initval, flags.bits()) };

    Errno::result(res).map(|r| r as RawFd)
}
<|endoftext|>


<commit_before>use cgmath::Point2;
use character::controls::CharacterInputState;
use game::constants::{ASPECT_RATIO, TILE_MAP_BUF_LENGTH, TILES_PCS_H, TILES_PCS_W, VIEW_DISTANCE};
use genmesh::{generators::{IndexedPolygon, Plane, SharedVertex}, Triangulate, Vertices};
use gfx;
use gfx_app::{ColorFormat, DepthFormat};
use graphics::{camera::CameraInputState, can_move_to_tile, coords_to_tile, dimensions::{Dimensions, get_projection, get_view_matrix}, is_map_edge};
use graphics::mesh::Mesh;
use graphics::texture::{load_texture, Texture};
use shaders::{Position, Projection, tilemap_pipeline, TilemapSettings, VertexData};
use specs;
use specs::prelude::{Read, ReadStorage, WriteStorage};

pub mod path_finding;
mod path_finding_test;
pub mod tile_map;

fn cartesian_to_isometric(point_x: f32, point_y: f32) -> (f32, f32) {
  ((point_x - point_y), (point_x + point_y) / 1.78)
}

#[derive(Debug)]
pub struct TerrainDrawable {
  projection: Projection,
  pub position: Position,
  pub tile_position: Point2<i32>,
}

impl TerrainDrawable {
  pub fn new() -> TerrainDrawable {
    let view = get_view_matrix(VIEW_DISTANCE);
    let projection = get_projection(view, ASPECT_RATIO);
    TerrainDrawable {
      projection,
      position: Position::origin(),
      tile_position: coords_to_tile(Position::origin())
    }
  }

  pub fn update(&mut self, world_to_clip: &Projection, ci: &mut CharacterInputState) {
    self.projection = *world_to_clip;
    if can_move_to_tile(ci.movement) {
      ci.is_colliding = false;
      self.position = ci.movement;
      self.tile_position = coords_to_tile(self.position);
    } else {
      ci.is_colliding = true;
    }
    println!("Pos {:?}", self.tile_position);
  }
}

impl specs::prelude::Component for TerrainDrawable {
  type Storage = specs::storage::HashMapStorage<TerrainDrawable>;
}

const SHADER_VERT: &[u8] = include_bytes!("../shaders/terrain.v.glsl");
const SHADER_FRAG: &[u8] = include_bytes!("../shaders/terrain.f.glsl");

pub struct TerrainDrawSystem<R: gfx::Resources> {
  bundle: gfx::pso::bundle::Bundle<R, tilemap_pipeline::Data<R>>,
  terrain: tile_map::Terrain,
  is_tile_map_dirty: bool,
}

impl<R: gfx::Resources> TerrainDrawSystem<R> {
  pub fn new<F>(factory: &mut F,
                rtv: gfx::handle::RenderTargetView<R, ColorFormat>,
                dsv: gfx::handle::DepthStencilView<R, DepthFormat>)
                -> TerrainDrawSystem<R>
                where F: gfx::Factory<R> {
    use gfx::traits::FactoryExt;

    let tile_size = 32;
    let width = TILES_PCS_W;
    let height = TILES_PCS_H;
    let half_width = (tile_size * width) / 2;
    let half_height = (tile_size * height) / 2;

    let plane = Plane::subdivide(width, width);
    let vertex_data: Vec<VertexData> =
      plane.shared_vertex_iter()
           .map(|vertex| {
             let (raw_x, raw_y) = cartesian_to_isometric(vertex.pos[0], vertex.pos[1]);
             let vertex_x = half_width as f32 * raw_x;
             let vertex_y = half_height as f32 * raw_y;

             let (u_pos, v_pos) = ((raw_x / 4.0 - raw_y / 2.25) + 0.5, (raw_x / 4.0 + raw_y / 2.25) + 0.5);
             let tile_map_x = u_pos * width as f32;
             let tile_map_y = v_pos * height as f32;

             VertexData {
               pos: [vertex_x, vertex_y],
               uv: [tile_map_x as f32, tile_map_y as f32],
             }
           })
           .collect();

    let index_data =
      plane.indexed_polygon_iter()
           .triangulate()
           .vertices()
           .map(|i| i as u16)
           .collect::<Vec<u16>>();

    let tile_sheet_bytes = &include_bytes!("../../assets/maps/terrain.png")[..];
    let tile_texture = load_texture(factory, tile_sheet_bytes);

    let mesh = Mesh::new(factory, &vertex_data.as_slice(), index_data.as_slice(), Texture::new(tile_texture, None));

    let pso = factory.create_pipeline_simple(SHADER_VERT, SHADER_FRAG, tilemap_pipeline::new())
                     .map_err(|err| panic!("Terrain shader loading error {:?}", err))
                     .unwrap();

    let pipeline_data = tilemap_pipeline::Data {
      vbuf: mesh.vertex_buffer,
      position_cb: factory.create_constant_buffer(1),
      projection_cb: factory.create_constant_buffer(1),
      tilemap: factory.create_constant_buffer(TILE_MAP_BUF_LENGTH),
      tilemap_cb: factory.create_constant_buffer(1),
      tilesheet: (mesh.texture.raw, factory.create_sampler_linear()),
      out_color: rtv,
      out_depth: dsv,
    };

    let terrain = tile_map::Terrain::new();

    TerrainDrawSystem {
      bundle: gfx::Bundle::new(mesh.slice, pso, pipeline_data),
      terrain,
      is_tile_map_dirty: true,
    }
  }

  pub fn draw<C>(&mut self,
                 drawable: &TerrainDrawable,
                 encoder: &mut gfx::Encoder<R, C>)
                 where C: gfx::CommandBuffer<R> {
    encoder.update_constant_buffer(&self.bundle.data.projection_cb, &drawable.projection);
    encoder.update_constant_buffer(&self.bundle.data.position_cb, &drawable.position);

    self.handle_map_update(drawable);

    if self.is_tile_map_dirty {
      encoder.update_buffer(&self.bundle.data.tilemap, self.terrain.tiles.as_slice(), 0).unwrap();
      encoder.update_constant_buffer(&self.bundle.data.tilemap_cb, &TilemapSettings {
        world_size: [TILES_PCS_W as f32, TILES_PCS_H as f32],
        tilesheet_size: [32.0, 32.0],
      });
      self.is_tile_map_dirty = false
    }

    self.bundle.encode(encoder);
  }

  fn handle_map_update(&mut self, drawable: &TerrainDrawable) {
    if is_map_edge(drawable.tile_position) {
      let map_idx = self.terrain.curr_tile_set_idx;
      if map_idx == 0 {
        self.terrain.change_map(1);
      } else if map_idx == 1 {
        self.terrain.change_map(0);
      }
      self.is_tile_map_dirty = true
    }
  }
}

#[derive(Debug)]
pub struct PreDrawSystem;

impl PreDrawSystem {
  pub fn new() -> PreDrawSystem {
    PreDrawSystem {}
  }
}

impl<'a> specs::prelude::System<'a> for PreDrawSystem {
  type SystemData = (WriteStorage<'a, TerrainDrawable>,
                     ReadStorage<'a, CameraInputState>,
                     WriteStorage<'a, CharacterInputState>,
                     Read<'a, Dimensions>);

  fn run(&mut self, (mut terrain, camera_input, mut character_input, dim): Self::SystemData) {
    use specs::join::Join;

    for (t, camera, ci) in (&mut terrain, &camera_input, &mut character_input).join() {
      let world_to_clip = dim.world_to_projection(camera);
      t.update(&world_to_clip, ci);
    }
  }
}
<commit_msg>Remove tile pos logging<commit_after>use cgmath::Point2;
use character::controls::CharacterInputState;
use game::constants::{ASPECT_RATIO, TILE_MAP_BUF_LENGTH, TILES_PCS_H, TILES_PCS_W, VIEW_DISTANCE};
use genmesh::{generators::{IndexedPolygon, Plane, SharedVertex}, Triangulate, Vertices};
use gfx;
use gfx_app::{ColorFormat, DepthFormat};
use graphics::{camera::CameraInputState, can_move_to_tile, coords_to_tile, dimensions::{Dimensions, get_projection, get_view_matrix}, is_map_edge};
use graphics::mesh::Mesh;
use graphics::texture::{load_texture, Texture};
use shaders::{Position, Projection, tilemap_pipeline, TilemapSettings, VertexData};
use specs;
use specs::prelude::{Read, ReadStorage, WriteStorage};

pub mod path_finding;
mod path_finding_test;
pub mod tile_map;

fn cartesian_to_isometric(point_x: f32, point_y: f32) -> (f32, f32) {
  ((point_x - point_y), (point_x + point_y) / 1.78)
}

#[derive(Debug)]
pub struct TerrainDrawable {
  projection: Projection,
  pub position: Position,
  pub tile_position: Point2<i32>,
}

impl TerrainDrawable {
  pub fn new() -> TerrainDrawable {
    let view = get_view_matrix(VIEW_DISTANCE);
    let projection = get_projection(view, ASPECT_RATIO);
    TerrainDrawable {
      projection,
      position: Position::origin(),
      tile_position: coords_to_tile(Position::origin())
    }
  }

  pub fn update(&mut self, world_to_clip: &Projection, ci: &mut CharacterInputState) {
    self.projection = *world_to_clip;
    if can_move_to_tile(ci.movement) {
      ci.is_colliding = false;
      self.position = ci.movement;
      self.tile_position = coords_to_tile(self.position);
    } else {
      ci.is_colliding = true;
    }
  }
}

impl specs::prelude::Component for TerrainDrawable {
  type Storage = specs::storage::HashMapStorage<TerrainDrawable>;
}

const SHADER_VERT: &[u8] = include_bytes!("../shaders/terrain.v.glsl");
const SHADER_FRAG: &[u8] = include_bytes!("../shaders/terrain.f.glsl");

pub struct TerrainDrawSystem<R: gfx::Resources> {
  bundle: gfx::pso::bundle::Bundle<R, tilemap_pipeline::Data<R>>,
  terrain: tile_map::Terrain,
  is_tile_map_dirty: bool,
}

impl<R: gfx::Resources> TerrainDrawSystem<R> {
  pub fn new<F>(factory: &mut F,
                rtv: gfx::handle::RenderTargetView<R, ColorFormat>,
                dsv: gfx::handle::DepthStencilView<R, DepthFormat>)
                -> TerrainDrawSystem<R>
                where F: gfx::Factory<R> {
    use gfx::traits::FactoryExt;

    let tile_size = 32;
    let width = TILES_PCS_W;
    let height = TILES_PCS_H;
    let half_width = (tile_size * width) / 2;
    let half_height = (tile_size * height) / 2;

    let plane = Plane::subdivide(width, width);
    let vertex_data: Vec<VertexData> =
      plane.shared_vertex_iter()
           .map(|vertex| {
             let (raw_x, raw_y) = cartesian_to_isometric(vertex.pos[0], vertex.pos[1]);
             let vertex_x = half_width as f32 * raw_x;
             let vertex_y = half_height as f32 * raw_y;

             let (u_pos, v_pos) = ((raw_x / 4.0 - raw_y / 2.25) + 0.5, (raw_x / 4.0 + raw_y / 2.25) + 0.5);
             let tile_map_x = u_pos * width as f32;
             let tile_map_y = v_pos * height as f32;

             VertexData {
               pos: [vertex_x, vertex_y],
               uv: [tile_map_x as f32, tile_map_y as f32],
             }
           })
           .collect();

    let index_data =
      plane.indexed_polygon_iter()
           .triangulate()
           .vertices()
           .map(|i| i as u16)
           .collect::<Vec<u16>>();

    let tile_sheet_bytes = &include_bytes!("../../assets/maps/terrain.png")[..];
    let tile_texture = load_texture(factory, tile_sheet_bytes);

    let mesh = Mesh::new(factory, &vertex_data.as_slice(), index_data.as_slice(), Texture::new(tile_texture, None));

    let pso = factory.create_pipeline_simple(SHADER_VERT, SHADER_FRAG, tilemap_pipeline::new())
                     .map_err(|err| panic!("Terrain shader loading error {:?}", err))
                     .unwrap();

    let pipeline_data = tilemap_pipeline::Data {
      vbuf: mesh.vertex_buffer,
      position_cb: factory.create_constant_buffer(1),
      projection_cb: factory.create_constant_buffer(1),
      tilemap: factory.create_constant_buffer(TILE_MAP_BUF_LENGTH),
      tilemap_cb: factory.create_constant_buffer(1),
      tilesheet: (mesh.texture.raw, factory.create_sampler_linear()),
      out_color: rtv,
      out_depth: dsv,
    };

    let terrain = tile_map::Terrain::new();

    TerrainDrawSystem {
      bundle: gfx::Bundle::new(mesh.slice, pso, pipeline_data),
      terrain,
      is_tile_map_dirty: true,
    }
  }

  pub fn draw<C>(&mut self,
                 drawable: &TerrainDrawable,
                 encoder: &mut gfx::Encoder<R, C>)
                 where C: gfx::CommandBuffer<R> {
    encoder.update_constant_buffer(&self.bundle.data.projection_cb, &drawable.projection);
    encoder.update_constant_buffer(&self.bundle.data.position_cb, &drawable.position);

    self.handle_map_update(drawable);

    if self.is_tile_map_dirty {
      encoder.update_buffer(&self.bundle.data.tilemap, self.terrain.tiles.as_slice(), 0).unwrap();
      encoder.update_constant_buffer(&self.bundle.data.tilemap_cb, &TilemapSettings {
        world_size: [TILES_PCS_W as f32, TILES_PCS_H as f32],
        tilesheet_size: [32.0, 32.0],
      });
      self.is_tile_map_dirty = false
    }

    self.bundle.encode(encoder);
  }

  fn handle_map_update(&mut self, drawable: &TerrainDrawable) {
    if is_map_edge(drawable.tile_position) {
      let map_idx = self.terrain.curr_tile_set_idx;
      if map_idx == 0 {
        self.terrain.change_map(1);
      } else if map_idx == 1 {
        self.terrain.change_map(0);
      }
      self.is_tile_map_dirty = true
    }
  }
}

#[derive(Debug)]
pub struct PreDrawSystem;

impl PreDrawSystem {
  pub fn new() -> PreDrawSystem {
    PreDrawSystem {}
  }
}

impl<'a> specs::prelude::System<'a> for PreDrawSystem {
  type SystemData = (WriteStorage<'a, TerrainDrawable>,
                     ReadStorage<'a, CameraInputState>,
                     WriteStorage<'a, CharacterInputState>,
                     Read<'a, Dimensions>);

  fn run(&mut self, (mut terrain, camera_input, mut character_input, dim): Self::SystemData) {
    use specs::join::Join;

    for (t, camera, ci) in (&mut terrain, &camera_input, &mut character_input).join() {
      let world_to_clip = dim.world_to_projection(camera);
      t.update(&world_to_clip, ci);
    }
  }
}
<|endoftext|>


<commit_before>//! `bless` updates the reference files in the repo with changed output files
//! from the last test run.

use std::env;
use std::ffi::OsStr;
use std::fs;
use std::lazy::SyncLazy;
use std::path::{Path, PathBuf};
use walkdir::WalkDir;

use crate::clippy_project_root;

// NOTE: this is duplicated with tests/cargo/mod.rs What to do?
pub static CARGO_TARGET_DIR: SyncLazy<PathBuf> = SyncLazy::new(|| match env::var_os("CARGO_TARGET_DIR") {
    Some(v) => v.into(),
    None => env::current_dir().unwrap().join("target"),
});

static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> = SyncLazy::new(|| {
    let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
    let mut path = PathBuf::from(&**CARGO_TARGET_DIR);
    path.push(profile);
    path.push("cargo-clippy");
    fs::metadata(path).ok()?.modified().ok()
});

/// # Panics
///
/// Panics if the path to a test file is broken
pub fn bless(ignore_timestamp: bool) {
    let test_suite_dirs = [
        clippy_project_root().join("tests").join("ui"),
        clippy_project_root().join("tests").join("ui-internal"),
        clippy_project_root().join("tests").join("ui-toml"),
        clippy_project_root().join("tests").join("ui-cargo"),
    ];
    for test_suite_dir in &test_suite_dirs {
        WalkDir::new(test_suite_dir)
            .into_iter()
            .filter_map(Result::ok)
            .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
            .for_each(|f| {
                let test_name = f.path().strip_prefix(test_suite_dir).unwrap();
                for &ext in &["stdout", "stderr", "fixed"] {
                    update_reference_file(
                        f.path().with_extension(ext),
                        test_name.with_extension(ext),
                        ignore_timestamp,
                    );
                }
            });
    }
}

fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf, ignore_timestamp: bool) {
    let test_output_path = build_dir().join(test_name);
    let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();

    // If compiletest did not write any changes during the test run,
    // we don't have to update anything
    if !test_output_path.exists() {
        return;
    }

    // If the test output was not updated since the last clippy build, it may be outdated
    if !ignore_timestamp && !updated_since_clippy_build(&test_output_path).unwrap_or(true) {
        return;
    }

    let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
    let reference_file = fs::read(&reference_file_path).unwrap_or_default();

    if test_output_file != reference_file {
        // If a test run caused an output file to change, update the reference file
        println!("updating {}", &relative_reference_file_path.display());
        fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");

        // We need to re-read the file now because it was potentially updated from copying
        let reference_file = fs::read(&reference_file_path).unwrap_or_default();

        if reference_file.is_empty() {
            // If we copied over an empty output file, we remove the now empty reference file
            println!("removing {}", &relative_reference_file_path.display());
            fs::remove_file(reference_file_path).expect("Could not remove reference file");
        }
    }
}

fn updated_since_clippy_build(path: &Path) -> Option<bool> {
    let clippy_build_time = (*CLIPPY_BUILD_TIME)?;
    let modified = fs::metadata(path).ok()?.modified().ok()?;
    Some(modified >= clippy_build_time)
}

fn build_dir() -> PathBuf {
    let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
    let mut path = PathBuf::new();
    path.push(CARGO_TARGET_DIR.clone());
    path.push(profile);
    path.push("test_build_base");
    path
}
<commit_msg>Auto merge of #6774 - Y-Nak:quick-fix-bless, r=phansch<commit_after>//! `bless` updates the reference files in the repo with changed output files
//! from the last test run.

use std::env;
use std::ffi::OsStr;
use std::fs;
use std::lazy::SyncLazy;
use std::path::{Path, PathBuf};
use walkdir::WalkDir;

use crate::clippy_project_root;

// NOTE: this is duplicated with tests/cargo/mod.rs What to do?
pub static CARGO_TARGET_DIR: SyncLazy<PathBuf> = SyncLazy::new(|| match env::var_os("CARGO_TARGET_DIR") {
    Some(v) => v.into(),
    None => env::current_dir().unwrap().join("target"),
});

static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> = SyncLazy::new(|| {
    let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
    let mut path = PathBuf::from(&**CARGO_TARGET_DIR);
    path.push(profile);
    path.push("cargo-clippy");
    fs::metadata(path).ok()?.modified().ok()
});

/// # Panics
///
/// Panics if the path to a test file is broken
pub fn bless(ignore_timestamp: bool) {
    let test_suite_dirs = [
        clippy_project_root().join("tests").join("ui"),
        clippy_project_root().join("tests").join("ui-internal"),
        clippy_project_root().join("tests").join("ui-toml"),
        clippy_project_root().join("tests").join("ui-cargo"),
    ];
    for test_suite_dir in &test_suite_dirs {
        WalkDir::new(test_suite_dir)
            .into_iter()
            .filter_map(Result::ok)
            .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
            .for_each(|f| {
                let test_name = f.path().strip_prefix(test_suite_dir).unwrap();
                for &ext in &["stdout", "stderr", "fixed"] {
                    let test_name_ext = format!("stage-id.{}", ext);
                    update_reference_file(
                        f.path().with_extension(ext),
                        test_name.with_extension(test_name_ext),
                        ignore_timestamp,
                    );
                }
            });
    }
}

fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf, ignore_timestamp: bool) {
    let test_output_path = build_dir().join(test_name);
    let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();

    // If compiletest did not write any changes during the test run,
    // we don't have to update anything
    if !test_output_path.exists() {
        return;
    }

    // If the test output was not updated since the last clippy build, it may be outdated
    if !ignore_timestamp && !updated_since_clippy_build(&test_output_path).unwrap_or(true) {
        return;
    }

    let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
    let reference_file = fs::read(&reference_file_path).unwrap_or_default();

    if test_output_file != reference_file {
        // If a test run caused an output file to change, update the reference file
        println!("updating {}", &relative_reference_file_path.display());
        fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");

        // We need to re-read the file now because it was potentially updated from copying
        let reference_file = fs::read(&reference_file_path).unwrap_or_default();

        if reference_file.is_empty() {
            // If we copied over an empty output file, we remove the now empty reference file
            println!("removing {}", &relative_reference_file_path.display());
            fs::remove_file(reference_file_path).expect("Could not remove reference file");
        }
    }
}

fn updated_since_clippy_build(path: &Path) -> Option<bool> {
    let clippy_build_time = (*CLIPPY_BUILD_TIME)?;
    let modified = fs::metadata(path).ok()?.modified().ok()?;
    Some(modified >= clippy_build_time)
}

fn build_dir() -> PathBuf {
    let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
    let mut path = PathBuf::new();
    path.push(CARGO_TARGET_DIR.clone());
    path.push(profile);
    path.push("test_build_base");
    path
}
<|endoftext|>