<commit_before>use rutorch::*;
use std::ops::{Index, IndexMut};
//use std::convert::From;
use std::cmp::max;

use storage::*;
use rand;
use {Ixs, RcMut};

pub enum TensorKind {
    FloatTensor(Tensor<f32>),
    LongTensor(Tensor<i64>),
}

pub type TensorList<T> = Vec<Tensor<T>>;
pub type TensorKindList = Vec<TensorKind>;
pub type RefTensorList<'a, T> = Vec<&'a mut Tensor<T>>;
pub type RefTensorKindList<'a> = Vec<&'a mut TensorKind>;
pub type TensorId = i32;

pub struct Tensor<T> {
    pub id: i32,
    value: RcMut<TensorImpl<T, Output = T>>,
}

impl<T: Copy> Index<usize> for Tensor<T> {
    type Output = T;
    fn index(&self, idx: usize) -> &Self::Output {

        //        self.value.borrow_mut().index(idx as isize)
        unimplemented!()
    }
}

impl<'a, T: Copy> Index<usize> for &'a Tensor<T> {
    type Output = T;
    fn index(&self, idx: usize) -> &Self::Output {

        //        self.value.borrow_mut().index(idx as isize)
        unimplemented!()
    }
}

pub trait New<D, T> {
    fn new(args: D) -> T;
    fn new_(&self, args: D) -> T;
}

impl<T> New<usize, Tensor<T>> for Tensor<T> {
    fn new(args: usize) -> Self {
        unimplemented!()
    }
    fn new_(&self, args: usize) -> Self {
        unimplemented!()
    }
}
impl<T> New<Vec<usize>, Tensor<T>> for Tensor<T> {
    fn new(args: Vec<usize>) -> Self {
        unimplemented!()
    }
    fn new_(&self, args: Vec<usize>) -> Self {
        unimplemented!()
    }
}

impl<T> Tensor<T> {
    pub fn len(&self) -> usize {
        unimplemented!()
    }
    pub fn size(&self) -> Vec<usize> {
        unimplemented!()
    }
    pub fn zero_(&mut self) -> Self {
        unimplemented!()
    }
    pub fn add_(&mut self, rhs: T) {
        unimplemented!()
    }
    pub fn cuda(&self) -> Self {
        unimplemented!()
    }
    pub fn cpu(&self) -> Self {
        unimplemented!()
    }
    pub fn reduce_max(&self, axis: usize) -> (Self, Tensor<i64>) {
        unimplemented!()
    }
    pub fn tensor_eq(&self, rhs: &Self) -> Tensor<i64> {
        unimplemented!()
    }
    pub fn sum(&self) -> u32 {
        unimplemented!()
    }
    pub fn s(&self, dim: usize) -> Self {
        unimplemented!()
    }
}

impl<T> Default for Tensor<T> {
    fn default() -> Self {
        unimplemented!()
    }
}

impl<T> Clone for Tensor<T> {
    fn clone(&self) -> Self {
        Tensor {
            id: self.id,
            value: self.value.clone(),
        }
    }
}

impl<T: Copy> Index<isize> for Tensor<T> {
    type Output = T;

    fn index(&self, idx: isize) -> &Self::Output {
        unimplemented!()
    }
}
pub trait TensorImpl<T>: Index<Ixs, Output = T> {
    //fn view<'a>(&self, dims: &[i32]) -> Tensor<'a>;
}

pub struct FloatTensor {
    t: *mut THFloatTensor,
    storage: FloatStorage,
    dims: Vec<isize>,
}

impl Default for FloatTensor {
    fn default() -> Self {
        FloatTensor::new()
    }
}

impl FloatTensor {
    pub fn new() -> Self {
        unsafe {
            FloatTensor {
                t: THFloatTensor_new(),
                storage: FloatStorage::new(),
                dims: Vec::new(),
            }
        }
    }
    pub fn with_capacity(dims: &[isize]) -> Self {
        let size = dims.iter().product();
        let storage = FloatStorage::with_capacity(size);
        let strides = vec![1; dims.len()];
        let mut t = THFloatTensor {
            size: dims.clone().as_ptr() as *mut ::std::os::raw::c_long,
            stride: strides.as_ptr() as *mut ::std::os::raw::c_long,
            nDimension: dims.len() as i32,
            storage: storage.t,
            storageOffset: 0,
            refcount: 1,
            flag: TH_TENSOR_REFCOUNTED as i8,
        };
        FloatTensor {
            t: &mut t,
            storage: storage,
            dims: Vec::from(dims),
        }
    }
    pub fn randn(dims: &[isize]) -> Self {
        /* XXX */
        let mut t = FloatTensor::with_capacity(dims);
        for x in t.storage.iter_mut() {
            *x = rand::random::<f32>()
        }
        t
    }
}

impl<'a> Index<&'a [isize]> for FloatTensor {
    type Output = f32;

    fn index(&self, idx: &'a [isize]) -> &Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &self.storage[index]
    }
}

impl<'a> IndexMut<&'a [isize]> for FloatTensor {
    fn index_mut(&mut self, idx: &'a [isize]) -> &mut Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &mut self.storage[index]
    }
}
<commit_msg>add RTTI version of Tensor<commit_after>use rutorch::*;
use std::ops::{Index, IndexMut};
use std::convert::From;
use std::cmp::max;

use storage::*;
use rand;
use {Ixs, RcMut};

pub enum TensorKind {
    FloatTensor(Tensor<f32>),
    LongTensor(Tensor<i64>),
}

pub type TensorList<T> = Vec<Tensor<T>>;
pub type TensorKindList = Vec<TensorKind>;
pub type RefTensorList<'a, T> = Vec<&'a mut Tensor<T>>;
pub type RefTensorKindList<'a> = Vec<&'a mut TensorKind>;
pub type TensorId = i32;

impl<T> From<Tensor<T>> for TensorKind {
    default fn from(input: Tensor<T>) -> Self {
        unreachable!()
    }
}

impl From<Tensor<f32>> for TensorKind {
    fn from(input: Tensor<f32>) -> TensorKind {
        TensorKind::FloatTensor(input)
    }
}

impl From<Tensor<i64>> for TensorKind {
    fn from(input: Tensor<i64>) -> TensorKind {
        TensorKind::LongTensor(input)
    }
}

impl<T> From<TensorKind> for Tensor<T> {
    default fn from(input: TensorKind) -> Tensor<T> {
        panic!("bad cast")
    }
}
impl From<TensorKind> for Tensor<f32> {
    fn from(input: TensorKind) -> Self {
        match input {
            TensorKind::FloatTensor(v) => v,
            _ => unimplemented!(),
        }
    }
}

impl From<TensorKind> for Tensor<i64> {
    fn from(input: TensorKind) -> Self {
        match input {
            TensorKind::LongTensor(v) => v,
            _ => unimplemented!(),
        }
    }
}

pub struct Tensor<T> {
    pub id: i32,
    value: RcMut<TensorImpl<T, Output = T>>,
}

impl<T: Copy> Index<usize> for Tensor<T> {
    type Output = T;
    fn index(&self, idx: usize) -> &Self::Output {

        //        self.value.borrow_mut().index(idx as isize)
        unimplemented!()
    }
}

impl<T: Copy> Index<i32> for Tensor<T> {
    type Output = T;
    fn index(&self, idx: i32) -> &Self::Output {

        //        self.value.borrow_mut().index(idx as isize)
        unimplemented!()
    }
}

pub trait New<D, T> {
    fn new(args: D) -> T;
    fn new_(&self, args: D) -> T;
}

