<commit_before>use screen::*;
use piston_window;

pub struct BattleScreen {
    // TODO: FIXME.
    _fixme: i32,
//    player: object::Object,
}

impl BattleScreen {
    pub fn new() -> BattleScreen {
        BattleScreen{ _fixme: 42 }
    }
}

impl Screen for BattleScreen {
    fn on_input(&mut self, input: &piston_window::Input) -> InputResults {
        use piston_window::{Input, Button, Key};

        let result = Vec::new();

        match input {
            &Input::Press(button) => {
                match button {
//                    Button::Keyboard(Key::Up) => { self.up = true; }
//                    Button::Keyboard(Key::Down) => { self.down = true; }
//                    Button::Keyboard(Key::Left) => { self.left = true; }
//                    Button::Keyboard(Key::Right) => { self.right = true; }
                    _ => {}
                }
            }
            &Input::Release(button) => {
                match button {
//                    Button::Keyboard(Key::Up) => { self.up = false; }
//                    Button::Keyboard(Key::Down) => { self.down = false; }
//                    Button::Keyboard(Key::Left) => { self.left = false; }
//                    Button::Keyboard(Key::Right) => { self.right = false; }
                    _ => {}
                }
            }
            _ => {}
        }

        result
    }

    fn on_draw(&mut self, args: &piston_window::RenderArgs, window: &piston_window::PistonWindow) {
    }

    fn on_update(&mut self, args: &piston_window::UpdateArgs) {
    }
}
<commit_msg>Battle screen - on_draw (stub)<commit_after>use screen::*;
use piston_window;

pub struct BattleScreen {
    // TODO: FIXME.
    _fixme: i32,
//    player: object::Object,
}

impl BattleScreen {
    pub fn new() -> BattleScreen {
        BattleScreen{ _fixme: 42 }
    }
}

impl Screen for BattleScreen {
    fn on_input(&mut self, input: &piston_window::Input) -> InputResults {
        use piston_window::{Input, Button, Key};

        let result = Vec::new();

        match input {
            &Input::Press(button) => {
                match button {
//                    Button::Keyboard(Key::Up) => { self.up = true; }
//                    Button::Keyboard(Key::Down) => { self.down = true; }
//                    Button::Keyboard(Key::Left) => { self.left = true; }
//                    Button::Keyboard(Key::Right) => { self.right = true; }
                    _ => {}
                }
            }
            &Input::Release(button) => {
                match button {
//                    Button::Keyboard(Key::Up) => { self.up = false; }
//                    Button::Keyboard(Key::Down) => { self.down = false; }
//                    Button::Keyboard(Key::Left) => { self.left = false; }
//                    Button::Keyboard(Key::Right) => { self.right = false; }
                    _ => {}
                }
            }
            _ => {}
        }

        result
    }

    fn on_draw(&mut self, args: &piston_window::RenderArgs, window: &piston_window::PistonWindow) {
	window.draw_2d(|context, graphics| {
	    piston_window::clear([1., 0., 0., 1.0], graphics);
	}
    }

    fn on_update(&mut self, args: &piston_window::UpdateArgs) {
    }
}
<|endoftext|>


<commit_before>//! # TreeView Sample
//!
//! This sample demonstrates how to create a TreeView with either a ListStore or TreeStore.

extern crate glib;
extern crate gtk;
extern crate gdk_pixbuf;

use gtk::prelude::*;
use gdk_pixbuf::Pixbuf;

fn append_text_column(tree: &gtk::TreeView) {
    let column = gtk::TreeViewColumn::new();
    let cell = gtk::CellRendererText::new();

    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    tree.append_column(&column);
}

fn main() {
    if gtk::init().is_err() {
        println!("Failed to initialize GTK.");
        return;
    }

    let window = gtk::Window::new(gtk::WindowType::Toplevel);

    window.set_title("TreeView Sample");
    window.set_position(gtk::WindowPosition::Center);

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(false)
    });

    // left pane

    let left_tree = gtk::TreeView::new();
    let column_types = [String::static_type()];
    let left_store = gtk::ListStore::new(&column_types);

    left_tree.set_model(Some(&left_store));
    left_tree.set_headers_visible(false);
    append_text_column(&left_tree);

    // print out when a row is selected

    let left_selection = left_tree.get_selection().unwrap();
    left_selection.connect_changed(|tree_selection| {
        let (left_model, iter) = tree_selection.get_selected().unwrap();
        println!("selected row {}", left_model.get_path(&iter));
    });

    for _ in 0..10 {
        let iter = left_store.append();
        left_store.set_value(&iter, 0, &"I'm in a list".to_value());

        // select this row as a test
        //
        left_selection.select_path(&left_store.get_path(&iter));
    }

    // middle pane

    let middle_tree = gtk::TreeView::new();
    let column_types = [String::static_type()];
    let middle_store = gtk::TreeStore::new(&column_types);

    middle_tree.set_model(Some(&middle_store));
    middle_tree.set_headers_visible(false);
    append_text_column(&middle_tree);

    for i in 0..10 {
        let iter = middle_store.append(None);
        middle_store.set_value(&iter, 0, &format!("Hello {}", i).to_value());

        for _ in 0..i {
            let child_iter = middle_store.append(Some(&iter));
            middle_store.set_value(&child_iter, 0, &"I'm a child node".to_value());
        }
    }

    // right pane
    let right_tree = gtk::TreeView::new();
    let right_column_types = [Pixbuf::static_type(), String::static_type()];
    let right_store = gtk::TreeStore::new(&right_column_types);
    let renderer = gtk::CellRendererPixbuf::new();
    let col = gtk::TreeViewColumn::new();

    col.set_title("Picture");
    col.pack_start(&renderer, false);

    col.add_attribute(&renderer, "pixbuf", 0);

    let renderer2 = gtk::CellRendererText::new();
    col.pack_start(&renderer2, true);
    col.add_attribute(&renderer2, "text", 1);
    let image = match Pixbuf::new_from_file("./resources/eye.png") {
        Ok(i) => i,
        Err(e) => {
            println!("Error while creating image: {}", e);
            if e.kind() == Some(glib::FileError::Noent) {
                println!("Relaunch this example from the same level as the `resources` folder");
            }
            return;
        }
    };

    right_tree.append_column(&col);
    right_tree.set_model(Some(&right_store));
    right_tree.set_headers_visible(true);

    for _ in 0..10 {
        let iter = right_store.append(None);
        right_store.set(&iter, &[0, 1], &[&image, &"I'm a child node with an image"]);
    }

    // display the panes

    let split_pane = gtk::Box::new(gtk::Orientation::Horizontal, 10);

    split_pane.set_size_request(-1, -1);
    split_pane.add(&left_tree);
    split_pane.add(&middle_tree);
    split_pane.add(&right_tree);

    window.add(&split_pane);
    window.show_all();
    gtk::main();
}
<commit_msg>Use insert_with_values instead of append&set<commit_after>//! # TreeView Sample
//!
//! This sample demonstrates how to create a TreeView with either a ListStore or TreeStore.

extern crate glib;
extern crate gtk;
extern crate gdk_pixbuf;

use gtk::prelude::*;
use gdk_pixbuf::Pixbuf;

fn append_text_column(tree: &gtk::TreeView) {
    let column = gtk::TreeViewColumn::new();
    let cell = gtk::CellRendererText::new();

    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    tree.append_column(&column);
}

fn main() {
    if gtk::init().is_err() {
        println!("Failed to initialize GTK.");
        return;
    }

    let window = gtk::Window::new(gtk::WindowType::Toplevel);

    window.set_title("TreeView Sample");
    window.set_position(gtk::WindowPosition::Center);

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(false)
    });

    // left pane

    let left_tree = gtk::TreeView::new();
    let column_types = [String::static_type()];
    let left_store = gtk::ListStore::new(&column_types);

    left_tree.set_model(Some(&left_store));
    left_tree.set_headers_visible(false);
    append_text_column(&left_tree);

    // print out when a row is selected

    let left_selection = left_tree.get_selection().unwrap();
    left_selection.connect_changed(|tree_selection| {
        let (left_model, iter) = tree_selection.get_selected().unwrap();
        println!("selected row {}", left_model.get_path(&iter));
    });

    for _ in 0..10 {
        left_store.insert_with_values(None, &[0], &[&"I'm in a list"]);
    }

    // middle pane

    let middle_tree = gtk::TreeView::new();
    let column_types = [String::static_type()];
    let middle_store = gtk::TreeStore::new(&column_types);

    middle_tree.set_model(Some(&middle_store));
    middle_tree.set_headers_visible(false);
    append_text_column(&middle_tree);

    for i in 0..10 {
        // insert_with_values takes two slices: column indices and ToValue
        // trait objects. ToValue is implemented for strings, numeric types,
        // bool and Object descendants
        let iter = middle_store.insert_with_values(None, None, &[0], &[&format!("Hello {}", i)]);

        for _ in 0..i {
            middle_store.insert_with_values(Some(&iter), None, &[0], &[&"I'm a child node"]);
        }
    }

    // right pane
    let right_tree = gtk::TreeView::new();
    let right_column_types = [Pixbuf::static_type(), String::static_type()];
    let right_store = gtk::TreeStore::new(&right_column_types);
    let renderer = gtk::CellRendererPixbuf::new();
    let col = gtk::TreeViewColumn::new();

    col.set_title("Picture");
    col.pack_start(&renderer, false);

    col.add_attribute(&renderer, "pixbuf", 0);

    let renderer2 = gtk::CellRendererText::new();
    col.pack_start(&renderer2, true);
    col.add_attribute(&renderer2, "text", 1);
    let image = match Pixbuf::new_from_file("./resources/eye.png") {
        Ok(i) => i,
        Err(e) => {
            println!("Error while creating image: {}", e);
            if e.kind() == Some(glib::FileError::Noent) {
                println!("Relaunch this example from the same level as the `resources` folder");
            }
            return;
        }
    };

    right_tree.append_column(&col);
    right_tree.set_model(Some(&right_store));
    right_tree.set_headers_visible(true);

    for _ in 0..10 {
        right_store.insert_with_values(None, None, &[0, 1],
                                       &[&image, &"I'm a child node with an image"]);
    }

    // display the panes

    let split_pane = gtk::Box::new(gtk::Orientation::Horizontal, 10);

    split_pane.set_size_request(-1, -1);
    split_pane.add(&left_tree);
    split_pane.add(&middle_tree);
    split_pane.add(&right_tree);

    window.add(&split_pane);
    window.show_all();
    gtk::main();
}
<|endoftext|>


<commit_before>extern crate itertools;
extern crate rand;

use self::itertools::Itertools;

use self::rand::Rng;

use super::train;
use super::train::Train;
use super::error::Error;
use super::common::{Node, Value};
use super::mutator::{Arc, Mutator};
use super::network::NetworkBuf;
use super::id_generator::IdGenerator;

pub struct Conf<'r, RngT: 'r + Rng> {
    pub train_conf: &'r train::Conf<'r>,
    pub rng: &'r mut RngT,
    pub node_id: &'r mut IdGenerator,
    pub population_size: usize,
    pub error: Value,
    pub iterations_count: usize,
}

pub trait Evolve {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self;
}

impl Evolve for NetworkBuf {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self {
        Mutator::from_network(&self.as_network()).evolve(conf).as_network_buf()
    }
}

impl Evolve for Mutator {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self {
        Evolution::new(conf, self).perform()
    }
}

trait MutatorRandom {
    fn random_node<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Node;
    fn random_arc<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Arc;
}

impl MutatorRandom for Mutator {
    fn random_node<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Node {
        let nth = rng.gen_range(0, self.nodes().len());
        *self.nodes().nth(nth).unwrap()
    }

