<commit_before><commit_msg>Added an example ini parser<commit_after>//! Parser example for INI files.
extern crate combine;

use std::collections::HashMap;

use combine::*;
use combine::primitives::{Error, SourcePosition, Stream};

#[derive(PartialEq, Debug)]
pub struct Ini {
    pub global: HashMap<String, String>,
    pub sections: HashMap<String, HashMap<String, String>>
}

fn property<I>(input: State<I>) -> ParseResult<(String, String), I>
where I: Stream<Item=char> {
    (
        many1(satisfy(|c| c != '=' && c != '[' && c != ';')),
        token('='),
        many1(satisfy(|c| c != '\n' && c != ';'))
    )
        .map(|(key, _, value)| (key, value))
        .expected("property")
        .parse_state(input)
}

fn whitespace<I>(input: State<I>) -> ParseResult<(), I>
where I: Stream<Item=char> {
    let comment = (token(';'), skip_many(satisfy(|c| c != '\n')))
        .map(|_| ());
    //Wrap the `spaces().or(comment)` in `skip_many` so that it skips alternating whitespace and comments
    skip_many(skip_many1(space()).or(comment))
        .parse_state(input)
}

fn properties<I>(input: State<I>) -> ParseResult<HashMap<String, String>, I>
where I: Stream<Item=char> {
    //After each property we skip any whitespace that followed it
    many(parser(property).skip(parser(whitespace)))
        .parse_state(input)
}

fn section<I>(input: State<I>) -> ParseResult<(String, HashMap<String, String>), I>
where I: Stream<Item=char> {
    (
        between(token('['), token(']'), many(satisfy(|c| c != ']'))),
        parser(whitespace),
        parser(properties)
    )
        .map(|(name, _, properties)| (name, properties))
        .expected("section")
        .parse_state(input)
}

fn ini<I>(input: State<I>) -> ParseResult<Ini, I>
where I: Stream<Item=char> {
    (parser(whitespace), parser(properties), many(parser(section)))
        .map(|(_, global, sections)| Ini { global: global, sections: sections })
        .parse_state(input)
}

#[test]
fn ini_ok() {
    let text = r#"
language=rust

[section]
name=combine; Comment
type=LL(1)

"#;
    let mut expected = Ini {
        global: HashMap::new(),
        sections: HashMap::new()
    };
    expected.global.insert(String::from("language"), String::from("rust"));

    let mut section = HashMap::new();
    section.insert(String::from("name"), String::from("combine"));
    section.insert(String::from("type"), String::from("LL(1)"));
    expected.sections.insert(String::from("section"), section);

    let result = parser(ini)
        .parse(text)
        .map(|t| t.0);
    assert_eq!(result, Ok(expected));
}

#[test]
fn ini_error() {
    let text = "[error";
    let result = parser(ini)
        .parse(text)
        .map(|t| t.0);
    assert_eq!(result, Err(ParseError {
        position: SourcePosition { line: 1, column: 7 },
        errors: vec![
            Error::end_of_input(),
            Error::Expected("section".into()),
        ]
    }));
}
<|endoftext|>


<commit_before><commit_msg>add test for all workspace members<commit_after>extern crate meta;

use std::path::PathBuf;
use std::process::Command;

/// Calls `cargo test` in every workspace member.
///
/// FIXME: This test should be removed once `cargo` has a way to run tests for all crates in a
/// workspace.
#[test]
fn test_all_workspace_members() {
    for task in meta::local::parse_tasks("Cargo.toml") {
        let status = Command::new("cargo")
            .current_dir(PathBuf::from("tasks").join(&task.crate_name()))
            .arg("test")
            .status()
            .unwrap();

        assert!(status.success());
    }
}
<|endoftext|>


<commit_before><commit_msg>add EC2 Simple Systems Manager tests<commit_after>#![cfg(feature = "ssm")]

extern crate rusoto;

use rusoto::ssm::{SsmClient, ListDocumentsRequest, ListCommandsRequest, ListCommandInvocationsRequest};
use rusoto::{DefaultCredentialsProvider, Region};

#[test]
fn should_list_documents() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = SsmClient::new(credentials, Region::UsEast1);

    let request = ListDocumentsRequest::default();

    match client.list_documents(&request) {
        Ok(response) => {
            println!("{:#?}", response);
            assert!(true)
        },
        Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}

#[test]
fn should_list_commands() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = SsmClient::new(credentials, Region::UsEast1);

    let request = ListCommandsRequest::default();

    match client.list_commands(&request) {
        Ok(response) => {
            println!("{:#?}", response);
            assert!(true)
        },
        Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}

#[test]
fn should_list_command_invocations() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = SsmClient::new(credentials, Region::UsEast1);

    let request = ListCommandInvocationsRequest::default();

    match client.list_command_invocations(&request) {
        Ok(response) => {
            println!("{:#?}", response);
            assert!(true)
        },
        Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}<|endoftext|>


<commit_before><commit_msg>Tests: Add code to generate Add docs<commit_after>#![allow(dead_code)]
#[macro_use]
extern crate derive_more;

#[derive(Add)]
struct MyInts(i32, i32);

#[derive(Add)]
struct Point2D {
    x: i32,
    y: i32,
}

#[derive(Add)]
enum MixedInts {
    SmallInt(i32),
    BigInt(i64),
    TwoSmallInts(i32, i32),
    NamedSmallInts { x: i32, y: i32 },
    UnsignedOne(u32),
    UnsignedTwo(u32),
    Unit,
}
<|endoftext|>


<commit_before>use buffer::{Content, Buffer, BufferAny, BufferType, BufferMode, BufferCreationError};
use buffer::{BufferSlice, BufferMutSlice};
use uniforms::{AsUniformValue, UniformBlock, UniformValue, LayoutMismatchError};
use program;

use std::ops::{Deref, DerefMut};

use backend::Facade;

/// Buffer that contains a uniform block.
#[derive(Debug)]
pub struct UniformBuffer<T: ?Sized> where T: Content {
    buffer: Buffer<T>,
}

/// Same as `UniformBuffer` but doesn't contain any information about the type.
#[derive(Debug)]
pub struct TypelessUniformBuffer {
    buffer: BufferAny,
}

impl<T> UniformBuffer<T> where T: Copy {
    /// Uploads data in the uniforms buffer.
    #[inline]
    pub fn new<F>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
                  where F: Facade
    {
        UniformBuffer::new_impl(facade, data, BufferMode::Default)
    }

    /// Uploads data in the uniforms buffer.
    #[inline]
    pub fn dynamic<F>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
                      where F: Facade
    {
        UniformBuffer::new_impl(facade, data, BufferMode::Dynamic)
    }

    /// Uploads data in the uniforms buffer.
    #[inline]
    pub fn persistent<F>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
                  where F: Facade
    {
        UniformBuffer::new_impl(facade, data, BufferMode::Persistent)
    }

    /// Uploads data in the uniforms buffer.
    #[inline]
    pub fn immutable<F>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
                        where F: Facade
    {
        UniformBuffer::new_impl(facade, data, BufferMode::Immutable)
    }

    #[inline]
    fn new_impl<F>(facade: &F, data: T, mode: BufferMode)
                   -> Result<UniformBuffer<T>, BufferCreationError>
                   where F: Facade
    {
        let buffer = try!(Buffer::new(facade, &data, BufferType::UniformBuffer, mode));

        Ok(UniformBuffer {
            buffer: buffer,
        })
    }

    /// Creates an empty buffer.
    #[inline]
    pub fn empty<F>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError> where F: Facade {
        UniformBuffer::empty_impl(facade, BufferMode::Default)
    }

    /// Creates an empty buffer.
    #[inline]
    pub fn empty_dynamic<F>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
                            where F: Facade
    {
        UniformBuffer::empty_impl(facade, BufferMode::Dynamic)
    }

    /// Creates an empty buffer.
    #[inline]
    pub fn empty_persistent<F>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
                               where F: Facade
    {
        UniformBuffer::empty_impl(facade, BufferMode::Persistent)
    }

    /// Creates an empty buffer.
    #[inline]
    pub fn empty_immutable<F>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
                              where F: Facade
    {
        UniformBuffer::empty_impl(facade, BufferMode::Immutable)
    }

    #[inline]
    fn empty_impl<F>(facade: &F, mode: BufferMode) -> Result<UniformBuffer<T>, BufferCreationError>
                     where F: Facade
    {
        let buffer = try!(Buffer::empty(facade, BufferType::UniformBuffer, mode));

        Ok(UniformBuffer {
            buffer: buffer,
        })
    }
}

impl<T: ?Sized> UniformBuffer<T> where T: Content {
    /// Creates an empty buffer.
    ///
    /// # Panic
    ///
    /// Panicks if the size passed as parameter is not suitable for the type of data.
    ///
    #[inline]
    pub fn empty_unsized<F>(facade: &F, size: usize)
                            -> Result<UniformBuffer<T>, BufferCreationError>
                            where F: Facade
    {
        UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Default)
    }

    /// Creates an empty buffer.
    ///
    /// # Panic
    ///
    /// Panicks if the size passed as parameter is not suitable for the type of data.
    ///
    #[inline]
    pub fn empty_unsized_dynamic<F>(facade: &F, size: usize)
                                    -> Result<UniformBuffer<T>, BufferCreationError>
                                    where F: Facade
    {
        UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Dynamic)
    }

    /// Creates an empty buffer.
    ///
    /// # Panic
    ///
    /// Panicks if the size passed as parameter is not suitable for the type of data.
    ///
    #[inline]
    pub fn empty_unsized_persistent<F>(facade: &F, size: usize)
                                       -> Result<UniformBuffer<T>, BufferCreationError>
                                       where F: Facade
    {
        UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Persistent)
    }

    /// Creates an empty buffer.
    ///
    /// # Panic
    ///
    /// Panicks if the size passed as parameter is not suitable for the type of data.
    ///
    #[inline]
    pub fn empty_unsized_immutable<F>(facade: &F, size: usize)
                                      -> Result<UniformBuffer<T>, BufferCreationError>
                                      where F: Facade
    {
        UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Immutable)
    }

    #[inline]
    fn empty_unsized_impl<F>(facade: &F, size: usize, mode: BufferMode)
                             -> Result<UniformBuffer<T>, BufferCreationError>
                             where F: Facade
    {
        let buffer = try!(Buffer::empty_unsized(facade, BufferType::UniformBuffer, size, mode));

        Ok(UniformBuffer {
            buffer: buffer,
        })
    }
}