impl<T> New<usize, Tensor<T>> for Tensor<T> {
    fn new(args: usize) -> Self {
        unimplemented!()
    }
    fn new_(&self, args: usize) -> Self {
        unimplemented!()
    }
}
impl<T> New<Vec<usize>, Tensor<T>> for Tensor<T> {
    fn new(args: Vec<usize>) -> Self {
        unimplemented!()
    }
    fn new_(&self, args: Vec<usize>) -> Self {
        unimplemented!()
    }
}

impl<T> Tensor<T> {
    pub fn len(&self) -> usize {
        unimplemented!()
    }
    pub fn size(&self) -> Vec<usize> {
        unimplemented!()
    }
    pub fn zero_(&mut self) -> Self {
        unimplemented!()
    }
    pub fn add_(&mut self, rhs: T) {
        unimplemented!()
    }
    pub fn cuda(&self) -> Self {
        unimplemented!()
    }
    pub fn cpu(&self) -> Self {
        unimplemented!()
    }
    pub fn reduce_max(&self, axis: usize) -> (Self, Tensor<i64>) {
        unimplemented!()
    }
    pub fn tensor_eq(&self, rhs: &Self) -> Tensor<i64> {
        unimplemented!()
    }
    pub fn sum(&self) -> u32 {
        unimplemented!()
    }
    pub fn s(&self, dim: usize) -> Self {
        unimplemented!()
    }
}

impl<T> Default for Tensor<T> {
    fn default() -> Self {
        unimplemented!()
    }
}

impl<T> Clone for Tensor<T> {
    fn clone(&self) -> Self {
        Tensor {
            id: self.id,
            value: self.value.clone(),
        }
    }
}

impl<T: Copy> Index<isize> for Tensor<T> {
    type Output = T;

    fn index(&self, idx: isize) -> &Self::Output {
        unimplemented!()
    }
}
pub trait TensorImpl<T>: Index<Ixs, Output = T> {
    //fn view<'a>(&self, dims: &[i32]) -> Tensor<'a>;
}

pub struct FloatTensor {
    t: *mut THFloatTensor,
    storage: FloatStorage,
    dims: Vec<isize>,
}

impl Default for FloatTensor {
    fn default() -> Self {
        FloatTensor::new()
    }
}

impl FloatTensor {
    pub fn new() -> Self {
        unsafe {
            FloatTensor {
                t: THFloatTensor_new(),
                storage: FloatStorage::new(),
                dims: Vec::new(),
            }
        }
    }
    pub fn with_capacity(dims: &[isize]) -> Self {
        let size = dims.iter().product();
        let storage = FloatStorage::with_capacity(size);
        let strides = vec![1; dims.len()];
        let mut t = THFloatTensor {
            size: dims.clone().as_ptr() as *mut ::std::os::raw::c_long,
            stride: strides.as_ptr() as *mut ::std::os::raw::c_long,
            nDimension: dims.len() as i32,
            storage: storage.t,
            storageOffset: 0,
            refcount: 1,
            flag: TH_TENSOR_REFCOUNTED as i8,
        };
        FloatTensor {
            t: &mut t,
            storage: storage,
            dims: Vec::from(dims),
        }
    }
    pub fn randn(dims: &[isize]) -> Self {
        /* XXX */
        let mut t = FloatTensor::with_capacity(dims);
        for x in t.storage.iter_mut() {
            *x = rand::random::<f32>()
        }
        t
    }
}

impl<'a> Index<&'a [isize]> for FloatTensor {
    type Output = f32;

    fn index(&self, idx: &'a [isize]) -> &Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &self.storage[index]
    }
}

impl<'a> IndexMut<&'a [isize]> for FloatTensor {
    fn index_mut(&mut self, idx: &'a [isize]) -> &mut Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &mut self.storage[index]
    }
}
<|endoftext|>


<commit_before>use time;

pub fn cycle_anim<'a, T>(period_s: f64, frames: &'a [T]) -> &'a T {
    assert!(period_s > 0.0);
    assert!(frames.len() > 0);
    let idx = (time::precise_time_s() / period_s) as uint % frames.len();

    &frames[idx]
}

pub fn single_anim<'a, T>(start_s: f64, period_s: f64, frames: &'a [T]) -> &'a T {
    assert!(period_s > 0.0);
    assert!(frames.len() > 0);
    let mut idx = ((time::precise_time_s() - start_s) / period_s) as int;
    if idx < 0 { idx = 0; }
    if idx >= frames.len() as int { idx = frames.len() as int - 1; }

    &frames[idx as uint]
}

pub struct Ticker {
    period_s: f64,
    last_t: f64,
}

impl Ticker {
    pub fn new(period_s: f64) -> Ticker {
        Ticker {
            period_s: period_s,
            last_t: time::precise_time_s()
        }
    }

    pub fn get(&mut self) -> bool {
        let now = time::precise_time_s();
        if now - self.last_t > self.period_s {
            if now - self.last_t > self.period_s * 2.0 {
                // Bring the clock up to speed.
                self.last_t = now;
            } else {
                self.last_t += self.period_s;
            }
            true
        } else {
            false
        }
    }
}
<commit_msg>More timing utilities<commit_after>use time;
use std::io::timer;

pub fn cycle_anim<'a, T>(period_s: f64, frames: &'a [T]) -> &'a T {
    assert!(period_s > 0.0);
    assert!(frames.len() > 0);
    let idx = (time::precise_time_s() / period_s) as uint % frames.len();

    &frames[idx]
}

pub fn single_anim<'a, T>(start_s: f64, period_s: f64, frames: &'a [T]) -> &'a T {
    assert!(period_s > 0.0);
    assert!(frames.len() > 0);
    let mut idx = ((time::precise_time_s() - start_s) / period_s) as int;
    if idx < 0 { idx = 0; }
    if idx >= frames.len() as int { idx = frames.len() as int - 1; }

    &frames[idx as uint]
}

pub struct Ticker {
    period_s: f64,
    last_t: f64,
}

impl Ticker {
    pub fn new(period_s: f64) -> Ticker {
        Ticker {
            period_s: period_s,
            last_t: time::precise_time_s()
        }
    }

    fn time_remaining(&mut self) -> Option<f64> {
        let now = time::precise_time_s();
        if now - self.last_t > self.period_s {
            if now - self.last_t > self.period_s * 2.0 {
                // Bring the clock up to speed if running very late.
                self.last_t = now;
            } else {
                self.last_t += self.period_s;
            }
            None
        } else {
            Some(self.period_s - (now - self.last_t))
        }
    }

    pub fn get(&mut self) -> bool {
        self.time_remaining().is_none()
    }

    pub fn wait_for_tick(&mut self) {
        match self.time_remaining() {
            Some(t) => {
                timer::sleep((t * 1000.0) as u64);
                self.last_t += self.period_s;
            }
            _ => {}
        }
    }
}

pub struct TimePerFrame {
    update_weight: f64,
    start_t: f64,
    pub average: f64,
    pub last: f64,
}

impl TimePerFrame {
    pub fn new(update_weight: f64) -> TimePerFrame {
        assert!(update_weight >= 0.0 && update_weight <= 1.0);
        TimePerFrame {
            update_weight: update_weight,
            start_t: time::precise_time_s(),
            average: 0.0,
            last: 0.0,
        }
    }

    pub fn begin(&mut self) {
        self.start_t = time::precise_time_s();
    }

    pub fn end(&mut self) {
        self.last = time::precise_time_s() - self.start_t;
        self.average = self.update_weight * self.last +
            (1.0 - self.update_weight) * self.average;
    }
}
<|endoftext|>


<commit_before>use common::*;
use std::io::{Read, Write, Result};

mod events;
mod memory;
mod modes;
mod opcodes;
mod registers;

use self::memory::*;
use self::modes::*;
use self::opcodes::*;
use self::registers::*;

pub struct VM<R: Read, W: Write> {
    input: R,
    output: W,

    registers: Registers,
    memory: Memory,
}