    fn random_arc<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Arc {
        let nth = rng.gen_range(0, self.arcs().len());
        self.arcs().nth(nth).unwrap().clone()
    }
}

struct Evolution<'c, 'f, RngT: 'c + Rng> {
    conf: &'c mut Conf<'c, RngT>,
    mutator: &'f Mutator,
    iterations_count: usize,
}

impl<'c, 'f, RngT: 'c + Rng> Evolution<'c, 'f, RngT> {
    pub fn new(conf: &'c mut Conf<'c, RngT>, mutator: &'f Mutator) -> Self {
        assert!(conf.population_size > 1);
        assert!(conf.population_size % 2 == 0);
        Evolution {conf: conf, mutator: mutator, iterations_count: 0}
    }

    pub fn perform(&mut self) -> Mutator {
        let population = (0..self.conf.population_size)
            .map(|_| self.mutator.clone()).collect::<Vec<_>>();
        let evolved = self.evolve(population);
        self.select_one(evolved)
    }

    fn evolve(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        let mut mutated = self.mutate(population);
        while !self.terminate(&mutated) {
            let propagated = self.propagate(mutated);
            let selected = self.select(propagated);
            mutated = self.mutate(selected);
            self.iterations_count += 1;
        }
        mutated
    }

    fn mutate(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        let ref mut node_id = self.conf.node_id;
        let ref mut rng = self.conf.rng;
        let ref train_conf = self.conf.train_conf;
        population.into_iter()
            .map(|mut x| {
                for _ in 0..3 {
                    match rng.gen_range(0, 3) {
                        0 => {
                            let arc = x.random_arc(rng);
                            x.split(node_id, &arc);
                        },
                        1 => {
                            let src = x.random_node(rng);
                            let dst = x.random_node(rng);
                            x.add_arc(src, dst, 0.1);
                        },
                        2 => {
                            let arc = x.random_arc(rng);
                            x.rm_arc(&arc);
                        },
                        _ => (),
                    }
                }
                x
            })
            .map(|x| {
                let mut network_buf = x.as_network_buf();
                network_buf.as_network_mut().train(train_conf);
                Mutator::from_network(&network_buf.as_network())
            })
            .collect()
    }

    fn terminate(&self, population: &Vec<Mutator>) -> bool {
        self.iterations_count >= self.conf.iterations_count
        || population.iter()
            .map(|x| x.as_network_buf().as_network().error(self.conf.train_conf.error_conf))
            .filter(|&x| x <= self.conf.error)
            .count() > 0
    }

    fn propagate(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        let mut new = {
            let mut a = population.iter().collect::<Vec<_>>();
            let mut b = population.iter().collect::<Vec<_>>();
            self.conf.rng.shuffle(&mut a[..]);
            self.conf.rng.shuffle(&mut b[..]);
            a.iter().zip(b.iter()).map(|(l, r)| l.union(r)).collect::<Vec<_>>()
        };
        new.extend(population.into_iter());
        new
    }

    fn select(&self, population: Vec<Mutator>) -> Vec<Mutator> {
        population.into_iter()
            .map(|x| (x.as_network_buf().as_network().error(self.conf.train_conf.error_conf), x))
            .sorted_by(|l, r| l.0.partial_cmp(&r.0).unwrap())
            .into_iter()
            .take(self.conf.population_size)
            .map(|x| x.1)
            .collect()
    }

    fn select_one(&self, population: Vec<Mutator>) -> Mutator {
        population.into_iter()
            .map(|x| (x.as_network_buf().as_network().error(self.conf.train_conf.error_conf), x))
            .sorted_by(|l, r| l.0.partial_cmp(&r.0).unwrap())
            .into_iter()
            .nth(0)
            .unwrap().1
    }
}
<commit_msg>Add evolve test<commit_after>extern crate itertools;
extern crate rand;

use self::itertools::Itertools;

use self::rand::Rng;

use super::train;
use super::train::Train;
use super::error::Error;
use super::common::{Node, Value};
use super::mutator::{Arc, Mutator};
use super::network::NetworkBuf;
use super::id_generator::IdGenerator;

pub struct Conf<'r, RngT: 'r + Rng> {
    pub train_conf: &'r train::Conf<'r>,
    pub rng: &'r mut RngT,
    pub node_id: &'r mut IdGenerator,
    pub population_size: usize,
    pub error: Value,
    pub iterations_count: usize,
}

pub trait Evolve {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self;
}

impl Evolve for NetworkBuf {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self {
        Mutator::from_network(&self.as_network()).evolve(conf).as_network_buf()
    }
}

impl Evolve for Mutator {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self {
        Evolution::new(conf, self).perform()
    }
}

trait MutatorRandom {
    fn random_node<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Node;
    fn random_arc<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Arc;
}

impl MutatorRandom for Mutator {
    fn random_node<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Node {
        let nth = rng.gen_range(0, self.nodes().len());
        *self.nodes().nth(nth).unwrap()
    }

    fn random_arc<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Arc {
        let nth = rng.gen_range(0, self.arcs().len());
        self.arcs().nth(nth).unwrap().clone()
    }
}

struct Evolution<'c, 'f, RngT: 'c + Rng> {
    conf: &'c mut Conf<'c, RngT>,
    mutator: &'f Mutator,
    iterations_count: usize,
}

impl<'c, 'f, RngT: 'c + Rng> Evolution<'c, 'f, RngT> {
    pub fn new(conf: &'c mut Conf<'c, RngT>, mutator: &'f Mutator) -> Self {
        assert!(conf.population_size > 1);
        assert!(conf.population_size % 2 == 0);
        Evolution {conf: conf, mutator: mutator, iterations_count: 0}
    }

    pub fn perform(&mut self) -> Mutator {
        if !self.begin() {
            return self.mutator.clone();
        }
        let population = (0..self.conf.population_size)
            .map(|_| self.mutator.clone()).collect::<Vec<_>>();
        let evolved = self.evolve(population);
        self.select_one(evolved)
    }

    fn evolve(&mut self, mut population: Vec<Mutator>) -> Vec<Mutator> {
        loop {
            let mutated = self.mutate(population);
            self.iterations_count += 1;
            if self.terminate(&mutated[..]) {
                return mutated;
            }
            let propagated = self.propagate(mutated);
            population = self.select(propagated);
        }
    }

    fn mutate(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        let ref mut node_id = self.conf.node_id;
        let ref mut rng = self.conf.rng;
        let ref train_conf = self.conf.train_conf;
        population.into_iter()
            .map(|mut x| {
                for _ in 0..3 {
                    match rng.gen_range(0, 3) {
                        0 => {
                            let arc = x.random_arc(rng);
                            x.split(node_id, &arc);
                        },
                        1 => {
                            let src = x.random_node(rng);
                            let dst = x.random_node(rng);
                            x.add_arc(src, dst, 0.1);
                        },
                        2 => {
                            let arc = x.random_arc(rng);
                            x.rm_arc(&arc);
                        },
                        _ => (),
                    }
                }
                x
            })
            .map(|x| {
                let mut network_buf = x.as_network_buf();
                network_buf.as_network_mut().train(train_conf);
                Mutator::from_network(&network_buf.as_network())
            })
            .collect()
    }

    fn begin(&self) -> bool {
        self.iterations_count < self.conf.iterations_count
        && self.mutator.as_network_buf().as_network().error(self.conf.train_conf.error_conf)
           > self.conf.error
    }

    fn terminate(&self, population: &[Mutator]) -> bool {
        self.iterations_count >= self.conf.iterations_count
        || population.iter()
            .map(|x| x.as_network_buf().as_network().error(self.conf.train_conf.error_conf))
            .filter(|&x| x <= self.conf.error)
            .count() > 0
    }

    fn propagate(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        let mut new = {
            let mut a = population.iter().collect::<Vec<_>>();
            let mut b = population.iter().collect::<Vec<_>>();
            self.conf.rng.shuffle(&mut a[..]);
            self.conf.rng.shuffle(&mut b[..]);
            a.iter().zip(b.iter()).map(|(l, r)| l.union(r)).collect::<Vec<_>>()
        };
        new.extend(population.into_iter());
        new
    }

    fn select(&self, population: Vec<Mutator>) -> Vec<Mutator> {
        population.into_iter()
            .map(|x| (x.as_network_buf().as_network().error(self.conf.train_conf.error_conf), x))
            .sorted_by(|l, r| l.0.partial_cmp(&r.0).unwrap())
            .into_iter()
            .take(self.conf.population_size)
            .map(|x| x.1)
            .collect()
    }

    fn select_one(&self, population: Vec<Mutator>) -> Mutator {
        population.into_iter()
            .map(|x| (x.as_network_buf().as_network().error(self.conf.train_conf.error_conf), x))
            .sorted_by(|l, r| l.0.partial_cmp(&r.0).unwrap())
            .into_iter()
            .nth(0)
            .unwrap().1
    }
}

#[test]
fn test_evolve_should_succeed() {
    extern crate rand;
    use std::collections::{BTreeSet, HashMap, HashSet};
    use self::rand::{XorShiftRng, SeedableRng};
    use neural_network::apply::{Conf as ApplyConf};
    use neural_network::error::{Conf as ErrorConf, Sample};
    use neural_network::train::{Conf as TrainConf};
    use neural_network::matrix::Matrix;
    use neural_network::network::Network;
    let mut weights_values = [
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.0, 0.0,
    ];
    let inputs = [0, 1, 2].iter().cloned().collect::<BTreeSet<usize>>();
    let outputs = [3, 4].iter().cloned().collect::<HashSet<usize>>();
    let weights = Matrix::new(5, &mut weights_values);
    let nodes = (0..5).map(|x| (x, Node(x))).collect::<HashMap<usize, Node>>();
    let network = Network {
        inputs: &inputs,
        outputs: &outputs,
        weights: weights,
        nodes: &nodes
    };
    let mutator = Mutator::from_network(&network);
    let apply_conf = ApplyConf {
        group_size: 1000,
        threshold: 1e-4,
    };
    let samples = [
        Sample {input: &[0.6, 0.7, 0.8], output: &[0.5, 0.4]},
        Sample {input: &[0.3, 0.4, 0.5], output: &[0.3, 0.4]},
    ];
    let error_conf = ErrorConf {
        apply_conf: &apply_conf,
        samples: &samples,
    };
    let train_conf = TrainConf {
        error_conf: &error_conf,
    };
    let mut rng = XorShiftRng::new_unseeded();
    rng.reseed([1, 1, 1, 1]);
    let mut node_id = IdGenerator::new(0);
    let mut conf = Conf {
        train_conf: &train_conf,
        rng: &mut rng,
        node_id: &mut node_id,
        population_size: 2,
        error: 1e-3,
        iterations_count: 2,
    };
    let evolved = mutator.evolve(&mut conf);
    let evolved_network_buf = evolved.as_network_buf();
    let evolved_network = evolved_network_buf.as_network();
    let result: &[f64] = evolved_network.weights.values();
    assert_eq!(result, &[
        0.0, 0.0, 0.0, 0.0, 0.49028704348647656,
        0.0, 0.0, 0.0, 0.4949691958362526, 0.28046393072142795,
        0.0, 0.0, 0.0, 0.37300793037516183, 0.32337664807119676,
        0.000049464489018874805, 0.00008103643147741657, 0.00016638669416522351, 0.001251673322024201, 0.00008411499868450062,
        0.0013426293689717068, 0.0014433214233762046, 0.001525153631654263, 0.5282397259358337, 0.001543939790084261,
    ] as &[f64]);
}
<|endoftext|>


