<commit_before>#![allow(unused)]
extern crate rz80;
extern crate time;
extern crate minifb;

use std::cell::RefCell;
use minifb::{Window, Key, Scale, WindowOptions};
use rz80::*;

const FB_WIDTH: usize=256;          // Z1013 framebuffer width
const FB_HEIGHT: usize=256;         // Z1013 framebuffer height
const Z1013_MAX_KEYS: usize=128;
const Z1013_FREQ_KHZ: i64=2000;     // frequency (2MHz = 2000 kHz)

const DEV_PIO: usize=0;
const DEV_PIO_A: usize=0;
const DEV_PIO_B: usize=1;
const NUM_DEVS: usize=2;

static Z1013_MON_A2: &'static [u8] = include_bytes!("z1013_mon_a2.bin");
static Z1013_FONT:   &'static [u8] = include_bytes!("z1013_font.bin");

struct Z1013 {
    kbd_column_nr_requested: usize,
    kbd_8x8_requested: bool,
    next_kbd_column_bits: u64,
    kbd_column_bits: u64,
    key_map: [u64; Z1013_MAX_KEYS],
}

impl Z1013 {
    pub fn new() -> Z1013 {
        let mut z1013 = Z1013 {
            kbd_column_nr_requested: 0,
            kbd_8x8_requested: false,
            next_kbd_column_bits: 0,
            kbd_column_bits: 0,
            key_map: [0; Z1013_MAX_KEYS],
        };
        z1013.init_keymap_8x8();
        z1013
    }

    fn kbd_bit(col: usize, line: usize, num_lines: usize) -> u64 {
        (1u64<<line)<<(col*num_lines)
    }

    fn init_key(&mut self, ascii: u8, col: usize, line: usize, shift:usize, num_lines: usize) {
        let mask =
            Z1013::kbd_bit(col, line, num_lines) |
            if shift != 0 {Z1013::kbd_bit(7, 6, num_lines)} else {0};
        self.key_map[ascii as usize] = mask;
    }

    fn init_keymap_8x8(&mut self) {

        // 8x8 keyboard matrix with 2 shift-layers
        let layers_8x8 =
            b"13579-  \
              QETUO@  \
              ADGJL*  \
              YCBM.^  \
              24680[  \
              WRZIP]  \
              SFHK+\\  \
              XVN,/_  \
              !#%')=  \
              qetuo`  \
              adgjl:  \
              ycbm>~  \
              \"$&( {  \
              wrzip}  \
              sfhk;|  \
              xvn<?   ";
        for shift in 0..2 {
            for line in 0..8 {
                for col in 0..8 {
                    let c = layers_8x8[shift*64 + line*8 + col];
                    if 0x20 != c {
                        self.init_key(c, col, line, shift, 8);
                    }
                }
            }
        }

        // special keys
        self.init_key(0x20, 6, 4, 0, 8);    // space
        self.init_key(0x08, 6, 2, 0, 8);    // cursor left
        self.init_key(0x09, 6, 3, 0, 8);    // cursor right
        self.init_key(0x0A, 6, 7, 0, 8);    // cursor down
        self.init_key(0x0B, 6, 6, 0, 8);    // cursor up
        self.init_key(0x0D, 6, 1, 0, 8);    // enter

        // Ctrl+C (== STOP/BREAK)
        self.key_map[0x03] = Z1013::kbd_bit(6, 5, 8) | Z1013::kbd_bit(1, 3, 4);
    }

    pub fn poweron(&mut self, cpu: &mut CPU) {

        // reset the hardware
        self.init_keymap_8x8();
        self.kbd_column_nr_requested = 0;
        self.kbd_8x8_requested = false;
        self.next_kbd_column_bits = 0;
        self.kbd_column_bits = 0;

        // map memory (64 KByte RAM incl. vid-mem, and 2 KByte ROM)
        cpu.mem.unmap_all();
        cpu.mem.map(1, 0x00000, 0x0000, true, 1<<16);
        cpu.mem.map_bytes(0, 0x10000, 0xF000, false, &Z1013_MON_A2);

        // start execution at address 0xF000
        cpu.reg.set_pc(0xF000);
    }

    pub fn reset(&mut self, cpu: &mut CPU) {
        self.kbd_column_nr_requested = 0;
        self.next_kbd_column_bits = 0;
        self.kbd_column_bits = 0;
        cpu.reg.set_pc(0xF000);
    }

    pub fn put_key(&mut self, ascii: u8) {
        let key_index = (ascii as usize) & (Z1013_MAX_KEYS-1);
        match ascii {
            0 => {
                self.next_kbd_column_bits = 0;
            },
            _ => {
                self.next_kbd_column_bits = self.key_map[key_index];
            }
        }
    }
}

struct System {
    pub cpu: RefCell<CPU>,
    pub pio: RefCell<PIO>,
    pub daisy: RefCell<Daisychain>,
    pub z1013: RefCell<Z1013>,
}

impl Bus for System {

    fn cpu_outp(&self, port: RegT, val: RegT) {
        match port & 0xFF {
            // PIO-A data
            0x00 => {
                // println!("PIO-A write data {:x}", val);
                self.pio.borrow_mut().write_data(self, PIO_A, val);
            },
            // PIO-A, control
            0x01 => {
                // println!("PIO-A write control {:x}", val);
                self.pio.borrow_mut().write_data(self, PIO_A, val);
            },
            // PIO-B, data
            0x02 => {
                // println!("PIO-B write data {:x}", val);
                self.pio.borrow_mut().write_data(self, PIO_B, val);
            },
            // PIO-B, data
            0x03 => {
                // println!("PIO-B write control {:x}", val);
                self.pio.borrow_mut().write_data(self, PIO_B, val);
            },
            // keyboard column
            0x08 => {
                // println!("keyboard column {:x}", val);
                let mut z1013 = self.z1013.borrow_mut();
                if val == 0 {
                    z1013.kbd_column_bits = z1013.next_kbd_column_bits;
                }
                z1013.kbd_column_nr_requested = val as usize;
            },
            _ => {
                println!("CPU OUT: {:x}", val);
            }
        }
    }

    fn cpu_inp(&self, port: RegT) -> RegT {
        match port & 0xFF {
            // PIO-A data
            0x00 => {
                // println!("PIO-A read data");
                self.pio.borrow_mut().read_data(self, PIO_A)
            },
            // PIO-A control
            0x01 => {
                // println!("PIO-A read control");
                self.pio.borrow_mut().read_control()
            },
            // PIO-B read data
            0x02 => {
                // println!("PIO-B read data");
                self.pio.borrow_mut().read_data(self, PIO_B)
            },
            // PIO-B read control
            0x03 => {
                // println!("PIO-B read control");
                self.pio.borrow_mut().read_control()
            },
            _ => {
                println!("CPU IN: {:x}", port);
                0xFF
            }
        }
    }

    fn pio_outp(&self, pio: usize, chn: usize, data: RegT) {
        if chn == PIO_B {
            // println!("PIO-B out {:x}", data);
            let mut z1013 = self.z1013.borrow_mut();
            z1013.kbd_8x8_requested = 0 != (data & (1<<4));
        }
        else {
            println!("PIO-A output (unused)");
        }
    }

    fn pio_inp(&self, pio: usize, chn: usize) -> RegT {
        if chn == PIO_B {
            // println!("PIO-B in");
            let z1013 = self.z1013.borrow();
            let col = z1013.kbd_column_nr_requested & 7;
            let mut val = z1013.kbd_column_bits >> (col*8);
            if z1013.kbd_8x8_requested {
                val >>= 4;
            }
            val = 0xF & !(val & 0xF);
            val as RegT
        }
        else {
            println!("PIO-A input (unused)");
            0xFF
        }
    }

    fn irq(&self, ctrl_id: usize, vec: u8) {
        println!("IRQ");
    }
    fn irq_cpu(&self) {
        println!("IRQ CPU");
    }

    fn irq_ack(&self) -> RegT {
        println!("IRQ ACK");
        0
    }
    fn irq_reti(&self) {
        println!("IRQ RETI");
    }

}

impl System {
    pub fn new() -> System {
        System {
            cpu: RefCell::new(CPU::new()),
            pio: RefCell::new(PIO::new(DEV_PIO)),
            daisy: RefCell::new(Daisychain::new(NUM_DEVS)),
            z1013: RefCell::new(Z1013::new()),
        }
    }

    pub fn poweron(&self) {
        let mut z1013 = self.z1013.borrow_mut();
        let mut cpu = self.cpu.borrow_mut();
        z1013.poweron(&mut cpu);
    }

    pub fn reset(&self) {
        let mut cpu = self.cpu.borrow_mut();
        let mut pio = self.pio.borrow_mut();
        let mut daisy = self.daisy.borrow_mut();
        let mut z1013 = self.z1013.borrow_mut();
        cpu.reset();
        pio.reset();
        daisy.reset();
        z1013.reset(&mut cpu);
    }

    pub fn step(&self, micro_seconds: i64) {
        let num_cycles = (Z1013_FREQ_KHZ * micro_seconds) / 1000;
        let mut cur_cycles = 0;
        let mut cpu = self.cpu.borrow_mut();
        while cur_cycles < num_cycles {
            cur_cycles += cpu.step(self);
        }
    }

    pub fn decode_video(&self, fb: &mut [u32]) {
        let mut i: usize = 0;
        let cpu = self.cpu.borrow();
        let vid_mem = &cpu.mem.heap[0xEC00..0xF000];
        for y in 0..32 {
            for py in 0..8 {
                for x in 0..32 {
                    let chr = vid_mem[(y<<5)+x] as usize;
                    let bits = Z1013_FONT[(chr<<3)|py];
                    for px in 0..8 {
                        fb[i] = if (bits & (1<<(7-px))) != 0 {0xFFFFFFFF} else {0xFF000000};
                        i += 1;
                    }
                }
            }
        }
    }

    pub fn put_key(&mut self, ascii: u8) {
        let mut z1013 = self.z1013.borrow_mut();
        z1013.put_key(ascii);
    }
}

fn create_window() -> Window {
    match Window::new("rz80 Z1013 Example",
               FB_WIDTH, FB_HEIGHT,
               WindowOptions {
                   resize: false,
                   scale: Scale::X2,
                   ..WindowOptions::default()
               }) {
        Ok(win) => win,
        Err(err) => panic!("Unable to create minifb window: {}", err)
    }
}

