<commit_before>use std::io::net::ip::{SocketAddr, Ipv4Addr};
use string_telephone::{Client, ConnectionConfig};
use scene::{Scene, SceneManager};
use gamescene::GameScene;
use gamestate::GameState;
use conrod::{
    label,
    Color,
    Point,
    widget_matrix,
    Button,
    Callable,
    Colorable,
    Drawable,
    Frameable,
    Labelable,
    Positionable,
    Shapeable,
    TextBox,
};

use piston::{graphics, Render, Event, Update};
use piston::graphics::{AddColor, Draw};
use packet;

enum ConnectState {
    Disconnected,
    Connecting(Receiver<Option<Client<packet::Packet>>>)
}

pub struct ConnectScene<'r> {
    manager: &'r mut SceneManager,
    pub edit_ip: Vec<String>,
    try_connect: ConnectState,
}

impl <'r> ConnectScene<'r> {

    pub fn new<'r>(manager: &'r mut SceneManager) -> ConnectScene<'r> {
       ConnectScene {
           manager: manager,
           edit_ip: vec!["127".to_string(), "0".to_string(), "0".to_string(), "1".to_string()],
           try_connect: Disconnected
       }
    }

    pub fn is_connecting(&self) -> bool {
        match self.try_connect { Disconnected => false, _ => true}
    }
}

impl <'r> Scene for ConnectScene <'r> {
    fn handle_event(&mut self, e: &Event, state: &mut GameState) {
        match e {
            &Update(args) => {
                let should_disconnect = match self.try_connect {
                    Connecting(ref socket) => {
                        match socket.try_recv() {
                            Ok(Some(comms)) => {
                                println!("Connected");
                                self.manager.set_scene(|manager| box GameScene::new(manager));
                                true
                            },
                            Ok(None) => {
                                println!("Couldn't connect");
                                true
                            },
                            _ => false
                        }
                    },
                    _ => false
                };
                if should_disconnect {
                    self.try_connect = Disconnected;
                }

            },
            &Render(args) => {
                let (uic, gl) = state.get_drawables();

                gl.viewport(0, 0, args.width as i32, args.height as i32);

                let c = &graphics::Context::abs(args.width as f64, args.height as f64);

                c.rgb(1.0, 1.0, 1.0).draw(gl);
                label::draw(
                    gl,
                    uic,
                    Point::new(0f64, 0f64, 0f64), // Screen position.
                    48u32, // Font size.
                    Color::new(1.0, 0.0, 0.0, 1.0),
                    "Select a server"
                );

                widget_matrix::draw(
                    4, // cols.
                    1, // rows.
                    Point::new(0.0, 56.0, 0.0), // matrix position.
                    300.0, // width.
                    240.0, // height.
                    |num, _, _, pos, width, _| { // This is called for every widget.
                        // Now draw the widgets with the given callback.
                        uic.text_box(2 + num as u64, self.edit_ip.get_mut(num))
                            .font_size(24u32)
                            .dimensions(width, 36.0)
                            .position(pos.x, pos.y)
                            .frame(2.0, Color::black())
                            .color(Color::black())
                            .draw(gl);

                    }
                );

                uic.button(7u64)
                    .dimensions(90.0, 36.0)
                    .position(0.0, 128.0)
                    .color(Color::black())
                    .frame(2.0, Color::black())
                    .label("Connect", 24u32, Color::white())
                    .callback(|| {
                        if self.is_connecting() == false {
                            let parsed = (from_str(self.edit_ip[0].as_slice()), from_str(self.edit_ip[1].as_slice()), from_str(self.edit_ip[2].as_slice()), from_str(self.edit_ip[3].as_slice()));

                            match parsed {
                                (Some(a), Some(b), Some(c), Some(d)) => {
                                    let (tx, rx) = channel();
                                    self.try_connect = Connecting(rx);
                                    spawn(proc() {
                                        let settings = ConnectionConfig {
                                            protocol_id: 88869,
                                            timeout_period: 10,
                                            packet_deserializer: packet::deserializer,
                                            packet_serializer: packet::serializer
                                        };

                                        println!("Connecting");
                                        match Client::connect(SocketAddr {ip: Ipv4Addr(0, 0, 0, 0), port: 0}, SocketAddr {ip: Ipv4Addr(a, b, c, d), port: 8869}, settings) {
                                            Ok(client) => {
                                                tx.send(Some(client))
                                            },
                                            Err(e) => tx.send(None)
                                        };
                                    });
                                },
                                _ => ()
                            };
                        }
                    })
                    .draw(gl);

            },
            _ => {},
        }
    }
}
<commit_msg>Updated to latest COnrod<commit_after>use std::io::net::ip::{SocketAddr, Ipv4Addr};
use string_telephone::{Client, ConnectionConfig};
use scene::{Scene, SceneManager};
use gamescene::GameScene;
use gamestate::GameState;
use conrod::{
    label,
    Color,
    Point,
    WidgetMatrix,
    Button,
    Callable,
    Colorable,
    Drawable,
    Frameable,
    Labelable,
    Positionable,
    Shapeable,
    TextBox,
};

use piston::{graphics, Render, Event, Update};
use piston::graphics::{AddColor, Draw};
use packet;

enum ConnectState {
    Disconnected,
    Connecting(Receiver<Option<Client<packet::Packet>>>)
}

pub struct ConnectScene<'r> {
    manager: &'r mut SceneManager,
    pub edit_ip: Vec<String>,
    try_connect: ConnectState,
}

impl <'r> ConnectScene<'r> {

    pub fn new<'r>(manager: &'r mut SceneManager) -> ConnectScene<'r> {
       ConnectScene {
           manager: manager,
           edit_ip: vec!["127".to_string(), "0".to_string(), "0".to_string(), "1".to_string()],
           try_connect: Disconnected
       }
    }

    pub fn is_connecting(&self) -> bool {
        match self.try_connect { Disconnected => false, _ => true}
    }
}

impl <'r> Scene for ConnectScene <'r> {
    fn handle_event(&mut self, e: &Event, state: &mut GameState) {
        match e {
            &Update(args) => {
                let should_disconnect = match self.try_connect {
                    Connecting(ref socket) => {
                        match socket.try_recv() {
                            Ok(Some(comms)) => {
                                println!("Connected");
                                self.manager.set_scene(|manager| box GameScene::new(manager));
                                true
                            },
                            Ok(None) => {
                                println!("Couldn't connect");
                                true
                            },
                            _ => false
                        }
                    },
                    _ => false
                };
                if should_disconnect {
                    self.try_connect = Disconnected;
                }

            },
            &Render(args) => {
                let (uic, gl) = state.get_drawables();

                gl.viewport(0, 0, args.width as i32, args.height as i32);

                let c = &graphics::Context::abs(args.width as f64, args.height as f64);

                c.rgb(1.0, 1.0, 1.0).draw(gl);
                label::draw(
                    gl,
                    uic,
                    Point::new(0f64, 0f64, 0f64), // Screen position.
                    48u32, // Font size.
                    Color::new(1.0, 0.0, 0.0, 1.0),
                    "Select a server"
                );

                uic.widget_matrix(4, 1)
                    .position(0.0, 56.0)
                    .dimensions(300.0, 240.0)
                    .each_widget(|uic, num, _, _, pos, width, _| {
                        // Now draw the widgets with the given callback.
                        uic.text_box(2 + num as u64, self.edit_ip.get_mut(num))
                            .font_size(24u32)
                            .dimensions(width, 36.0)
                            .position(pos.x, pos.y)
                            .frame(2.0, Color::black())
                            .color(Color::black())
                            .draw(gl);

                    });

                uic.button(7u64)
                    .dimensions(90.0, 36.0)
                    .position(0.0, 128.0)
                    .color(Color::black())
                    .frame(2.0, Color::black())
                    .label("Connect", 24u32, Color::white())
                    .callback(|| {
                        if self.is_connecting() == false {
                            let parsed = (from_str(self.edit_ip[0].as_slice()), from_str(self.edit_ip[1].as_slice()), from_str(self.edit_ip[2].as_slice()), from_str(self.edit_ip[3].as_slice()));

                            match parsed {
                                (Some(a), Some(b), Some(c), Some(d)) => {
                                    let (tx, rx) = channel();
                                    self.try_connect = Connecting(rx);
                                    spawn(proc() {
                                        let settings = ConnectionConfig {
                                            protocol_id: 88869,
                                            timeout_period: 10,
                                            packet_deserializer: packet::deserializer,
                                            packet_serializer: packet::serializer
                                        };

                                        println!("Connecting");
                                        match Client::connect(SocketAddr {ip: Ipv4Addr(0, 0, 0, 0), port: 0}, SocketAddr {ip: Ipv4Addr(a, b, c, d), port: 8869}, settings) {
                                            Ok(client) => {
                                                tx.send(Some(client))
                                            },
                                            Err(e) => tx.send(None)
                                        };
                                    });
                                },
                                _ => ()
                            };
                        }
                    })
                    .draw(gl);

            },
            _ => {},
        }
    }
}
<|endoftext|>


<commit_before>use decoders::*;
use decoders::tiff::*;
use decoders::basics::*;
use std::f32::NAN;

pub fn is_x3f(buf: &[u8]) -> bool {
  buf[0..4] == b"FOVb"[..]
}

#[derive(Debug, Clone)]
struct X3fFile {
  dirs: Vec<X3fDirectory>,
  images: Vec<X3fImage>,
}

#[derive(Debug, Clone)]
struct X3fDirectory {
  offset: usize,
  len: usize,
  id: String,
}

#[derive(Debug, Clone)]
struct X3fImage {
  typ: usize,
  format: usize,
  width: usize,
  height: usize,
  pitch: usize,
  doffset: usize,
}

impl X3fFile {
  fn new(buf: &Buffer) -> Result<X3fFile, String> {
    let offset = LEu32(&buf.buf, buf.size-4) as usize;
    let data = &buf.buf[offset..];
    let version = LEu32(data, 4);
    if version < 0x00020000 {
      return Err(format!("X3F: Directory version too old {}", version).to_string())
    }
    let entries = LEu32(data, 8) as usize;
    let mut dirs = Vec::new();
    let mut images = Vec::new();
    for i in 0..entries {
      let dir = try!(X3fDirectory::new(data, 12+i*12));
      if dir.id == "IMA2" {
        let img = try!(X3fImage::new(&buf.buf, dir.offset));
        println!("Found image with offset {}", img.doffset);
        images.push(img);
      }
      dirs.push(dir);
    }

    Ok(X3fFile{
      dirs: dirs,
      images: images,
    })
  }
}

impl X3fDirectory {
  fn new(buf: &[u8], offset: usize) -> Result<X3fDirectory, String> {
    let data = &buf[offset..];
    let off = LEu32(data, 0) as usize;
    let len = LEu32(data, 4) as usize;
    let name = String::from_utf8_lossy(&data[8..12]).to_string();

    Ok(X3fDirectory {
      offset: off,
      len: len,
      id: name,
    })
  }
}

impl X3fImage {
  fn new(buf: &[u8], offset: usize) -> Result<X3fImage, String> {
    let data = &buf[offset..];
    println!("Decoding image at offset {}", offset);

    Ok(X3fImage {
      typ:     LEu32(data,  8) as usize,
      format:  LEu32(data, 12) as usize,
      width:   LEu32(data, 16) as usize,
      height:  LEu32(data, 20) as usize,
      pitch:   LEu32(data, 24) as usize,
      doffset: offset+28,
    })
  }
}

#[derive(Debug, Clone)]
pub struct X3fDecoder<'a> {
  buffer: &'a [u8],
  rawloader: &'a RawLoader,
  dir: X3fFile,
}

impl<'a> X3fDecoder<'a> {
  pub fn new(buf: &'a Buffer, rawloader: &'a RawLoader) -> X3fDecoder<'a> {
    let dir = X3fFile::new(buf).unwrap();