impl<R: Read, W: Write> VM<R, W> {
    pub fn new(input: R, output: W, executable: Data) -> Self {
        let memory = Memory::from_executable(executable);

        VM {
            input: input,
            output: output,
            registers: [0; REGISTERS],
            memory: memory,
        }
    }

    pub fn run(&mut self) {
        self.set_register(PC, CODE_OFFSET as Word);

        let mut args = vec![];
        while self.memory.is_in_code(self.get_register(PC)) {
            self.fetch()
                .decode(&mut args)
                .execute(&args)
                .process_events();
            args.clear();
        }
    }

    pub fn stack(&self) -> DataSlice {
        let sp = self.get_register(SP);
        self.memory.stack(sp)
    }

    pub fn data(&self) -> DataSlice {
        self.memory.data()
    }

    fn fetch(&mut self) -> &mut Self {
        let code_offset = self.get_register(PC);
        let opcode = self.memory.get(code_offset) as Word;
        self.set_register(IR, opcode);
        self.increment_register(PC);
        self
    }

    fn decode(&mut self, args: &mut Words) -> &mut Self {
        unimplemented!()
        // match self.get_register(IR) as u8 {
        //     MOV => {
        //         args.push(self.read_memory());
        //         args.push(self.read_memory());
        //     }
        //     _ => unimplemented!(),
        // }
        // self
    }

    fn execute(&mut self, args: WordsSlice) -> &mut Self {
        unimplemented!()
    }

    fn process_events(&mut self) {
        unimplemented!()
    }

    // fn read_memory(&mut self) -> Word {
    //     let code_offset = self.get_register(PC);
    //     let mode = self.memory.get(code_offset);
    //     self.increment_register(PC);
    //
    //     match mode {
    //         REG => {
    //             let code_offset = self.get_register(PC);
    //             self.increment_register(PC);
    //             let register_id = self.memory.get(code_offset);
    //             self.get_register(register_id)
    //         }
    //         PTR => unimplemented!(),
    //         PTR_WITH_OFFSET => unimplemented!(),
    //         VALUE => {
    //             let code_offset = self.get_register(PC) as usize;
    //             self.increment_register(PC);
    //             let value = self.memory.read_word(code_offset);
    //             for _ in 0..WORD_SIZE {
    //                 self.increment_register(PC);
    //             }
    //             value
    //         }
    //         _ => unreachable!(),
    //     }
    // }

    fn get_register(&self, id: u8) -> Word {
        self.registers[id as usize]
    }

    fn set_register(&mut self, id: u8, value: Word) {
        self.registers[id as usize] = value;
    }

    fn increment_register(&mut self, id: u8) {
        self.registers[id as usize] += 1;
    }
}

#[cfg(test)]
mod tests {
    use self::events::*;
    use std::io::{BufReader, BufWriter};
    use super::*;

    #[cfg_attr(rustfmt, rustfmt_skip)]
    #[test]
    fn simple() {
        {
            let (output, vm) = run(&[], vec![]);

            assert!(output.is_empty());
            assert!(vm.stack().is_empty());
            assert!(vm.data().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 3,                       // b
                PUSH, 4,                       // a
                ADD];                          // pop 2 bytes,
                                               // add (a + b) and push
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[7], vm.stack());
            assert!(output.is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b
                PUSH, 10,                      // a
                DEC,                           // a--
                INT, OUTPUT,
                JNE, 6, 0];                    // a != b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[9, 8, 7, 6, 5, 4, 3, 2, 1, 0], output.as_slice());
            assert_eq!([0], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // zero
                PUSH, 0,                       // offset

                // label loop
                LOAD, PTR_WITH_OFFSET, 21, 0,  // d = [data segment + offset]
                INT, OUTPUT,                   // print d
                JE, 20, 0,                     // if d == zero: goto end
                POP,                           // pop d
                INC,                           // offset++
                JMP, 6, 0,                     // goto loop

                // label end
                NOP,                           // optional
                3, 2, 1, 0];
            let data_size = 4;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(4, vm.data().len());
            assert_eq!(&[0], vm.stack());
            assert_eq!(&[3, 2, 1], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b

                // label loop
                INT, INPUT,                    // a
                INT, OUTPUT,                   // print a
                JE, 15, 0,                     // if a == b: goto end
                POP,                           // remove a
                JMP, 4, 0                      // goto loop

                // label end
                // NOP                         // optional
                ];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let input = [3, 2, 1, 0];
            let (output, vm) = run(&input, executable);

            assert_eq!(&[0, 0], vm.stack());
            assert_eq!(&[3, 2, 1, 0], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 4,                       // b
                PUSH, 12,                      // a
                DIV];                          // a / b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert!(output.is_empty());
            assert_eq!(&[3], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b
                PUSH, 1,                       // a
                DIV];                          // a / b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Unknown Error", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                POP];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Segfault", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 255, 255];          // access violation
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Segfault", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 2, 0];              // try to load code segment
                                               // as data segment
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Segfault", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 6, 0,
                123];
            let data_size = 1;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[123], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // zero
                                               // loop:
                INT, INPUT,                    //   x = read
                CALL, PTR, 20, 0,              //   x = f(x)
                INT, OUTPUT,                   //   print x
                JE, 18, 0,                     // if x == zero: goto exit
                POP,                           // pop x
                JMP, 2, 0,                     // goto loop
                INT, TERMINATE,                // exit:

                                               // f:
                PUSH, 2,
                MUL,                           // a = a * 2
                RET];

            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let input = [3, 2, 1, 0];
            let (output, vm) = run(&input, executable);

            assert_eq!(&[6, 4, 2, 0], output.as_slice());
            assert_eq!(&[0, 0], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // i
                                               // loop:
                LOAD, 19, 0,                   // x
                JLE, 19, 0,                    // if x <= i goto: end
                DEC,
                STORE, 19, 0,                  // x
                POP,
                INC,
                JMP, 4, 0,                     // goto loop
                                               // end:
                5];                            // x
            let data_size = 1;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[3], vm.stack());
            assert_eq!(&[2], vm.data());
        }
    }

    fn run(input: DataSlice,
           executable: Data)
           -> (Data, VM<BufReader<DataSlice>, BufWriter<Data>>) {
        let input = BufReader::new(input);

        let output: Data = vec![];
        let output = BufWriter::new(output);

        let mut vm = VM::new(input, output, executable);
        vm.run();

        let output = vm.output
            .get_mut()
            .by_ref()
            .iter()
            .map(|x| *x)
            .collect::<Data>();

        (output, vm)
    }
}
<commit_msg>update tests<commit_after>use common::*;
use std::io::{Read, Write, Result};

mod events;
mod memory;
mod modes;
mod opcodes;
mod registers;

use self::memory::*;
use self::modes::*;
use self::opcodes::*;
use self::registers::*;

pub struct VM<R: Read, W: Write> {
    input: R,
    output: W,

    registers: Registers,
    memory: Memory,
}

impl<R: Read, W: Write> VM<R, W> {
    pub fn new(input: R, output: W, executable: Data) -> Self {
        let memory = Memory::from_executable(executable);

        VM {
            input: input,
            output: output,
            registers: [0; REGISTERS],
            memory: memory,
        }
    }

    pub fn run(&mut self) {
        self.set_register(PC, CODE_OFFSET as Word);

        let mut args = vec![];
        while self.memory.is_in_code(self.get_register(PC)) {
            self.fetch()
                .decode(&mut args)
                .execute(&args)
                .process_events();
            args.clear();
        }
    }

    pub fn stack(&self) -> DataSlice {
        let sp = self.get_register(SP);
        self.memory.stack(sp)
    }

    pub fn data(&self) -> DataSlice {
        self.memory.data()
    }

    fn fetch(&mut self) -> &mut Self {
        let code_offset = self.get_register(PC);
        let opcode = self.memory.get(code_offset) as Word;
        self.set_register(IR, opcode);
        self.increment_register(PC);
        self
    }