impl<T: ?Sized> Deref for UniformBuffer<T> where T: Content {
    type Target = Buffer<T>;

    #[inline]
    fn deref(&self) -> &Buffer<T> {
        &self.buffer
    }
}

impl<T: ?Sized> DerefMut for UniformBuffer<T> where T: Content {
    #[inline]
    fn deref_mut(&mut self) -> &mut Buffer<T> {
        &mut self.buffer
    }
}

impl<'a, T: ?Sized> From<&'a UniformBuffer<T>> for BufferSlice<'a, T> where T: Content {
    #[inline]
    fn from(b: &'a UniformBuffer<T>) -> BufferSlice<'a, T> {
        b.buffer.as_slice()
    }
}

impl<'a, T: ?Sized> From<&'a mut UniformBuffer<T>> for BufferMutSlice<'a, T> where T: Content {
    #[inline]
    fn from(b: &'a mut UniformBuffer<T>) -> BufferMutSlice<'a, T> {
        b.buffer.as_mut_slice()
    }
}

impl<'a, T: ?Sized> AsUniformValue for &'a UniformBuffer<T> where T: UniformBlock + Content {
    #[inline]
    fn as_uniform_value(&self) -> UniformValue {
        #[inline]
        fn f<T: ?Sized>(block: &program::UniformBlock)
                        -> Result<(), LayoutMismatchError> where T: UniformBlock + Content
        {
            // TODO: more checks?
            T::matches(&block.layout, 0)
        }

        UniformValue::Block(self.buffer.as_slice_any(), f::<T>)
    }
}
<commit_msg>forgotten uniform::Buffer GLObject Trait implementation<commit_after>use buffer::{Content, Buffer, BufferAny, BufferType, BufferMode, BufferCreationError};
use buffer::{BufferSlice, BufferMutSlice};
use uniforms::{AsUniformValue, UniformBlock, UniformValue, LayoutMismatchError};
use program;

use gl;
use GlObject;

use std::ops::{Deref, DerefMut};

use backend::Facade;

/// Buffer that contains a uniform block.
#[derive(Debug)]
pub struct UniformBuffer<T: ?Sized> where T: Content {
    buffer: Buffer<T>,
}

/// Same as `UniformBuffer` but doesn't contain any information about the type.
#[derive(Debug)]
pub struct TypelessUniformBuffer {
    buffer: BufferAny,
}

impl<T: Copy> GlObject for UniformBuffer<T> {
    type Id = gl::types::GLuint;

    #[inline]
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

impl<T> UniformBuffer<T> where T: Copy {
    /// Uploads data in the uniforms buffer.
    #[inline]
    pub fn new<F>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
                  where F: Facade
    {
        UniformBuffer::new_impl(facade, data, BufferMode::Default)
    }

    /// Uploads data in the uniforms buffer.
    #[inline]
    pub fn dynamic<F>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
                      where F: Facade
    {
        UniformBuffer::new_impl(facade, data, BufferMode::Dynamic)
    }

    /// Uploads data in the uniforms buffer.
    #[inline]
    pub fn persistent<F>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
                  where F: Facade
    {
        UniformBuffer::new_impl(facade, data, BufferMode::Persistent)
    }

    /// Uploads data in the uniforms buffer.
    #[inline]
    pub fn immutable<F>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
                        where F: Facade
    {
        UniformBuffer::new_impl(facade, data, BufferMode::Immutable)
    }

    #[inline]
    fn new_impl<F>(facade: &F, data: T, mode: BufferMode)
                   -> Result<UniformBuffer<T>, BufferCreationError>
                   where F: Facade
    {
        let buffer = try!(Buffer::new(facade, &data, BufferType::UniformBuffer, mode));

        Ok(UniformBuffer {
            buffer: buffer,
        })
    }

    /// Creates an empty buffer.
    #[inline]
    pub fn empty<F>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError> where F: Facade {
        UniformBuffer::empty_impl(facade, BufferMode::Default)
    }

    /// Creates an empty buffer.
    #[inline]
    pub fn empty_dynamic<F>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
                            where F: Facade
    {
        UniformBuffer::empty_impl(facade, BufferMode::Dynamic)
    }

    /// Creates an empty buffer.
    #[inline]
    pub fn empty_persistent<F>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
                               where F: Facade
    {
        UniformBuffer::empty_impl(facade, BufferMode::Persistent)
    }

    /// Creates an empty buffer.
    #[inline]
    pub fn empty_immutable<F>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
                              where F: Facade
    {
        UniformBuffer::empty_impl(facade, BufferMode::Immutable)
    }

    #[inline]
    fn empty_impl<F>(facade: &F, mode: BufferMode) -> Result<UniformBuffer<T>, BufferCreationError>
                     where F: Facade
    {
        let buffer = try!(Buffer::empty(facade, BufferType::UniformBuffer, mode));

        Ok(UniformBuffer {
            buffer: buffer,
        })
    }
}

impl<T: ?Sized> UniformBuffer<T> where T: Content {
    /// Creates an empty buffer.
    ///
    /// # Panic
    ///
    /// Panicks if the size passed as parameter is not suitable for the type of data.
    ///
    #[inline]
    pub fn empty_unsized<F>(facade: &F, size: usize)
                            -> Result<UniformBuffer<T>, BufferCreationError>
                            where F: Facade
    {
        UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Default)
    }

    /// Creates an empty buffer.
    ///
    /// # Panic
    ///
    /// Panicks if the size passed as parameter is not suitable for the type of data.
    ///
    #[inline]
    pub fn empty_unsized_dynamic<F>(facade: &F, size: usize)
                                    -> Result<UniformBuffer<T>, BufferCreationError>
                                    where F: Facade
    {
        UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Dynamic)
    }

    /// Creates an empty buffer.
    ///
    /// # Panic
    ///
    /// Panicks if the size passed as parameter is not suitable for the type of data.
    ///
    #[inline]
    pub fn empty_unsized_persistent<F>(facade: &F, size: usize)
                                       -> Result<UniformBuffer<T>, BufferCreationError>
                                       where F: Facade
    {
        UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Persistent)
    }

    /// Creates an empty buffer.
    ///
    /// # Panic
    ///
    /// Panicks if the size passed as parameter is not suitable for the type of data.
    ///
    #[inline]
    pub fn empty_unsized_immutable<F>(facade: &F, size: usize)
                                      -> Result<UniformBuffer<T>, BufferCreationError>
                                      where F: Facade
    {
        UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Immutable)
    }

    #[inline]
    fn empty_unsized_impl<F>(facade: &F, size: usize, mode: BufferMode)
                             -> Result<UniformBuffer<T>, BufferCreationError>
                             where F: Facade
    {
        let buffer = try!(Buffer::empty_unsized(facade, BufferType::UniformBuffer, size, mode));

        Ok(UniformBuffer {
            buffer: buffer,
        })
    }
}

impl<T: ?Sized> Deref for UniformBuffer<T> where T: Content {
    type Target = Buffer<T>;

    #[inline]
    fn deref(&self) -> &Buffer<T> {
        &self.buffer
    }
}

impl<T: ?Sized> DerefMut for UniformBuffer<T> where T: Content {
    #[inline]
    fn deref_mut(&mut self) -> &mut Buffer<T> {
        &mut self.buffer
    }
}

impl<'a, T: ?Sized> From<&'a UniformBuffer<T>> for BufferSlice<'a, T> where T: Content {
    #[inline]
    fn from(b: &'a UniformBuffer<T>) -> BufferSlice<'a, T> {
        b.buffer.as_slice()
    }
}

impl<'a, T: ?Sized> From<&'a mut UniformBuffer<T>> for BufferMutSlice<'a, T> where T: Content {
    #[inline]
    fn from(b: &'a mut UniformBuffer<T>) -> BufferMutSlice<'a, T> {
        b.buffer.as_mut_slice()
    }
}

impl<'a, T: ?Sized> AsUniformValue for &'a UniformBuffer<T> where T: UniformBlock + Content {
    #[inline]
    fn as_uniform_value(&self) -> UniformValue {
        #[inline]
        fn f<T: ?Sized>(block: &program::UniformBlock)
                        -> Result<(), LayoutMismatchError> where T: UniformBlock + Content
        {
            // TODO: more checks?
            T::matches(&block.layout, 0)
        }

        UniformValue::Block(self.buffer.as_slice_any(), f::<T>)
    }
}
<|endoftext|>


<commit_before><commit_msg>prepare outline of helper function<commit_after><|endoftext|>


<commit_before><commit_msg>Add empty parser module<commit_after><|endoftext|>


<commit_before><commit_msg>initial commit<commit_after>#![recursion_limit="5000"]
//#![feature(trace_macros)] trace_macros!(true);