<commit_before>//! Protocol messages
//!
//! All protocol messages are serialized by serde according to the bincode data format. For
//! transmission on the wire, `tokio_io::codec::length_delimited` is used to prepend protocol
//! messages by an additional length header, thereby creating frames. It is crucial to
//!
//! The main type `Message` and the types in its fields are dump containers, which are not
//! responsible for any protocol logic (except for syntactic validation including validation of
//! `PublicKey` and `SecretKey` fields). Consequently, all fields of `Message` and all fields of
//! its contained types such as `Header` and `Payload` are public.

use secp256k1::key::{PublicKey, SecretKey};
use secp256k1::Signature;
use ::{SessionId, PeerIndex, SymmetricKey, SequenceNum};

/// A protocol message
///
/// Protocol messages consist of a header and a payload.
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct Message {
    pub header: Header,
    pub payload: Payload,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct Header {
    pub session_id: SessionId,
    pub peer_index: PeerIndex,
    pub sequence_num: SequenceNum,
    pub signature: Signature,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) enum Payload {
    KeyExchange(KeyExchange),
    DcExponential(DcExponential),
    DcXor(DcXor),
    DcAddSecp256k1Scalar(DcAddSecp256k1Scalar),
    Blame(Blame),
    Confirm(Confirm),
    Reveal(Reveal),
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct KeyExchange {
    pub ke_pk: PublicKey,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct DcExponential {
    pub commitment: [u8; 32],
    pub dc_exp: Vec<[u8; 16]>,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct DcXor {
    pub ok: bool,
    pub dc_xor: Vec<Vec<u8>>,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct DcAddSecp256k1Scalar {
    // FIXME
    pub dc_add_secp256k1_scalar: (),
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct Blame {
    pub ke_sk: SecretKey,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct Confirm {
    pub data: Vec<u8>,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct Reveal {
    pub keys: Vec<(PeerIndex, SymmetricKey)>,
}

#[cfg(test)]
mod tests {
    use super::*;
    use secp256k1::key::SecretKey;

    use std::io::Cursor;
    use tokio_io::codec::length_delimited;
    use tokio_serde_bincode::{ReadBincode, WriteBincode};
    use futures::sink::Sink;
    use futures::{Future, Stream};

    #[test]
    fn roundtrip_serde_bincode() {
        // Create secret key, public key, message digest and signature
        let slice: [u8; 32] = [0xab; 32];
        let sk = SecretKey::from_slice(&::SECP256K1, &slice).unwrap();
        let ke_pk = PublicKey::from_secret_key(&::SECP256K1, &sk).unwrap();
        assert!(ke_pk.is_valid());
        let slice: [u8; 32] = [0x01; 32];
        let msg = ::secp256k1::Message::from_slice(&slice).unwrap();
        let sig = ::SECP256K1.sign(&msg, &sk).unwrap();

        // Create message
        let msg1 = Message {
            header: Header {
                peer_id: PeerId([17; 32], [7; 32]),
                session_id: SessionId([56; 32]),
                signature: sig,
            },
            payload: Payload::KeyExchange(KeyExchange {
                ke_pk: ke_pk,
            }),
        };

        // Write message
        let pipe = Cursor::new(Vec::new());
        let write = WriteBincode::new(length_delimited::FramedWrite::new(pipe));
        let write = write.send(msg1.clone()).wait().unwrap();

        // Read message again
        let pipe = Cursor::new(write.into_inner().into_inner().into_inner());
        let read = ReadBincode::<_ ,Message>::new(length_delimited::FramedRead::new(pipe));
        let msg2 = read.wait().next().unwrap().unwrap();

        assert_eq!(msg1, msg2);
    }
}
<commit_msg>Fix message test<commit_after>//! Protocol messages
//!
//! All protocol messages are serialized by serde according to the bincode data format. For
//! transmission on the wire, `tokio_io::codec::length_delimited` is used to prepend protocol
//! messages by an additional length header, thereby creating frames. It is crucial to
//!
//! The main type `Message` and the types in its fields are dump containers, which are not
//! responsible for any protocol logic (except for syntactic validation including validation of
//! `PublicKey` and `SecretKey` fields). Consequently, all fields of `Message` and all fields of
//! its contained types such as `Header` and `Payload` are public.

use secp256k1::key::{PublicKey, SecretKey};
use secp256k1::Signature;
use ::{SessionId, PeerIndex, SymmetricKey, SequenceNum};

/// A protocol message
///
/// Protocol messages consist of a header and a payload.
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct Message {
    pub header: Header,
    pub payload: Payload,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct Header {
    pub session_id: SessionId,
    pub peer_index: PeerIndex,
    pub sequence_num: SequenceNum,
    pub signature: Signature,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) enum Payload {
    KeyExchange(KeyExchange),
    DcExponential(DcExponential),
    DcXor(DcXor),
    DcAddSecp256k1Scalar(DcAddSecp256k1Scalar),
    Blame(Blame),
    Confirm(Confirm),
    Reveal(Reveal),
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct KeyExchange {
    pub ke_pk: PublicKey,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct DcExponential {
    pub commitment: [u8; 32],
    pub dc_exp: Vec<[u8; 16]>,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct DcXor {
    pub ok: bool,
    pub dc_xor: Vec<Vec<u8>>,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct DcAddSecp256k1Scalar {
    // FIXME
    pub dc_add_secp256k1_scalar: (),
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct Blame {
    pub ke_sk: SecretKey,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct Confirm {
    pub data: Vec<u8>,
}

#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub(crate) struct Reveal {
    pub keys: Vec<(PeerIndex, SymmetricKey)>,
}

#[cfg(test)]
mod tests {
    use std::io::Cursor;
    use tokio_io::codec::length_delimited;
    use tokio_serde_bincode::{ReadBincode, WriteBincode};
    use futures::sink::Sink;
    use futures::{Future, Stream};

    use super::*;
    use secp256k1::key::SecretKey;

    #[test]
    fn roundtrip_serde_bincode() {
        // Create secret key, public key, message digest and signature
        let slice: [u8; 32] = [0xab; 32];
        let sk = SecretKey::from_slice(&::SECP256K1, &slice).unwrap();
        let ke_pk = PublicKey::from_secret_key(&::SECP256K1, &sk).unwrap();
        assert!(ke_pk.is_valid());
        let slice: [u8; 32] = [0x01; 32];
        let msg = ::secp256k1::Message::from_slice(&slice).unwrap();
        let sig = ::SECP256K1.sign(&msg, &sk).unwrap();

        // Create message
        let msg1 = Message {
            header: Header {
                peer_index: 17,
                session_id: SessionId([56; 32]),
                sequence_num: 14,
                signature: sig,
            },
            payload: Payload::KeyExchange(KeyExchange {
                ke_pk: ke_pk,
            }),
        };

        // Write message
        let pipe = Cursor::new(Vec::new());
        let write = WriteBincode::new(length_delimited::FramedWrite::new(pipe));
        let write = write.send(msg1.clone()).wait().unwrap();

        // Read message again
        let pipe = Cursor::new(write.into_inner().into_inner().into_inner());
        let read = ReadBincode::<_ ,Message>::new(length_delimited::FramedRead::new(pipe));
        let msg2 = read.wait().next().unwrap().unwrap();

        assert_eq!(msg1, msg2);
    }
}
<|endoftext|>


<commit_before>static ROMAN_MAP: [(usize, &'static str); 13] = [
    (1, "I"),
    (4, "IV"),
    (5, "V"),
    (9, "IX"),
    (10, "X"),
    (40, "XL"),
    (50, "L"),
    (90, "XC"),
    (100, "C"),
    (400, "CD"),
    (500, "D"),
    (900, "CM"),
    (1000, "M"),
];

pub struct Roman {
    num: usize
}

impl From<usize> for Roman {
    fn from(i: usize) -> Self {
        Roman::new(i)
    }
}

impl ToString for Roman {
    fn to_string(&self) -> String {
        let mut start = self.num.clone();
        let mut result = String::new();
        for &(numeric, roman_string) in ROMAN_MAP.into_iter().rev() {
            while start >= numeric {
                result.push_str(roman_string);
                start = start - numeric;
            }
        }
        result
    }
}

impl Roman {
    fn new(num: usize) -> Roman {
        Roman {
            num: num,
        }
    }
}
<commit_msg>Update example to use Display<commit_after>use std::fmt;

static ROMAN_MAP: [(usize, &'static str); 13] = [(1, "I"),
                                                 (4, "IV"),
                                                 (5, "V"),
                                                 (9, "IX"),
                                                 (10, "X"),
                                                 (40, "XL"),
                                                 (50, "L"),
                                                 (90, "XC"),
                                                 (100, "C"),
                                                 (400, "CD"),
                                                 (500, "D"),
                                                 (900, "CM"),
                                                 (1000, "M")];

pub struct Roman {
    num: usize,
}

impl From<usize> for Roman {
    fn from(i: usize) -> Self {
        Roman::new(i)
    }
}

impl fmt::Display for Roman {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut start = self.num.clone();
        let mut result = String::new();
        for &(numeric, roman_string) in ROMAN_MAP.into_iter().rev() {
            while start >= numeric {
                result.push_str(roman_string);
                start = start - numeric;
            }
        }
        write!(f, "{}", result)
    }
}

impl Roman {
    fn new(num: usize) -> Roman {
        Roman { num: num }
    }
}
<|endoftext|>


<commit_before>use std::f32::consts::PI;

use num::complex::Complex32;
use num::traits::Zero;
use quad_osc::QuadOsc;
use rand::distributions::normal::Normal;
use rand::distributions::IndependentSample;
use rand;

use consts::SAMPLES_PER_FRAME;
use descramble::VoiceDecisions;
use enhance::EnhancedSpectrals;
use params::BaseParams;
use window;

// Result of equation 121
const SCALING_COEF: f32 = 146.6432708443356;

const DFT_SIZE: usize = 256;
const IDFT_SIZE: usize = 256;

const DFT_HALF: usize = DFT_SIZE / 2;
const IDFT_HALF: usize = IDFT_SIZE / 2;

fn edges(l: usize, params: &BaseParams) -> (usize, usize) {
    let common = DFT_SIZE as f32 / (2.0 * PI) * params.fundamental;

    (
        (common * (l as f32 - 0.5)).ceil() as usize,
        (common * (l as f32 + 0.5)).ceil() as usize,
    )
}

/// Constructs unvoiced DFT/IDFT.
///
/// Constructs a frequency-domain representation of an "unvoiced" white noise signal,
/// bandpassed only for the unvoiced frequencies in the current frame. This spectrum can
/// then be used with an inverse Fourier transform to produce a white noise signal
/// containing only unvoiced frequency content.
pub struct UnvoicedDFT([Complex32; DFT_HALF]);

impl UnvoicedDFT {
    pub fn new(params: &BaseParams, voice: &VoiceDecisions, enhanced: &EnhancedSpectrals)
        -> UnvoicedDFT
    {
        let mut dft = [Complex32::default(); DFT_HALF];

        let mut rng = rand::weak_rng();
        let gaus = Normal::new(0.0, (DFT_HALF as f64).sqrt());

        for (l, &amplitude) in enhanced.iter().enumerate() {
            let l = l + 1;

            if voice.is_voiced(l) {
                continue;
            }

            let (lower, upper) = edges(l, params);

            for m in lower..upper {
                dft[m] = Complex32::new(gaus.ind_sample(&mut rng) as f32,
                                        gaus.ind_sample(&mut rng) as f32);
            }

            let energy = (lower..upper)
                .map(|m| dft[m].norm_sqr())
                .fold(0.0, |s, x| s + x);
            let power = energy / (upper - lower) as f32;
            let scale = SCALING_COEF * amplitude / power.sqrt();

            for m in lower..upper {
                dft[m] = scale * dft[m];
            }
        }

        UnvoicedDFT(dft)
    }

    pub fn idft(&self, n: isize) -> f32 {
        if n < -(IDFT_HALF as isize) || n >= IDFT_HALF as isize {
            return 0.0;
        }

        let mut osc = QuadOsc::new(0.0, 2.0 / IDFT_SIZE as f32 * PI * n as f32);

        2.0 / (DFT_SIZE as f32 * IDFT_SIZE as f32).sqrt() * (0..DFT_HALF).map(|m| {
            let (sin, cos) = osc.next();
            self.0[m].re * cos - self.0[m].im * sin
        }).fold(0.0, |s, x| s + x)
    }
}

impl Default for UnvoicedDFT {
    fn default() -> UnvoicedDFT {
        UnvoicedDFT([Complex32::zero(); DFT_HALF])
    }
}

pub struct Unvoiced<'a, 'b> {
    cur: &'a UnvoicedDFT,
    prev: &'b UnvoicedDFT,
    window: window::Window,
}

impl<'a, 'b> Unvoiced<'a, 'b> {
    pub fn new(cur: &'a UnvoicedDFT, prev: &'b UnvoicedDFT) -> Unvoiced<'a, 'b> {
        Unvoiced {
            cur: cur,
            prev: prev,
            window: window::synthesis(),
        }
    }

    pub fn get(&self, n: usize) -> f32 {
        let n = n as isize;

        let numer = self.window.get(n) * self.prev.idft(n) +
            self.window.get(n - SAMPLES_PER_FRAME as isize) * self.cur.idft(n - SAMPLES_PER_FRAME as isize);
        let denom = self.window.get(n).powi(2) +
            self.window.get(n - SAMPLES_PER_FRAME as isize).powi(2);

        numer / denom
    }
}

#[cfg(test)]
mod test {
    use super::edges;
    use descramble::Bootstrap;
    use params::BaseParams;

    #[test]
    fn test_edges() {
        let chunks = [
            0b001000010010,
            0b110011001100,
            0b111000111000,
            0b111111111111,
            0b10100110101,
            0b00101111010,
            0b01110111011,
            0b00001000,
        ];

        let b = Bootstrap::new(&chunks);
        let p = BaseParams::new(b.unwrap_period());

        assert!((p.fundamental - 0.17575344).abs() < 0.000001);

        let (lower, upper) = edges(1, &p);
        assert_eq!(lower, 4);
        assert_eq!(upper, 11);

        let (lower, upper) = edges(2, &p);
        assert_eq!(lower, 11);
        assert_eq!(upper, 18);

        let (lower, upper) = edges(5, &p);
        assert_eq!(lower, 33);
        assert_eq!(upper, 40);

        let (lower, upper) = edges(8, &p);
        assert_eq!(lower, 54);
        assert_eq!(upper, 61);

        let (lower, upper) = edges(16, &p);
        assert_eq!(lower, 111);
        assert_eq!(upper, 119);
    }
}
<commit_msg>Use iterator rather than indexing<commit_after>use std::f32::consts::PI;

use num::complex::Complex32;
use num::traits::Zero;
use quad_osc::QuadOsc;
use rand::distributions::normal::Normal;
use rand::distributions::IndependentSample;
use rand;

use consts::SAMPLES_PER_FRAME;
use descramble::VoiceDecisions;
use enhance::EnhancedSpectrals;
use params::BaseParams;
use window;

// Result of equation 121
const SCALING_COEF: f32 = 146.6432708443356;

const DFT_SIZE: usize = 256;
const IDFT_SIZE: usize = 256;

const DFT_HALF: usize = DFT_SIZE / 2;
const IDFT_HALF: usize = IDFT_SIZE / 2;

fn edges(l: usize, params: &BaseParams) -> (usize, usize) {
    let common = DFT_SIZE as f32 / (2.0 * PI) * params.fundamental;

    (
        (common * (l as f32 - 0.5)).ceil() as usize,
        (common * (l as f32 + 0.5)).ceil() as usize,
    )
}

/// Constructs unvoiced DFT/IDFT.
///
/// Constructs a frequency-domain representation of an "unvoiced" white noise signal,
/// bandpassed only for the unvoiced frequencies in the current frame. This spectrum can
/// then be used with an inverse Fourier transform to produce a white noise signal
/// containing only unvoiced frequency content.
pub struct UnvoicedDFT([Complex32; DFT_HALF]);

impl UnvoicedDFT {
    pub fn new(params: &BaseParams, voice: &VoiceDecisions, enhanced: &EnhancedSpectrals)
        -> UnvoicedDFT
    {
        let mut dft = [Complex32::default(); DFT_HALF];

        let mut rng = rand::weak_rng();
        let gaus = Normal::new(0.0, (DFT_HALF as f64).sqrt());

        for (l, &amplitude) in enhanced.iter().enumerate() {
            let l = l + 1;

            if voice.is_voiced(l) {
                continue;
            }

            let (lower, upper) = edges(l, params);

            for m in lower..upper {
                dft[m] = Complex32::new(gaus.ind_sample(&mut rng) as f32,
                                        gaus.ind_sample(&mut rng) as f32);
            }

            let energy = (lower..upper)
                .map(|m| dft[m].norm_sqr())
                .fold(0.0, |s, x| s + x);
            let power = energy / (upper - lower) as f32;
            let scale = SCALING_COEF * amplitude / power.sqrt();

            for m in lower..upper {
                dft[m] = scale * dft[m];
            }
        }

        UnvoicedDFT(dft)
    }

    pub fn idft(&self, n: isize) -> f32 {
        if n < -(IDFT_HALF as isize) || n >= IDFT_HALF as isize {
            return 0.0;
        }

        let mut osc = QuadOsc::new(0.0, 2.0 / IDFT_SIZE as f32 * PI * n as f32);

        2.0 / (DFT_SIZE as f32 * IDFT_SIZE as f32).sqrt() * self.0.iter().map(|x| {
            let (sin, cos) = osc.next();
            x.re * cos - x.im * sin
        }).fold(0.0, |s, x| s + x)
    }
}

impl Default for UnvoicedDFT {
    fn default() -> UnvoicedDFT {
        UnvoicedDFT([Complex32::zero(); DFT_HALF])
    }
}

pub struct Unvoiced<'a, 'b> {
    cur: &'a UnvoicedDFT,
    prev: &'b UnvoicedDFT,
    window: window::Window,
}

impl<'a, 'b> Unvoiced<'a, 'b> {
    pub fn new(cur: &'a UnvoicedDFT, prev: &'b UnvoicedDFT) -> Unvoiced<'a, 'b> {
        Unvoiced {
            cur: cur,
            prev: prev,
            window: window::synthesis(),
        }
    }

    pub fn get(&self, n: usize) -> f32 {
        let n = n as isize;

        let numer = self.window.get(n) * self.prev.idft(n) +
            self.window.get(n - SAMPLES_PER_FRAME as isize) * self.cur.idft(n - SAMPLES_PER_FRAME as isize);
        let denom = self.window.get(n).powi(2) +
            self.window.get(n - SAMPLES_PER_FRAME as isize).powi(2);

        numer / denom
    }
}

#[cfg(test)]
mod test {
    use super::edges;
    use descramble::Bootstrap;
    use params::BaseParams;

    #[test]
    fn test_edges() {
        let chunks = [
            0b001000010010,
            0b110011001100,
            0b111000111000,
            0b111111111111,
            0b10100110101,
            0b00101111010,
            0b01110111011,
            0b00001000,
        ];

        let b = Bootstrap::new(&chunks);
        let p = BaseParams::new(b.unwrap_period());

        assert!((p.fundamental - 0.17575344).abs() < 0.000001);

        let (lower, upper) = edges(1, &p);
        assert_eq!(lower, 4);
        assert_eq!(upper, 11);

        let (lower, upper) = edges(2, &p);
        assert_eq!(lower, 11);
        assert_eq!(upper, 18);

        let (lower, upper) = edges(5, &p);
        assert_eq!(lower, 33);
        assert_eq!(upper, 40);

        let (lower, upper) = edges(8, &p);
        assert_eq!(lower, 54);
        assert_eq!(upper, 61);

        let (lower, upper) = edges(16, &p);
        assert_eq!(lower, 111);
        assert_eq!(upper, 119);
    }
}
<|endoftext|>


<commit_before>use std::time::Duration;
use ggez::{Context, GameResult, graphics};
use ggez::graphics::Point;
use event::{Assets, Transition, EventHandler, Keycode, Mod};
mod option;

use self::option::Option;
use states::play_state::{PlayState, Position};
use states::play_state::tetromino::{Piece, PieceType};
use util::DurationExt;

pub struct MenuState {
    title_text: graphics::Text,
    title_rotation: f64,
    piece: Piece,
    options: Vec<Option>,
    current_selection: usize,

    request_play: bool,
    request_exit: bool,
}

impl MenuState {
    pub fn new(ctx: &mut Context, assets: &Assets) -> GameResult<MenuState> {
        let title = graphics::Text::new(ctx, "Rustris", assets.get_font("title")?)?;
        let mut options_vec: Vec<Option> = Vec::new();
        let coords = graphics::get_screen_coordinates(&ctx);

        options_vec.push(Option::new(ctx, assets, "Play!", Point::new(coords.w / 2.0, 250.0)));
        options_vec.push(Option::new(ctx, assets, "Exit", Point::new(coords.w / 2.0, 325.0)));

        Ok(MenuState {
            title_text: title,
            title_rotation: 0.0,
            piece: Piece::new(PieceType::L),
            options: options_vec,
            current_selection: 0,

            request_play: false,
            request_exit: false,
        })
    }
}

impl EventHandler for MenuState {
    fn update(&mut self,
              ctx: &mut Context,
              assets: &Assets,
              dt: Duration)
              -> GameResult<Transition> {
        self.title_rotation += dt.as_subsec_millis();

        if self.request_play {
            return Ok(Transition::Swap(Box::new(PlayState::new(ctx, assets).unwrap())));
        }
        if self.request_exit {
            return Ok(Transition::Pop);
        }

        // for mut option in &mut self.options {
        for (i, option) in self.options.iter_mut().enumerate() {
            if i == self.current_selection {
                option.update(true)?;
            } else {
                option.update(false)?;
            }
        }

        Ok(Transition::None)
    }

    fn draw(&mut self, ctx: &mut Context, assets: &Assets) -> GameResult<()> {
        let coords = graphics::get_screen_coordinates(&ctx);

        let title_dest = graphics::Point::new(coords.w / 2.0, 100.0);
        let pos = Position::new(5, 50);

        graphics::set_color(ctx, graphics::Color::new(1.0, 1.0, 1.0, 1.0))?;
        graphics::draw(ctx, &self.title_text, title_dest, 0.0)?;
        self.piece.draw_at_point(ctx, assets.get_image("block")?, pos, self.title_rotation)?;

        for option in &self.options {
            option.draw(ctx)?;
        }

        Ok(())
    }

    fn key_down_event(&mut self, keycode: Keycode, _keymod: Mod, repeat: bool) {
        if repeat {
            return;
        }

        match keycode {
            Keycode::Up => {
                if self.current_selection <= 0 {
                    self.current_selection = self.options.len() - 1;
                }
                else {
                    self.current_selection -= 1;
                }
            },
            Keycode::Down => {
                if self.current_selection >= self.options.len() - 1{
                    self.current_selection = 0;
                }
                else {
                    self.current_selection += 1;
                }
            },
            Keycode::Return => {
                println!("HI!");
                if self.current_selection == 0 {
                    self.request_play = true;
                }
                else if self.current_selection == 1 {
                    self.request_exit = true;
                }
            },
            _ => (),
        }
    }
}
<commit_msg>MenuState: Controller input, keeping input DRY<commit_after>use std::time::Duration;
use ggez::{Context, GameResult, graphics};
use ggez::graphics::Point;
use event::{Assets, Transition, EventHandler, Keycode, Mod, Button};
mod option;

use self::option::Option;
use states::play_state::{PlayState, Position};
use states::play_state::tetromino::{Piece, PieceType};
use util::DurationExt;

enum MenuInputCommand {
    Up,
    Down,
    Select,
}

pub struct MenuState {
    title_text: graphics::Text,
    title_rotation: f64,
    piece: Piece,
    options: Vec<Option>,
    current_selection: usize,

    request_play: bool,
    request_exit: bool,
}

impl MenuState {
    pub fn new(ctx: &mut Context, assets: &Assets) -> GameResult<MenuState> {
        let title = graphics::Text::new(ctx, "Rustris", assets.get_font("title")?)?;
        let mut options_vec: Vec<Option> = Vec::new();
        let coords = graphics::get_screen_coordinates(&ctx);

        options_vec.push(Option::new(ctx, assets, "Play!", Point::new(coords.w / 2.0, 250.0)));
        options_vec.push(Option::new(ctx, assets, "Exit", Point::new(coords.w / 2.0, 325.0)));

        Ok(MenuState {
            title_text: title,
            title_rotation: 0.0,
            piece: Piece::new(PieceType::L),
            options: options_vec,
            current_selection: 0,

            request_play: false,
            request_exit: false,
        })
    }

    fn handle_input(&mut self, command: MenuInputCommand) {
        match command {
            MenuInputCommand::Up => {
                if self.current_selection <= 0 {
                    self.current_selection = self.options.len() - 1;
                }
                else {
                    self.current_selection -= 1;
                }
            },
            MenuInputCommand::Down => {
                if self.current_selection >= self.options.len() - 1{
                    self.current_selection = 0;
                }
                else {
                    self.current_selection += 1;
                }
            },
            MenuInputCommand::Select => {
                println!("HI!");
                if self.current_selection == 0 {
                    self.request_play = true;
                }
                else if self.current_selection == 1 {
                    self.request_exit = true;
                }
            },
        }
    }
}

impl EventHandler for MenuState {
    fn update(&mut self,
              ctx: &mut Context,
              assets: &Assets,
              dt: Duration)
              -> GameResult<Transition> {
        self.title_rotation += dt.as_subsec_millis();

        if self.request_play {
            return Ok(Transition::Swap(Box::new(PlayState::new(ctx, assets).unwrap())));
        }
        if self.request_exit {
            return Ok(Transition::Pop);
        }

        // for mut option in &mut self.options {
        for (i, option) in self.options.iter_mut().enumerate() {
            if i == self.current_selection {
                option.update(true)?;
            } else {
                option.update(false)?;
            }
        }

        Ok(Transition::None)
    }

    fn draw(&mut self, ctx: &mut Context, assets: &Assets) -> GameResult<()> {
        let coords = graphics::get_screen_coordinates(&ctx);

        let title_dest = graphics::Point::new(coords.w / 2.0, 100.0);
        let pos = Position::new(5, 50);

        graphics::set_color(ctx, graphics::Color::new(1.0, 1.0, 1.0, 1.0))?;
        graphics::draw(ctx, &self.title_text, title_dest, 0.0)?;
        self.piece.draw_at_point(ctx, assets.get_image("block")?, pos, self.title_rotation)?;

        for option in &self.options {
            option.draw(ctx)?;
        }

        Ok(())
    }

    fn key_down_event(&mut self, keycode: Keycode, _keymod: Mod, repeat: bool) {
        if repeat {
            return;
        }

        match keycode {
            Keycode::Up => self.handle_input(MenuInputCommand::Up),
            Keycode::Down => self.handle_input(MenuInputCommand::Down),
            Keycode::Return => self.handle_input(MenuInputCommand::Select),
            _ => (),
        }
    }

    fn controller_button_down_event(&mut self, btn: Button, _instance_id: i32) {
        match btn {
            Button::DPadUp => self.handle_input(MenuInputCommand::Up),
            Button::DPadDown => self.handle_input(MenuInputCommand::Down),
            Button::A => self.handle_input(MenuInputCommand::Select),
            _ => (),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 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 std::env;
use std::process::Command;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::Write;

struct Test {
    repo: &'static str,
    name: &'static str,
    sha: &'static str,
    lock: Option<&'static str>,
}

const TEST_REPOS: &'static [Test] = &[Test {
                                          name: "cargo",
                                          repo: "https://github.com/rust-lang/cargo",
                                          sha: "806e3c368a15f618244a3b4e918bf77f9c403fd0",
                                          lock: None,
                                      },
                                      Test {
                                          name: "iron",
                                          repo: "https://github.com/iron/iron",
                                          sha: "16c858ec2901e2992fe5e529780f59fa8ed12903",
                                          lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
                                      }];

fn main() {
    // One of the projects being tested here is Cargo, and when being tested
    // Cargo will at some point call `nmake.exe` on Windows MSVC. Unfortunately
    // `nmake` will read these two environment variables below and try to
    // intepret them. We're likely being run, however, from MSYS `make` which
    // uses the same variables.
    //
    // As a result, to prevent confusion and errors, we remove these variables
    // from our environment to prevent passing MSYS make flags to nmake, causing
    // it to blow up.
    if cfg!(target_env = "msvc") {
        env::remove_var("MAKE");
        env::remove_var("MAKEFLAGS");
    }

    let args = env::args().collect::<Vec<_>>();
    let ref cargo = args[1];
    let out_dir = Path::new(&args[2]);
    let ref cargo = Path::new(cargo);

    for test in TEST_REPOS.iter().rev() {
        test_repo(cargo, out_dir, test);
    }
}

fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
    println!("testing {}", test.repo);
    let dir = clone_repo(test, out_dir);
    if let Some(lockfile) = test.lock {
        File::create(&dir.join("Cargo.lock"))
            .expect("")
            .write_all(lockfile.as_bytes())
            .expect("");
    }
    if !run_cargo_test(cargo, &dir) {
        panic!("tests failed for {}", test.repo);
    }
}

fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
    let out_dir = out_dir.join(test.name);

    if !out_dir.join(".git").is_dir() {
        let status = Command::new("git")
                         .arg("init")
                         .arg(&out_dir)
                         .status()
                         .expect("");
        assert!(status.success());
    }

    // Try progressively deeper fetch depths to find the commit
    let mut found = false;
    for depth in &[0, 1, 10, 100, 1000, 100000] {
        if *depth > 0 {
            let status = Command::new("git")
                             .arg("fetch")
                             .arg(test.repo)
                             .arg("master")
                             .arg(&format!("--depth={}", depth))
                             .current_dir(&out_dir)
                             .status()
                             .expect("");
            assert!(status.success());
        }

        let status = Command::new("git")
                         .arg("reset")
                         .arg(test.sha)
                         .arg("--hard")
                         .current_dir(&out_dir)
                         .status()
                         .expect("");

        if status.success() {
            found = true;
            break;
        }
    }

    if !found {
        panic!("unable to find commit {}", test.sha)
    }
    let status = Command::new("git")
                     .arg("clean")
                     .arg("-fdx")
                     .current_dir(&out_dir)
                     .status()
                     .unwrap();
    assert!(status.success());

    out_dir
}

fn run_cargo_test(cargo_path: &Path, crate_path: &Path) -> bool {
    let status = Command::new(cargo_path)
        .arg("test")
        // Disable rust-lang/cargo's cross-compile tests
        .env("CFG_DISABLE_CROSS_TESTS", "1")
        .current_dir(crate_path)
        .status()
        .expect("");

    status.success()
}
<commit_msg>Update commit hash in cargotest<commit_after>// Copyright 2016 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 std::env;
use std::process::Command;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::Write;

struct Test {
    repo: &'static str,
    name: &'static str,
    sha: &'static str,
    lock: Option<&'static str>,
}

const TEST_REPOS: &'static [Test] = &[Test {
                                          name: "cargo",
                                          repo: "https://github.com/rust-lang/cargo",
                                          sha: "b7be4f2ef2cf743492edc6dfb55d087ed88f2d76",
                                          lock: None,
                                      },
                                      Test {
                                          name: "iron",
                                          repo: "https://github.com/iron/iron",
                                          sha: "16c858ec2901e2992fe5e529780f59fa8ed12903",
                                          lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
                                      }];

fn main() {
    // One of the projects being tested here is Cargo, and when being tested
    // Cargo will at some point call `nmake.exe` on Windows MSVC. Unfortunately
    // `nmake` will read these two environment variables below and try to
    // intepret them. We're likely being run, however, from MSYS `make` which
    // uses the same variables.
    //
    // As a result, to prevent confusion and errors, we remove these variables
    // from our environment to prevent passing MSYS make flags to nmake, causing
    // it to blow up.
    if cfg!(target_env = "msvc") {
        env::remove_var("MAKE");
        env::remove_var("MAKEFLAGS");
    }

    let args = env::args().collect::<Vec<_>>();
    let ref cargo = args[1];
    let out_dir = Path::new(&args[2]);
    let ref cargo = Path::new(cargo);

    for test in TEST_REPOS.iter().rev() {
        test_repo(cargo, out_dir, test);
    }
}

fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
    println!("testing {}", test.repo);
    let dir = clone_repo(test, out_dir);
    if let Some(lockfile) = test.lock {
        File::create(&dir.join("Cargo.lock"))
            .expect("")
            .write_all(lockfile.as_bytes())
            .expect("");
    }
    if !run_cargo_test(cargo, &dir) {
        panic!("tests failed for {}", test.repo);
    }
}

fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
    let out_dir = out_dir.join(test.name);

    if !out_dir.join(".git").is_dir() {
        let status = Command::new("git")
                         .arg("init")
                         .arg(&out_dir)
                         .status()
                         .expect("");
        assert!(status.success());
    }

    // Try progressively deeper fetch depths to find the commit
    let mut found = false;
    for depth in &[0, 1, 10, 100, 1000, 100000] {
        if *depth > 0 {
            let status = Command::new("git")
                             .arg("fetch")
                             .arg(test.repo)
                             .arg("master")
                             .arg(&format!("--depth={}", depth))
                             .current_dir(&out_dir)
                             .status()
                             .expect("");
            assert!(status.success());
        }

        let status = Command::new("git")
                         .arg("reset")
                         .arg(test.sha)
                         .arg("--hard")
                         .current_dir(&out_dir)
                         .status()
                         .expect("");

        if status.success() {
            found = true;
            break;
        }
    }

    if !found {
        panic!("unable to find commit {}", test.sha)
    }
    let status = Command::new("git")
                     .arg("clean")
                     .arg("-fdx")
                     .current_dir(&out_dir)
                     .status()
                     .unwrap();
    assert!(status.success());

    out_dir
}

fn run_cargo_test(cargo_path: &Path, crate_path: &Path) -> bool {
    let status = Command::new(cargo_path)
        .arg("test")
        // Disable rust-lang/cargo's cross-compile tests
        .env("CFG_DISABLE_CROSS_TESTS", "1")
        .current_dir(crate_path)
        .status()
        .expect("");

    status.success()
}
<|endoftext|>


<commit_before>use core::fmt;

#[derive(Debug, Copy, Clone)]
#[repr(C, packed)]
pub struct VBEInfoTag {
    typ: u32,
    length: u32,
    pub mode: u16,
    pub interface_segment: u16,
    pub interface_offset: u16,
    pub interface_length: u16,
    pub control_info: VBEControlInfo,
    pub mode_info: VBEModeInfo
}

#[derive(Copy, Clone)]
#[repr(C, packed)]
pub struct VBEControlInfo {
    pub signature: [u8; 4],
    pub version: u16,
    pub oem_string_ptr: u32,
    pub capabilities: VBECapabilities,
    pub mode_list_ptr: u32,
    pub total_memory: u16, // Measured in 64kb blocks.
    pub oem_software_revision: u16,
    pub oem_vendor_name_ptr: u32,
    pub oem_product_name_ptr: u32,
    pub oem_product_revision_ptr: u32,
    reserved: [u8; 222],
    oem_data: [u8; 256]
}

impl fmt::Debug for VBEControlInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            f.debug_struct("VBEControlInfo")
             .field("signature", &self.signature)
             .field("oem_string_ptr", &self.oem_string_ptr)
             .field("capabilities", &self.capabilities)
             .field("mode_list_ptr", &self.mode_list_ptr)
             .field("total_memory", &self.total_memory)
             .field("oem_software_revision", &self.oem_software_revision)
             .field("oem_vendor_name_ptr", &self.oem_vendor_name_ptr)
             .field("oem_product_name_ptr", &self.oem_product_name_ptr)
             .field("oem_product_revision_ptr", &self.oem_product_revision_ptr)
             .finish()
        }
    }
}

#[derive(Copy, Clone)]
#[repr(C, packed)]
pub struct VBEModeInfo {
    pub mode_attributes: VBEModeAttributes,
    pub window_a_attributes: VBEWindowAttributes,
    pub window_b_attributes: VBEWindowAttributes,
    pub window_granularity: u16, // Measured in kilobytes.
    pub window_size: u16,
    pub window_a_segment: u16,
    pub window_b_segment: u16,
    pub window_function_ptr: u32,
    pub pitch: u16,
    pub resolution: (u16, u16),
    pub character_size: (u8, u8),
    pub number_of_planes: u8,
    pub bpp: u8,
    pub number_of_banks: u8,
    pub memory_model: VBEMemoryModel,
    pub bank_size: u8, // Measured in kilobytes.
    pub number_of_image_pages: u8,
    reserved0: u8,
    pub red_field: VBEField,
    pub green_field: VBEField,
    pub blue_field: VBEField,
    pub reserved_field: VBEField,
    pub direct_color_attributes: VBEDirectColorAttributes,
    pub framebuffer_base_ptr: u32,
    pub offscreen_memory_offset: u32,
    pub offscreen_memory_size: u16,
    reserved1: [u8; 206]
}

impl fmt::Debug for VBEModeInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            f.debug_struct("VBEModeInfo")
             .field("mode_attributes", &self.mode_attributes)
             .field("window_a_attributes", &self.window_a_attributes)
             .field("window_b_attributes", &self.window_b_attributes)
             .field("window_granularity", &self.window_granularity)
             .field("window_size", &self.window_size)
             .field("window_a_segment", &self.window_a_segment)
             .field("window_b_segment", &self.window_b_segment)
             .field("window_function_ptr", &self.window_function_ptr)
             .field("pitch", &self.pitch)
             .field("resolution", &self.resolution)
             .field("character_size", &self.character_size)
             .field("number_of_planes", &self.number_of_planes)
             .field("bpp", &self.bpp)
             .field("number_of_banks", &self.number_of_banks)
             .field("memory_model", &self.memory_model)
             .field("bank_size", &self.bank_size)
             .field("number_of_image_pages", &self.number_of_image_pages)
             .field("red_field", &self.red_field)
             .field("green_field", &self.green_field)
             .field("blue_field", &self.blue_field)
             .field("reserved_field", &self.reserved_field)
             .field("direct_color_attributes", &self.direct_color_attributes)
             .field("framebuffer_base_ptr", &self.framebuffer_base_ptr)
             .field("offscreen_memory_offset", &self.offscreen_memory_offset)
             .field("offscreen_memory_size", &self.offscreen_memory_size)
             .finish()
        }
    }
}

#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(C, packed)]
pub struct VBEField {
    pub size: u8,
    pub position: u8
}

bitflags! {
    pub struct VBECapabilities: u32 {
        const SWITCHABLE_DAC = 0x1;     // The DAC can be switched between 6 and 8-bit modes.
        const NOT_VGA_COMPATIBLE = 0x2; // The controller can be switched into VGA modes.
        const RAMDAC_FIX = 0x4;         // When writing lots of information to the palette, the blank bit should be used.
    }
}

bitflags! {
    pub struct VBEModeAttributes: u16 {
        const SUPPORTED = 0x1;           // This mode is supported by the hardware.
        const TTY_SUPPORTED = 0x4;       // TTY output is supported.
        const COLOR = 0x8;
        const GRAPHICS = 0x10;
        const NOT_VGA_COMPATIBLE = 0x20;
        const NO_VGA_WINDOW = 0x40;      // If this is set, the window A and B fields of VBEModeInfo are invalid.
        const LINEAR_FRAMEBUFFER = 0x80; // A linear framebuffer is available for this mode.
    }
}

bitflags! {
    pub struct VBEWindowAttributes: u8 {
        const RELOCATABLE = 0x1;
        const READABLE = 0x2;
        const WRITEABLE = 0x4;
    }
}

bitflags! {
    pub struct VBEDirectColorAttributes: u8 {
        const PROGRAMMABLE = 0x1;       // The color ramp of the DAC is programmable.
        const RESERVED_USABLE = 0x2;    // The bits of the 'reserved' field are usable by the application.
    }
}

#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(u8)]
pub enum VBEMemoryModel {
    Text = 0x00,
    CGAGraphics = 0x01,
    HerculesGraphics = 0x02,
    Planar = 0x03,
    PackedPixel = 0x04,
    Unchained = 0x05,
    DirectColor = 0x06,
    YUV = 0x07
}<commit_msg>Added missing version field.<commit_after>use core::fmt;

#[derive(Debug, Copy, Clone)]
#[repr(C, packed)]
pub struct VBEInfoTag {
    typ: u32,
    length: u32,
    pub mode: u16,
    pub interface_segment: u16,
    pub interface_offset: u16,
    pub interface_length: u16,
    pub control_info: VBEControlInfo,
    pub mode_info: VBEModeInfo
}

#[derive(Copy, Clone)]
#[repr(C, packed)]
pub struct VBEControlInfo {
    pub signature: [u8; 4],
    pub version: u16,
    pub oem_string_ptr: u32,
    pub capabilities: VBECapabilities,
    pub mode_list_ptr: u32,
    pub total_memory: u16, // Measured in 64kb blocks.
    pub oem_software_revision: u16,
    pub oem_vendor_name_ptr: u32,
    pub oem_product_name_ptr: u32,
    pub oem_product_revision_ptr: u32,
    reserved: [u8; 222],
    oem_data: [u8; 256]
}

impl fmt::Debug for VBEControlInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            f.debug_struct("VBEControlInfo")
             .field("signature", &self.signature)
             .field("version", &self.version)
             .field("oem_string_ptr", &self.oem_string_ptr)
             .field("capabilities", &self.capabilities)
             .field("mode_list_ptr", &self.mode_list_ptr)
             .field("total_memory", &self.total_memory)
             .field("oem_software_revision", &self.oem_software_revision)
             .field("oem_vendor_name_ptr", &self.oem_vendor_name_ptr)
             .field("oem_product_name_ptr", &self.oem_product_name_ptr)
             .field("oem_product_revision_ptr", &self.oem_product_revision_ptr)
             .finish()
        }
    }
}

#[derive(Copy, Clone)]
#[repr(C, packed)]
pub struct VBEModeInfo {
    pub mode_attributes: VBEModeAttributes,
    pub window_a_attributes: VBEWindowAttributes,
    pub window_b_attributes: VBEWindowAttributes,
    pub window_granularity: u16, // Measured in kilobytes.
    pub window_size: u16,
    pub window_a_segment: u16,
    pub window_b_segment: u16,
    pub window_function_ptr: u32,
    pub pitch: u16,
    pub resolution: (u16, u16),
    pub character_size: (u8, u8),
    pub number_of_planes: u8,
    pub bpp: u8,
    pub number_of_banks: u8,
    pub memory_model: VBEMemoryModel,
    pub bank_size: u8, // Measured in kilobytes.
    pub number_of_image_pages: u8,
    reserved0: u8,
    pub red_field: VBEField,
    pub green_field: VBEField,
    pub blue_field: VBEField,
    pub reserved_field: VBEField,
    pub direct_color_attributes: VBEDirectColorAttributes,
    pub framebuffer_base_ptr: u32,
    pub offscreen_memory_offset: u32,
    pub offscreen_memory_size: u16,
    reserved1: [u8; 206]
}

impl fmt::Debug for VBEModeInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            f.debug_struct("VBEModeInfo")
             .field("mode_attributes", &self.mode_attributes)
             .field("window_a_attributes", &self.window_a_attributes)
             .field("window_b_attributes", &self.window_b_attributes)
             .field("window_granularity", &self.window_granularity)
             .field("window_size", &self.window_size)
             .field("window_a_segment", &self.window_a_segment)
             .field("window_b_segment", &self.window_b_segment)
             .field("window_function_ptr", &self.window_function_ptr)
             .field("pitch", &self.pitch)
             .field("resolution", &self.resolution)
             .field("character_size", &self.character_size)
             .field("number_of_planes", &self.number_of_planes)
             .field("bpp", &self.bpp)
             .field("number_of_banks", &self.number_of_banks)
             .field("memory_model", &self.memory_model)
             .field("bank_size", &self.bank_size)
             .field("number_of_image_pages", &self.number_of_image_pages)
             .field("red_field", &self.red_field)
             .field("green_field", &self.green_field)
             .field("blue_field", &self.blue_field)
             .field("reserved_field", &self.reserved_field)
             .field("direct_color_attributes", &self.direct_color_attributes)
             .field("framebuffer_base_ptr", &self.framebuffer_base_ptr)
             .field("offscreen_memory_offset", &self.offscreen_memory_offset)
             .field("offscreen_memory_size", &self.offscreen_memory_size)
             .finish()
        }
    }
}