    X3fDecoder {
      buffer: &buf.buf,
      rawloader: rawloader,
      dir: dir,
    }
  }
}

impl<'a> Decoder for X3fDecoder<'a> {
  fn image(&self) -> Result<RawImage,String> {
    let caminfo = try!(
      self.dir.images.iter().find(|i| i.typ == 2 && i.format == 0x12)
        .ok_or("X3F: Couldn't find camera info".to_string())
    );
    let data = &self.buffer[caminfo.doffset+6..];
    if data[0..4] != b"Exif"[..] {
      return Err("X3F: Couldn't find EXIF info".to_string())
    }
    let tiff = try!(TiffIFD::new_root(self.buffer, caminfo.doffset+12));
    let camera = try!(self.rawloader.check_supported(&tiff));

    let imginfo = try!(
      self.dir.images.iter().find(|i| i.typ == 1 || i.typ == 3)
        .ok_or("X3F: Couldn't find image".to_string())
    );
    let width = imginfo.width;
    let height = imginfo.height;
    let offset = imginfo.doffset;
    let src = &self.buffer[offset..];

    let image = decode_12be(src, width, height);
    ok_image(camera, width, height, try!(self.get_wb()), image)
  }
}

impl<'a> X3fDecoder<'a> {
  fn get_wb(&self) -> Result<[f32;4], String> {
    Ok([NAN,NAN,NAN,NAN])
  }
}
<commit_msg>X3F: return a 3 color image<commit_after>use decoders::*;
use decoders::tiff::*;
use decoders::basics::*;
use std::f32::NAN;

pub fn is_x3f(buf: &[u8]) -> bool {
  buf[0..4] == b"FOVb"[..]
}

#[derive(Debug, Clone)]
struct X3fFile {
  dirs: Vec<X3fDirectory>,
  images: Vec<X3fImage>,
}

#[derive(Debug, Clone)]
struct X3fDirectory {
  offset: usize,
  len: usize,
  id: String,
}

#[derive(Debug, Clone)]
struct X3fImage {
  typ: usize,
  format: usize,
  width: usize,
  height: usize,
  pitch: usize,
  doffset: usize,
}

impl X3fFile {
  fn new(buf: &Buffer) -> Result<X3fFile, String> {
    let offset = LEu32(&buf.buf, buf.size-4) as usize;
    let data = &buf.buf[offset..];
    let version = LEu32(data, 4);
    if version < 0x00020000 {
      return Err(format!("X3F: Directory version too old {}", version).to_string())
    }
    let entries = LEu32(data, 8) as usize;
    let mut dirs = Vec::new();
    let mut images = Vec::new();
    for i in 0..entries {
      let dir = try!(X3fDirectory::new(data, 12+i*12));
      if dir.id == "IMA2" {
        let img = try!(X3fImage::new(&buf.buf, dir.offset));
        images.push(img);
      }
      dirs.push(dir);
    }

    Ok(X3fFile{
      dirs: dirs,
      images: images,
    })
  }
}

impl X3fDirectory {
  fn new(buf: &[u8], offset: usize) -> Result<X3fDirectory, String> {
    let data = &buf[offset..];
    let off = LEu32(data, 0) as usize;
    let len = LEu32(data, 4) as usize;
    let name = String::from_utf8_lossy(&data[8..12]).to_string();

    Ok(X3fDirectory {
      offset: off,
      len: len,
      id: name,
    })
  }
}

impl X3fImage {
  fn new(buf: &[u8], offset: usize) -> Result<X3fImage, String> {
    let data = &buf[offset..];

    Ok(X3fImage {
      typ:     LEu32(data,  8) as usize,
      format:  LEu32(data, 12) as usize,
      width:   LEu32(data, 16) as usize,
      height:  LEu32(data, 20) as usize,
      pitch:   LEu32(data, 24) as usize,
      doffset: offset+28,
    })
  }
}

#[derive(Debug, Clone)]
pub struct X3fDecoder<'a> {
  buffer: &'a [u8],
  rawloader: &'a RawLoader,
  dir: X3fFile,
}

impl<'a> X3fDecoder<'a> {
  pub fn new(buf: &'a Buffer, rawloader: &'a RawLoader) -> X3fDecoder<'a> {
    let dir = X3fFile::new(buf).unwrap();

    X3fDecoder {
      buffer: &buf.buf,
      rawloader: rawloader,
      dir: dir,
    }
  }
}

impl<'a> Decoder for X3fDecoder<'a> {
  fn image(&self) -> Result<RawImage,String> {
    let caminfo = try!(
      self.dir.images.iter().find(|i| i.typ == 2 && i.format == 0x12)
        .ok_or("X3F: Couldn't find camera info".to_string())
    );
    let data = &self.buffer[caminfo.doffset+6..];
    if data[0..4] != b"Exif"[..] {
      return Err("X3F: Couldn't find EXIF info".to_string())
    }
    let tiff = try!(TiffIFD::new_root(self.buffer, caminfo.doffset+12));
    let camera = try!(self.rawloader.check_supported(&tiff));

    let imginfo = try!(
      self.dir.images.iter().find(|i| i.typ == 1 || i.typ == 3)
        .ok_or("X3F: Couldn't find image".to_string())
    );
    let width = imginfo.width;
    let height = imginfo.height;
    let offset = imginfo.doffset;
    let src = &self.buffer[offset..];

    let image = match imginfo.format {
      35 => try!(self.decode_compressed(src, width, height)),
      x => return Err(format!("X3F Don't know how to decode format {}", x).to_string())
    };

    let mut img = RawImage::new(camera, width, height, try!(self.get_wb()), image);
    img.cpp = 3;
    Ok(img)
  }
}

impl<'a> X3fDecoder<'a> {
  fn get_wb(&self) -> Result<[f32;4], String> {
    Ok([NAN,NAN,NAN,NAN])
  }

  fn decode_compressed(&self, src: &[u8], width: usize, height: usize) -> Result<Vec<u16>, String> {
    let mut out = vec![0 as u16; width*height*3];
    Ok(out)
  }
}
<|endoftext|>


<commit_before>use math3d::matrix::Matrix4x4;
use num::{Float,NumCast,cast,Zero,One};
use std::f32;

#[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)]
pub struct Frustum<N: Float> {
	pub projection_matrix:Matrix4x4<N>
}

impl<N: Float+NumCast+Zero+One> Frustum<N> {
	pub fn new() -> Frustum<N> {
		Frustum {
			projection_matrix:Matrix4x4::<N>::identity()
		}
	}
	pub fn set_perspective(&mut self, fov:N, aspect_ratio:N, near:N, far:N){
        // calculate the near clipping plane
        // TODO: this number casting might not be ideal, maybe using traits on the numbers is more ideal
		let nymax = near * (fov * cast(f32::consts::PI).unwrap() / cast(360).unwrap()).tan();
        let nymin = -nymax;
        let nxmin = nymin * aspect_ratio;
        let nxmax = -nxmin;

        // update the projection matrix (creating new one right now)
        let zero = N::zero();
        let one = N::one();
        let two = one + one;
        self.projection_matrix = Matrix4x4::<N>::identity();
        self.projection_matrix.m11 = (two * near) / (nxmax - nxmin);
        self.projection_matrix.m22 = (two * near) / (nymax - nymin);
        self.projection_matrix.m31 = (nxmax + nxmin) / (nxmax - nxmin);
        self.projection_matrix.m32 = (nymax + nymin) / (nymax - nymin);
        self.projection_matrix.m33 = -((far + near) / (far - near));
        self.projection_matrix.m34 = -one;
        self.projection_matrix.m43 = -((two * far * near) / (far - near));
        self.projection_matrix.m44 = zero;
	}
	pub fn set_orthographic(&mut self){

	}
}

/*

void Frustum::setPerspective(GLfloat fov, GLfloat aspect, GLfloat near, GLfloat far){
    float nxmin, nxmax, nymin, nymax; // dimensions of near clipping plane;
    float fxmin, fxmax, fymin, fymax; // dimensions of far clipping plane;

    // near clipping plane
    nymax = near * float(tan(fov * PI / 360.0));
    nymin = -nymax;
    nxmin = nymin * aspect;
    nxmax = -nxmin;

    // construct projection matrix
    loadIdentity44(projectionMatrix);
    projectionMatrix[0] = (2.0f * near)/(nxmax - nxmin);
    projectionMatrix[5] = (2.0f * near)/(nymax - nymin);
    projectionMatrix[8] = (nxmax + nxmin) / (nxmax - nxmin);
    projectionMatrix[9] = (nymax + nymin) / (nymax - nymin);
    projectionMatrix[10] = -((far + near) / (far - near));
    projectionMatrix[11] = -1.0f;
    projectionMatrix[14] = -((2.0f * far * near)/(far - near));
    projectionMatrix[15] = 0.0f;

    // do the math for the far clipping plane
    fymax = far * float(tan(fov * PI / 360.0));
    fymin = -fymax;
    fxmin = fymin * aspect;
    fxmax = -fxmin;

    // values for transformed frustum corners
    nearUL[0] = nxmin; nearUL[1] = nymax; nearUL[2] = -near; nearUL[3] = 1.0f;
    nearLL[0] = nxmin; nearLL[1] = nymin; nearLL[2] = -near; nearLL[3] = 1.0f;
    nearUR[0] = nxmax; nearUR[1] = nymax; nearUR[2] = -near; nearUR[3] = 1.0f;
    nearLR[0] = nxmax; nearLR[1] = nymin; nearLR[2] = -near; nearLR[3] = 1.0f;
    farUL[0] = fxmin; farUL[1] = fymax; farUL[2] = -far; farUL[3] = 1.0f;
    farLL[0] = fxmin; farLL[1] = fymin; farLL[2] = -far; farLL[3] = 1.0f;
    farUR[0] = fxmax; farUR[1] = fymax; farUR[2] = -far; farUR[3] = 1.0f;
    farLR[0] = fxmax; farLR[1] = fymin; farLR[2] = -far; farLR[3] = 1.0f;
}

void Frustum::setOrthographic(GLfloat xmin, GLfloat xmax, GLfloat ymin, GLfloat ymax, GLfloat zmin, GLfloat zmax){
    makeOrthographicMatrix(projectionMatrix, xmin, xmax, ymin, ymax, zmin, zmax);
    projectionMatrix[15] = 1.0f;

    // values for untransformed frustum corners
    nearUL[0] = xmin; nearUL[1] = ymax; nearUL[2] = zmin; nearUL[3] = 1.0f;
    nearLL[0] = xmin; nearLL[1] = ymin; nearLL[2] = zmin; nearLL[3] = 1.0f;
    nearUR[0] = xmax; nearUR[1] = ymax; nearUR[2] = zmin; nearUR[3] = 1.0f;
    nearLR[0] = xmax; nearLR[1] = ymin; nearLR[2] = zmin; nearLR[3] = 1.0f;
    farUL[0] = xmin; farUL[1] = ymax; farUL[2] = zmax; farUL[3] = 1.0f;
    farLL[0] = xmin; farLL[1] = ymin; farLL[2] = zmax; farLL[3] = 1.0f;
    farUR[0] = xmax; farUR[1] = ymax; farUR[2] = zmax; farUR[3] = 1.0f;
    farLR[0] = xmax; farLR[1] = ymin; farLR[2] = zmax; farLR[3] = 1.0f;
}

*/<commit_msg>Orthographic projection<commit_after>use math3d::matrix::Matrix4x4;
use num::{Float,NumCast,cast,Zero,One};
use std::f32;

#[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)]
pub struct Frustum<N: Float> {
	pub projection_matrix:Matrix4x4<N>
}