macro_rules! bf {
    // these rules handle the end of the instruction stream -- either the real end of the program,
    // or the end of a loop body

    // no loop stack and no tail stack => goodbye
    (@run () [$cur_:tt $left_:tt $right_:tt] [] [] [] $out_:tt $_in:tt) => {
        bf!(@out $cur_ [] $left_ $right_ $out_)
    };
    // counter is zero, pop the loop stack to exit the loop
    (@run () [() $left_:tt $right_:tt] [] [$loops_head:tt $($loops_tail:tt)*] [[$head:tt $($tail:tt)*] $($tails_:tt)*] $out_:tt $in_:tt) => {
        bf!(@run $head [() $left_ $right_] [$($tail)*] [$($loops_tail)*] [$($tails_)*] $out_ $in_)
    };
    // counter is nonzero, restart the loop
    (@run () $state_:tt [] [[$head:tt $($tail:tt)*] $($loops:tt)*] $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head $state_ [$($tail)*] [[$head $($tail)*] $($loops)*] $tails_ $out_ $in_)
    };

    // the next few rules deal with multi-character tokens which are parsed together, but we want
    // the individual tokens, so just split them up and push the pieces back onto the program

    // >> is actually > >
    (@run >> $state_:tt [$($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run > $state_ [> $($tail)*] $loops_ $tails_ $out_ $in_)
    };
    // << is actually < <
    (@run << $state_:tt [$($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run < $state_ [< $($tail)*] $loops_ $tails_ $out_ $in_)
    };
    // .. is actually . .
    (@run .. $state_:tt [$($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run . $state_ [. $($tail)*] $loops_ $tails_ $out_ $in_)
    };
    // ... is actually . . .
    (@run ... $state_:tt [$($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run . $state_ [. . $($tail)*] $loops_ $tails_ $out_ $in_)
    };
    // <- is actually < -
    (@run <- $state_:tt [$($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run < $state_ [- $($tail)*] $loops_ $tails_ $out_ $in_)
    };
    // -> is actually - >
    (@run -> $state_:tt [$($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $out_:tt) => {
        bf!(@run - $state_ [> $($tail)*] $loops_ $tails_ $out_ $in_)
    };

    // now the instructions themselves!

    // add one to the current cell: $cur => ($cur)
    (@run + [$cur:tt $left_:tt $right_:tt] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head [($cur) $left_ $right_] [$($tail)*] $loops_ $tails_ $out_ $in_)
    };

    // subtract one from the current cell: ($cur) => (), () => () (that is, underflow is a no-op)
    (@run - [() $left_:tt $right_:tt] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {{
        bf!(@run $head [() $left_ $right_] [$($tail)*] $loops_ $tails_ $out_ $in_)
    }};
    (@run - [($cur:tt) $left_:tt $right_:tt] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head [$cur $left_ $right_] [$($tail)*] $loops_ $tails_ $out_ $in_)
    };

    // move the cell pointer to the right
    // the memory expands if necessary (new cell initialized to zero)
    (@run > [$cur:tt [$($lmore:tt)*] [$right:tt $($rmore:tt)*]] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head [$right [$cur $($lmore)*] [$($rmore)*]] [$($tail)*] $loops_ $tails_ $out_ $in_)
    };
    (@run > [$cur:tt [$($lmore:tt)*] []] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head [() [$cur $($lmore)*] []] [$($tail)*] $loops_ $tails_ $out_ $in_)
    };

    // move the cell pointer to the left
    // the memory expands if necessary (new cell initialized to zero)
    (@run < [$cur:tt [$left:tt $($lmore:tt)*] [$($rmore:tt)*]] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head [$left [$($lmore)*] [$cur $($rmore)*]] [$($tail)*] $loops_ $tails_ $out_ $in_)
    };
    (@run < [$cur:tt [] [$($rmore:tt)*]] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head [() [] [$cur $($rmore)*]] [$($tail)*] $loops_ $tails_ $out_ $in_)
    };

    // loops!

    // counter is zero, skip the loop
    (@run [$inner_head:tt $($inner_tail:tt)*] [() $left_:tt $right_:tt] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head [() $left_ $right_] [$($tail)*] $loops_ $tails_ $out_ $in_)
    };
    // counter is nonzero, push the current tail + loop and enter the loop
    (@run [$inner_head:tt $($inner_tail:tt)*] $state_:tt $tail_:tt [$($loops:tt)*] [$($tails:tt)*] $out_:tt $in_:tt) => {
        bf!(@run $inner_head $state_ [$($inner_tail)* ()] [[$inner_head $($inner_tail)* ()] $($loops)*] [$tail_ $($tails)*] $out_ $in_)
    };

    // output the current cell: just push $cur onto $out
    //  note: the Rust "program" will crash at runtime if the BF program outputs invalid UTF-8
    (@run . [$cur:tt $left_:tt $right_:tt] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt [$($out:tt)*] $in_:tt) => {
        bf!(@run $head [$cur $left_ $right_] [$($tail)*] $loops_ $tails_ [$($out)* $cur] $in_)
    };

    // input to the current cell: do nothing on EOF, otherwise pop $in and parse it
    (@run , [$cur:tt $left_:tt $right_:tt] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt []) => {
        bf!(@run $head [$cur $left_ $right_] [$($tail)*] $loops_ $tails_ $out_ [])
    };
    (@run , [$cur:tt $left_:tt $right_:tt] [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt [$in_head:tt $($in_tail:tt)*]) => {
        bf!(@in @revconv $in_head [] [[$head $left_ $right_] [[$($tail)*] $loops_ $tails_ $out_ [$($in_tail)*]]])
    };

    (@in @revconv [] [$($digit:tt)*] $stuff:tt) => { bf!(@in @unary [] [] [()] [$($digit)*] $stuff) };
    (@in @revconv [0 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [() $($digit)*] $stuff) };
    (@in @revconv [1 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [(()) $($digit)*] $stuff) };
    (@in @revconv [2 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [((())) $($digit)*] $stuff) };
    (@in @revconv [3 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [(((()))) $($digit)*] $stuff) };
    (@in @revconv [4 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [((((())))) $($digit)*] $stuff) };
    (@in @revconv [5 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [(((((()))))) $($digit)*] $stuff) };
    (@in @revconv [6 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [((((((())))))) $($digit)*] $stuff) };
    (@in @revconv [7 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [(((((((()))))))) $($digit)*] $stuff) };
    (@in @revconv [8 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [((((((((())))))))) $($digit)*] $stuff) };
    (@in @revconv [9 $($tail:tt)*] [$($digit:tt)*] $stuff:tt) => { bf!(@in @revconv [$($tail)*] [(((((((((()))))))))) $($digit)*] $stuff) };
    (@in @unary $fullacc:tt $digitacc:tt $pv:tt [] $stuff:tt) => { bf!(@in @zem () $fullacc $stuff) };
    (@in @unary        [$($fullacc:tt)*]            [$($digitacc:tt)*] [$($pv:tt)*]                              [() $($digits:tt)*] $stuff:tt) => {
        bf!(@in @unary [$($fullacc)* $($digitacc)*] []                 [$($pv)* $($pv)* $($pv)* $($pv)* $($pv)*
                                                                        $($pv)* $($pv)* $($pv)* $($pv)* $($pv)*] [$($digits)*]       $stuff)
    };
    (@in @unary        $fullacc:tt [$($digitacc:tt)*]      [$($pv:tt)*] [($digit:tt) $($digits:tt)*] $stuff:tt) => {
        bf!(@in @unary $fullacc    [$($digitacc)* $($pv)*] [$($pv)*]    [$digit      $($digits)*]    $stuff)
    };
    (@in @zem $acc:tt []                      [[$head:tt $left:tt $right:tt] [$($other_stuff:tt)*]]) => { bf!(@run $head [$acc $left $right] $($other_stuff)*) };
    (@in @zem $acc:tt [$head:tt $($tail:tt)*] $stuff:tt)                                             => { bf!(@in @zem ($acc) [$($tail)*] $stuff) };

    // invalid instruction is a no-op
    (@run $_instr:tt $state_:tt [$head:tt $($tail:tt)*] $loops_:tt $tails_:tt $out_:tt $in_:tt) => {
        bf!(@run $head $state_ [$($tail)*] $loops_ $tails_ $out_ $in_)
    };

    // the program is over! we now output the memory state and the output to Rust
    // first we need to unzip the memory, which involves reversing the left-hand side

    // the reversal is finished: convert each memory cell and output character to arithmetic and
    // output them into arrays
    (@out $cur:tt [$($left:tt)*] [] [$($right:tt)*] [$($out:tt)*]) => {
        (&[$(bf!(@count $left),)* bf!(@count $cur), $(bf!(@count $right),)*], &[$(bf!(@count $out),)*])
    };
    // reverse the left-hand side of the memory zipper for output
    (@out $cur_:tt [$($left_:tt)*] [$left_head:tt $($left_tail:tt)*] $right_:tt $out_:tt) => {
        bf!(@out $cur_ [$left_head $($left_)*] [$($left_tail)*] $right_ $out_)
    };

    // recursively convert a Zermelo numeral to an arithmetic expression
    //  note: only the first and last line should be necessary, but the compiler has a stack
    //  overflow on a too-long chain of additions, so we do a little unrolling
    (@count ()) => { 0u8 };
    (@count ((($inner:tt)))) => { 3u8 + bf!(@count $inner) };
    (@count (($inner:tt))) => { 2u8 + bf!(@count $inner) };
    (@count ($inner:tt)) => { 1u8 + bf!(@count $inner) };

    // entry point: given a sequence of instructions, launch the machine
    ({$head:tt $($tail:tt)*} {$($input:tt)*}) => { bf!(@run $head [() [] []] [$($tail)* ()] [] [] [] [$($input)*]) }
    //                                                      |     |           |         |   |  |  |  ^ input
    //                                                      |     |           |         |   |  |  ^ output
    //                                                      |     |           |         |   |  ^ tail stack
    //                                                      |     |           |         |   ^ loop stack
    //                                                      |     |           |         ^ sentinel added to mark the end of the program
    //                                                      |     |           ^ remainder of program
    //                                                      |     ^ memory zipper [cur [left cells, adjacent first] [right cells, adjacent first]]
    //                                                      ^ current instruction
}

// the BF program is interpreted by the macro system at compile time and turned into a constant
// arithmetic expression (see expanded.rs)
// MACHINE is a tuple where MACHINE.0 is the memory state and MACHINE.1 is the output
const MACHINE: (&'static [u8], &'static [u8]) =
    bf!({ ,[+.[-],] } { [6 4] [6 5] [6 6] [6 7] [6 8] [6 9] });
    //bf!({ ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. } {});
    //bf!({ + } { });

fn main() {
    // all we do at runtime is print the memory state and the output (converted to UTF-8)
    println!("memory={:?}", MACHINE.0);
    println!("output:");
    println!("{}", std::str::from_utf8(MACHINE.1).unwrap());
}
<|endoftext|>


<commit_before><commit_msg>Fix: Do only check entries which are a ref<commit_after><|endoftext|>


<commit_before>extern mod extra;
extern mod glfw;
extern mod gl;
extern mod cgmath;
extern mod noise;

use std::cast;
use std::ptr;
use std::hashmap::HashMap;
use std;

use gl::types::*;

use cgmath::vector::Vector;
use cgmath::vector::Vec3;
use cgmath::vector::Vec4;

use noise::Perlin;

use CHUNK_SIZE;
use WORLD_SIZE;
use GraphicsResources;

static MAX_CHUNKS : uint = 32;

pub struct ChunkLoader<'a> {
    seed : u32,
    graphics_resources : &'a GraphicsResources,
    cache : HashMap<(i64, i64), ~Chunk>
}