#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(C, packed)]
pub struct VBEField {
    pub size: u8,
    pub position: u8
}

bitflags! {
    pub struct VBECapabilities: u32 {
        const SWITCHABLE_DAC = 0x1;     // The DAC can be switched between 6 and 8-bit modes.
        const NOT_VGA_COMPATIBLE = 0x2; // The controller can be switched into VGA modes.
        const RAMDAC_FIX = 0x4;         // When writing lots of information to the palette, the blank bit should be used.
    }
}

bitflags! {
    pub struct VBEModeAttributes: u16 {
        const SUPPORTED = 0x1;           // This mode is supported by the hardware.
        const TTY_SUPPORTED = 0x4;       // TTY output is supported.
        const COLOR = 0x8;
        const GRAPHICS = 0x10;
        const NOT_VGA_COMPATIBLE = 0x20;
        const NO_VGA_WINDOW = 0x40;      // If this is set, the window A and B fields of VBEModeInfo are invalid.
        const LINEAR_FRAMEBUFFER = 0x80; // A linear framebuffer is available for this mode.
    }
}

bitflags! {
    pub struct VBEWindowAttributes: u8 {
        const RELOCATABLE = 0x1;
        const READABLE = 0x2;
        const WRITEABLE = 0x4;
    }
}

bitflags! {
    pub struct VBEDirectColorAttributes: u8 {
        const PROGRAMMABLE = 0x1;       // The color ramp of the DAC is programmable.
        const RESERVED_USABLE = 0x2;    // The bits of the 'reserved' field are usable by the application.
    }
}