// TODO: number casting might not be ideal for performance, maybe use traits to improve this
impl<N: Float+NumCast+Zero+One> Frustum<N> {
	pub fn new() -> Frustum<N> {
		Frustum {
			projection_matrix:Matrix4x4::<N>::identity()
		}
	}
	pub fn set_perspective(&mut self, fov:N, aspect_ratio:N, near:N, far:N){
        // calculate the near clipping plane
		let nymax = near * (fov * cast(f32::consts::PI).unwrap() / cast(360).unwrap()).tan();
        let nymin = -nymax;
        let nxmin = nymin * aspect_ratio;
        let nxmax = -nxmin;

        // update the projection matrix (creating new one right now)
        let zero = N::zero();
        let one = N::one();
        let two = one + one;
        self.projection_matrix = Matrix4x4::<N>::identity();
        self.projection_matrix.m11 = (two * near) / (nxmax - nxmin);
        self.projection_matrix.m22 = (two * near) / (nymax - nymin);
        self.projection_matrix.m31 = (nxmax + nxmin) / (nxmax - nxmin);
        self.projection_matrix.m32 = (nymax + nymin) / (nymax - nymin);
        self.projection_matrix.m33 = -((far + near) / (far - near));
        self.projection_matrix.m34 = -one;
        self.projection_matrix.m43 = -((two * far * near) / (far - near));
        self.projection_matrix.m44 = zero;
	}
	pub fn set_orthographic(&mut self, xmin:N, xmax:N, ymin:N, ymax:N, zmin:N, zmax:N){
        let zero = N::zero();
        let one = N::one();
        let two = one + one;
        self.projection_matrix = Matrix4x4::<N>::identity();
        self.projection_matrix.m11 = two / (xmax - xmin);
        self.projection_matrix.m22 = two / (ymax - ymin);
        self.projection_matrix.m33 = -two / (zmax - zmin);
        self.projection_matrix.m41 = -((xmax + xmin) / (xmax - xmin));
        self.projection_matrix.m42 = -((ymax + ymin) / (ymax - ymin));
        self.projection_matrix.m43 = -((zmax + zmin) / (zmax - zmin));
        self.projection_matrix.m44 = one;
	}
}<|endoftext|>


<commit_before>use crate::event::Event;
use crate::sys;

use std::fmt;

/// A collection of readiness events.
///
/// `Events` is passed as an argument to [`Poll::poll`] and will be used to
/// receive any new readiness events received since the last poll. Usually, a
/// single `Events` instance is created at the same time as a [`Poll`] and
/// reused on each call to [`Poll::poll`].
///
/// See [`Poll`] for more documentation on polling.
///
/// [`Poll::poll`]: crate::Poll::poll
/// [`Poll`]: crate::Poll
///
/// # Examples
///
/// ```
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// use mio::{Events, Poll};
/// use std::time::Duration;
///
/// let mut events = Events::with_capacity(1024);
/// let mut poll = Poll::new()?;
/// #
/// # assert!(events.is_empty());
///
/// // Register `event::Source`s with `poll`.
///
/// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
///
/// for event in events.iter() {
///     println!("Got an event for {:?}", event.token());
/// }
/// #     Ok(())
/// # }
/// ```
pub struct Events {
    inner: sys::Events,
}

/// [`Events`] iterator.
///
/// This struct is created by the [`iter`] method on [`Events`].
///
/// [`Events`]: crate::event::Events
/// [`iter`]: crate::event::Events::iter
///
/// # Examples
///
/// ```
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// use mio::{Events, Poll};
/// use std::time::Duration;
///
/// let mut events = Events::with_capacity(1024);
/// let mut poll = Poll::new()?;
///
/// // Register handles with `poll`.
///
/// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
///
/// for event in events.iter() {
///     println!("Got an event for {:?}", event.token());
/// }
/// #     Ok(())
/// # }
/// ```
#[derive(Debug, Clone)]
pub struct Iter<'a> {
    inner: &'a Events,
    pos: usize,
}

impl Events {
    /// Return a new `Events` capable of holding up to `capacity` events.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::Events;
    ///
    /// let events = Events::with_capacity(1024);
    /// assert_eq!(1024, events.capacity());
    /// ```
    pub fn with_capacity(capacity: usize) -> Events {
        Events {
            inner: sys::Events::with_capacity(capacity),
        }
    }

    /// Returns the number of `Event` values that `self` can hold.
    ///
    /// ```
    /// use mio::Events;
    ///
    /// let events = Events::with_capacity(1024);
    /// assert_eq!(1024, events.capacity());
    /// ```
    pub fn capacity(&self) -> usize {
        self.inner.capacity()
    }

    /// Returns `true` if `self` contains no `Event` values.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::Events;
    ///
    /// let events = Events::with_capacity(1024);
    /// assert!(events.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }

    /// Returns an iterator over the `Event` values.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::error::Error;
    /// # fn main() -> Result<(), Box<dyn Error>> {
    /// use mio::{Events, Poll};
    /// use std::time::Duration;
    ///
    /// let mut events = Events::with_capacity(1024);
    /// let mut poll = Poll::new()?;
    ///
    /// // Register handles with `poll`.
    ///
    /// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
    ///
    /// for event in events.iter() {
    ///     println!("Got an event for {:?}", event.token());
    /// }
    /// #     Ok(())
    /// # }
    /// ```
    pub fn iter(&self) -> Iter<'_> {
        Iter {
            inner: self,
            pos: 0,
        }
    }

    /// Clearing all `Event` values from container explicitly.
    ///
    /// # Notes
    ///
    /// Events are cleared before every `poll`, it not needed to this.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::error::Error;
    /// # fn main() -> Result<(), Box<dyn Error>> {
    /// use mio::{Events, Poll};
    /// use std::time::Duration;
    ///
    /// let mut events = Events::with_capacity(1024);
    /// let mut poll = Poll::new()?;
    ///
    /// // Register handles with `poll`.
    ///
    /// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
    ///
    /// // Clear all events.
    /// events.clear();
    /// assert!(events.is_empty());
    /// #     Ok(())
    /// # }
    /// ```
    pub fn clear(&mut self) {
        self.inner.clear();
    }

    pub(crate) fn sys(&mut self) -> &mut sys::Events {
        &mut self.inner
    }
}

impl<'a> IntoIterator for &'a Events {
    type Item = &'a Event;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a> Iterator for Iter<'a> {
    type Item = &'a Event;

    fn next(&mut self) -> Option<Self::Item> {
        let ret = self
            .inner
            .inner
            .get(self.pos)
            .map(Event::from_sys_event_ref);
        self.pos += 1;
        ret
    }
}

impl fmt::Debug for Events {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Events")
            .field("capacity", &self.capacity())
            .finish()
    }
}
<commit_msg>Fix type-o in Events doc<commit_after>use crate::event::Event;
use crate::sys;

use std::fmt;

/// A collection of readiness events.
///
/// `Events` is passed as an argument to [`Poll::poll`] and will be used to
/// receive any new readiness events received since the last poll. Usually, a
/// single `Events` instance is created at the same time as a [`Poll`] and
/// reused on each call to [`Poll::poll`].
///
/// See [`Poll`] for more documentation on polling.
///
/// [`Poll::poll`]: crate::Poll::poll
/// [`Poll`]: crate::Poll
///
/// # Examples
///
/// ```
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// use mio::{Events, Poll};
/// use std::time::Duration;
///
/// let mut events = Events::with_capacity(1024);
/// let mut poll = Poll::new()?;
/// #
/// # assert!(events.is_empty());
///
/// // Register `event::Source`s with `poll`.
///
/// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
///
/// for event in events.iter() {
///     println!("Got an event for {:?}", event.token());
/// }
/// #     Ok(())
/// # }
/// ```
pub struct Events {
    inner: sys::Events,
}

/// [`Events`] iterator.
///
/// This struct is created by the [`iter`] method on [`Events`].
///
/// [`Events`]: crate::event::Events
/// [`iter`]: crate::event::Events::iter
///
/// # Examples
///
/// ```
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// use mio::{Events, Poll};
/// use std::time::Duration;
///
/// let mut events = Events::with_capacity(1024);
/// let mut poll = Poll::new()?;
///
/// // Register handles with `poll`.
///
/// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
///
/// for event in events.iter() {
///     println!("Got an event for {:?}", event.token());
/// }
/// #     Ok(())
/// # }
/// ```
#[derive(Debug, Clone)]
pub struct Iter<'a> {
    inner: &'a Events,
    pos: usize,
}

impl Events {
    /// Return a new `Events` capable of holding up to `capacity` events.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::Events;
    ///
    /// let events = Events::with_capacity(1024);
    /// assert_eq!(1024, events.capacity());
    /// ```
    pub fn with_capacity(capacity: usize) -> Events {
        Events {
            inner: sys::Events::with_capacity(capacity),
        }
    }

    /// Returns the number of `Event` values that `self` can hold.
    ///
    /// ```
    /// use mio::Events;
    ///
    /// let events = Events::with_capacity(1024);
    /// assert_eq!(1024, events.capacity());
    /// ```
    pub fn capacity(&self) -> usize {
        self.inner.capacity()
    }

    /// Returns `true` if `self` contains no `Event` values.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::Events;
    ///
    /// let events = Events::with_capacity(1024);
    /// assert!(events.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }

    /// Returns an iterator over the `Event` values.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::error::Error;
    /// # fn main() -> Result<(), Box<dyn Error>> {
    /// use mio::{Events, Poll};
    /// use std::time::Duration;
    ///
    /// let mut events = Events::with_capacity(1024);
    /// let mut poll = Poll::new()?;
    ///
    /// // Register handles with `poll`.
    ///
    /// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
    ///
    /// for event in events.iter() {
    ///     println!("Got an event for {:?}", event.token());
    /// }
    /// #     Ok(())
    /// # }
    /// ```
    pub fn iter(&self) -> Iter<'_> {
        Iter {
            inner: self,
            pos: 0,
        }
    }

    /// Clearing all `Event` values from container explicitly.
    ///
    /// # Notes
    ///
    /// Events are cleared before every `poll`, so this is not required.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::error::Error;
    /// # fn main() -> Result<(), Box<dyn Error>> {
    /// use mio::{Events, Poll};
    /// use std::time::Duration;
    ///
    /// let mut events = Events::with_capacity(1024);
    /// let mut poll = Poll::new()?;
    ///
    /// // Register handles with `poll`.
    ///
    /// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
    ///
    /// // Clear all events.
    /// events.clear();
    /// assert!(events.is_empty());
    /// #     Ok(())
    /// # }
    /// ```
    pub fn clear(&mut self) {
        self.inner.clear();
    }

    pub(crate) fn sys(&mut self) -> &mut sys::Events {
        &mut self.inner
    }
}

impl<'a> IntoIterator for &'a Events {
    type Item = &'a Event;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a> Iterator for Iter<'a> {
    type Item = &'a Event;

    fn next(&mut self) -> Option<Self::Item> {
        let ret = self
            .inner
            .inner
            .get(self.pos)
            .map(Event::from_sys_event_ref);
        self.pos += 1;
        ret
    }
}

impl fmt::Debug for Events {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Events")
            .field("capacity", &self.capacity())
            .finish()
    }
}
<|endoftext|>


<commit_before>#[crate_id = "redis-example#0.1"];
#[crate_type = "app"];

extern mod redis;

fn main() {
    /*
    let input = bytes!("*6\r\n$3\r\nabc\r\n:123\r\n:1\n$-1\r\n-ERR unknown command foo\r\n-\r\n");
    let resp = redis::parse_redis_value(input);
    println!("{:?}", resp);
    */

    let mut client = redis::Client::open("redis://127.0.0.1/").unwrap();
    println!("foo get: {:?}", client.get("foo"));
    println!("foo as int: {:?}", client.get_as::<int>("foo"));
    println!("Ping: {:?}", client.ping());
    println!("Keys: {:?}", client.keys("*"));
}
<commit_msg>Removed some dead code<commit_after>#[crate_id = "redis-example#0.1"];
#[crate_type = "app"];

extern mod redis;

fn main() {
    let mut client = redis::Client::open("redis://127.0.0.1/").unwrap();
    println!("foo get: {:?}", client.get("foo"));
    println!("foo as int: {:?}", client.get_as::<int>("foo"));
    println!("Ping: {:?}", client.ping());
    println!("Keys: {:?}", client.keys("*"));
}
<|endoftext|>


