<commit_before><commit_msg>Added multicast<commit_after>use multiqueue::{InnerSend, InnerRecv, BCast, Multicast, MultiQueue};
use countedindex::Index;

use std::sync::mpsc::{TrySendError, TryRecvError, RecvError};

/// This class is the sending half of the multicast Queue. It supports both
/// single and multi consumer modes with competitive performance in each case.
/// It only supports nonblocking writes (the futures sender being an exception)
/// as well as being the conduit for adding new writers.
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let (send, recv) = multiqueue::multiqueue(4);
///
/// let mut handles = vec![];
///
/// for i in 0..2 { // or n
///     let cur_recv = recv.add_stream();
///     for j in 0..2 {
///         let stream_consumer = cur_recv.clone();
///         handles.push(thread::spawn(move || {
///             for val in stream_consumer {
///                 println!("Stream {} consumer {} got {}", i, j, val);
///             }
///         }));
///     }
///     // cur_recv is dropped here
/// }
///
/// // Take notice that I drop the reader - this removes it from
/// // the queue, meaning that the readers in the new threads
/// // won't get starved by the lack of progress from recv
/// recv.unsubscribe();
///
/// for i in 0..10 {
///     // Don't do this busy loop in real stuff unless you're really sure
///     loop {
///         if send.try_send(i).is_ok() {
///             break;
///         }
///     }
/// }
/// drop(send);
///
/// for t in handles {
///     t.join();
/// }
/// // prints along the lines of
/// // Stream 0 consumer 1 got 2
/// // Stream 0 consumer 0 got 0
/// // Stream 1 consumer 0 got 0
/// // Stream 0 consumer 1 got 1
/// // Stream 1 consumer 1 got 1
/// // Stream 1 consumer 0 got 2
/// // etc
/// ```
#[derive(Clone)]
pub struct MulticastSender<T: Clone> {
    sender: InnerSend<BCast<T>, T>,
}

/// This class is the receiving half of the MultiQueue.
/// Within each stream, it supports both single and multi consumer modes
/// with competitive performance in each case. It supports blocking and
/// nonblocking read modes as well as being the conduit for adding
/// new streams.
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let (send, recv) = multiqueue::multiqueue(4);
///
/// let mut handles = vec![];
///
/// for i in 0..2 { // or n
///     let cur_recv = recv.add_stream();
///     for j in 0..2 {
///         let stream_consumer = cur_recv.clone();
///         handles.push(thread::spawn(move || {
///             for val in stream_consumer {
///                 println!("Stream {} consumer {} got {}", i, j, val);
///             }
///         }));
///     }
///     // cur_recv is dropped here
/// }
///
/// // Take notice that I drop the reader - this removes it from
/// // the queue, meaning that the readers in the new threads
/// // won't get starved by the lack of progress from recv
/// recv.unsubscribe();
///
/// for i in 0..10 {
///     // Don't do this busy loop in real stuff unless you're really sure
///     loop {
///         if send.try_send(i).is_ok() {
///             break;
///         }
///     }
/// }
/// drop(send);
///
/// for t in handles {
///     t.join();
/// }
/// // prints along the lines of
/// // Stream 0 consumer 1 got 2
/// // Stream 0 consumer 0 got 0
/// // Stream 1 consumer 0 got 0
/// // Stream 0 consumer 1 got 1
/// // Stream 1 consumer 1 got 1
/// // Stream 1 consumer 0 got 2
/// // etc
/// ```
#[derive(Clone)]
pub struct MulticastReceiver<T: Clone> {
    reader: InnerRecv<BCast<T>, T>,
}

/// This class is similar to the receiver, except it ensures that there
/// is only one consumer for the stream it owns. This means that
/// one can safely view the data in-place with the recv_view method family
/// and avoid the cost of copying it. If there's only one receiver on a stream,
/// it can be converted into a UniInnerRecv
///
/// # Example:
///
/// ```
/// use multiqueue::multiqueue;
///
/// let (w, r) = multiqueue(10);
/// w.try_send(1).unwrap();
/// let r2 = r.clone();
/// // Fails since there's two receivers on the stream
/// assert!(r2.into_single().is_err());
/// let single_r = r.into_single().unwrap();
/// let val = match single_r.try_recv_view(|x| 2 * *x) {
///     Ok(val) => val,
///     Err(_) => panic!("Queue should have an element"),
/// };
/// assert_eq!(2, val);
/// ```
pub struct MulticastUniReceiver<T: Clone + Sync> {
    reader: InnerRecv<BCast<T>, T>,
}

impl<T: Clone> MulticastReceiver<T> {

    /// Tries to receive a value from the queue without blocking.
    ///
    /// # Examples:
    ///
    /// ```
    /// use multiqueue::multicast_queue;
    /// let (w, r) = multicast_queue(10);
    /// w.try_send(1).unwrap();
    /// assert_eq!(1, r.try_recv().unwrap());
    /// ```
    ///
    /// ```
    /// use multiqueue::multiqueue;
    /// use std::thread;
    ///
    /// let (send, recv) = multiqueue(10);
    ///
    /// let handle = thread::spawn(move || {
    ///     for val in recv {
    ///         println!("Got {}", val);
    ///     }
    /// });
    ///
    /// for i in 0..10 {
    ///     send.try_send(i).unwrap();
    /// }
    ///
    /// // Drop the sender to close the queue
    /// drop(send);
    ///
    /// handle.join();
    /// ```
    pub fn try_recv(&self) -> Result<T, TryRecvError> {
        self.reader.try_recv()
    }

    pub fn recv(&self) -> Result<T, RecvError> {
        self.reader.recv()
    }

    /// Adds a new data stream to the queue, starting at the same position
    /// as the InnerRecv this is being called on.
    ///
    /// # Examples
    ///
    /// ```
    /// use multiqueue::multiqueue;
    /// let (w, r) = multiqueue(10);
    /// w.try_send(1).unwrap();
    /// assert_eq!(r.recv().unwrap(), 1);
    /// w.try_send(1).unwrap();
    /// let r2 = r.add_stream();
    /// assert_eq!(r.recv().unwrap(), 1);
    /// assert_eq!(r2.recv().unwrap(), 1);
    /// assert!(r.try_recv().is_err());
    /// assert!(r2.try_recv().is_err());
    /// ```
    ///
    /// ```
    /// use multiqueue::multiqueue;
    ///
    /// use std::thread;
    ///
    /// let (send, recv) = multiqueue(4);
    /// let mut handles = vec![];
    /// for i in 0..2 { // or n
    ///     let cur_recv = recv.add_stream();
    ///     handles.push(thread::spawn(move || {
    ///         for val in cur_recv {
    ///             println!("Stream {} got {}", i, val);
    ///         }
    ///     }));
    /// }
    ///
    /// // Take notice that I drop the reader - this removes it from
    /// // the queue, meaning that the readers in the new threads
    /// // won't get starved by the lack of progress from recv
    /// recv.unsubscribe();
    ///
    /// for i in 0..10 {
    ///     // Don't do this busy loop in real stuff unless you're really sure
    ///     loop {
    ///         if send.try_send(i).is_ok() {
    ///             break;
    ///         }
    ///     }
    /// }
    ///
    /// // Drop the sender to close the queue
    /// drop(send);
    ///
    /// for t in handles {
    ///     t.join();
    /// }
    ///
    /// ```

    pub fn add_stream(&self) -> MulticastReceiver<T> {
        MulticastReceiver { reader: self.reader.add_stream() }
    }

    /// Removes the given reader from the queue subscription lib
    /// Returns true if this is the last reader in a given broadcast unit
    ///
    /// # Examples
    ///
    /// ```
    /// use multiqueue::multiqueue;
    /// let (writer, reader) = multiqueue(1);
    /// let reader_2_1 = reader.add_stream();
    /// let reader_2_2 = reader_2_1.clone();
    /// writer.try_send(1).expect("This will succeed since queue is empty");
    /// reader.try_recv().expect("This reader can read");
    /// assert!(writer.try_send(1).is_err(), "This fails since the reader2 group hasn't advanced");
    /// assert!(!reader_2_2.unsubscribe(), "This returns false since reader_2_1 is still alive");
    /// assert!(reader_2_1.unsubscribe(),
    ///         "This returns true since there are no readers alive in the reader_2_x group");
    /// writer.try_send(1).expect("This succeeds since the reader_2 group is not blocking");
    /// ```
    pub fn unsubscribe(self) -> bool {
        self.reader.unsubscribe()
    }
}

impl<T: Clone + Sync> MulticastUniReceiver<T> {
    /// Identical to MulticastReceiver::try_recv
    pub fn try_recv(&self) -> Result<T, TryRecvError> {
        self.reader.try_recv()
    }

    /// Identical to MulticastReceiver::recv
    pub fn recv(&self) -> Result<T, RecvError> {
        self.reader.recv()
    }

    /// Applies the passed function to the value in the queue without copying it out
    /// If there is no data in the queue or the writers have disconnected,
    /// returns an Err((F, TryRecvError))
    ///
    /// # Example
    /// ```
    /// use multiqueue::multicast_queue;
    ///
    /// let (w, r) = multicase_queue(10);
    /// let single_r = r.into_single().unwrap();
    /// for i in 0..5 {
    ///     w.try_send(i).unwrap();
    /// }
    ///
    /// for i in 0..5 {
    ///     let val = match single_r.try_recv_view(|x| 1 + *x) {
    ///         Ok(val) => val,
    ///         Err(_) => panic!("Queue shouldn't be disconncted or empty"),
    ///     };
    ///     assert_eq!(i + 1, val);
    /// }
    /// assert!(single_r.try_recv_view(|x| *x).is_err());
    /// drop(w);
    /// assert!(single_r.try_recv_view(|x| *x).is_err());
    /// ```
    pub fn try_recv_view<R, F: FnOnce(&T) -> R>(&self, op: F) -> Result<R, (F, TryRecvError)> {
        let mut_w = |v: &mut T| op(v);
        self.reader.try_recv_view(mut_w)
    }

    /// Applies the passed function to the value in the queue without copying it out
    /// If there is no data in the queue, blocks until an item is pushed into the queue
    /// or all writers disconnect
    ///
    /// # Example
    /// ```
    /// use multiqueue::multiqueue;
    ///
    /// let (w, r) = multiqueue(10);
    /// let single_r = r.into_single().unwrap();
    /// for i in 0..5 {
    ///     w.try_send(i).unwrap();
    /// }
    ///
    /// for i in 0..5 {
    ///     let val = match single_r.recv_view(|x| 1 + *x) {
    ///         Ok(val) => val,
    ///         Err(_) => panic!("Queue shouldn't be disconncted or empty"),
    ///     };
    ///     assert_eq!(i + 1, val);
    /// }
    /// drop(w);
    /// assert!(single_r.recv_view(|x| *x).is_err());
    /// ```
    pub fn recv_view<R, F: FnOnce(&T) -> R>(&self, op: F) -> Result<R, (F, RecvError)> {
        let mut_w = |v: &mut T| op(v);
        self.reader.recv_view(mut_w)
    }

    /// Almost identical to MulticastReceiver::unsubscribe, except it doesn't
    /// return a boolean of whether this was the last receiver on the stream
    /// because a receiver of this type must be the last one on the stream
    pub fn unsubscribe(self) {
        self.reader.unsubscribe();
    }
}

pub fn multicast_queue<T: Clone>(capacity: Index) -> (MulticastSender<T>, MulticastReceiver<T>) {
    let (send, recv) = MultiQueue::<BCast<T>, T>::new(capacity);
    (MulticastSender { sender: send }, MulticastReceiver { reader: recv })
}

unsafe impl<T: Send + Clone> Send for MulticastSender<T> {}
unsafe impl<T: Send + Clone> Send for MulticastReceiver<T> {}
unsafe impl<T: Send + Clone + Sync> Send for MulticastUniReceiver<T> {}

pub struct MulticastIter<T: Clone> {
    recv: MulticastReceiver<T>,
}

impl<T: Clone> Iterator for MulticastIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        match self.recv.recv() {
            Ok(val) => Some(val),
            Err(_) => None,
        }
    }
}