#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(u8)]
pub enum VBEMemoryModel {
    Text = 0x00,
    CGAGraphics = 0x01,
    HerculesGraphics = 0x02,
    Planar = 0x03,
    PackedPixel = 0x04,
    Unchained = 0x05,
    DirectColor = 0x06,
    YUV = 0x07
}<|endoftext|>


<commit_before>#![macro_use]
use super::Core;
macro_rules! ir_dx {
	($e:ident) => (($e.ir >> 9 & 7) as usize);
}
macro_rules! ir_dy {
	($e:ident) => (($e.ir & 7) as usize);
}
macro_rules! ir_ax {
	($e:ident) => (8+($e.ir >> 9 & 7) as usize);
}
macro_rules! ir_ay {
	($e:ident) => (8+($e.ir & 7) as usize);
}
macro_rules! dx {
	($e:ident) => ($e.dar[ir_dx!($e)]);
}
macro_rules! dy {
	($e:ident) => ($e.dar[ir_dy!($e)]);
}
macro_rules! ax {
	($e:ident) => ($e.dar[ir_ax!($e)]);
}
macro_rules! ay {
	($e:ident) => ($e.dar[ir_ay!($e)]);
}
macro_rules! mask_out_above_8 {
	($e:expr) => ($e & 0xff)
}
macro_rules! mask_out_below_8 {
	($e:expr) => ($e & !0xff)
}
macro_rules! low_nibble {
	($e:expr) => ($e & 0x0f);
}
macro_rules! high_nibble {
	($e:expr) => ($e & 0xf0);
}
macro_rules! true1 {
	($e:expr) => (if $e {1} else {0})
}
macro_rules! not1 {
	($e:expr) => (true1!($e == 0))
}