    fn decode(&mut self, args: &mut Words) -> &mut Self {
        unimplemented!()
        // match self.get_register(IR) as u8 {
        //     MOV => {
        //         args.push(self.read_memory());
        //         args.push(self.read_memory());
        //     }
        //     _ => unimplemented!(),
        // }
        // self
    }

    fn execute(&mut self, args: WordsSlice) -> &mut Self {
        unimplemented!()
    }

    fn process_events(&mut self) {
        unimplemented!()
    }

    // fn read_memory(&mut self) -> Word {
    //     let code_offset = self.get_register(PC);
    //     let mode = self.memory.get(code_offset);
    //     self.increment_register(PC);
    //
    //     match mode {
    //         REG => {
    //             let code_offset = self.get_register(PC);
    //             self.increment_register(PC);
    //             let register_id = self.memory.get(code_offset);
    //             self.get_register(register_id)
    //         }
    //         PTR => unimplemented!(),
    //         PTR_WITH_OFFSET => unimplemented!(),
    //         VALUE => {
    //             let code_offset = self.get_register(PC) as usize;
    //             self.increment_register(PC);
    //             let value = self.memory.read_word(code_offset);
    //             for _ in 0..WORD_SIZE {
    //                 self.increment_register(PC);
    //             }
    //             value
    //         }
    //         _ => unreachable!(),
    //     }
    // }

    fn get_register(&self, id: u8) -> Word {
        self.registers[id as usize]
    }

    fn set_register(&mut self, id: u8, value: Word) {
        self.registers[id as usize] = value;
    }

    fn increment_register(&mut self, id: u8) {
        self.registers[id as usize] += 1;
    }
}

#[cfg(test)]
mod tests {
    use self::events::*;
    use std::io::{BufReader, BufWriter};
    use super::*;

    #[cfg_attr(rustfmt, rustfmt_skip)]
    #[test]
    fn simple() {
        {
            let executable = vec![0, 0];
            let (output, vm) = run(&[], executable);

            assert!(vm.stack().is_empty());
            assert!(vm.data().is_empty());
            assert!(output.is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 3,                       // b
                PUSH, 4,                       // a
                ADD];                          // pop 2 bytes,
                                               // add (a + b) and push
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[7], vm.stack());
            assert!(vm.data().is_empty());
            assert!(output.is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b
                PUSH, 10,                      // a
                DEC,                           // a--
                INT, OUTPUT,
                JNE, 6, 0];                    // a != b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!([0], vm.stack());
            assert!(vm.data().is_empty());
            assert_eq!(&[9, 8, 7, 6, 5, 4, 3, 2, 1, 0], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // zero
                PUSH, 0,                       // offset

                // label loop
                LOAD, PTR_WITH_OFFSET, 21, 0,  // d = [data segment + offset]
                INT, OUTPUT,                   // print d
                JE, 20, 0,                     // if d == zero: goto end
                POP,                           // pop d
                INC,                           // offset++
                JMP, 6, 0,                     // goto loop

                // label end
                NOP,                           // optional
                3, 2, 1, 0];
            let data_size = 4;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[0], vm.stack());
            assert_eq!(&[3, 2, 1, 0], vm.data());
            assert_eq!(&[3, 2, 1], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b

                // label loop
                INT, INPUT,                    // a
                INT, OUTPUT,                   // print a
                JE, 15, 0,                     // if a == b: goto end
                POP,                           // remove a
                JMP, 4, 0                      // goto loop

                // label end
                // NOP                         // optional
                ];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let input = [3, 2, 1, 0];
            let (output, vm) = run(&input, executable);

            assert_eq!(&[0, 0], vm.stack());
            assert!(vm.data().is_empty());
            assert_eq!(&[3, 2, 1, 0], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 4,                       // b
                PUSH, 12,                      // a
                DIV];                          // a / b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[3], vm.stack());
            assert!(vm.data().is_empty());
            assert!(output.is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b
                PUSH, 1,                       // a
                DIV];                          // a / b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert!(vm.stack().is_empty());
            assert!(vm.data().is_empty());
            assert_eq!(b"Unknown Error", output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                POP];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert!(vm.stack().is_empty());
            assert!(vm.data().is_empty());
            assert_eq!(b"Segfault", output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 255, 255];          // access violation
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert!(vm.stack().is_empty());
            assert!(vm.data().is_empty());
            assert_eq!(b"Segfault", output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 2, 0];              // try to load code segment
                                               // as data segment
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert!(vm.stack().is_empty());
            assert!(vm.data().is_empty());
            assert_eq!(b"Segfault", output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 6, 0,
                123];
            let data_size = 1;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[123], vm.stack());
            assert!(vm.data().is_empty());
            assert!(output.is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // zero
                                               // loop:
                INT, INPUT,                    //   x = read
                CALL, PTR, 20, 0,              //   x = f(x)
                INT, OUTPUT,                   //   print x
                JE, 18, 0,                     // if x == zero: goto exit
                POP,                           // pop x
                JMP, 2, 0,                     // goto loop
                INT, TERMINATE,                // exit:

                                               // f:
                PUSH, 2,
                MUL,                           // a = a * 2
                RET];

            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let input = [3, 2, 1, 0];
            let (output, vm) = run(&input, executable);

            assert_eq!(&[0, 0], vm.stack());
            assert!(vm.data().is_empty());
            assert_eq!(&[6, 4, 2, 0], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // i
                                               // loop:
                LOAD, 19, 0,                   // x
                JLE, 19, 0,                    // if x <= i goto: end
                DEC,
                STORE, 19, 0,                  // x
                POP,
                INC,
                JMP, 4, 0,                     // goto loop
                                               // end:
                5];                            // x
            let data_size = 1;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[3], vm.stack());
            assert_eq!(&[2], vm.data());
            assert!(output.is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // i
                PUSH, 5,                       // x
                                               // loop:
                DEC,
                SWP,
                INC,
                SWP,
                JLE, 16, 0,                    // if x <= i: goto end
                JMP, 6, 0];                    // goto loop
            let data_size = 1;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[2, 3], vm.stack());
            assert!(vm.data().is_empty());
            assert!(output.is_empty());
        }
    }

    fn run(input: DataSlice,
           executable: Data)
           -> (Data, VM<BufReader<DataSlice>, BufWriter<Data>>) {
        let input = BufReader::new(input);

        let output: Data = vec![];
        let output = BufWriter::new(output);

        let mut vm = VM::new(input, output, executable);
        vm.run();

        let output = vm.output
            .get_mut()
            .by_ref()
            .iter()
            .map(|x| *x)
            .collect::<Data>();

        (output, vm)
    }
}
<|endoftext|>


<commit_before>//! This is a simle crate module

use std::io::BufRead;
use std::io::BufReader;
use std::fs::File;
use std::path::PathBuf;

use rustc_serialize::json::Json;
use rustc_serialize::json::ParserError;

/// We are only using crate name and versions in this program
#[derive(Debug)]
pub struct Crate {
    pub name: String,
    pub versions: Vec<String>,
}

#[derive(Debug)]
pub enum CrateOpenError {
    FileNotFound,
    ParseError(ParserError),
    NotObject,
    NameNotFound,
    VersNotFound,
}

impl Crate {
    /// Returns a new Crate
    ///
    /// # Examples
    ///
    /// ```
    /// let crte = Crate::new("cratesfyi".to_string(),
    ///                       vec!["0.1.0".to_string()]);
    /// assert_eq!(crte.name, "cratesfyi");
    /// ```
    pub fn new(name: String, versions: Vec<String>) -> Crate {
        Crate {
            name: name,
            versions: versions,
        }
    }