fn main() {
    let mut system = System::new();
    let mut window = create_window();
    let mut frame_buffer = [0u32; FB_WIDTH*FB_HEIGHT];
    let micro_seconds_per_frame: i64 = 1000000 / 60;
    system.poweron();
    while window.is_open() && !window.is_key_down(Key::Escape) {
        if window.is_key_down(Key::A) {
            println!("KEY!");
            system.put_key(b'A');
        }
        else {
            system.put_key(0);
        }
        system.step(micro_seconds_per_frame);
        system.decode_video(&mut frame_buffer);
        window.update_with_buffer(&frame_buffer);
    }
}

<commit_msg>Z1013 example: bugfix when writing PIO<commit_after>#![allow(unused)]
extern crate rz80;
extern crate time;
extern crate minifb;

use std::cell::RefCell;
use minifb::{Window, Key, Scale, WindowOptions};
use rz80::*;

const FB_WIDTH: usize=256;          // Z1013 framebuffer width
const FB_HEIGHT: usize=256;         // Z1013 framebuffer height
const Z1013_MAX_KEYS: usize=128;
const Z1013_FREQ_KHZ: i64=2000;     // frequency (2MHz = 2000 kHz)

const DEV_PIO: usize=0;
const DEV_PIO_A: usize=0;
const DEV_PIO_B: usize=1;
const NUM_DEVS: usize=2;

static Z1013_MON_A2: &'static [u8] = include_bytes!("z1013_mon_a2.bin");
static Z1013_FONT:   &'static [u8] = include_bytes!("z1013_font.bin");

struct Z1013 {
    kbd_column_nr_requested: usize,
    kbd_8x8_requested: bool,
    next_kbd_column_bits: u64,
    kbd_column_bits: u64,
    key_map: [u64; Z1013_MAX_KEYS],
}

impl Z1013 {
    pub fn new() -> Z1013 {
        let mut z1013 = Z1013 {
            kbd_column_nr_requested: 0,
            kbd_8x8_requested: false,
            next_kbd_column_bits: 0,
            kbd_column_bits: 0,
            key_map: [0; Z1013_MAX_KEYS],
        };
        z1013.init_keymap_8x8();
        z1013
    }

    fn kbd_bit(col: usize, line: usize, num_lines: usize) -> u64 {
        (1u64<<line)<<(col*num_lines)
    }

    fn init_key(&mut self, ascii: u8, col: usize, line: usize, shift:usize, num_lines: usize) {
        let mask =
            Z1013::kbd_bit(col, line, num_lines) |
            if shift != 0 {Z1013::kbd_bit(7, 6, num_lines)} else {0};
        self.key_map[ascii as usize] = mask;
    }

    fn init_keymap_8x8(&mut self) {

        // 8x8 keyboard matrix with 2 shift-layers
        let layers_8x8 =
            b"13579-  \
              QETUO@  \
              ADGJL*  \
              YCBM.^  \
              24680[  \
              WRZIP]  \
              SFHK+\\  \
              XVN,/_  \
              !#%')=  \
              qetuo`  \
              adgjl:  \
              ycbm>~  \
              \"$&( {  \
              wrzip}  \
              sfhk;|  \
              xvn<?   ";
        for shift in 0..2 {
            for line in 0..8 {
                for col in 0..8 {
                    let c = layers_8x8[shift*64 + line*8 + col];
                    if 0x20 != c {
                        self.init_key(c, col, line, shift, 8);
                    }
                }
            }
        }

        // special keys
        self.init_key(0x20, 6, 4, 0, 8);    // space
        self.init_key(0x08, 6, 2, 0, 8);    // cursor left
        self.init_key(0x09, 6, 3, 0, 8);    // cursor right
        self.init_key(0x0A, 6, 7, 0, 8);    // cursor down
        self.init_key(0x0B, 6, 6, 0, 8);    // cursor up
        self.init_key(0x0D, 6, 1, 0, 8);    // enter

        // Ctrl+C (== STOP/BREAK)
        self.key_map[0x03] = Z1013::kbd_bit(6, 5, 8) | Z1013::kbd_bit(1, 3, 4);
    }

    pub fn poweron(&mut self, cpu: &mut CPU) {

        // reset the hardware
        self.init_keymap_8x8();
        self.kbd_column_nr_requested = 0;
        self.kbd_8x8_requested = false;
        self.next_kbd_column_bits = 0;
        self.kbd_column_bits = 0;

        // map memory (64 KByte RAM incl. vid-mem, and 2 KByte ROM)
        cpu.mem.unmap_all();
        cpu.mem.map(1, 0x00000, 0x0000, true, 1<<16);
        cpu.mem.map_bytes(0, 0x10000, 0xF000, false, &Z1013_MON_A2);

        // start execution at address 0xF000
        cpu.reg.set_pc(0xF000);
    }

    pub fn reset(&mut self, cpu: &mut CPU) {
        self.kbd_column_nr_requested = 0;
        self.next_kbd_column_bits = 0;
        self.kbd_column_bits = 0;
        cpu.reg.set_pc(0xF000);
    }

    pub fn put_key(&mut self, ascii: u8) {
        let key_index = (ascii as usize) & (Z1013_MAX_KEYS-1);
        match ascii {
            0 => {
                self.next_kbd_column_bits = 0;
            },
            _ => {
                self.next_kbd_column_bits = self.key_map[key_index];
            }
        }
    }
}

struct System {
    pub cpu: RefCell<CPU>,
    pub pio: RefCell<PIO>,
    pub daisy: RefCell<Daisychain>,
    pub z1013: RefCell<Z1013>,
}

impl Bus for System {

    fn cpu_outp(&self, port: RegT, val: RegT) {
        match port & 0xFF {
            // PIO-A data
            0x00 => {
                // println!("PIO-A write data {:x}", val);
                self.pio.borrow_mut().write_data(self, PIO_A, val);
            },
            // PIO-A, control
            0x01 => {
                // println!("PIO-A write control {:x}", val);
                self.pio.borrow_mut().write_control(PIO_A, val);
            },
            // PIO-B, data
            0x02 => {
                // println!("PIO-B write data {:x}", val);
                self.pio.borrow_mut().write_data(self, PIO_B, val);
            },
            // PIO-B, control
            0x03 => {
                // println!("PIO-B write control {:x}", val);
                self.pio.borrow_mut().write_control(PIO_B, val);
            },
            // keyboard column
            0x08 => {
                // println!("keyboard column {:x}", val);
                let mut z1013 = self.z1013.borrow_mut();
                if val == 0 {
                    z1013.kbd_column_bits = z1013.next_kbd_column_bits;
                }
                z1013.kbd_column_nr_requested = val as usize;
            },
            _ => {
                println!("CPU OUT: {:x}", val);
            }
        }
    }

    fn cpu_inp(&self, port: RegT) -> RegT {
        match port & 0xFF {
            // PIO-A data
            0x00 => {
                // println!("PIO-A read data");
                self.pio.borrow_mut().read_data(self, PIO_A)
            },
            // PIO-A control
            0x01 => {
                // println!("PIO-A read control");
                self.pio.borrow_mut().read_control()
            },
            // PIO-B read data
            0x02 => {
                // println!("PIO-B read data");
                self.pio.borrow_mut().read_data(self, PIO_B)
            },
            // PIO-B read control
            0x03 => {
                // println!("PIO-B read control");
                self.pio.borrow_mut().read_control()
            },
            _ => {
                println!("CPU IN: {:x}", port);
                0xFF
            }
        }
    }

    fn pio_outp(&self, pio: usize, chn: usize, data: RegT) {
        if chn == PIO_B {
            // println!("PIO-B out {:x}", data);
            let mut z1013 = self.z1013.borrow_mut();
            z1013.kbd_8x8_requested = 0 != (data & (1<<4));
        }
        else {
            println!("PIO-A output (unused)");
        }
    }

    fn pio_inp(&self, pio: usize, chn: usize) -> RegT {
        if chn == PIO_B {
            // println!("PIO-B in");
            let z1013 = self.z1013.borrow();
            let col = z1013.kbd_column_nr_requested & 7;
            let mut val = z1013.kbd_column_bits >> (col*8);
            if z1013.kbd_8x8_requested {
                val >>= 4;
            }
            val = 0xF & !(val & 0xF);
            val as RegT
        }
        else {
            println!("PIO-A input (unused)");
            0xFF
        }
    }

    fn irq(&self, ctrl_id: usize, vec: u8) {
        println!("IRQ");
    }
    fn irq_cpu(&self) {
        println!("IRQ CPU");
    }

    fn irq_ack(&self) -> RegT {
        println!("IRQ ACK");
        0
    }
    fn irq_reti(&self) {
        println!("IRQ RETI");
    }

}

impl System {
    pub fn new() -> System {
        System {
            cpu: RefCell::new(CPU::new()),
            pio: RefCell::new(PIO::new(DEV_PIO)),
            daisy: RefCell::new(Daisychain::new(NUM_DEVS)),
            z1013: RefCell::new(Z1013::new()),
        }
    }

    pub fn poweron(&self) {
        let mut z1013 = self.z1013.borrow_mut();
        let mut cpu = self.cpu.borrow_mut();
        z1013.poweron(&mut cpu);
    }

    pub fn reset(&self) {
        let mut cpu = self.cpu.borrow_mut();
        let mut pio = self.pio.borrow_mut();
        let mut daisy = self.daisy.borrow_mut();
        let mut z1013 = self.z1013.borrow_mut();
        cpu.reset();
        pio.reset();
        daisy.reset();
        z1013.reset(&mut cpu);
    }

    pub fn step(&self, micro_seconds: i64) {
        let num_cycles = (Z1013_FREQ_KHZ * micro_seconds) / 1000;
        let mut cur_cycles = 0;
        let mut cpu = self.cpu.borrow_mut();
        while cur_cycles < num_cycles {
            cur_cycles += cpu.step(self);
        }
    }