pub mod fake {
	use super::super::Core;

	pub fn set_d0(core: &mut Core) {
		core.dar[0] = 0xabcd;
	}

	pub fn set_d1(core: &mut Core) {
		core.dar[1] = 0xbcde;
	}

	pub fn set_dx(core: &mut Core) {
		dx!(core) = 0xcdef;
	}

	use super::super::InstructionSet;
	use super::illegal;
	const SET_DX_0: usize = 0b0100_0000_0000_0000;

	pub fn instruction_set() -> InstructionSet {
		// Covers all possible IR values (64k entries)
		let mut handler: InstructionSet = Vec::with_capacity(0x10000);
		for _ in 0..0x10000 { handler.push(illegal); }
		handler[0xA] = set_d0;
		handler[0xB] = set_d1;
		for i in 0..8 {
			let opcode = SET_DX_0 | (i << 9);
			// println!("{:x}", opcode);
			handler[opcode] = set_dx;
		}
		handler
	}
}

pub fn illegal(core: &mut Core) {
	panic!("Illegal instruction {:04x} at {:08x}", core.ir, core.pc-2);
}

use std::num::Wrapping;

pub fn abcd_8_common(core: &mut Core, dst: u32, src: u32) -> u32 {
	let mut res = low_nibble!(src) + low_nibble!(dst) + core.x_flag_as_1();

	// m68ki_cpu.v_flag = ~res;
	core.v_flag = !res;

	// if(res > 9)
	//  res += 6;
	if res > 9 {
		res += 6;
	}
	// res += ((src) & 0xf0) + ((dst) & 0xf0);
	res += high_nibble!(src) + high_nibble!(dst);
	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = (res > 0x99) << 8;
	core.c_flag = true1!(res > 0x99) << 8;
	core.x_flag = core.c_flag;

	if core.c_flag > 0 {
		res = (Wrapping(res) - Wrapping(0xa0)).0;
	}

	// m68ki_cpu.v_flag &= res;
	// m68ki_cpu.n_flag = (res);
	core.v_flag &= res;
	core.n_flag = res;

	// res = ((res) & 0xff);
	// m68ki_cpu.not_z_flag |= res;
	res = mask_out_above_8!(res);
	core.not_z_flag |= res;
	res
}