impl<'a> ChunkLoader<'a> {
    pub fn new<'a>(seed : u32, graphics_resources : &'a GraphicsResources) -> ChunkLoader<'a> {
        ChunkLoader {
            seed: seed,
            graphics_resources : graphics_resources,
            cache: HashMap::new(),
        }
    }

    pub fn load(&mut self, cx : i64, cz: i64) {
        println!("loading chunk ({}, {})", cx, cz);
        let chunk = chunk_gen(self.graphics_resources, self.seed, cx, cz);
        self.cache.insert((cx, cz), chunk);

        while self.cache.len() > MAX_CHUNKS {
            let (&k, _) = self.cache.iter().min_by(|&(_, chunk)| chunk.used_time).unwrap();
            self.cache.remove(&k);
        }
    }
}

pub struct Chunk {
    x: i64,
    z: i64,
    map: ~Map,
    vao: GLuint,
    vertex_buffer: GLuint,
    normal_buffer: GLuint,
    element_buffer: GLuint,
    num_elements: uint,
    used_time: u64,
}

impl Chunk {
    pub fn touch(&mut self) {
        self.used_time = extra::time::precise_time_ns();
    }
}

impl Drop for Chunk {
    fn drop(&mut self) {
        unsafe {
            println!("unloading chunk ({}, {})", self.x, self.z);
            gl::DeleteBuffers(1, &self.vertex_buffer);
            gl::DeleteBuffers(1, &self.normal_buffer);
            gl::DeleteBuffers(1, &self.element_buffer);
            gl::DeleteVertexArrays(1, &self.vao);
        }
    }
}

struct Block {
    visible: bool,
}

struct Map {
    blocks: [[[Block, ..CHUNK_SIZE], ..CHUNK_SIZE], ..CHUNK_SIZE],
}

struct Face {
    normal: Vec3<f32>,
    vertices: [Vec3<f32>, ..4],
}

#[inline]
fn fast_add_vec3f(a: Vec3<f32>, b: Vec3<f32>) -> Vec3<f32> {
    Vec3{x: a.x + b.x, y: a.y + b.y, z: a.z + b.z }
}

pub fn chunk_gen(res: &GraphicsResources, seed: u32, chunk_x: i64, chunk_z: i64) -> ~Chunk {
    let def_block = Block { visible: false };
    let mut map = ~Map {
        blocks: [[[def_block, ..CHUNK_SIZE], ..CHUNK_SIZE], ..CHUNK_SIZE],
    };

    let block_exists = |x: int, y: int, z: int| -> bool {
        if x < 0 || x >= CHUNK_SIZE as int || y < 0 || y >= CHUNK_SIZE as int || z < 0 || z >= CHUNK_SIZE as int {
            return false;
        }

        map.blocks[x][y][z].visible
    };

    let start_time = extra::time::precise_time_ns();

    let perlin = Perlin::from_seed([seed as uint]);

    for block_x in range(0, CHUNK_SIZE) {
        for block_z in range(0, CHUNK_SIZE) {
            let noise = perlin.gen([
                (chunk_x + block_x as i64) as f64 * 0.1,
                (chunk_z + block_z as i64) as f64 * 0.1
            ]);
            let height = ((noise + 1.0) * (CHUNK_SIZE as f64 / 8.0)) as uint;
            for y in range(0, height) {
                map.blocks[block_x][y][block_z] = Block { visible: true };
            }
        }
    }

    let after_noise_time = extra::time::precise_time_ns();

    let mut vertices : ~[Vec3<f32>] = ~[];
    let mut normals : ~[Vec3<f32>] = ~[];
    let mut elements : ~[GLuint] = ~[];

    let mut idx = 0;

    for x in range(0, CHUNK_SIZE) {
        for y in range(0, CHUNK_SIZE) {
            for z in range(0, CHUNK_SIZE) {
                let block = &map.blocks[x][y][z];

                if (!block.visible) {
                    continue;
                }

                let block_position = Vec3 { x: x as f32, y: y as f32, z: z as f32 };

                for face in faces.iter() {
                    let neighbor_position = fast_add_vec3f(block_position, face.normal);
                    if block_exists(neighbor_position.x as int, neighbor_position.y as int, neighbor_position.z as int) {
                        continue;
                    }

                    for &v in face.vertices.iter() {
                        vertices.push(fast_add_vec3f(v, block_position));
                        normals.push(face.normal);
                    }

                    for e in face_elements.iter() {
                        elements.push((idx * face.vertices.len()) as GLuint + *e);
                    }

                    idx += 1;
                }
            }
        }
    }

    let after_mesh_time = extra::time::precise_time_ns();

    let mut vao = 0;
    let mut vertex_buffer = 0;
    let mut normal_buffer = 0;
    let mut element_buffer = 0;

    unsafe {
        // Create Vertex Array Object
        gl::GenVertexArrays(1, &mut vao);
        gl::BindVertexArray(vao);

        // Create a Vertex Buffer Object and copy the vertex data to it
        gl::GenBuffers(1, &mut vertex_buffer);
        gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer);
        gl::BufferData(gl::ARRAY_BUFFER,
                        (vertices.len() * std::mem::size_of::<Vec3<f32>>()) as GLsizeiptr,
                        cast::transmute(&vertices[0]),
                        gl::STATIC_DRAW);

        // Create a Vertex Buffer Object and copy the normal data to it
        gl::GenBuffers(1, &mut normal_buffer);
        gl::BindBuffer(gl::ARRAY_BUFFER, normal_buffer);
        gl::BufferData(gl::ARRAY_BUFFER,
                        (normals.len() * std::mem::size_of::<Vec3<f32>>()) as GLsizeiptr,
                        cast::transmute(&normals[0]),
                        gl::STATIC_DRAW);

        // Create a Vertex Buffer Object and copy the element data to it
        gl::GenBuffers(1, &mut element_buffer);
        gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, element_buffer);
        gl::BufferData(gl::ELEMENT_ARRAY_BUFFER,
                        (elements.len() * std::mem::size_of::<GLuint>()) as GLsizeiptr,
                        cast::transmute(&elements[0]),
                        gl::STATIC_DRAW);

        // Specify the layout of the vertex data
        let vert_attr = "position".with_c_str(|ptr| gl::GetAttribLocation(res.program, ptr));
        assert!(vert_attr as u32 != gl::INVALID_VALUE);
        gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer);
        gl::EnableVertexAttribArray(vert_attr as GLuint);
        gl::VertexAttribPointer(vert_attr as GLuint, 3, gl::FLOAT,
                                gl::FALSE as GLboolean, 0, ptr::null());

        let normal_attr = "normal".with_c_str(|ptr| gl::GetAttribLocation(res.program, ptr));
        assert!(normal_attr as u32 != gl::INVALID_VALUE);
        gl::BindBuffer(gl::ARRAY_BUFFER, normal_buffer);
        gl::EnableVertexAttribArray(normal_attr as GLuint);
        gl::VertexAttribPointer(normal_attr as GLuint, 3, gl::FLOAT,
                                gl::FALSE as GLboolean, 0, ptr::null());
    }

    gl::BindVertexArray(0);

    let after_buffer_time = extra::time::precise_time_ns();

    println!("chunk loading profile (us): noise={} mesh={} buffer={}",
             (after_noise_time - start_time)/1000,
             (after_mesh_time - after_noise_time)/1000,
             (after_buffer_time - after_mesh_time)/1000)

    return ~Chunk {
        x: chunk_x,
        z: chunk_z,
        map: map,
        vao: vao,
        vertex_buffer: vertex_buffer,
        normal_buffer: normal_buffer,
        element_buffer: element_buffer,
        num_elements: elements.len(),
        used_time: extra::time::precise_time_ns(),
    };
}

static face_elements : [GLuint, ..6] = [
    0, 1, 2, 3, 2, 1,
];