    pub fn from_cargo_index_file(path: PathBuf) -> Result<Crate, CrateOpenError> {

        let mut file = match File::open(path) {
            Ok(f) => BufReader::new(f),
            Err(_) => return Err(CrateOpenError::FileNotFound),
        };

        let mut line = String::new();

        let mut name = String::new();
        let mut versions = Vec::new();

        while file.read_line(&mut line).unwrap() > 0 {

            let (cname, vers) = match Crate::parse_cargo_index_line(&line) {
                Ok((c, v)) => (c, v),
                Err(e) => return Err(e)
            };

            name = cname;
            versions.push(vers);

            line.clear();
        }

        versions.reverse();

        Ok(Crate {
            name: name,
            versions: versions
        })
    }

    fn parse_cargo_index_line(line: &String) -> Result<(String, String), CrateOpenError> {

        let data = match Json::from_str(line.trim()) {
            Ok(json) => json,
            Err(e) => return Err(CrateOpenError::ParseError(e)),
        };

        let obj = match data.as_object() {
            Some(o) => o,
            None => return Err(CrateOpenError::NotObject),
        };

        // try to get name and vers(ion)
        let crate_name = match obj.get("name") {
            Some(n) => {
                match n.as_string() {
                    Some(s) => s,
                    None => return Err(CrateOpenError::NameNotFound),
                }
            }
            None => return Err(CrateOpenError::NameNotFound),
        };

        let vers = match obj.get("vers") {
            Some(n) => {
                match n.as_string() {
                    Some(s) => s,
                    None => return Err(CrateOpenError::VersNotFound),
                }
            }
            None => return Err(CrateOpenError::VersNotFound),
        };

        Ok((String::from(crate_name), String::from(vers)))
    }

    pub fn get_version_index(&self, requested_version: &str) -> Option<usize> {
        for i in 0..self.versions.len() {
            if self.versions[i] == requested_version {
                return Some(i);
            }
        }
        None
    }

    pub fn canonical_name(&self, version_index: usize) -> String {
        format!("{}-{}", self.name, self.versions[version_index])
    }

}

#[test]
fn test_get_vesion_index() {
    let crte = Crate::new("cratesfyi".to_string(),
                          vec!["0.1.0".to_string(), "0.1.1".to_string()]);
    assert_eq!(crte.get_version_index("0.1.0"), Some(0));
    assert_eq!(crte.get_version_index("0.1.1"), Some(1));
    assert_eq!(crte.get_version_index("0.1.2"), None);
}
<commit_msg>Add from_cargo_index file and version_starts with<commit_after>//! This is a simle crate module

use std::io::prelude::*;
use std::io::BufReader;
use std::io::Error;
use std::fs::File;
use std::path::PathBuf;

use rustc_serialize::json::Json;
use rustc_serialize::json::ParserError;

/// Really simple crate model
#[derive(Debug)]
pub struct Crate {
    /// Name of crate
    pub name: String,
    /// Versions of crate
    pub versions: Vec<String>,
}

#[derive(Debug)]
pub enum CrateOpenError {
    FileNotFound,
    ParseError(ParserError),
    IoError(Error),
    NotObject,
    NameNotFound,
    VersNotFound,
}

impl Crate {
    /// Returns a new Crate
    ///
    /// # Examples
    ///
    /// ```
    /// let crte = Crate::new("cratesfyi".to_string(),
    ///                       vec!["0.1.0".to_string()]);
    /// assert_eq!(crte.name, "cratesfyi");
    /// ```
    pub fn new(name: String, versions: Vec<String>) -> Crate {
        Crate {
            name: name,
            versions: versions,
        }
    }

    pub fn from_cargo_index_file(path: PathBuf) -> Result<Crate, CrateOpenError> {

        let mut file = match File::open(path) {
            Ok(f) => BufReader::new(f),
            Err(_) => return Err(CrateOpenError::FileNotFound),
        };

        let mut line = String::new();

        let mut name = String::new();
        let mut versions = Vec::new();

        while file.read_line(&mut line).unwrap() > 0 {

            let (cname, vers) = match Crate::parse_cargo_index_line(&line) {
                Ok((c, v)) => (c, v),
                Err(e) => return Err(e)
            };

            name = cname;
            versions.push(vers);

            line.clear();
        }

        versions.reverse();

        Ok(Crate {
            name: name,
            versions: versions
        })
    }

    /// Create Crate from crate name and try to find it in crates.io-index
    /// to load versions
    pub fn from_cargo_index_path(name: &str, path: &PathBuf) -> Result<Crate, CrateOpenError> {

        if !path.is_dir() {
            return Err(CrateOpenError::FileNotFound);
        }

        for file in try!(path.read_dir().map_err(CrateOpenError::IoError)) {

            let file = try!(file.map_err(CrateOpenError::IoError));

            let path = file.path();

            // skip files under .git and config.json
            if path.to_str().unwrap().contains(".git") ||
                path.file_name().unwrap() == "config.json" {
                    continue;
                }

            if path.is_dir() {
                if let Ok(c) = Crate::from_cargo_index_path(&name, &path) {
                    return Ok(c);
                }
            } else if file.file_name().into_string().unwrap() == name {
                return Crate::from_cargo_index_file(path);
            }

        }

        Err(CrateOpenError::FileNotFound)
    }

    fn parse_cargo_index_line(line: &String) -> Result<(String, String), CrateOpenError> {

        let data = match Json::from_str(line.trim()) {
            Ok(json) => json,
            Err(e) => return Err(CrateOpenError::ParseError(e)),
        };

        let obj = match data.as_object() {
            Some(o) => o,
            None => return Err(CrateOpenError::NotObject),
        };

        // try to get name and vers(ion)
        let crate_name = match obj.get("name") {
            Some(n) => {
                match n.as_string() {
                    Some(s) => s,
                    None => return Err(CrateOpenError::NameNotFound),
                }
            }
            None => return Err(CrateOpenError::NameNotFound),
        };

        let vers = match obj.get("vers") {
            Some(n) => {
                match n.as_string() {
                    Some(s) => s,
                    None => return Err(CrateOpenError::VersNotFound),
                }
            }
            None => return Err(CrateOpenError::VersNotFound),
        };

        Ok((String::from(crate_name), String::from(vers)))
    }

    pub fn get_version_index(&self, requested_version: &str) -> Option<usize> {
        for i in 0..self.versions.len() {
            if self.versions[i] == requested_version {
                return Some(i);
            }
        }
        None
    }

    pub fn version_starts_with(&self, version: String) -> Option<usize> {
        // if version is "*" return latest version index which is 0
        if version == "*" {
            return Some(0);
        }
        for i in 0..self.versions.len() {
            if self.versions[i].starts_with(&version) {
                return Some(i)
            }
        }
        None
    }

