<commit_before>use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name = ".kic";
    if dir_exists(&dir_name) {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(dir_name) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let config_file    = "config";
    let path_to_config = Path::new(dir_name).join(config_file);
    if file_exists(&path_to_config) {
        println!("  OK: \"{}\" file has already exist.", config_file);
    } else {
        match File::create(path_to_config) {
            Ok(mut fp) => {
                println!("  OK: Created \"{}\" file.", config_file);
                match fp.write(b"Hello, world!!\n") {
                    Ok(_)    => {},
                    Err(why) => panic!("{:?}", why),
                }
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

fn dir_exists<P: AsRef<Path>>(path: P) -> bool {
    match fs::metadata(path) {
        Ok(m)    => m.is_dir(),
        Err(why) => {
            match why.raw_os_error() {
                Some(2) => false,
                _       => panic!("{:?}", why),
            }
        }
    }
}

fn file_exists<P: AsRef<Path>>(path: P) -> bool {
    match fs::metadata(path) {
        Ok(m) => m.is_file(),
        Err(why) => {
            match why.raw_os_error() {
                Some(2) => false,
                _       => panic!("{:?}", why),
            }
        }
    }
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    println!("sweep");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("destroy");
}
<commit_msg>Refactor dir_exists() and file_exists()<commit_after>use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name    = ".kic";
    let path_to_dir = Path::new(dir_name);
    if dir_exists(path_to_dir) {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(path_to_dir) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let config_file    = "config";
    let path_to_config = Path::new(dir_name).join(config_file);
    if file_exists(path_to_config.as_path()) {
        println!("  OK: \"{}\" file has already exist.", config_file);
    } else {
        match File::create(path_to_config) {
            Ok(mut fp) => {
                println!("  OK: Created \"{}\" file.", config_file);
                match fp.write(b"Hello, world!!\n") {
                    Ok(_)    => {},
                    Err(why) => panic!("{:?}", why),
                }
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

fn dir_exists(p: &Path) -> bool {
    p.exists() && p.is_dir()
}

fn file_exists(p: &Path) -> bool {
    p.exists() && p.is_file()
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    println!("sweep");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("destroy");
}
<|endoftext|>


<commit_before>const INTERPRETER_START: u32 = 0x000;
const INTERPRETER_END: u32 = 0x1FF;
const INTERPRETER_LENGTH: u32 = INTERPRETER_END - INTERPRETER_START;

const FONT_SET_START: usize = 0x050;
const FONT_SET_END: usize = 0x0A0;
const FONT_SET_LENGTH: usize = FONT_SET_END - FONT_SET_START;

const DATA_START: usize = 0x200;
const DATA_END: usize = 0xFFF;
const DATA_LENGTH: usize = DATA_END - DATA_START;

const MEM_LENGTH: usize = 4096;
const STACK_LEVEL: usize = 16;
const REG_NUM: usize = 16;
pub const GFX_WIDTH: usize = 64;
pub const GFX_HEIGHT: usize = 32;

const FONTSET: [u8; 80] = [
    0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
    0x20, 0x60, 0x20, 0x20, 0x70, // 1
    0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
    0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
    0x90, 0x90, 0xF0, 0x10, 0x10, // 4
    0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
    0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
    0xF0, 0x10, 0x20, 0x40, 0x40, // 7
    0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
    0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
    0xF0, 0x90, 0xF0, 0x90, 0x90, // A
    0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
    0xF0, 0x80, 0x80, 0x80, 0xF0, // C
    0xE0, 0x90, 0x90, 0x90, 0xE0, // D
    0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
    0xF0, 0x80, 0xF0, 0x80, 0x80  // F
];

pub fn init() -> Cpu {
    let mut ret = Cpu {
        pc: 0x200,
        opcode: 0,
        memory: vec![0; MEM_LENGTH],
        reg: vec![0; REG_NUM],
        index: 0,
        sp: 0,
        stack: vec![0; STACK_LEVEL],
        // gfx: vec![vec![0; GFX_HEIGHT]; GFX_WIDTH],
        gfx: vec![0; GFX_WIDTH * GFX_HEIGHT],
        delay_timer: 0,
        sound_timer: 0,
        key: vec![0; STACK_LEVEL],
    };
    ret.load_fontset();
    ret
}

#[derive(Debug, Clone)]
pub struct Cpu {
    pc: usize,
    opcode: u16,
    memory: Vec<u8>,
    reg: Vec<u8>,
    index: usize,
    // gfx: Vec<Vec<u8>>,
    gfx: Vec<u8>,
    delay_timer: u8,
    sound_timer: u8,
    stack: Vec<usize>,
    sp: usize,
    key: Vec<u8>,
}

impl Cpu {
    fn load_fontset(&mut self) {
        for i in 0..FONT_SET_LENGTH {
            self.memory[FONT_SET_START + i] = FONTSET[i];
        }
    }

    pub fn load_rom(&mut self, rom: Box<[u8]>) {
        for i in 0..rom.len() {
            self.memory[DATA_START + i] = rom[i];
        }
    }

    pub fn curr_pc(&mut self) -> usize {
        self.pc
    }

    pub fn curr_index(&mut self) -> usize {
        self.index
    }

    pub fn curr_opcode(&mut self) -> u16 {
        self.opcode
    }

    pub fn curr_regs(&mut self) -> Vec<u8> {
        self.clone().reg
    }

    pub fn curr_stack(&mut self) -> Vec<usize> {
        self.clone().stack
    }

    pub fn curr_sp(&mut self) -> usize {
        self.sp
    }

    pub fn curr_gfx(&mut self) -> Vec<u8> {
        self.clone().gfx
    }

    pub fn emulate_cycle(&mut self) {
        self.opcode = (self.memory[self.pc] as u16) << 8 | (self.memory[self.pc+1] as u16);

        match self.opcode & 0xF000 {
            0x0000 => {
                match self.opcode & 0x0F00 {
                    0x0000 => {
                        match self.opcode & 0x00FF {
                            0x00EE => {
                                self.sp -= 1;
                                self.pc = self.stack[self.sp];
                            },
                            _ => panic!("Unknown opcode or not implemented yet: {:X}", self.opcode)
                        }
                    },
                    _ => panic!("Unknown opcode or not implemented yet: {:X}", self.opcode)
                }
            },
            0x2000 => { // 2NNN: Calls subroutine at NNN
                let addr = self.opcode & 0x0FFF;
                self.stack[self.sp] = self.pc;
                self.sp += 1;
                self.pc = addr as usize;
            },
            0x6000 => { // 6XNN: Sets VX to NN
                let index = (self.opcode & 0x0F00) >> 8;
                let val = self.opcode & 0x00FF;
                self.reg[index as usize] = val as u8;
                self.pc += 2;
            },
            0x7000 => { // 7XNN: Adds NN to VX
                let x = (self.opcode & 0x0F00) >> 8;
                let nn = self.opcode & 0x00FF;
                self.reg[x as usize] += nn as u8;
                self.pc += 2;
            },
            0xA000 => { // ANNN: Sets I to the address NNN
                let val = self.opcode & 0x0FFF;
                self.index = val as usize;
                self.pc += 2;
            },
            0xD000 => { // DXYN: Draws sprite at cordinate VX, VY with height N
                let x = (self.opcode & 0x0F00) >> 8;
                let y = (self.opcode & 0x00F0) >> 4;
                let n = self.opcode & 0x000F;
                let mut pix: u8;

                let tmp = self.index as usize;
                let sprite = &self.memory[tmp..(tmp + (n as usize))];

                self.reg[0xF] = 0;
                for i in 0..n {
                    pix = (&sprite)[i as usize];
                    for j in 0..8 {
                        if (pix & (0x80 >> j)) != 0 {
                            if self.gfx[(x + j + ((y + i) * 64)) as usize] == 1 {
                                self.reg[0xF] = 1;
                            }
                            self.gfx[(x + j + ((y + i) * 64)) as usize] ^= 1;
                        }
                    }
                }
                self.pc += 2;
            },
            0xF000 => {
                match self.opcode & 0x00FF {
                    0x0029 => { // FX29: set I to character sprite in VX
                        let x = (self.opcode & 0x0F00) >> 8;
                        let tmp = FONT_SET_START + ((self.reg[x as usize] * 5) as usize);
                        self.index = self.memory[tmp] as usize;
                        self.pc += 2;
                    },
                    0x0033 => { // FX33: set memory at I:I+2 to VX
                        let x = (self.opcode & 0x0F00) >> 8;
                        let val = self.reg[x as usize];
                        self.memory[self.index] = val / 100;
                        self.memory[self.index + 1] = (val / 10) % 10;
                        self.memory[self.index + 2] = val % 10;
                        self.pc += 2;
                    },
                    0x0065 => { // FX65: fill V0 to VX with values at I:I+X
                        let x = (self.opcode & 0x0F00) >> 8;
                        for i in 0..x {
                            self.reg[i as usize] = self.memory[self.index + (i as usize)];
                        }
                        self.pc += 2;
                    },
                    _ => panic!("Unknown opcode or not implemented yet: {:X}", self.opcode)
                }
            },
            _ => panic!("Unknown opcode or not implemented yet: {:X}", self.opcode)
        }
    }
}
<commit_msg>Add opcode 3XNN (skip next if VX == NN)<commit_after>const INTERPRETER_START: u32 = 0x000;
const INTERPRETER_END: u32 = 0x1FF;
const INTERPRETER_LENGTH: u32 = INTERPRETER_END - INTERPRETER_START;

const FONT_SET_START: usize = 0x050;
const FONT_SET_END: usize = 0x0A0;
const FONT_SET_LENGTH: usize = FONT_SET_END - FONT_SET_START;

const DATA_START: usize = 0x200;
const DATA_END: usize = 0xFFF;
const DATA_LENGTH: usize = DATA_END - DATA_START;

const MEM_LENGTH: usize = 4096;
const STACK_LEVEL: usize = 16;
const REG_NUM: usize = 16;
pub const GFX_WIDTH: usize = 64;
pub const GFX_HEIGHT: usize = 32;

const FONTSET: [u8; 80] = [
    0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
    0x20, 0x60, 0x20, 0x20, 0x70, // 1
    0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
    0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
    0x90, 0x90, 0xF0, 0x10, 0x10, // 4
    0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
    0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
    0xF0, 0x10, 0x20, 0x40, 0x40, // 7
    0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
    0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
    0xF0, 0x90, 0xF0, 0x90, 0x90, // A
    0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
    0xF0, 0x80, 0x80, 0x80, 0xF0, // C
    0xE0, 0x90, 0x90, 0x90, 0xE0, // D
    0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
    0xF0, 0x80, 0xF0, 0x80, 0x80  // F
];

pub fn init() -> Cpu {
    let mut ret = Cpu {
        pc: 0x200,
        opcode: 0,
        memory: vec![0; MEM_LENGTH],
        reg: vec![0; REG_NUM],
        index: 0,
        sp: 0,
        stack: vec![0; STACK_LEVEL],
        // gfx: vec![vec![0; GFX_HEIGHT]; GFX_WIDTH],
        gfx: vec![0; GFX_WIDTH * GFX_HEIGHT],
        delay_timer: 0,
        sound_timer: 0,
        key: vec![0; STACK_LEVEL],
    };
    ret.load_fontset();
    ret
}

#[derive(Debug, Clone)]
pub struct Cpu {
    pc: usize,
    opcode: u16,
    memory: Vec<u8>,
    reg: Vec<u8>,
    index: usize,
    // gfx: Vec<Vec<u8>>,
    gfx: Vec<u8>,
    delay_timer: u8,
    sound_timer: u8,
    stack: Vec<usize>,
    sp: usize,
    key: Vec<u8>,
}

impl Cpu {
    fn load_fontset(&mut self) {
        for i in 0..FONT_SET_LENGTH {
            self.memory[FONT_SET_START + i] = FONTSET[i];
        }
    }

    pub fn load_rom(&mut self, rom: Box<[u8]>) {
        for i in 0..rom.len() {
            self.memory[DATA_START + i] = rom[i];
        }
    }

    pub fn curr_pc(&mut self) -> usize {
        self.pc
    }

    pub fn curr_index(&mut self) -> usize {
        self.index
    }

    pub fn curr_opcode(&mut self) -> u16 {
        self.opcode
    }

    pub fn curr_regs(&mut self) -> Vec<u8> {
        self.clone().reg
    }

    pub fn curr_stack(&mut self) -> Vec<usize> {
        self.clone().stack
    }

    pub fn curr_sp(&mut self) -> usize {
        self.sp
    }

    pub fn curr_gfx(&mut self) -> Vec<u8> {
        self.clone().gfx
    }

    pub fn emulate_cycle(&mut self) {
        self.opcode = (self.memory[self.pc] as u16) << 8 | (self.memory[self.pc+1] as u16);

        match self.opcode & 0xF000 {
            0x0000 => {
                match self.opcode & 0x0F00 {
                    0x0000 => {
                        match self.opcode & 0x00FF {
                            0x00EE => { // 00EE: return from subroutine
                                self.sp -= 1;
                                self.pc = self.stack[self.sp];
                            },
                            _ => panic!("Unknown opcode or not implemented yet: {:X}", self.opcode)
                        }
                    },
                    _ => panic!("Unknown opcode or not implemented yet: {:X}", self.opcode)
                }
            },
            0x2000 => { // 2NNN: Calls subroutine at NNN
                let addr = self.opcode & 0x0FFF;
                self.stack[self.sp] = self.pc;
                self.sp += 1;
                self.pc = addr as usize;
            },
            0x3000 => { // 3XNN: skip next if VX == NN
                let x = (self.opcode & 0x0F00) >> 8;
                let nn = self.opcode & 0x00FF;
                if self.reg[x as usize] == nn as u8 {
                    self.pc += 4;
                } else {
                    self.pc += 2;
                }
            },
            0x6000 => { // 6XNN: Sets VX to NN
                let index = (self.opcode & 0x0F00) >> 8;
                let val = self.opcode & 0x00FF;
                self.reg[index as usize] = val as u8;
                self.pc += 2;
            },
            0x7000 => { // 7XNN: Adds NN to VX
                let x = (self.opcode & 0x0F00) >> 8;
                let nn = self.opcode & 0x00FF;
                self.reg[x as usize] += nn as u8;
                self.pc += 2;
            },
            0xA000 => { // ANNN: Sets I to the address NNN
                let val = self.opcode & 0x0FFF;
                self.index = val as usize;
                self.pc += 2;
            },
            0xD000 => { // DXYN: Draws sprite at cordinate VX, VY with height N
                let x = (self.opcode & 0x0F00) >> 8;
                let y = (self.opcode & 0x00F0) >> 4;
                let n = self.opcode & 0x000F;
                let mut pix: u8;

                let tmp = self.index as usize;
                let sprite = &self.memory[tmp..(tmp + (n as usize))];

                self.reg[0xF] = 0;
                for i in 0..n {
                    pix = (&sprite)[i as usize];
                    for j in 0..8 {
                        if (pix & (0x80 >> j)) != 0 {
                            if self.gfx[(x + j + ((y + i) * 64)) as usize] == 1 {
                                self.reg[0xF] = 1;
                            }
                            self.gfx[(x + j + ((y + i) * 64)) as usize] ^= 1;
                        }
                    }
                }
                self.pc += 2;
            },
            0xF000 => {
                match self.opcode & 0x00FF {
                    0x0029 => { // FX29: set I to character sprite in VX
                        let x = (self.opcode & 0x0F00) >> 8;
                        let tmp = FONT_SET_START + ((self.reg[x as usize] * 5) as usize);
                        self.index = self.memory[tmp] as usize;
                        self.pc += 2;
                    },
                    0x0033 => { // FX33: set memory at I:I+2 to VX
                        let x = (self.opcode & 0x0F00) >> 8;
                        let val = self.reg[x as usize];
                        self.memory[self.index] = val / 100;
                        self.memory[self.index + 1] = (val / 10) % 10;
                        self.memory[self.index + 2] = val % 10;
                        self.pc += 2;
                    },
                    0x0065 => { // FX65: fill V0 to VX with values at I:I+X
                        let x = (self.opcode & 0x0F00) >> 8;
                        for i in 0..x {
                            self.reg[i as usize] = self.memory[self.index + (i as usize)];
                        }
                        self.pc += 2;
                    },
                    _ => panic!("Unknown opcode or not implemented yet: {:X}", self.opcode)
                }
            },
            _ => panic!("Unknown opcode or not implemented yet: {:X}", self.opcode)
        }
    }
}
<|endoftext|>


<commit_before>mod registers;
mod ops;

use std::rc::Rc;
use std::cell::RefCell;
use memory::Memory;
use cpu::registers::{Registers, Reg8};
use cpu::ops::{CpuOps, In8, Out8};

/*
    Instruction Layout
    ====================

    This analysis is based upon the Zilog Z80 manual with modifications done by the GB/GBC
    such as removing the instructions involving the IX and IY registers.

    [] = 1 byte

    Addressing Modes
    --------------------
    Immediate Addressing: [op][operand] (1 or 2 byte op code)
        Operand is a single byte, such as loading the accumulator with a constant.
    Immediate Extended Addressing: [op][low][high] (1 or 2 byte op code)
        Operand is split into two bytes, such as to load the HL register pair with 16 bits
        of data.
    Register Addressing:
        Many Z80 opcodes specify register to registers directly
    Implied Addressing:
        This indicates OP codes imply registers, such as arithmetic instructions always
        implying that the destination is the accumulator (A in AF register).
    Register Indirect Addressing: [op] (1 or 2 byte op code)
        This specifies a 16 bit register pair to be used as a pointer to any location in
        memory. Such as loading the accumulator with data pointed to in the HR register.

    Modified Page Zero Addressing: [op] (1 byte op code)
        Eight special locations in page 0 of memory, depending on which version of CALL is
        called.
    Relative Addressing: [op][displacement] (1 byte op code)
        Used for Jump Relative, displacement is 8 bit twos complement offset from A+2 (where
        A is the current PC value)
    Extended Addressing: [op][lowaddr][highaddr] (1 or 2 byte op code)
        Used to jump to any location in 16 bit memory

*/

// CPU Data
pub struct Cpu {
    pub running: bool,
    memory: Rc<RefCell<Memory>>,
    regs: Registers
}

// Control Conditions
#[derive(Debug)]
enum Cond {
    None, C, NC, Z, NZ
}

// Registers
impl In8 for Reg8 {
    fn read(&self, cpu: &mut Cpu) -> u8 {
        match *self {
            Reg8::A => cpu.regs.a,
            Reg8::B => cpu.regs.b,
            Reg8::C => cpu.regs.c,
            Reg8::D => cpu.regs.d,
            Reg8::E => cpu.regs.e,
            Reg8::F => cpu.regs.f,
            Reg8::H => cpu.regs.h,
            Reg8::L => cpu.regs.l
        }
    }
}
impl Out8 for Reg8 {
    fn write(&self, cpu: &mut Cpu, data: u8) {
        match *self {
            Reg8::A => cpu.regs.a = data,
            Reg8::B => cpu.regs.b = data,
            Reg8::C => cpu.regs.c = data,
            Reg8::D => cpu.regs.d = data,
            Reg8::E => cpu.regs.e = data,
            Reg8::F => cpu.regs.f = data,
            Reg8::H => cpu.regs.h = data,
            Reg8::L => cpu.regs.l = data
        }
    }
}

// Immediate operand - a constant stored in the next byte
#[derive(Debug)]
struct Imm8;
impl In8 for Imm8 {
    fn read(&self, cpu: &mut Cpu) -> u8 {
        // Just read the next byte
        cpu.next_u8()
    }
}

// Immediate extended operand - a constant stored in the next two bytes
// TODO

// Indirect Addressing
#[derive(Debug)]
enum IndirectAddr {
    BC, DE, HL
}
impl In8 for IndirectAddr {
    fn read(&self, cpu: &mut Cpu) -> u8 {
        // do stuff
        0
    }
}
impl Out8 for IndirectAddr {
    fn write(&self, cpu: &mut Cpu, data: u8) {
    }
}

// Interpreter implementation of the CPU ops defined in the ops module
impl<'a> CpuOps for &'a mut Cpu {
    fn load<I: In8, O: Out8>(self, i: I, o: O) {
        println!("status: Load - in: {:?} out: {:?}", i, o);
    }
    fn add<I: In8>(self, i: I) {
        println!("status: Add - in: {:?}", i);
    }
    fn adc<I: In8>(self, i: I) {
        println!("status: Add with carry - in: {:?}", i);
    }
    fn sub<I: In8>(self, i: I) {
        println!("status: Sub - in: {:?}", i);
    }
    fn sbc<I: In8>(self, i: I) {
        println!("status: Sub with carry - in: {:?}", i);
    }
    fn and<I: In8>(self, i: I) {
        println!("status: And - in: {:?}", i);
    }
    fn xor<I: In8>(self, i: I) {
        println!("status: Xor - in: {:?}", i);
    }
    fn or<I: In8>(self, i: I) {
        println!("status: Or - in: {:?}", i);
    }
    fn cp<I: In8>(self, i: I) {
        println!("status: Compare - in: {:?}", i);
    }
    fn inc<I: In8>(self, i: I) {
        println!("status: Increment - in: {:?}", i);
    }
    fn dec<I: In8>(self, i: I) {
        println!("status: Decrement - in: {:?}", i);
    }
    // control
    fn jp(self, cond: Cond) {
        let dest = self.next_u16();
        println!("status: Jump - dest: {:02x} cond: {:?}", dest, cond);
    }
    fn jp_hl(self, cond: Cond) {
        println!("status: Jump (HL) - cond: {:?}", cond);
    }
    fn jr(self, cond: Cond) {
        let offset = self.next_u8();
        println!("status: Jump - dest: {:02x} cond: {:?}", self.regs.pc + offset as u16, cond);
    }
    fn call(self, cond: Cond) {
        let dest = self.next_u16();
        println!("status: Call - dest: {:02x} cond: {:?}", dest, cond);
    }
    fn ret(self, cond: Cond) {
        println!("status: Return - cond: {:?}", cond);
    }
    fn reti(self) {
        println!("status: Return from Interrupt");
    }
    // misc
    fn nop(self) {}
    fn daa(self) {}
    fn cpl(self) {}
    fn neg(self) {}
    fn ccf(self) {}
    fn scf(self) {}
}

impl Cpu {
    pub fn new(memory: Rc<RefCell<Memory>>) -> Cpu {
        Cpu {
            running: true,
            memory: memory,
            regs: Registers::new()
        }
    }

    pub fn tick(&mut self) {
        let opcode = self.next_u8();
        ops::decode(&mut *self as &mut Cpu, opcode);

        // Stop execution for the lols
        if self.regs.pc > 256 {
            self.running = false;
            self.dump_state();
        }
    }

    // Memory reading helper functions
    fn next_u8(&mut self) -> u8 {
        let byte = self.memory.borrow().read_u8(self.regs.pc);
        self.regs.pc += 1;
        byte
    }

    fn next_u16(&mut self) -> u16 {
        ((self.next_u8() as u16) >> 8) | self.next_u8() as u16
    }

    // Some misc helper functions
    fn get_bits(&self, number: u16, min: u16, max: u16) -> u16 {
        (number >> min) & ((max - min) - 1)
    }

    fn get_bit(&self, number: u16, bit: u16) -> u16 {
        (number >> bit) & 0x1
    }

    pub fn dump_state(&self) {
        println!("Registers:");
        println!("- PC: {:04x} SP: {:04x} ", self.regs.pc, self.regs.sp);
        println!("- A: {:02x} F: {:02x} B: {:02x} C: {:02x}", self.regs.a, self.regs.f, self.regs.b, self.regs.c);
        println!("- D: {:02x} E: {:02x} H: {:02x} L: {:02x}", self.regs.d, self.regs.e, self.regs.h, self.regs.l);
        println!("Flags:");
        println!("- Zero: {}", self.get_bit(self.regs.f as u16, 7));
        println!("- Add/Sub: {}", self.get_bit(self.regs.f as u16, 6));
        println!("- Half Carry: {}", self.get_bit(self.regs.f as u16, 5));
        println!("- Carry Flag {}", self.get_bit(self.regs.f as u16, 4));
    }
}
<commit_msg>Correct next_u16 implementation<commit_after>mod registers;
mod ops;

use std::rc::Rc;
use std::cell::RefCell;
use memory::Memory;
use cpu::registers::{Registers, Reg8};
use cpu::ops::{CpuOps, In8, Out8};

/*
    Instruction Layout
    ====================

    This analysis is based upon the Zilog Z80 manual with modifications done by the GB/GBC
    such as removing the instructions involving the IX and IY registers.

    [] = 1 byte

    Addressing Modes
    --------------------
    Immediate Addressing: [op][operand] (1 or 2 byte op code)
        Operand is a single byte, such as loading the accumulator with a constant.
    Immediate Extended Addressing: [op][low][high] (1 or 2 byte op code)
        Operand is split into two bytes, such as to load the HL register pair with 16 bits
        of data.
    Register Addressing:
        Many Z80 opcodes specify register to registers directly
    Implied Addressing:
        This indicates OP codes imply registers, such as arithmetic instructions always
        implying that the destination is the accumulator (A in AF register).
    Register Indirect Addressing: [op] (1 or 2 byte op code)
        This specifies a 16 bit register pair to be used as a pointer to any location in
        memory. Such as loading the accumulator with data pointed to in the HR register.

    Modified Page Zero Addressing: [op] (1 byte op code)
        Eight special locations in page 0 of memory, depending on which version of CALL is
        called.
    Relative Addressing: [op][displacement] (1 byte op code)
        Used for Jump Relative, displacement is 8 bit twos complement offset from A+2 (where
        A is the current PC value)
    Extended Addressing: [op][lowaddr][highaddr] (1 or 2 byte op code)
        Used to jump to any location in 16 bit memory

*/

// CPU Data
pub struct Cpu {
    pub running: bool,
    memory: Rc<RefCell<Memory>>,
    regs: Registers
}

// Control Conditions
#[derive(Debug)]
enum Cond {
    None, C, NC, Z, NZ
}

// Registers
impl In8 for Reg8 {
    fn read(&self, cpu: &mut Cpu) -> u8 {
        match *self {
            Reg8::A => cpu.regs.a,
            Reg8::B => cpu.regs.b,
            Reg8::C => cpu.regs.c,
            Reg8::D => cpu.regs.d,
            Reg8::E => cpu.regs.e,
            Reg8::F => cpu.regs.f,
            Reg8::H => cpu.regs.h,
            Reg8::L => cpu.regs.l
        }
    }
}
impl Out8 for Reg8 {
    fn write(&self, cpu: &mut Cpu, data: u8) {
        match *self {
            Reg8::A => cpu.regs.a = data,
            Reg8::B => cpu.regs.b = data,
            Reg8::C => cpu.regs.c = data,
            Reg8::D => cpu.regs.d = data,
            Reg8::E => cpu.regs.e = data,
            Reg8::F => cpu.regs.f = data,
            Reg8::H => cpu.regs.h = data,
            Reg8::L => cpu.regs.l = data
        }
    }
}

// Immediate operand - a constant stored in the next byte
#[derive(Debug)]
struct Imm8;
impl In8 for Imm8 {
    fn read(&self, cpu: &mut Cpu) -> u8 {
        // Just read the next byte
        cpu.next_u8()
    }
}

// Immediate extended operand - a constant stored in the next two bytes
// TODO

// Indirect Addressing
#[derive(Debug)]
enum IndirectAddr {
    BC, DE, HL
}
impl In8 for IndirectAddr {
    fn read(&self, cpu: &mut Cpu) -> u8 {
        // do stuff
        0
    }
}
impl Out8 for IndirectAddr {
    fn write(&self, cpu: &mut Cpu, data: u8) {
    }
}

// Interpreter implementation of the CPU ops defined in the ops module
impl<'a> CpuOps for &'a mut Cpu {
    fn load<I: In8, O: Out8>(self, i: I, o: O) {
        println!("status: Load - in: {:?} out: {:?}", i, o);
    }
    fn add<I: In8>(self, i: I) {
        println!("status: Add - in: {:?}", i);
    }
    fn adc<I: In8>(self, i: I) {
        println!("status: Add with carry - in: {:?}", i);
    }
    fn sub<I: In8>(self, i: I) {
        println!("status: Sub - in: {:?}", i);
    }
    fn sbc<I: In8>(self, i: I) {
        println!("status: Sub with carry - in: {:?}", i);
    }
    fn and<I: In8>(self, i: I) {
        println!("status: And - in: {:?}", i);
    }
    fn xor<I: In8>(self, i: I) {
        println!("status: Xor - in: {:?}", i);
    }
    fn or<I: In8>(self, i: I) {
        println!("status: Or - in: {:?}", i);
    }
    fn cp<I: In8>(self, i: I) {
        println!("status: Compare - in: {:?}", i);
    }
    fn inc<I: In8>(self, i: I) {
        println!("status: Increment - in: {:?}", i);
    }
    fn dec<I: In8>(self, i: I) {
        println!("status: Decrement - in: {:?}", i);
    }
    // control
    fn jp(self, cond: Cond) {
        let dest = self.next_u16();
        println!("status: Jump - dest: {:04x} cond: {:?}", dest, cond);
    }
    fn jp_hl(self, cond: Cond) {
        println!("status: Jump (HL) - cond: {:?}", cond);
    }
    fn jr(self, cond: Cond) {
        let offset = self.next_u8();
        println!("status: Jump - dest: {:04x} cond: {:?}", self.regs.pc + offset as u16, cond);
    }
    fn call(self, cond: Cond) {
        let dest = self.next_u16();
        println!("status: Call - dest: {:04x} cond: {:?}", dest, cond);
    }
    fn ret(self, cond: Cond) {
        println!("status: Return - cond: {:?}", cond);
    }
    fn reti(self) {
        println!("status: Return from Interrupt");
    }
    // misc
    fn nop(self) {}
    fn daa(self) {}
    fn cpl(self) {}
    fn neg(self) {}
    fn ccf(self) {}
    fn scf(self) {}
}

impl Cpu {
    pub fn new(memory: Rc<RefCell<Memory>>) -> Cpu {
        Cpu {
            running: true,
            memory: memory,
            regs: Registers::new()
        }
    }

    pub fn tick(&mut self) {
        let opcode = self.next_u8();
        ops::decode(&mut *self as &mut Cpu, opcode);

        // Stop execution for the lols
        if self.regs.pc > 256 {
            self.running = false;
            self.dump_state();
        }
    }

    // Memory reading helper functions
    fn next_u8(&mut self) -> u8 {
        let byte = self.memory.borrow().read_u8(self.regs.pc);
        self.regs.pc += 1;
        byte
    }

    fn next_u16(&mut self) -> u16 {
        let l = self.next_u8();
        let h = self.next_u8();
        ((l as u16) << 8) | (h as u16)
    }

    // Some misc helper functions
    fn get_bits(&self, number: u16, min: u16, max: u16) -> u16 {
        (number >> min) & ((max - min) - 1)
    }

    fn get_bit(&self, number: u16, bit: u16) -> u16 {
        (number >> bit) & 0x1
    }

    pub fn dump_state(&self) {
        println!("Registers:");
        println!("- PC: {:04x} SP: {:04x} ", self.regs.pc, self.regs.sp);
        println!("- A: {:02x} F: {:02x} B: {:02x} C: {:02x}", self.regs.a, self.regs.f, self.regs.b, self.regs.c);
        println!("- D: {:02x} E: {:02x} H: {:02x} L: {:02x}", self.regs.d, self.regs.e, self.regs.h, self.regs.l);
        println!("Flags:");
        println!("- Zero: {}", self.get_bit(self.regs.f as u16, 7));
        println!("- Add/Sub: {}", self.get_bit(self.regs.f as u16, 6));
        println!("- Half Carry: {}", self.get_bit(self.regs.f as u16, 5));
        println!("- Carry Flag {}", self.get_bit(self.regs.f as u16, 4));
    }
}
<|endoftext|>


<commit_before>//! Request extractors
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

use actix_http::error::Error;
use futures_util::future::{ok, FutureExt, LocalBoxFuture, Ready};

use crate::dev::Payload;
use crate::request::HttpRequest;

/// Trait implemented by types that can be extracted from request.
///
/// Types that implement this trait can be used with `Route` handlers.
pub trait FromRequest: Sized {
    /// The associated error which can be returned.
    type Error: Into<Error>;

    /// Future that resolves to a Self
    type Future: Future<Output = Result<Self, Self::Error>>;

    /// Configuration for this extractor
    type Config: Default + 'static;

    /// Convert request to a Self
    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future;

    /// Convert request to a Self
    ///
    /// This method uses `Payload::None` as payload stream.
    fn extract(req: &HttpRequest) -> Self::Future {
        Self::from_request(req, &mut Payload::None)
    }

    /// Create and configure config instance.
    fn configure<F>(f: F) -> Self::Config
    where
        F: FnOnce(Self::Config) -> Self::Config,
    {
        f(Self::Config::default())
    }
}

/// Optionally extract a field from the request
///
/// If the FromRequest for T fails, return None rather than returning an error response
///
/// ## Example
///
/// ```rust
/// use actix_web::{web, dev, App, Error, HttpRequest, FromRequest};
/// use actix_web::error::ErrorBadRequest;
/// use futures_util::future::{ok, err, Ready};
/// use serde_derive::Deserialize;
/// use rand;
///
/// #[derive(Debug, Deserialize)]
/// struct Thing {
///     name: String
/// }
///
/// impl FromRequest for Thing {
///     type Error = Error;
///     type Future = Ready<Result<Self, Self::Error>>;
///     type Config = ();
///
///     fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
///         if rand::random() {
///             ok(Thing { name: "thingy".into() })
///         } else {
///             err(ErrorBadRequest("no luck"))
///         }
///
///     }
/// }
///
/// /// extract `Thing` from request
/// async fn index(supplied_thing: Option<Thing>) -> String {
///     match supplied_thing {
///         // Puns not intended
///         Some(thing) => format!("Got something: {:?}", thing),
///         None => format!("No thing!")
///     }
/// }
///
/// fn main() {
///     let app = App::new().service(
///         web::resource("/users/:first").route(
///             web::post().to(index))
///     );
/// }
/// ```
impl<T: 'static> FromRequest for Option<T>
where
    T: FromRequest,
    T::Future: 'static,
{
    type Config = T::Config;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Option<T>, Error>>;

    #[inline]
    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
        T::from_request(req, payload)
            .then(|r| match r {
                Ok(v) => ok(Some(v)),
                Err(e) => {
                    log::debug!("Error for Option<T> extractor: {}", e.into());
                    ok(None)
                }
            })
            .boxed_local()
    }
}

/// Optionally extract a field from the request or extract the Error if unsuccessful
///
/// If the `FromRequest` for T fails, inject Err into handler rather than returning an error response
///
/// ## Example
///
/// ```rust
/// use actix_web::{web, dev, App, Result, Error, HttpRequest, FromRequest};
/// use actix_web::error::ErrorBadRequest;
/// use futures_util::future::{ok, err, Ready};
/// use serde_derive::Deserialize;
/// use rand;
///
/// #[derive(Debug, Deserialize)]
/// struct Thing {
///     name: String
/// }
///
/// impl FromRequest for Thing {
///     type Error = Error;
///     type Future = Ready<Result<Thing, Error>>;
///     type Config = ();
///
///     fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
///         if rand::random() {
///             ok(Thing { name: "thingy".into() })
///         } else {
///             err(ErrorBadRequest("no luck"))
///         }
///     }
/// }
///
/// /// extract `Thing` from request
/// async fn index(supplied_thing: Result<Thing>) -> String {
///     match supplied_thing {
///         Ok(thing) => format!("Got thing: {:?}", thing),
///         Err(e) => format!("Error extracting thing: {}", e)
///     }
/// }
///
/// fn main() {
///     let app = App::new().service(
///         web::resource("/users/:first").route(web::post().to(index))
///     );
/// }
/// ```
impl<T> FromRequest for Result<T, T::Error>
where
    T: FromRequest + 'static,
    T::Error: 'static,
    T::Future: 'static,
{
    type Config = T::Config;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Result<T, T::Error>, Error>>;

    #[inline]
    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
        T::from_request(req, payload)
            .then(|res| match res {
                Ok(v) => ok(Ok(v)),
                Err(e) => ok(Err(e)),
            })
            .boxed_local()
    }
}

#[doc(hidden)]
impl FromRequest for () {
    type Config = ();
    type Error = Error;
    type Future = Ready<Result<(), Error>>;

    fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
        ok(())
    }
}

macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {

    // This module is a trick to get around the inability of
    // `macro_rules!` macros to make new idents. We want to make
    // a new `FutWrapper` struct for each distinct invocation of
    // this macro. Ideally, we would name it something like
    // `FutWrapper_$fut_type`, but this can't be done in a macro_rules
    // macro.
    //
    // Instead, we put everything in a module named `$fut_type`, thus allowing
    // us to use the name `FutWrapper` without worrying about conflicts.
    // This macro only exists to generate trait impls for tuples - these
    // are inherently global, so users don't have to care about this
    // weird trick.
    #[allow(non_snake_case)]
    mod $fut_type {

        // Bring everything into scope, so we don't need
        // redundant imports
        use super::*;

        /// A helper struct to allow us to pin-project through
        /// to individual fields
        #[pin_project::pin_project]
        struct FutWrapper<$($T: FromRequest),+>($(#[pin] $T::Future),+);

        /// FromRequest implementation for tuple
        #[doc(hidden)]
        #[allow(unused_parens)]
        impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
        {
            type Error = Error;
            type Future = $fut_type<$($T),+>;
            type Config = ($($T::Config),+);

            fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
                $fut_type {
                    items: <($(Option<$T>,)+)>::default(),
                    futs: FutWrapper($($T::from_request(req, payload),)+),
                }
            }
        }

        #[doc(hidden)]
        #[pin_project::pin_project]
        pub struct $fut_type<$($T: FromRequest),+> {
            items: ($(Option<$T>,)+),
            #[pin]
            futs: FutWrapper<$($T,)+>,
        }

        impl<$($T: FromRequest),+> Future for $fut_type<$($T),+>
        {
            type Output = Result<($($T,)+), Error>;

            fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
                let mut this = self.project();

                let mut ready = true;
                $(
                    if this.items.$n.is_none() {
                        match this.futs.as_mut().project().$n.poll(cx) {
                            Poll::Ready(Ok(item)) => {
                                this.items.$n = Some(item);
                            }
                            Poll::Pending => ready = false,
                            Poll::Ready(Err(e)) => return Poll::Ready(Err(e.into())),
                        }
                    }
                )+

                    if ready {
                        Poll::Ready(Ok(
                            ($(this.items.$n.take().unwrap(),)+)
                        ))
                    } else {
                        Poll::Pending
                    }
            }
        }
    }
});

#[rustfmt::skip]
mod m {
    use super::*;

tuple_from_req!(TupleFromRequest1, (0, A));
tuple_from_req!(TupleFromRequest2, (0, A), (1, B));
tuple_from_req!(TupleFromRequest3, (0, A), (1, B), (2, C));
tuple_from_req!(TupleFromRequest4, (0, A), (1, B), (2, C), (3, D));
tuple_from_req!(TupleFromRequest5, (0, A), (1, B), (2, C), (3, D), (4, E));
tuple_from_req!(TupleFromRequest6, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
tuple_from_req!(TupleFromRequest7, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
tuple_from_req!(TupleFromRequest8, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
tuple_from_req!(TupleFromRequest9, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
tuple_from_req!(TupleFromRequest10, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
}

#[cfg(test)]
mod tests {
    use actix_http::http::header;
    use bytes::Bytes;
    use serde_derive::Deserialize;

    use super::*;
    use crate::test::TestRequest;
    use crate::types::{Form, FormConfig};

    #[derive(Deserialize, Debug, PartialEq)]
    struct Info {
        hello: String,
    }

    #[actix_rt::test]
    async fn test_option() {
        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .data(FormConfig::default().limit(4096))
        .to_http_parts();

        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
            .await
            .unwrap();
        assert_eq!(r, None);

        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .header(header::CONTENT_LENGTH, "9")
        .set_payload(Bytes::from_static(b"hello=world"))
        .to_http_parts();

        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
            .await
            .unwrap();
        assert_eq!(
            r,
            Some(Form(Info {
                hello: "world".into()
            }))
        );

        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .header(header::CONTENT_LENGTH, "9")
        .set_payload(Bytes::from_static(b"bye=world"))
        .to_http_parts();

        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
            .await
            .unwrap();
        assert_eq!(r, None);
    }

    #[actix_rt::test]
    async fn test_result() {
        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .header(header::CONTENT_LENGTH, "11")
        .set_payload(Bytes::from_static(b"hello=world"))
        .to_http_parts();

        let r = Result::<Form<Info>, Error>::from_request(&req, &mut pl)
            .await
            .unwrap()
            .unwrap();
        assert_eq!(
            r,
            Form(Info {
                hello: "world".into()
            })
        );

        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .header(header::CONTENT_LENGTH, "9")
        .set_payload(Bytes::from_static(b"bye=world"))
        .to_http_parts();

        let r = Result::<Form<Info>, Error>::from_request(&req, &mut pl)
            .await
            .unwrap();
        assert!(r.is_err());
    }
}
<commit_msg>remove boxed future for Option<T> and Result<T, E> extract type (#1829)<commit_after>//! Request extractors
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

use actix_http::error::Error;
use futures_util::future::{ready, Ready};
use futures_util::ready;

use crate::dev::Payload;
use crate::request::HttpRequest;

/// Trait implemented by types that can be extracted from request.
///
/// Types that implement this trait can be used with `Route` handlers.
pub trait FromRequest: Sized {
    /// The associated error which can be returned.
    type Error: Into<Error>;

    /// Future that resolves to a Self
    type Future: Future<Output = Result<Self, Self::Error>>;

    /// Configuration for this extractor
    type Config: Default + 'static;

    /// Convert request to a Self
    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future;

    /// Convert request to a Self
    ///
    /// This method uses `Payload::None` as payload stream.
    fn extract(req: &HttpRequest) -> Self::Future {
        Self::from_request(req, &mut Payload::None)
    }

    /// Create and configure config instance.
    fn configure<F>(f: F) -> Self::Config
    where
        F: FnOnce(Self::Config) -> Self::Config,
    {
        f(Self::Config::default())
    }
}

/// Optionally extract a field from the request
///
/// If the FromRequest for T fails, return None rather than returning an error response
///
/// ## Example
///
/// ```rust
/// use actix_web::{web, dev, App, Error, HttpRequest, FromRequest};
/// use actix_web::error::ErrorBadRequest;
/// use futures_util::future::{ok, err, Ready};
/// use serde_derive::Deserialize;
/// use rand;
///
/// #[derive(Debug, Deserialize)]
/// struct Thing {
///     name: String
/// }
///
/// impl FromRequest for Thing {
///     type Error = Error;
///     type Future = Ready<Result<Self, Self::Error>>;
///     type Config = ();
///
///     fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
///         if rand::random() {
///             ok(Thing { name: "thingy".into() })
///         } else {
///             err(ErrorBadRequest("no luck"))
///         }
///
///     }
/// }
///
/// /// extract `Thing` from request
/// async fn index(supplied_thing: Option<Thing>) -> String {
///     match supplied_thing {
///         // Puns not intended
///         Some(thing) => format!("Got something: {:?}", thing),
///         None => format!("No thing!")
///     }
/// }
///
/// fn main() {
///     let app = App::new().service(
///         web::resource("/users/:first").route(
///             web::post().to(index))
///     );
/// }
/// ```
impl<T: 'static> FromRequest for Option<T>
where
    T: FromRequest,
    T::Future: 'static,
{
    type Error = Error;
    type Future = FromRequestOptFuture<T::Future>;
    type Config = T::Config;

    #[inline]
    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
        FromRequestOptFuture {
            fut: T::from_request(req, payload),
        }
    }
}

#[pin_project::pin_project]
pub struct FromRequestOptFuture<Fut> {
    #[pin]
    fut: Fut,
}

impl<Fut, T, E> Future for FromRequestOptFuture<Fut>
where
    Fut: Future<Output = Result<T, E>>,
    E: Into<Error>,
{
    type Output = Result<Option<T>, Error>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = self.project();
        let res = ready!(this.fut.poll(cx));
        match res {
            Ok(t) => Poll::Ready(Ok(Some(t))),
            Err(e) => {
                log::debug!("Error for Option<T> extractor: {}", e.into());
                Poll::Ready(Ok(None))
            }
        }
    }
}

/// Optionally extract a field from the request or extract the Error if unsuccessful
///
/// If the `FromRequest` for T fails, inject Err into handler rather than returning an error response
///
/// ## Example
///
/// ```rust
/// use actix_web::{web, dev, App, Result, Error, HttpRequest, FromRequest};
/// use actix_web::error::ErrorBadRequest;
/// use futures_util::future::{ok, err, Ready};
/// use serde_derive::Deserialize;
/// use rand;
///
/// #[derive(Debug, Deserialize)]
/// struct Thing {
///     name: String
/// }
///
/// impl FromRequest for Thing {
///     type Error = Error;
///     type Future = Ready<Result<Thing, Error>>;
///     type Config = ();
///
///     fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
///         if rand::random() {
///             ok(Thing { name: "thingy".into() })
///         } else {
///             err(ErrorBadRequest("no luck"))
///         }
///     }
/// }
///
/// /// extract `Thing` from request
/// async fn index(supplied_thing: Result<Thing>) -> String {
///     match supplied_thing {
///         Ok(thing) => format!("Got thing: {:?}", thing),
///         Err(e) => format!("Error extracting thing: {}", e)
///     }
/// }
///
/// fn main() {
///     let app = App::new().service(
///         web::resource("/users/:first").route(web::post().to(index))
///     );
/// }
/// ```
impl<T> FromRequest for Result<T, T::Error>
where
    T: FromRequest + 'static,
    T::Error: 'static,
    T::Future: 'static,
{
    type Error = Error;
    type Future = FromRequestResFuture<T::Future>;
    type Config = T::Config;

    #[inline]
    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
        FromRequestResFuture {
            fut: T::from_request(req, payload),
        }
    }
}

#[pin_project::pin_project]
pub struct FromRequestResFuture<Fut> {
    #[pin]
    fut: Fut,
}

impl<Fut, T, E> Future for FromRequestResFuture<Fut>
where
    Fut: Future<Output = Result<T, E>>,
{
    type Output = Result<Result<T, E>, Error>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = self.project();
        let res = ready!(this.fut.poll(cx));
        Poll::Ready(Ok(res))
    }
}

#[doc(hidden)]
impl FromRequest for () {
    type Error = Error;
    type Future = Ready<Result<(), Error>>;
    type Config = ();

    fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
        ready(Ok(()))
    }
}

macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {

    // This module is a trick to get around the inability of
    // `macro_rules!` macros to make new idents. We want to make
    // a new `FutWrapper` struct for each distinct invocation of
    // this macro. Ideally, we would name it something like
    // `FutWrapper_$fut_type`, but this can't be done in a macro_rules
    // macro.
    //
    // Instead, we put everything in a module named `$fut_type`, thus allowing
    // us to use the name `FutWrapper` without worrying about conflicts.
    // This macro only exists to generate trait impls for tuples - these
    // are inherently global, so users don't have to care about this
    // weird trick.
    #[allow(non_snake_case)]
    mod $fut_type {

        // Bring everything into scope, so we don't need
        // redundant imports
        use super::*;

        /// A helper struct to allow us to pin-project through
        /// to individual fields
        #[pin_project::pin_project]
        struct FutWrapper<$($T: FromRequest),+>($(#[pin] $T::Future),+);

        /// FromRequest implementation for tuple
        #[doc(hidden)]
        #[allow(unused_parens)]
        impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
        {
            type Error = Error;
            type Future = $fut_type<$($T),+>;
            type Config = ($($T::Config),+);

            fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
                $fut_type {
                    items: <($(Option<$T>,)+)>::default(),
                    futs: FutWrapper($($T::from_request(req, payload),)+),
                }
            }
        }

        #[doc(hidden)]
        #[pin_project::pin_project]
        pub struct $fut_type<$($T: FromRequest),+> {
            items: ($(Option<$T>,)+),
            #[pin]
            futs: FutWrapper<$($T,)+>,
        }

        impl<$($T: FromRequest),+> Future for $fut_type<$($T),+>
        {
            type Output = Result<($($T,)+), Error>;

            fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
                let mut this = self.project();

                let mut ready = true;
                $(
                    if this.items.$n.is_none() {
                        match this.futs.as_mut().project().$n.poll(cx) {
                            Poll::Ready(Ok(item)) => {
                                this.items.$n = Some(item);
                            }
                            Poll::Pending => ready = false,
                            Poll::Ready(Err(e)) => return Poll::Ready(Err(e.into())),
                        }
                    }
                )+

                    if ready {
                        Poll::Ready(Ok(
                            ($(this.items.$n.take().unwrap(),)+)
                        ))
                    } else {
                        Poll::Pending
                    }
            }
        }
    }
});

#[rustfmt::skip]
mod m {
    use super::*;

tuple_from_req!(TupleFromRequest1, (0, A));
tuple_from_req!(TupleFromRequest2, (0, A), (1, B));
tuple_from_req!(TupleFromRequest3, (0, A), (1, B), (2, C));
tuple_from_req!(TupleFromRequest4, (0, A), (1, B), (2, C), (3, D));
tuple_from_req!(TupleFromRequest5, (0, A), (1, B), (2, C), (3, D), (4, E));
tuple_from_req!(TupleFromRequest6, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
tuple_from_req!(TupleFromRequest7, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
tuple_from_req!(TupleFromRequest8, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
tuple_from_req!(TupleFromRequest9, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
tuple_from_req!(TupleFromRequest10, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
}

#[cfg(test)]
mod tests {
    use actix_http::http::header;
    use bytes::Bytes;
    use serde_derive::Deserialize;

    use super::*;
    use crate::test::TestRequest;
    use crate::types::{Form, FormConfig};

    #[derive(Deserialize, Debug, PartialEq)]
    struct Info {
        hello: String,
    }

    #[actix_rt::test]
    async fn test_option() {
        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .data(FormConfig::default().limit(4096))
        .to_http_parts();

        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
            .await
            .unwrap();
        assert_eq!(r, None);

        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .header(header::CONTENT_LENGTH, "9")
        .set_payload(Bytes::from_static(b"hello=world"))
        .to_http_parts();

        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
            .await
            .unwrap();
        assert_eq!(
            r,
            Some(Form(Info {
                hello: "world".into()
            }))
        );

        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .header(header::CONTENT_LENGTH, "9")
        .set_payload(Bytes::from_static(b"bye=world"))
        .to_http_parts();

        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
            .await
            .unwrap();
        assert_eq!(r, None);
    }

    #[actix_rt::test]
    async fn test_result() {
        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .header(header::CONTENT_LENGTH, "11")
        .set_payload(Bytes::from_static(b"hello=world"))
        .to_http_parts();

        let r = Result::<Form<Info>, Error>::from_request(&req, &mut pl)
            .await
            .unwrap()
            .unwrap();
        assert_eq!(
            r,
            Form(Info {
                hello: "world".into()
            })
        );

        let (req, mut pl) = TestRequest::with_header(
            header::CONTENT_TYPE,
            "application/x-www-form-urlencoded",
        )
        .header(header::CONTENT_LENGTH, "9")
        .set_payload(Bytes::from_static(b"bye=world"))
        .to_http_parts();

        let r = Result::<Form<Info>, Error>::from_request(&req, &mut pl)
            .await
            .unwrap();
        assert!(r.is_err());
    }
}
<|endoftext|>


<commit_before>extern crate bootstrap_rs as bootstrap;
extern crate parse_collada as collada;
extern crate polygon_rs as polygon;
extern crate polygon_math as math;

pub mod entity;
pub mod component;
pub mod system;
pub mod input;
pub mod resource;

use std::f32::consts::PI;
use std::rc::Rc;
use std::cell::RefCell;

use bootstrap::window::Window;
use bootstrap::window::Message::*;
use bootstrap::input::ScanCode;
use bootstrap::time;

use math::point::Point;
use math::vector::Vector3;
use math::matrix::Matrix4;

use polygon::gl_render::{self, GLRender};

use entity::EntityManager;
use input::Input;
use component::transform::TransformManager;
use component::camera::CameraManager;
use component::mesh::MeshManager;
use system::System;
use resource::ResourceManager;

pub struct Engine {
    pub window: Box<Window>,
    pub renderer: GLRender,
    pub resource_manager: Rc<RefCell<ResourceManager>>,
    pub entity_manager: EntityManager,
    pub transform_manager: TransformManager,
    pub camera_manager: CameraManager,
    pub mesh_manager: MeshManager,
    pub input: Input,
    systems: Vec<Rc<RefCell<Box<System>>>>
}

impl Engine {
    pub fn new() -> Engine {
        let instance = bootstrap::init();
        let window = Window::new("Rust Window", instance);
        let renderer = gl_render::init(&window);
        let resource_manager = Rc::new(RefCell::new(ResourceManager::new(renderer)));

        Engine {
            window: window,
            renderer: renderer,
            resource_manager: resource_manager.clone(),
            entity_manager: EntityManager::new(),
            transform_manager: TransformManager::new(),
            camera_manager: CameraManager::new(),
            mesh_manager: MeshManager::new(resource_manager.clone()),
            input: Input::new(),
            systems: Vec::new()
        }
    }

    pub fn draw(&mut self) {
        self.renderer.clear();

        // Handle rendering for each camera.
        for (camera, entity) in self.camera_manager.iter_mut() {
            // Update the camera's bounds based on it's transform.
            // TODO: Update the camera's bounds before rendering.
            {
                let transform = self.transform_manager.get(entity);
                camera.position = transform.position;
                camera.rotation = Matrix4::rotation(transform.rotation.x, transform.rotation.y, transform.rotation.z);
            }

            // Draw all of the meshes.
            for (mesh, entity) in self.mesh_manager.iter() {
                let mut transform = self.transform_manager.get_mut(entity);
                transform.update(); // TODO: Update all transforms before rendering.
                self.renderer.draw_mesh(&mesh, transform.matrix(), &camera);
            }
        }

        self.renderer.swap_buffers();
    }

    pub fn main_loop(&mut self) {
        let mut close = false;
        let frequency = time::frequency();
        let mut last_time = time::now();

        loop {
            let time_now = time::now();
            let elapsed_time = (time_now - last_time) as f64 / frequency as f64;
            last_time = time_now;

            self.window.handle_messages();
            self.input.clear();
            loop {
                let message = self.window.next_message(); // TODO: Make this an iterator to simplify this loop.
                match message {
                    Some(message) => {
                        match message {
                            Activate => (),
                            Close => close = true,
                            Destroy => (),
                            Paint => (),

                            // Handle inputs.
                            KeyDown(_)
                          | KeyUp(_)
                          | MouseMove(_, _)
                          | MousePos(_, _)
                          | MouseButtonPressed(_)
                          | MouseButtonReleased(_)
                          | MouseWheel(_) => self.input.push_input(message),
                        }
                    },
                    None => break
                }
            }

            // Update systems.
            for system in self.systems.clone().iter_mut() {
                system.borrow_mut().update(self, elapsed_time as f32);
            }

            self.draw();

            if close {
                break;
            }
        };
    }

    pub fn register_system(&mut self, system: Rc<RefCell<Box<System>>>) {
        self.systems.push(system);
    }
}

fn main() {
    // Start Gunship.
    let mut engine = Engine::new();

    // Create camera.
    {
        let camera_entity = engine.entity_manager.create();
        let mut transform = engine.transform_manager.create(camera_entity);
        transform.position = Point::new(5.0, 0.0, 5.0);
        transform.update();
        engine.camera_manager.create(
            camera_entity,
            PI / 3.0,
            1.0,
            0.001,
            100.0);
    }

    // Create gun mesh.
    {
        let mesh_entity = engine.entity_manager.create();
        let mesh_transform = engine.transform_manager.create(mesh_entity);
        mesh_transform.position = Point::new(5.0, 5.0, 5.0);
        mesh_transform.rotation = Vector3::new(0.0, PI, 5.0);
        mesh_transform.scale = Vector3::new(0.5, 1.0, 2.0);
        engine.mesh_manager.create(mesh_entity, "meshes/gun_small.dae");
    }

    engine.register_system(Rc::new(RefCell::new(Box::new(CameraMoveSystem {
        rotation_x: 0.0,
        rotation_y: 0.0
    }))));

    engine.main_loop();
}

struct CameraMoveSystem {
    rotation_x: f32,
    rotation_y: f32
}

impl System for CameraMoveSystem {
    fn update(&mut self, engine: &mut Engine, delta: f32) {
        let entity = engine.camera_manager.entities()[0];

        // Cache off the position and rotation and then drop the transform
        // so that we don't have multiple borrows of transform_manager.
        let (position, rotation) = {
            let transform = engine.transform_manager.get_mut(entity);
            let (movement_x, movement_y) = engine.input.mouse_delta();

            // Add mouse movement to total rotation.
            self.rotation_x += (-movement_y as f32) * PI * 0.001;
            self.rotation_y += (-movement_x as f32) * PI * 0.001;

            // Apply a rotation to the camera based on mouse movmeent.
            transform.rotation =
                Vector3::new(self.rotation_x,
                             self.rotation_y,
                             0.0);
            let rotation_matrix =
                Matrix4::rotation(self.rotation_x,
                                  self.rotation_y,
                                  0.0);

            // Calculate the forward and right vectors.
            let forward_dir = -rotation_matrix.z_part();
            let right_dir = rotation_matrix.x_part();

            // Move camera based on input.
            if engine.input.key_down(ScanCode::W) {
                transform.position = transform.position + forward_dir * delta;
            }

            if engine.input.key_down(ScanCode::S) {
                transform.position = transform.position - forward_dir * delta;
            }

            if engine.input.key_down(ScanCode::D) {
                transform.position = transform.position + right_dir * delta;
            }

            if engine.input.key_down(ScanCode::A) {
                transform.position = transform.position - right_dir * delta
            }

            (transform.position, transform.rotation)
        };

        // Maybe shoot some bullets?
        if engine.input.mouse_button_pressed(0) {
            let bullet_entity = engine.entity_manager.create();
            let bullet_transform = engine.transform_manager.create(bullet_entity);
            bullet_transform.position = position;
            bullet_transform.rotation = rotation;
            bullet_transform.scale = Vector3::new(0.5, 0.5, 0.5);
            engine.mesh_manager.create(bullet_entity, "meshes/gun_small.dae");
        }
    }
}
<commit_msg>Enforce Maximum Frame Time - Adds code to sleep the thread if the frame rate is more than 60fps.<commit_after>extern crate bootstrap_rs as bootstrap;
extern crate parse_collada as collada;
extern crate polygon_rs as polygon;
extern crate polygon_math as math;

pub mod entity;
pub mod component;
pub mod system;
pub mod input;
pub mod resource;

use std::f32::consts::PI;
use std::rc::Rc;
use std::cell::RefCell;
use std::thread;

use bootstrap::window::Window;
use bootstrap::window::Message::*;
use bootstrap::input::ScanCode;
use bootstrap::time;

use math::point::Point;
use math::vector::Vector3;
use math::matrix::Matrix4;

use polygon::gl_render::{self, GLRender};

use entity::EntityManager;
use input::Input;
use component::transform::TransformManager;
use component::camera::CameraManager;
use component::mesh::MeshManager;
use system::System;
use resource::ResourceManager;

pub const TARGET_FRAME_TIME_SECONDS: f32 = 1.0 / 60.0;

pub struct Engine {
    pub window: Box<Window>,
    pub renderer: GLRender,
    pub resource_manager: Rc<RefCell<ResourceManager>>,
    pub entity_manager: EntityManager,
    pub transform_manager: TransformManager,
    pub camera_manager: CameraManager,
    pub mesh_manager: MeshManager,
    pub input: Input,
    systems: Vec<Rc<RefCell<Box<System>>>>
}

impl Engine {
    pub fn new() -> Engine {
        let instance = bootstrap::init();
        let window = Window::new("Rust Window", instance);
        let renderer = gl_render::init(&window);
        let resource_manager = Rc::new(RefCell::new(ResourceManager::new(renderer)));

        Engine {
            window: window,
            renderer: renderer,
            resource_manager: resource_manager.clone(),
            entity_manager: EntityManager::new(),
            transform_manager: TransformManager::new(),
            camera_manager: CameraManager::new(),
            mesh_manager: MeshManager::new(resource_manager.clone()),
            input: Input::new(),
            systems: Vec::new()
        }
    }

    pub fn draw(&mut self) {
        self.renderer.clear();

        // Handle rendering for each camera.
        for (camera, entity) in self.camera_manager.iter_mut() {
            // Update the camera's bounds based on it's transform.
            // TODO: Update the camera's bounds before rendering.
            {
                let transform = self.transform_manager.get(entity);
                camera.position = transform.position;
                camera.rotation = Matrix4::rotation(transform.rotation.x, transform.rotation.y, transform.rotation.z);
            }

            // Draw all of the meshes.
            for (mesh, entity) in self.mesh_manager.iter() {
                let mut transform = self.transform_manager.get_mut(entity);
                transform.update(); // TODO: Update all transforms before rendering.
                self.renderer.draw_mesh(&mesh, transform.matrix(), &camera);
            }
        }

        self.renderer.swap_buffers();
    }

    pub fn main_loop(&mut self) {
        let mut close = false;
        let frequency = time::frequency() as f32;
        let mut last_time = time::now();

        loop {
            let start_time = time::now();
            let frame_time = (start_time - last_time) as f32 / frequency;
            last_time = start_time;

            self.window.handle_messages();
            self.input.clear();
            loop {
                let message = self.window.next_message(); // TODO: Make this an iterator to simplify this loop.
                match message {
                    Some(message) => {
                        match message {
                            Activate => (),
                            Close => close = true,
                            Destroy => (),
                            Paint => (),

                            // Handle inputs.
                            KeyDown(_)
                          | KeyUp(_)
                          | MouseMove(_, _)
                          | MousePos(_, _)
                          | MouseButtonPressed(_)
                          | MouseButtonReleased(_)
                          | MouseWheel(_) => self.input.push_input(message),
                        }
                    },
                    None => break
                }
            }

            // Update systems.
            for system in self.systems.clone().iter_mut() {
                system.borrow_mut().update(self, frame_time as f32);
            }

            self.draw();

            if close {
                break;
            }

            let end_time = time::now();
            let mut elapsed_time = (end_time - start_time) as f32 / frequency;
            if elapsed_time > 0.1 {
                elapsed_time = 0.1;
            }

            let difference = TARGET_FRAME_TIME_SECONDS - elapsed_time;
            if difference > 0.0 {
                let sleep_ms = (difference * 1000.0).round() as u32;
                thread::sleep_ms(sleep_ms);
            } else {
                println!("Failed to meet required frame time: {} ms", elapsed_time);
            }
        };
    }

    pub fn register_system(&mut self, system: Rc<RefCell<Box<System>>>) {
        self.systems.push(system);
    }
}

fn main() {
    // Start Gunship.
    let mut engine = Engine::new();

    // Create camera.
    {
        let camera_entity = engine.entity_manager.create();
        let mut transform = engine.transform_manager.create(camera_entity);
        transform.position = Point::new(5.0, 0.0, 5.0);
        transform.update();
        engine.camera_manager.create(
            camera_entity,
            PI / 3.0,
            1.0,
            0.001,
            100.0);
    }

    // Create gun mesh.
    {
        let mesh_entity = engine.entity_manager.create();
        let mesh_transform = engine.transform_manager.create(mesh_entity);
        mesh_transform.position = Point::new(5.0, 5.0, 5.0);
        mesh_transform.rotation = Vector3::new(0.0, PI, 5.0);
        mesh_transform.scale = Vector3::new(0.5, 1.0, 2.0);
        engine.mesh_manager.create(mesh_entity, "meshes/gun_small.dae");
    }

    engine.register_system(Rc::new(RefCell::new(Box::new(CameraMoveSystem {
        rotation_x: 0.0,
        rotation_y: 0.0
    }))));

    engine.main_loop();
}

struct CameraMoveSystem {
    rotation_x: f32,
    rotation_y: f32
}

impl System for CameraMoveSystem {
    fn update(&mut self, engine: &mut Engine, delta: f32) {
        let entity = engine.camera_manager.entities()[0];

        // Cache off the position and rotation and then drop the transform
        // so that we don't have multiple borrows of transform_manager.
        let (position, rotation) = {
            let transform = engine.transform_manager.get_mut(entity);
            let (movement_x, movement_y) = engine.input.mouse_delta();

            // Add mouse movement to total rotation.
            self.rotation_x += (-movement_y as f32) * PI * 0.001;
            self.rotation_y += (-movement_x as f32) * PI * 0.001;

            // Apply a rotation to the camera based on mouse movmeent.
            transform.rotation =
                Vector3::new(self.rotation_x,
                             self.rotation_y,
                             0.0);
            let rotation_matrix =
                Matrix4::rotation(self.rotation_x,
                                  self.rotation_y,
                                  0.0);

            // Calculate the forward and right vectors.
            let forward_dir = -rotation_matrix.z_part();
            let right_dir = rotation_matrix.x_part();

            // Move camera based on input.
            if engine.input.key_down(ScanCode::W) {
                transform.position = transform.position + forward_dir * delta;
            }

            if engine.input.key_down(ScanCode::S) {
                transform.position = transform.position - forward_dir * delta;
            }

            if engine.input.key_down(ScanCode::D) {
                transform.position = transform.position + right_dir * delta;
            }

            if engine.input.key_down(ScanCode::A) {
                transform.position = transform.position - right_dir * delta
            }

            (transform.position, transform.rotation)
        };

        // Maybe shoot some bullets?
        if engine.input.mouse_button_pressed(0) {
            let bullet_entity = engine.entity_manager.create();
            let bullet_transform = engine.transform_manager.create(bullet_entity);
            bullet_transform.position = position;
            bullet_transform.rotation = rotation;
            bullet_transform.scale = Vector3::new(0.5, 0.5, 0.5);
            engine.mesh_manager.create(bullet_entity, "meshes/gun_small.dae");
        }
    }
}
<|endoftext|>


<commit_before>// HAT support
<commit_msg>Add Piface2 HAT<commit_after>mod piface;

#[cfg(feature = "spi")]
pub use self::piface::PiFace;
<|endoftext|>


<commit_before>// Copyright 2014-2016 bluss and ndarray developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Methods for two-dimensional arrays.
use imp_prelude::*;

impl ArrayBase<S, Ix2>
    where S: Data<Elem=A>,
{
    /// Return an array view of row `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn row(&self, index: Ix) -> ArrayView1
    {
        self.subview(Axis(0), index)
    }

    /// Return a mutable array view of row `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn row_mut(&mut self, index: Ix) -> ArrayViewMut1
        where S: DataMut
    {
        self.subview_mut(Axis(0), index)
    }

    /// Return the number of rows (length of `Axis(0)`) in the two-dimensional array.
    pub fn rows(&self) -> usize {
        self.shape().axis(Axis(0))
    }

    /// Return an array view of column `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn column(&self, index: Ix) -> ArrayView1
    {
        self.subview(Axis(1), index)
    }

    /// Return a mutable array view of column `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn column_mut(&mut self, index: Ix) -> ArrayViewMut1
        where S: DataMut
    {
        self.subview_mut(Axis(1), index)
    }

    /// Return the number of columns (length of `Axis(1)`) in the two-dimensional array.
    pub fn cols(&self) -> usize {
        self.shape().axis(Axis(1))
    }
}

<commit_msg>Add array method .is_square()<commit_after>// Copyright 2014-2016 bluss and ndarray developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Methods for two-dimensional arrays.
use imp_prelude::*;

impl ArrayBase<S, Ix2>
    where S: Data<Elem=A>,
{
    /// Return an array view of row `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn row(&self, index: Ix) -> ArrayView1
    {
        self.subview(Axis(0), index)
    }

    /// Return a mutable array view of row `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn row_mut(&mut self, index: Ix) -> ArrayViewMut1
        where S: DataMut
    {
        self.subview_mut(Axis(0), index)
    }

    /// Return the number of rows (length of `Axis(0)`) in the two-dimensional array.
    pub fn rows(&self) -> usize {
        self.shape().axis(Axis(0))
    }

    /// Return an array view of column `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn column(&self, index: Ix) -> ArrayView1
    {
        self.subview(Axis(1), index)
    }

    /// Return a mutable array view of column `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn column_mut(&mut self, index: Ix) -> ArrayViewMut1
        where S: DataMut
    {
        self.subview_mut(Axis(1), index)
    }

    /// Return the number of columns (length of `Axis(1)`) in the two-dimensional array.
    pub fn cols(&self) -> usize {
        self.shape().axis(Axis(1))
    }

    /// Return true if the array is square, false otherwise.
    pub fn is_square(&self) -> bool {
        self.rows() == self.cols()
    }
}

<|endoftext|>


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

use lists::{write_list, itemize_list, ListItem, ListFormatting, SeparatorTactic, ListTactic};
use utils::span_after;
use rewrite::{Rewrite, RewriteContext};
use config::Config;

use syntax::ast;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::codemap::{CodeMap, Span};

// TODO (some day) remove unused imports, expand globs, compress many single imports into a list import

impl Rewrite for ast::ViewPath {
    // Returns an empty string when the ViewPath is empty (like foo::bar::{})
    fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Option<String> {
        match self.node {
            ast::ViewPath_::ViewPathList(ref path, ref path_list) => {
                Some(rewrite_use_list(width,
                                 offset,
                                 path,
                                 path_list,
                                 self.span,
                                 context.codemap,
                                 context.config).unwrap_or("".to_owned()))
            }
            ast::ViewPath_::ViewPathGlob(_) => {
                // FIXME convert to list?
                None
            }
            ast::ViewPath_::ViewPathSimple(_,_) => {
                None
            }
        }
    }
}

fn rewrite_single_use_list(path_str: String, vpi: ast::PathListItem) -> String {
    if let ast::PathListItem_::PathListIdent{ name, .. } = vpi.node {
        let name_str = token::get_ident(name).to_string();
        if path_str.len() == 0 {
            name_str
        } else {
            format!("{}::{}", path_str, name_str)
        }
    } else {
        if path_str.len() != 0 {
            path_str
        } else {
            // This catches the import: use {self}, which is a compiler error, so we just
            // leave it alone.
            "{self}".to_owned()
        }
    }
}

// Basically just pretty prints a multi-item import.
// Returns None when the import can be removed.
pub fn rewrite_use_list(width: usize,
                        offset: usize,
                        path: &ast::Path,
                        path_list: &[ast::PathListItem],
                        span: Span,
                        codemap: &CodeMap,
                        config: &Config)
                        -> Option<String> {
    let path_str = pprust::path_to_string(path);

    match path_list.len() {
        0 => return None,
        1 => return Some(rewrite_single_use_list(path_str, path_list[0])),
        _ => ()
    }

    // 2 = ::
    let path_separation_w = if path_str.len() > 0 {
        2
    } else {
        0
    };
    // 1 = {
    let supp_indent = path_str.len() + path_separation_w + 1;
    // 1 = }
    let remaining_width = width.checked_sub(supp_indent + 1).unwrap_or(0);

    let fmt = ListFormatting {
        tactic: ListTactic::Mixed,
        separator: ",",
        trailing_separator: SeparatorTactic::Never,
        indent: offset + supp_indent,
        h_width: remaining_width,
        // FIXME This is too conservative, and will not use all width
        // available
        // (loose 1 column (";"))
        v_width: remaining_width,
        ends_with_newline: true,
    };

    let mut items = itemize_list(codemap,
                                 vec![ListItem::from_str("")], /* Dummy value, explanation
                                                                * below */
                                 path_list.iter(),
                                 ",",
                                 "}",
                                 |vpi| vpi.span.lo,
                                 |vpi| vpi.span.hi,
                                 |vpi| match vpi.node {
                                     ast::PathListItem_::PathListIdent{ name, .. } => {
                                         token::get_ident(name).to_string()
                                     }
                                     ast::PathListItem_::PathListMod{ .. } => {
                                         "self".to_owned()
                                     }
                                 },
                                 span_after(span, "{", codemap),
                                 span.hi);

    // We prefixed the item list with a dummy value so that we can
    // potentially move "self" to the front of the vector without touching
    // the rest of the items.
    // FIXME: Make more efficient by using a linked list? That would
    // require changes to the signatures of itemize_list and write_list.
    let has_self = move_self_to_front(&mut items);
    let first_index = if has_self {
        0
    } else {
        1
    };

    if config.reorder_imports {
        items[1..].sort_by(|a, b| a.item.cmp(&b.item));
    }

    let list = write_list(&items[first_index..], &fmt);

    Some(if path_str.len() == 0 {
            format!("{{{}}}", list)
        } else {
            format!("{}::{{{}}}", path_str, list)
        })
}

// Returns true when self item was found.
fn move_self_to_front(items: &mut Vec<ListItem>) -> bool {
    match items.iter().position(|item| item.item == "self") {
        Some(pos) => {
            items[0] = items.remove(pos);
            true
        },
        None => false
    }
}
<commit_msg>Indent fix<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use lists::{write_list, itemize_list, ListItem, ListFormatting, SeparatorTactic, ListTactic};
use utils::span_after;
use rewrite::{Rewrite, RewriteContext};
use config::Config;

use syntax::ast;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::codemap::{CodeMap, Span};

// TODO (some day) remove unused imports, expand globs, compress many single imports into a list import

impl Rewrite for ast::ViewPath {
    // Returns an empty string when the ViewPath is empty (like foo::bar::{})
    fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Option<String> {
        match self.node {
            ast::ViewPath_::ViewPathList(ref path, ref path_list) => {
                Some(rewrite_use_list(width,
                                      offset,
                                      path,
                                      path_list,
                                      self.span,
                                      context.codemap,
                                      context.config).unwrap_or("".to_owned()))
            }
            ast::ViewPath_::ViewPathGlob(_) => {
                // FIXME convert to list?
                None
            }
            ast::ViewPath_::ViewPathSimple(_,_) => {
                None
            }
        }
    }
}

fn rewrite_single_use_list(path_str: String, vpi: ast::PathListItem) -> String {
    if let ast::PathListItem_::PathListIdent{ name, .. } = vpi.node {
        let name_str = token::get_ident(name).to_string();
        if path_str.len() == 0 {
            name_str
        } else {
            format!("{}::{}", path_str, name_str)
        }
    } else {
        if path_str.len() != 0 {
            path_str
        } else {
            // This catches the import: use {self}, which is a compiler error, so we just
            // leave it alone.
            "{self}".to_owned()
        }
    }
}

// Basically just pretty prints a multi-item import.
// Returns None when the import can be removed.
pub fn rewrite_use_list(width: usize,
                        offset: usize,
                        path: &ast::Path,
                        path_list: &[ast::PathListItem],
                        span: Span,
                        codemap: &CodeMap,
                        config: &Config)
                        -> Option<String> {
    let path_str = pprust::path_to_string(path);

    match path_list.len() {
        0 => return None,
        1 => return Some(rewrite_single_use_list(path_str, path_list[0])),
        _ => ()
    }

    // 2 = ::
    let path_separation_w = if path_str.len() > 0 {
        2
    } else {
        0
    };
    // 1 = {
    let supp_indent = path_str.len() + path_separation_w + 1;
    // 1 = }
    let remaining_width = width.checked_sub(supp_indent + 1).unwrap_or(0);

    let fmt = ListFormatting {
        tactic: ListTactic::Mixed,
        separator: ",",
        trailing_separator: SeparatorTactic::Never,
        indent: offset + supp_indent,
        h_width: remaining_width,
        // FIXME This is too conservative, and will not use all width
        // available
        // (loose 1 column (";"))
        v_width: remaining_width,
        ends_with_newline: true,
    };

    let mut items = itemize_list(codemap,
                                 vec![ListItem::from_str("")], /* Dummy value, explanation
                                                                * below */
                                 path_list.iter(),
                                 ",",
                                 "}",
                                 |vpi| vpi.span.lo,
                                 |vpi| vpi.span.hi,
                                 |vpi| match vpi.node {
                                     ast::PathListItem_::PathListIdent{ name, .. } => {
                                         token::get_ident(name).to_string()
                                     }
                                     ast::PathListItem_::PathListMod{ .. } => {
                                         "self".to_owned()
                                     }
                                 },
                                 span_after(span, "{", codemap),
                                 span.hi);

    // We prefixed the item list with a dummy value so that we can
    // potentially move "self" to the front of the vector without touching
    // the rest of the items.
    // FIXME: Make more efficient by using a linked list? That would
    // require changes to the signatures of itemize_list and write_list.
    let has_self = move_self_to_front(&mut items);
    let first_index = if has_self {
        0
    } else {
        1
    };

    if config.reorder_imports {
        items[1..].sort_by(|a, b| a.item.cmp(&b.item));
    }

    let list = write_list(&items[first_index..], &fmt);

    Some(if path_str.len() == 0 {
            format!("{{{}}}", list)
        } else {
            format!("{}::{{{}}}", path_str, list)
        })
}

// Returns true when self item was found.
fn move_self_to_front(items: &mut Vec<ListItem>) -> bool {
    match items.iter().position(|item| item.item == "self") {
        Some(pos) => {
            items[0] = items.remove(pos);
            true
        },
        None => false
    }
}
<|endoftext|>


<commit_before>#[cfg(not(all(feature = "c", target_arch = "x86")))]
use int::LargeInt;
use int::Int;

macro_rules! mul {
    ($intrinsic:ident: $ty:ty) => {
        /// Returns `a * b`
        #[cfg_attr(not(test), no_mangle)]
        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
            let half_bits = <$ty>::bits() / 4;
            let lower_mask = !0 >> half_bits;
            let mut low = (a.low() & lower_mask) * (b.low() & lower_mask);
            let mut t = low >> half_bits;
            low &= lower_mask;
            t += (a.low() >> half_bits) * (b.low() & lower_mask);
            low += (t & lower_mask) << half_bits;
            let mut high = t >> half_bits;
            t = low >> half_bits;
            low &= lower_mask;
            t += (b.low() >> half_bits) * (a.low() & lower_mask);
            low += (t & lower_mask) << half_bits;
            high += t >> half_bits;
            high += (a.low() >> half_bits) * (b.low() >> half_bits);
            high = high.wrapping_add(a.high().wrapping_mul(b.low()).wrapping_add(a.low().wrapping_mul(b.high())));
            <$ty>::from_parts(low, high)
        }
    }
}

macro_rules! mulo {
    ($intrinsic:ident: $ty:ty) => {
        /// Returns `a * b` and sets `*overflow = 1` if `a * b` overflows
        #[cfg_attr(not(test), no_mangle)]
        pub extern "C" fn $intrinsic(a: $ty, b: $ty, overflow: &mut i32) -> $ty {
            *overflow = 0;
            let result = a.wrapping_mul(b);
            if a == <$ty>::min_value() {
                if b != 0 && b != 1 {
                    *overflow = 1;
                }
                return result;
            }
            if b == <$ty>::min_value() {
                if a != 0 && a != 1 {
                    *overflow = 1;
                }
                return result;
            }

            let sa = a >> (<$ty>::bits() - 1);
            let abs_a = (a ^ sa) - sa;
            let sb = b >> (<$ty>::bits() - 1);
            let abs_b = (b ^ sb) - sb;
            if abs_a < 2 || abs_b < 2 {
                return result;
            }
            if sa == sb {
                if abs_a > <$ty>::max_value() / abs_b {
                    *overflow = 1;
                }
            } else {
                if abs_a > <$ty>::min_value() / -abs_b {
                    *overflow = 1;
                }
            }
            result
        }
    }
}

#[cfg(not(all(feature = "c", target_arch = "x86")))]
mul!(__muldi3: u64);

mulo!(__mulosi4: i32);
mulo!(__mulodi4: i64);

#[cfg(test)]
mod tests {
    use qc::{I32, I64, U64};

    check! {
        fn __muldi3(f: extern fn(u64, u64) -> u64, a: U64, b: U64)
                    -> Option<u64> {
            Some(f(a.0, b.0))
        }

        fn __mulosi4(f: extern fn(i32, i32, &mut i32) -> i32,
                     a: I32,
                     b: I32) -> Option<(i32, i32)> {
            let (a, b) = (a.0, b.0);
            let mut overflow = 2;
            let r = f(a, b, &mut overflow);
            if overflow != 0 && overflow != 1 {
                return None
            }
            Some((r, overflow))
        }

        fn __mulodi4(f: extern fn(i64, i64, &mut i32) -> i64,
                     a: I64,
                     b: I64) -> Option<(i64, i32)> {
            let (a, b) = (a.0, b.0);
            let mut overflow = 2;
            let r = f(a, b, &mut overflow);
            if overflow != 0 && overflow != 1 {
                return None
            }
            Some((r, overflow))
        }
    }
}
<commit_msg>Auto merge of #132 - parched:master, r=japaric<commit_after>#[cfg(not(all(feature = "c", target_arch = "x86")))]
use int::LargeInt;
use int::Int;

macro_rules! mul {
    ($intrinsic:ident: $ty:ty) => {
        /// Returns `a * b`
        #[cfg_attr(not(test), no_mangle)]
        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
            let half_bits = <$ty>::bits() / 4;
            let lower_mask = !0 >> half_bits;
            let mut low = (a.low() & lower_mask).wrapping_mul(b.low() & lower_mask);
            let mut t = low >> half_bits;
            low &= lower_mask;
            t += (a.low() >> half_bits).wrapping_mul(b.low() & lower_mask);
            low += (t & lower_mask) << half_bits;
            let mut high = t >> half_bits;
            t = low >> half_bits;
            low &= lower_mask;
            t += (b.low() >> half_bits).wrapping_mul(a.low() & lower_mask);
            low += (t & lower_mask) << half_bits;
            high += t >> half_bits;
            high += (a.low() >> half_bits).wrapping_mul(b.low() >> half_bits);
            high = high.wrapping_add(a.high().wrapping_mul(b.low()).wrapping_add(a.low().wrapping_mul(b.high())));
            <$ty>::from_parts(low, high)
        }
    }
}

macro_rules! mulo {
    ($intrinsic:ident: $ty:ty) => {
        /// Returns `a * b` and sets `*overflow = 1` if `a * b` overflows
        #[cfg_attr(not(test), no_mangle)]
        pub extern "C" fn $intrinsic(a: $ty, b: $ty, overflow: &mut i32) -> $ty {
            *overflow = 0;
            let result = a.wrapping_mul(b);
            if a == <$ty>::min_value() {
                if b != 0 && b != 1 {
                    *overflow = 1;
                }
                return result;
            }
            if b == <$ty>::min_value() {
                if a != 0 && a != 1 {
                    *overflow = 1;
                }
                return result;
            }

            let sa = a >> (<$ty>::bits() - 1);
            let abs_a = (a ^ sa) - sa;
            let sb = b >> (<$ty>::bits() - 1);
            let abs_b = (b ^ sb) - sb;
            if abs_a < 2 || abs_b < 2 {
                return result;
            }
            if sa == sb {
                if abs_a > <$ty>::max_value() / abs_b {
                    *overflow = 1;
                }
            } else {
                if abs_a > <$ty>::min_value() / -abs_b {
                    *overflow = 1;
                }
            }
            result
        }
    }
}

#[cfg(not(all(feature = "c", target_arch = "x86")))]
mul!(__muldi3: u64);

mulo!(__mulosi4: i32);
mulo!(__mulodi4: i64);

#[cfg(test)]
mod tests {
    use qc::{I32, I64, U64};

    check! {
        fn __muldi3(f: extern fn(u64, u64) -> u64, a: U64, b: U64)
                    -> Option<u64> {
            Some(f(a.0, b.0))
        }

        fn __mulosi4(f: extern fn(i32, i32, &mut i32) -> i32,
                     a: I32,
                     b: I32) -> Option<(i32, i32)> {
            let (a, b) = (a.0, b.0);
            let mut overflow = 2;
            let r = f(a, b, &mut overflow);
            if overflow != 0 && overflow != 1 {
                return None
            }
            Some((r, overflow))
        }

        fn __mulodi4(f: extern fn(i64, i64, &mut i32) -> i64,
                     a: I64,
                     b: I64) -> Option<(i64, i32)> {
            let (a, b) = (a.0, b.0);
            let mut overflow = 2;
            let r = f(a, b, &mut overflow);
            if overflow != 0 && overflow != 1 {
                return None
            }
            Some((r, overflow))
        }
    }
}
<|endoftext|>