static faces : [Face, ..6] = [
    /* front */
    Face {
        normal: Vec3 { x: 0.0, y: 0.0, z: 1.0 },
        vertices: [
            Vec3 { x: 0.0, y: 0.0, z: 1.0 }, /* bottom left */
            Vec3 { x: 1.0, y: 0.0, z: 1.0 },  /* bottom right */
            Vec3 { x: 0.0, y: 1.0, z: 1.0 }, /* top left */
            Vec3 { x: 1.0, y: 1.0, z: 1.0 },  /* top right */
        ],
    },

    /* back */
    Face {
        normal: Vec3 { x: 0.0, y: 0.0, z: -1.0 },
        vertices: [
            Vec3 { x: 1.0, y: 0.0, z: 0.0 }, /* bottom right */
            Vec3 { x: 0.0, y: 0.0, z: 0.0 },  /* bottom left */
            Vec3 { x: 1.0, y: 1.0, z: 0.0 }, /* top right */
            Vec3 { x: 0.0, y: 1.0, z: 0.0 },  /* top left */
        ],
    },

    /* right */
    Face {
        normal: Vec3 { x: 1.0, y: 0.0, z: 0.0 },
        vertices: [
            Vec3 { x: 1.0, y: 0.0, z: 1.0 }, /* bottom front */
            Vec3 { x: 1.0, y: 0.0, z: 0.0 }, /* bottom back */
            Vec3 { x: 1.0, y: 1.0, z: 1.0 }, /* top front */
            Vec3 { x: 1.0, y: 1.0, z: 0.0 }, /* top back */
        ],
    },

    /* left */
    Face {
        normal: Vec3 { x: -1.0, y: 0.0, z: 0.0 },
        vertices: [
            Vec3 { x: 0.0, y: 0.0, z: 0.0 }, /* bottom back */
            Vec3 { x: 0.0, y: 0.0, z: 1.0 }, /* bottom front */
            Vec3 { x: 0.0, y: 1.0, z: 0.0 }, /* top back */
            Vec3 { x: 0.0, y: 1.0, z: 1.0 }, /* top front */
        ],
    },

    /* top */
    Face {
        normal: Vec3 { x: 0.0, y: 1.0, z: 0.0 },
        vertices: [
            Vec3 { x: 0.0, y: 1.0, z: 1.0 }, /* front left */
            Vec3 { x: 1.0, y: 1.0, z: 1.0 }, /* front right */
            Vec3 { x: 0.0, y: 1.0, z: 0.0 }, /* back left */
            Vec3 { x: 1.0, y: 1.0, z: 0.0 }, /* back right */
        ],
    },

    /* bottom */
    Face {
        normal: Vec3 { x: 0.0, y: -1.0, z: 0.0 },
        vertices: [
            Vec3 { x: 0.0, y: 0.0, z: 0.0 }, /* back left */
            Vec3 { x: 1.0, y: 0.0, z: 0.0 }, /* back right */
            Vec3 { x: 0.0, y: 0.0, z: 1.0 }, /* front left */
            Vec3 { x: 1.0, y: 0.0, z: 1.0 }, /* front right */
        ],
    },
];
<commit_msg>Revert "hack to optimize meshing"<commit_after>extern mod extra;
extern mod glfw;
extern mod gl;
extern mod cgmath;
extern mod noise;

use std::cast;
use std::ptr;
use std::hashmap::HashMap;
use std;

use gl::types::*;

use cgmath::vector::Vector;
use cgmath::vector::Vec3;
use cgmath::vector::Vec4;

use noise::Perlin;

use CHUNK_SIZE;
use WORLD_SIZE;
use GraphicsResources;

static MAX_CHUNKS : uint = 32;

pub struct ChunkLoader<'a> {
    seed : u32,
    graphics_resources : &'a GraphicsResources,
    cache : HashMap<(i64, i64), ~Chunk>
}

impl<'a> ChunkLoader<'a> {
    pub fn new<'a>(seed : u32, graphics_resources : &'a GraphicsResources) -> ChunkLoader<'a> {
        ChunkLoader {
            seed: seed,
            graphics_resources : graphics_resources,
            cache: HashMap::new(),
        }
    }

    pub fn load(&mut self, cx : i64, cz: i64) {
        println!("loading chunk ({}, {})", cx, cz);
        let chunk = chunk_gen(self.graphics_resources, self.seed, cx, cz);
        self.cache.insert((cx, cz), chunk);

        while self.cache.len() > MAX_CHUNKS {
            let (&k, _) = self.cache.iter().min_by(|&(_, chunk)| chunk.used_time).unwrap();
            self.cache.remove(&k);
        }
    }
}

pub struct Chunk {
    x: i64,
    z: i64,
    map: ~Map,
    vao: GLuint,
    vertex_buffer: GLuint,
    normal_buffer: GLuint,
    element_buffer: GLuint,
    num_elements: uint,
    used_time: u64,
}

impl Chunk {
    pub fn touch(&mut self) {
        self.used_time = extra::time::precise_time_ns();
    }
}

impl Drop for Chunk {
    fn drop(&mut self) {
        unsafe {
            println!("unloading chunk ({}, {})", self.x, self.z);
            gl::DeleteBuffers(1, &self.vertex_buffer);
            gl::DeleteBuffers(1, &self.normal_buffer);
            gl::DeleteBuffers(1, &self.element_buffer);
            gl::DeleteVertexArrays(1, &self.vao);
        }
    }
}

struct Block {
    visible: bool,
}

struct Map {
    blocks: [[[Block, ..CHUNK_SIZE], ..CHUNK_SIZE], ..CHUNK_SIZE],
}

struct Face {
    normal: Vec3<f32>,
    vertices: [Vec3<f32>, ..4],
}

pub fn chunk_gen(res: &GraphicsResources, seed: u32, chunk_x: i64, chunk_z: i64) -> ~Chunk {
    let def_block = Block { visible: false };
    let mut map = ~Map {
        blocks: [[[def_block, ..CHUNK_SIZE], ..CHUNK_SIZE], ..CHUNK_SIZE],
    };

    let block_exists = |x: int, y: int, z: int| -> bool {
        if x < 0 || x >= CHUNK_SIZE as int || y < 0 || y >= CHUNK_SIZE as int || z < 0 || z >= CHUNK_SIZE as int {
            return false;
        }

        map.blocks[x][y][z].visible
    };

    let start_time = extra::time::precise_time_ns();

    let perlin = Perlin::from_seed([seed as uint]);

    for block_x in range(0, CHUNK_SIZE) {
        for block_z in range(0, CHUNK_SIZE) {
            let noise = perlin.gen([
                (chunk_x + block_x as i64) as f64 * 0.1,
                (chunk_z + block_z as i64) as f64 * 0.1
            ]);
            let height = ((noise + 1.0) * (CHUNK_SIZE as f64 / 8.0)) as uint;
            for y in range(0, height) {
                map.blocks[block_x][y][block_z] = Block { visible: true };
            }
        }
    }

    let after_noise_time = extra::time::precise_time_ns();

    let mut vertices : ~[Vec3<f32>] = ~[];
    let mut normals : ~[Vec3<f32>] = ~[];
    let mut elements : ~[GLuint] = ~[];

    let mut idx = 0;

    for x in range(0, CHUNK_SIZE) {
        for y in range(0, CHUNK_SIZE) {
            for z in range(0, CHUNK_SIZE) {
                let block = &map.blocks[x][y][z];

                if (!block.visible) {
                    continue;
                }

                let block_position = Vec3 { x: x as f32, y: y as f32, z: z as f32 };

                for face in faces.iter() {
                    let neighbor_position = block_position.add_v(&face.normal);
                    if block_exists(neighbor_position.x as int, neighbor_position.y as int, neighbor_position.z as int) {
                        continue;
                    }

                    for v in face.vertices.iter() {
                        vertices.push(v.add_v(&block_position));
                        normals.push(face.normal);
                    }

                    for e in face_elements.iter() {
                        elements.push((idx * face.vertices.len()) as GLuint + *e);
                    }

                    idx += 1;
                }
            }
        }
    }

    let after_mesh_time = extra::time::precise_time_ns();

    let mut vao = 0;
    let mut vertex_buffer = 0;
    let mut normal_buffer = 0;
    let mut element_buffer = 0;

    unsafe {
        // Create Vertex Array Object
        gl::GenVertexArrays(1, &mut vao);
        gl::BindVertexArray(vao);

        // Create a Vertex Buffer Object and copy the vertex data to it
        gl::GenBuffers(1, &mut vertex_buffer);
        gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer);
        gl::BufferData(gl::ARRAY_BUFFER,
                        (vertices.len() * std::mem::size_of::<Vec3<f32>>()) as GLsizeiptr,
                        cast::transmute(&vertices[0]),
                        gl::STATIC_DRAW);

        // Create a Vertex Buffer Object and copy the normal data to it
        gl::GenBuffers(1, &mut normal_buffer);
        gl::BindBuffer(gl::ARRAY_BUFFER, normal_buffer);
        gl::BufferData(gl::ARRAY_BUFFER,
                        (normals.len() * std::mem::size_of::<Vec3<f32>>()) as GLsizeiptr,
                        cast::transmute(&normals[0]),
                        gl::STATIC_DRAW);

        // Create a Vertex Buffer Object and copy the element data to it
        gl::GenBuffers(1, &mut element_buffer);
        gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, element_buffer);
        gl::BufferData(gl::ELEMENT_ARRAY_BUFFER,
                        (elements.len() * std::mem::size_of::<GLuint>()) as GLsizeiptr,
                        cast::transmute(&elements[0]),
                        gl::STATIC_DRAW);

        // Specify the layout of the vertex data
        let vert_attr = "position".with_c_str(|ptr| gl::GetAttribLocation(res.program, ptr));
        assert!(vert_attr as u32 != gl::INVALID_VALUE);
        gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer);
        gl::EnableVertexAttribArray(vert_attr as GLuint);
        gl::VertexAttribPointer(vert_attr as GLuint, 3, gl::FLOAT,
                                gl::FALSE as GLboolean, 0, ptr::null());

        let normal_attr = "normal".with_c_str(|ptr| gl::GetAttribLocation(res.program, ptr));
        assert!(normal_attr as u32 != gl::INVALID_VALUE);
        gl::BindBuffer(gl::ARRAY_BUFFER, normal_buffer);
        gl::EnableVertexAttribArray(normal_attr as GLuint);
        gl::VertexAttribPointer(normal_attr as GLuint, 3, gl::FLOAT,
                                gl::FALSE as GLboolean, 0, ptr::null());
    }

    gl::BindVertexArray(0);

    let after_buffer_time = extra::time::precise_time_ns();

    println!("chunk loading profile (us): noise={} mesh={} buffer={}",
             (after_noise_time - start_time)/1000,
             (after_mesh_time - after_noise_time)/1000,
             (after_buffer_time - after_mesh_time)/1000)

    return ~Chunk {
        x: chunk_x,
        z: chunk_z,
        map: map,
        vao: vao,
        vertex_buffer: vertex_buffer,
        normal_buffer: normal_buffer,
        element_buffer: element_buffer,
        num_elements: elements.len(),
        used_time: extra::time::precise_time_ns(),
    };
}