    pub fn canonical_name(&self, version_index: usize) -> String {
        format!("{}-{}", self.name, self.versions[version_index])
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use std::env;
    use std::path::PathBuf;

    #[test]
    fn test_get_vesion_index() {
        let crte = Crate::new("cratesfyi".to_string(),
                              vec!["0.1.0".to_string(), "0.1.1".to_string()]);
        assert_eq!(crte.get_version_index("0.1.0"), Some(0));
        assert_eq!(crte.get_version_index("0.1.1"), Some(1));
        assert_eq!(crte.get_version_index("0.1.2"), None);
    }

    // Rest of the tests only works if crates.io-index is exists in:
    // ../cratesfyi-prefix/crates.io-index

    #[test]
    #[ignore]
    fn test_from_cargo_index_path() {
        let mut path = PathBuf::from(env::current_dir().unwrap());
        path.push("../cratesfyi-prefix/crates.io-index");

        if !path.exists() {
            return;
        }

        let crte = Crate::from_cargo_index_path("rand", &path).unwrap();
        assert_eq!(crte.name, "rand");
        assert!(crte.versions.len() > 0);
    }

    #[test]
    #[ignore]
    fn test_version_starts_with() {
        let mut path = PathBuf::from(env::current_dir().unwrap());
        path.push("../cratesfyi-prefix/crates.io-index");

        if !path.exists() {
            return;
        }

        let crte = Crate::from_cargo_index_path("rand", &path).unwrap();
        assert!(crte.version_starts_with("0.1".to_string()).is_some());
        assert!(crte.version_starts_with("*".to_string()).is_some());
        assert!(crte.version_starts_with("999.099.99".to_string()).is_none());
    }

}
<|endoftext|>


<commit_before>//! Window abstraction

use std::cell::RefCell;
use input::InputEvent;
use current::{ Get, Modifier, Set, Usage };

use GenericEvent;

/// Whether window should close or not.
pub struct ShouldClose(pub bool);

/// Work-around trait for `Get<ShouldClose>`.
/// Used to support generic constraints.
pub trait GetShouldClose: Get<ShouldClose> {
    /// Returns whether window should close.
    fn get_should_close(&self) -> ShouldClose {
        self.get()
    }
}

impl<T: Get<ShouldClose>> GetShouldClose for T {}

/// Work-around trait for `Set<ShouldClose>`.
/// Used to support generic constraints.
pub trait SetShouldClose: Set<ShouldClose> {
    /// Sets whether window should close.
    fn set_should_close(&mut self, val: ShouldClose) {
        self.set_mut(val);
    }
}

impl<T: Set<ShouldClose>> SetShouldClose for T {}

/// The size of the window.
pub struct Size(pub [u32, ..2]);

/// Work-around trait for `Get<Size>`.
/// Used to support generic constraints.
pub trait GetSize: Get<Size> {
    /// Returns the size of window.
    fn get_size(&self) -> Size {
        self.get()
    }
}

impl<T: Get<Size>> GetSize for T {}

/// Work-around trait for `Set<Size>`.
/// Used to support generic constraints.
pub trait SetSize: Set<Size> {
    /// Sets size of window.
    fn set_size(&mut self, val: Size) {
        self.set_mut(val);
    }
}

impl<T: Set<Size>> SetSize for T {}

/// The title of the window.
pub struct Title(pub String);

/// Work-around trait for `Get<Title>`.
/// Used to support generic constraints.
pub trait GetTitle: Get<Title> {
    /// Returns the title of the window.
    fn get_title(&self) -> Title {
        self.get()
    }
}

impl<T: Get<Title>> GetTitle for T {}

/// Work-around trait for `Set<Title>`.
/// Used to support generic constraints.
pub trait SetTitle: Set<Title> {
    /// Sets title of window.
    fn set_title(&mut self, val: Title) {
        self.set_mut(val);
    }
}

impl<T: Set<Title>> SetTitle for T {}

/// The anti-aliasing samples when rendering.
pub struct Samples(pub u8);

/// Work-around trait for `Get<Samples>`.
/// Used to support generic constraints.
pub trait GetSamples: Get<Samples> {
    /// Returns the antialiasing samples when rendering.
    fn get_samples(&self) -> Samples {
        self.get()
    }
}

impl<T: Get<Samples>> GetSamples for T {}

/// Work-around trait for `Set<Samples>`.
/// Used to support generic constraints.
pub trait SetSamples: Set<Samples> {
    /// Sets antialiasing samples of window.
    fn set_samples(&mut self, val: Samples) {
        self.set_mut(val);
    }
}

impl<T: Set<Samples>> SetSamples for T {}

/// Whether window is opened in full screen mode.
pub struct Fullscreen(pub bool);

/// Work-around trait for `Get<Fullscreen>`.
/// Used to support generic constraints.
pub trait GetFullscreen: Get<Fullscreen> {
    /// Returns whether window is in full screen mode.
    fn get_fullscreen(&self) -> Fullscreen {
        self.get()
    }
}

impl<T: Get<Fullscreen>> GetFullscreen for T {}

/// Work-around trait for `Set<Fullscreen>`.
/// Used to support generic constraints.
pub trait SetFullscreen: Set<Fullscreen> {
    /// Sets window to fullscreen mode.
    fn set_fullscreen(&mut self, val: Fullscreen) {
        self.set_mut(val);
    }
}

impl<T: Set<Fullscreen>> SetFullscreen for T {}

/// Whether to exit when pressing the Esc keyboard button.
pub struct ExitOnEsc(pub bool);

/// Work-around trait for `Get<ExitOnEsc>`.
/// Used to support generic constraints.
pub trait GetExitOnEsc: Get<ExitOnEsc> {
    /// Returns whether window exits when pressing Esc.
    fn get_exit_on_esc(&self) -> ExitOnEsc {
        self.get()
    }
}

impl<T: Get<ExitOnEsc>> GetExitOnEsc for T {}

/// Work-around trait for `Set<ExitOnEsc>`.
/// Used to support generic constraints.
pub trait SetExitOnEsc: Set<ExitOnEsc> {
    /// Sets exit when pressing Esc.
    fn set_exit_on_esc(&mut self, val: ExitOnEsc) {
        self.set_mut(val);
    }
}

impl<T: Set<ExitOnEsc>> SetExitOnEsc for T {}

/// Whether to capture the mouse cursor.
pub struct CaptureCursor(pub bool);

/// Work-around trait for `Get<CaptureCursor>`.
/// Used to support generic constraints.
pub trait GetCaptureCursor: Get<CaptureCursor> {
    /// Returns whether window captures cursor.
    fn get_capture_cursor(&self) -> CaptureCursor {
        self.get()
    }
}

impl<T: Get<CaptureCursor>> GetCaptureCursor for T {}

/// Work-around trait for `Set<CaptureCursor>`.
/// Used to support generic constraints.
pub trait SetCaptureCursor: Set<CaptureCursor> {
    /// Sets capture cursor.
    fn set_capture_cursor(&mut self, val: CaptureCursor) {
        self.set_mut(val);
    }
}

impl<T: Set<CaptureCursor>> SetCaptureCursor for T {}

/// The draw size of the window.
pub struct DrawSize(pub [u32, ..2]);

/// Work-around trait for `Get<DrawSize>`.
/// Used to support generic constraints.
pub trait GetDrawSize: Get<DrawSize> {
    /// Returns the draw size of window.
    fn get_draw_size(&self) -> DrawSize {
        self.get()
    }
}

impl<T: Get<DrawSize>> GetDrawSize for T {}

/// Work-around trait for `Set<DrawSize>`.
/// Used to support generic constraints.
pub trait SetDrawSize: Set<DrawSize> {
    /// Sets draw size.
    fn set_draw_size(&mut self, val: DrawSize) {
        self.set_mut(val);
    }
}

impl<T: Set<DrawSize>> SetDrawSize for T {}

#[test]
fn test_methods() {
    use current::Modifier;

    struct Obj;

    impl Get<ShouldClose> for Obj {
        fn get(&self) -> ShouldClose { ShouldClose(false) }
    }

    impl Modifier<Obj> for ShouldClose {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Size> for Obj {
        fn get(&self) -> Size { Size([0, 0]) }
    }

    impl Modifier<Obj> for Size {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Title> for Obj {
        fn get(&self) -> Title { Title("hello".to_string()) }
    }

    impl Modifier<Obj> for Title {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Samples> for Obj {
        fn get(&self) -> Samples { Samples(0) }
    }

    impl Modifier<Obj> for Samples {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Fullscreen> for Obj {
        fn get(&self) -> Fullscreen { Fullscreen(false) }
    }

    impl Modifier<Obj> for Fullscreen {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<ExitOnEsc> for Obj {
        fn get(&self) -> ExitOnEsc { ExitOnEsc(true) }
    }

    impl Modifier<Obj> for ExitOnEsc {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<CaptureCursor> for Obj {
        fn get(&self) -> CaptureCursor { CaptureCursor(false) }
    }

    impl Modifier<Obj> for CaptureCursor {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<DrawSize> for Obj {
        fn get(&self) -> DrawSize { DrawSize([0, 0]) }
    }

    impl Modifier<Obj> for DrawSize {
        fn modify(self, _obj: &mut Obj) {}
    }

    fn foo<T: GetShouldClose + SetShouldClose
            + GetSize + SetSize
            + GetTitle + SetTitle
            + GetSamples + SetSamples
            + GetFullscreen + SetFullscreen
            + GetExitOnEsc + SetExitOnEsc
            + GetCaptureCursor + SetCaptureCursor
            + GetDrawSize + SetDrawSize>(_obj: T) {}

    foo(Obj);
}

/// Implemented by windows that can swap buffers.
pub trait SwapBuffers {
    /// Swaps the buffers.
    fn swap_buffers(&mut self);
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for Usage<'a, W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.with_unwrap(|window: &RefCell<W>| {
            window.borrow_mut().deref_mut().swap_buffers()
        })
    }
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for &'a RefCell<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.borrow_mut().deref_mut().swap_buffers()
    }
}

/// Implemented by windows that can pull events.
pub trait PollEvent<E: GenericEvent> {
    /// Polls event from window.
    fn poll_event(&mut self) -> Option<E>;
}

impl<'a, W: 'a + PollEvent<I>, I: GenericEvent> PollEvent<I> for Usage<'a, W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.with_unwrap(|window: &RefCell<W>| {
            window.borrow_mut().deref_mut().poll_event()
        })
    }
}