<commit_before>mod extractor;

extern crate num_cpus;

use clap;
use flate2::write::GzEncoder;
use rayon::prelude::*;
use std::fs;
use std::io::{BufRead, BufWriter, Write};
use std::path::{Path, PathBuf};

enum TrapCompression {
    None,
    Gzip,
}

impl TrapCompression {
    fn from_env() -> TrapCompression {
        match std::env::var("CODEQL_RUBY_TRAP_COMPRESSION") {
            Ok(method) => match TrapCompression::from_string(&method) {
                Some(c) => c,
                None => {
                    tracing::error!("Unknown compression method '{}'; using gzip.", &method);
                    TrapCompression::Gzip
                }
            },
            // Default compression method if the env var isn't set:
            Err(_) => TrapCompression::Gzip,
        }
    }

    fn from_string(s: &str) -> Option<TrapCompression> {
        match s.to_lowercase().as_ref() {
            "none" => Some(TrapCompression::None),
            "gzip" => Some(TrapCompression::Gzip),
            _ => None,
        }
    }

    fn extension(&self) -> &str {
        match self {
            TrapCompression::None => ".trap",
            TrapCompression::Gzip => ".trap.gz",
        }
    }
}

/**
 * Gets the number of threads the extractor should use, by reading the
 * CODEQL_THREADS environment variable and using it as follows:
 *
 * If the number is positive, it indicates the number of threads that should be
 * used. If the number is negative or zero, it should be added to the number of
 * cores available on the machine to determine how many threads to use (minimum
 * of 1). If unspecified, should be considered as set to 1.
 */
fn num_codeql_threads() -> usize {
    match std::env::var("CODEQL_THREADS") {
        Ok(num) => match num.parse::<i32>() {
            Ok(num) => {
                if num <= 0 {
                    let reduction = -num as usize;
                    num_cpus::get() - reduction
                } else {
                    num as usize
                }
            }

            Err(_) => {
                tracing::error!(
                    "Unable to parse CODEQL_THREADS value '{}'; defaulting to 1 thread.",
                    &num
                );
                1
            }
        },

        // Use 1 thread if the environment variable isn't set.
        Err(_) => 1,
    }
}

fn main() -> std::io::Result<()> {
    tracing_subscriber::fmt()
        .with_target(false)
        .without_time()
        .with_level(true)
        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
        .init();

    let num_threads = num_codeql_threads();
    tracing::info!(
        "Using {} {}",
        num_threads,
        if num_threads == 1 {
            "thread"
        } else {
            "threads"
        }
    );
    rayon::ThreadPoolBuilder::new()
        .num_threads(num_threads)
        .build_global()
        .unwrap();

    let matches = clap::App::new("Ruby extractor")
        .version("1.0")
        .author("GitHub")
        .about("CodeQL Ruby extractor")
        .args_from_usage(
            "--source-archive-dir=<DIR> 'Sets a custom source archive folder'
                    --output-dir=<DIR>         'Sets a custom trap folder'
                    --file-list=<FILE_LIST>    'A text files containing the paths of the files to extract'",
        )
        .get_matches();
    let src_archive_dir = matches
        .value_of("source-archive-dir")
        .expect("missing --source-archive-dir");
    let src_archive_dir = PathBuf::from(src_archive_dir);

    let trap_dir = matches
        .value_of("output-dir")
        .expect("missing --output-dir");
    let trap_dir = PathBuf::from(trap_dir);
    let trap_compression = TrapCompression::from_env();

    let file_list = matches.value_of("file-list").expect("missing --file-list");
    let file_list = fs::File::open(file_list)?;

    let language = tree_sitter_ruby::language();
    let schema = node_types::read_node_types_str(tree_sitter_ruby::NODE_TYPES)?;
    let lines: std::io::Result<Vec<String>> = std::io::BufReader::new(file_list).lines().collect();
    let lines = lines?;
    lines.par_iter().try_for_each(|line| {
        let path = PathBuf::from(line).canonicalize()?;
        let trap_file = path_for(&trap_dir, &path, trap_compression.extension());
        let src_archive_file = path_for(&src_archive_dir, &path, "");
        let trap = extractor::extract(language, &schema, &path)?;
        std::fs::create_dir_all(&src_archive_file.parent().unwrap())?;
        std::fs::copy(&path, &src_archive_file)?;
        std::fs::create_dir_all(&trap_file.parent().unwrap())?;
        let trap_file = std::fs::File::create(&trap_file)?;
        let mut trap_file = BufWriter::new(trap_file);
        match trap_compression {
            TrapCompression::None => {
                write!(trap_file, "{}", trap)?;
            }
            TrapCompression::Gzip => {
                let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast());
                write!(compressed_writer, "{}", trap)?;
            }
        }
        std::io::Result::Ok(())
    })?;

    Ok(())
}

fn path_for(dir: &Path, path: &Path, ext: &str) -> PathBuf {
    let mut result = PathBuf::from(dir);
    for component in path.components() {
        match component {
            std::path::Component::Prefix(prefix) => match prefix.kind() {
                std::path::Prefix::Disk(letter) | std::path::Prefix::VerbatimDisk(letter) => {
                    result.push(format!("{}_", letter as char))
                }
                std::path::Prefix::Verbatim(x) | std::path::Prefix::DeviceNS(x) => {
                    result.push(x);
                }
                std::path::Prefix::UNC(server, share)
                | std::path::Prefix::VerbatimUNC(server, share) => {
                    result.push("unc");
                    result.push(server);
                    result.push(share);
                }
            },
            std::path::Component::RootDir => {
                // skip
            }
            std::path::Component::Normal(_) => {
                result.push(component);
            }
            std::path::Component::CurDir => {
                // skip
            }
            std::path::Component::ParentDir => {
                result.pop();
            }
        }
    }
    if let Some(x) = result.extension() {
        let mut new_ext = x.to_os_string();
        new_ext.push(ext);
        result.set_extension(new_ext);
    } else {
        result.set_extension(ext);
    }
    result
}
<commit_msg>Simplify num_codeql_threads function slightly<commit_after>mod extractor;

extern crate num_cpus;

use clap;
use flate2::write::GzEncoder;
use rayon::prelude::*;
use std::fs;
use std::io::{BufRead, BufWriter, Write};
use std::path::{Path, PathBuf};

enum TrapCompression {
    None,
    Gzip,
}

impl TrapCompression {
    fn from_env() -> TrapCompression {
        match std::env::var("CODEQL_RUBY_TRAP_COMPRESSION") {
            Ok(method) => match TrapCompression::from_string(&method) {
                Some(c) => c,
                None => {
                    tracing::error!("Unknown compression method '{}'; using gzip.", &method);
                    TrapCompression::Gzip
                }
            },
            // Default compression method if the env var isn't set:
            Err(_) => TrapCompression::Gzip,
        }
    }

    fn from_string(s: &str) -> Option<TrapCompression> {
        match s.to_lowercase().as_ref() {
            "none" => Some(TrapCompression::None),
            "gzip" => Some(TrapCompression::Gzip),
            _ => None,
        }
    }

    fn extension(&self) -> &str {
        match self {
            TrapCompression::None => ".trap",
            TrapCompression::Gzip => ".trap.gz",
        }
    }
}

/**
 * Gets the number of threads the extractor should use, by reading the
 * CODEQL_THREADS environment variable and using it as described in the
 * extractor spec:
 *
 * "If the number is positive, it indicates the number of threads that should
 * be used. If the number is negative or zero, it should be added to the number
 * of cores available on the machine to determine how many threads to use
 * (minimum of 1). If unspecified, should be considered as set to 1."
 */
fn num_codeql_threads() -> usize {
    match std::env::var("CODEQL_THREADS") {
        // Use 1 thread if the environment variable isn't set.
        Err(_) => 1,

        Ok(num) => match num.parse::<i32>() {
            Ok(num) if num <= 0 => {
                let reduction = -num as usize;
                num_cpus::get() - reduction
            }
            Ok(num) => num as usize,

            Err(_) => {
                tracing::error!(
                    "Unable to parse CODEQL_THREADS value '{}'; defaulting to 1 thread.",
                    &num
                );
                1
            }
        },
    }
}

fn main() -> std::io::Result<()> {
    tracing_subscriber::fmt()
        .with_target(false)
        .without_time()
        .with_level(true)
        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
        .init();

    let num_threads = num_codeql_threads();
    tracing::info!(
        "Using {} {}",
        num_threads,
        if num_threads == 1 {
            "thread"
        } else {
            "threads"
        }
    );
    rayon::ThreadPoolBuilder::new()
        .num_threads(num_threads)
        .build_global()
        .unwrap();

    let matches = clap::App::new("Ruby extractor")
        .version("1.0")
        .author("GitHub")
        .about("CodeQL Ruby extractor")
        .args_from_usage(
            "--source-archive-dir=<DIR> 'Sets a custom source archive folder'
                    --output-dir=<DIR>         'Sets a custom trap folder'
                    --file-list=<FILE_LIST>    'A text files containing the paths of the files to extract'",
        )
        .get_matches();
    let src_archive_dir = matches
        .value_of("source-archive-dir")
        .expect("missing --source-archive-dir");
    let src_archive_dir = PathBuf::from(src_archive_dir);

    let trap_dir = matches
        .value_of("output-dir")
        .expect("missing --output-dir");
    let trap_dir = PathBuf::from(trap_dir);
    let trap_compression = TrapCompression::from_env();

    let file_list = matches.value_of("file-list").expect("missing --file-list");
    let file_list = fs::File::open(file_list)?;

    let language = tree_sitter_ruby::language();
    let schema = node_types::read_node_types_str(tree_sitter_ruby::NODE_TYPES)?;
    let lines: std::io::Result<Vec<String>> = std::io::BufReader::new(file_list).lines().collect();
    let lines = lines?;
    lines.par_iter().try_for_each(|line| {
        let path = PathBuf::from(line).canonicalize()?;
        let trap_file = path_for(&trap_dir, &path, trap_compression.extension());
        let src_archive_file = path_for(&src_archive_dir, &path, "");
        let trap = extractor::extract(language, &schema, &path)?;
        std::fs::create_dir_all(&src_archive_file.parent().unwrap())?;
        std::fs::copy(&path, &src_archive_file)?;
        std::fs::create_dir_all(&trap_file.parent().unwrap())?;
        let trap_file = std::fs::File::create(&trap_file)?;
        let mut trap_file = BufWriter::new(trap_file);
        match trap_compression {
            TrapCompression::None => {
                write!(trap_file, "{}", trap)?;
            }
            TrapCompression::Gzip => {
                let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast());
                write!(compressed_writer, "{}", trap)?;
            }
        }
        std::io::Result::Ok(())
    })?;

    Ok(())
}

fn path_for(dir: &Path, path: &Path, ext: &str) -> PathBuf {
    let mut result = PathBuf::from(dir);
    for component in path.components() {
        match component {
            std::path::Component::Prefix(prefix) => match prefix.kind() {
                std::path::Prefix::Disk(letter) | std::path::Prefix::VerbatimDisk(letter) => {
                    result.push(format!("{}_", letter as char))
                }
                std::path::Prefix::Verbatim(x) | std::path::Prefix::DeviceNS(x) => {
                    result.push(x);
                }
                std::path::Prefix::UNC(server, share)
                | std::path::Prefix::VerbatimUNC(server, share) => {
                    result.push("unc");
                    result.push(server);
                    result.push(share);
                }
            },
            std::path::Component::RootDir => {
                // skip
            }
            std::path::Component::Normal(_) => {
                result.push(component);
            }
            std::path::Component::CurDir => {
                // skip
            }
            std::path::Component::ParentDir => {
                result.pop();
            }
        }
    }
    if let Some(x) = result.extension() {
        let mut new_ext = x.to_os_string();
        new_ext.push(ext);
        result.set_extension(new_ext);
    } else {
        result.set_extension(ext);
    }
    result
}
<|endoftext|>