static face_elements : [GLuint, ..6] = [
    0, 1, 2, 3, 2, 1,
];

static faces : [Face, ..6] = [
    /* front */
    Face {
        normal: Vec3 { x: 0.0, y: 0.0, z: 1.0 },
        vertices: [
            Vec3 { x: 0.0, y: 0.0, z: 1.0 }, /* bottom left */
            Vec3 { x: 1.0, y: 0.0, z: 1.0 },  /* bottom right */
            Vec3 { x: 0.0, y: 1.0, z: 1.0 }, /* top left */
            Vec3 { x: 1.0, y: 1.0, z: 1.0 },  /* top right */
        ],
    },

    /* back */
    Face {
        normal: Vec3 { x: 0.0, y: 0.0, z: -1.0 },
        vertices: [
            Vec3 { x: 1.0, y: 0.0, z: 0.0 }, /* bottom right */
            Vec3 { x: 0.0, y: 0.0, z: 0.0 },  /* bottom left */
            Vec3 { x: 1.0, y: 1.0, z: 0.0 }, /* top right */
            Vec3 { x: 0.0, y: 1.0, z: 0.0 },  /* top left */
        ],
    },

    /* right */
    Face {
        normal: Vec3 { x: 1.0, y: 0.0, z: 0.0 },
        vertices: [
            Vec3 { x: 1.0, y: 0.0, z: 1.0 }, /* bottom front */
            Vec3 { x: 1.0, y: 0.0, z: 0.0 }, /* bottom back */
            Vec3 { x: 1.0, y: 1.0, z: 1.0 }, /* top front */
            Vec3 { x: 1.0, y: 1.0, z: 0.0 }, /* top back */
        ],
    },

    /* left */
    Face {
        normal: Vec3 { x: -1.0, y: 0.0, z: 0.0 },
        vertices: [
            Vec3 { x: 0.0, y: 0.0, z: 0.0 }, /* bottom back */
            Vec3 { x: 0.0, y: 0.0, z: 1.0 }, /* bottom front */
            Vec3 { x: 0.0, y: 1.0, z: 0.0 }, /* top back */
            Vec3 { x: 0.0, y: 1.0, z: 1.0 }, /* top front */
        ],
    },

    /* top */
    Face {
        normal: Vec3 { x: 0.0, y: 1.0, z: 0.0 },
        vertices: [
            Vec3 { x: 0.0, y: 1.0, z: 1.0 }, /* front left */
            Vec3 { x: 1.0, y: 1.0, z: 1.0 }, /* front right */
            Vec3 { x: 0.0, y: 1.0, z: 0.0 }, /* back left */
            Vec3 { x: 1.0, y: 1.0, z: 0.0 }, /* back right */
        ],
    },

    /* bottom */
    Face {
        normal: Vec3 { x: 0.0, y: -1.0, z: 0.0 },
        vertices: [
            Vec3 { x: 0.0, y: 0.0, z: 0.0 }, /* back left */
            Vec3 { x: 1.0, y: 0.0, z: 0.0 }, /* back right */
            Vec3 { x: 0.0, y: 0.0, z: 1.0 }, /* front left */
            Vec3 { x: 1.0, y: 0.0, z: 1.0 }, /* front right */
        ],
    },
];
<|endoftext|>


<commit_before><commit_msg>Added an example that reconnects on error using IrcReactor.<commit_after>extern crate irc;

use std::default::Default;
use irc::error;
use irc::client::prelude::*;

fn main() {
    let cfg1 = Config {
        nickname: Some("pickles".to_owned()),
        server: Some("irc.fyrechat.net".to_owned()),
        channels: Some(vec!["#irc-crate".to_owned()]),
        ..Default::default()
    };

    let cfg2 = Config {
        nickname: Some("bananas".to_owned()),
        server: Some("irc.fyrechat.net".to_owned()),
        channels: Some(vec!["#irc-crate".to_owned()]),
        ..Default::default()
    };

    let configs = vec![cfg1, cfg2];

    let mut reactor = IrcReactor::new().unwrap();

    loop {
        let res = configs.iter().fold(Ok(()), |acc, config| {
            acc.and(
                reactor.prepare_server_and_connect(config).and_then(|server| {
                    server.identify().and(Ok(server))
                }).and_then(|server| {
                    reactor.register_server_with_handler(server, process_msg);
                    Ok(())
                })
            )
        }).and_then(|()| reactor.run());

        match res {
            Ok(_) => break,
            Err(e) => eprintln!("{}", e),
        }
    }
}

fn process_msg(server: &IrcServer, message: Message) -> error::Result<()> {
    print!("{}", message);
    match message.command {
        Command::PRIVMSG(ref target, ref msg) => {
            if msg.contains("pickles") {
                server.send_privmsg(target, "Hi!")?;
            } else if msg.contains("quit") {
                server.send_quit("bye")?;
            }
        }
        _ => (),
    }
    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>debuginfo: Add test case for issue #8513.<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249

// compile-flags:-Z extra-debug-info
// debugger:run

// Nothing to do here really, just make sure it compiles. See issue #8513.
fn main() {
    let _ = ||();
}

<|endoftext|>


<commit_before>use redox::*;
use redox::time::*;

pub struct FileManager {
    folder_icon: BMPFile,
    audio_icon: BMPFile,
    bin_icon: BMPFile,
    image_icon: BMPFile,
    source_icon: BMPFile,
    script_icon: BMPFile,
    text_icon: BMPFile,
    file_icon: BMPFile,
    files: Vec<String>,
    selected: isize,
    last_mouse_event: MouseEvent,
    click_time: Duration,
}

fn load_icon(path: &str) -> BMPFile {
    let mut resource = File::open(&("file:///ui/mimetypes/".to_string() + path + ".bmp"));

    let mut vec: Vec<u8> = Vec::new();
    resource.read_to_end(&mut vec);

    BMPFile::from_data(&vec)
}

impl FileManager {
    pub fn new() -> Self {
        FileManager {
            folder_icon: load_icon("inode-directory"),
            audio_icon: load_icon("audio-x-wav"),
            bin_icon: load_icon("application-x-executable"),
            image_icon: load_icon("image-x-generic"),
            source_icon: load_icon("text-x-makefile"),
            script_icon: load_icon("text-x-script"),
            text_icon: load_icon("text-x-generic"),
            file_icon: load_icon("unknown"),
            files: Vec::new(),
            selected: -1,
            last_mouse_event: MouseEvent {
                x: 0,
                y: 0,
                left_button: false,
                middle_button: false,
                right_button: false,
            }
            click_time: Duration::new(0, 0),
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        window.set([255, 255, 255, 255]);

        let mut i = 0;
        let mut row = 0;
        for string in self.files.iter() {
            if i == self.selected {
                let width = window.width();
                window.rect(0, 32 * row as isize, width, 32, [224, 224, 224, 255]);
            }

            if string.ends_with('/') {
                window.image(0,
                             32 * row as isize,
                             self.folder_icon.width(),
                             self.folder_icon.height(),
                             self.folder_icon.as_slice());
            } else if string.ends_with(".wav") {
                window.image(0,
                             32 * row as isize,
                             self.audio_icon.width(),
                             self.audio_icon.height(),
                             self.audio_icon.as_slice());
            } else if string.ends_with(".bin") {
                window.image(0,
                             32 * row as isize,
                             self.bin_icon.width(),
                             self.bin_icon.height(),
                             self.bin_icon.as_slice());
            } else if string.ends_with(".bmp") {
                window.image(0,
                             32 * row as isize,
                             self.image_icon.width(),
                             self.image_icon.height(),
                             self.image_icon.as_slice());
            } else if string.ends_with(".rs") || string.ends_with(".asm") || string.ends_with(".list") {
                window.image(0,
                             32 * row as isize,
                             self.source_icon.width(),
                             self.source_icon.height(),
                             self.source_icon.as_slice());
            } else if string.ends_with(".sh") || string.ends_with(".lua") {
                window.image(0,
                             32 * row as isize,
                             self.script_icon.width(),
                             self.script_icon.height(),
                             self.script_icon.as_slice());
            } else if string.ends_with(".md") || string.ends_with(".txt") {
                window.image(0,
                             32 * row as isize,
                             self.text_icon.width(),
                             self.text_icon.height(),
                             self.text_icon.as_slice());
            } else {
                window.image(0,
                             32 * row as isize,
                             self.file_icon.width(),
                             self.file_icon.height(),
                             self.file_icon.as_slice());
            }

            let mut col = 0;
            for c in string.chars() {
                if c == '\n' {
                    col = 0;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col < window.width() / 8 && row < window.height() / 32 {
                        window.char(8 * col as isize + 40,
                                    32 * row as isize + 8,
                                    c,
                                    [0, 0, 0, 255]);
                        col += 1;
                    }
                }
                if col >= window.width() / 8 {
                    col = 0;
                    row += 1;
                }
            }
            row += 1;
            i += 1;
        }

        window.sync();
    }

    fn main(&mut self, path: &str) {
        let mut width = 160;
        let mut height = 0;
        {
            let mut resource = File::open(path);

            let mut vec: Vec<u8> = Vec::new();
            resource.read_to_end(&mut vec);

            for file in unsafe { String::from_utf8_unchecked(vec) }.split('\n') {
                if width < 40 + (file.len() + 1) * 8 {
                    width = 40 + (file.len() + 1) * 8;
                }
                self.files.push(file.to_string());
            }

            if height < self.files.len() * 32 {
                height = self.files.len() * 32;
            }
        }

        let mut window = Window::new((rand() % 400 + 50) as isize,
                                     (rand() % 300 + 50) as isize,
                                     width,
                                     height,
                                     &path);

        self.draw_content(&mut window);

        while let Option::Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        match key_event.scancode {
                            K_ESC => break,
                            K_HOME => self.selected = 0,
                            K_UP => if self.selected > 0 {
                                self.selected -= 1;
                            },
                            K_END => self.selected = self.files.len() as isize - 1,
                            K_DOWN => if self.selected < self.files.len() as isize - 1 {
                                self.selected += 1;
                            },
                            _ => match key_event.character {
                                '\0' => (),
                                '\n' => {
                                    if self.selected >= 0 &&
                                       self.selected < self.files.len() as isize {
                                        match self.files.get(self.selected as usize) {
                                            Option::Some(file) => OpenEvent {
                                                url_string: path.to_string() + &file,
                                            }.trigger(),
                                            Option::None => (),
                                        }
                                    }
                                }
                                _ => {
                                    let mut i = 0;
                                    for file in self.files.iter() {
                                        if file.starts_with(key_event.character) {
                                            self.selected = i;
                                            break;
                                        }
                                        i += 1;
                                    }
                                }
                            },
                        }

                        self.draw_content(&mut window);
                    }
                }
                EventOption::Mouse(mouse_event) => {
                    let mut redraw = false;
                    let mut i = 0;
                    let mut row = 0;
                    for file in self.files.iter() {
                        let mut col = 0;
                        for c in file.chars() {
                            if mouse_event.y >= 32 * row as isize &&
                               mouse_event.y < 32 * row as isize + 32 {
                                let click_time = Duration::realtime();
                                if self.selected == i {
                                    if click_time - self.click_time < Duration::new(0, 500 * NANOS_PER_MILLI) {
                                        match self.files.get(self.selected as usize) {
                                            Option::Some(file) => OpenEvent {
                                                url_string: path.to_string() + &file,
                                            }.trigger(),
                                            Option::None => (),
                                        }
                                        self.click_time = Duration::new(0, 0);
                                    }
                                } else {
                                    self.selected = i;
                                    self.click_time = click_time;
                                }
                                redraw = true;
                            }

                            if c == '\n' {
                                col = 0;
                                row += 1;
                            } else if c == '\t' {
                                col += 8 - col % 8;
                            } else {
                                if col < window.width() / 8 && row < window.height() / 32 {
                                    col += 1;
                                }
                            }
                            if col >= window.width() / 8 {
                                col = 0;
                                row += 1;
                            }
                        }
                        row += 1;
                        i += 1;
                    }

                    if redraw {
                        self.draw_content(&mut window);
                    }

                    self.last_mouse_event = mouse_event;
                }
                _ => (),
            }
        }
    }
}