// All instructions are ported from https://github.com/kstenerud/Musashi
// First real instruction
pub fn abcd_8_rr(core: &mut Core) {
	// unsigned int* r_dst = &(m68ki_cpu.dar[(m68ki_cpu.ir >> 9) & 7]);
	// unsigned int src = (m68ki_cpu.dar[m68ki_cpu.ir & 7]);
	// unsigned int dst = *r_dst;
	// unsigned int res = ((src) & 0x0f) + ((dst) & 0x0f) + ((m68ki_cpu.x_flag>>8)&1);
	let dst = dx!(core);
	let src = dy!(core);
	let res = abcd_8_common(core, dst, src);
	// *r_dst = ((*r_dst) & ~0xff) | res;
	dx!(core) = mask_out_below_8!(dst) | res;
}

use ram::{AddressBus, SUPERVISOR_DATA, USER_DATA};
fn ea_predecrement_8(core: &mut Core, reg_ndx: usize) -> u32 {
	// pre-decrement
	core.dar[reg_ndx] -= match reg_ndx {
		15 => 2, // A7 is kept even
		 _ => 1
	};
	core.dar[reg_ndx]
}
fn ea_ay_pd_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	ea_predecrement_8(core, reg_ndx)
}
fn ea_ax_pd_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ax!(core);
	ea_predecrement_8(core, reg_ndx)
}
fn oper_ay_pd_8(core: &mut Core) -> u32 {
	let ea = ea_ay_pd_8(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
fn oper_ax_pd_8(core: &mut Core) -> (u32, u32) {
	let ea = ea_ax_pd_8(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	(core.mem.read_byte(address_space, ea), ea)
}

// Second real instruction
pub fn abcd_8_mm(core: &mut Core) {
	// unsigned int src = OPER_AY_PD_8();
	let src = oper_ay_pd_8(core);
	// unsigned int ea = (--((m68ki_cpu.dar+8)[(m68ki_cpu.ir >> 9) & 7]));
	// unsigned int dst = m68ki_read_8_fc (ea, m68ki_cpu.s_flag | m68ki_address_space);
	let (dst, ea) = oper_ax_pd_8(core);

	let res = abcd_8_common(core, dst, src);

	// m68ki_write_8_fc (ea, m68ki_cpu.s_flag | 1, res);		*/
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.write_byte(address_space, ea, res);
}

use super::Handler;
#[allow(dead_code)]
struct OpcodeHandler {
	mask: u32,
	matching: u32,
	name: String,
	handler: Handler
}

use super::InstructionSet;
macro_rules! op_entry {
    ($mask:expr, $matching:expr, $handler:ident) => (OpcodeHandler { mask: $mask, matching: $matching, handler: $handler, name: stringify!($handler).to_string() })
}
pub const MASK_OUT_X_Y: u32 = 0b1111000111111000; // masks out X and Y register bits (????xxx??????yyy)
pub const OP_ABCD_8_RR: u32 = 0xc100;
pub const OP_ABCD_8_MM: u32 = 0xc108;
pub fn instruction_set() -> InstructionSet {
	// Covers all possible IR values (64k entries)
	let mut handler: InstructionSet = Vec::with_capacity(0x10000);
	for _ in 0..0x10000 { handler.push(illegal); }
	//let handler = [illegal].iter().cycle().take(0x10000).collect::<InstructionSet>();
	// (0..0x10000).map(|_| illegal).collect::<InstructionSet>();
	// the optable contains opcode mask, matching mask and the corresponding handler + name
	let optable = vec![
		op_entry!(MASK_OUT_X_Y, OP_ABCD_8_RR, abcd_8_rr),
		op_entry!(MASK_OUT_X_Y, OP_ABCD_8_MM, abcd_8_mm),
	];
	for op in optable {
		for opcode in 0..0x10000 {
			if (opcode & op.mask) == op.matching {
				// println!("{:16b}: {}", opcode, op.name);
				handler[opcode as usize] = op.handler;
			}
		}
	}
	handler
}

#[cfg(test)]
mod tests {
	use super::super::Core;
	use super::{oper_ax_pd_8, oper_ay_pd_8};
	use ram::{AddressBus, SUPERVISOR_DATA};

	#[test]
	fn low_nibble() {
		assert_eq!(0x0a, low_nibble!(0xba));
	}
	#[test]
	fn high_nibble() {
		assert_eq!(0xb0, high_nibble!(0xba));
	}
	#[test]
	fn mask_out_below_8() {
		assert_eq!(0x2bcdef00, mask_out_below_8!(0x2bcdef73));
	}
	#[test]
	fn mask_out_above_8() {
		assert_eq!(0xf1, mask_out_above_8!(0x2bcdeff1));
	}
	#[test]
	fn dx_and_dy() {
		let mut core = Core::new(0x40);
		core.dar[0] = 0x00;
		core.dar[1] = 0x11;
		core.dar[2] = 0x22;
		core.dar[3] = 0x33;
		core.dar[4] = 0x44;
		core.dar[5] = 0x55;
		core.dar[6] = 0x66;
		core.dar[7] = 0x77;

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		assert_eq!(0x22, dy!(core));
		assert_eq!(0x44, dx!(core));

		core.ir = 0b1111_1011_1111_1110; // X=5, Y=6
		assert_eq!(0x66, dy!(core));
		assert_eq!(0x55, dx!(core));
	}
	#[test]
	fn predecrement_ax() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}
		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;

		assert_eq!(512+4*4, core.dar[8+4]);
		let (dst, ea) = oper_ax_pd_8(core);
		assert_eq!(0x44, dst);
		assert_eq!(512+4*4-1, core.dar[8+4]);
		assert_eq!(512+4*4-1, ea);

		core.ir = 0b1111_1111_1111_1111; // X=7, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		let (dst, ea) = oper_ax_pd_8(core);
		assert_eq!(0x77, dst);
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
		assert_eq!(512+4*7-2, ea);
	}
	#[test]
	fn predecrement_ay() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;
		assert_eq!(512+4*2, core.dar[8+2]);
		assert_eq!(0x22, oper_ay_pd_8(core));
		assert_eq!(512+4*2-1, core.dar[8+2]);

		core.ir = 0b1111_1011_1111_1111; // X=5, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		assert_eq!(0x77, oper_ay_pd_8(core));
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
	}
}
<commit_msg>Make ea_predecrement_8 wrap around zero<commit_after>#![macro_use]
use super::Core;
macro_rules! ir_dx {
	($e:ident) => (($e.ir >> 9 & 7) as usize);
}
macro_rules! ir_dy {
	($e:ident) => (($e.ir & 7) as usize);
}
macro_rules! ir_ax {
	($e:ident) => (8+($e.ir >> 9 & 7) as usize);
}
macro_rules! ir_ay {
	($e:ident) => (8+($e.ir & 7) as usize);
}
macro_rules! dx {
	($e:ident) => ($e.dar[ir_dx!($e)]);
}
macro_rules! dy {
	($e:ident) => ($e.dar[ir_dy!($e)]);
}
macro_rules! ax {
	($e:ident) => ($e.dar[ir_ax!($e)]);
}
macro_rules! ay {
	($e:ident) => ($e.dar[ir_ay!($e)]);
}
macro_rules! mask_out_above_8 {
	($e:expr) => ($e & 0xff)
}
macro_rules! mask_out_below_8 {
	($e:expr) => ($e & !0xff)
}
macro_rules! low_nibble {
	($e:expr) => ($e & 0x0f);
}
macro_rules! high_nibble {
	($e:expr) => ($e & 0xf0);
}
macro_rules! true1 {
	($e:expr) => (if $e {1} else {0})
}
macro_rules! not1 {
	($e:expr) => (true1!($e == 0))
}