<commit_before>use std::env;
use std::path::Path;

use lazy_static::lazy_static;
use raw_cpuid::CpuId;

lazy_static! {
    static ref CPUID: CpuId = CpuId::new();
}

fn has_aesni() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_feature_info()
            .map_or(false, |features| features.has_aesni())
}

fn has_sse41() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_feature_info()
            .map_or(false, |features| features.has_sse41())
}

fn has_sse42() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_feature_info()
            .map_or(false, |features| features.has_sse42())
}

fn has_avx() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_feature_info()
            .map_or(false, |features| features.has_avx())
}

fn has_avx2() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_extended_feature_info()
            .map_or(false, |features| features.has_avx2())
}

fn support_aesni() -> bool {
    cfg!(any(feature = "aes", target_feature = "aes")) || has_aesni()
}

fn support_sse41() -> bool {
    cfg!(any(feature = "sse41", target_feature = "sse41")) || has_sse41()
}

fn support_sse42() -> bool {
    cfg!(any(feature = "sse42", target_feature = "sse42")) || has_sse42()
}

fn support_avx() -> bool {
    cfg!(any(feature = "avx", target_feature = "avx")) || has_avx()
}

fn support_avx2() -> bool {
    cfg!(any(feature = "avx2", target_feature = "avx2")) || has_avx2()
}