pub fn main() {
    match args().get(1) {
        Option::Some(arg) => FileManager::new().main(arg),
        Option::None => FileManager::new().main("file:///"),
    }
}
<commit_msg>WIP double click<commit_after>use redox::*;
use redox::time::*;

pub struct FileManager {
    folder_icon: BMPFile,
    audio_icon: BMPFile,
    bin_icon: BMPFile,
    image_icon: BMPFile,
    source_icon: BMPFile,
    script_icon: BMPFile,
    text_icon: BMPFile,
    file_icon: BMPFile,
    files: Vec<String>,
    selected: isize,
    last_mouse_event: MouseEvent,
    click_time: Duration,
}

fn load_icon(path: &str) -> BMPFile {
    let mut resource = File::open(&("file:///ui/mimetypes/".to_string() + path + ".bmp"));

    let mut vec: Vec<u8> = Vec::new();
    resource.read_to_end(&mut vec);

    BMPFile::from_data(&vec)
}

impl FileManager {
    pub fn new() -> Self {
        FileManager {
            folder_icon: load_icon("inode-directory"),
            audio_icon: load_icon("audio-x-wav"),
            bin_icon: load_icon("application-x-executable"),
            image_icon: load_icon("image-x-generic"),
            source_icon: load_icon("text-x-makefile"),
            script_icon: load_icon("text-x-script"),
            text_icon: load_icon("text-x-generic"),
            file_icon: load_icon("unknown"),
            files: Vec::new(),
            selected: -1,
            last_mouse_event: MouseEvent {
                x: 0,
                y: 0,
                left_button: false,
                middle_button: false,
                right_button: false,
            }
            click_time: Duration::new(0, 0),
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        window.set([255, 255, 255, 255]);

        let mut i = 0;
        let mut row = 0;
        for string in self.files.iter() {
            if i == self.selected {
                let width = window.width();
                window.rect(0, 32 * row as isize, width, 32, [224, 224, 224, 255]);
            }

            if string.ends_with('/') {
                window.image(0,
                             32 * row as isize,
                             self.folder_icon.width(),
                             self.folder_icon.height(),
                             self.folder_icon.as_slice());
            } else if string.ends_with(".wav") {
                window.image(0,
                             32 * row as isize,
                             self.audio_icon.width(),
                             self.audio_icon.height(),
                             self.audio_icon.as_slice());
            } else if string.ends_with(".bin") {
                window.image(0,
                             32 * row as isize,
                             self.bin_icon.width(),
                             self.bin_icon.height(),
                             self.bin_icon.as_slice());
            } else if string.ends_with(".bmp") {
                window.image(0,
                             32 * row as isize,
                             self.image_icon.width(),
                             self.image_icon.height(),
                             self.image_icon.as_slice());
            } else if string.ends_with(".rs") || string.ends_with(".asm") || string.ends_with(".list") {
                window.image(0,
                             32 * row as isize,
                             self.source_icon.width(),
                             self.source_icon.height(),
                             self.source_icon.as_slice());
            } else if string.ends_with(".sh") || string.ends_with(".lua") {
                window.image(0,
                             32 * row as isize,
                             self.script_icon.width(),
                             self.script_icon.height(),
                             self.script_icon.as_slice());
            } else if string.ends_with(".md") || string.ends_with(".txt") {
                window.image(0,
                             32 * row as isize,
                             self.text_icon.width(),
                             self.text_icon.height(),
                             self.text_icon.as_slice());
            } else {
                window.image(0,
                             32 * row as isize,
                             self.file_icon.width(),
                             self.file_icon.height(),
                             self.file_icon.as_slice());
            }

            let mut col = 0;
            for c in string.chars() {
                if c == '\n' {
                    col = 0;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col < window.width() / 8 && row < window.height() / 32 {
                        window.char(8 * col as isize + 40,
                                    32 * row as isize + 8,
                                    c,
                                    [0, 0, 0, 255]);
                        col += 1;
                    }
                }
                if col >= window.width() / 8 {
                    col = 0;
                    row += 1;
                }
            }
            row += 1;
            i += 1;
        }

        window.sync();
    }

    fn main(&mut self, path: &str) {
        let mut width = 160;
        let mut height = 0;
        {
            let mut resource = File::open(path);

            let mut vec: Vec<u8> = Vec::new();
            resource.read_to_end(&mut vec);

            for file in unsafe { String::from_utf8_unchecked(vec) }.split('\n') {
                if width < 40 + (file.len() + 1) * 8 {
                    width = 40 + (file.len() + 1) * 8;
                }
                self.files.push(file.to_string());
            }

            if height < self.files.len() * 32 {
                height = self.files.len() * 32;
            }
        }

        let mut window = Window::new((rand() % 400 + 50) as isize,
                                     (rand() % 300 + 50) as isize,
                                     width,
                                     height,
                                     &path);

        self.draw_content(&mut window);

        while let Option::Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        match key_event.scancode {
                            K_ESC => break,
                            K_HOME => self.selected = 0,
                            K_UP => if self.selected > 0 {
                                self.selected -= 1;
                            },
                            K_END => self.selected = self.files.len() as isize - 1,
                            K_DOWN => if self.selected < self.files.len() as isize - 1 {
                                self.selected += 1;
                            },
                            _ => match key_event.character {
                                '\0' => (),
                                '\n' => {
                                    if self.selected >= 0 &&
                                       self.selected < self.files.len() as isize {
                                        match self.files.get(self.selected as usize) {
                                            Option::Some(file) => OpenEvent {
                                                url_string: path.to_string() + &file,
                                            }.trigger(),
                                            Option::None => (),
                                        }
                                    }
                                }
                                _ => {
                                    let mut i = 0;
                                    for file in self.files.iter() {
                                        if file.starts_with(key_event.character) {
                                            self.selected = i;
                                            break;
                                        }
                                        i += 1;
                                    }
                                }
                            },
                        }

                        self.draw_content(&mut window);
                    }
                }
                EventOption::Mouse(mouse_event) => {
                    let mut redraw = false;
                    let mut i = 0;
                    let mut row = 0;
                    for file in self.files.iter() {
                        let mut col = 0;
                        for c in file.chars() {
                            if mouse_event.y >= 32 * row as isize &&
                               mouse_event.y < 32 * row as isize + 32 {
                                let click_time = Duration::realtime();
                                if self.selected == i {
                                    if click_time - self.click_time < Duration::new(0, 500 * NANOS_PER_MILLI) {
                                        match self.files.get(self.selected as usize) {
                                            Option::Some(file) => OpenEvent {
                                                url_string: path.to_string() + &file,
                                            }.trigger(),
                                            Option::None => (),
                                        }
                                        self.click_time = Duration::new(0, 0);
                                    }
                                } else {
                                    self.selected = i;
                                    self.click_time = click_time;
                                }
                                redraw = true;
                            }

                            if c == '\n' {
                                col = 0;
                                row += 1;
                            } else if c == '\t' {
                                col += 8 - col % 8;
                            } else {
                                if col < window.width() / 8 && row < window.height() / 32 {
                                    col += 1;
                                }
                            }
                            if col >= window.width() / 8 {
                                col = 0;
                                row += 1;
                            }
                        }
                        row += 1;
                        i += 1;
                    }

                    if redraw {
                        self.draw_content(&mut window);
                    }

                    if mouse_event.left_button
                    self.last_mouse_event = mouse_event;
                }
                _ => (),
            }
        }
    }
}