impl<'a, W: 'a + PollEvent<I>, I: GenericEvent> PollEvent<I> for &'a RefCell<W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.borrow_mut().deref_mut().poll_event()
    }
}

/// Settings for window behavior.
pub struct WindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window.
    pub size: [u32, ..2],
    /// Number samples per pixel (anti-aliasing).
    pub samples: u8,
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl WindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> WindowSettings {
        WindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// Implemented by window back-end.
pub trait Window<E: GenericEvent = InputEvent>:
    SwapBuffers
  + PollEvent<E>
  + GetShouldClose + SetShouldClose
  + GetSize
  + SetCaptureCursor
  + GetDrawSize
  + GetTitle + SetTitle
  + GetExitOnEsc + SetExitOnEsc {}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    should_close: bool,
    title: String,
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: WindowSettings) -> NoWindow {
        let title = settings.title.clone();
        NoWindow {
            should_close: false,
            title: title,
        }
    }
}

impl SwapBuffers for NoWindow {
    fn swap_buffers(&mut self) {}
}

impl PollEvent<InputEvent> for NoWindow {
    fn poll_event(&mut self) -> Option<InputEvent> { None }
}

impl Get<ShouldClose> for NoWindow {
    fn get(&self) -> ShouldClose {
        ShouldClose(self.should_close)
    }
}

impl Get<Size> for NoWindow {
    fn get(&self) -> Size {
        Size([0, 0])
    }
}

impl Modifier<NoWindow> for CaptureCursor {
    fn modify(self, _window: &mut NoWindow) {}
}

impl Modifier<NoWindow> for ShouldClose {
    fn modify(self, window: &mut NoWindow) {
        let ShouldClose(val) = self;
        window.should_close = val;
    }
}

impl Get<DrawSize> for NoWindow {
    fn get(&self) -> DrawSize {
        let Size(val) = self.get();
        DrawSize(val)
    }
}

impl Window<InputEvent> for NoWindow {}

impl Get<Title> for NoWindow {
    fn get(&self) -> Title {
        Title(self.title.clone())
    }
}

impl Modifier<NoWindow> for Title {
    fn modify(self, window: &mut NoWindow) {
        let Title(val) = self;
        window.title = val;
    }
}

impl Get<ExitOnEsc> for NoWindow {
    fn get(&self) -> ExitOnEsc {
        ExitOnEsc(false)
    }
}

impl Modifier<NoWindow> for ExitOnEsc {
    // Ignore attempt to exit by pressing Esc.
    fn modify(self, _window: &mut NoWindow) {}
}

<commit_msg>Upgraded to latest piston-current<commit_after>//! Window abstraction

use std::cell::RefCell;
use input::InputEvent;
use current::{ Current, Get, Modifier, Set };

use GenericEvent;

/// Whether window should close or not.
pub struct ShouldClose(pub bool);

/// Work-around trait for `Get<ShouldClose>`.
/// Used to support generic constraints.
pub trait GetShouldClose: Get<ShouldClose> {
    /// Returns whether window should close.
    fn get_should_close(&self) -> ShouldClose {
        self.get()
    }
}

impl<T: Get<ShouldClose>> GetShouldClose for T {}

/// Work-around trait for `Set<ShouldClose>`.
/// Used to support generic constraints.
pub trait SetShouldClose: Set<ShouldClose> {
    /// Sets whether window should close.
    fn set_should_close(&mut self, val: ShouldClose) {
        self.set_mut(val);
    }
}

impl<T: Set<ShouldClose>> SetShouldClose for T {}

/// The size of the window.
pub struct Size(pub [u32, ..2]);

/// Work-around trait for `Get<Size>`.
/// Used to support generic constraints.
pub trait GetSize: Get<Size> {
    /// Returns the size of window.
    fn get_size(&self) -> Size {
        self.get()
    }
}

impl<T: Get<Size>> GetSize for T {}

/// Work-around trait for `Set<Size>`.
/// Used to support generic constraints.
pub trait SetSize: Set<Size> {
    /// Sets size of window.
    fn set_size(&mut self, val: Size) {
        self.set_mut(val);
    }
}

impl<T: Set<Size>> SetSize for T {}

/// The title of the window.
pub struct Title(pub String);

/// Work-around trait for `Get<Title>`.
/// Used to support generic constraints.
pub trait GetTitle: Get<Title> {
    /// Returns the title of the window.
    fn get_title(&self) -> Title {
        self.get()
    }
}

impl<T: Get<Title>> GetTitle for T {}

/// Work-around trait for `Set<Title>`.
/// Used to support generic constraints.
pub trait SetTitle: Set<Title> {
    /// Sets title of window.
    fn set_title(&mut self, val: Title) {
        self.set_mut(val);
    }
}

impl<T: Set<Title>> SetTitle for T {}

/// The anti-aliasing samples when rendering.
pub struct Samples(pub u8);

/// Work-around trait for `Get<Samples>`.
/// Used to support generic constraints.
pub trait GetSamples: Get<Samples> {
    /// Returns the antialiasing samples when rendering.
    fn get_samples(&self) -> Samples {
        self.get()
    }
}

impl<T: Get<Samples>> GetSamples for T {}

/// Work-around trait for `Set<Samples>`.
/// Used to support generic constraints.
pub trait SetSamples: Set<Samples> {
    /// Sets antialiasing samples of window.
    fn set_samples(&mut self, val: Samples) {
        self.set_mut(val);
    }
}

impl<T: Set<Samples>> SetSamples for T {}

/// Whether window is opened in full screen mode.
pub struct Fullscreen(pub bool);

/// Work-around trait for `Get<Fullscreen>`.
/// Used to support generic constraints.
pub trait GetFullscreen: Get<Fullscreen> {
    /// Returns whether window is in full screen mode.
    fn get_fullscreen(&self) -> Fullscreen {
        self.get()
    }
}

impl<T: Get<Fullscreen>> GetFullscreen for T {}

/// Work-around trait for `Set<Fullscreen>`.
/// Used to support generic constraints.
pub trait SetFullscreen: Set<Fullscreen> {
    /// Sets window to fullscreen mode.
    fn set_fullscreen(&mut self, val: Fullscreen) {
        self.set_mut(val);
    }
}