pub mod fake {
	use super::super::Core;

	pub fn set_d0(core: &mut Core) {
		core.dar[0] = 0xabcd;
	}

	pub fn set_d1(core: &mut Core) {
		core.dar[1] = 0xbcde;
	}

	pub fn set_dx(core: &mut Core) {
		dx!(core) = 0xcdef;
	}

	use super::super::InstructionSet;
	use super::illegal;
	const SET_DX_0: usize = 0b0100_0000_0000_0000;

	pub fn instruction_set() -> InstructionSet {
		// Covers all possible IR values (64k entries)
		let mut handler: InstructionSet = Vec::with_capacity(0x10000);
		for _ in 0..0x10000 { handler.push(illegal); }
		handler[0xA] = set_d0;
		handler[0xB] = set_d1;
		for i in 0..8 {
			let opcode = SET_DX_0 | (i << 9);
			// println!("{:x}", opcode);
			handler[opcode] = set_dx;
		}
		handler
	}
}

pub fn illegal(core: &mut Core) {
	panic!("Illegal instruction {:04x} at {:08x}", core.ir, core.pc-2);
}

use std::num::Wrapping;

pub fn abcd_8_common(core: &mut Core, dst: u32, src: u32) -> u32 {
	let mut res = low_nibble!(src) + low_nibble!(dst) + core.x_flag_as_1();

	// m68ki_cpu.v_flag = ~res;
	core.v_flag = !res;

	// if(res > 9)
	//  res += 6;
	if res > 9 {
		res += 6;
	}
	// res += ((src) & 0xf0) + ((dst) & 0xf0);
	res += high_nibble!(src) + high_nibble!(dst);
	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = (res > 0x99) << 8;
	core.c_flag = true1!(res > 0x99) << 8;
	core.x_flag = core.c_flag;

	if core.c_flag > 0 {
		res = (Wrapping(res) - Wrapping(0xa0)).0;
	}

	// m68ki_cpu.v_flag &= res;
	// m68ki_cpu.n_flag = (res);
	core.v_flag &= res;
	core.n_flag = res;

	// res = ((res) & 0xff);
	// m68ki_cpu.not_z_flag |= res;
	res = mask_out_above_8!(res);
	core.not_z_flag |= res;
	res
}

// All instructions are ported from https://github.com/kstenerud/Musashi
// First real instruction
pub fn abcd_8_rr(core: &mut Core) {
	// unsigned int* r_dst = &(m68ki_cpu.dar[(m68ki_cpu.ir >> 9) & 7]);
	// unsigned int src = (m68ki_cpu.dar[m68ki_cpu.ir & 7]);
	// unsigned int dst = *r_dst;
	// unsigned int res = ((src) & 0x0f) + ((dst) & 0x0f) + ((m68ki_cpu.x_flag>>8)&1);
	let dst = dx!(core);
	let src = dy!(core);
	let res = abcd_8_common(core, dst, src);
	// *r_dst = ((*r_dst) & ~0xff) | res;
	dx!(core) = mask_out_below_8!(dst) | res;
}

use ram::{AddressBus, SUPERVISOR_DATA, USER_DATA};
fn ea_predecrement_8(core: &mut Core, reg_ndx: usize) -> u32 {
	// pre-decrement
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) - match reg_ndx {
		15 => Wrapping(2), // A7 is kept even
		 _ => Wrapping(1)
	}).0;
	core.dar[reg_ndx]
}
fn ea_ay_pd_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	ea_predecrement_8(core, reg_ndx)
}
fn ea_ax_pd_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ax!(core);
	ea_predecrement_8(core, reg_ndx)
}
fn oper_ay_pd_8(core: &mut Core) -> u32 {
	let ea = ea_ay_pd_8(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
fn oper_ax_pd_8(core: &mut Core) -> (u32, u32) {
	let ea = ea_ax_pd_8(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	(core.mem.read_byte(address_space, ea), ea)
}

// Second real instruction
pub fn abcd_8_mm(core: &mut Core) {
	// unsigned int src = OPER_AY_PD_8();
	let src = oper_ay_pd_8(core);
	// unsigned int ea = (--((m68ki_cpu.dar+8)[(m68ki_cpu.ir >> 9) & 7]));
	// unsigned int dst = m68ki_read_8_fc (ea, m68ki_cpu.s_flag | m68ki_address_space);
	let (dst, ea) = oper_ax_pd_8(core);

	let res = abcd_8_common(core, dst, src);

	// m68ki_write_8_fc (ea, m68ki_cpu.s_flag | 1, res);		*/
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.write_byte(address_space, ea, res);
}

use super::Handler;
#[allow(dead_code)]
struct OpcodeHandler {
	mask: u32,
	matching: u32,
	name: String,
	handler: Handler
}

use super::InstructionSet;
macro_rules! op_entry {
    ($mask:expr, $matching:expr, $handler:ident) => (OpcodeHandler { mask: $mask, matching: $matching, handler: $handler, name: stringify!($handler).to_string() })
}
pub const MASK_OUT_X_Y: u32 = 0b1111000111111000; // masks out X and Y register bits (????xxx??????yyy)
pub const OP_ABCD_8_RR: u32 = 0xc100;
pub const OP_ABCD_8_MM: u32 = 0xc108;
pub fn instruction_set() -> InstructionSet {
	// Covers all possible IR values (64k entries)
	let mut handler: InstructionSet = Vec::with_capacity(0x10000);
	for _ in 0..0x10000 { handler.push(illegal); }
	//let handler = [illegal].iter().cycle().take(0x10000).collect::<InstructionSet>();
	// (0..0x10000).map(|_| illegal).collect::<InstructionSet>();
	// the optable contains opcode mask, matching mask and the corresponding handler + name
	let optable = vec![
		op_entry!(MASK_OUT_X_Y, OP_ABCD_8_RR, abcd_8_rr),
		op_entry!(MASK_OUT_X_Y, OP_ABCD_8_MM, abcd_8_mm),
	];
	for op in optable {
		for opcode in 0..0x10000 {
			if (opcode & op.mask) == op.matching {
				// println!("{:16b}: {}", opcode, op.name);
				handler[opcode as usize] = op.handler;
			}
		}
	}
	handler
}

#[cfg(test)]
mod tests {
	use super::super::Core;
	use super::{oper_ax_pd_8, oper_ay_pd_8};
	use ram::{AddressBus, SUPERVISOR_DATA};

	#[test]
	fn low_nibble() {
		assert_eq!(0x0a, low_nibble!(0xba));
	}
	#[test]
	fn high_nibble() {
		assert_eq!(0xb0, high_nibble!(0xba));
	}
	#[test]
	fn mask_out_below_8() {
		assert_eq!(0x2bcdef00, mask_out_below_8!(0x2bcdef73));
	}
	#[test]
	fn mask_out_above_8() {
		assert_eq!(0xf1, mask_out_above_8!(0x2bcdeff1));
	}
	#[test]
	fn dx_and_dy() {
		let mut core = Core::new(0x40);
		core.dar[0] = 0x00;
		core.dar[1] = 0x11;
		core.dar[2] = 0x22;
		core.dar[3] = 0x33;
		core.dar[4] = 0x44;
		core.dar[5] = 0x55;
		core.dar[6] = 0x66;
		core.dar[7] = 0x77;

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		assert_eq!(0x22, dy!(core));
		assert_eq!(0x44, dx!(core));

		core.ir = 0b1111_1011_1111_1110; // X=5, Y=6
		assert_eq!(0x66, dy!(core));
		assert_eq!(0x55, dx!(core));
	}
	#[test]
	fn predecrement_ax() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}
		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;

		assert_eq!(512+4*4, core.dar[8+4]);
		let (dst, ea) = oper_ax_pd_8(core);
		assert_eq!(0x44, dst);
		assert_eq!(512+4*4-1, core.dar[8+4]);
		assert_eq!(512+4*4-1, ea);

		core.ir = 0b1111_1111_1111_1111; // X=7, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		let (dst, ea) = oper_ax_pd_8(core);
		assert_eq!(0x77, dst);
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
		assert_eq!(512+4*7-2, ea);
	}
	#[test]
	fn predecrement_ay() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;
		assert_eq!(512+4*2, core.dar[8+2]);
		assert_eq!(0x22, oper_ay_pd_8(core));
		assert_eq!(512+4*2-1, core.dar[8+2]);

		core.ir = 0b1111_1011_1111_1111; // X=5, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		assert_eq!(0x77, oper_ay_pd_8(core));
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
	}
}
<|endoftext|>


<commit_before>extern crate pink_spider;
extern crate feed_rs;
extern crate hyper;
extern crate chrono;
extern crate serde_json;

use std::time::Instant;
use chrono::Duration;
use pink_spider::model::{Model, Feed};

pub fn main() {
    println!("Start crawling...");
    let now = Instant::now();
    let mut page  = 0;
    let per_page  = 10;
    let mut feeds = Feed::find(0, 0, None);
    let total = feeds.total;
    let mut index = 0;
    println!("{} feeds", total);
    while feeds.page * feeds.per_page < total {
        feeds = Feed::find(page, per_page, None);
        for mut feed in feeds.items {
            println!("[{}/{}] Crawl {} ", index, total, feed.url);
            match feed.crawl() {
                Ok(entries) => {
                    println!("Found {} entries", entries.len());
                    println!("Found {} tracks",
                             entries.iter().fold(0, |sum, e| sum + e.tracks.len()));
                    println!("Found {} albums",
                             entries.iter().fold(0, |sum, e| sum + e.albums.len()));
                    println!("Found {} playlists",
                             entries.iter().fold(0, |sum, e| sum + e.playlists.len()));
                },
                Err(e) => {
                    println!("Failed to crawl {}: {:?}", feed.url, e);
                },
            }
            index += 1;
        }
        page += 1;
    }
    println!("Complete crawling... total {} ms",
             Duration::from_std(now.elapsed()).unwrap().num_milliseconds());
}
<commit_msg>Add prefix to rss_crawler<commit_after>extern crate pink_spider;
extern crate feed_rs;
extern crate hyper;
extern crate chrono;
extern crate serde_json;

use std::time::Instant;
use chrono::Duration;
use pink_spider::model::{Model, Feed};

pub fn main() {
    println!("[rss_cralwer] Start crawling...");
    let now = Instant::now();
    let mut page  = 0;
    let per_page  = 10;
    let mut feeds = Feed::find(0, 0, None);
    let total = feeds.total;
    let mut index = 0;
    println!("[rss_cralwer] {} feeds", total);
    while feeds.page * feeds.per_page < total {
        feeds = Feed::find(page, per_page, None);
        for mut feed in feeds.items {
            println!("[rss_cralwer][{}/{}] Crawl {} ", index, total, feed.url);
            match feed.crawl() {
                Ok(entries) => {
                    println!("[rss_cralwer] Found {} entries", entries.len());
                    println!("[rss_cralwer] Found {} tracks",
                             entries.iter().fold(0, |sum, e| sum + e.tracks.len()));
                    println!("[rss_cralwer] Found {} albums",
                             entries.iter().fold(0, |sum, e| sum + e.albums.len()));
                    println!("[rss_cralwer] Found {} playlists",
                             entries.iter().fold(0, |sum, e| sum + e.playlists.len()));
                },
                Err(e) => {
                    println!("[rss_cralwer] Failed to crawl {}: {:?}", feed.url, e);
                },
            }
            index += 1;
        }
        page += 1;
    }
    println!("[rss_cralwer] Complete crawling... total {} ms",
             Duration::from_std(now.elapsed()).unwrap().num_milliseconds());
}
<|endoftext|>