pub fn main() {
    match args().get(1) {
        Option::Some(arg) => FileManager::new().main(arg),
        Option::None => FileManager::new().main("file:///"),
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A shareable mutable container for the DOM.

use dom::bindings::trace::JSTraceable;
use js::jsapi::{JSTracer};

use util::task_state;
use util::task_state::{SCRIPT, IN_GC};

use std::cell::{BorrowState, RefCell, Ref, RefMut};

/// A mutable field in the DOM.
///
/// This extends the API of `core::cell::RefCell` to allow unsafe access in
/// certain situations, with dynamic checking in debug builds.
pub struct DOMRefCell<T> {
    value: RefCell<T>,
}

// Functionality specific to Servo's `DOMRefCell` type
// ===================================================

impl<T> DOMRefCell<T> {
    /// Return a reference to the contents.
    ///
    /// For use in the layout task only.
    #[allow(unsafe_code)]
    pub unsafe fn borrow_for_layout<'a>(&'a self) -> &'a T {
        debug_assert!(task_state::get().is_layout());
        &*self.value.as_unsafe_cell().get()
    }

    /// Borrow the contents for the purpose of GC tracing.
    ///
    /// This succeeds even if the object is mutably borrowed,
    /// so you have to be careful in trace code!
    #[allow(unsafe_code)]
    pub unsafe fn borrow_for_gc_trace<'a>(&'a self) -> &'a T {
        debug_assert!(task_state::get().contains(SCRIPT | IN_GC));
        &*self.value.as_unsafe_cell().get()
    }

    /// Borrow the contents for the purpose of script deallocation.
    ///
    #[allow(unsafe_code)]
    pub unsafe fn borrow_for_script_deallocation<'a>(&'a self) -> &'a mut T {
        debug_assert!(task_state::get().contains(SCRIPT));
        &mut *self.value.as_unsafe_cell().get()
    }

    /// Is the cell mutably borrowed?
    ///
    /// For safety checks in debug builds only.
    pub fn is_mutably_borrowed(&self) -> bool {
        self.value.borrow_state() == BorrowState::Writing
    }

    /// Attempts to immutably borrow the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// Returns `None` if the value is currently mutably borrowed.
    ///
    /// # Panics
    ///
    /// Panics if this is called off the script thread.
    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
        debug_assert!(task_state::get().is_script());
        match self.value.borrow_state() {
            BorrowState::Writing => None,
            _ => Some(self.value.borrow()),
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// Returns `None` if the value is currently borrowed.
    ///
    /// # Panics
    ///
    /// Panics if this is called off the script thread.
    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
        debug_assert!(task_state::get().is_script());
        match self.value.borrow_state() {
            BorrowState::Unused => Some(self.value.borrow_mut()),
            _ => None,
        }
    }
}

impl<T: JSTraceable> JSTraceable for DOMRefCell<T> {
    fn trace(&self, trc: *mut JSTracer) {
        unsafe {
            (*self).borrow_for_gc_trace().trace(trc)
        }
    }
}

// Functionality duplicated with `core::cell::RefCell`
// ===================================================
impl<T> DOMRefCell<T> {
    /// Create a new `DOMRefCell` containing `value`.
    pub fn new(value: T) -> DOMRefCell<T> {
        DOMRefCell {
            value: RefCell::new(value),
        }
    }

    /// Immutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// # Panics
    ///
    /// Panics if this is called off the script thread.
    ///
    /// Panics if the value is currently mutably borrowed.
    pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
        match self.try_borrow() {
            Some(ptr) => ptr,
            None => panic!("DOMRefCell<T> already mutably borrowed")
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// # Panics
    ///
    /// Panics if this is called off the script thread.
    ///
    /// Panics if the value is currently borrowed.
    pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
        match self.try_borrow_mut() {
            Some(ptr) => ptr,
            None => panic!("DOMRefCell<T> already borrowed")
        }
    }
}
<commit_msg>Utilize Option::expect<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A shareable mutable container for the DOM.

use dom::bindings::trace::JSTraceable;
use js::jsapi::{JSTracer};

use util::task_state;
use util::task_state::{SCRIPT, IN_GC};

use std::cell::{BorrowState, RefCell, Ref, RefMut};

/// A mutable field in the DOM.
///
/// This extends the API of `core::cell::RefCell` to allow unsafe access in
/// certain situations, with dynamic checking in debug builds.
pub struct DOMRefCell<T> {
    value: RefCell<T>,
}

// Functionality specific to Servo's `DOMRefCell` type
// ===================================================

impl<T> DOMRefCell<T> {
    /// Return a reference to the contents.
    ///
    /// For use in the layout task only.
    #[allow(unsafe_code)]
    pub unsafe fn borrow_for_layout<'a>(&'a self) -> &'a T {
        debug_assert!(task_state::get().is_layout());
        &*self.value.as_unsafe_cell().get()
    }

    /// Borrow the contents for the purpose of GC tracing.
    ///
    /// This succeeds even if the object is mutably borrowed,
    /// so you have to be careful in trace code!
    #[allow(unsafe_code)]
    pub unsafe fn borrow_for_gc_trace<'a>(&'a self) -> &'a T {
        debug_assert!(task_state::get().contains(SCRIPT | IN_GC));
        &*self.value.as_unsafe_cell().get()
    }

    /// Borrow the contents for the purpose of script deallocation.
    ///
    #[allow(unsafe_code)]
    pub unsafe fn borrow_for_script_deallocation<'a>(&'a self) -> &'a mut T {
        debug_assert!(task_state::get().contains(SCRIPT));
        &mut *self.value.as_unsafe_cell().get()
    }

    /// Is the cell mutably borrowed?
    ///
    /// For safety checks in debug builds only.
    pub fn is_mutably_borrowed(&self) -> bool {
        self.value.borrow_state() == BorrowState::Writing
    }

    /// Attempts to immutably borrow the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// Returns `None` if the value is currently mutably borrowed.
    ///
    /// # Panics
    ///
    /// Panics if this is called off the script thread.
    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
        debug_assert!(task_state::get().is_script());
        match self.value.borrow_state() {
            BorrowState::Writing => None,
            _ => Some(self.value.borrow()),
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// Returns `None` if the value is currently borrowed.
    ///
    /// # Panics
    ///
    /// Panics if this is called off the script thread.
    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
        debug_assert!(task_state::get().is_script());
        match self.value.borrow_state() {
            BorrowState::Unused => Some(self.value.borrow_mut()),
            _ => None,
        }
    }
}

impl<T: JSTraceable> JSTraceable for DOMRefCell<T> {
    fn trace(&self, trc: *mut JSTracer) {
        unsafe {
            (*self).borrow_for_gc_trace().trace(trc)
        }
    }
}

// Functionality duplicated with `core::cell::RefCell`
// ===================================================
impl<T> DOMRefCell<T> {
    /// Create a new `DOMRefCell` containing `value`.
    pub fn new(value: T) -> DOMRefCell<T> {
        DOMRefCell {
            value: RefCell::new(value),
        }
    }

    /// Immutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// # Panics
    ///
    /// Panics if this is called off the script thread.
    ///
    /// Panics if the value is currently mutably borrowed.
    pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
        self.try_borrow().expect("DOMRefCell<T> already mutably borrowed")
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// # Panics
    ///
    /// Panics if this is called off the script thread.
    ///
    /// Panics if the value is currently borrowed.
    pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
        self.try_borrow_mut().expect("DOMRefCell<T> already borrowed")
    }
}
<|endoftext|>


<commit_before><commit_msg>practise rust version<commit_after>fn two_sum(nums: Vec<i32>, target: i32) -> Vec<u32> {
    let len = nums.len();
    for i in 0..len {
        for j in i + 1..len {
            if nums[i] + nums[j] == target {
                return vec![i as u32, j as u32];
            }
        }
    }
    return vec![];
}

fn main() {
    let testcase0 = vec![2, 7, 11, 15];
    let testcase1 = vec![0, 4, 3, 0];
    let testcase2 = vec![-3, 4, 3, 90];

    println!("{:?}", two_sum(testcase0, 9));
    println!("{:?}", two_sum(testcase1, 0));
    println!("{:?}", two_sum(testcase2, 0));
}
<|endoftext|>


<commit_before><commit_msg>Add support for template specialization. Add support for `mod` item without body. Add support for tuple patterns. Fix bug parsing template application with lifetimes. Fix bug parsing single arg item in an enum. Simplify some codes.<commit_after><|endoftext|>