impl<T: Set<Fullscreen>> SetFullscreen for T {}

/// Whether to exit when pressing the Esc keyboard button.
pub struct ExitOnEsc(pub bool);

/// Work-around trait for `Get<ExitOnEsc>`.
/// Used to support generic constraints.
pub trait GetExitOnEsc: Get<ExitOnEsc> {
    /// Returns whether window exits when pressing Esc.
    fn get_exit_on_esc(&self) -> ExitOnEsc {
        self.get()
    }
}

impl<T: Get<ExitOnEsc>> GetExitOnEsc for T {}

/// Work-around trait for `Set<ExitOnEsc>`.
/// Used to support generic constraints.
pub trait SetExitOnEsc: Set<ExitOnEsc> {
    /// Sets exit when pressing Esc.
    fn set_exit_on_esc(&mut self, val: ExitOnEsc) {
        self.set_mut(val);
    }
}

impl<T: Set<ExitOnEsc>> SetExitOnEsc for T {}

/// Whether to capture the mouse cursor.
pub struct CaptureCursor(pub bool);

/// Work-around trait for `Get<CaptureCursor>`.
/// Used to support generic constraints.
pub trait GetCaptureCursor: Get<CaptureCursor> {
    /// Returns whether window captures cursor.
    fn get_capture_cursor(&self) -> CaptureCursor {
        self.get()
    }
}

impl<T: Get<CaptureCursor>> GetCaptureCursor for T {}

/// Work-around trait for `Set<CaptureCursor>`.
/// Used to support generic constraints.
pub trait SetCaptureCursor: Set<CaptureCursor> {
    /// Sets capture cursor.
    fn set_capture_cursor(&mut self, val: CaptureCursor) {
        self.set_mut(val);
    }
}

impl<T: Set<CaptureCursor>> SetCaptureCursor for T {}

/// The draw size of the window.
pub struct DrawSize(pub [u32, ..2]);

/// Work-around trait for `Get<DrawSize>`.
/// Used to support generic constraints.
pub trait GetDrawSize: Get<DrawSize> {
    /// Returns the draw size of window.
    fn get_draw_size(&self) -> DrawSize {
        self.get()
    }
}

impl<T: Get<DrawSize>> GetDrawSize for T {}

/// Work-around trait for `Set<DrawSize>`.
/// Used to support generic constraints.
pub trait SetDrawSize: Set<DrawSize> {
    /// Sets draw size.
    fn set_draw_size(&mut self, val: DrawSize) {
        self.set_mut(val);
    }
}

impl<T: Set<DrawSize>> SetDrawSize for T {}

#[test]
fn test_methods() {
    use current::Modifier;

    struct Obj;

    impl Get<ShouldClose> for Obj {
        fn get(&self) -> ShouldClose { ShouldClose(false) }
    }

    impl Modifier<Obj> for ShouldClose {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Size> for Obj {
        fn get(&self) -> Size { Size([0, 0]) }
    }

    impl Modifier<Obj> for Size {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Title> for Obj {
        fn get(&self) -> Title { Title("hello".to_string()) }
    }

    impl Modifier<Obj> for Title {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Samples> for Obj {
        fn get(&self) -> Samples { Samples(0) }
    }

    impl Modifier<Obj> for Samples {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Fullscreen> for Obj {
        fn get(&self) -> Fullscreen { Fullscreen(false) }
    }

    impl Modifier<Obj> for Fullscreen {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<ExitOnEsc> for Obj {
        fn get(&self) -> ExitOnEsc { ExitOnEsc(true) }
    }

    impl Modifier<Obj> for ExitOnEsc {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<CaptureCursor> for Obj {
        fn get(&self) -> CaptureCursor { CaptureCursor(false) }
    }

    impl Modifier<Obj> for CaptureCursor {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<DrawSize> for Obj {
        fn get(&self) -> DrawSize { DrawSize([0, 0]) }
    }

    impl Modifier<Obj> for DrawSize {
        fn modify(self, _obj: &mut Obj) {}
    }

    fn foo<T: GetShouldClose + SetShouldClose
            + GetSize + SetSize
            + GetTitle + SetTitle
            + GetSamples + SetSamples
            + GetFullscreen + SetFullscreen
            + GetExitOnEsc + SetExitOnEsc
            + GetCaptureCursor + SetCaptureCursor
            + GetDrawSize + SetDrawSize>(_obj: T) {}

    foo(Obj);
}

/// Implemented by windows that can swap buffers.
pub trait SwapBuffers {
    /// Swaps the buffers.
    fn swap_buffers(&mut self);
}

impl<W: SwapBuffers> SwapBuffers for Current<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        (*self).deref_mut().swap_buffers();
    }
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for &'a RefCell<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.borrow_mut().deref_mut().swap_buffers()
    }
}

/// Implemented by windows that can pull events.
pub trait PollEvent<E: GenericEvent> {
    /// Polls event from window.
    fn poll_event(&mut self) -> Option<E>;
}

impl<W: PollEvent<I>, I: GenericEvent> PollEvent<I> for Current<W> {
    fn poll_event(&mut self) -> Option<I> {
        (*self).deref_mut().poll_event()
    }
}

impl<'a, W: 'a + PollEvent<I>, I: GenericEvent> PollEvent<I> for &'a RefCell<W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.borrow_mut().deref_mut().poll_event()
    }
}

/// Settings for window behavior.
pub struct WindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window.
    pub size: [u32, ..2],
    /// Number samples per pixel (anti-aliasing).
    pub samples: u8,
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl WindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> WindowSettings {
        WindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// Implemented by window back-end.
pub trait Window<E: GenericEvent = InputEvent>:
    SwapBuffers
  + PollEvent<E>
  + GetShouldClose + SetShouldClose
  + GetSize
  + SetCaptureCursor
  + GetDrawSize
  + GetTitle + SetTitle
  + GetExitOnEsc + SetExitOnEsc {}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    should_close: bool,
    title: String,
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: WindowSettings) -> NoWindow {
        let title = settings.title.clone();
        NoWindow {
            should_close: false,
            title: title,
        }
    }
}

impl SwapBuffers for NoWindow {
    fn swap_buffers(&mut self) {}
}

impl PollEvent<InputEvent> for NoWindow {
    fn poll_event(&mut self) -> Option<InputEvent> { None }
}

impl Get<ShouldClose> for NoWindow {
    fn get(&self) -> ShouldClose {
        ShouldClose(self.should_close)
    }
}

impl Get<Size> for NoWindow {
    fn get(&self) -> Size {
        Size([0, 0])
    }
}

impl Modifier<NoWindow> for CaptureCursor {
    fn modify(self, _window: &mut NoWindow) {}
}

impl Modifier<NoWindow> for ShouldClose {
    fn modify(self, window: &mut NoWindow) {
        let ShouldClose(val) = self;
        window.should_close = val;
    }
}

impl Get<DrawSize> for NoWindow {
    fn get(&self) -> DrawSize {
        let Size(val) = self.get();
        DrawSize(val)
    }
}

impl Window<InputEvent> for NoWindow {}

impl Get<Title> for NoWindow {
    fn get(&self) -> Title {
        Title(self.title.clone())
    }
}

impl Modifier<NoWindow> for Title {
    fn modify(self, window: &mut NoWindow) {
        let Title(val) = self;
        window.title = val;
    }
}

impl Get<ExitOnEsc> for NoWindow {
    fn get(&self) -> ExitOnEsc {
        ExitOnEsc(false)
    }
}

impl Modifier<NoWindow> for ExitOnEsc {
    // Ignore attempt to exit by pressing Esc.
    fn modify(self, _window: &mut NoWindow) {}
}

<|endoftext|>