impl<T: Clone> IntoIterator for MulticastReceiver<T> {
    type Item = T;

    type IntoIter = MulticastIter<T>;

    fn into_iter(self) -> MulticastIter<T> {
        MulticastIter { recv: self }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fail with pg-to-tar.<commit_after><|endoftext|>


<commit_before><commit_msg>Add start_prototype, a tool used for writing entry point assembly.<commit_after>// The `start` symbol must be written purely in assembly, because it has an ABI
// that the Rust compiler doesn't know (e.g. it does not expect the stack to be
// set up). One way to write a correct `start` implementation is to write it in
// Rust using the C ABI, compile that implementation, then tweak the assembly by
// hand. This is a Rust version of `start` for developers who are working on
// `start`.
//
// This file is not compiled by default; it must be included manually by adding
// `mod start_prototype;` to `lib.rs`.

#[repr(C)]
struct RtHeader {
    start: usize,
    initial_break: usize,
    stack_top: usize,
    data_size: usize,
    data_flash_start: *const u32,
    data_ram_start: *mut u32,
    bss_size: usize,
    bss_start: *mut u8,
}

#[link_section = ".start"]
#[no_mangle]
extern fn start_prototype(
    rt_header: &RtHeader,
    _memory_start: usize,
    _memory_len: usize,
    _app_break: usize,
) -> ! {
    use crate::TockSyscalls;
    use libtock_platform::{OneArgMemop, RawSyscalls, YieldType};

    let pc: usize;
    #[cfg(target_arch = "riscv32")]
    unsafe {
        asm!("auipc {}, 0", lateout(reg) pc, options(nomem, nostack, preserves_flags));
    }
    if pc != rt_header.start {
        // Binary is in an incorrect location: report an error via
        // LowLevelDebug.
        unsafe {
            TockSyscalls::four_arg_syscall(8, 1, 2, 0, 2);
        }
        // TODO: Replace with an Exit call when exit is implemented.
        loop {
            TockSyscalls::raw_yield(YieldType::Wait);
        }
    }

    // Set the app break.
    // TODO: Replace with Syscalls::memop_brk() when that is implemented.
    TockSyscalls::one_arg_memop(OneArgMemop::Brk, rt_header.initial_break);

    // Set the stack pointer.
    #[cfg(target_arch = "riscv32")]
    unsafe {
        asm!("mv sp, {}", in(reg) rt_header.stack_top, options(nomem, preserves_flags));
    }

    // Copy .data into place. Uses a manual loop rather than
    // `core::ptr::copy*()` to avoid relying on `memcopy` or `memmove`.
    let mut remaining = rt_header.data_size;
    let mut src = rt_header.data_flash_start;
    let mut dest = rt_header.data_ram_start;
    while remaining > 0 {
        unsafe {
            core::ptr::write(dest, *(src));
            src = src.add(1);
            dest = dest.add(1);
        }
        remaining -= 4;
    }

    // Zero .bss. Uses a manual loop and volatile write to avoid relying on
    // `memset`.
    let mut remaining = rt_header.bss_size;
    let mut dest = rt_header.bss_start;
    while remaining > 0 {
        unsafe {
            core::ptr::write_volatile(dest, 0);
            dest = dest.add(1);
        }
        remaining -= 1;
    }

    extern {
        fn rust_start() -> !;
    }

    unsafe { rust_start(); }
}
<|endoftext|>


<commit_before><commit_msg>Remove Clippy<commit_after><|endoftext|>


<commit_before><commit_msg>added bot.rs<commit_after>use std::io;
use std::io::prelude::*;
use std::str::FromStr;

#[derive(Copy,Clone)]
struct Bot {
    x:i32,
    y:i32,
}

impl Bot {
    fn new() -> Self {
        Bot {x:0,y:0}
    }
}

fn main() {
    let mut myBot = Bot::new();
    let mut moves:[u8;1] = [0;1];
    let mut moves_vec = Vec::<i32>::new();
    while moves[0] as char != '\n' {
        io::stdin().read(&mut moves).ok().expect("read error");
        let num = 1 + i32::from_str(&moves[0].to_string()[..]).unwrap() % 49;
        moves_vec.push(num);
    }

    let mut not_working:[u8;1] = [0;1];
    io::stdin().read(&mut not_working).ok().expect("read_error");
    let not_working = 1 + i32::from_str(&not_working[0].to_string()[..]).unwrap() % 49;
    moves_vec.pop();
    for i in moves_vec {
        match i {
            1 => { if i == not_working {} else {myBot.x +=1}},
            2 => { if i == not_working {} else {myBot.x +=-1}},
            3 => { if i == not_working {} else {myBot.y +=1}},
            4 => { if i == not_working {} else {myBot.y +=-1}},
            _ => {},
        }

        }

    println!("{:?}\n{:?}\n",myBot.x,myBot.y);
}
<|endoftext|>


<commit_before><commit_msg>Removes panic! calls from the Nbt implementation.<commit_after><|endoftext|>


<commit_before><commit_msg>Fixup the indexing in mv.rs to get the appropriate args<commit_after><|endoftext|>


<commit_before><commit_msg>Don't use to_string to get number of u64 digits<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: Use fill storeid when listing<commit_after><|endoftext|>


<commit_before><commit_msg>Fix build.rs whitespace<commit_after><|endoftext|>


<commit_before><commit_msg>Added AsMilliseconds trait for Duration<commit_after><|endoftext|>


<commit_before>struct Point { x: i32, y: i32, z: i32 }

fn main() {
    let mut point = Point { x: 0, y: 0, z: 0 };

    {
        let borrowed_point = &point;
        let another_borrow = &point;

        // Data can be accessed via the references and the original owner
        println!("Point has coordinates: ({}, {}, {})",
                 borrowed_point.x, another_borrow.y, point.z);

        // Error! Can't borrow point as mutable because it's currently
        // borrowed as immutable.
        //let mutable_borrow = &mut point;
        // TODO ^ Try uncommenting this line

        // Immutable references go out of scope
    }

    {
        let mutable_borrow = &mut point;

        // Change data via mutable reference
        mutable_borrow.x = 5;
        mutable_borrow.y = 2;
        mutable_borrow.z = 1;

        // Error! Can't borrow `point` as immutable because it's currently
        // borrowed as mutable.
        //let y = &point.y;
        // TODO ^ Try uncommenting this line

        // Error! Can't print because `println!` takes an immutable reference.
        //println!("Point Z coordinate is {}", point.z);
        // TODO ^ Try uncommenting this line

        // Mutable reference goes out of scope
    }

    // Immutable references to point are allowed again
    println!("Point now has coordinates: ({}, {}, {})",
             point.x, point.y, point.z);
}
<commit_msg>Clarify single mutable reference vs mutliple references<commit_after>struct Point { x: i32, y: i32, z: i32 }

fn main() {
    let mut point = Point { x: 0, y: 0, z: 0 };

    {
        let borrowed_point = &point;
        let another_borrow = &point;

        // Data can be accessed via the references and the original owner
        println!("Point has coordinates: ({}, {}, {})",
                 borrowed_point.x, another_borrow.y, point.z);

        // Error! Can't borrow point as mutable because it's currently
        // borrowed as immutable.
        //let mutable_borrow = &mut point;
        // TODO ^ Try uncommenting this line

        // Immutable references go out of scope
    }

    {
        let mutable_borrow = &mut point;

        // Change data via mutable reference
        mutable_borrow.x = 5;
        mutable_borrow.y = 2;
        mutable_borrow.z = 1;

        // Error! Can't borrow `point` as immutable because it's currently
        // borrowed as mutable.
        //let y = &point.y;
        // TODO ^ Try uncommenting this line

        // Error! Can't print because `println!` takes an immutable reference.
        //println!("Point Z coordinate is {}", point.z);
        // TODO ^ Try uncommenting this line

        // Ok! Mutable references can be passed as immutable to `println!`
        println!("Point has coordinates: ({}, {}, {})",
                 mutable_borrow.x, mutable_borrow.y, mutable_borrow.z);

        // Mutable reference goes out of scope
    }

    // Immutable references to point are allowed again
    let borrowed_point = &point;
    println!("Point now has coordinates: ({}, {}, {})",
             borrowed_point.x, borrowed_point.y, borrowed_point.z);
}
<|endoftext|>


<commit_before><commit_msg>minor<commit_after><|endoftext|>


<commit_before><commit_msg>Created variables for DRY purposes<commit_after><|endoftext|>


<commit_before><commit_msg>removed example with ncurses menu<commit_after><|endoftext|>


<commit_before>extern crate piston;
extern crate graphics;
extern crate piston_window;
extern crate time;
extern crate rand;
extern crate ai_behavior;
extern crate cgmath;
extern crate opengl_graphics;

mod app;
mod entity;
mod player;
mod config;
mod person;

use player::Player;
use entity::Entity;

use piston_window::{ PistonWindow, WindowSettings };
use piston::input::*;
use piston::event_loop::*;
use opengl_graphics::*;
use graphics::{ Image, clear, default_draw_state };
use graphics::rectangle::square;
use std::path::Path;
use rand::{Rng, SeedableRng, XorShiftRng};

use cgmath::rad;
use cgmath::{ Vector2, Vector4 };
use cgmath::{ Rotation2, Basis2 };

fn transform_camera_coords(player : &Player, x : u32, y: u32, width : u32, height : u32) -> (i32, i32) {
    return (
        x as i32 - player.get_position().x as i32 + (width as f32 / 2f32) as i32 ,
        y as i32 - player.get_position().y as i32 + (height as f32 / 2f32) as i32
    );
}

fn draw_background(x: u32, y: u32, context: graphics::context::Context, gl_graphics: &mut GlGraphics, textures: &Vec<Texture>, seed: [u32;4], player : &mut Player) {
    let mut rng1: XorShiftRng = SeedableRng::from_seed(seed);
    let txt: &Texture = textures.get(0).unwrap();
    let (width, height) = txt.get_size();
    for i in 0..(x/width) + 1 {
        for j in 0..(y/height) + 1 {
            let (k, l) = transform_camera_coords(player, i, j, x, y);
            let rand = rng1.gen::<u32>() % textures.len() as u32;
            let txt: &Texture = textures.get(rand as usize).unwrap();
            let (width, height) = txt.get_size();
            let image = Image::new().rect(square((i * width) as f64, (j * height) as f64, width as f64));
            image.draw(txt, default_draw_state(), context.transform, gl_graphics);
        }
    }
}

fn main() {
    let mut rng = rand::thread_rng();
    let seed: [u32;4] = [rng.gen::<u32>(), rng.gen::<u32>(), rng.gen::<u32>(), rng.gen::<u32>()];
    let opengl = OpenGL::V3_2;
    let mut window: PistonWindow = WindowSettings::new("GGJ2016", [800, 600])
        .exit_on_esc(true)
        .opengl(opengl)
        .build()
        .unwrap_or_else(|e| { panic!("Failed to build PistonWindow: {}", e) });
    window.set_ups(60);
    let mut gl = GlGraphics::new(opengl);

    let mut app = app::App::new();

    let emoji = Texture::from_path(Path::new("assets/img/emoji/77.png")).unwrap();
    app.add_entity(Box::new(person::Person::new(emoji, Vector2::new(50.0, 50.0))));

    // Add player to entities (player instanciated in app)
    //app.add_entity(Box::new(player::Player::new()));

    let mut textures :Vec<Texture>= Vec::new();
    textures.push(Texture::from_path(Path::new("assets/img/ground/placeholder_01.jpg")).unwrap());
    textures.push(Texture::from_path(Path::new("assets/img/ground/placeholder_02.jpg")).unwrap());

    for e in window {
        if let Some(args) = e.press_args() {
            app.key_press(args);
            println!("asda");
        }

        if let Some(args) = e.update_args() {
            app.update(args);
        }

        if let Some(args) = e.render_args() {
            gl.draw(args.viewport(), |c, gl| {
                clear([0.5, 0.2, 0.9, 1.0], gl);
                draw_background(args.width, args.height, c, gl, &textures, seed, app.get_player());

                app.render(c, gl, args);
            });
        }
    }
}
<commit_msg>camera now working properly.<commit_after>extern crate piston;
extern crate graphics;
extern crate piston_window;
extern crate time;
extern crate rand;
extern crate ai_behavior;
extern crate cgmath;
extern crate opengl_graphics;

mod app;
mod entity;
mod player;
mod config;
mod person;

use player::Player;
use entity::Entity;

use piston_window::{ PistonWindow, WindowSettings };
use piston::input::*;
use piston::event_loop::*;
use opengl_graphics::*;
use graphics::{ Image, clear, default_draw_state };
use graphics::rectangle::square;
use std::path::Path;
use rand::{Rng, SeedableRng, XorShiftRng};

use cgmath::rad;
use cgmath::{ Vector2, Vector4 };
use cgmath::{ Rotation2, Basis2 };

fn transform_camera_coords(player : &Player, x : u32, y: u32, width : u32, height : u32) -> (f64, f64) {
    return (
        x as f64 - player.get_position().x as f64 + (width as f64 / 2f64) as f64 ,
        y as f64 - player.get_position().y as f64 + (height as f64 / 2f64) as f64
    );
}

fn draw_background(x: u32, y: u32, context: graphics::context::Context, gl_graphics: &mut GlGraphics, textures: &Vec<Texture>, seed: [u32;4], player : &mut Player) {
    let mut rng1: XorShiftRng = SeedableRng::from_seed(seed);
    let txt: &Texture = textures.get(0).unwrap();
    let (width, height) = txt.get_size();
    for i in 0..(x/width) + 1 {
        for j in 0..(y/height) + 1 {
            let (k, l) = transform_camera_coords(player, i, j, x, y);
            let rand = rng1.gen::<u32>() % textures.len() as u32;
            let txt: &Texture = textures.get(rand as usize).unwrap();
            let (width, height) = txt.get_size();
            let image = Image::new().rect(square((i as f64 * width as f64) as f64 + k, (j as f64 * height as f64) as f64 + l, width as f64));
            println!("({}, {}) = ({}, {})", (k * width as f64) as f64, (l * height as f64) as f64, k, l);
            image.draw(txt, default_draw_state(), context.transform, gl_graphics);
        }
    }
}

fn main() {
    let mut rng = rand::thread_rng();
    let seed: [u32;4] = [rng.gen::<u32>(), rng.gen::<u32>(), rng.gen::<u32>(), rng.gen::<u32>()];
    let opengl = OpenGL::V3_2;
    let mut window: PistonWindow = WindowSettings::new("GGJ2016", [800, 600])
        .exit_on_esc(true)
        .opengl(opengl)
        .build()
        .unwrap_or_else(|e| { panic!("Failed to build PistonWindow: {}", e) });
    window.set_ups(60);
    let mut gl = GlGraphics::new(opengl);

    let mut app = app::App::new();

    let emoji = Texture::from_path(Path::new("assets/img/emoji/77.png")).unwrap();
    app.add_entity(Box::new(person::Person::new(emoji, Vector2::new(50.0, 50.0))));

    // Add player to entities (player instanciated in app)
    //app.add_entity(Box::new(player::Player::new()));

    let mut textures :Vec<Texture>= Vec::new();
    textures.push(Texture::from_path(Path::new("assets/img/ground/placeholder_01.jpg")).unwrap());
    textures.push(Texture::from_path(Path::new("assets/img/ground/placeholder_02.jpg")).unwrap());

    for e in window {
        if let Some(args) = e.press_args() {
            app.key_press(args);
            println!("asda");
        }

        if let Some(args) = e.update_args() {
            app.update(args);
        }

        if let Some(args) = e.render_args() {
            gl.draw(args.viewport(), |c, gl| {
                clear([0.5, 0.2, 0.9, 1.0], gl);
                draw_background(args.width, args.height, c, gl, &textures, seed, app.get_player());

                app.render(c, gl, args);
            });
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Export nat literal helpers<commit_after><|endoftext|>


<commit_before><commit_msg>Add time module<commit_after>//! Information about frame timing.
//!
//! By default the engine will run at 60 fps (giving a delta of 16.667 ms), but it will change
//! its fixed framerate if necessary. For example, if the game fails to meet 60 fps, the engine
//! will throttle down to 30 fps (with a delta of 33.333 ms) until it can return to 60 fps. The
//! time delta doesn't represent the exact amount of time it took to complete the last frame,
//! rather it gives the current locked framerate for the game. Therefore, game code can be
//! written with the assumption of a fixed time step (i.e. the delta will be the same
//! frame-to-frame) even if the exact time step may occaisonally change in practice.

use std::time::Duration;

/// Returns the exact time between frames.
///
/// See module documentation for more information about frame timing.
pub fn delta() -> Duration {
    Duration::new(1, 0) / 60
}

/// Returns the current time between frames in seconds.
///
/// See module documentation for more information about frame timing.
pub fn delta_f32() -> f32 {
    1.0 / 60.0
}
<|endoftext|>


<commit_before><commit_msg>using most of space on character screen now<commit_after><|endoftext|>


<commit_before><commit_msg>Smaller MAX_OBJECTS in test cfg<commit_after><|endoftext|>


<commit_before><commit_msg>first house in the village<commit_after><|endoftext|>


<commit_before><commit_msg>Used to store the old file just in case<commit_after>extern crate sdl2;

#[derive(Debug)]
pub struct DepthPoint {
    pub x: f64,
    pub y: f64,
    pub z: f64,
    pub x_z: f64,
    pub angle_view: f64,
}

impl DepthPoint {
    pub fn new(x: f64, y: f64, z: f64) -> DepthPoint {
        DepthPoint {
            x: x,
            y: y,
            z: z,
            x_z: 0.0,
            angle_view: 0.0,
        }
    }

    pub fn sdl_point(&self) -> sdl2::rect::Point {
        sdl2::rect::Point::new((self.x as f64/self.z) as i32, (self.y as f64/self.z) as i32)
    }

    pub fn perspect_point(&mut self, w: i32, h: i32) -> sdl2::rect::Point {
        if self.z > -0.01 && self.z < 0.0 {
            self.z = 0.001
        }

        else if self.z < 0.1 { // Prevents division by nearly 0, that cause integer overflow/underflow
            self.z = 0.11;
        }

        sdl2::rect::Point::new(
            ((w as f64 * self.x as f64/self.z) + w as f64) as i32,
            ((w as f64 * self.y as f64/self.z) + h as f64) as i32)
    }

    pub fn set_x (&mut self, x: f64) {
        self.x = x;
    }

    pub fn set_y (&mut self, y: f64) {
        self.y = y;
    }

    pub fn set_z (&mut self, z: f64) {
        self.z = z;
    }

    pub fn rotate_x_y(&mut self, cx: f64, cy: f64, angle: f64) {
        use std::f64;
        let s = f64::sin(angle);
        let c = f64::cos(angle);

        self.x -= cx;
        self.y -= cy;

        let new_x = self.x * c - self.y * s;
        let new_y = self.x * s + self.y * c;

        self.x = new_x + cx;
        self.y = new_y + cy;
    }

    pub fn rotate_x_z(&mut self, cx: f64, cz: f64, angle: f64) {
        use std::f64;
        let s = f64::sin(angle);
        let c = f64::cos(angle);

        self.x -= cx;
        self.z -= cz;

        let new_x = self.x * c - self.z * s;
        let new_z = self.x * s + self.z * c;

        self.x = new_x + cx;
        self.z = new_z + cz;
        self.x_z += angle;

        let angle_view = (f64::atan2(cx - self.x, cz - self.z) * 180.0 / f64::consts::PI);

        self.angle_view = angle_view;

    }

    pub fn rotate_y_z(&mut self, cy: f64, cz: f64, angle: f64) {
        use std::f64;
        let s = f64::sin(angle);
        let c = f64::cos(angle);

        self.y -= cy;
        self.z -= cz;

        let new_y = self.y * c - self.z * s;
        let new_z = self.y * s + self.z * c;

        self.y = new_y + cy;
        self.z = new_z + cz;
    }

    pub fn clone(&self) -> DepthPoint {
        DepthPoint {
            x: self.x,
            y: self.y,
            z: self.z,
            x_z: self.x_z,
            angle_view: self.angle_view,
        }
    }
}
#[derive(Debug)]
pub struct Square {
    pub points: Vec<DepthPoint>,
    pub x: f64,
    pub y: f64,
    pub z: f64,
    pub angle_view: f64,
}

impl Square {
    pub fn new(p1: DepthPoint, p2: DepthPoint, p3: DepthPoint, p4: DepthPoint) -> Square {
        Square {
            points: vec![p1, p2, p3, p4],
            x: 0.0,
            y: 0.0,
            z: 0.0,
            angle_view: 0.0,
        }
    }

    pub fn flat(&mut self, w: i32, h: i32, renderer: &mut sdl2::render::Renderer, cx: f64, cy: f64, cz: f64) {
        let mut return_buffer = Vec::<sdl2::rect::Point>::new();
        for point in &mut self.points {
            use std::f64;
            let point_x = point.x;
            let point_y = point.y;
            let point_z = point.z;

            point.set_x(point_x+self.x);
            point.set_y(point_y+self.y);
            point.set_z(point_z+self.z);

            let pers_point = point.perspect_point(w, h);

            if !(point.angle_view < 100.0 && point.angle_view > 0.0
            || point.angle_view < 0.0 && point.angle_view > -100.0)  {
                return_buffer.push(pers_point);
            }
            /* CAUSES A COOL BUG WHEN UNCOMMENTED! I RECOMMEND TRYING IT OUT.
            * Bug itself happens because the points position doesn't get reset when i just jump out to the next point in the loop.
            else {
                continue;
            }
            */

            point.set_x(point_x);
            point.set_y(point_y);
            point.set_z(point_z);
        }

        let point_x = self.points[0].x;
        let point_y = self.points[0].y;
        let point_z = self.points[0].z;

        self.points[0].set_x(point_x+self.x);
        self.points[0].set_y(point_y+self.y);
        self.points[0].set_z(point_z+self.z);

        return_buffer.push(self.points[0].perspect_point(w, h));
        renderer.draw_lines(&return_buffer);

        self.points[0].set_x(point_x);
        self.points[0].set_y(point_y);
        self.points[0].set_z(point_z);
    }

    pub fn set_x (&mut self, x: f64) {
        self.x = x;
    }

    pub fn set_y (&mut self, y: f64) {
        self.y = y;
    }

    pub fn set_z (&mut self, z: f64) {
        self.z = z;
    }
}

#[derive(Debug)]
pub struct Cube {
    pub faces: Vec<Square>,
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

impl Cube {
    pub fn new(p1: Square, p2: Square, p3: Square, p4: Square) -> Cube {
        Cube {
            faces: vec![p1, p2, p3, p4],
            x: 0.0,
            y: 0.0,
            z: 0.0,
        }
    }

    pub fn gen_new(x: f64, y: f64, z:f64, x_s: f64, y_s: f64, z_s:f64) -> Cube {
        let face1 = Square::new(DepthPoint::new(x_s, y_s, z_s),
                                DepthPoint::new(-x_s, y_s, z_s),
                                DepthPoint::new(-x_s, -y_s, z_s),
                                DepthPoint::new(x_s, -y_s, z_s));

        let face2 = Square::new(DepthPoint::new(x_s, y_s, -z_s),
                                DepthPoint::new(x_s, -y_s, -z_s),
                                DepthPoint::new(x_s, -y_s, z_s),
                                DepthPoint::new(x_s, y_s, z_s));

        let face3 = Square::new(DepthPoint::new(x_s, y_s, -z_s),
                                DepthPoint::new(-x_s, y_s, -z_s),
                                DepthPoint::new(-x_s, -y_s, -z_s),
                                DepthPoint::new(x_s, -y_s, -z_s));

        let face4 = Square::new(DepthPoint::new(-x_s, -y_s, -z_s),
                                DepthPoint::new(-x_s, y_s, -z_s),
                                DepthPoint::new(-x_s, y_s, z_s),
                                DepthPoint::new(-x_s, -y_s, z_s));

        Cube {
            faces: vec![face1, face2, face3, face4],
            x: x,
            y: y,
            z: z,
        }
    }

    pub fn flat(&mut self, w: i32, h: i32, renderer: &mut sdl2::render::Renderer, cx: f64, cy: f64, cz: f64, cxy: f64, cxz: f64, cyz: f64) {
        for face in &mut self.faces {
            let self_x = self.x;
            let self_y = self.y;
            let self_z = self.z;

            self.x += cx;
            self.y += cy;
            self.z += cz;

            for point in &mut face.points {
                    //let point_x = point.x;
                    //let point_y = point.y;
                    //let point_z = point.z;
                    point.rotate_y_z((-cy + -self_y), (-cz + -self_z), cyz);
                    point.rotate_x_z((-cx + -self_x), (-cz + -self_z), cxz);
                    point.rotate_x_y((-cx + -self_x), (-cy + -self_y), cxy);
            }

            let face_x = face.x;
            let face_y = face.y;
            let face_z = face.z;

            face.set_x(face_x+self.x);
            face.set_y(face_y+self.y);
            face.set_z(face_z+self.z);

            let flat = face.flat(w, h, renderer, cx, cy, cz);

            face.set_x(face_x);
            face.set_y(face_y);
            face.set_z(face_z);

            self.x = self_x;
            self.y = self_y;
            self.z = self_z;
        }
    }
}

pub struct Lines {
    pub lines: Vec<[DepthPoint; 2]>,
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

impl Lines {
    pub fn new(line_vec: Vec<[DepthPoint; 2]>) -> Lines {
        Lines {
            lines: line_vec,
            x: 0.0,
            y: 0.0,
            z: 0.0,
        }
    }

    pub fn flat(&mut self, w: i32, h: i32, renderer: &mut sdl2::render::Renderer,
                           cx: f64, cy: f64, cz: f64,
                           cxy: f64, cxz: f64, cyz: f64,
                           draw: bool) {
        for line in &mut self.lines {
            // Apply rotations
            let self_x = self.x;
            let self_y = self.y;
            let self_z = self.z;

            self.x += cx;
            self.y += cy;
            self.z += cz;

            line[0].rotate_y_z((-cy + -self_y), (-cz + -self_z), cyz);
            line[0].rotate_x_z((-cx + -self_x), (-cz + -self_z), cxz);
            line[0].rotate_x_y((-cx + -self_x), (-cy + -self_y), cxy);

            line[1].rotate_y_z((-cy + -self_y), (-cz + -self_z), cyz);
            line[1].rotate_x_z((-cx + -self_x), (-cz + -self_z), cxz);
            line[1].rotate_x_y((-cx + -self_x), (-cy + -self_y), cxy);

            if !(line[0].angle_view < 100.0 && line[0].angle_view > 0.0
            || line[0].angle_view < 0.0 && line[0].angle_view > -100.0) {
                // Grab all the positions because Rust doesn't allow for a method
                // to take its instances class variable as an argument
                let mut line_begin_x = line[0].x;
                let mut line_begin_y = line[0].y;
                let mut line_begin_z = line[0].z;

                let mut line_end_x = line[1].x;
                let mut line_end_y = line[1].y;
                let mut line_end_z = line[1].z;

                line[0].x = line_begin_x + self.x;
                line[0].y = line_begin_y + self.y;
                line[0].z = line_begin_z + self.z;

                line[1].x = line_end_x + self.x;
                line[1].y = line_end_y + self.y;
                line[1].z = line_end_z + self.z;

                // Generate 2d lines.
                let line_begin = line[0].perspect_point(w, h);
                //println!("{:?}", line_begin);
                let line_end = line[1].perspect_point(w, h);
                if draw {renderer.draw_lines(&[line_begin, line_end]);};

                line[0].x = line_begin_x;
                line[0].y = line_begin_y;
                line[0].z = line_begin_z;

                line[1].x = line_end_x;
                line[1].y = line_end_y;
                line[1].z = line_end_z;

                self.x = self_x;
                self.y = self_y;
                self.z = self_z;
            }

            // Set points' positions back to the ones they had before.
            self.x = self_x;
            self.y = self_y;
            self.z = self_z;
        }
    }
}

pub struct Triangle {
    pub points: [DepthPoint; 3],
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

impl Triangle {
    pub fn new(p1: DepthPoint, p2: DepthPoint, p3: DepthPoint) -> Triangle {
        Triangle {
            points: [p1, p2, p3],
            x: 0.0,
            y: 0.0,
            z: 0.0,
        }
    }

    pub fn flat(&mut self, w: i32, h: i32, renderer: &mut sdl2::render::Renderer,
                           cx: f64, cy: f64, cz: f64,
                           cxy: f64, cxz: f64, cyz: f64,
                           draw: bool)
    {

        //println!("{:?}", self.points[0].perspect_point(w, h).x());
        //MOST PROBABLY USELESS MEMORY REALLOCATIONS, BUT SUCH IS LIFE.
        let mut lines = Lines::new(vec![[self.points[0].clone(), self.points[1].clone()],
                                        [self.points[1].clone(), self.points[2].clone()],
                                        [self.points[2].clone(), self.points[0].clone()],]);

        lines.flat(w, h, renderer,
                   cx, cy, cz,
                   cxy, cxz, cyz,
                   draw);

        self.points = [lines.lines[0][0].clone(), lines.lines[1][0].clone(), lines.lines[2][0].clone()];
    }

    pub fn fill_bottom_flat(&mut self, w: i32, h: i32, renderer: &mut sdl2::render::Renderer,
                            cx: f64, cy: f64, cz: f64,
                            cxy: f64, cxz: f64, cyz: f64)
    {
        let mut largest_y = -2147483648; // used value from someone gave on irc because std::i32::MIN wasnt feeling like working at the moment
        let mut largest_index = 0 as usize;

        let p1 = self.points[0].clone();
        let p2 = self.points[1].clone();
        let p3 = self.points[2].clone();

        let mut iterator = 0;
        let mut sdl_points: [sdl2::rect::Point; 3] = [sdl2::rect::Point::new(0, 0); 3];

        for point in &mut [p1, p2, p3] {
            // Apply rotations
            let self_x = self.x;
            let self_y = self.y;
            let self_z = self.z;

            self.x += cx;
            self.y += cy;
            self.z += cz;

            point.rotate_y_z((-cy + -self_y), (-cz + -self_z), cyz);
            point.rotate_x_z((-cx + -self_x), (-cz + -self_z), cxz);
            point.rotate_x_y((-cx + -self_x), (-cy + -self_y), cxy);

            if !(point.angle_view < 100.0 && point.angle_view > 0.0
            || point.angle_view < 0.0 && point.angle_view > -100.0) {
                // Grab all the positions because Rust doesn't allow for a method
                // to take its instances class variable as an argument
                let mut point_x = point.x;
                let mut point_y = point.y;
                let mut point_z = point.z;

                point.x = point_x + self.x;
                point.y = point_y + self.y;
                point.z = point_z + self.z;

                // Generate 2d lines.
                let perspect_point = point.perspect_point(w, h);
                //println!("{:?}", perspect_point);
                sdl_points[iterator] = perspect_point;

                point.x = point_x;
                point.y = point_y;
                point.z = point_z;
                self.x = self_x;
                self.y = self_y;
                self.z = self_z;
            }

            // Set points' positions back to the ones they had before.
            self.x = self_x;
            self.y = self_y;
            self.z = self_z;

            iterator += 1;
        }

        //println!("{:?}", sdl_points);

        let flat_p1 = sdl_points[0];
        let flat_p2 = sdl_points[1];
        let flat_p3 = sdl_points[2];

        //println!("{:?}", self.points[0].perspect_point(w, h).x());

        let mut top: sdl2::rect::Point;
        let mut left: sdl2::rect::Point;
        let mut right: sdl2::rect::Point;

        // find top, left, and right.

        let points = [flat_p1, flat_p2, flat_p3];
        let top = points.iter().max_by_key(|p| -p.y()).unwrap().clone();
        let left = points.iter().max_by_key(|p| -p.x()).unwrap().clone();
        let right = points.iter().max_by_key(|p| p.x()).unwrap().clone();

        if (left.y() - top.y()) != 0 && (right.y() - top.y()) != 0 {
            let left_slope = -(left.x() - top.x()) as f64 / (left.y() - top.y()) as f64;
            let right_slope = -(right.x() - top.x()) as f64 / (right.y() - top.y()) as f64;

            for i in 0..left.y() - top.y() {
                renderer.draw_line(sdl2::rect::Point::new(right.x() + (right_slope * i as f64) as i32, right.y() - i),
                                   sdl2::rect::Point::new(left.x() + (left_slope * i as f64) as i32, left.y() - i));
            }
            println!("{:?} {:?}", left_slope, right_slope);
        }
    }

    pub fn fill_top_flat(&mut self, w: i32, h: i32, renderer: &mut sdl2::render::Renderer,
                            cx: f64, cy: f64, cz: f64,
                            cxy: f64, cxz: f64, cyz: f64)
    {
        let mut largest_y = -2147483648; // used value from someone gave on irc because std::i32::MIN wasnt feeling like working at the moment
        let mut largest_index = 0 as usize;

        let p1 = self.points[0].clone();
        let p2 = self.points[1].clone();
        let p3 = self.points[2].clone();

        let mut iterator = 0;
        let mut sdl_points: [sdl2::rect::Point; 3] = [sdl2::rect::Point::new(0, 0); 3];

        for point in &mut [p1, p2, p3] {
            // Apply rotations
            let self_x = self.x;
            let self_y = self.y;
            let self_z = self.z;

            self.x += cx;
            self.y += cy;
            self.z += cz;

            point.rotate_y_z((-cy + -self_y), (-cz + -self_z), cyz);
            point.rotate_x_z((-cx + -self_x), (-cz + -self_z), cxz);
            point.rotate_x_y((-cx + -self_x), (-cy + -self_y), cxy);

            if !(point.angle_view < 100.0 && point.angle_view > 0.0
            || point.angle_view < 0.0 && point.angle_view > -100.0) {
                // Grab all the positions because Rust doesn't allow for a method
                // to take its instances class variable as an argument
                let mut point_x = point.x;
                let mut point_y = point.y;
                let mut point_z = point.z;

                point.x = point_x + self.x;
                point.y = point_y + self.y;
                point.z = point_z + self.z;

                // Generate 2d lines.
                let perspect_point = point.perspect_point(w, h);
                //println!("{:?}", perspect_point);
                sdl_points[iterator] = perspect_point;

                point.x = point_x;
                point.y = point_y;
                point.z = point_z;
                self.x = self_x;
                self.y = self_y;
                self.z = self_z;
            }

            // Set points' positions back to the ones they had before.
            self.x = self_x;
            self.y = self_y;
            self.z = self_z;

            iterator += 1;
        }

        //println!("{:?}", sdl_points);

        let flat_p1 = sdl_points[0];
        let flat_p2 = sdl_points[1];
        let flat_p3 = sdl_points[2];

        //println!("{:?}", self.points[0].perspect_point(w, h).x());

        let mut top: sdl2::rect::Point;
        let mut left: sdl2::rect::Point;
        let mut right: sdl2::rect::Point;

        // find top, left, and right.

        let points = [flat_p1, flat_p2, flat_p3];
        let top = points.iter().max_by_key(|p| p.y()).unwrap().clone();
        let left = points.iter().max_by_key(|p| -p.x()).unwrap().clone();
        let right = points.iter().max_by_key(|p| p.x()).unwrap().clone();

        if (left.y() - top.y()) != 0 && (right.y() - top.y()) != 0 {
            let left_slope = -(left.x() - top.x()) as f64 / (left.y() - top.y()) as f64;
            let right_slope = -(right.x() - top.x()) as f64 / (right.y() - top.y()) as f64;

            for i in 0..top.y() - left.y() {
                renderer.draw_line(sdl2::rect::Point::new(right.x() + (right_slope * -i as f64) as i32, right.y() + i),
                                   sdl2::rect::Point::new(left.x() + (left_slope * -i as f64) as i32, left.y() + i));
            }
            println!("{:?} {:?}", left_slope, right_slope);
        }
    }
}<|endoftext|>


<commit_before>// Copyright 2015 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.

use syntax::ast;
use syntax::codemap::{self, CodeMap, Span, BytePos};
use syntax::visit;
use syntax::parse::{token, parser};
use std::path::PathBuf;

use utils;
use config::Config;

use changes::ChangeSet;
use rewrite::{Rewrite, RewriteContext};

pub struct FmtVisitor<'a> {
    pub codemap: &'a CodeMap,
    pub changes: ChangeSet<'a>,
    pub last_pos: BytePos,
    // TODO RAII util for indenting
    pub block_indent: usize,
    pub config: &'a Config,
}

impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> {
    fn visit_expr(&mut self, ex: &'v ast::Expr) {
        debug!("visit_expr: {:?} {:?}",
               self.codemap.lookup_char_pos(ex.span.lo),
               self.codemap.lookup_char_pos(ex.span.hi));
        self.format_missing(ex.span.lo);
        let offset = self.changes.cur_offset_span(ex.span);
        let context = RewriteContext {
            codemap: self.codemap,
            config: self.config,
            block_indent: self.block_indent,
        };
        let rewrite = ex.rewrite(&context, self.config.max_width - offset, offset);

        if let Some(new_str) = rewrite {
            self.changes.push_str_span(ex.span, &new_str);
            self.last_pos = ex.span.hi;
        }
    }

    fn visit_stmt(&mut self, stmt: &'v ast::Stmt) {
        // If the stmt is actually an item, then we'll handle any missing spans
        // there. This is important because of annotations.
        // Although it might make more sense for the statement span to include
        // any annotations on the item.
        let skip_missing = match stmt.node {
            ast::Stmt_::StmtDecl(ref decl, _) => {
                match decl.node {
                    ast::Decl_::DeclItem(_) => true,
                    _ => false,
                }
            }
            _ => false,
        };
        if !skip_missing {
            self.format_missing_with_indent(stmt.span.lo);
        }
        visit::walk_stmt(self, stmt);
    }

    fn visit_block(&mut self, b: &'v ast::Block) {
        debug!("visit_block: {:?} {:?}",
               self.codemap.lookup_char_pos(b.span.lo),
               self.codemap.lookup_char_pos(b.span.hi));
        self.format_missing(b.span.lo);

        self.changes.push_str_span(b.span, "{");
        self.last_pos = self.last_pos + BytePos(1);
        self.block_indent += self.config.tab_spaces;

        for stmt in &b.stmts {
            self.visit_stmt(&stmt)
        }
        match b.expr {
            Some(ref e) => {
                self.format_missing_with_indent(e.span.lo);
                self.visit_expr(e);
            }
            None => {}
        }

        self.block_indent -= self.config.tab_spaces;
        // TODO we should compress any newlines here to just one
        self.format_missing_with_indent(b.span.hi - BytePos(1));
        self.changes.push_str_span(b.span, "}");
        self.last_pos = b.span.hi;
    }

    // Note that this only gets called for function definitions. Required methods
    // on traits do not get handled here.
    fn visit_fn(&mut self,
                fk: visit::FnKind<'v>,
                fd: &'v ast::FnDecl,
                b: &'v ast::Block,
                s: Span,
                _: ast::NodeId) {
        self.format_missing_with_indent(s.lo);
        self.last_pos = s.lo;

        let indent = self.block_indent;
        match fk {
            visit::FkItemFn(ident,
                            ref generics,
                            ref unsafety,
                            ref constness,
                            ref abi,
                            vis) => {
                let new_fn = self.rewrite_fn(indent,
                                             ident,
                                             fd,
                                             None,
                                             generics,
                                             unsafety,
                                             constness,
                                             abi,
                                             vis,
                                             codemap::mk_sp(s.lo, b.span.lo));
                self.changes.push_str_span(s, &new_fn);
            }
            visit::FkMethod(ident, ref sig, vis) => {
                let new_fn = self.rewrite_fn(indent,
                                             ident,
                                             fd,
                                             Some(&sig.explicit_self),
                                             &sig.generics,
                                             &sig.unsafety,
                                             &sig.constness,
                                             &sig.abi,
                                             vis.unwrap_or(ast::Visibility::Inherited),
                                             codemap::mk_sp(s.lo, b.span.lo));
                self.changes.push_str_span(s, &new_fn);
            }
            visit::FkFnBlock(..) => {}
        }

        self.last_pos = b.span.lo;
        self.visit_block(b)
    }

    fn visit_item(&mut self, item: &'v ast::Item) {
        // Don't look at attributes for modules.
        // We want to avoid looking at attributes in another file, which the AST
        // doesn't distinguish. FIXME This is overly conservative and means we miss
        // attributes on inline modules.
        match item.node {
            ast::Item_::ItemMod(_) => {}
            _ => {
                if self.visit_attrs(&item.attrs) {
                    return;
                }
            }
        }

        match item.node {
            ast::Item_::ItemUse(ref vp) => {
                let vis = utils::format_visibility(item.vis);
                let offset = self.block_indent + vis.len() + "use ".len();
                let context = RewriteContext {
                    codemap: self.codemap, config: self.config, block_indent: self.block_indent };
                // 1 = ";"
                match vp.rewrite(&context, self.config.max_width - offset - 1, offset) {
                    Some(ref s) if s.len() == 0 => {
                        // Format up to last newline
                        let span = codemap::mk_sp(self.last_pos, item.span.lo);
                        let span_end = match self.snippet(span).rfind('\n') {
                            Some(offset) => self.last_pos + BytePos(offset as u32),
                            None => item.span.lo
                        };
                        self.format_missing(span_end);
                        self.last_pos = item.span.hi;
                    }
                    Some(ref s) => {
                        let s = format!("{}use {};", vis, s);
                        self.format_missing_with_indent(item.span.lo);
                        self.changes.push_str_span(item.span, &s);
                        self.last_pos = item.span.hi;
                    }
                    None => {
                        self.format_missing_with_indent(item.span.lo);
                    }
                }
                visit::walk_item(self, item);
            }
            ast::Item_::ItemImpl(..) |
            ast::Item_::ItemTrait(..) => {
                self.block_indent += self.config.tab_spaces;
                visit::walk_item(self, item);
                self.block_indent -= self.config.tab_spaces;
            }
            ast::Item_::ItemExternCrate(_) => {
                self.format_missing_with_indent(item.span.lo);
                let new_str = self.snippet(item.span);
                self.changes.push_str_span(item.span, &new_str);
                self.last_pos = item.span.hi;
            }
            ast::Item_::ItemStruct(ref def, ref generics) => {
                self.format_missing_with_indent(item.span.lo);
                self.visit_struct(item.ident,
                                  item.vis,
                                  def,
                                  generics,
                                  item.span);
                self.last_pos = item.span.hi;
            }
            ast::Item_::ItemEnum(ref def, ref generics) => {
                self.format_missing_with_indent(item.span.lo);
                self.visit_enum(item.ident,
                                item.vis,
                                def,
                                generics,
                                item.span);
                self.last_pos = item.span.hi;
            }
            ast::Item_::ItemMod(ref module) => {
                self.format_missing_with_indent(item.span.lo);
                self.format_mod(module, item.span, item.ident, &item.attrs);
            }
            _ => {
                visit::walk_item(self, item);
            }
        }
    }

    fn visit_trait_item(&mut self, ti: &'v ast::TraitItem) {
        if self.visit_attrs(&ti.attrs) {
            return;
        }

        if let ast::TraitItem_::MethodTraitItem(ref sig, None) = ti.node {
            self.format_missing_with_indent(ti.span.lo);

            let indent = self.block_indent;
            let new_fn = self.rewrite_required_fn(indent,
                                                  ti.ident,
                                                  sig,
                                                  ti.span);

            self.changes.push_str_span(ti.span, &new_fn);
            self.last_pos = ti.span.hi;
        }
        // TODO format trait types

        visit::walk_trait_item(self, ti)
    }

    fn visit_impl_item(&mut self, ii: &'v ast::ImplItem) {
        if self.visit_attrs(&ii.attrs) {
            return;
        }
        visit::walk_impl_item(self, ii)
    }

    fn visit_mac(&mut self, mac: &'v ast::Mac) {
        visit::walk_mac(self, mac)
    }

    fn visit_mod(&mut self, m: &'v ast::Mod, s: Span, _: ast::NodeId) {
        // This is only called for the root module
        let filename = self.codemap.span_to_filename(s);
        self.format_separate_mod(m, &filename);
    }
}

impl<'a> FmtVisitor<'a> {
    pub fn from_codemap<'b>(codemap: &'b CodeMap, config: &'b Config) -> FmtVisitor<'b> {
        FmtVisitor {
            codemap: codemap,
            changes: ChangeSet::from_codemap(codemap),
            last_pos: BytePos(0),
            block_indent: 0,
            config: config,
        }
    }

    pub fn snippet(&self, span: Span) -> String {
        match self.codemap.span_to_snippet(span) {
            Ok(s) => s,
            Err(_) => {
                println!("Couldn't make snippet for span {:?}->{:?}",
                         self.codemap.lookup_char_pos(span.lo),
                         self.codemap.lookup_char_pos(span.hi));
                "".to_owned()
            }
        }
    }

    // Returns true if we should skip the following item.
    pub fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
        if attrs.len() == 0 {
            return false;
        }

        let first = &attrs[0];
        self.format_missing_with_indent(first.span.lo);

        if utils::contains_skip(attrs) {
            true
        } else {
            let rewrite = self.rewrite_attrs(attrs, self.block_indent);
            self.changes.push_str_span(first.span, &rewrite);
            let last = attrs.last().unwrap();
            self.last_pos = last.span.hi;
            false
        }
    }

    pub fn rewrite_attrs(&self, attrs: &[ast::Attribute], indent: usize) -> String {
        let mut result = String::new();
        let indent = utils::make_indent(indent);

        for (i, a) in attrs.iter().enumerate() {
            let a_str = self.snippet(a.span);

            if i > 0 {
                let comment = self.snippet(codemap::mk_sp(attrs[i-1].span.hi, a.span.lo));
                // This particular horror show is to preserve line breaks in between doc
                // comments. An alternative would be to force such line breaks to start
                // with the usual doc comment token.
                let multi_line = a_str.starts_with("//") && comment.matches('\n').count() > 1;
                let comment = comment.trim();
                if comment.len() > 0 {
                    result.push_str(&indent);
                    result.push_str(comment);
                    result.push('\n');
                } else if multi_line {
                    result.push('\n');
                }
                result.push_str(&indent);
            }

            result.push_str(&a_str);

            if i < attrs.len() - 1 {
                result.push('\n');
            }
        }

        result
    }

    fn format_mod(&mut self, m: &ast::Mod, s: Span, ident: ast::Ident, attrs: &[ast::Attribute]) {
        debug!("FmtVisitor::format_mod: ident: {:?}, span: {:?}", ident, s);

        // Decide whether this is an inline mod or an external mod.
        let local_file_name = self.codemap.span_to_filename(s);
        let is_internal = local_file_name == self.codemap.span_to_filename(m.inner);

        // TODO Should rewrite properly `mod X;`

        if is_internal {
            debug!("FmtVisitor::format_mod: internal mod");
            self.block_indent += self.config.tab_spaces;
            visit::walk_mod(self, m);
            debug!("... last_pos after: {:?}", self.last_pos);
            self.block_indent -= self.config.tab_spaces;
        } else {
            debug!("FmtVisitor::format_mod: external mod");
            let file_path = self.module_file(ident, attrs, local_file_name);
            let filename = file_path.to_str().unwrap();
            if self.changes.is_changed(filename) {
                // The file has already been reformatted, do nothing
            } else {
                self.format_separate_mod(m, filename);
            }
        }

        debug!("FmtVisitor::format_mod: exit");
    }

    /// Find the file corresponding to an external mod
    fn module_file(&self, id: ast::Ident, attrs: &[ast::Attribute], filename: String) -> PathBuf {
        let dir_path = {
            let mut path = PathBuf::from(&filename);
            path.pop();
            path
        };

        if let Some(path) = parser::Parser::submod_path_from_attr(attrs, &dir_path) {
            return path;
        }

        match parser::Parser::default_submod_path(id, &dir_path, &self.codemap).result {
            Ok(parser::ModulePathSuccess { path, .. }) => path,
            _ => panic!("Couldn't find module {}", token::get_ident(id))
        }
    }

    /// Format the content of a module into a separate file
    fn format_separate_mod(&mut self, m: &ast::Mod, filename: &str) {
        let last_pos = self.last_pos;
        let block_indent = self.block_indent;
        let filemap = self.codemap.get_filemap(filename);
        self.last_pos = filemap.start_pos;
        self.block_indent = 0;
        visit::walk_mod(self, m);
        self.format_missing(filemap.end_pos);
        self.last_pos = last_pos;
        self.block_indent = block_indent;
    }
}
<commit_msg>Add a helper method to format imports<commit_after>// Copyright 2015 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.

use syntax::ast;
use syntax::codemap::{self, CodeMap, Span, BytePos};
use syntax::visit;
use syntax::parse::{token, parser};
use std::path::PathBuf;

use utils;
use config::Config;

use changes::ChangeSet;
use rewrite::{Rewrite, RewriteContext};

pub struct FmtVisitor<'a> {
    pub codemap: &'a CodeMap,
    pub changes: ChangeSet<'a>,
    pub last_pos: BytePos,
    // TODO RAII util for indenting
    pub block_indent: usize,
    pub config: &'a Config,
}

impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> {
    fn visit_expr(&mut self, ex: &'v ast::Expr) {
        debug!("visit_expr: {:?} {:?}",
               self.codemap.lookup_char_pos(ex.span.lo),
               self.codemap.lookup_char_pos(ex.span.hi));
        self.format_missing(ex.span.lo);
        let offset = self.changes.cur_offset_span(ex.span);
        let context = RewriteContext {
            codemap: self.codemap,
            config: self.config,
            block_indent: self.block_indent,
        };
        let rewrite = ex.rewrite(&context, self.config.max_width - offset, offset);

        if let Some(new_str) = rewrite {
            self.changes.push_str_span(ex.span, &new_str);
            self.last_pos = ex.span.hi;
        }
    }

    fn visit_stmt(&mut self, stmt: &'v ast::Stmt) {
        // If the stmt is actually an item, then we'll handle any missing spans
        // there. This is important because of annotations.
        // Although it might make more sense for the statement span to include
        // any annotations on the item.
        let skip_missing = match stmt.node {
            ast::Stmt_::StmtDecl(ref decl, _) => {
                match decl.node {
                    ast::Decl_::DeclItem(_) => true,
                    _ => false,
                }
            }
            _ => false,
        };
        if !skip_missing {
            self.format_missing_with_indent(stmt.span.lo);
        }
        visit::walk_stmt(self, stmt);
    }

    fn visit_block(&mut self, b: &'v ast::Block) {
        debug!("visit_block: {:?} {:?}",
               self.codemap.lookup_char_pos(b.span.lo),
               self.codemap.lookup_char_pos(b.span.hi));
        self.format_missing(b.span.lo);

        self.changes.push_str_span(b.span, "{");
        self.last_pos = self.last_pos + BytePos(1);
        self.block_indent += self.config.tab_spaces;

        for stmt in &b.stmts {
            self.visit_stmt(&stmt)
        }
        match b.expr {
            Some(ref e) => {
                self.format_missing_with_indent(e.span.lo);
                self.visit_expr(e);
            }
            None => {}
        }

        self.block_indent -= self.config.tab_spaces;
        // TODO we should compress any newlines here to just one
        self.format_missing_with_indent(b.span.hi - BytePos(1));
        self.changes.push_str_span(b.span, "}");
        self.last_pos = b.span.hi;
    }

    // Note that this only gets called for function definitions. Required methods
    // on traits do not get handled here.
    fn visit_fn(&mut self,
                fk: visit::FnKind<'v>,
                fd: &'v ast::FnDecl,
                b: &'v ast::Block,
                s: Span,
                _: ast::NodeId) {
        self.format_missing_with_indent(s.lo);
        self.last_pos = s.lo;

        let indent = self.block_indent;
        match fk {
            visit::FkItemFn(ident,
                            ref generics,
                            ref unsafety,
                            ref constness,
                            ref abi,
                            vis) => {
                let new_fn = self.rewrite_fn(indent,
                                             ident,
                                             fd,
                                             None,
                                             generics,
                                             unsafety,
                                             constness,
                                             abi,
                                             vis,
                                             codemap::mk_sp(s.lo, b.span.lo));
                self.changes.push_str_span(s, &new_fn);
            }
            visit::FkMethod(ident, ref sig, vis) => {
                let new_fn = self.rewrite_fn(indent,
                                             ident,
                                             fd,
                                             Some(&sig.explicit_self),
                                             &sig.generics,
                                             &sig.unsafety,
                                             &sig.constness,
                                             &sig.abi,
                                             vis.unwrap_or(ast::Visibility::Inherited),
                                             codemap::mk_sp(s.lo, b.span.lo));
                self.changes.push_str_span(s, &new_fn);
            }
            visit::FkFnBlock(..) => {}
        }

        self.last_pos = b.span.lo;
        self.visit_block(b)
    }

    fn visit_item(&mut self, item: &'v ast::Item) {
        // Don't look at attributes for modules.
        // We want to avoid looking at attributes in another file, which the AST
        // doesn't distinguish. FIXME This is overly conservative and means we miss
        // attributes on inline modules.
        match item.node {
            ast::Item_::ItemMod(_) => {}
            _ => {
                if self.visit_attrs(&item.attrs) {
                    return;
                }
            }
        }

        match item.node {
            ast::Item_::ItemUse(ref vp) => {
                self.format_import(item.vis, vp, item.span);
            }
            ast::Item_::ItemImpl(..) |
            ast::Item_::ItemTrait(..) => {
                self.block_indent += self.config.tab_spaces;
                visit::walk_item(self, item);
                self.block_indent -= self.config.tab_spaces;
            }
            ast::Item_::ItemExternCrate(_) => {
                self.format_missing_with_indent(item.span.lo);
                let new_str = self.snippet(item.span);
                self.changes.push_str_span(item.span, &new_str);
                self.last_pos = item.span.hi;
            }
            ast::Item_::ItemStruct(ref def, ref generics) => {
                self.format_missing_with_indent(item.span.lo);
                self.visit_struct(item.ident,
                                  item.vis,
                                  def,
                                  generics,
                                  item.span);
            }
            ast::Item_::ItemEnum(ref def, ref generics) => {
                self.format_missing_with_indent(item.span.lo);
                self.visit_enum(item.ident,
                                item.vis,
                                def,
                                generics,
                                item.span);
                self.last_pos = item.span.hi;
            }
            ast::Item_::ItemMod(ref module) => {
                self.format_missing_with_indent(item.span.lo);
                self.format_mod(module, item.span, item.ident, &item.attrs);
            }
            _ => {
                visit::walk_item(self, item);
            }
        }
    }

    fn visit_trait_item(&mut self, ti: &'v ast::TraitItem) {
        if self.visit_attrs(&ti.attrs) {
            return;
        }

        if let ast::TraitItem_::MethodTraitItem(ref sig, None) = ti.node {
            self.format_missing_with_indent(ti.span.lo);

            let indent = self.block_indent;
            let new_fn = self.rewrite_required_fn(indent,
                                                  ti.ident,
                                                  sig,
                                                  ti.span);

            self.changes.push_str_span(ti.span, &new_fn);
            self.last_pos = ti.span.hi;
        }
        // TODO format trait types

        visit::walk_trait_item(self, ti)
    }

    fn visit_impl_item(&mut self, ii: &'v ast::ImplItem) {
        if self.visit_attrs(&ii.attrs) {
            return;
        }
        visit::walk_impl_item(self, ii)
    }

    fn visit_mac(&mut self, mac: &'v ast::Mac) {
        visit::walk_mac(self, mac)
    }

    fn visit_mod(&mut self, m: &'v ast::Mod, s: Span, _: ast::NodeId) {
        // This is only called for the root module
        let filename = self.codemap.span_to_filename(s);
        self.format_separate_mod(m, &filename);
    }
}

impl<'a> FmtVisitor<'a> {
    pub fn from_codemap<'b>(codemap: &'b CodeMap, config: &'b Config) -> FmtVisitor<'b> {
        FmtVisitor {
            codemap: codemap,
            changes: ChangeSet::from_codemap(codemap),
            last_pos: BytePos(0),
            block_indent: 0,
            config: config,
        }
    }

    pub fn snippet(&self, span: Span) -> String {
        match self.codemap.span_to_snippet(span) {
            Ok(s) => s,
            Err(_) => {
                println!("Couldn't make snippet for span {:?}->{:?}",
                         self.codemap.lookup_char_pos(span.lo),
                         self.codemap.lookup_char_pos(span.hi));
                "".to_owned()
            }
        }
    }

    // Returns true if we should skip the following item.
    pub fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
        if attrs.len() == 0 {
            return false;
        }

        let first = &attrs[0];
        self.format_missing_with_indent(first.span.lo);

        if utils::contains_skip(attrs) {
            true
        } else {
            let rewrite = self.rewrite_attrs(attrs, self.block_indent);
            self.changes.push_str_span(first.span, &rewrite);
            let last = attrs.last().unwrap();
            self.last_pos = last.span.hi;
            false
        }
    }

    pub fn rewrite_attrs(&self, attrs: &[ast::Attribute], indent: usize) -> String {
        let mut result = String::new();
        let indent = utils::make_indent(indent);

        for (i, a) in attrs.iter().enumerate() {
            let a_str = self.snippet(a.span);

            if i > 0 {
                let comment = self.snippet(codemap::mk_sp(attrs[i-1].span.hi, a.span.lo));
                // This particular horror show is to preserve line breaks in between doc
                // comments. An alternative would be to force such line breaks to start
                // with the usual doc comment token.
                let multi_line = a_str.starts_with("//") && comment.matches('\n').count() > 1;
                let comment = comment.trim();
                if comment.len() > 0 {
                    result.push_str(&indent);
                    result.push_str(comment);
                    result.push('\n');
                } else if multi_line {
                    result.push('\n');
                }
                result.push_str(&indent);
            }

            result.push_str(&a_str);

            if i < attrs.len() - 1 {
                result.push('\n');
            }
        }

        result
    }

    fn format_mod(&mut self, m: &ast::Mod, s: Span, ident: ast::Ident, attrs: &[ast::Attribute]) {
        debug!("FmtVisitor::format_mod: ident: {:?}, span: {:?}", ident, s);

        // Decide whether this is an inline mod or an external mod.
        let local_file_name = self.codemap.span_to_filename(s);
        let is_internal = local_file_name == self.codemap.span_to_filename(m.inner);

        // TODO Should rewrite properly `mod X;`

        if is_internal {
            debug!("FmtVisitor::format_mod: internal mod");
            self.block_indent += self.config.tab_spaces;
            visit::walk_mod(self, m);
            debug!("... last_pos after: {:?}", self.last_pos);
            self.block_indent -= self.config.tab_spaces;
        } else {
            debug!("FmtVisitor::format_mod: external mod");
            let file_path = self.module_file(ident, attrs, local_file_name);
            let filename = file_path.to_str().unwrap();
            if self.changes.is_changed(filename) {
                // The file has already been reformatted, do nothing
            } else {
                self.format_separate_mod(m, filename);
            }
        }

        debug!("FmtVisitor::format_mod: exit");
    }

    /// Find the file corresponding to an external mod
    fn module_file(&self, id: ast::Ident, attrs: &[ast::Attribute], filename: String) -> PathBuf {
        let dir_path = {
            let mut path = PathBuf::from(&filename);
            path.pop();
            path
        };

        if let Some(path) = parser::Parser::submod_path_from_attr(attrs, &dir_path) {
            return path;
        }

        match parser::Parser::default_submod_path(id, &dir_path, &self.codemap).result {
            Ok(parser::ModulePathSuccess { path, .. }) => path,
            _ => panic!("Couldn't find module {}", token::get_ident(id))
        }
    }

    /// Format the content of a module into a separate file
    fn format_separate_mod(&mut self, m: &ast::Mod, filename: &str) {
        let last_pos = self.last_pos;
        let block_indent = self.block_indent;
        let filemap = self.codemap.get_filemap(filename);
        self.last_pos = filemap.start_pos;
        self.block_indent = 0;
        visit::walk_mod(self, m);
        self.format_missing(filemap.end_pos);
        self.last_pos = last_pos;
        self.block_indent = block_indent;
    }

    fn format_import(&mut self, vis: ast::Visibility, vp: &ast::ViewPath, span: Span) {
        let vis = utils::format_visibility(vis);
        let offset = self.block_indent + vis.len() + "use ".len();
        let context = RewriteContext {
            codemap: self.codemap,
            config: self.config,
            block_indent: self.block_indent,
        };
        // 1 = ";"
        match vp.rewrite(&context, self.config.max_width - offset - 1, offset) {
            Some(ref s) if s.len() == 0 => {
                // Format up to last newline
                let prev_span = codemap::mk_sp(self.last_pos, span.lo);
                let span_end = match self.snippet(prev_span).rfind('\n') {
                    Some(offset) => self.last_pos + BytePos(offset as u32),
                    None => span.lo
                };
                self.format_missing(span_end);
                self.last_pos = span.hi;
            }
            Some(ref s) => {
                let s = format!("{}use {};", vis, s);
                self.format_missing_with_indent(span.lo);
                self.changes.push_str_span(span, &s);
                self.last_pos = span.hi;
            }
            None => {
                self.format_missing_with_indent(span.lo);
                self.format_missing(span.hi);
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add tests for the new write function<commit_after>extern crate geo;
extern crate geo_types;
extern crate gpx;

#[cfg(test)]
mod tests {
    use std::fs::File;
    use std::io::BufReader;

    use gpx::read;
    use gpx::write;
    use gpx::Gpx;
    use gpx::Link;
    use gpx::Waypoint;

    #[test]
    fn gpx_writer_write_unknown_gpx_version() {
        let gpx: Gpx = Default::default();
        let mut writer: Vec<u8> = Vec::new();
        // Should fail with unknown version.
        let result = write(&gpx, &mut writer);

        assert!(result.is_err());
    }

    #[test]
    fn gpx_writer_write_test_wikipedia() {
        check_write_for_example_file("tests/fixtures/wikipedia_example.gpx");
    }

    #[test]
    fn gpx_writer_write_test_garmin_activity() {
        check_write_for_example_file("tests/fixtures/garmin-activity.gpx");
    }

    #[test]
    fn gpx_writer_write_test_with_accuracy() {
        check_write_for_example_file("tests/fixtures/with_accuracy.gpx");
    }

    fn check_write_for_example_file(filename: &str) {
        let reference_gpx = read_test_gpx_file(filename);
        let written_gpx = write_and_reread_gpx(&reference_gpx);

        check_metadata_equal(&reference_gpx, &written_gpx);
        check_points_equal(&reference_gpx, &written_gpx);
    }

    fn read_test_gpx_file(filename: &str) -> Gpx {
        let file = File::open(filename).unwrap();
        let reader = BufReader::new(file);

        let result = read(reader);
        assert!(result.is_ok());

        result.unwrap()
    }

    fn write_and_reread_gpx(reference_gpx: &Gpx) -> Gpx {
        let mut buffer: Vec<u8> = Vec::new();
        let result = write(&reference_gpx, &mut buffer);
        assert!(result.is_ok());

        let written_gpx = read(buffer.as_slice()).unwrap();
        written_gpx
    }

    fn check_metadata_equal(reference_gpx: &Gpx, written_gpx: &Gpx) {
        let reference = &reference_gpx.metadata;
        let written = &written_gpx.metadata;
        if reference.is_some() {
            assert!(written.is_some());
        } else {
            assert!(written.is_none());
            return;
        }
        let reference = reference.as_ref().unwrap();
        let written = written.as_ref().unwrap();
        assert_eq!(reference.name, written.name);
        assert_eq!(reference.time, written.time);
        check_links_equal(&reference.links, &written.links);
    }

    fn check_links_equal(reference: &Vec<Link>, written: &Vec<Link>) {
        assert_eq!(reference.len(), written.len());
        for (r, w) in reference.iter().zip(written) {
            assert_eq!(r.href, w.href);
            assert_eq!(r.text, w.text);
        }
    }

    fn check_points_equal(reference: &Gpx, written: &Gpx) {
        check_waypoints_equal(&reference.waypoints, &written.waypoints);
        assert_eq!(reference.tracks.len(), written.tracks.len());
        for (r_track, w_track) in reference.tracks.iter().zip(written.tracks.iter()) {
            assert_eq!(r_track.name, w_track.name);
            assert_eq!(r_track.segments.len(), w_track.segments.len());
            for (r_seg, w_seg) in r_track.segments.iter().zip(w_track.segments.iter()) {
                check_waypoints_equal(&r_seg.points, &w_seg.points);
            }
        }
    }

    fn check_waypoints_equal(reference: &Vec<Waypoint>, written: &Vec<Waypoint>) {
        assert_eq!(reference.len(), written.len());
        for (r_wp, w_wp) in reference.iter().zip(written) {
            assert_eq!(r_wp.point(), w_wp.point());
            assert_eq!(r_wp.elevation, w_wp.elevation);
            assert_eq!(r_wp.speed, w_wp.speed);
            assert_eq!(r_wp.time, w_wp.time);
            assert_eq!(r_wp.geoidheight, w_wp.geoidheight);
            assert_eq!(r_wp.name, w_wp.name);
            assert_eq!(r_wp.comment, w_wp.comment);
            assert_eq!(r_wp.description, w_wp.description);
            assert_eq!(r_wp.source, w_wp.source);
            check_links_equal(&r_wp.links, &w_wp.links);
            assert_eq!(r_wp.symbol, w_wp.symbol);
            assert_eq!(r_wp._type, w_wp._type);
            assert_eq!(r_wp.fix, w_wp.fix);
            assert_eq!(r_wp.sat, w_wp.sat);
            assert_eq!(r_wp.hdop, w_wp.hdop);
            assert_eq!(r_wp.vdop, w_wp.vdop);
            assert_eq!(r_wp.pdop, w_wp.pdop);
            assert_eq!(r_wp.age, w_wp.age);
            assert_eq!(r_wp.dgpsid, w_wp.dgpsid);
        }
    }
}
<|endoftext|>


<commit_before>use std::num::{Zero, One, atan2};
use glfw;
use glfw::consts::*;
use nalgebra::vec::{Vec2, Vec3, AlgebraicVec, Cross};
use nalgebra::mat::{Mat4, Inv, ToHomogeneous};
use nalgebra::types::Iso3f64;
use camera::Camera;
use event;

/// Arc-ball camera mode. An arc-ball camera is a camera rotating around a fixed point (the focus
/// point) and always looking at it. The following inputs are handled:
///
///   * Left button press + drag - rotates the camera around the focus point
///   * Right button press + drag - translates the focus point on the plane orthogonal to the view
///   direction
///   * Scroll in/out - zoom in/out
///   * Enter key - set the focus point to the origin
#[deriving(Clone, ToStr)]
pub struct ArcBall {
    /// The focus point.
    priv at:    Vec3<f64>,
    /// Yaw of the camera (rotation along the y axis).
    priv yaw:   f64,
    /// Pitch of the camera (rotation along the x axis).
    priv pitch: f64,
    /// Distance from the camera to the `at` focus point.
    priv dist:  f64,

    /// Increment of the yaw per unit mouse movement. The default value is 0.005.
    priv yaw_step:   f64,
    /// Increment of the pitch per unit mouse movement. The default value is 0.005.
    priv pitch_step: f64,
    /// Increment of the distance per unit scrolling. The default value is 40.0.
    priv dist_step:  f64,

    priv fov:        f64,
    priv znear:      f64,
    priv zfar:       f64,
    priv projection:      Mat4<f64>,
    priv proj_view:       Mat4<f64>,
    priv inv_proj_view:   Mat4<f64>,
    priv last_cursor_pos: Vec2<f64>
}

impl ArcBall {
    /// Create a new arc-ball camera.
    pub fn new(eye: Vec3<f64>, at: Vec3<f64>) -> ArcBall {
        ArcBall::new_with_frustrum(45.0f64.to_radians(), 0.1, 1024.0, eye, at)
    }

    /// Creates a new arc ball camera with default sensitivity values.
    pub fn new_with_frustrum(fov:    f64,
                             znear:  f64,
                             zfar:   f64,
                             eye:    Vec3<f64>,
                             at:     Vec3<f64>) -> ArcBall {
        let mut res = ArcBall {
            at:         Vec3::new(0.0, 0.0, 0.0),
            yaw:        0.0,
            pitch:      0.0,
            dist:       0.0,
            yaw_step:   0.005,
            pitch_step: 0.005,
            dist_step:  40.0,
            fov:        fov,
            znear:      znear,
            zfar:       zfar,
            projection: Mat4::new_perspective(800.0, 600.0, fov, znear, zfar),
            proj_view:  Zero::zero(),
            inv_proj_view:   Zero::zero(),
            last_cursor_pos: Zero::zero()
        };

        res.look_at_z(eye, at);

        res
    }

    /// The arc-ball camera `yaw`.
    pub fn yaw(&self) -> f64 {
        self.yaw
    }

    /// Sets the camera `yaw`. Change this to modify the rotation along the `up` axis.
    pub fn set_yaw(&mut self, yaw: f64) {
        self.yaw = yaw;

        self.update_restrictions();
        self.update_projviews();
    }

    /// The arc-ball camera `pitch`.
    pub fn pitch(&self) -> f64 {
        self.pitch
    }

    /// Sets the camera `pitch`.
    pub fn set_pitch(&mut self, pitch: f64) {
        self.pitch = pitch;

        self.update_restrictions();
        self.update_projviews();
    }

    /// The distance from the camera position to its view point.
    pub fn dist(&self) -> f64 {
        self.dist
    }

    /// Move the camera such that it is at a given distance from the view point.
    pub fn set_dist(&mut self, dist: f64) {
        self.dist = dist;

        self.update_restrictions();
        self.update_projviews();
    }

    /// Move and orient the camera such that it looks at a specific point.
    pub fn look_at_z(&mut self, eye: Vec3<f64>, at: Vec3<f64>) {
        let dist  = (eye - at).norm();
        let pitch = ((eye.y - at.y) / dist).acos();
        let yaw   = atan2(eye.z - at.z, eye.x - at.x);

        self.at    = at;
        self.dist  = dist;
        self.yaw   = yaw;
        self.pitch = pitch;
        self.update_projviews();
    }

    /// Transformation applied by the camera without perspective.
    fn update_restrictions(&mut self) {
        if (self.dist < 0.00001) {
            self.dist = 0.00001
        }

        if (self.pitch <= 0.0001) {
            self.pitch = 0.0001
        }

        let _pi: f64 = Real::pi();
        if (self.pitch > _pi - 0.0001) {
            self.pitch = _pi - 0.0001
        }
    }

    fn handle_left_button_displacement(&mut self, dpos: &Vec2<f64>) {
        self.yaw   = self.yaw   + dpos.x * self.yaw_step;
        self.pitch = self.pitch - dpos.y * self.pitch_step;

        self.update_restrictions();
        self.update_projviews();
    }

    fn handle_right_button_displacement(&mut self, dpos: &Vec2<f64>) {
        let eye       = self.eye();
        let dir       = (self.at - eye).normalized();
        let tangent   = Vec3::y().cross(&dir).normalized();
        let bitangent = dir.cross(&tangent);
        let mult      = self.dist / 1000.0;

        self.at = self.at + tangent * (dpos.x * mult) + bitangent * (dpos.y * mult);
        self.update_projviews();
    }

    fn handle_scroll(&mut self, off: float) {
        self.dist = self.dist + self.dist_step * (off as f64) / 120.0;
        self.update_restrictions();
        self.update_projviews();
    }

    fn update_projviews(&mut self) {
        self.proj_view = self.projection * self.view_transform().inverse().unwrap().to_homogeneous();
        self.inv_proj_view = self.proj_view.inverse().unwrap();
    }
}

impl Camera for ArcBall {
    fn clip_planes(&self) -> (f64, f64) {
        (self.znear, self.zfar)
    }

    fn view_transform(&self) -> Iso3f64 {
        let mut id: Iso3f64 = One::one();
        id.look_at_z(&self.eye(), &self.at, &Vec3::y());

        id
    }

    fn eye(&self) -> Vec3<f64> {
        let px = self.at.x + self.dist * self.yaw.cos() * self.pitch.sin();
        let py = self.at.y + self.dist * self.pitch.cos();
        let pz = self.at.z + self.dist * self.yaw.sin() * self.pitch.sin();

        Vec3::new(px, py, pz)
    }

    fn handle_mouse(&mut self, window: &glfw::Window, event: &event::MouseEvent) {
        match *event {
            event::CursorPos(x, y) => {
                let curr_pos = Vec2::new(x as f64, y as f64);

                if window.get_mouse_button(MOUSE_BUTTON_1) == PRESS {
                    let dpos = curr_pos - self.last_cursor_pos;
                    self.handle_left_button_displacement(&dpos)
                }

                if window.get_mouse_button(MOUSE_BUTTON_2) == PRESS {
                    let dpos = curr_pos - self.last_cursor_pos;
                    self.handle_right_button_displacement(&dpos)
                }

                self.last_cursor_pos = curr_pos;
            },
            event::Scroll(_, off)  => self.handle_scroll(off),
            _ => { }
        }
    }

    fn handle_keyboard(&mut self, _: &glfw::Window, event: &event::KeyboardEvent) {
        match *event {
            event::KeyReleased(button) => if button == KEY_ENTER {
                self.at = Zero::zero();
                self.update_projviews();
            },
            _ => { }
        }
    }

    fn handle_framebuffer_size_change(&mut self, w: f64, h: f64) {
        self.projection = Mat4::new_perspective(w, h, self.fov, self.znear, self.zfar);
        self.update_projviews();
    }

    fn transformation(&self) -> Mat4<f64> {
        self.proj_view
    }

    fn inv_transformation(&self) -> Mat4<f64> {
        self.inv_proj_view
    }

    fn update(&mut self, _: &glfw::Window) { }
}
<commit_msg>Git access to the arc-ball look at point.<commit_after>use std::num::{Zero, One, atan2};
use glfw;
use glfw::consts::*;
use nalgebra::vec::{Vec2, Vec3, AlgebraicVec, Cross};
use nalgebra::mat::{Mat4, Inv, ToHomogeneous};
use nalgebra::types::Iso3f64;
use camera::Camera;
use event;

/// Arc-ball camera mode. An arc-ball camera is a camera rotating around a fixed point (the focus
/// point) and always looking at it. The following inputs are handled:
///
///   * Left button press + drag - rotates the camera around the focus point
///   * Right button press + drag - translates the focus point on the plane orthogonal to the view
///   direction
///   * Scroll in/out - zoom in/out
///   * Enter key - set the focus point to the origin
#[deriving(Clone, ToStr)]
pub struct ArcBall {
    /// The focus point.
    priv at:    Vec3<f64>,
    /// Yaw of the camera (rotation along the y axis).
    priv yaw:   f64,
    /// Pitch of the camera (rotation along the x axis).
    priv pitch: f64,
    /// Distance from the camera to the `at` focus point.
    priv dist:  f64,

    /// Increment of the yaw per unit mouse movement. The default value is 0.005.
    priv yaw_step:   f64,
    /// Increment of the pitch per unit mouse movement. The default value is 0.005.
    priv pitch_step: f64,
    /// Increment of the distance per unit scrolling. The default value is 40.0.
    priv dist_step:  f64,

    priv fov:        f64,
    priv znear:      f64,
    priv zfar:       f64,
    priv projection:      Mat4<f64>,
    priv proj_view:       Mat4<f64>,
    priv inv_proj_view:   Mat4<f64>,
    priv last_cursor_pos: Vec2<f64>
}

impl ArcBall {
    /// Create a new arc-ball camera.
    pub fn new(eye: Vec3<f64>, at: Vec3<f64>) -> ArcBall {
        ArcBall::new_with_frustrum(45.0f64.to_radians(), 0.1, 1024.0, eye, at)
    }

    /// Creates a new arc ball camera with default sensitivity values.
    pub fn new_with_frustrum(fov:    f64,
                             znear:  f64,
                             zfar:   f64,
                             eye:    Vec3<f64>,
                             at:     Vec3<f64>) -> ArcBall {
        let mut res = ArcBall {
            at:         Vec3::new(0.0, 0.0, 0.0),
            yaw:        0.0,
            pitch:      0.0,
            dist:       0.0,
            yaw_step:   0.005,
            pitch_step: 0.005,
            dist_step:  40.0,
            fov:        fov,
            znear:      znear,
            zfar:       zfar,
            projection: Mat4::new_perspective(800.0, 600.0, fov, znear, zfar),
            proj_view:  Zero::zero(),
            inv_proj_view:   Zero::zero(),
            last_cursor_pos: Zero::zero()
        };

        res.look_at_z(eye, at);

        res
    }

    /// The point the arc-ball is looking at.
    pub fn at(&self) -> Vec3<f64> {
        self.at
    }

    /// The arc-ball camera `yaw`.
    pub fn yaw(&self) -> f64 {
        self.yaw
    }

    /// Sets the camera `yaw`. Change this to modify the rotation along the `up` axis.
    pub fn set_yaw(&mut self, yaw: f64) {
        self.yaw = yaw;

        self.update_restrictions();
        self.update_projviews();
    }

    /// The arc-ball camera `pitch`.
    pub fn pitch(&self) -> f64 {
        self.pitch
    }

    /// Sets the camera `pitch`.
    pub fn set_pitch(&mut self, pitch: f64) {
        self.pitch = pitch;

        self.update_restrictions();
        self.update_projviews();
    }

    /// The distance from the camera position to its view point.
    pub fn dist(&self) -> f64 {
        self.dist
    }

    /// Move the camera such that it is at a given distance from the view point.
    pub fn set_dist(&mut self, dist: f64) {
        self.dist = dist;

        self.update_restrictions();
        self.update_projviews();
    }

    /// Move and orient the camera such that it looks at a specific point.
    pub fn look_at_z(&mut self, eye: Vec3<f64>, at: Vec3<f64>) {
        let dist  = (eye - at).norm();
        let pitch = ((eye.y - at.y) / dist).acos();
        let yaw   = atan2(eye.z - at.z, eye.x - at.x);

        self.at    = at;
        self.dist  = dist;
        self.yaw   = yaw;
        self.pitch = pitch;
        self.update_projviews();
    }

    /// Transformation applied by the camera without perspective.
    fn update_restrictions(&mut self) {
        if (self.dist < 0.00001) {
            self.dist = 0.00001
        }

        if (self.pitch <= 0.0001) {
            self.pitch = 0.0001
        }

        let _pi: f64 = Real::pi();
        if (self.pitch > _pi - 0.0001) {
            self.pitch = _pi - 0.0001
        }
    }

    fn handle_left_button_displacement(&mut self, dpos: &Vec2<f64>) {
        self.yaw   = self.yaw   + dpos.x * self.yaw_step;
        self.pitch = self.pitch - dpos.y * self.pitch_step;

        self.update_restrictions();
        self.update_projviews();
    }

    fn handle_right_button_displacement(&mut self, dpos: &Vec2<f64>) {
        let eye       = self.eye();
        let dir       = (self.at - eye).normalized();
        let tangent   = Vec3::y().cross(&dir).normalized();
        let bitangent = dir.cross(&tangent);
        let mult      = self.dist / 1000.0;

        self.at = self.at + tangent * (dpos.x * mult) + bitangent * (dpos.y * mult);
        self.update_projviews();
    }

    fn handle_scroll(&mut self, off: float) {
        self.dist = self.dist + self.dist_step * (off as f64) / 120.0;
        self.update_restrictions();
        self.update_projviews();
    }

    fn update_projviews(&mut self) {
        self.proj_view = self.projection * self.view_transform().inverse().unwrap().to_homogeneous();
        self.inv_proj_view = self.proj_view.inverse().unwrap();
    }
}

impl Camera for ArcBall {
    fn clip_planes(&self) -> (f64, f64) {
        (self.znear, self.zfar)
    }

    fn view_transform(&self) -> Iso3f64 {
        let mut id: Iso3f64 = One::one();
        id.look_at_z(&self.eye(), &self.at, &Vec3::y());

        id
    }

    fn eye(&self) -> Vec3<f64> {
        let px = self.at.x + self.dist * self.yaw.cos() * self.pitch.sin();
        let py = self.at.y + self.dist * self.pitch.cos();
        let pz = self.at.z + self.dist * self.yaw.sin() * self.pitch.sin();

        Vec3::new(px, py, pz)
    }

    fn handle_mouse(&mut self, window: &glfw::Window, event: &event::MouseEvent) {
        match *event {
            event::CursorPos(x, y) => {
                let curr_pos = Vec2::new(x as f64, y as f64);

                if window.get_mouse_button(MOUSE_BUTTON_1) == PRESS {
                    let dpos = curr_pos - self.last_cursor_pos;
                    self.handle_left_button_displacement(&dpos)
                }

                if window.get_mouse_button(MOUSE_BUTTON_2) == PRESS {
                    let dpos = curr_pos - self.last_cursor_pos;
                    self.handle_right_button_displacement(&dpos)
                }

                self.last_cursor_pos = curr_pos;
            },
            event::Scroll(_, off)  => self.handle_scroll(off),
            _ => { }
        }
    }

    fn handle_keyboard(&mut self, _: &glfw::Window, event: &event::KeyboardEvent) {
        match *event {
            event::KeyReleased(button) => if button == KEY_ENTER {
                self.at = Zero::zero();
                self.update_projviews();
            },
            _ => { }
        }
    }

    fn handle_framebuffer_size_change(&mut self, w: f64, h: f64) {
        self.projection = Mat4::new_perspective(w, h, self.fov, self.znear, self.zfar);
        self.update_projviews();
    }

    fn transformation(&self) -> Mat4<f64> {
        self.proj_view
    }

    fn inv_transformation(&self) -> Mat4<f64> {
        self.inv_proj_view
    }

    fn update(&mut self, _: &glfw::Window) { }
}
<|endoftext|>


<commit_before><commit_msg>Missing file.<commit_after>
extern crate rust_bio_tools;
extern crate itertools;
#[macro_use]
extern crate log;
extern crate fern;
#[macro_use]
extern crate clap;

use clap::{App,AppSettings};
use itertools::Itertools;

use rust_bio_tools::bam;
use rust_bio_tools::fastq;

fn main() {
    let yaml = load_yaml!("../cli.yaml");
    let matches = App::from_yaml(yaml)
                      .version(env!("CARGO_PKG_VERSION"))
                      .global_settings(&[AppSettings::SubcommandRequired,
                                         AppSettings::ColoredHelp])
                      .get_matches();

    fern::init_global_logger(fern::DispatchConfig {
        format: Box::new(|msg, _, _| msg.to_owned()),
        output: vec![fern::OutputConfig::stderr()],
        level: log::LogLevelFilter::Info
    }, log::LogLevelFilter::Trace).unwrap();

    if let Some(matches) = matches.subcommand_matches("fastq-split") {
        fastq::split::split(&matches.values_of("chunks").unwrap().collect_vec())
    }
    else if let Some(matches) = matches.subcommand_matches("bam-depth") {
        bam::depth::depth(&matches.value_of("bam-path").unwrap(), value_t!(matches, "max-read-length", u32).unwrap_or(1000))
    }
}
<|endoftext|>


<commit_before><commit_msg>Add Generated and Transient Unit States<commit_after><|endoftext|>