    pub fn decode_video(&self, fb: &mut [u32]) {
        let mut i: usize = 0;
        let cpu = self.cpu.borrow();
        let vid_mem = &cpu.mem.heap[0xEC00..0xF000];
        for y in 0..32 {
            for py in 0..8 {
                for x in 0..32 {
                    let chr = vid_mem[(y<<5)+x] as usize;
                    let bits = Z1013_FONT[(chr<<3)|py];
                    for px in 0..8 {
                        fb[i] = if (bits & (1<<(7-px))) != 0 {0xFFFFFFFF} else {0xFF000000};
                        i += 1;
                    }
                }
            }
        }
    }

    pub fn put_key(&mut self, ascii: u8) {
        let mut z1013 = self.z1013.borrow_mut();
        z1013.put_key(ascii);
    }
}

fn create_window() -> Window {
    match Window::new("rz80 Z1013 Example",
               FB_WIDTH, FB_HEIGHT,
               WindowOptions {
                   resize: false,
                   scale: Scale::X2,
                   ..WindowOptions::default()
               }) {
        Ok(win) => win,
        Err(err) => panic!("Unable to create minifb window: {}", err)
    }
}

fn main() {
    let mut system = System::new();
    let mut window = create_window();
    let mut frame_buffer = [0u32; FB_WIDTH*FB_HEIGHT];
    let micro_seconds_per_frame: i64 = 1000000 / 60;
    system.poweron();
    while window.is_open() && !window.is_key_down(Key::Escape) {
        if window.is_key_down(Key::A) {
            println!("KEY!");
            system.put_key(b'A');
        }
        else {
            system.put_key(0);
        }
        system.step(micro_seconds_per_frame);
        system.decode_video(&mut frame_buffer);
        window.update_with_buffer(&frame_buffer);
    }
}

<|endoftext|>


<commit_before>#![feature(test)]

extern crate crossbeam;
extern crate ipc_channel;
extern crate test;

use ipc_channel::platform;

use std::sync::{mpsc, Mutex};

/// Allows doing multiple inner iterations per bench.iter() run.
///
/// This is mostly to amortise the overhead of spawning a thread in the benchmark
/// when sending larger messages (that might be fragmented).
///
/// Note that you need to compensate the displayed results
/// for the proportionally longer runs yourself,
/// as the benchmark framework doesn't know about the inner iterations...
const ITERATIONS: usize = 1;

#[bench]
fn create_channel(b: &mut test::Bencher) {
    b.iter(|| {
        for _ in 0..ITERATIONS {
            platform::channel().unwrap();
        }
    });
}

fn bench_size(b: &mut test::Bencher, size: usize) {
    let data: Vec<u8> = (0..size).map(|i| (i % 251) as u8).collect();
    let (tx, rx) = platform::channel().unwrap();

    let (wait_tx, wait_rx) = mpsc::channel();
    let wait_rx = Mutex::new(wait_rx);

    if size > platform::OsIpcSender::get_max_fragment_size() {
        b.iter(|| {
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let wait_rx = wait_rx.lock().unwrap();
                    for _ in 0..ITERATIONS {
                        tx.send(&data, vec![], vec![]).unwrap();
                        if ITERATIONS > 1 {
                            // Prevent beginning of the next send
                            // from overlapping with receive of last fragment,
                            // as otherwise results of runs with a large tail fragment
                            // are significantly skewed.
                            wait_rx.recv().unwrap();
                        }
                    }
                });
                for _ in 0..ITERATIONS {
                    rx.recv().unwrap();
                    if ITERATIONS > 1 {
                        wait_tx.send(()).unwrap();
                    }
                }
                // For reasons mysterious to me,
                // not returning a value *from every branch*
                // adds some 100 ns or so of overhead to all results --
                // which is quite significant for very short tests...
                0
            })
        });
    } else {
        b.iter(|| {
            for _ in 0..ITERATIONS {
                tx.send(&data, vec![], vec![]).unwrap();
                rx.recv().unwrap();
            }
            0
        });
    }
}

#[bench]
fn size_00_1(b: &mut test::Bencher) {
    bench_size(b, 1);
}
#[bench]
fn size_01_2(b: &mut test::Bencher) {
    bench_size(b, 2);
}
#[bench]
fn size_02_4(b: &mut test::Bencher) {
    bench_size(b, 4);
}
#[bench]
fn size_03_8(b: &mut test::Bencher) {
    bench_size(b, 8);
}
#[bench]
fn size_04_16(b: &mut test::Bencher) {
    bench_size(b, 16);
}
#[bench]
fn size_05_32(b: &mut test::Bencher) {
    bench_size(b, 32);
}
#[bench]
fn size_06_64(b: &mut test::Bencher) {
    bench_size(b, 64);
}
#[bench]
fn size_07_128(b: &mut test::Bencher) {
    bench_size(b, 128);
}
#[bench]
fn size_08_256(b: &mut test::Bencher) {
    bench_size(b, 256);
}
#[bench]
fn size_09_512(b: &mut test::Bencher) {
    bench_size(b, 512);
}
#[bench]
fn size_10_1k(b: &mut test::Bencher) {
    bench_size(b, 1 * 1024);
}
#[bench]
fn size_11_2k(b: &mut test::Bencher) {
    bench_size(b, 2 * 1024);
}
#[bench]
fn size_12_4k(b: &mut test::Bencher) {
    bench_size(b, 4 * 1024);
}
#[bench]
fn size_13_8k(b: &mut test::Bencher) {
    bench_size(b, 8 * 1024);
}
#[bench]
fn size_14_16k(b: &mut test::Bencher) {
    bench_size(b, 16 * 1024);
}
#[bench]
fn size_15_32k(b: &mut test::Bencher) {
    bench_size(b, 32 * 1024);
}
#[bench]
fn size_16_64k(b: &mut test::Bencher) {
    bench_size(b, 64 * 1024);
}
#[bench]
fn size_17_128k(b: &mut test::Bencher) {
    bench_size(b, 128 * 1024);
}
#[bench]
fn size_18_256k(b: &mut test::Bencher) {
    bench_size(b, 256 * 1024);
}
#[bench]
fn size_19_512k(b: &mut test::Bencher) {
    bench_size(b, 512 * 1024);
}
#[bench]
fn size_20_1m(b: &mut test::Bencher) {
    bench_size(b, 1 * 1024 * 1024);
}
#[bench]
fn size_21_2m(b: &mut test::Bencher) {
    bench_size(b, 2 * 1024 * 1024);
}
#[bench]
fn size_22_4m(b: &mut test::Bencher) {
    bench_size(b, 4 * 1024 * 1024);
}
#[bench]
fn size_23_8m(b: &mut test::Bencher) {
    bench_size(b, 8 * 1024 * 1024);
}
<commit_msg>Auto merge of #122 - antrik:fix-bench, r=Wafflespeanut<commit_after>#![feature(test)]

extern crate crossbeam;
extern crate ipc_channel;
extern crate test;

use ipc_channel::platform;

use std::sync::{mpsc, Mutex};

/// Allows doing multiple inner iterations per bench.iter() run.
///
/// This is mostly to amortise the overhead of spawning a thread in the benchmark
/// when sending larger messages (that might be fragmented).
///
/// Note that you need to compensate the displayed results
/// for the proportionally longer runs yourself,
/// as the benchmark framework doesn't know about the inner iterations...
const ITERATIONS: usize = 1;

#[bench]
fn create_channel(b: &mut test::Bencher) {
    b.iter(|| {
        for _ in 0..ITERATIONS {
            platform::channel().unwrap();
        }
    });
}

fn bench_size(b: &mut test::Bencher, size: usize) {
    let data: Vec<u8> = (0..size).map(|i| (i % 251) as u8).collect();
    let (tx, rx) = platform::channel().unwrap();

    let (wait_tx, wait_rx) = mpsc::channel();
    let wait_rx = Mutex::new(wait_rx);

    if size > platform::OsIpcSender::get_max_fragment_size() {
        b.iter(|| {
            crossbeam::scope(|scope| {
                let tx = tx.clone();
                scope.spawn(|| {
                    let wait_rx = wait_rx.lock().unwrap();
                    let tx = tx;
                    for _ in 0..ITERATIONS {
                        tx.send(&data, vec![], vec![]).unwrap();
                        if ITERATIONS > 1 {
                            // Prevent beginning of the next send
                            // from overlapping with receive of last fragment,
                            // as otherwise results of runs with a large tail fragment
                            // are significantly skewed.
                            wait_rx.recv().unwrap();
                        }
                    }
                });
                for _ in 0..ITERATIONS {
                    rx.recv().unwrap();
                    if ITERATIONS > 1 {
                        wait_tx.send(()).unwrap();
                    }
                }
                // For reasons mysterious to me,
                // not returning a value *from every branch*
                // adds some 100 ns or so of overhead to all results --
                // which is quite significant for very short tests...
                0
            })
        });
    } else {
        b.iter(|| {
            for _ in 0..ITERATIONS {
                tx.send(&data, vec![], vec![]).unwrap();
                rx.recv().unwrap();
            }
            0
        });
    }
}