#[cfg(feature = "gen")]
fn generate_binding(out_file: &Path) {
    println!("generate binding file @ {:?}.", out_file);

    let _ = bindgen::builder()
        .clang_args(&["-x", "c++", "-std=c++11"])
        .clang_args(&[
            "-Dt1ha_EXPORTS",
            "-DXXH_STATIC_LINKING_ONLY",
            "-Isrc/highwayhash",
        ])
        .clang_args(if support_aesni() {
            &[
                "-maes",
                "-DT1HA0_RUNTIME_SELECT=1",
                "-DT1HA0_AESNI_AVAILABLE=1",
            ][..]
        } else {
            &[][..]
        })
        .clang_args(
            vec![
                if cfg!(feature = "native") {
                    Some("-march=native")
                } else {
                    None
                },
                if support_sse42() {
                    Some("-msse4.2")
                } else {
                    None
                },
                if support_avx() { Some("-mavx") } else { None },
                if support_avx2() { Some("-mavx2") } else { None },
                if cfg!(feature = "city") {
                    Some("-DCITY_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "farm") {
                    Some("-DFARM_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "highway") {
                    Some("-DHIGHWAY_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "lookup3") {
                    Some("-DLOOKUP3=1")
                } else {
                    None
                },
                if cfg!(feature = "meow") {
                    Some("-DMEOW_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "metro") {
                    Some("-DMETRO_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "mum") {
                    Some("-DMUM_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "murmur") {
                    Some("-DMURMUR_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "spooky") {
                    Some("-DSPOOKY_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "t1ha") {
                    Some("-DT1_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "wy") {
                    Some("-DWY_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "xx") {
                    Some("-DXX_HASH=1")
                } else {
                    None
                },
            ]
            .into_iter()
            .flatten(),
        )
        .header("src/fasthash.hpp")
        .size_t_is_usize(true)
        .generate_inline_functions(true)
        .disable_name_namespacing()
        .allowlist_function("^CityHash.*")
        .allowlist_function("^farmhash.*")
        .allowlist_function("^lookup3.*")
        .allowlist_function("^metrohash.*")
        .allowlist_function("^mum_hash.*")
        .allowlist_function("^MurmurHash.*")
        .allowlist_function("^SpookyHasher.*")
        .allowlist_function("^t1ha.*")
        .blocklist_function("^t1ha_selfcheck__.*")
        .allowlist_function("^XXH.*")
        .allowlist_function("^HighwayHash.*")
        .allowlist_function("^wyhash.*")
        .allowlist_var("^Meow.*")
        .allowlist_function("^Meow.*")
        .generate()
        .unwrap()
        .write_to_file(out_file)
        .expect("fail to write bindings");
}

#[cfg(not(feature = "gen"))]
fn generate_binding(_out_file: &Path) {
    println!("direct include pregenerated binding file.");
}

fn build_fasthash() {
    let mut build = cc::Build::new();

    build
        .cpp(true)
        .flag("-std=c++11")
        .include("src/highwayhash")
        .flag("-Wno-implicit-fallthrough")
        .flag("-Wno-unknown-attributes")
        .file("src/fasthash.cpp");

    if cfg!(feature = "city") {
        build.flag("-DCITY_HASH=1").file("src/smhasher/City.cpp");
    }

    if cfg!(feature = "farm") {
        build
            .flag("-DFARM_HASH=1")
            .file("src/smhasher/farmhash-c.c");
    }

    if cfg!(feature = "highway") {
        build.flag("-DHIGHWAY_HASH=1");
    }

    if cfg!(feature = "lookup3") {
        build.flag("-DLOOKUP3=1").file("src/smhasher/lookup3.cpp");
    }

    if cfg!(feature = "meow") {
        build.flag("-DMEOW_HASH=1");
    }

    if cfg!(feature = "t1ha") {
        build.flag("-DT1_HASH=1");
    }

    if cfg!(feature = "metro") {
        build
            .flag("-DMETRO_HASH=1")
            .file("src/smhasher/metrohash/metrohash64.cpp")
            .file("src/smhasher/metrohash/metrohash128.cpp");

        if support_sse42() {
            build
                .file("src/smhasher/metrohash/metrohash64crc.cpp")
                .file("src/smhasher/metrohash/metrohash128crc.cpp");
        }
    }

    if cfg!(feature = "mum") {
        build.flag("-DMUM_HASH=1").file("src/smhasher/mum.cc");
    }

    if cfg!(feature = "murmur") {
        build
            .flag("-DMURMUR_HASH=1")
            .file("src/smhasher/MurmurHash1.cpp")
            .file("src/smhasher/MurmurHash2.cpp")
            .file("src/smhasher/MurmurHash3.cpp");
    }

    if cfg!(feature = "spooky") {
        build
            .flag("-DSPOOKY_HASH=1")
            .file("src/smhasher/Spooky.cpp");
    }

    if cfg!(feature = "wy") {
        build.flag("-DWY_HASH=1");
    }

    if cfg!(feature = "xx") {
        build.flag("-DXX_HASH=1").file("src/xxHash/xxhash.c");
    }

    if cfg!(feature = "native") {
        build.flag("-march=native");
    } else {
        if cfg!(target_feature = "aes") {
            build.flag("-maes");
        }
        if cfg!(target_feature = "sse41") {
            build.flag("-msse41");
        }
        if cfg!(target_feature = "sse42") {
            build.flag("-msse4.2");
        }
        if cfg!(target_feature = "avx") {
            build.flag("-mavx");
        }
        if cfg!(target_feature = "avx2") {
            build.flag("-mavx2");
        }
    }

    build.static_flag(true).compile("fasthash");
}

fn build_t1() {
    let mut build = cc::Build::new();

    build
        .file("src/t1ha/src/t1ha0.c")
        .file("src/t1ha/src/t1ha1.c")
        .file("src/t1ha/src/t1ha2.c");

    // indirect functions are not supported on all targets (e.g. x86_64-unknown-linux-musl)
    #[cfg(target_env = "musl")]
    build.define("T1HA_USE_INDIRECT_FUNCTIONS", Some("0"));

    if support_aesni() {
        build
            .define("T1HA0_RUNTIME_SELECT", Some("1"))
            .define("T1HA0_AESNI_AVAILABLE", Some("1"))
            .flag("-maes")
            .file("src/t1ha/src/t1ha0_ia32aes_noavx.c")
            .file("src/t1ha/src/t1ha0_ia32aes_avx.c")
            .file("src/t1ha/src/t1ha0_ia32aes_avx2.c");

        if support_avx() {
            build.flag("-mavx");
        }

        if support_avx2() {
            build.flag("-mavx2");
        }
    }

    build.static_flag(true).compile("t1ha");
}

fn build_highway() {
    let mut build = cc::Build::new();

    build
        .cpp(true)
        .flag("-std=c++11")
        .include("src/highwayhash")
        .file("src/highwayhash/highwayhash/arch_specific.cc")
        .file("src/highwayhash/highwayhash/instruction_sets.cc")
        .file("src/highwayhash/highwayhash/os_specific.cc")
        .file("src/highwayhash/highwayhash/hh_portable.cc")
        .file("src/highwayhash/highwayhash/c_bindings.cc");

    if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
        if support_sse41() {
            build
                .flag("-msse4.1")
                .file("src/highwayhash/highwayhash/hh_sse41.cc");
        }

        if support_avx2() {
            build
                .flag("-mavx2")
                .file("src/highwayhash/highwayhash/hh_avx2.cc");
        }
    } else if cfg!(target_arch = "aarch64") {
        build.file("src/highwayhash/highwayhash/hh_neon.cc");
    } else if cfg!(target_arch = "powerpc64") {
        build.file("src/highwayhash/highwayhash/hh_vsx.cc");
    }

    build.static_flag(true).compile("highwayhash");
}

fn main() {
    if has_aesni() {
        println!(r#"cargo:rustc-cfg=feature="aes""#);
    }
    if has_sse41() {
        println!(r#"cargo:rustc-cfg=feature="sse41""#);
    }
    if has_sse42() {
        println!(r#"cargo:rustc-cfg=feature="sse42""#);
    }
    if has_avx() {
        println!(r#"cargo:rustc-cfg=feature="avx""#);
    }
    if has_avx2() {
        println!(r#"cargo:rustc-cfg=feature="avx2""#);
    }

    build_fasthash();
    if cfg!(feature = "t1ha") {
        build_t1();
    }
    if cfg!(feature = "highway") {
        build_highway();
    }

    let out_dir = env::var("OUT_DIR").unwrap();
    let out_file = Path::new(&out_dir).join("fasthash.rs");

    println!("cargo:rerun-if-changed=src/fasthash.hpp");
    println!("cargo:rerun-if-changed=src/fasthash.cpp");

    generate_binding(&out_file);
}
<commit_msg>disable compile warning<commit_after>use std::env;
use std::path::Path;

use lazy_static::lazy_static;
use raw_cpuid::CpuId;

lazy_static! {
    static ref CPUID: CpuId = CpuId::new();
}

fn has_aesni() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_feature_info()
            .map_or(false, |features| features.has_aesni())
}

fn has_sse41() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_feature_info()
            .map_or(false, |features| features.has_sse41())
}

fn has_sse42() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_feature_info()
            .map_or(false, |features| features.has_sse42())
}

fn has_avx() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_feature_info()
            .map_or(false, |features| features.has_avx())
}

fn has_avx2() -> bool {
    cfg!(feature = "native")
        && CPUID
            .get_extended_feature_info()
            .map_or(false, |features| features.has_avx2())
}

fn support_aesni() -> bool {
    cfg!(any(feature = "aes", target_feature = "aes")) || has_aesni()
}

fn support_sse41() -> bool {
    cfg!(any(feature = "sse41", target_feature = "sse41")) || has_sse41()
}

fn support_sse42() -> bool {
    cfg!(any(feature = "sse42", target_feature = "sse42")) || has_sse42()
}

fn support_avx() -> bool {
    cfg!(any(feature = "avx", target_feature = "avx")) || has_avx()
}

fn support_avx2() -> bool {
    cfg!(any(feature = "avx2", target_feature = "avx2")) || has_avx2()
}

#[cfg(feature = "gen")]
fn generate_binding(out_file: &Path) {
    println!("generate binding file @ {:?}.", out_file);

    let _ = bindgen::builder()
        .clang_args(&["-x", "c++", "-std=c++11"])
        .clang_args(&[
            "-Dt1ha_EXPORTS",
            "-DXXH_STATIC_LINKING_ONLY",
            "-Isrc/highwayhash",
        ])
        .clang_args(if support_aesni() {
            &[
                "-maes",
                "-DT1HA0_RUNTIME_SELECT=1",
                "-DT1HA0_AESNI_AVAILABLE=1",
            ][..]
        } else {
            &[][..]
        })
        .clang_args(
            vec![
                if cfg!(feature = "native") {
                    Some("-march=native")
                } else {
                    None
                },
                if support_sse42() {
                    Some("-msse4.2")
                } else {
                    None
                },
                if support_avx() { Some("-mavx") } else { None },
                if support_avx2() { Some("-mavx2") } else { None },
                if cfg!(feature = "city") {
                    Some("-DCITY_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "farm") {
                    Some("-DFARM_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "highway") {
                    Some("-DHIGHWAY_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "lookup3") {
                    Some("-DLOOKUP3=1")
                } else {
                    None
                },
                if cfg!(feature = "meow") {
                    Some("-DMEOW_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "metro") {
                    Some("-DMETRO_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "mum") {
                    Some("-DMUM_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "murmur") {
                    Some("-DMURMUR_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "spooky") {
                    Some("-DSPOOKY_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "t1ha") {
                    Some("-DT1_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "wy") {
                    Some("-DWY_HASH=1")
                } else {
                    None
                },
                if cfg!(feature = "xx") {
                    Some("-DXX_HASH=1")
                } else {
                    None
                },
            ]
            .into_iter()
            .flatten(),
        )
        .header("src/fasthash.hpp")
        .size_t_is_usize(true)
        .generate_inline_functions(true)
        .disable_name_namespacing()
        .allowlist_function("^CityHash.*")
        .allowlist_function("^farmhash.*")
        .allowlist_function("^lookup3.*")
        .allowlist_function("^metrohash.*")
        .allowlist_function("^mum_hash.*")
        .allowlist_function("^MurmurHash.*")
        .allowlist_function("^SpookyHasher.*")
        .allowlist_function("^t1ha.*")
        .blocklist_function("^t1ha_selfcheck__.*")
        .allowlist_function("^XXH.*")
        .allowlist_function("^HighwayHash.*")
        .allowlist_function("^wyhash.*")
        .allowlist_var("^Meow.*")
        .allowlist_function("^Meow.*")
        .generate()
        .unwrap()
        .write_to_file(out_file)
        .expect("fail to write bindings");
}

#[cfg(not(feature = "gen"))]
fn generate_binding(_out_file: &Path) {
    println!("direct include pregenerated binding file.");
}

fn build_fasthash() {
    let mut build = cc::Build::new();

    build
        .cpp(true)
        .include("src/highwayhash")
        .flag("-std=c++11")
        .flag_if_supported("-Wno-implicit-fallthrough")
        .flag_if_supported("-Wno-unknown-attributes")
        .flag_if_supported("-Wno-sign-compare")
        .file("src/fasthash.cpp");

    if cfg!(feature = "city") {
        build.flag("-DCITY_HASH=1").file("src/smhasher/City.cpp");
    }

    if cfg!(feature = "farm") {
        build
            .flag("-DFARM_HASH=1")
            .file("src/smhasher/farmhash-c.c");
    }

    if cfg!(feature = "highway") {
        build.flag("-DHIGHWAY_HASH=1");
    }

    if cfg!(feature = "lookup3") {
        build.flag("-DLOOKUP3=1").file("src/smhasher/lookup3.cpp");
    }

    if cfg!(feature = "meow") {
        build.flag("-DMEOW_HASH=1");
    }

    if cfg!(feature = "t1ha") {
        build.flag("-DT1_HASH=1");
    }

    if cfg!(feature = "metro") {
        build
            .flag("-DMETRO_HASH=1")
            .file("src/smhasher/metrohash/metrohash64.cpp")
            .file("src/smhasher/metrohash/metrohash128.cpp");

        if support_sse42() {
            build
                .file("src/smhasher/metrohash/metrohash64crc.cpp")
                .file("src/smhasher/metrohash/metrohash128crc.cpp");
        }
    }

    if cfg!(feature = "mum") {
        build.flag("-DMUM_HASH=1").file("src/smhasher/mum.cc");
    }

    if cfg!(feature = "murmur") {
        build
            .flag("-DMURMUR_HASH=1")
            .file("src/smhasher/MurmurHash1.cpp")
            .file("src/smhasher/MurmurHash2.cpp")
            .file("src/smhasher/MurmurHash3.cpp");
    }

    if cfg!(feature = "spooky") {
        build
            .flag("-DSPOOKY_HASH=1")
            .file("src/smhasher/Spooky.cpp");
    }

    if cfg!(feature = "wy") {
        build.flag("-DWY_HASH=1");
    }

    if cfg!(feature = "xx") {
        build.flag("-DXX_HASH=1").file("src/xxHash/xxhash.c");
    }

    if cfg!(feature = "native") {
        build.flag("-march=native");
    } else {
        if cfg!(target_feature = "aes") {
            build.flag("-maes");
        }
        if cfg!(target_feature = "sse41") {
            build.flag("-msse41");
        }
        if cfg!(target_feature = "sse42") {
            build.flag("-msse4.2");
        }
        if cfg!(target_feature = "avx") {
            build.flag("-mavx");
        }
        if cfg!(target_feature = "avx2") {
            build.flag("-mavx2");
        }
    }

    build.static_flag(true).compile("fasthash");
}

fn build_t1() {
    let mut build = cc::Build::new();

    build
        .file("src/t1ha/src/t1ha0.c")
        .file("src/t1ha/src/t1ha1.c")
        .file("src/t1ha/src/t1ha2.c");

    // indirect functions are not supported on all targets (e.g. x86_64-unknown-linux-musl)
    #[cfg(target_env = "musl")]
    build.define("T1HA_USE_INDIRECT_FUNCTIONS", Some("0"));

    if support_aesni() {
        build
            .define("T1HA0_RUNTIME_SELECT", Some("1"))
            .define("T1HA0_AESNI_AVAILABLE", Some("1"))
            .flag("-maes")
            .file("src/t1ha/src/t1ha0_ia32aes_noavx.c")
            .file("src/t1ha/src/t1ha0_ia32aes_avx.c")
            .file("src/t1ha/src/t1ha0_ia32aes_avx2.c");

        if support_avx() {
            build.flag("-mavx");
        }

        if support_avx2() {
            build.flag("-mavx2");
        }
    }

    build.static_flag(true).compile("t1ha");
}

fn build_highway() {
    let mut build = cc::Build::new();

    build
        .cpp(true)
        .flag("-std=c++11")
        .flag_if_supported("-Wno-sign-compare")
        .include("src/highwayhash")
        .file("src/highwayhash/highwayhash/arch_specific.cc")
        .file("src/highwayhash/highwayhash/instruction_sets.cc")
        .file("src/highwayhash/highwayhash/os_specific.cc")
        .file("src/highwayhash/highwayhash/hh_portable.cc")
        .file("src/highwayhash/highwayhash/c_bindings.cc");

    if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
        if support_sse41() {
            build
                .flag("-msse4.1")
                .file("src/highwayhash/highwayhash/hh_sse41.cc");
        }

        if support_avx2() {
            build
                .flag("-mavx2")
                .file("src/highwayhash/highwayhash/hh_avx2.cc");
        }
    } else if cfg!(target_arch = "aarch64") {
        build.file("src/highwayhash/highwayhash/hh_neon.cc");
    } else if cfg!(target_arch = "powerpc64") {
        build.file("src/highwayhash/highwayhash/hh_vsx.cc");
    }

    build.static_flag(true).compile("highwayhash");
}

fn main() {
    if has_aesni() {
        println!(r#"cargo:rustc-cfg=feature="aes""#);
    }
    if has_sse41() {
        println!(r#"cargo:rustc-cfg=feature="sse41""#);
    }
    if has_sse42() {
        println!(r#"cargo:rustc-cfg=feature="sse42""#);
    }
    if has_avx() {
        println!(r#"cargo:rustc-cfg=feature="avx""#);
    }
    if has_avx2() {
        println!(r#"cargo:rustc-cfg=feature="avx2""#);
    }

    build_fasthash();
    if cfg!(feature = "t1ha") {
        build_t1();
    }
    if cfg!(feature = "highway") {
        build_highway();
    }

    let out_dir = env::var("OUT_DIR").unwrap();
    let out_file = Path::new(&out_dir).join("fasthash.rs");

    println!("cargo:rerun-if-changed=src/fasthash.hpp");
    println!("cargo:rerun-if-changed=src/fasthash.cpp");

    generate_binding(&out_file);
}
<|endoftext|>


<commit_before>fn main() {
    for i in range(0, 10) {
        printfln!("%d", i)
    }
}
<commit_msg>fix loop example<commit_after>fn main() {
    for i in range(0, 10) {
        println!("{}", i)
    }
}
<|endoftext|>


<commit_before>#![allow(missing_docs)]
#![allow(dead_code)]

//! A first person camera.

use std::num::{Float, FloatMath};
use event::GenericEvent;
use input::Button;
use {
    input,
    Camera,
};
use vecmath::consts::Radians;

bitflags!(flags Keys: u8 {
    const MOVE_FORWARD  = 0b00000001,
    const MOVE_BACKWARD = 0b00000010,
    const STRAFE_LEFT   = 0b00000100,
    const STRAFE_RIGHT  = 0b00001000,
    const FLY_UP        = 0b00010000,
    const FLY_DOWN      = 0b00100000
})

/// First person camera settings.
pub struct FirstPersonSettings<T=f32> {
    /// Which button to press to move forward.
    pub move_forward_button: input::Button,
    /// Which button to press to move backward.
    pub move_backward_button: input::Button,
    /// Which button to press to strafe left.
    pub strafe_left_button: input::Button,
    /// Which button to press to strafe right.
    pub strafe_right_button: input::Button,
    /// Which button to press to fly up.
    pub fly_up_button: input::Button,
    /// Which button to press to fly down.
    pub fly_down_button: input::Button,
    /// Which button to press to move faster.
    pub move_faster_button: input::Button,
    /// The horizontal movement speed.
    ///
    /// This is measured in units per second.
    pub speed_horizontal: T,
    /// The vertical movement speed.
    ///
    /// This is measured in units per second.
    pub speed_vertical: T,
}

impl<T: Float> FirstPersonSettings<T> {
    /// Creates new first person camera settings with wasd defaults.
    pub fn keyboard_wasd() -> FirstPersonSettings<T> {
        use input::Button::Keyboard;
        use input::keyboard::Key;

        FirstPersonSettings {
            move_forward_button: Keyboard(Key::W),
            move_backward_button: Keyboard(Key::S),
            strafe_left_button: Keyboard(Key::A),
            strafe_right_button: Keyboard(Key::D),
            fly_up_button: Keyboard(Key::Space),
            fly_down_button: Keyboard(Key::LShift),
            move_faster_button: Keyboard(Key::LCtrl),
            speed_horizontal: Float::one(),
            speed_vertical: Float::one(),
        }
    }

    /// Creates a new first person camera settings with esdf defaults.
    pub fn keyboard_esdf() -> FirstPersonSettings<T> {
        use input::Button::Keyboard;
        use input::keyboard::Key;

        FirstPersonSettings {
            move_forward_button: Keyboard(Key::E),
            move_backward_button: Keyboard(Key::D),
            strafe_left_button: Keyboard(Key::S),
            strafe_right_button: Keyboard(Key::F),
            fly_up_button: Keyboard(Key::Space),
            fly_down_button: Keyboard(Key::Z),
            move_faster_button: Keyboard(Key::LShift),
            speed_horizontal: Float::one(),
            speed_vertical: Float::one(),
        }
    }
}

/// Models a flying first person camera.
pub struct FirstPerson<T=f32> {
    /// The first person camera settings.
    pub settings: FirstPersonSettings<T>,
    /// The yaw angle (in radians).
    pub yaw: T,
    /// The pitch angle (in radians).
    pub pitch: T,
    /// The direction we are heading.
    pub direction: [T, ..3],
    /// The position of the camera.
    pub position: [T, ..3],
    /// The velocity we are moving in the direction.
    pub velocity: T,
    /// The keys that are pressed.
    keys: Keys,
}

impl<T: Float + FromPrimitive + Copy + FloatMath + Radians>
FirstPerson<T> {

    /// Creates a new first person camera.
    pub fn new(
        position: [T, ..3],
        settings: FirstPersonSettings<T>
    ) -> FirstPerson<T> {
        let _0: T = Float::zero();
        FirstPerson {
            settings: settings,
            yaw: _0,
            pitch: _0,
            keys: Keys::empty(),
            direction: [_0, _0, _0],
            position: position,
            velocity: Float::one(),
        }
    }

    /// Computes camera.
    pub fn camera(&self, dt: f64) -> Camera<T> {
        let dt: T = FromPrimitive::from_f64(dt).unwrap();
        let dh = dt * self.velocity * self.settings.speed_horizontal;
        let [dx, dy, dz] = self.direction;
        let (s, c) = (self.yaw.sin(), self.yaw.cos());
        let mut camera = Camera::new([
            self.position[0] + (s * dx - c * dz) * dh,
            self.position[1] + dy * dt * self.settings.speed_vertical,
            self.position[2] + (s * dz + c * dx) * dh
        ]);
        camera.set_yaw_pitch(self.yaw, self.pitch);
        camera
    }

    /// Handles game event and updates camera.
    pub fn event<E: GenericEvent>(&mut self, e: &E) {
        use event::{ MouseRelativeEvent, PressEvent, ReleaseEvent, UpdateEvent };

        e.update(|args| {
            let cam = self.camera(args.dt);
            self.position = cam.position;
        });

        let &FirstPerson {
            ref mut yaw,
            ref mut pitch,
            ref mut keys,
            ref mut direction,
            ref mut velocity,
            ref settings,
            ..
        } = self;

        let pi: T = Radians::_180();
        let sqrt2: T = Float::sqrt2();
        let _0: T = Float::zero();
        let _1: T = Float::one();
        let _2: T = FromPrimitive::from_int(2).unwrap();
        let _3: T = FromPrimitive::from_int(3).unwrap();
        let _4: T = FromPrimitive::from_int(4).unwrap();
        let _360: T = FromPrimitive::from_int(360).unwrap();
        e.mouse_relative(|dx, dy| {
            let dx: T = FromPrimitive::from_f64(dx).unwrap();
            let dy: T = FromPrimitive::from_f64(dy).unwrap();
            *yaw = (*yaw - dx / _360 * pi / _4) % (_2 * pi);
            *pitch = *pitch + dy / _360 * pi / _4;
            *pitch = (*pitch).min(pi / _2).max(-pi / _2);
        });
        e.press(|button| {
            let [dx, dy, dz] = *direction;
            let sgn = |x: T| if x == _0 { _0 } else { x.signum() };
            let set = |k, x: T, y: T, z: T| {
                let (x, z) = (sgn(x), sgn(z));
                let (x, z) = if x != _0 && z != _0 {
                    (x / sqrt2, z / sqrt2)
                } else {
                    (x, z)
                };
                *direction = [x, y, z];
                keys.insert(k);
            };
            match button {
                x if x == settings.move_forward_button =>
                    set(MOVE_FORWARD, -_1, dy, dz),
                x if x == settings.move_backward_button =>
                    set(MOVE_BACKWARD, _1, dy, dz),
                x if x == settings.strafe_left_button =>
                    set(STRAFE_LEFT, dx, dy, _1),
                x if x == settings.strafe_right_button =>
                    set(STRAFE_RIGHT, dx, dy, -_1),
                x if x == settings.fly_up_button =>
                    set(FLY_UP, dx, _1, dz),
                x if x == settings.fly_down_button =>
                    set(FLY_DOWN, dx, -_1, dz),
                x if x == settings.move_faster_button => *velocity = _2,
                _ => {}
            }
        });
        e.release(|button| {
            let [dx, dy, dz] = *direction;
            let sgn = |x: T| if x == _0 { _0 } else { x.signum() };
            let set = |x: T, y: T, z: T| {
                let (x, z) = (sgn(x), sgn(z));
                let (x, z) = if x != _0 && z != _0 {
                    (x / sqrt2, z / sqrt2)
                } else {
                    (x, z)
                };
                *direction = [x, y, z];
            };
            let release = |key, rev_key, rev_val| {
                keys.remove(key);
                if keys.contains(rev_key) { rev_val } else { _0 }
            };
            match button {
                x if x == settings.move_forward_button =>
                    set(release(MOVE_FORWARD, MOVE_BACKWARD, _1), dy, dz),
                x if x == settings.move_backward_button =>
                    set(release(MOVE_BACKWARD, MOVE_FORWARD, -_1), dy, dz),
                x if x == settings.strafe_left_button =>
                    set(dx, dy, release(STRAFE_LEFT, STRAFE_RIGHT, -_1)),
                x if x == settings.strafe_right_button =>
                    set(dx, dy, release(STRAFE_RIGHT, STRAFE_LEFT, _1)),
                x if x == settings.fly_up_button =>
                    set(dx, release(FLY_UP, FLY_DOWN, -_1), dz),
                x if x == settings.fly_down_button =>
                    set(dx, release(FLY_DOWN, FLY_UP, _1), dz),
                x if x == settings.move_faster_button => *velocity = _1,
                _ => {}
            }
        });
    }
}

<commit_msg>Add semicolon to macro definition.<commit_after>#![allow(missing_docs)]
#![allow(dead_code)]

//! A first person camera.

use std::num::{Float, FloatMath};
use event::GenericEvent;
use input::Button;
use {
    input,
    Camera,
};
use vecmath::consts::Radians;

bitflags!(flags Keys: u8 {
    const MOVE_FORWARD  = 0b00000001,
    const MOVE_BACKWARD = 0b00000010,
    const STRAFE_LEFT   = 0b00000100,
    const STRAFE_RIGHT  = 0b00001000,
    const FLY_UP        = 0b00010000,
    const FLY_DOWN      = 0b00100000
});

/// First person camera settings.
pub struct FirstPersonSettings<T=f32> {
    /// Which button to press to move forward.
    pub move_forward_button: input::Button,
    /// Which button to press to move backward.
    pub move_backward_button: input::Button,
    /// Which button to press to strafe left.
    pub strafe_left_button: input::Button,
    /// Which button to press to strafe right.
    pub strafe_right_button: input::Button,
    /// Which button to press to fly up.
    pub fly_up_button: input::Button,
    /// Which button to press to fly down.
    pub fly_down_button: input::Button,
    /// Which button to press to move faster.
    pub move_faster_button: input::Button,
    /// The horizontal movement speed.
    ///
    /// This is measured in units per second.
    pub speed_horizontal: T,
    /// The vertical movement speed.
    ///
    /// This is measured in units per second.
    pub speed_vertical: T,
}

impl<T: Float> FirstPersonSettings<T> {
    /// Creates new first person camera settings with wasd defaults.
    pub fn keyboard_wasd() -> FirstPersonSettings<T> {
        use input::Button::Keyboard;
        use input::keyboard::Key;

        FirstPersonSettings {
            move_forward_button: Keyboard(Key::W),
            move_backward_button: Keyboard(Key::S),
            strafe_left_button: Keyboard(Key::A),
            strafe_right_button: Keyboard(Key::D),
            fly_up_button: Keyboard(Key::Space),
            fly_down_button: Keyboard(Key::LShift),
            move_faster_button: Keyboard(Key::LCtrl),
            speed_horizontal: Float::one(),
            speed_vertical: Float::one(),
        }
    }

    /// Creates a new first person camera settings with esdf defaults.
    pub fn keyboard_esdf() -> FirstPersonSettings<T> {
        use input::Button::Keyboard;
        use input::keyboard::Key;

        FirstPersonSettings {
            move_forward_button: Keyboard(Key::E),
            move_backward_button: Keyboard(Key::D),
            strafe_left_button: Keyboard(Key::S),
            strafe_right_button: Keyboard(Key::F),
            fly_up_button: Keyboard(Key::Space),
            fly_down_button: Keyboard(Key::Z),
            move_faster_button: Keyboard(Key::LShift),
            speed_horizontal: Float::one(),
            speed_vertical: Float::one(),
        }
    }
}

/// Models a flying first person camera.
pub struct FirstPerson<T=f32> {
    /// The first person camera settings.
    pub settings: FirstPersonSettings<T>,
    /// The yaw angle (in radians).
    pub yaw: T,
    /// The pitch angle (in radians).
    pub pitch: T,
    /// The direction we are heading.
    pub direction: [T, ..3],
    /// The position of the camera.
    pub position: [T, ..3],
    /// The velocity we are moving in the direction.
    pub velocity: T,
    /// The keys that are pressed.
    keys: Keys,
}

impl<T: Float + FromPrimitive + Copy + FloatMath + Radians>
FirstPerson<T> {

    /// Creates a new first person camera.
    pub fn new(
        position: [T, ..3],
        settings: FirstPersonSettings<T>
    ) -> FirstPerson<T> {
        let _0: T = Float::zero();
        FirstPerson {
            settings: settings,
            yaw: _0,
            pitch: _0,
            keys: Keys::empty(),
            direction: [_0, _0, _0],
            position: position,
            velocity: Float::one(),
        }
    }

    /// Computes camera.
    pub fn camera(&self, dt: f64) -> Camera<T> {
        let dt: T = FromPrimitive::from_f64(dt).unwrap();
        let dh = dt * self.velocity * self.settings.speed_horizontal;
        let [dx, dy, dz] = self.direction;
        let (s, c) = (self.yaw.sin(), self.yaw.cos());
        let mut camera = Camera::new([
            self.position[0] + (s * dx - c * dz) * dh,
            self.position[1] + dy * dt * self.settings.speed_vertical,
            self.position[2] + (s * dz + c * dx) * dh
        ]);
        camera.set_yaw_pitch(self.yaw, self.pitch);
        camera
    }

    /// Handles game event and updates camera.
    pub fn event<E: GenericEvent>(&mut self, e: &E) {
        use event::{ MouseRelativeEvent, PressEvent, ReleaseEvent, UpdateEvent };

        e.update(|args| {
            let cam = self.camera(args.dt);
            self.position = cam.position;
        });

        let &FirstPerson {
            ref mut yaw,
            ref mut pitch,
            ref mut keys,
            ref mut direction,
            ref mut velocity,
            ref settings,
            ..
        } = self;

        let pi: T = Radians::_180();
        let sqrt2: T = Float::sqrt2();
        let _0: T = Float::zero();
        let _1: T = Float::one();
        let _2: T = FromPrimitive::from_int(2).unwrap();
        let _3: T = FromPrimitive::from_int(3).unwrap();
        let _4: T = FromPrimitive::from_int(4).unwrap();
        let _360: T = FromPrimitive::from_int(360).unwrap();
        e.mouse_relative(|dx, dy| {
            let dx: T = FromPrimitive::from_f64(dx).unwrap();
            let dy: T = FromPrimitive::from_f64(dy).unwrap();
            *yaw = (*yaw - dx / _360 * pi / _4) % (_2 * pi);
            *pitch = *pitch + dy / _360 * pi / _4;
            *pitch = (*pitch).min(pi / _2).max(-pi / _2);
        });
        e.press(|button| {
            let [dx, dy, dz] = *direction;
            let sgn = |x: T| if x == _0 { _0 } else { x.signum() };
            let set = |k, x: T, y: T, z: T| {
                let (x, z) = (sgn(x), sgn(z));
                let (x, z) = if x != _0 && z != _0 {
                    (x / sqrt2, z / sqrt2)
                } else {
                    (x, z)
                };
                *direction = [x, y, z];
                keys.insert(k);
            };
            match button {
                x if x == settings.move_forward_button =>
                    set(MOVE_FORWARD, -_1, dy, dz),
                x if x == settings.move_backward_button =>
                    set(MOVE_BACKWARD, _1, dy, dz),
                x if x == settings.strafe_left_button =>
                    set(STRAFE_LEFT, dx, dy, _1),
                x if x == settings.strafe_right_button =>
                    set(STRAFE_RIGHT, dx, dy, -_1),
                x if x == settings.fly_up_button =>
                    set(FLY_UP, dx, _1, dz),
                x if x == settings.fly_down_button =>
                    set(FLY_DOWN, dx, -_1, dz),
                x if x == settings.move_faster_button => *velocity = _2,
                _ => {}
            }
        });
        e.release(|button| {
            let [dx, dy, dz] = *direction;
            let sgn = |x: T| if x == _0 { _0 } else { x.signum() };
            let set = |x: T, y: T, z: T| {
                let (x, z) = (sgn(x), sgn(z));
                let (x, z) = if x != _0 && z != _0 {
                    (x / sqrt2, z / sqrt2)
                } else {
                    (x, z)
                };
                *direction = [x, y, z];
            };
            let release = |key, rev_key, rev_val| {
                keys.remove(key);
                if keys.contains(rev_key) { rev_val } else { _0 }
            };
            match button {
                x if x == settings.move_forward_button =>
                    set(release(MOVE_FORWARD, MOVE_BACKWARD, _1), dy, dz),
                x if x == settings.move_backward_button =>
                    set(release(MOVE_BACKWARD, MOVE_FORWARD, -_1), dy, dz),
                x if x == settings.strafe_left_button =>
                    set(dx, dy, release(STRAFE_LEFT, STRAFE_RIGHT, -_1)),
                x if x == settings.strafe_right_button =>
                    set(dx, dy, release(STRAFE_RIGHT, STRAFE_LEFT, _1)),
                x if x == settings.fly_up_button =>
                    set(dx, release(FLY_UP, FLY_DOWN, -_1), dz),
                x if x == settings.fly_down_button =>
                    set(dx, release(FLY_DOWN, FLY_UP, _1), dz),
                x if x == settings.move_faster_button => *velocity = _1,
                _ => {}
            }
        });
    }
}

<|endoftext|>


<commit_before>use std::cmp;
use std::ops;

const BILLION: i64 = 1_000_000_000;

#[derive(Clone, Default, Serialize, Deserialize, Debug)]
pub struct Time {
    pub sec: i32,
    pub nsec: i32,
}

impl Time {
    #[inline]
    pub fn new() -> Time {
        Self::default()
    }

    #[inline]
    pub fn from_nanos(t: i64) -> Time {
        Time {
            sec: (t / BILLION) as i32,
            nsec: (t % BILLION) as i32,
        }
    }

    #[inline]
    pub fn nanos(&self) -> i64 {
        i64::from(self.sec) * BILLION + i64::from(self.nsec)
    }
}

impl cmp::PartialEq for Time {
    fn eq(&self, other: &Self) -> bool {
        self.nanos() == other.nanos()
    }
}

impl cmp::PartialOrd for Time {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        self.nanos().partial_cmp(&other.nanos())
    }
}

impl cmp::Eq for Time {}

impl cmp::Ord for Time {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.nanos().cmp(&other.nanos())
    }
}

#[derive(Clone, Default, Serialize, Deserialize, Debug)]
pub struct Duration {
    pub sec: i32,
    pub nsec: i32,
}

impl Duration {
    #[inline]
    pub fn new() -> Duration {
        Self::default()
    }

    #[inline]
    pub fn from_nanos(t: i64) -> Duration {
        Duration {
            sec: (t / BILLION) as i32,
            nsec: (t % BILLION) as i32,
        }
    }

    #[inline]
    fn nanos(&self) -> i64 {
        i64::from(self.sec) * BILLION + i64::from(self.nsec)
    }
}

impl cmp::PartialEq for Duration {
    fn eq(&self, other: &Self) -> bool {
        self.nanos() == other.nanos()
    }
}

impl cmp::PartialOrd for Duration {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        self.nanos().partial_cmp(&other.nanos())
    }
}

impl cmp::Eq for Duration {}

impl cmp::Ord for Duration {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.nanos().cmp(&other.nanos())
    }
}

impl ops::Add<Duration> for Time {
    type Output = Time;
    fn add(self, rhs: Duration) -> Self::Output {
        Time::from_nanos(self.nanos() + rhs.nanos())
    }
}

impl ops::Add<Duration> for Duration {
    type Output = Duration;
    fn add(self, rhs: Duration) -> Self::Output {
        Duration::from_nanos(self.nanos() + rhs.nanos())
    }
}

impl ops::Sub<Time> for Time {
    type Output = Duration;
    fn sub(self, rhs: Time) -> Self::Output {
        Duration::from_nanos(self.nanos() - rhs.nanos())
    }
}

impl ops::Sub<Duration> for Time {
    type Output = Time;
    fn sub(self, rhs: Duration) -> Self::Output {
        Time::from_nanos(self.nanos() - rhs.nanos())
    }
}

impl ops::Sub<Duration> for Duration {
    type Output = Duration;
    fn sub(self, rhs: Duration) -> Self::Output {
        Duration::from_nanos(self.nanos() - rhs.nanos())
    }
}

impl ops::Neg for Duration {
    type Output = Duration;
    fn neg(self) -> Self::Output {
        Duration {
            sec: -self.sec,
            nsec: -self.nsec,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{Duration, Time};

    #[test]
    fn from_nanos_works() {
        let time = Time::from_nanos(123456789987654321);
        assert_eq!(time.sec, 123456789);
        assert_eq!(time.nsec, 987654321);
        let time = Duration::from_nanos(123456789987654321);
        assert_eq!(time.sec, 123456789);
        assert_eq!(time.nsec, 987654321);
    }

    #[test]
    fn nanos_works() {
        let time = Time {
            sec: 123456789,
            nsec: 987654321,
        };
        assert_eq!(time.nanos(), 123456789987654321);
        let time = Duration {
            sec: 123456789,
            nsec: 987654321,
        };
        assert_eq!(time.nanos(), 123456789987654321);
    }

    #[test]
    fn works_with_negative() {
        let time = Time::from_nanos(-123456789987654321);
        assert_eq!(time.sec, -123456789);
        assert_eq!(time.nsec, -987654321);
        assert_eq!(time.nanos(), -123456789987654321);
        let time = Duration::from_nanos(-123456789987654321);
        assert_eq!(time.sec, -123456789);
        assert_eq!(time.nsec, -987654321);
        assert_eq!(time.nanos(), -123456789987654321);
    }
}
<commit_msg>Implement From<std::time::Duration> trait for Duration<commit_after>use std::cmp;
use std::convert::From;
use std::time;
use std::ops;

const BILLION: i64 = 1_000_000_000;

#[derive(Clone, Default, Serialize, Deserialize, Debug)]
pub struct Time {
    pub sec: i32,
    pub nsec: i32,
}

impl Time {
    #[inline]
    pub fn new() -> Time {
        Self::default()
    }

    #[inline]
    pub fn from_nanos(t: i64) -> Time {
        Time {
            sec: (t / BILLION) as i32,
            nsec: (t % BILLION) as i32,
        }
    }

    #[inline]
    pub fn nanos(&self) -> i64 {
        i64::from(self.sec) * BILLION + i64::from(self.nsec)
    }
}

impl cmp::PartialEq for Time {
    fn eq(&self, other: &Self) -> bool {
        self.nanos() == other.nanos()
    }
}

impl cmp::PartialOrd for Time {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        self.nanos().partial_cmp(&other.nanos())
    }
}

impl cmp::Eq for Time {}

impl cmp::Ord for Time {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.nanos().cmp(&other.nanos())
    }
}

#[derive(Clone, Default, Serialize, Deserialize, Debug)]
pub struct Duration {
    pub sec: i32,
    pub nsec: i32,
}

impl Duration {
    #[inline]
    pub fn new() -> Duration {
        Self::default()
    }

    #[inline]
    pub fn from_nanos(t: i64) -> Duration {
        Duration {
            sec: (t / BILLION) as i32,
            nsec: (t % BILLION) as i32,
        }
    }

    #[inline]
    fn nanos(&self) -> i64 {
        i64::from(self.sec) * BILLION + i64::from(self.nsec)
    }
}

impl cmp::PartialEq for Duration {
    fn eq(&self, other: &Self) -> bool {
        self.nanos() == other.nanos()
    }
}

impl cmp::PartialOrd for Duration {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        self.nanos().partial_cmp(&other.nanos())
    }
}

impl cmp::Eq for Duration {}

impl cmp::Ord for Duration {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.nanos().cmp(&other.nanos())
    }
}

impl ops::Add<Duration> for Time {
    type Output = Time;
    fn add(self, rhs: Duration) -> Self::Output {
        Time::from_nanos(self.nanos() + rhs.nanos())
    }
}

impl ops::Add<Duration> for Duration {
    type Output = Duration;
    fn add(self, rhs: Duration) -> Self::Output {
        Duration::from_nanos(self.nanos() + rhs.nanos())
    }
}

impl ops::Sub<Time> for Time {
    type Output = Duration;
    fn sub(self, rhs: Time) -> Self::Output {
        Duration::from_nanos(self.nanos() - rhs.nanos())
    }
}

impl ops::Sub<Duration> for Time {
    type Output = Time;
    fn sub(self, rhs: Duration) -> Self::Output {
        Time::from_nanos(self.nanos() - rhs.nanos())
    }
}

impl ops::Sub<Duration> for Duration {
    type Output = Duration;
    fn sub(self, rhs: Duration) -> Self::Output {
        Duration::from_nanos(self.nanos() - rhs.nanos())
    }
}

impl ops::Neg for Duration {
    type Output = Duration;
    fn neg(self) -> Self::Output {
        Duration {
            sec: -self.sec,
            nsec: -self.nsec,
        }
    }
}

impl From<time::Duration> for Duration {
    fn from(std_duration: time::Duration) -> Self {
        Duration {
            sec: std_duration.as_secs() as i32,
            nsec: std_duration.subsec_nanos() as i32,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{Duration, Time};
    use std::time;

    #[test]
    fn from_nanos_works() {
        let time = Time::from_nanos(123456789987654321);
        assert_eq!(time.sec, 123456789);
        assert_eq!(time.nsec, 987654321);
        let time = Duration::from_nanos(123456789987654321);
        assert_eq!(time.sec, 123456789);
        assert_eq!(time.nsec, 987654321);
    }

    #[test]
    fn nanos_works() {
        let time = Time {
            sec: 123456789,
            nsec: 987654321,
        };
        assert_eq!(time.nanos(), 123456789987654321);
        let time = Duration {
            sec: 123456789,
            nsec: 987654321,
        };
        assert_eq!(time.nanos(), 123456789987654321);
    }

    #[test]
    fn works_with_negative() {
        let time = Time::from_nanos(-123456789987654321);
        assert_eq!(time.sec, -123456789);
        assert_eq!(time.nsec, -987654321);
        assert_eq!(time.nanos(), -123456789987654321);
        let time = Duration::from_nanos(-123456789987654321);
        assert_eq!(time.sec, -123456789);
        assert_eq!(time.nsec, -987654321);
        assert_eq!(time.nanos(), -123456789987654321);
    }

    #[test]
    fn convert_works() {
        let std_duration = time::Duration::new(123, 456);
        let msg_duration = Duration::from(std_duration);
        assert_eq!(msg_duration.sec, 123);
        assert_eq!(msg_duration.nsec, 456);

        let std_duration2 = time::Duration::new(9876, 54321);
        let msg_duration2: Duration = std_duration2.into();
        assert_eq!(msg_duration2.sec, 9876);
        assert_eq!(msg_duration2.nsec, 54321);
    }
}
<|endoftext|>