#[bench]
fn size_00_1(b: &mut test::Bencher) {
    bench_size(b, 1);
}
#[bench]
fn size_01_2(b: &mut test::Bencher) {
    bench_size(b, 2);
}
#[bench]
fn size_02_4(b: &mut test::Bencher) {
    bench_size(b, 4);
}
#[bench]
fn size_03_8(b: &mut test::Bencher) {
    bench_size(b, 8);
}
#[bench]
fn size_04_16(b: &mut test::Bencher) {
    bench_size(b, 16);
}
#[bench]
fn size_05_32(b: &mut test::Bencher) {
    bench_size(b, 32);
}
#[bench]
fn size_06_64(b: &mut test::Bencher) {
    bench_size(b, 64);
}
#[bench]
fn size_07_128(b: &mut test::Bencher) {
    bench_size(b, 128);
}
#[bench]
fn size_08_256(b: &mut test::Bencher) {
    bench_size(b, 256);
}
#[bench]
fn size_09_512(b: &mut test::Bencher) {
    bench_size(b, 512);
}
#[bench]
fn size_10_1k(b: &mut test::Bencher) {
    bench_size(b, 1 * 1024);
}
#[bench]
fn size_11_2k(b: &mut test::Bencher) {
    bench_size(b, 2 * 1024);
}
#[bench]
fn size_12_4k(b: &mut test::Bencher) {
    bench_size(b, 4 * 1024);
}
#[bench]
fn size_13_8k(b: &mut test::Bencher) {
    bench_size(b, 8 * 1024);
}
#[bench]
fn size_14_16k(b: &mut test::Bencher) {
    bench_size(b, 16 * 1024);
}
#[bench]
fn size_15_32k(b: &mut test::Bencher) {
    bench_size(b, 32 * 1024);
}
#[bench]
fn size_16_64k(b: &mut test::Bencher) {
    bench_size(b, 64 * 1024);
}
#[bench]
fn size_17_128k(b: &mut test::Bencher) {
    bench_size(b, 128 * 1024);
}
#[bench]
fn size_18_256k(b: &mut test::Bencher) {
    bench_size(b, 256 * 1024);
}
#[bench]
fn size_19_512k(b: &mut test::Bencher) {
    bench_size(b, 512 * 1024);
}
#[bench]
fn size_20_1m(b: &mut test::Bencher) {
    bench_size(b, 1 * 1024 * 1024);
}
#[bench]
fn size_21_2m(b: &mut test::Bencher) {
    bench_size(b, 2 * 1024 * 1024);
}
#[bench]
fn size_22_4m(b: &mut test::Bencher) {
    bench_size(b, 4 * 1024 * 1024);
}
#[bench]
fn size_23_8m(b: &mut test::Bencher) {
    bench_size(b, 8 * 1024 * 1024);
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2018 Scott Lamb <slamb@slamb.org>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE.txt or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT.txt or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Benchmarks of serving data built in to the binary via `include_bytes!`, using both the
//! `serve` function on an `Entity` and the `streaming_body` method.

#![feature(test)]

extern crate futures;
extern crate http;
extern crate http_serve;
extern crate hyper;
#[macro_use]
extern crate lazy_static;
extern crate mime;
extern crate reqwest;
extern crate test;
extern crate tokio;

use futures::{future, stream};
use futures::{Future, Stream};
use http::header::HeaderValue;
use http::{Request, Response};
use http_serve::streaming_body;
use hyper::Body;
use std::io::{Read, Write};
use std::ops::Range;
use std::str::FromStr;
use std::time::SystemTime;

static WONDERLAND: &[u8] = include_bytes!("wonderland.txt");

struct WonderlandEntity;

impl http_serve::Entity for WonderlandEntity {
    type Data = hyper::Chunk;
    type Error = Box<::std::error::Error + Send + Sync>;

    fn len(&self) -> u64 {
        WONDERLAND.len() as u64
    }
    fn get_range(
        &self,
        range: Range<u64>,
    ) -> Box<Stream<Item = Self::Data, Error = Self::Error> + Send> {
        Box::new(stream::once(Ok(WONDERLAND
            [range.start as usize..range.end as usize]
            .into())))
    }
    fn add_headers(&self, headers: &mut http::header::HeaderMap) {
        headers.insert(
            http::header::CONTENT_TYPE,
            HeaderValue::from_static("text/plain"),
        );
    }
    fn etag(&self) -> Option<HeaderValue> {
        None
    }
    fn last_modified(&self) -> Option<SystemTime> {
        None
    }
}

fn serve_req(req: Request<Body>) -> Response<Body> {
    let path = req.uri().path();
    match path.as_bytes()[1] {
        b'e' => {
            // entity
            http_serve::serve(WonderlandEntity, &req)
        }
        b'b' => {
            // chunked, data written before returning the Response.
            let l = u32::from_str(&path[2..]).unwrap();
            let (resp, w) = streaming_body(&req).with_gzip_level(l).build();
            if let Some(mut w) = w {
                w.write_all(WONDERLAND).unwrap();
            }
            resp
        }
        b'a' => {
            // chunked, data written after returning the Response.
            let l = u32::from_str(&path[2..]).unwrap();
            let (resp, w) = streaming_body(&req).with_gzip_level(l).build();
            tokio::spawn(future::lazy(|| {
                if let Some(mut w) = w {
                    w.write_all(WONDERLAND).unwrap();
                }
                Ok(())
            }));
            resp
        }
        _ => unreachable!(),
    }
}

/// Returns the hostport of a newly-created, never-destructed server.
fn new_server() -> String {
    let (tx, rx) = ::std::sync::mpsc::channel();
    ::std::thread::spawn(move || {
        let addr = "127.0.0.1:0".parse().unwrap();
        let server =
            hyper::server::Server::bind(&addr).serve(|| hyper::service::service_fn_ok(serve_req));
        let addr = server.local_addr();
        tx.send(addr).unwrap();
        tokio::run(server.map_err(|e| panic!(e)))
    });
    let addr = rx.recv().unwrap();
    format!("http://{}:{}", addr.ip(), addr.port())
}

lazy_static! {
    static ref SERVER: String = { new_server() };
}

fn serve(b: &mut test::Bencher, path: &str) {
    let client = reqwest::Client::new();

    // Add enough buffer space for the uncompressed representation and some extra header stuff.
    // Should be plenty for effective or ineffective compression.
    let mut buf = Vec::with_capacity(WONDERLAND.len());
    let mut run = || {
        let mut resp = client
            .get(&format!("{}/{}", &*SERVER, path))
            .send()
            .unwrap();
        buf.clear();
        let size = resp.read_to_end(&mut buf).unwrap();
        assert_eq!(reqwest::StatusCode::Ok, resp.status());
        assert_eq!(size, WONDERLAND.len());
    };
    run(); // warm.
    b.iter(run);
    b.bytes = WONDERLAND.len() as u64;
}

#[bench]
fn serve_entity(b: &mut test::Bencher) {
    serve(b, "e");
}

#[bench]
fn serve_chunked_after_gzip_level_0(b: &mut test::Bencher) {
    serve(b, "a0");
}

#[bench]
fn serve_chunked_before_gzip_level_0(b: &mut test::Bencher) {
    serve(b, "b0");
}

#[bench]
fn serve_chunked_before_gzip_level_1(b: &mut test::Bencher) {
    serve(b, "b1");
}

#[bench]
fn serve_chunked_before_gzip_level_2(b: &mut test::Bencher) {
    serve(b, "b2");
}

#[bench]
fn serve_chunked_before_gzip_level_3(b: &mut test::Bencher) {
    serve(b, "b3");
}

#[bench]
fn serve_chunked_before_gzip_level_4(b: &mut test::Bencher) {
    serve(b, "b4");
}

#[bench]
fn serve_chunked_before_gzip_level_5(b: &mut test::Bencher) {
    serve(b, "b5");
}

#[bench]
fn serve_chunked_before_gzip_level_6(b: &mut test::Bencher) {
    serve(b, "b6");
}

#[bench]
fn serve_chunked_before_gzip_level_7(b: &mut test::Bencher) {
    serve(b, "b7");
}

#[bench]
fn serve_chunked_before_gzip_level_8(b: &mut test::Bencher) {
    serve(b, "b8");
}

#[bench]
fn serve_chunked_before_gzip_level_9(b: &mut test::Bencher) {
    serve(b, "b9");
}
<commit_msg>refine serve benchmarks<commit_after>// Copyright (c) 2016-2018 Scott Lamb <slamb@slamb.org>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE.txt or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT.txt or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Benchmarks of serving data built in to the binary via `include_bytes!`, using both the
//! `serve` function on an `Entity` and the `streaming_body` method.

#![feature(test)]

extern crate bytes;
extern crate futures;
extern crate http;
extern crate http_serve;
extern crate hyper;
#[macro_use]
extern crate lazy_static;
extern crate mime;
extern crate reqwest;
extern crate test;
extern crate tokio;

use bytes::{Bytes, BytesMut};
use futures::{future, stream};
use futures::{Future, Stream};
use http::header::HeaderValue;
use http::{Request, Response};
use http_serve::streaming_body;
use hyper::Body;
use std::io::{Read, Write};
use std::ops::Range;
use std::str::FromStr;
use std::time::SystemTime;

static WONDERLAND: &[u8] = include_bytes!("wonderland.txt");

struct BytesEntity(Bytes);

impl http_serve::Entity for BytesEntity {
    type Data = hyper::Chunk;
    type Error = Box<::std::error::Error + Send + Sync>;

    fn len(&self) -> u64 {
        self.0.len() as u64
    }
    fn get_range(
        &self,
        range: Range<u64>,
    ) -> Box<Stream<Item = Self::Data, Error = Self::Error> + Send> {
        Box::new(stream::once(Ok(self
            .0
            .slice(range.start as usize, range.end as usize)
            .into())))
    }
    fn add_headers(&self, headers: &mut http::header::HeaderMap) {
        headers.insert(
            http::header::CONTENT_TYPE,
            HeaderValue::from_static("text/plain"),
        );
    }
    fn etag(&self) -> Option<HeaderValue> {
        None
    }
    fn last_modified(&self) -> Option<SystemTime> {
        None
    }
}

fn serve_req(req: Request<Body>) -> Response<Body> {
    let path = req.uri().path();
    match path.as_bytes()[1] {
        b's' => {
            // static entity
            http_serve::serve(BytesEntity(Bytes::from_static(WONDERLAND)), &req)
        }
        b'c' => {
            // copied entity
            let mut b = BytesMut::with_capacity(WONDERLAND.len());
            b.extend_from_slice(WONDERLAND);
            http_serve::serve(BytesEntity(b.freeze()), &req)
        }
        b'b' => {
            // chunked, data written before returning the Response.
            let l = u32::from_str(&path[2..]).unwrap();
            let (resp, w) = streaming_body(&req).with_gzip_level(l).build();
            if let Some(mut w) = w {
                w.write_all(WONDERLAND).unwrap();
            }
            resp
        }
        b'a' => {
            // chunked, data written after returning the Response.
            let l = u32::from_str(&path[2..]).unwrap();
            let (resp, w) = streaming_body(&req).with_gzip_level(l).build();
            tokio::spawn(future::lazy(|| {
                if let Some(mut w) = w {
                    w.write_all(WONDERLAND).unwrap();
                }
                Ok(())
            }));
            resp
        }
        _ => unreachable!(),
    }
}

/// Returns the hostport of a newly-created, never-destructed server.
fn new_server() -> String {
    let (tx, rx) = ::std::sync::mpsc::channel();
    ::std::thread::spawn(move || {
        let addr = "127.0.0.1:0".parse().unwrap();
        let server =
            hyper::server::Server::bind(&addr).serve(|| hyper::service::service_fn_ok(serve_req));
        let addr = server.local_addr();
        tx.send(addr).unwrap();
        tokio::run(server.map_err(|e| panic!(e)))
    });
    let addr = rx.recv().unwrap();
    format!("http://{}:{}", addr.ip(), addr.port())
}

lazy_static! {
    static ref SERVER: String = { new_server() };
}

fn serve(b: &mut test::Bencher, path: &str) {
    let client = reqwest::Client::new();

    // Add enough buffer space for the uncompressed representation and some extra header stuff.
    // Should be plenty for effective or ineffective compression.
    let mut buf = Vec::with_capacity(WONDERLAND.len());
    let mut run = || {
        let mut resp = client
            .get(&format!("{}/{}", &*SERVER, path))
            .send()
            .unwrap();
        buf.clear();
        let size = resp.read_to_end(&mut buf).unwrap();
        assert_eq!(reqwest::StatusCode::Ok, resp.status());
        assert_eq!(size, WONDERLAND.len());
    };
    run(); // warm.
    b.iter(run);
    b.bytes = WONDERLAND.len() as u64;
}

#[bench]
fn serve_static_entity(b: &mut test::Bencher) {
    serve(b, "s");
}

#[bench]
fn serve_copied_entity(b: &mut test::Bencher) {
    serve(b, "c");
}

#[bench]
fn serve_chunked_after_gzip_level_0(b: &mut test::Bencher) {
    serve(b, "a0");
}

#[bench]
fn serve_chunked_before_gzip_level_0(b: &mut test::Bencher) {
    serve(b, "b0");
}

#[bench]
fn serve_chunked_before_gzip_level_1(b: &mut test::Bencher) {
    serve(b, "b1");
}

#[bench]
fn serve_chunked_before_gzip_level_2(b: &mut test::Bencher) {
    serve(b, "b2");
}

#[bench]
fn serve_chunked_before_gzip_level_3(b: &mut test::Bencher) {
    serve(b, "b3");
}

#[bench]
fn serve_chunked_before_gzip_level_4(b: &mut test::Bencher) {
    serve(b, "b4");
}

#[bench]
fn serve_chunked_before_gzip_level_5(b: &mut test::Bencher) {
    serve(b, "b5");
}

#[bench]
fn serve_chunked_before_gzip_level_6(b: &mut test::Bencher) {
    serve(b, "b6");
}

#[bench]
fn serve_chunked_before_gzip_level_7(b: &mut test::Bencher) {
    serve(b, "b7");
}

#[bench]
fn serve_chunked_before_gzip_level_8(b: &mut test::Bencher) {
    serve(b, "b8");
}

#[bench]
fn serve_chunked_before_gzip_level_9(b: &mut test::Bencher) {
    serve(b, "b9");
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate x11;

use std::ptr;
use x11::xlib;
use x11::xlib::Window;
use super::super::libx;

use super::config::Config;
use super::Container;
use super::Workspaces;
use super::handler;

unsafe extern fn error_handler(display: *mut xlib::Display, event: *mut xlib::XErrorEvent) -> libc::c_int {
    // match event.error_code {
    //     xlib::BadAtom => {
    //         println!("bad atom");
    //     }
    //     _ => {}
    // }
    x11::xmu::XmuSimpleErrorHandler(display, event);
    1
}

extern "C" {
    fn setlocale(category: i32, locale: *const i8) -> *mut i8;
}

fn load_resource(mut context: &mut libx::Context) {
    use std::mem;
    use std::ffi;
    let screen = context.screen_num;
    let root = context.root;
    let display = context.display;
    let mut values: xlib::XGCValues = unsafe{ mem::zeroed() };
    // let gc = libx::create_gc(self.context, self.id, 0, values);
    let gc = libx::default_gc(*context, screen);

    unsafe {
        let black = xlib::XBlackPixel(display, screen);
        let white = xlib::XWhitePixel(display, screen);

        xlib::XSetLineAttributes(display, gc, 5, 0, 0, 0);

        let cmap = xlib::XDefaultColormap(display, screen);
        let mut color: xlib::XColor = mem::zeroed();
        let name = ffi::CString::new("blue").unwrap().as_ptr();
        let r = xlib::XParseColor(display, cmap, name, &mut color);
        xlib::XAllocColor(display, cmap, &mut color);

        context.gc = gc;
        context.focus_bg = black;
        context.focus_fg = color.pixel;
        context.unfocus_bg = black;
        context.unfocus_fg = black;
        context.font_color = white;

        let s = ffi::CString::new("").unwrap().as_ptr();
        let p = setlocale(6, s);
        let res = xlib::XSupportsLocale();
        let res = xlib::XSetLocaleModifiers(s);

        let mut missing_charsets = ptr::null_mut();
        let mut num_missing_charsets: i32 = 0;
        let mut default_string = ptr::null_mut();
        // let name = "-misc-fixed-*-*-*-*-*-130-75-75-*-*-*-*";
        let name = "*";
        let fontbase = ffi::CString::new(name).unwrap().as_ptr();
        let fontset = xlib::XCreateFontSet(display,
                                           fontbase,
                                           &mut missing_charsets,
                                           &mut num_missing_charsets,
                                           &mut default_string);
        if num_missing_charsets > 0 {
            xlib::XFreeStringList(missing_charsets);
        }
        context.fontset = fontset;
    }
}

pub struct WindowManager {
    pub context: libx::Context,
    pub workspaces: Workspaces,
    config: Config
}

impl WindowManager {
    pub fn new() -> WindowManager {
	let res = libx::open_display(None);
        let mut context = match res {
            Some(c) => {
                c
            }
            None => {
                panic!("can't open display")
            }
        };

	context.screen_num  = libx::default_screen(context);
	context.root = libx::root_window(context, context.screen_num);
        load_resource(&mut context);

	let mut wm = WindowManager {
            context: context,
            config: Config::load(),
            workspaces: Workspaces::new(context)
        };
        wm
    }

    pub fn clean(&mut self) {
        libx::close_display(self.context);
    }

    pub fn handle_create(&mut self, event: &xlib::XCreateWindowEvent) {
        if event.override_redirect != 0 {
            return;
        }

        let attrs = libx::get_window_attributes(self.context, event.window);
        println!("{} attr {} {}", event.window, attrs.width, attrs.height);
        // get window property
        let n = libx::get_text_property(self.context, event.window, xlib::XA_WM_NAME);
        match n {
            Some(s) => {debug!("create window {} for {}", event.window, s);}
            None => {}
        }

        // let atoms = libx::get_wm_protocols(self.context, event.window);
        // for a in atoms.iter() {
        //     println!("atom {}", a);
        //     let name = libx::get_atom_name(self.context, *a);
        //     match name {
        //         Some(n) => println!("name {}", n),
        //         None => println!("name {}", a),
        //     };
        // }
    }

    pub fn handle_destroy(&mut self, event: &xlib::XDestroyWindowEvent) {
        self.workspaces.remove_window(event.window);
        if self.workspaces.get_focus().is_none() {
            self.workspaces.set_focus(self.context.root);
        }
    }

    pub fn handle_map_request(&mut self, event: &xlib::XMapRequestEvent) {

        // add app top-level window to workspace
        // let window = Window::new(self.context, event.window);
        let manage = Workspaces::can_manage(self.context, event.window);

        if manage {
            debug!("top level window");
            let mut container = Container::from_id(self.context, event.window);
            container.map();
            // container.focus();
            // change attributes before display
            let mask = 0x420010;
            let mask = xlib::EnterWindowMask | xlib::PropertyChangeMask;
            libx::select_input(self.context, container.raw_id(), mask);

            if self.config.titlebar_height > 0 {
                container.titlebar_height = self.config.titlebar_height;
            }
            self.workspaces.insert_window(container);
        }
        else {
            libx::map_window(self.context, event.window);
        }
    }

    pub fn handle_client_message(&mut self, event: &xlib::XClientMessageEvent) {
        println!("message type {}", event.message_type);
        let s = libx::get_atom_name(self.context, event.message_type);
        match s {
            Some(v) => println!("{}", &v),
            None => {}
        }

        match event.format {
            8 => {
                for i in 0..20 {
                    println!("{}", event.data.get_byte(i));
                }
            }
            16 => {
                for i in 0..10 {
                    println!("{}", event.data.get_short(i))
                }
            }
            32 => {
                for i in 0..5 {
                    let a = event.data.get_long(i);
                    if a != 0{
                        let s = libx::get_atom_name(self.context, a as xlib::Atom);
                        match s {
                            Some(v) => println!("{}", v),
                            None => {}
                        }
                    }
                }
            }
            _ => {}
        }
    }

    pub fn handle_button_motion(&mut self, event: &xlib::XMotionEvent) {
        let (window, _) = libx::get_input_focus(self.context);
        if window != event.window {
            self.workspaces.set_focus(event.window);
        }
    }

    pub fn handle_button_press(&mut self, event: &xlib::XButtonEvent) {
        let id = match self.workspaces.get_container(event.window) {
            Some((_,container)) => {
                let client = container.query_point(event.x, event.y);
                match client {
                    Some(c) => {
                        c.raw_id()
                    }
                    None => { container.raw_id() }
                }
            }
            None => { return }
        };
        self.workspaces.set_focus(id);
    }
    pub fn handle_key_release(&mut self, event: &xlib::XKeyEvent) {
        if event.state > 0 {
            let sym = libx::lookup_keysym(*event, 0);
            let b = handler::KeyBind {
                key: sym,
                mask: event.state,
            };
            debug!("key {} {}", event.state, sym);

            match self.config.bindsyms.get_mut(&b) {
                Some(handler) => {
                    handler.handle(&mut self.workspaces, self.context);
                }
                None => {
                    println!("no bind");
                }
            }
        }
    }

    pub fn handle_property(&mut self, event: &xlib::XPropertyEvent) {
        let usertime = libx::get_atom(self.context, "_NET_WM_USER_TIME");
        match event.atom {
            usertime => {
                self.workspaces.set_focus(event.window);
            }
        }
    }

    pub fn handle_configure_request(&mut self, event: &xlib::XConfigureRequestEvent) {
        let mut change = xlib::XWindowChanges {
            x: event.x,
            y: event.y,
            width: event.width,
            height: event.height,
            border_width: event.border_width,
            sibling: event.above,
            stack_mode: event.detail
        };
        debug!("config x: {}, y: {}, width: {}, height: {}",
               change.x, change.y, change.width, change.height);
        libx::configure_window(self.context, event.window, event.value_mask as u32, change);
    }

    pub fn handle_focus_in(&mut self, event: &xlib::XFocusChangeEvent) {
        self.workspaces.set_focus(event.window);
    }

    pub fn handle_enter(&mut self, event: &xlib::XCrossingEvent){
        if event.focus == 0 {
            self.workspaces.set_focus(event.window);
        }
    }

    pub fn handle(&mut self, e: xlib::XEvent) {
        let t = e.get_type();
        match t {
            xlib::CreateNotify => {
                let event: xlib::XCreateWindowEvent = From::from(e);
                debug!("create notify {}", event.window);
                self.handle_create(&event);
            }
            xlib::DestroyNotify => {
                let event: xlib::XDestroyWindowEvent = From::from(e);
                debug!("destroy notify {}", event.window);
                self.handle_destroy(&event);
            }
            xlib::MapNotify => {
                let event: xlib::XMapEvent = From::from(e);
                debug!("map notify {}", event.window);
            }
            xlib::UnmapNotify => {
                let event: xlib::XUnmapEvent = From::from(e);
                debug!("unmap notify {}", event.window);
            }
            xlib::MapRequest => {
                let event: xlib::XMapRequestEvent = From::from(e);
                debug!("map request {}", event.window);
                self.handle_map_request(&event);
            }
            xlib::ClientMessage => {
                debug!("client message");
                // let event = cast_event::<xlib::XClientMessageEvent>(&e);
                let event: xlib::XClientMessageEvent = From::from(e);
                self.handle_client_message(&event);
            }
            xlib::KeyRelease => {
                debug!("key release");
                let mut event: xlib::XKeyEvent = From::from(e);
                self.handle_key_release(&mut event);
            }
            xlib::MotionNotify => {
                let mut event: xlib::XMotionEvent = From::from(e);
                debug!("button motion {}", event.window);
                self.handle_button_motion(&event);
            }
            xlib::ButtonRelease => {
                let mut event: xlib::XButtonEvent = From::from(e);
                debug!("button release {}", event.window);
            }
            xlib::ButtonPress => {
                let mut event: xlib::XButtonEvent = From::from(e);
                debug!("button press {}", event.window);
                self.handle_button_press(&event);
            }
            xlib::ConfigureNotify => {
                debug!("configure notify");
            }
            xlib::ConfigureRequest =>{
                let mut event: xlib::XConfigureRequestEvent = From::from(e);
                debug!("configure request {}", event.window);
                self.handle_configure_request(&event);
            }
            xlib::FocusIn => {
                let mut event: xlib::XFocusChangeEvent = From::from(e);
                debug!("focus in {}", event.window);
                self.handle_focus_in(&event);

            }
            xlib::FocusOut => {
                let mut event: xlib::XFocusChangeEvent = From::from(e);
                debug!("focus out {}", event.window);
            }
            xlib::EnterNotify => {
                let mut event: xlib::XCrossingEvent = From::from(e);
                debug!("enter window {}", event.window);
                self.handle_enter(&event);
            }
            xlib::PropertyNotify => {
                let mut event: xlib::XPropertyEvent = From::from(e);
                debug!("property notify {}", event.window);
                self.handle_property(&event);
            }
            _ => {
                debug!("unhandled event {}", t);
            }
        }
    }
    pub fn run(&mut self) {
        loop {
            //handle events here
            let mut e = libx::next_event(self.context);
            self.handle(e);
        }
    }

    pub fn init(&mut self) {
        let mask = 0x1A0034;
        let mask = xlib::SubstructureRedirectMask | xlib::SubstructureNotifyMask | xlib::ButtonPressMask;

        unsafe{
            xlib::XSetErrorHandler(Some(error_handler));
        }
        let left_ptr: u32 = 68;
        libx::define_cursor(self.context, self.context.root, left_ptr);

        libx::ungrab_button(self.context, 0, 0x8000, self.context.root);
        libx::select_input(self.context, self.context.root,
                           mask);

        for bind in self.config.bindsyms.keys() {
            let code = libx::keysym_to_keycode(self.context, bind.key);
            libx::grab_key(self.context, code, bind.mask, self.context.root);
        }
        libx::sync(self.context, 0);

        self.init_workspaces();
    }

    fn init_workspaces(&mut self) {
        self.workspaces.switch_workspace('1', self.context);
    }
}
<commit_msg>to pass tarvis compile<commit_after>extern crate libc;
extern crate x11;

use std::ptr;
use x11::xlib;
use x11::xlib::Window;
use super::super::libx;

use super::config::Config;
use super::Container;
use super::Workspaces;
use super::handler;

unsafe extern fn error_handler(display: *mut xlib::Display, event: *mut xlib::XErrorEvent) -> libc::c_int {
    // match event.error_code {
    //     xlib::BadAtom => {
    //         println!("bad atom");
    //     }
    //     _ => {}
    // }
    // x11::xmu::XmuSimpleErrorHandler(display, event);
    1
}

extern "C" {
    fn setlocale(category: i32, locale: *const i8) -> *mut i8;
}

fn load_resource(mut context: &mut libx::Context) {
    use std::mem;
    use std::ffi;
    let screen = context.screen_num;
    let root = context.root;
    let display = context.display;
    let mut values: xlib::XGCValues = unsafe{ mem::zeroed() };
    // let gc = libx::create_gc(self.context, self.id, 0, values);
    let gc = libx::default_gc(*context, screen);

    unsafe {
        let black = xlib::XBlackPixel(display, screen);
        let white = xlib::XWhitePixel(display, screen);

        xlib::XSetLineAttributes(display, gc, 5, 0, 0, 0);

        let cmap = xlib::XDefaultColormap(display, screen);
        let mut color: xlib::XColor = mem::zeroed();
        let name = ffi::CString::new("blue").unwrap().as_ptr();
        let r = xlib::XParseColor(display, cmap, name, &mut color);
        xlib::XAllocColor(display, cmap, &mut color);

        context.gc = gc;
        context.focus_bg = black;
        context.focus_fg = color.pixel;
        context.unfocus_bg = black;
        context.unfocus_fg = black;
        context.font_color = white;

        let s = ffi::CString::new("").unwrap().as_ptr();
        let p = setlocale(6, s);
        let res = xlib::XSupportsLocale();
        let res = xlib::XSetLocaleModifiers(s);

        let mut missing_charsets = ptr::null_mut();
        let mut num_missing_charsets: i32 = 0;
        let mut default_string = ptr::null_mut();
        // let name = "-misc-fixed-*-*-*-*-*-130-75-75-*-*-*-*";
        let name = "*";
        let fontbase = ffi::CString::new(name).unwrap().as_ptr();
        let fontset = xlib::XCreateFontSet(display,
                                           fontbase,
                                           &mut missing_charsets,
                                           &mut num_missing_charsets,
                                           &mut default_string);
        if num_missing_charsets > 0 {
            xlib::XFreeStringList(missing_charsets);
        }
        context.fontset = fontset;
    }
}

pub struct WindowManager {
    pub context: libx::Context,
    pub workspaces: Workspaces,
    config: Config
}

impl WindowManager {
    pub fn new() -> WindowManager {
	let res = libx::open_display(None);
        let mut context = match res {
            Some(c) => {
                c
            }
            None => {
                panic!("can't open display")
            }
        };

	context.screen_num  = libx::default_screen(context);
	context.root = libx::root_window(context, context.screen_num);
        load_resource(&mut context);

	let mut wm = WindowManager {
            context: context,
            config: Config::load(),
            workspaces: Workspaces::new(context)
        };
        wm
    }

    pub fn clean(&mut self) {
        libx::close_display(self.context);
    }

    pub fn handle_create(&mut self, event: &xlib::XCreateWindowEvent) {
        if event.override_redirect != 0 {
            return;
        }

        let attrs = libx::get_window_attributes(self.context, event.window);
        println!("{} attr {} {}", event.window, attrs.width, attrs.height);
        // get window property
        let n = libx::get_text_property(self.context, event.window, xlib::XA_WM_NAME);
        match n {
            Some(s) => {debug!("create window {} for {}", event.window, s);}
            None => {}
        }

        // let atoms = libx::get_wm_protocols(self.context, event.window);
        // for a in atoms.iter() {
        //     println!("atom {}", a);
        //     let name = libx::get_atom_name(self.context, *a);
        //     match name {
        //         Some(n) => println!("name {}", n),
        //         None => println!("name {}", a),
        //     };
        // }
    }

    pub fn handle_destroy(&mut self, event: &xlib::XDestroyWindowEvent) {
        self.workspaces.remove_window(event.window);
        if self.workspaces.get_focus().is_none() {
            self.workspaces.set_focus(self.context.root);
        }
    }

    pub fn handle_map_request(&mut self, event: &xlib::XMapRequestEvent) {

        // add app top-level window to workspace
        // let window = Window::new(self.context, event.window);
        let manage = Workspaces::can_manage(self.context, event.window);

        if manage {
            debug!("top level window");
            let mut container = Container::from_id(self.context, event.window);
            container.map();
            // container.focus();
            // change attributes before display
            let mask = 0x420010;
            let mask = xlib::EnterWindowMask | xlib::PropertyChangeMask;
            libx::select_input(self.context, container.raw_id(), mask);

            if self.config.titlebar_height > 0 {
                container.titlebar_height = self.config.titlebar_height;
            }
            self.workspaces.insert_window(container);
        }
        else {
            libx::map_window(self.context, event.window);
        }
    }

    pub fn handle_client_message(&mut self, event: &xlib::XClientMessageEvent) {
        println!("message type {}", event.message_type);
        let s = libx::get_atom_name(self.context, event.message_type);
        match s {
            Some(v) => println!("{}", &v),
            None => {}
        }

        match event.format {
            8 => {
                for i in 0..20 {
                    println!("{}", event.data.get_byte(i));
                }
            }
            16 => {
                for i in 0..10 {
                    println!("{}", event.data.get_short(i))
                }
            }
            32 => {
                for i in 0..5 {
                    let a = event.data.get_long(i);
                    if a != 0{
                        let s = libx::get_atom_name(self.context, a as xlib::Atom);
                        match s {
                            Some(v) => println!("{}", v),
                            None => {}
                        }
                    }
                }
            }
            _ => {}
        }
    }

    pub fn handle_button_motion(&mut self, event: &xlib::XMotionEvent) {
        let (window, _) = libx::get_input_focus(self.context);
        if window != event.window {
            self.workspaces.set_focus(event.window);
        }
    }

    pub fn handle_button_press(&mut self, event: &xlib::XButtonEvent) {
        let id = match self.workspaces.get_container(event.window) {
            Some((_,container)) => {
                let client = container.query_point(event.x, event.y);
                match client {
                    Some(c) => {
                        c.raw_id()
                    }
                    None => { container.raw_id() }
                }
            }
            None => { return }
        };
        self.workspaces.set_focus(id);
    }
    pub fn handle_key_release(&mut self, event: &xlib::XKeyEvent) {
        if event.state > 0 {
            let sym = libx::lookup_keysym(*event, 0);
            let b = handler::KeyBind {
                key: sym,
                mask: event.state,
            };
            debug!("key {} {}", event.state, sym);

            match self.config.bindsyms.get_mut(&b) {
                Some(handler) => {
                    handler.handle(&mut self.workspaces, self.context);
                }
                None => {
                    println!("no bind");
                }
            }
        }
    }

    pub fn handle_property(&mut self, event: &xlib::XPropertyEvent) {
        let usertime = libx::get_atom(self.context, "_NET_WM_USER_TIME");
        match event.atom {
            usertime => {
                self.workspaces.set_focus(event.window);
            }
        }
    }

    pub fn handle_configure_request(&mut self, event: &xlib::XConfigureRequestEvent) {
        let mut change = xlib::XWindowChanges {
            x: event.x,
            y: event.y,
            width: event.width,
            height: event.height,
            border_width: event.border_width,
            sibling: event.above,
            stack_mode: event.detail
        };
        debug!("config x: {}, y: {}, width: {}, height: {}",
               change.x, change.y, change.width, change.height);
        libx::configure_window(self.context, event.window, event.value_mask as u32, change);
    }

    pub fn handle_focus_in(&mut self, event: &xlib::XFocusChangeEvent) {
        self.workspaces.set_focus(event.window);
    }

    pub fn handle_enter(&mut self, event: &xlib::XCrossingEvent){
        if event.focus == 0 {
            self.workspaces.set_focus(event.window);
        }
    }

    pub fn handle(&mut self, e: xlib::XEvent) {
        let t = e.get_type();
        match t {
            xlib::CreateNotify => {
                let event: xlib::XCreateWindowEvent = From::from(e);
                debug!("create notify {}", event.window);
                self.handle_create(&event);
            }
            xlib::DestroyNotify => {
                let event: xlib::XDestroyWindowEvent = From::from(e);
                debug!("destroy notify {}", event.window);
                self.handle_destroy(&event);
            }
            xlib::MapNotify => {
                let event: xlib::XMapEvent = From::from(e);
                debug!("map notify {}", event.window);
            }
            xlib::UnmapNotify => {
                let event: xlib::XUnmapEvent = From::from(e);
                debug!("unmap notify {}", event.window);
            }
            xlib::MapRequest => {
                let event: xlib::XMapRequestEvent = From::from(e);
                debug!("map request {}", event.window);
                self.handle_map_request(&event);
            }
            xlib::ClientMessage => {
                debug!("client message");
                // let event = cast_event::<xlib::XClientMessageEvent>(&e);
                let event: xlib::XClientMessageEvent = From::from(e);
                self.handle_client_message(&event);
            }
            xlib::KeyRelease => {
                debug!("key release");
                let mut event: xlib::XKeyEvent = From::from(e);
                self.handle_key_release(&mut event);
            }
            xlib::MotionNotify => {
                let mut event: xlib::XMotionEvent = From::from(e);
                debug!("button motion {}", event.window);
                self.handle_button_motion(&event);
            }
            xlib::ButtonRelease => {
                let mut event: xlib::XButtonEvent = From::from(e);
                debug!("button release {}", event.window);
            }
            xlib::ButtonPress => {
                let mut event: xlib::XButtonEvent = From::from(e);
                debug!("button press {}", event.window);
                self.handle_button_press(&event);
            }
            xlib::ConfigureNotify => {
                debug!("configure notify");
            }
            xlib::ConfigureRequest =>{
                let mut event: xlib::XConfigureRequestEvent = From::from(e);
                debug!("configure request {}", event.window);
                self.handle_configure_request(&event);
            }
            xlib::FocusIn => {
                let mut event: xlib::XFocusChangeEvent = From::from(e);
                debug!("focus in {}", event.window);
                self.handle_focus_in(&event);

            }
            xlib::FocusOut => {
                let mut event: xlib::XFocusChangeEvent = From::from(e);
                debug!("focus out {}", event.window);
            }
            xlib::EnterNotify => {
                let mut event: xlib::XCrossingEvent = From::from(e);
                debug!("enter window {}", event.window);
                self.handle_enter(&event);
            }
            xlib::PropertyNotify => {
                let mut event: xlib::XPropertyEvent = From::from(e);
                debug!("property notify {}", event.window);
                self.handle_property(&event);
            }
            _ => {
                debug!("unhandled event {}", t);
            }
        }
    }
    pub fn run(&mut self) {
        loop {
            //handle events here
            let mut e = libx::next_event(self.context);
            self.handle(e);
        }
    }

    pub fn init(&mut self) {
        let mask = 0x1A0034;
        let mask = xlib::SubstructureRedirectMask | xlib::SubstructureNotifyMask | xlib::ButtonPressMask;

        unsafe{
            xlib::XSetErrorHandler(Some(error_handler));
        }
        let left_ptr: u32 = 68;
        libx::define_cursor(self.context, self.context.root, left_ptr);

        libx::ungrab_button(self.context, 0, 0x8000, self.context.root);
        libx::select_input(self.context, self.context.root,
                           mask);

        for bind in self.config.bindsyms.keys() {
            let code = libx::keysym_to_keycode(self.context, bind.key);
            libx::grab_key(self.context, code, bind.mask, self.context.root);
        }
        libx::sync(self.context, 0);

        self.init_workspaces();
    }

    fn init_workspaces(&mut self) {
        self.workspaces.switch_workspace('1', self.context);
    }
}
<|endoftext|>


<commit_before>use super::Vector;
use super::Vector3;

pub struct Vector3f {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}

impl Vector<f32> for Vector3f {
    fn add(&mut self, v: &Vector3f) -> &mut Vector3f {
        self.x += v.x;
        self.y += v.y;
        self.z += v.z;
        self
    }

    fn add_into(&self, v: &Vector3f, dest: &mut Vector3f) {
        dest.x = self.x + v.x;
        dest.y = self.y + v.y;
        dest.z = self.z + v.z;
    }

    fn angle(&self, v: &Vector3f) -> f32 {
        unimplemented!()
    }

    fn angle_cos(&self, v: &Vector3f) -> f32 {
        unimplemented!()
    }

    fn distance(&self, v: &Vector3f) -> f32 {
        self.distance_squared(v).sqrt()
    }

    fn distance_squared(&self, v: &Vector3f) -> f32 {
        let dx = self.x - v.x;
        let dy = self.y - v.y;
        let dz = self.z - v.z;
        (dx * dx) + (dy * dy) + (dz * dz)
    }

    fn dot(&self, v: &Vector3f) -> f32 {
        unimplemented!()
    }

    fn fma_scalar(&mut self, a: f32, b: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn fma_scalar_into(&self, a: f32, b: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn fma_vector(&mut self, a: &Vector3f, b: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn fma_vector_into(&self, a: &Vector3f, b: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn length(&self) -> f32 {
        unimplemented!()
    }

    fn length_squared(&self) -> f32 {
        unimplemented!()
    }

    fn lerp(&mut self, other: &Vector3f, t: f32) -> &mut Vector3f {
        unimplemented!()
    }

    fn lerp_into(&self, other: &Vector3f, t: f32, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn mul_scalar(&mut self, s: f32) -> &mut Vector3f {
        unimplemented!()
    }

    fn mul_scalar_into(&self, s: f32, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn mul_vector(&mut self, v: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn mul_vector_into(&self, v: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn negate(&mut self) -> &mut Vector3f {
        unimplemented!()
    }

    fn negate_into(&self, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn normalize(&mut self) -> &mut Vector3f {
        unimplemented!()
    }

    fn normalize_into(&self, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn set(&mut self, v: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn sub(&mut self, v: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn sub_into(&self, v: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn zero(&mut self) -> &mut Vector3f {
        unimplemented!()
    }
}

impl Vector3<f32> for Vector3f {
    fn new(x: f32, y: f32, z: f32) -> Vector3f {
        Vector3f {
            x: x,
            y: y,
            z: z,
        }
    }

    fn add_components(&mut self, x: f32, y: f32, z: f32) -> &mut Vector3f {
        unimplemented!()
    }

    fn add_components_into(&self, x: f32, y: f32, z: f32, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn cross(&mut self, v: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn cross_into(&self, v: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    use super::super::Vector;
    use super::super::Vector3;
    use super::Vector3f;

    use std;

    #[test]
    fn test_new() {
        let a = Vector3f::new(1f32, 2f32, 3f32);

        assert_eq!(a.x, 1f32);
        assert_eq!(a.y, 2f32);
        assert_eq!(a.z, 3f32);
    }

    #[test]
    fn test_add() {
        let mut a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(1f32, 2f32, 3f32);

        a.add(&b);

        assert_eq!(a.x, 2f32);
        assert_eq!(a.y, 4f32);
        assert_eq!(a.z, 6f32);
    }

    #[test]
    fn test_add_into() {
        let a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(1f32, 2f32, 3f32);
        let mut c = Vector3f::new(0f32, 0f32, 0f32);

        a.add_into(&b, &mut c);

        assert_eq!(c.x, 2f32);
        assert_eq!(c.y, 4f32);
        assert_eq!(c.z, 6f32);
    }

    #[test]
    fn test_distance() {
        let a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(-1f32, 2f32, 3f32);

        let target_distance = 2f32;
        let distance = a.distance(&b);

        assert_eq!(target_distance, distance);
    }

    #[test]
    fn test_distance_squared() {
        let a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(-1f32, 2f32, 3f32);

        let target_distance_sq = 4f32; // target distance is 2
        let distance_sq = a.distance_squared(&b);

        assert_eq!(target_distance_sq, distance_sq);
    }
}
<commit_msg>add dot impl<commit_after>use super::Vector;
use super::Vector3;

pub struct Vector3f {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}

impl Vector<f32> for Vector3f {
    fn add(&mut self, v: &Vector3f) -> &mut Vector3f {
        self.x += v.x;
        self.y += v.y;
        self.z += v.z;
        self
    }

    fn add_into(&self, v: &Vector3f, dest: &mut Vector3f) {
        dest.x = self.x + v.x;
        dest.y = self.y + v.y;
        dest.z = self.z + v.z;
    }

    fn angle(&self, v: &Vector3f) -> f32 {
        unimplemented!()
    }

    fn angle_cos(&self, v: &Vector3f) -> f32 {
        unimplemented!()
    }

    fn distance(&self, v: &Vector3f) -> f32 {
        self.distance_squared(v).sqrt()
    }

    fn distance_squared(&self, v: &Vector3f) -> f32 {
        let dx = self.x - v.x;
        let dy = self.y - v.y;
        let dz = self.z - v.z;
        (dx * dx) + (dy * dy) + (dz * dz)
    }

    fn dot(&self, v: &Vector3f) -> f32 {
        (self.x * v.x) + (self.y * v.y) + (self.z * v.z)
    }

    fn fma_scalar(&mut self, a: f32, b: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn fma_scalar_into(&self, a: f32, b: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn fma_vector(&mut self, a: &Vector3f, b: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn fma_vector_into(&self, a: &Vector3f, b: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn length(&self) -> f32 {
        unimplemented!()
    }

    fn length_squared(&self) -> f32 {
        unimplemented!()
    }

    fn lerp(&mut self, other: &Vector3f, t: f32) -> &mut Vector3f {
        unimplemented!()
    }

    fn lerp_into(&self, other: &Vector3f, t: f32, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn mul_scalar(&mut self, s: f32) -> &mut Vector3f {
        unimplemented!()
    }

    fn mul_scalar_into(&self, s: f32, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn mul_vector(&mut self, v: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn mul_vector_into(&self, v: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn negate(&mut self) -> &mut Vector3f {
        unimplemented!()
    }

    fn negate_into(&self, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn normalize(&mut self) -> &mut Vector3f {
        unimplemented!()
    }

    fn normalize_into(&self, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn set(&mut self, v: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn sub(&mut self, v: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn sub_into(&self, v: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn zero(&mut self) -> &mut Vector3f {
        unimplemented!()
    }
}

impl Vector3<f32> for Vector3f {
    fn new(x: f32, y: f32, z: f32) -> Vector3f {
        Vector3f {
            x: x,
            y: y,
            z: z,
        }
    }

    fn add_components(&mut self, x: f32, y: f32, z: f32) -> &mut Vector3f {
        unimplemented!()
    }

    fn add_components_into(&self, x: f32, y: f32, z: f32, dest: &mut Vector3f) {
        unimplemented!()
    }

    fn cross(&mut self, v: &Vector3f) -> &mut Vector3f {
        unimplemented!()
    }

    fn cross_into(&self, v: &Vector3f, dest: &mut Vector3f) {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    use super::super::Vector;
    use super::super::Vector3;
    use super::Vector3f;

    use std;

    #[test]
    fn test_new() {
        let a = Vector3f::new(1f32, 2f32, 3f32);

        assert_eq!(a.x, 1f32);
        assert_eq!(a.y, 2f32);
        assert_eq!(a.z, 3f32);
    }

    #[test]
    fn test_add() {
        let mut a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(1f32, 2f32, 3f32);

        a.add(&b);

        assert_eq!(a.x, 2f32);
        assert_eq!(a.y, 4f32);
        assert_eq!(a.z, 6f32);
    }

    #[test]
    fn test_add_into() {
        let a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(1f32, 2f32, 3f32);
        let mut c = Vector3f::new(0f32, 0f32, 0f32);

        a.add_into(&b, &mut c);

        assert_eq!(c.x, 2f32);
        assert_eq!(c.y, 4f32);
        assert_eq!(c.z, 6f32);
    }

    #[test]
    fn test_distance() {
        let a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(-1f32, 2f32, 3f32);

        let target_distance = 2f32;
        let distance = a.distance(&b);

        assert_eq!(target_distance, distance);
    }

    #[test]
    fn test_distance_squared() {
        let a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(-1f32, 2f32, 3f32);

        let target_distance_sq = 4f32; // target distance is 2
        let distance_sq = a.distance_squared(&b);

        assert_eq!(target_distance_sq, distance_sq);
    }

    #[test]
    fn test_dot() {
        let a = Vector3f::new(1f32, 2f32, 3f32);
        let b = Vector3f::new(1f32, 2f32, 3f32);

        let target_dot = 14f32;
        let dot = a.dot(&b);

        assert_eq!(target_dot, dot);
    }
}
<|endoftext|>


<commit_before>//public mods
pub mod address_mode;
pub mod opcode_class;

//private mods
use std::clone::Clone;

// hoisted interfaces

#[derive(Default)]
pub struct OpcodeDebugInfo {
    pub opcode: u8,
    pub name: String,
    pub address_mode_name: String,
    pub notes: String,
}

#[derive(Default)]
pub struct OpcodeExecInfo {
    pub opcode: u8,
    pub opcode_class:opcode_class::OpcodeClass,
    pub address_mode:address_mode::AddressMode,
    pub len: u8,
    pub cycles: u8,
    pub page_cycles: u8,
}

<commit_msg>added Clone trait implementation<commit_after>//public mods
pub mod address_mode;
pub mod opcode_class;

//private mods
use std::clone::Clone;

// hoisted interfaces

#[derive(Default)]
pub struct OpcodeDebugInfo {
    pub opcode: u8,
    pub name: String,
    pub address_mode_name: String,
    pub notes: String,
}

#[derive(Default)]
pub struct OpcodeExecInfo {
    pub opcode: u8,
    pub opcode_class:opcode_class::OpcodeClass,
    pub address_mode:address_mode::AddressMode,
    pub len: u8,
    pub cycles: u8,
    pub page_cycles: u8,
}

impl Clone for OpcodeExecInfo {
    fn clone(&self) -> OpcodeExecInfo {
        OpcodeExecInfo {
            opcode :self.opcode,
            opcode_class : self.opcode_class.clone(),
            address_mode : self.address_mode.clone(),
            len : self.len,
            cycles : self.cycles,
            page_cycles : self.page_cycles,
        }
    }
}

<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Example of explicit panic!<commit_after>fn main() {
    panic!("crash and burn");
}
<|endoftext|>


<commit_before>#![allow(dead_code, unused_imports)]

extern crate fitsio_sys;
extern crate libc;

use std::ptr;
use std::ffi;

mod stringutils;

/// Error type
#[derive(Debug, PartialEq, Eq)]
pub struct FitsError {
    status: i32,
    message: String,
}

pub type Result<T> = std::result::Result<T, FitsError>;

pub struct FitsFile {
    fptr: *mut fitsio_sys::fitsfile,
    pub filename: String,
}

impl FitsFile {
    fn create(path: &str) -> Result<Self> {
        let mut fptr = ptr::null_mut();
        let mut status = 0;
        let c_filename = ffi::CString::new(path).unwrap();

        unsafe {
            fitsio_sys::ffinit(&mut fptr as *mut *mut fitsio_sys::fitsfile,
                   c_filename.as_ptr(),
                   &mut status);
        }

        match status {
            0 => {
                Ok(FitsFile {
                    fptr: fptr,
                    filename: path.to_string(),
                })
            }
            status => {
                Err(FitsError {
                    status: status,
                    message: stringutils::status_to_string(status).unwrap(),
                })
            }
        }
    }
}

#[cfg(test)]
mod test {
    extern crate tempdir;
    use super::FitsFile;

    #[test]
    fn creating_a_new_file() {
        let tdir = tempdir::TempDir::new("fitsio-").unwrap();
        let tdir_path = tdir.path();
        let filename = tdir_path.join("test.fits");
        assert!(!filename.exists());

        match FitsFile::create(filename.to_str().unwrap()) {
            Ok(_) => assert!(filename.exists()),
            Err(e) => panic!("Error: {:?}", e),
        }
    }

}
<commit_msg>Add drop impl<commit_after>#![allow(dead_code, unused_imports)]

extern crate fitsio_sys;
extern crate libc;

use std::ptr;
use std::ffi;

mod stringutils;

/// Error type
#[derive(Debug, PartialEq, Eq)]
pub struct FitsError {
    status: i32,
    message: String,
}

pub type Result<T> = std::result::Result<T, FitsError>;

pub struct FitsFile {
    fptr: *mut fitsio_sys::fitsfile,
    pub filename: String,
}

impl FitsFile {
    fn create(path: &str) -> Result<Self> {
        let mut fptr = ptr::null_mut();
        let mut status = 0;
        let c_filename = ffi::CString::new(path).unwrap();

        unsafe {
            fitsio_sys::ffinit(&mut fptr as *mut *mut fitsio_sys::fitsfile,
                   c_filename.as_ptr(),
                   &mut status);
        }

        match status {
            0 => {
                Ok(FitsFile {
                    fptr: fptr,
                    filename: path.to_string(),
                })
            }
            status => {
                Err(FitsError {
                    status: status,
                    message: stringutils::status_to_string(status).unwrap(),
                })
            }
        }
    }
}

impl Drop for FitsFile {
    fn drop(&mut self) {
        let mut status = 0;
        unsafe {
            fitsio_sys::ffclos(self.fptr, &mut status);
        }
    }
}

#[cfg(test)]
mod test {
    extern crate tempdir;
    use super::FitsFile;

    #[test]
    fn creating_a_new_file() {
        let tdir = tempdir::TempDir::new("fitsio-").unwrap();
        let tdir_path = tdir.path();
        let filename = tdir_path.join("test.fits");
        assert!(!filename.exists());

        match FitsFile::create(filename.to_str().unwrap()) {
            Ok(_) => assert!(filename.exists()),
            Err(e) => panic!("Error: {:?}", e),
        }
    }

}
<|endoftext|>