<commit_before>use std::fs;
use std::io::prelude::*;
use std::path;
use std::process;
use std::sync::mpsc::channel;
use std::thread;

use clap;
use cobalt::cobalt_model::files;
use cobalt::cobalt_model;
use error_chain::ChainedError;
use hyper;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri;
use notify::{Watcher, RecursiveMode, raw_watcher};

use args;
use build;
use error::*;

pub fn serve_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("serve")
        .about("build, serve, and watch the project at the source dir")
        .args(&args::get_config_args())
        .arg(clap::Arg::with_name("port")
                 .short("P")
                 .long("port")
                 .value_name("INT")
                 .help("Port to serve from")
                 .default_value("3000")
                 .takes_value(true))
        .arg(clap::Arg::with_name("no-watch")
                 .long("no-watch")
                 .help("Disable rebuilding on change")
                 .conflicts_with("drafts")
                 .takes_value(false))
}

pub fn serve_command(matches: &clap::ArgMatches) -> Result<()> {
    let port = matches.value_of("port").unwrap().to_string();
    let ip = format!("127.0.0.1:{}", port);

    let mut config = args::get_config(matches)?;
    debug!("Overriding config `site.base_url` with `{}`", ip);
    config.site.base_url = Some(ip.clone());
    let config = config.build()?;
    let dest = path::Path::new(&config.destination).to_owned();

    build::build(&config)?;

    if matches.is_present("no-watch") {
        serve(&dest, &ip)?;
    } else {
        thread::spawn(move || if serve(&dest, &ip).is_err() {
                          process::exit(1)
                      });

        watch(config)?;
    }
    Ok(())
}

fn static_file_handler(dest: &path::Path, req: Request, mut res: Response) -> Result<()> {
    // grab the requested path
    let mut req_path = match req.uri {
        RequestUri::AbsolutePath(p) => p,
        _ => {
            // return a 400 and exit from this request
            *res.status_mut() = hyper::status::StatusCode::BadRequest;
            let body = b"<h1> <center> 400: Bad request </center> </h1>";
            res.send(body)?;
            return Ok(());
        }
    };

    // strip off any querystrings so path.is_file() matches
    // and doesn't stick index.html on the end of the path
    // (querystrings often used for cachebusting)
    if let Some(position) = req_path.rfind('?') {
        req_path.truncate(position);
    }

    // find the path of the file in the local system
    // (this gets rid of the '/' in `p`, so the `join()` will not replace the
    // path)
    let path = dest.to_path_buf().join(&req_path[1..]);

    let serve_path = if path.is_file() {
        // try to point the serve path to `path` if it corresponds to a file
        path
    } else {
        // try to point the serve path into a "index.html" file in the requested
        // path
        path.join("index.html")
    };

    // if the request points to a file and it exists, read and serve it
    if serve_path.exists() {
        let mut file = fs::File::open(serve_path)?;

        // buffer to store the file
        let mut buffer: Vec<u8> = vec![];

        file.read_to_end(&mut buffer)?;

        res.send(&buffer)?;
    } else {
        // return a 404 status
        *res.status_mut() = hyper::status::StatusCode::NotFound;

        // write a simple body for the 404 page
        let body = b"<h1> <center> 404: Page not found </center> </h1>";

        res.send(body)?;
    }

    Ok(())
}

fn serve(dest: &path::Path, ip: &str) -> Result<()> {
    info!("Serving {:?} through static file server", dest);

    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");

    // attempts to create a server
    let http_server = match Server::http(&*ip) {
        Ok(server) => server,
        Err(e) => {
            error!("{}", e);
            return Err(e.into());
        }
    };

    // need a clone because of closure's lifetime
    let dest_clone = dest.to_owned();

    // bind the handle function and start serving
    if let Err(e) = http_server.handle(move |req: Request, res: Response| if let Err(e) =
        static_file_handler(&dest_clone, req, res) {
        error!("{}", e);
        process::exit(1);
    }) {
        error!("{}", e);
        return Err(e.into());
    };

    Ok(())
}

fn watch(config: cobalt_model::Config) -> Result<()> {
    // canonicalize is to ensure there is no question that `watcher`s paths come back safe for
    // Files::includes_file
    let source = path::Path::new(&config.source)
        .canonicalize()
        .chain_err(|| "Failed in processing source")?;

    // Be as broad as possible in what can cause a rebuild to
    // ensure we don't miss anything (normal file walks will miss
    // `_layouts`, etc).
    let mut site_files = files::FilesBuilder::new(&source)?;
    site_files.ignore_hidden(false)?;
    for line in &config.ignore {
        site_files.add_ignore(line.as_str())?;
    }
    let site_files = site_files.build()?;

    let (tx, rx) = channel();
    let mut watcher = raw_watcher(tx).chain_err(|| "Notify error")?;
    watcher
        .watch(&source, RecursiveMode::Recursive)
        .chain_err(|| "Notify error")?;
    info!("Watching {:?} for changes", &config.source);

    loop {
        let event = rx.recv().chain_err(|| "Notify error")?;
        let rebuild = if let Some(ref event_path) = event.path {
            if site_files.includes_file(event_path) {
                debug!("Page changed {:?}", event);
                true
            } else {
                trace!("Ignored file changed {:?}", event);
                false
            }
        } else {
            trace!("Assuming change {:?} is relevant", event);
            true
        };
        if rebuild {
            let result = build::build(&config);
            if let Err(fail) = result {
                error!("build failed\n{}", fail.display_chain());
            }
        }
    }
}
<commit_msg>perf(serve): Reduce duplicate rebuilds<commit_after>use std::fs;
use std::io::prelude::*;
use std::path;
use std::process;
use std::sync::mpsc::channel;
use std::thread;
use std::time;

use clap;
use cobalt::cobalt_model::files;
use cobalt::cobalt_model;
use error_chain::ChainedError;
use hyper;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri;
use notify;
use notify::Watcher;

use args;
use build;
use error::*;

pub fn serve_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("serve")
        .about("build, serve, and watch the project at the source dir")
        .args(&args::get_config_args())
        .arg(clap::Arg::with_name("port")
                 .short("P")
                 .long("port")
                 .value_name("INT")
                 .help("Port to serve from")
                 .default_value("3000")
                 .takes_value(true))
        .arg(clap::Arg::with_name("no-watch")
                 .long("no-watch")
                 .help("Disable rebuilding on change")
                 .conflicts_with("drafts")
                 .takes_value(false))
}

pub fn serve_command(matches: &clap::ArgMatches) -> Result<()> {
    let port = matches.value_of("port").unwrap().to_string();
    let ip = format!("127.0.0.1:{}", port);

    let mut config = args::get_config(matches)?;
    debug!("Overriding config `site.base_url` with `{}`", ip);
    config.site.base_url = Some(ip.clone());
    let config = config.build()?;
    let dest = path::Path::new(&config.destination).to_owned();

    build::build(&config)?;

    if matches.is_present("no-watch") {
        serve(&dest, &ip)?;
    } else {
        thread::spawn(move || if serve(&dest, &ip).is_err() {
                          process::exit(1)
                      });

        watch(config)?;
    }
    Ok(())
}

fn static_file_handler(dest: &path::Path, req: Request, mut res: Response) -> Result<()> {
    // grab the requested path
    let mut req_path = match req.uri {
        RequestUri::AbsolutePath(p) => p,
        _ => {
            // return a 400 and exit from this request
            *res.status_mut() = hyper::status::StatusCode::BadRequest;
            let body = b"<h1> <center> 400: Bad request </center> </h1>";
            res.send(body)?;
            return Ok(());
        }
    };

    // strip off any querystrings so path.is_file() matches
    // and doesn't stick index.html on the end of the path
    // (querystrings often used for cachebusting)
    if let Some(position) = req_path.rfind('?') {
        req_path.truncate(position);
    }

    // find the path of the file in the local system
    // (this gets rid of the '/' in `p`, so the `join()` will not replace the
    // path)
    let path = dest.to_path_buf().join(&req_path[1..]);

    let serve_path = if path.is_file() {
        // try to point the serve path to `path` if it corresponds to a file
        path
    } else {
        // try to point the serve path into a "index.html" file in the requested
        // path
        path.join("index.html")
    };

    // if the request points to a file and it exists, read and serve it
    if serve_path.exists() {
        let mut file = fs::File::open(serve_path)?;

        // buffer to store the file
        let mut buffer: Vec<u8> = vec![];

        file.read_to_end(&mut buffer)?;

        res.send(&buffer)?;
    } else {
        // return a 404 status
        *res.status_mut() = hyper::status::StatusCode::NotFound;

        // write a simple body for the 404 page
        let body = b"<h1> <center> 404: Page not found </center> </h1>";

        res.send(body)?;
    }

    Ok(())
}

fn serve(dest: &path::Path, ip: &str) -> Result<()> {
    info!("Serving {:?} through static file server", dest);

    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");

    // attempts to create a server
    let http_server = match Server::http(&*ip) {
        Ok(server) => server,
        Err(e) => {
            error!("{}", e);
            return Err(e.into());
        }
    };

    // need a clone because of closure's lifetime
    let dest_clone = dest.to_owned();

    // bind the handle function and start serving
    if let Err(e) = http_server.handle(move |req: Request, res: Response| if let Err(e) =
        static_file_handler(&dest_clone, req, res) {
        error!("{}", e);
        process::exit(1);
    }) {
        error!("{}", e);
        return Err(e.into());
    };

    Ok(())
}

fn watch(config: cobalt_model::Config) -> Result<()> {
    // canonicalize is to ensure there is no question that `watcher`s paths come back safe for
    // Files::includes_file
    let source = path::Path::new(&config.source)
        .canonicalize()
        .chain_err(|| "Failed in processing source")?;

    // Be as broad as possible in what can cause a rebuild to
    // ensure we don't miss anything (normal file walks will miss
    // `_layouts`, etc).
    let mut site_files = files::FilesBuilder::new(&source)?;
    site_files.ignore_hidden(false)?;
    for line in &config.ignore {
        site_files.add_ignore(line.as_str())?;
    }
    let site_files = site_files.build()?;

    let (tx, rx) = channel();
    let mut watcher = notify::watcher(tx, time::Duration::from_secs(1))
        .chain_err(|| "Notify error")?;
    watcher
        .watch(&source, notify::RecursiveMode::Recursive)
        .chain_err(|| "Notify error")?;
    info!("Watching {:?} for changes", &config.source);

    loop {
        let event = rx.recv().chain_err(|| "Notify error")?;
        let event_path = match event {
            notify::DebouncedEvent::Create(ref path) |
            notify::DebouncedEvent::NoticeWrite(ref path) |
            notify::DebouncedEvent::Write(ref path) |
            notify::DebouncedEvent::NoticeRemove(ref path) |
            notify::DebouncedEvent::Remove(ref path) => Some(path),
            notify::DebouncedEvent::Rename(_, ref to) => Some(to),
            _ => None,
        };
        let rebuild = if let Some(event_path) = event_path {
            if site_files.includes_file(event_path) {
                debug!("Page changed {:?}", event);
                true
            } else {
                trace!("Ignored file changed {:?}", event);
                false
            }
        } else {
            trace!("Assuming change {:?} is relevant", event);
            true
        };
        if rebuild {
            let result = build::build(&config);
            if let Err(fail) = result {
                error!("build failed\n{}", fail.display_chain());
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate dcpu16;
extern crate getopts;

use std::env;
use std::fs::File;
use std::io::Read;
use std::error::Error;
use std::path::Path;
use getopts::Options;
use dcpu16::dcpu;
use dcpu16::disassembler;

fn main() {
    let mut opts = Options::new();
    let args: Vec<String> = env::args().collect();
    opts.optflag("m", "no-color", "no color");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m },
        Err(why) => {
            println!("{}", why);
            return;
        },
    };

    if matches.free.len() != 1 {
        println!("Please input file");
        return;
    }
    let color = !matches.opt_present("m");
    let ref filename = matches.free[0];

    let mut cpu = dcpu::DCPU::new();

    let path = Path::new(filename);
    let mut file = match File::open(&path) {
        Err(why) => {
            println!("Could not open file {}: {}", path.display(), why.description());
            return;
        },
        Ok(f) => f,
    };

    let mut i = 0usize;
    let mut buffer: Vec<u8> = Vec::new();
    let res = file.read_to_end(&mut buffer);
    match res {
        Ok(_) => {
            let mut j = 0;
            let mut sig = 0u16;
            for v in buffer {
                if j % 2 == 0 {
                    sig = v as u16;
                } else {
                    cpu.mem[i] = (sig << 8) + (v as u16);
                    i += 1;
                }

                j += 1;
            }
        }
        Err(why) => {
            println!("Could not read contents of file: {}", why);
            return;
        },
    }

    loop {
        let (offset, s) = disassembler::disassemble_instruction(&cpu, color);
        cpu.pc += offset;
        if cpu.pc as usize > i {
            break;
        }
        println!("{}", s);
    }
}
<commit_msg>Print partial matches in disassembler.<commit_after>extern crate dcpu16;
extern crate getopts;

use std::env;
use std::fs::File;
use std::io::Read;
use std::error::Error;
use std::path::Path;
use getopts::Options;
use dcpu16::dcpu;
use dcpu16::disassembler;

fn main() {
    let mut opts = Options::new();
    let args: Vec<String> = env::args().collect();
    opts.optflag("m", "no-color", "no color");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m },
        Err(why) => {
            println!("{}", why);
            return;
        },
    };

    if matches.free.len() != 1 {
        println!("Please input file");
        return;
    }
    let color = !matches.opt_present("m");
    let ref filename = matches.free[0];

    let mut cpu = dcpu::DCPU::new();

    let path = Path::new(filename);
    let mut file = match File::open(&path) {
        Err(why) => {
            println!("Could not open file {}: {}", path.display(), why.description());
            return;
        },
        Ok(f) => f,
    };

    let mut nwords = 0usize;
    let mut buffer: Vec<u8> = Vec::new();
    let res = file.read_to_end(&mut buffer);
    match res {
        Ok(_) => {
            let mut j = 0;
            let mut sig = 0u16;
            for v in buffer {
                if j % 2 == 0 {
                    sig = v as u16;
                } else {
                    cpu.mem[nwords] = (sig << 8) + (v as u16);
                    nwords += 1;
                }

                j += 1;
            }
        }
        Err(why) => {
            println!("Could not read contents of file: {}", why);
            return;
        },
    }

    loop {
        if cpu.pc as usize > nwords {
            break;
        }
        let (offset, s) = disassembler::disassemble_instruction(&cpu, color);
        cpu.pc += offset;
        println!("{}", s);
    }
}
<|endoftext|>


<commit_before>mod utils;

use clap::{App, Arg};

#[test]
fn issue_1076() {
    let mut app = App::new("myprog")
        .arg(
            Arg::new("GLOBAL_ARG")
                .long("global-arg")
                .about("Specifies something needed by the subcommands")
                .global(true)
                .takes_value(true)
                .default_value("default_value"),
        )
        .arg(
            Arg::new("GLOBAL_FLAG")
                .long("global-flag")
                .about("Specifies something needed by the subcommands")
                .takes_value(true)
                .multiple(true)
                .global(true),
        )
        .subcommand(App::new("outer").subcommand(App::new("inner")));
    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
}

#[test]
fn propagate_global_arg_in_subcommand_to_subsubcommand_1385() {
    let m1 = App::new("foo")
        .subcommand(
            App::new("sub1")
                .arg(Arg::new("arg1").long("arg1").takes_value(true).global(true))
                .subcommand(App::new("sub1a")),
        )
        .get_matches_from(&["foo", "sub1", "--arg1", "v1", "sub1a"]);
    assert_eq!(
        "v1",
        m1.subcommand_matches("sub1")
            .unwrap()
            .subcommand_matches("sub1a")
            .unwrap()
            .value_of("arg1")
            .unwrap()
    );
}

#[test]
fn propagate_global_arg_to_subcommand_in_subsubcommand_2053() {
    let m = App::new("opts")
        .arg(Arg::from("--global-flag").global(true))
        .arg(
            Arg::from("--global-str <global-str>")
                .required(false)
                .global(true),
        )
        .subcommand(
            App::new("test")
                .arg(Arg::from("--sub-flag").global(true))
                .arg(
                    Arg::from("--sub-str <sub-str>")
                        .required(false)
                        .global(true),
                )
                .subcommand(App::new("test")),
        )
        .get_matches_from(&[
            "app",
            "test",
            "test",
            "--global-flag",
            "--global-str",
            "hello",
            "--sub-flag",
            "--sub-str",
            "world",
        ]);
    assert_eq!(
        Some("world"),
        m.subcommand_matches("test").unwrap().value_of("sub-str")
    );
}
<commit_msg>Replicate the derive test for from_global<commit_after>mod utils;

use clap::{App, Arg};

#[test]
fn issue_1076() {
    let mut app = App::new("myprog")
        .arg(
            Arg::new("GLOBAL_ARG")
                .long("global-arg")
                .about("Specifies something needed by the subcommands")
                .global(true)
                .takes_value(true)
                .default_value("default_value"),
        )
        .arg(
            Arg::new("GLOBAL_FLAG")
                .long("global-flag")
                .about("Specifies something needed by the subcommands")
                .takes_value(true)
                .multiple(true)
                .global(true),
        )
        .subcommand(App::new("outer").subcommand(App::new("inner")));
    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
}

#[test]
fn propagate_global_arg_in_subcommand_to_subsubcommand_1385() {
    let m1 = App::new("foo")
        .subcommand(
            App::new("sub1")
                .arg(Arg::new("arg1").long("arg1").takes_value(true).global(true))
                .subcommand(App::new("sub1a")),
        )
        .get_matches_from(&["foo", "sub1", "--arg1", "v1", "sub1a"]);
    assert_eq!(
        "v1",
        m1.subcommand_matches("sub1")
            .unwrap()
            .subcommand_matches("sub1a")
            .unwrap()
            .value_of("arg1")
            .unwrap()
    );
}

#[test]
fn propagate_global_arg_to_subcommand_in_subsubcommand_2053() {
    let m = App::new("opts")
        .arg(Arg::from("--global-flag").global(true))
        .arg(
            Arg::from("--global-str <global-str>")
                .required(false)
                .global(true),
        )
        .subcommand(
            App::new("test")
                .arg(Arg::from("--sub-flag").global(true))
                .arg(
                    Arg::from("--sub-str <sub-str>")
                        .required(false)
                        .global(true),
                )
                .subcommand(App::new("test")),
        )
        .get_matches_from(&[
            "app",
            "test",
            "test",
            "--global-flag",
            "--global-str",
            "hello",
            "--sub-flag",
            "--sub-str",
            "world",
        ]);
    assert_eq!(
        Some("world"),
        m.subcommand_matches("test").unwrap().value_of("sub-str")
    );
}

#[test]
fn global_arg_available_in_subcommand() {
    let m = App::new("opt")
        .args(&[
            Arg::new("global").global(true).long("global"),
            Arg::new("not").global(false).long("not"),
        ])
        .subcommand(App::new("ping"))
        .get_matches_from(&["opt", "ping", "--global"]);

    assert!(m.is_present("global"));
    assert!(m.subcommand_matches("ping").unwrap().is_present("global"));
    assert!(!m.subcommand_matches("ping").unwrap().is_present("not"));
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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 texturegl::Texture;

use geom::matrix::{Matrix4, identity};
use geom::size::Size2D;
use geom::rect::Rect;
use geom::point::Point2D;
use platform::surface::{NativeSurfaceMethods, NativeSurface};
use std::cell::{RefCell, RefMut};
use std::num::Zero;
use std::rc::Rc;
use quadtree::{Quadtree, NodeStatus, Normal};

/// The amount of memory usage allowed per layer.
static MAX_TILE_MEMORY_PER_LAYER: uint = 10000000;

pub enum Format {
    ARGB32Format,
    RGB24Format
}

pub struct Layer<T> {
    pub children: RefCell<Vec<Rc<Layer<T>>>>,
    pub tiles: RefCell<Vec<Rc<TextureLayer>>>,
    pub quadtree: RefCell<Quadtree>,
    pub transform: RefCell<Matrix4<f32>>,
    pub origin: RefCell<Point2D<f32>>,
    tile_size: uint,
    pub extra_data: RefCell<T>,
}

impl<T> Layer<T> {
    pub fn new(page_size: Option<Size2D<f32>>, tile_size: uint, data: T) -> Layer<T> {
        Layer {
            children: RefCell::new(vec!()),
            tiles: RefCell::new(vec!()),
            quadtree: match page_size {
                None => {
                    RefCell::new(Quadtree::new(Size2D(tile_size, tile_size),
                                                   tile_size,
                                                   Some(MAX_TILE_MEMORY_PER_LAYER)))
                }
                Some(page_size) => {
                    RefCell::new(Quadtree::new(Size2D(page_size.width as uint, page_size.height as uint),
                                                   tile_size,
                                                   Some(MAX_TILE_MEMORY_PER_LAYER)))
                }
            },
            transform: RefCell::new(identity()),
            origin: RefCell::new(Zero::zero()),
            tile_size: tile_size,
            extra_data: RefCell::new(data),
        }
    }

    pub fn children<'a>(&'a self) -> RefMut<'a,Vec<Rc<Layer<T>>>> {
        self.children.borrow_mut()
    }

    pub fn add_child(this: Rc<Layer<T>>, new_child: Rc<Layer<T>>) {
        this.children().push(new_child);
    }

    pub fn tile_size(this: Rc<Layer<T>>) -> uint {
        this.tile_size
    }

    pub fn get_tile_rects_page(this: Rc<Layer<T>>, window: Rect<f32>, scale: f32) -> (Vec<BufferRequest>, Vec<Box<LayerBuffer>>) {
        this.quadtree.borrow_mut().get_tile_rects_page(window, scale)
    }

    pub fn set_status_page(this: Rc<Layer<T>>, rect: Rect<f32>, status: NodeStatus, include_border: bool) {
        this.quadtree.borrow_mut().set_status_page(rect, Normal, false); // Rect is unhidden
    }

    pub fn resize(this: Rc<Layer<T>>, new_size: Size2D<f32>) -> Vec<Box<LayerBuffer>> {
        this.quadtree.borrow_mut().resize(new_size.width as uint, new_size.height as uint)
    }

    pub fn do_for_all_tiles(this: Rc<Layer<T>>, f: |&Box<LayerBuffer>|) {
        this.quadtree.borrow_mut().do_for_all_tiles(f);
    }

    pub fn add_tile_pixel(this: Rc<Layer<T>>, tile: Box<LayerBuffer>) -> Vec<Box<LayerBuffer>> {
        this.quadtree.borrow_mut().add_tile_pixel(tile.screen_pos.origin.x,
                                                          tile.screen_pos.origin.y,
                                                          tile.resolution, tile)
    }

    pub fn collect_tiles(this: Rc<Layer<T>>) -> Vec<Box<LayerBuffer>> {
        this.quadtree.borrow_mut().collect_tiles()
    }
}

/// Whether a texture should be flipped.
#[deriving(PartialEq)]
pub enum Flip {
    /// The texture should not be flipped.
    NoFlip,
    /// The texture should be flipped vertically.
    VerticalFlip,
}

pub struct TextureLayer {
    /// A handle to the GPU texture.
    pub texture: Texture,
    /// The size of the texture in pixels.
    size: Size2D<uint>,
    /// Whether this texture is flipped vertically.
    pub flip: Flip,

    pub transform: Matrix4<f32>,
}

impl TextureLayer {
    pub fn new(texture: Texture, size: Size2D<uint>, flip: Flip, transform: Matrix4<f32>) -> TextureLayer {
        TextureLayer {
            texture: texture,
            size: size,
            flip: flip,
            transform: transform,
        }
    }
}

/// A request from the compositor to the renderer for tiles that need to be (re)displayed.
#[deriving(Clone)]
pub struct BufferRequest {
    // The rect in pixels that will be drawn to the screen
    pub screen_rect: Rect<uint>,

    // The rect in page coordinates that this tile represents
    pub page_rect: Rect<f32>,
}

impl BufferRequest {
    pub fn new(screen_rect: Rect<uint>, page_rect: Rect<f32>) -> BufferRequest {
        BufferRequest {
            screen_rect: screen_rect,
            page_rect: page_rect,
        }
    }
}

pub struct LayerBuffer {
    /// The native surface which can be shared between threads or processes. On Mac this is an
    /// `IOSurface`; on Linux this is an X Pixmap; on Android this is an `EGLImageKHR`.
    pub native_surface: NativeSurface,

    /// The rect in the containing RenderLayer that this represents.
    pub rect: Rect<f32>,

    /// The rect in pixels that will be drawn to the screen.
    pub screen_pos: Rect<uint>,

    /// The scale at which this tile is rendered
    pub resolution: f32,

    /// NB: stride is in pixels, like OpenGL GL_UNPACK_ROW_LENGTH.
    pub stride: uint,
}

/// A set of layer buffers. This is an atomic unit used to switch between the front and back
/// buffers.
pub struct LayerBufferSet {
    pub buffers: Vec<Box<LayerBuffer>>
}

impl LayerBufferSet {
    /// Notes all buffer surfaces will leak if not destroyed via a call to `destroy`.
    pub fn mark_will_leak(&mut self) {
        for buffer in self.buffers.mut_iter() {
            buffer.native_surface.mark_will_leak()
        }
    }
}
<commit_msg>No longer accept an Option for layer size<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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 texturegl::Texture;

use geom::matrix::{Matrix4, identity};
use geom::size::Size2D;
use geom::rect::Rect;
use geom::point::Point2D;
use platform::surface::{NativeSurfaceMethods, NativeSurface};
use std::cell::{RefCell, RefMut};
use std::num::Zero;
use std::rc::Rc;
use quadtree::{Quadtree, NodeStatus, Normal};

/// The amount of memory usage allowed per layer.
static MAX_TILE_MEMORY_PER_LAYER: uint = 10000000;

pub enum Format {
    ARGB32Format,
    RGB24Format
}

pub struct Layer<T> {
    pub children: RefCell<Vec<Rc<Layer<T>>>>,
    pub tiles: RefCell<Vec<Rc<TextureLayer>>>,
    pub quadtree: RefCell<Quadtree>,
    pub transform: RefCell<Matrix4<f32>>,
    pub origin: RefCell<Point2D<f32>>,
    tile_size: uint,
    pub extra_data: RefCell<T>,
}

impl<T> Layer<T> {
    pub fn new(page_size: Size2D<f32>, tile_size: uint, data: T) -> Layer<T> {
        Layer {
            children: RefCell::new(vec!()),
            tiles: RefCell::new(vec!()),
            quadtree: RefCell::new(Quadtree::new(Size2D(page_size.width as uint, page_size.height as uint),
                                                 tile_size, Some(MAX_TILE_MEMORY_PER_LAYER))),
            transform: RefCell::new(identity()),
            origin: RefCell::new(Zero::zero()),
            tile_size: tile_size,
            extra_data: RefCell::new(data),
        }
    }

    pub fn children<'a>(&'a self) -> RefMut<'a,Vec<Rc<Layer<T>>>> {
        self.children.borrow_mut()
    }

    pub fn add_child(this: Rc<Layer<T>>, new_child: Rc<Layer<T>>) {
        this.children().push(new_child);
    }

    pub fn tile_size(this: Rc<Layer<T>>) -> uint {
        this.tile_size
    }

    pub fn get_tile_rects_page(this: Rc<Layer<T>>, window: Rect<f32>, scale: f32) -> (Vec<BufferRequest>, Vec<Box<LayerBuffer>>) {
        this.quadtree.borrow_mut().get_tile_rects_page(window, scale)
    }

    pub fn set_status_page(this: Rc<Layer<T>>, rect: Rect<f32>, status: NodeStatus, include_border: bool) {
        this.quadtree.borrow_mut().set_status_page(rect, Normal, false); // Rect is unhidden
    }

    pub fn resize(this: Rc<Layer<T>>, new_size: Size2D<f32>) -> Vec<Box<LayerBuffer>> {
        this.quadtree.borrow_mut().resize(new_size.width as uint, new_size.height as uint)
    }

    pub fn do_for_all_tiles(this: Rc<Layer<T>>, f: |&Box<LayerBuffer>|) {
        this.quadtree.borrow_mut().do_for_all_tiles(f);
    }

    pub fn add_tile_pixel(this: Rc<Layer<T>>, tile: Box<LayerBuffer>) -> Vec<Box<LayerBuffer>> {
        this.quadtree.borrow_mut().add_tile_pixel(tile.screen_pos.origin.x,
                                                          tile.screen_pos.origin.y,
                                                          tile.resolution, tile)
    }

    pub fn collect_tiles(this: Rc<Layer<T>>) -> Vec<Box<LayerBuffer>> {
        this.quadtree.borrow_mut().collect_tiles()
    }
}

/// Whether a texture should be flipped.
#[deriving(PartialEq)]
pub enum Flip {
    /// The texture should not be flipped.
    NoFlip,
    /// The texture should be flipped vertically.
    VerticalFlip,
}

pub struct TextureLayer {
    /// A handle to the GPU texture.
    pub texture: Texture,
    /// The size of the texture in pixels.
    size: Size2D<uint>,
    /// Whether this texture is flipped vertically.
    pub flip: Flip,

    pub transform: Matrix4<f32>,
}

impl TextureLayer {
    pub fn new(texture: Texture, size: Size2D<uint>, flip: Flip, transform: Matrix4<f32>) -> TextureLayer {
        TextureLayer {
            texture: texture,
            size: size,
            flip: flip,
            transform: transform,
        }
    }
}

/// A request from the compositor to the renderer for tiles that need to be (re)displayed.
#[deriving(Clone)]
pub struct BufferRequest {
    // The rect in pixels that will be drawn to the screen
    pub screen_rect: Rect<uint>,

    // The rect in page coordinates that this tile represents
    pub page_rect: Rect<f32>,
}

impl BufferRequest {
    pub fn new(screen_rect: Rect<uint>, page_rect: Rect<f32>) -> BufferRequest {
        BufferRequest {
            screen_rect: screen_rect,
            page_rect: page_rect,
        }
    }
}

pub struct LayerBuffer {
    /// The native surface which can be shared between threads or processes. On Mac this is an
    /// `IOSurface`; on Linux this is an X Pixmap; on Android this is an `EGLImageKHR`.
    pub native_surface: NativeSurface,

    /// The rect in the containing RenderLayer that this represents.
    pub rect: Rect<f32>,

    /// The rect in pixels that will be drawn to the screen.
    pub screen_pos: Rect<uint>,

    /// The scale at which this tile is rendered
    pub resolution: f32,

    /// NB: stride is in pixels, like OpenGL GL_UNPACK_ROW_LENGTH.
    pub stride: uint,
}

/// A set of layer buffers. This is an atomic unit used to switch between the front and back
/// buffers.
pub struct LayerBufferSet {
    pub buffers: Vec<Box<LayerBuffer>>
}

impl LayerBufferSet {
    /// Notes all buffer surfaces will leak if not destroyed via a call to `destroy`.
    pub fn mark_will_leak(&mut self) {
        for buffer in self.buffers.mut_iter() {
            buffer.native_surface.mark_will_leak()
        }
    }
}
<|endoftext|>


<commit_before>use parser::combinators::{TypeWithLifetime, Str, Unit, Function, Parser, StrParser, ParserConsumer, string, character};
use self::TokenAt::{LParen, RParen, Whitespace, Identifier};

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum TokenAt<'a> {
    LParen,
    RParen,
    Whitespace,
    Identifier(&'a str),
}

pub struct Token;

impl<'a> TypeWithLifetime<'a> for Token {
    type Type = TokenAt<'a>;
}

impl Function<Unit,Token> for TokenAt<'static> {
    fn apply<'a>(&self, _: ()) -> TokenAt<'a> {
        self.clone()
    }
}

struct MkIdentifier;

impl Function<Str,Token> for MkIdentifier {
    fn apply<'a>(&self, name: &'a str) -> TokenAt<'a> {
        Identifier(name)
    }
}

#[allow(non_snake_case)]
pub fn lexer<C>(consumer: &mut C) where C: ParserConsumer<Str,Token> {
    let LPAREN = string("(").map(LParen);
    let RPAREN = string(")").map(RParen);
    let WHITESPACE = character(char::is_whitespace).plus().map(Whitespace);
    let IDENTIFIER = character(char::is_alphabetic).and_then(character(char::is_alphanumeric).star()).buffer().map(MkIdentifier);
    let TOKEN = LPAREN.or_else(RPAREN).or_else(WHITESPACE).or_else(IDENTIFIER);
    consumer.accept(TOKEN.star())
}

<commit_msg>Added test for lexer.<commit_after>use parser::combinators::{TypeWithLifetime, Str, Unit, Function, Parser, StrParser, Consumer, ParserConsumer, string, character};
use self::TokenAt::{LParen, RParen, Whitespace, Identifier};

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum TokenAt<'a> {
    LParen,
    RParen,
    Whitespace,
    Identifier(&'a str),
}

pub struct Token;

impl<'a> TypeWithLifetime<'a> for Token {
    type Type = TokenAt<'a>;
}

impl Function<Unit,Token> for TokenAt<'static> {
    fn apply<'a>(&self, _: ()) -> TokenAt<'a> {
        self.clone()
    }
}

struct MkIdentifier;

impl Function<Str,Token> for MkIdentifier {
    fn apply<'a>(&self, name: &'a str) -> TokenAt<'a> {
        Identifier(name)
    }
}

#[allow(non_snake_case)]
pub fn lexer<C>(consumer: &mut C) where C: ParserConsumer<Str,Token> {
    let LPAREN = string("(").map(LParen);
    let RPAREN = string(")").map(RParen);
    let WHITESPACE = character(char::is_whitespace).plus().map(Whitespace);
    let IDENTIFIER = character(char::is_alphabetic).and_then(character(char::is_alphanumeric).star()).buffer().map(MkIdentifier);
    let TOKEN = LPAREN.or_else(RPAREN).or_else(WHITESPACE).or_else(IDENTIFIER);
    consumer.accept(TOKEN.star())
}

#[test]
fn test_lexer() {
    impl Consumer<Token> for Vec<TokenAt<'static>> {
        fn accept<'a>(&mut self, token: TokenAt<'a>) {
            assert_eq!(self.remove(0), token);
        }
    }
    struct TestConsumer;
    impl ParserConsumer<Str,Token> for TestConsumer {
        fn accept<P>(&mut self, mut lex: P) where P: Parser<Str,Token> {
            let mut tokens = vec![LParen, Identifier("a123"), Whitespace, Whitespace, Identifier("bcd"), RParen];
            lex.push_to("(a123  bcd)", &mut tokens);
            assert_eq!(tokens, []);
        }
    }
    lexer(&mut TestConsumer);
}
<|endoftext|>


<commit_before>pub mod fen;
pub mod make;

use self::fen::*;
use super::util::grid_to_string_with_props;
use bb::*;
use castling_rights::*;
use hash::{Zobrist, DEFAULT_ZOBRISH_HASH};
use piece::*;
use side::Side;
use side::*;
use square;
use square::Square;
use std::fmt;

use std;

pub const STARTING_POSITION_FEN: &'static str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w \
                                                 QqKk - 0 1";

/// State encodes all game state except position
#[derive(Debug, Clone)]
pub struct State {
    pub castling_rights: CastlingRights,
    pub ep_square: Option<Square>,
    pub stm: Side,
    pub full_move_number: usize,
    pub half_move_clock: usize,
}

/// Position encodes all positional information and non-positional game state
pub struct Position {
    // grid is an array representation of position
    grid: [Piece; 64],
    // bb_sides represents a bitboard for each side
    bb_sides: [BB; 2],
    // bb_pieces represents a bitboard for each piece
    bb_pieces: [BB; 12],
    // state represents non-positional game state (eg side to move)
    state: State,

    key: u64,
    hash: &'static Zobrist,
}

impl std::clone::Clone for Position {
    fn clone(&self) -> Self {
        Position {
            grid: self.grid,
            bb_sides: self.bb_sides.clone(),
            bb_pieces: self.bb_pieces.clone(),
            state: self.state.clone(),
            key: self.key,
            hash: self.hash,
        }
    }
}

impl fmt::Debug for Position {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.to_string())
    }
}

impl fmt::Display for Position {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.to_string())
    }
}

impl Position {
    pub fn new(grid: [Piece; 64], state: State) -> Position {
        let mut bb_pieces = [EMPTY; 12];
        let mut bb_sides = [EMPTY; 2];

        for (idx, pc) in grid.iter().enumerate().filter(|&(_, &pc)| pc.is_some()) {
            let bb_mask = BB::new(Square::new(idx as square::Internal));
            bb_sides[pc.side().raw()] |= bb_mask;
            bb_pieces[pc.to_usize()] |= bb_mask;
        }

        let hash = &DEFAULT_ZOBRISH_HASH;
        let key = hash.position(&grid, &state);

        Position {
            grid: grid,
            bb_pieces: bb_pieces,
            bb_sides: bb_sides,
            state: state,
            hash: &DEFAULT_ZOBRISH_HASH,
            key: key,
        }
    }

    /// Construct a new position from a FEN string
    pub fn from_fen(fen: &str) -> Result<Position, String> {
        from_fen(fen).map(|(grid, state)| Position::new(grid, state))
    }

    // Convert position to FEN representation
    pub fn to_fen(&self) -> String {
        to_fen(&self.grid, &self.state)
    }

    #[inline]
    pub fn hash_key(&self) -> u64 {
        self.key
    }

    /// Get position non-positional state
    #[inline]
    pub fn state(&self) -> &State {
        &self.state
    }

    /// Get position position
    #[inline]
    pub fn grid(&self) -> &[Piece; 64] {
        &self.grid
    }

    /// Get piece at square
    #[inline]
    pub fn at(&self, sq: Square) -> Piece {
        unsafe { return *self.grid.get_unchecked(sq.to_usize()) }
    }

    pub fn to_string(&self) -> String {
        let props = vec![
            ("    side to move", self.state.stm.to_string()),
            (" castling rights", self.state.castling_rights.to_string()),
            (
                "      en-passant",
                self.state
                    .ep_square
                    .map_or("-".to_string(), |s| s.to_string()),
            ),
            (" half-move clock", self.state.half_move_clock.to_string()),
            ("full-move number", self.state.full_move_number.to_string()),
            ("             FEN", self.to_fen()),
        ];
        grid_to_string_with_props(
            |sq: Square| -> char {
                let pc = self.at(sq);
                if pc.is_none() {
                    '.'
                } else {
                    pc.to_char()
                }
            },
            props.as_slice(),
        )
    }

    #[inline]
    fn put_piece(&mut self, pc: Piece, sq: Square) {
        debug_assert!(self.at(sq).is_none());
        self.grid[sq.to_usize()] = pc;
        let bb_mask = BB::new(sq);
        let idx = pc.to_usize();
        self.bb_sides[idx & 1] |= bb_mask;
        self.bb_pieces[idx] |= bb_mask;
    }

    #[inline]
    fn remove_piece(&mut self, sq: Square) {
        debug_assert!(self.at(sq).is_some());

        let pc = self.grid[sq.to_usize()];
        self.grid[sq.to_usize()] = NULL_PIECE;
        let bb_mask = !BB::new(sq);
        let idx = pc.to_usize();
        self.bb_sides[idx & 1] &= bb_mask;
        self.bb_pieces[idx] &= bb_mask;
    }

    #[inline]
    fn move_piece(&mut self, from: Square, to: Square) -> BB {
        debug_assert!(self.at(from).is_some());
        debug_assert!(self.at(to).is_none());

        let pc = self.grid[from.to_usize()];

        self.grid[from.to_usize()] = NULL_PIECE;
        self.grid[to.to_usize()] = pc;

        let bb_mask = BB::new(from) | BB::new(to);
        let idx = pc.to_usize();
        self.bb_sides[idx & 1] ^= bb_mask;
        self.bb_pieces[idx] ^= bb_mask;

        bb_mask
    }

    fn promote_piece(&mut self, sq: Square, new_pc: Piece) {
        let old_pc = self.at(sq);
        debug_assert!(old_pc.is_some());

        self.grid[sq.to_usize()] = new_pc;

        let bb_mask = BB::new(sq);
        self.bb_pieces[old_pc.to_usize()] ^= bb_mask;
        self.bb_pieces[new_pc.to_usize()] |= bb_mask;
    }

    /// Get bitboard of pieces for a particular side
    #[inline]
    pub fn bb_side(&self, side: Side) -> BB {
        unsafe { return *self.bb_sides.get_unchecked(side.to_usize() & 1) }
    }

    /// Get bitboard of pieces for a particular piece
    #[inline]
    pub fn bb_pc(&self, pc: Piece) -> BB {
        unsafe { return *self.bb_pieces.get_unchecked(pc.to_usize()) }
    }

    /// Get bitboard of sliding pieces for a particular side
    #[inline]
    pub fn bb_sliders(&self, side: Side) -> (BB, BB) {
        let queens = self.bb_pc(QUEEN.pc(side));
        let rooks = self.bb_pc(ROOK.pc(side));
        let bishops = self.bb_pc(BISHOP.pc(side));
        (queens | bishops, queens | rooks)
    }

    /// Get bitboard of all occupied squares
    #[inline]
    pub fn bb_occupied(&self) -> BB {
        self.bb_side(WHITE) | self.bb_side(BLACK)
    }

    /// Get bitboard of all empty squares
    #[inline]
    pub fn bb_empty(&self) -> BB {
        !self.bb_occupied()
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use unindent;

    #[test]
    fn test_to_string() {
        let position =
            &Position::from_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w").unwrap();

        let expected = unindent::unindent(
            "
          ABCDEFGH
        8|rnbqkbnr|8     side to move: white
        7|pppppppp|7  castling rights: QqKk
        6|........|6       en-passant: -
        5|........|5  half-move clock: 0
        4|........|4 full-move number: 1
        3|........|3              FEN: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w QqKk - 0 1
        2|PPPPPPPP|2
        1|RNBQKBNR|1
          ABCDEFGH
        ",
        );
        assert_eq!(position.to_string(), expected);
    }
}
<commit_msg>pull out update_grid fn<commit_after>pub mod fen;
pub mod make;

use self::fen::*;
use super::util::grid_to_string_with_props;
use bb::*;
use castling_rights::*;
use hash::{Zobrist, DEFAULT_ZOBRISH_HASH};
use piece::*;
use side::Side;
use side::*;
use square;
use square::Square;
use std::fmt;

use std;

pub const STARTING_POSITION_FEN: &'static str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w \
                                                 QqKk - 0 1";

/// State encodes all game state except position
#[derive(Debug, Clone)]
pub struct State {
    pub castling_rights: CastlingRights,
    pub ep_square: Option<Square>,
    pub stm: Side,
    pub full_move_number: usize,
    pub half_move_clock: usize,
}

/// Position encodes all positional information and non-positional game state
pub struct Position {
    // grid is an array representation of position
    grid: [Piece; 64],
    // bb_sides represents a bitboard for each side
    bb_sides: [BB; 2],
    // bb_pieces represents a bitboard for each piece
    bb_pieces: [BB; 12],
    // state represents non-positional game state (eg side to move)
    state: State,

    key: u64,

    hash: &'static Zobrist,
}

impl std::clone::Clone for Position {
    fn clone(&self) -> Self {
        Position {
            grid: self.grid,
            bb_sides: self.bb_sides.clone(),
            bb_pieces: self.bb_pieces.clone(),
            state: self.state.clone(),
            key: self.key,
            hash: self.hash,
        }
    }
}

impl fmt::Debug for Position {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.to_string())
    }
}

impl fmt::Display for Position {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.to_string())
    }
}

impl Position {
    pub fn new(grid: [Piece; 64], state: State) -> Position {
        let mut bb_pieces = [EMPTY; 12];
        let mut bb_sides = [EMPTY; 2];

        for (idx, pc) in grid.iter().enumerate().filter(|&(_, &pc)| pc.is_some()) {
            let bb_mask = BB::new(Square::new(idx as square::Internal));
            bb_sides[pc.side().raw()] |= bb_mask;
            bb_pieces[pc.to_usize()] |= bb_mask;
        }

        let hash = &DEFAULT_ZOBRISH_HASH;
        let key = hash.position(&grid, &state);

        Position {
            grid: grid,
            bb_pieces: bb_pieces,
            bb_sides: bb_sides,
            state: state,
            hash: &DEFAULT_ZOBRISH_HASH,
            key: key,
        }
    }

    /// Construct a new position from a FEN string
    pub fn from_fen(fen: &str) -> Result<Position, String> {
        from_fen(fen).map(|(grid, state)| Position::new(grid, state))
    }

    // Convert position to FEN representation
    pub fn to_fen(&self) -> String {
        to_fen(&self.grid, &self.state)
    }

    #[inline]
    pub fn hash_key(&self) -> u64 {
        self.key
    }

    /// Get position non-positional state
    #[inline]
    pub fn state(&self) -> &State {
        &self.state
    }

    /// Get position position
    #[inline]
    pub fn grid(&self) -> &[Piece; 64] {
        &self.grid
    }

    /// Get piece at square
    #[inline]
    pub fn at(&self, sq: Square) -> Piece {
        unsafe { return *self.grid.get_unchecked(sq.to_usize()) }
    }

    pub fn to_string(&self) -> String {
        let props = vec![
            ("    side to move", self.state.stm.to_string()),
            (" castling rights", self.state.castling_rights.to_string()),
            (
                "      en-passant",
                self.state
                    .ep_square
                    .map_or("-".to_string(), |s| s.to_string()),
            ),
            (" half-move clock", self.state.half_move_clock.to_string()),
            ("full-move number", self.state.full_move_number.to_string()),
            ("             FEN", self.to_fen()),
        ];
        grid_to_string_with_props(
            |sq: Square| -> char {
                let pc = self.at(sq);
                if pc.is_none() {
                    '.'
                } else {
                    pc.to_char()
                }
            },
            props.as_slice(),
        )
    }

    #[inline]
    fn put_piece(&mut self, pc: Piece, sq: Square) {
        debug_assert!(self.at(sq).is_none());
        self.grid[sq.to_usize()] = pc;
        self.update_grid(sq, pc);
        let bb_mask = BB::new(sq);
        let idx = pc.to_usize();
        self.bb_sides[idx & 1] |= bb_mask;
        self.bb_pieces[idx] |= bb_mask;
    }

    #[inline]
    fn remove_piece(&mut self, sq: Square) {
        debug_assert!(self.at(sq).is_some());

        let pc = self.at(sq);
        self.grid[sq.to_usize()] = NULL_PIECE;
        let bb_mask = !BB::new(sq);

        self.update_grid(sq, NULL_PIECE);
        let idx = pc.to_usize();
        self.bb_sides[idx & 1] &= bb_mask;
        self.bb_pieces[idx] &= bb_mask;
    }

    #[inline]
    fn move_piece(&mut self, from: Square, to: Square) -> BB {
        debug_assert!(self.at(from).is_some());
        debug_assert!(self.at(to).is_none());

        let pc = self.at(from);
        self.update_grid(from, NULL_PIECE);
        self.update_grid(to, pc);

        let bb_mask = BB::new(from) | BB::new(to);
        let idx = pc.to_usize();
        self.bb_sides[idx & 1] ^= bb_mask;
        self.bb_pieces[idx] ^= bb_mask;

        bb_mask
    }

    fn promote_piece(&mut self, sq: Square, new_pc: Piece) {
        let old_pc = self.at(sq);
        debug_assert!(old_pc.is_some());
        debug_assert_eq!(old_pc.side(), new_pc.side());

        self.grid[sq.to_usize()] = new_pc;
        self.update_grid(sq, new_pc);

        let bb_mask = BB::new(sq);
        self.bb_pieces[old_pc.to_usize()] ^= bb_mask;
        self.bb_pieces[new_pc.to_usize()] |= bb_mask;
    }

    /// Get bitboard of pieces for a particular side
    #[inline]
    pub fn bb_side(&self, side: Side) -> BB {
        unsafe { return *self.bb_sides.get_unchecked(side.to_usize() & 1) }
    }

    /// Get bitboard of pieces for a particular piece
    #[inline]
    pub fn bb_pc(&self, pc: Piece) -> BB {
        unsafe { return *self.bb_pieces.get_unchecked(pc.to_usize()) }
    }

    /// Get bitboard of sliding pieces for a particular side
    #[inline]
    pub fn bb_sliders(&self, side: Side) -> (BB, BB) {
        let queens = self.bb_pc(QUEEN.pc(side));
        let rooks = self.bb_pc(ROOK.pc(side));
        let bishops = self.bb_pc(BISHOP.pc(side));
        (queens | bishops, queens | rooks)
    }

    /// Get bitboard of all occupied squares
    #[inline]
    pub fn bb_occupied(&self) -> BB {
        self.bb_side(WHITE) | self.bb_side(BLACK)
    }

    /// Get bitboard of all empty squares
    #[inline]
    pub fn bb_empty(&self) -> BB {
        !self.bb_occupied()
    }

    #[inline]
    fn update_grid(&mut self, sq: Square, pc: Piece) {
        unsafe {
            *(self.grid.get_unchecked_mut(sq.to_usize())) = pc;
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use unindent;

    #[test]
    fn test_to_string() {
        let position =
            &Position::from_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w").unwrap();

        let expected = unindent::unindent(
            "
          ABCDEFGH
        8|rnbqkbnr|8     side to move: white
        7|pppppppp|7  castling rights: QqKk
        6|........|6       en-passant: -
        5|........|5  half-move clock: 0
        4|........|4 full-move number: 1
        3|........|3              FEN: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w QqKk - 0 1
        2|PPPPPPPP|2
        1|RNBQKBNR|1
          ABCDEFGH
        ",
        );
        assert_eq!(position.to_string(), expected);
    }
}
<|endoftext|>


<commit_before>use std::collections::VecDeque;
use diff;
use term;
use std::io;

#[derive(Debug, PartialEq)]
pub enum DiffLine {
    Context(String),
    Expected(String),
    Resulting(String),
}

#[derive(Debug, PartialEq)]
pub struct Mismatch {
    pub line_number: u32,
    pub lines: Vec<DiffLine>,
}

impl Mismatch {
    fn new(line_number: u32) -> Mismatch {
        Mismatch {
            line_number: line_number,
            lines: Vec::new(),
        }
    }
}

// Produces a diff between the expected output and actual output of rustfmt.
pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
    let mut line_number = 1;
    let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
    let mut lines_since_mismatch = context_size + 1;
    let mut results = Vec::new();
    let mut mismatch = Mismatch::new(0);

    for result in diff::lines(expected, actual) {
        match result {
            diff::Result::Left(str) => {
                if lines_since_mismatch >= context_size {
                    results.push(mismatch);
                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                }

                while let Some(line) = context_queue.pop_front() {
                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
                }

                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
                lines_since_mismatch = 0;
            }
            diff::Result::Right(str) => {
                if lines_since_mismatch >= context_size {
                    results.push(mismatch);
                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                }

                while let Some(line) = context_queue.pop_front() {
                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
                }

                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
                line_number += 1;
                lines_since_mismatch = 0;
            }
            diff::Result::Both(str, _) => {
                if context_queue.len() >= context_size {
                    let _ = context_queue.pop_front();
                }

                if lines_since_mismatch < context_size {
                    mismatch.lines.push(DiffLine::Context(str.to_owned()));
                } else {
                    context_queue.push_back(str);
                }

                line_number += 1;
                lines_since_mismatch += 1;
            }
        }
    }

    results.push(mismatch);
    results.remove(0);

    results
}

pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F)
    where F: Fn(u32) -> String
{
    match term::stdout() {
        Some(_) if isatty() => print_diff_fancy(diff, get_section_title, term::stdout().unwrap()),
        _ => print_diff_basic(diff, get_section_title),
    }

    // isatty shamelessly adapted from cargo.
    #[cfg(unix)]
    fn isatty() -> bool {
        extern crate libc;

        unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
    }
    #[cfg(windows)]
    fn isatty() -> bool {
        extern crate kernel32;
        extern crate winapi;

        unsafe {
            let handle = kernel32::GetStdHandle(winapi::winbase::STD_OUTPUT_HANDLE);
            let mut out = 0;
            kernel32::GetConsoleMode(handle, &mut out) != 0
        }
    }
}

fn print_diff_fancy<F>(diff: Vec<Mismatch>,
                       get_section_title: F,
                       mut t: Box<term::Terminal<Output = io::Stdout>>)
    where F: Fn(u32) -> String
{
    for mismatch in diff {
        let title = get_section_title(mismatch.line_number);
        writeln!(t, "{}", title).unwrap();

        for line in mismatch.lines {
            match line {
                DiffLine::Context(ref str) => {
                    t.reset().unwrap();
                    writeln!(t, " {}⏎", str).unwrap();
                }
                DiffLine::Expected(ref str) => {
                    t.fg(term::color::GREEN).unwrap();
                    writeln!(t, "+{}⏎", str).unwrap();
                }
                DiffLine::Resulting(ref str) => {
                    t.fg(term::color::RED).unwrap();
                    writeln!(t, "-{}⏎", str).unwrap();
                }
            }
        }
        t.reset().unwrap();
    }
}

pub fn print_diff_basic<F>(diff: Vec<Mismatch>, get_section_title: F)
    where F: Fn(u32) -> String
{
    for mismatch in diff {
        let title = get_section_title(mismatch.line_number);
        println!("{}", title);

        for line in mismatch.lines {
            match line {
                DiffLine::Context(ref str) => {
                    println!(" {}⏎", str);
                }
                DiffLine::Expected(ref str) => {
                    println!("+{}⏎", str);
                }
                DiffLine::Resulting(ref str) => {
                    println!("-{}⏎", str);
                }
            }
        }
    }
}
<commit_msg>Check term supports colour before printing fancy diffs<commit_after>use std::collections::VecDeque;
use diff;
use term;
use std::io;

#[derive(Debug, PartialEq)]
pub enum DiffLine {
    Context(String),
    Expected(String),
    Resulting(String),
}

#[derive(Debug, PartialEq)]
pub struct Mismatch {
    pub line_number: u32,
    pub lines: Vec<DiffLine>,
}

impl Mismatch {
    fn new(line_number: u32) -> Mismatch {
        Mismatch {
            line_number: line_number,
            lines: Vec::new(),
        }
    }
}

// Produces a diff between the expected output and actual output of rustfmt.
pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
    let mut line_number = 1;
    let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
    let mut lines_since_mismatch = context_size + 1;
    let mut results = Vec::new();
    let mut mismatch = Mismatch::new(0);

    for result in diff::lines(expected, actual) {
        match result {
            diff::Result::Left(str) => {
                if lines_since_mismatch >= context_size {
                    results.push(mismatch);
                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                }

                while let Some(line) = context_queue.pop_front() {
                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
                }

                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
                lines_since_mismatch = 0;
            }
            diff::Result::Right(str) => {
                if lines_since_mismatch >= context_size {
                    results.push(mismatch);
                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                }

                while let Some(line) = context_queue.pop_front() {
                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
                }

                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
                line_number += 1;
                lines_since_mismatch = 0;
            }
            diff::Result::Both(str, _) => {
                if context_queue.len() >= context_size {
                    let _ = context_queue.pop_front();
                }

                if lines_since_mismatch < context_size {
                    mismatch.lines.push(DiffLine::Context(str.to_owned()));
                } else {
                    context_queue.push_back(str);
                }

                line_number += 1;
                lines_since_mismatch += 1;
            }
        }
    }

    results.push(mismatch);
    results.remove(0);

    results
}

pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F)
    where F: Fn(u32) -> String
{
    match term::stdout() {
        Some(ref t) if isatty() && t.supports_color() => {
            print_diff_fancy(diff, get_section_title, term::stdout().unwrap())
        }
        _ => print_diff_basic(diff, get_section_title),
    }

    // isatty shamelessly adapted from cargo.
    #[cfg(unix)]
    fn isatty() -> bool {
        extern crate libc;

        unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
    }
    #[cfg(windows)]
    fn isatty() -> bool {
        extern crate kernel32;
        extern crate winapi;

        unsafe {
            let handle = kernel32::GetStdHandle(winapi::winbase::STD_OUTPUT_HANDLE);
            let mut out = 0;
            kernel32::GetConsoleMode(handle, &mut out) != 0
        }
    }
}

fn print_diff_fancy<F>(diff: Vec<Mismatch>,
                       get_section_title: F,
                       mut t: Box<term::Terminal<Output = io::Stdout>>)
    where F: Fn(u32) -> String
{
    for mismatch in diff {
        let title = get_section_title(mismatch.line_number);
        writeln!(t, "{}", title).unwrap();

        for line in mismatch.lines {
            match line {
                DiffLine::Context(ref str) => {
                    t.reset().unwrap();
                    writeln!(t, " {}⏎", str).unwrap();
                }
                DiffLine::Expected(ref str) => {
                    t.fg(term::color::GREEN).unwrap();
                    writeln!(t, "+{}⏎", str).unwrap();
                }
                DiffLine::Resulting(ref str) => {
                    t.fg(term::color::RED).unwrap();
                    writeln!(t, "-{}⏎", str).unwrap();
                }
            }
        }
        t.reset().unwrap();
    }
}

pub fn print_diff_basic<F>(diff: Vec<Mismatch>, get_section_title: F)
    where F: Fn(u32) -> String
{
    for mismatch in diff {
        let title = get_section_title(mismatch.line_number);
        println!("{}", title);

        for line in mismatch.lines {
            match line {
                DiffLine::Context(ref str) => {
                    println!(" {}⏎", str);
                }
                DiffLine::Expected(ref str) => {
                    println!("+{}⏎", str);
                }
                DiffLine::Resulting(ref str) => {
                    println!("-{}⏎", str);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before>// Abstraction of the database.
// For the purposes of the backend, the only necessary
// actions are the following:
//
// 1. Put a pending build into the database.
// 2. Grab a pending build from the database, which
//    will immediately undergo being built.
// 3. Put test results into a database, given what
//    build was pending

extern crate postgres;
#[phase(plugin)]
extern crate pg_typeprovider;

use builder::BuildResult;

use self::EntryStatus::{Pending, InProgress, Done};

pub trait DatabaseEntry<A> : Send {
    fn get_base(&self) -> A;
}

impl<A : Send + Clone> DatabaseEntry<A> for A {
    fn get_base(&self) -> A { self.clone() }
}

/// Type A is some key
pub trait Database<A, B : DatabaseEntry<A>> : Sync + Send {
    fn add_pending(&self, entry: A);

    /// Optionally gets a pending build from the database.
    /// If `Some` is returned, it will not be returned again.
    /// If `None` is returned, it is expected that the caller will sleep.
    fn get_pending(&self) -> Option<B>;

    fn add_test_results(&self, entry: B, results: BuildResult);
}

pub enum EntryStatus {
    Pending,
    InProgress,
    Done
}

impl EntryStatus {
    pub fn to_int(&self) -> i32 {
        match *self {
            Pending => 0,
            InProgress => 1,
            Done => 2
        }
    }
}

pub mod postgres_db {
    extern crate pg_typeprovider;

    use self::pg_typeprovider::util::Joinable;

    use std::sync::Mutex;

    use super::postgres::{Connection, SslMode, ToSql};

    use builder::BuildResult;
    use super::EntryStatus::{Pending, InProgress, Done};
    use super::{Database, DatabaseEntry};

    pg_table!(builds)

    pub struct PostgresDatabase {
        db: Mutex<Connection>
    }

    impl PostgresDatabase {
        pub fn new(loc: &str) -> Option<PostgresDatabase> {
            Connection::connect(loc, &SslMode::None).ok().map(|db| {
                PostgresDatabase {
                    db: Mutex::new(db)
                }
            })
        }

        pub fn new_testing() -> Option<PostgresDatabase> {
            let retval = PostgresDatabase::new(
                "postgres://jroesch@localhost/gradr-test");
            match retval {
                Some(ref db) => {
                    db.with_connection(|conn| {
                        conn.execute(
                            "DELETE FROM users", &[]).unwrap();
                        conn.execute(
                            "DELETE FROM builds", &[]).unwrap();
                    })
                },
                None => ()
            };
            retval
        }

        pub fn with_connection<A>(&self, f: |&Connection| -> A) -> A {
            f(&*self.db.lock())
        }
    }

    impl DatabaseEntry<BuildInsert> for Build {
        fn get_base(&self) -> BuildInsert {
            BuildInsert {
                status: self.status,
                clone_url: self.clone_url.clone(),
                branch: self.branch.clone(),
                results: self.results.clone()
            }
        }
    }

    fn get_one_build(conn: &Connection) -> Option<Build> {
        BuildSearch::new()
            .where_status((&Pending).to_int())
            .search(conn, Some(1)).pop()
    }

    // returns true if it was able to lock it, else false
    fn try_lock_build(conn: &Connection, b: &Build) -> bool {
        BuildUpdate::new()
            .status_to((&InProgress).to_int())
            .where_id(b.id)
            .where_status((&Pending).to_int())
            .update(conn) == 1
    }

    impl Database<BuildInsert, Build> for PostgresDatabase {
        fn add_pending(&self, entry: BuildInsert) {
            self.with_connection(|conn| entry.insert(conn));
        }

        fn get_pending(&self) -> Option<Build> {
            self.with_connection(|conn| {
                loop {
                    match get_one_build(conn) {
                        Some(b) => {
                            if try_lock_build(conn, &b) {
                                return Some(b);
                            }
                        },
                        None => { return None; }
                    }
                }
            })
        }

        fn add_test_results(&self, entry: Build, results: BuildResult) {
            // TODO: we do a copy here because we cannot move into a closure,
            // even though this is what we want.  I spent around 2 hours trying
            // to get around this, but to no avail.
            let res = results.consume_to_json().to_string();
            let s = res.as_slice();
            self.with_connection(|conn| {
                let num_updated =
                    BuildUpdate::new()
                    .status_to((&Done).to_int())
                    .results_to(s.to_string())
                    .where_id(entry.id)
                    .update(conn);
                assert_eq!(num_updated, 1);
            });
        }
    }
}
<commit_msg>Now uses GenericConnection instead of Connection directly<commit_after>// Abstraction of the database.
// For the purposes of the backend, the only necessary
// actions are the following:
//
// 1. Put a pending build into the database.
// 2. Grab a pending build from the database, which
//    will immediately undergo being built.
// 3. Put test results into a database, given what
//    build was pending

extern crate postgres;
#[phase(plugin)]
extern crate pg_typeprovider;

use builder::BuildResult;

use self::EntryStatus::{Pending, InProgress, Done};

pub trait DatabaseEntry<A> : Send {
    fn get_base(&self) -> A;
}

impl<A : Send + Clone> DatabaseEntry<A> for A {
    fn get_base(&self) -> A { self.clone() }
}

/// Type A is some key
pub trait Database<A, B : DatabaseEntry<A>> : Sync + Send {
    fn add_pending(&self, entry: A);

    /// Optionally gets a pending build from the database.
    /// If `Some` is returned, it will not be returned again.
    /// If `None` is returned, it is expected that the caller will sleep.
    fn get_pending(&self) -> Option<B>;

    fn add_test_results(&self, entry: B, results: BuildResult);
}

pub enum EntryStatus {
    Pending,
    InProgress,
    Done
}

impl EntryStatus {
    pub fn to_int(&self) -> i32 {
        match *self {
            Pending => 0,
            InProgress => 1,
            Done => 2
        }
    }
}

pub mod postgres_db {
    extern crate pg_typeprovider;

    use self::pg_typeprovider::util::Joinable;

    use std::sync::Mutex;

    use super::postgres::{Connection, GenericConnection, SslMode, ToSql};

    use builder::BuildResult;
    use super::EntryStatus::{Pending, InProgress, Done};
    use super::{Database, DatabaseEntry};

    pg_table!(builds)

    pub struct PostgresDatabase {
        db: Mutex<Connection>
    }

    impl PostgresDatabase {
        pub fn new(loc: &str) -> Option<PostgresDatabase> {
            Connection::connect(loc, &SslMode::None).ok().map(|db| {
                PostgresDatabase {
                    db: Mutex::new(db)
                }
            })
        }

        pub fn new_testing() -> Option<PostgresDatabase> {
            let retval = PostgresDatabase::new(
                "postgres://jroesch@localhost/gradr-test");
            match retval {
                Some(ref db) => {
                    db.with_connection(|conn| {
                        conn.execute(
                            "DELETE FROM users", &[]).unwrap();
                        conn.execute(
                            "DELETE FROM builds", &[]).unwrap();
                    })
                },
                None => ()
            };
            retval
        }

        pub fn with_connection<A>(&self, f: |&Connection| -> A) -> A {
            f(&*self.db.lock())
        }
    }

    impl DatabaseEntry<BuildInsert> for Build {
        fn get_base(&self) -> BuildInsert {
            BuildInsert {
                status: self.status,
                clone_url: self.clone_url.clone(),
                branch: self.branch.clone(),
                results: self.results.clone()
            }
        }
    }

    fn get_one_build(conn: &Connection) -> Option<Build> {
        BuildSearch::new()
            .where_status((&Pending).to_int())
            .search(conn, Some(1)).pop()
    }

    // returns true if it was able to lock it, else false
    fn try_lock_build(conn: &Connection, b: &Build) -> bool {
        BuildUpdate::new()
            .status_to((&InProgress).to_int())
            .where_id(b.id)
            .where_status((&Pending).to_int())
            .update(conn) == 1
    }

    impl Database<BuildInsert, Build> for PostgresDatabase {
        fn add_pending(&self, entry: BuildInsert) {
            self.with_connection(|conn| entry.insert(conn));
        }

        fn get_pending(&self) -> Option<Build> {
            self.with_connection(|conn| {
                loop {
                    match get_one_build(conn) {
                        Some(b) => {
                            if try_lock_build(conn, &b) {
                                return Some(b);
                            }
                        },
                        None => { return None; }
                    }
                }
            })
        }

        fn add_test_results(&self, entry: Build, results: BuildResult) {
            // TODO: we do a copy here because we cannot move into a closure,
            // even though this is what we want.  I spent around 2 hours trying
            // to get around this, but to no avail.
            let res = results.consume_to_json().to_string();
            let s = res.as_slice();
            self.with_connection(|conn| {
                let num_updated =
                    BuildUpdate::new()
                    .status_to((&Done).to_int())
                    .results_to(s.to_string())
                    .where_id(entry.id)
                    .update(conn);
                assert_eq!(num_updated, 1);
            });
        }
    }
}
<|endoftext|>


<commit_before>#![cfg(test)]

use std::collections::HashMap;
use rustc_serialize::json;
use rustc_serialize::json::{Json, Object};
use rustc_serialize::{Decoder, Decodable};
use std::io::prelude::*;
use std::fs::File;
use token::{Token, ReservedWord};

pub struct DynJson {
    json: Json
}

impl Decodable for DynJson {
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
        unimplemented!()
    }
}

#[derive(RustcDecodable)]
pub struct ExpectPass {
    source: String,
    expected: DynJson,
    options: Option<DynJson>
}

pub struct ExpectFail {
    source: String,
    error: String,
    options: Option<Json>
}

pub enum TestCase {
    Pass(ExpectPass),
    Fail(ExpectFail)
}

trait JsonExt {
    fn into_array(self) -> json::Array;
    fn into_string(self) -> String;
    fn into_string_opt(self) -> Option<String>;
}

impl JsonExt for Json {
    fn into_array(self) -> json::Array {
        match self {
            Json::Array(array) => array,
            _ => panic!("expected array")
        }
    }
    fn into_string(self) -> String {
        match self {
            Json::String(string) => string,
            _ => panic!("expected string")
        }
    }
    fn into_string_opt(self) -> Option<String> {
        match self {
            Json::Null => None,
            Json::String(string) => Some(string),
            _ => panic!("expected string or null")
        }
    }
}

<commit_msg>acrichto said to use json::decode but that doesn't work for Json<commit_after>#![cfg(test)]

use std::collections::HashMap;
use rustc_serialize::json;
use rustc_serialize::json::{decode, Json, Object};
use rustc_serialize::{Decoder, Decodable};
use std::io::prelude::*;
use std::fs::File;
use token::{Token, ReservedWord};

pub struct ExpectPass {
    source: String,
    expected: Json,
    options: Option<Json>
}

pub struct ExpectFail {
    source: String,
    error: String,
    options: Option<Json>
}

pub enum TestCase {
    Pass(ExpectPass),
    Fail(ExpectFail)
}

trait JsonExt {
    fn into_array(self) -> json::Array;
    fn into_string(self) -> String;
    fn into_string_opt(self) -> Option<String>;
}

impl JsonExt for Json {
    fn into_array(self) -> json::Array {
        match self {
            Json::Array(array) => array,
            _ => panic!("expected array")
        }
    }
    fn into_string(self) -> String {
        match self {
            Json::String(string) => string,
            _ => panic!("expected string")
        }
    }
    fn into_string_opt(self) -> Option<String> {
        match self {
            Json::Null => None,
            Json::String(string) => Some(string),
            _ => panic!("expected string or null")
        }
    }
}

pub fn read_tests(path: &str) -> Vec<TestCase> {
    let mut f: File = File::open(path).unwrap();
    let mut s = String::new();
    f.read_to_string(&mut s);
    parse_tests(s)
}

pub fn parse_tests(src: &str) -> Vec<TestCase> {
    let data: Json = decode(src).unwrap();
    unimplemented!()
}
<|endoftext|>


<commit_before>//! Helper functions for dealing with shaders.

// External crates.
use gl;
use gl::types::{
    GLchar,
    GLenum,
    GLint,
    GLuint,
};

use std::ptr;

/// Compiles a shader.
///
/// Returns a shader or a message with the error.
pub fn compile_shader(
    shader_type: GLenum,
    source: &str
) -> Result<GLuint, String> {
    let shader = gl::CreateShader(shader_type);
    unsafe {
        source.with_c_str(
            |ptr| gl::ShaderSource(shader, 1, &ptr, ptr::null())
        );
        gl::CompileShader(shader);
        let mut status = gl::FALSE as GLint;
        gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);
        if status == (gl::TRUE as GLint) {
            Ok(shader)
        } else {
            let mut len = 0;
            gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
            // Subtract 1 to skip the trailing null character.
            let mut buf = Vec::from_elem(len as uint - 1, 0u8);
            gl::GetShaderInfoLog(
                shader,
                len,
                ptr::mut_null(),
                buf.as_mut_ptr() as *mut GLchar
            );

            gl::DeleteShader(shader);

            Err(String::from_utf8(buf).ok().expect(
                "ShaderInfoLog not valid utf8"
            ))
        }
    }
}

<commit_msg>Fix 'no information log' bug<commit_after>//! Helper functions for dealing with shaders.

// External crates.
use gl;
use gl::types::{
    GLchar,
    GLenum,
    GLint,
    GLuint,
};

use std::ptr;

/// Compiles a shader.
///
/// Returns a shader or a message with the error.
pub fn compile_shader(
    shader_type: GLenum,
    source: &str
) -> Result<GLuint, String> {
    let shader = gl::CreateShader(shader_type);
    unsafe {
        source.with_c_str(
            |ptr| gl::ShaderSource(shader, 1, &ptr, ptr::null())
        );
        gl::CompileShader(shader);
        let mut status = gl::FALSE as GLint;
        gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);
        if status == (gl::TRUE as GLint) {
            Ok(shader)
        } else {
            let mut len = 0;
            gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);

            if len == 0 {
                Err("Compilation failed with no log. The OpenGL context might have been created on another thread, or not have been created.".to_string())
            }
            else {
                // Subtract 1 to skip the trailing null character.
                let mut buf = Vec::from_elem(len as uint - 1, 0u8);
                gl::GetShaderInfoLog(
                    shader,
                    len,
                    ptr::mut_null(),
                    buf.as_mut_ptr() as *mut GLchar
                );

                gl::DeleteShader(shader);

                Err(String::from_utf8(buf).ok().expect(
                    "ShaderInfoLog not valid utf8"
                ))
            }
        }
    }
}

<|endoftext|>


<commit_before>//! Module docs?  whatever

use path::Element;
use vertex::Vertex;
use graph::Graph;
use std::collections::HashMap;

#[derive(Debug, Display, Clone)]
pub struct TreePath {
    pub element: Element,
    pub children: Box<HashMap<usize, TreePath>>,
    pub element_count: usize
}

impl TreePath {
    // we need to be able to use this on new graph query results because
    // we don't always start with a single vertex
    pub fn new() -> TreePath {

        TreePath{element:Element::TreeRoot, children:Box::new(HashMap::new()), element_count:0}
    }

    // convenience method
    pub fn from_vertex(vertex: Vertex) -> TreePath {
        let e = Element::Vertex(vertex);
        TreePath::from_element(e)
    }

    pub fn from_element(element: Element) -> TreePath {
        TreePath{element:element, children:Box::new(HashMap::new()), element_count:0}
    }

    pub fn add_child(&mut self, element: Element) {
        let child = TreePath::from_element(element);
                // create a new Treepath
        self.children.insert(self.element_count, child);
        self.element_count += 1;
    }

    pub fn child_count(&self) -> usize {
        self.children.len()
    }

    // iterator?
    pub fn leaves(&self)  {

    }
    // pub fn from_vertices(vlist: &[Vertex]) -> TreePath {
    //
    // }
}
<commit_msg>using an RC for the children - will need it to save ref to parents<commit_after>//! Module docs?  whatever

use path::Element;
use vertex::Vertex;
use graph::Graph;
use std::collections::HashMap;
use std::rc::Rc;

#[derive(Debug, Display, Clone)]
pub struct TreePath {
    pub element: Element,
    pub children: Box<HashMap<usize, Rc<TreePath>>>,
    pub element_count: usize
}

impl TreePath {
    // we need to be able to use this on new graph query results because
    // we don't always start with a single vertex
    pub fn new() -> TreePath {

        TreePath{element:Element::TreeRoot, children:Box::new(HashMap::new()), element_count:0}
    }

    // convenience method
    pub fn from_vertex(vertex: Vertex) -> TreePath {
        let e = Element::Vertex(vertex);
        TreePath::from_element(e)
    }

    pub fn from_element(element: Element) -> TreePath {
        TreePath{element:element, children:Box::new(HashMap::new()), element_count:0}
    }

    pub fn add_child(&mut self, element: Element) {
        let child = Rc::new(TreePath::from_element(element));
                // create a new Treepath
        self.children.insert(self.element_count, child);
        self.element_count += 1;
    }

    pub fn child_count(&self) -> usize {
        self.children.len()
    }

    // iterator?
    pub fn leaves(&self)  {

    }
    // pub fn from_vertices(vlist: &[Vertex]) -> TreePath {
    //
    // }
}
<|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;

use gtk::prelude::*;
use glib::types::StaticType;

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 = [glib::Type::String];
    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_store, iter) = tree_selection.get_selected().unwrap();
        println!("selected row {}", left_store.get_path(&iter));
    });

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

        // 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 = [glib::Type::String];
    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).into());

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

    // right pane
    let right_tree = gtk::TreeView::new();
    let right_column_types = [gdk::pixbuf::Pixbuf::static_type(), glib::Type::String];
    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 gdk::pixbuf::Pixbuf::new_from_file("./resources/eye.png") {
        Ok(i) => i,
        Err(e) => {
            println!("Error while creating image: {}", e);
            if e.typed::<glib::FileError>() == Some(glib::FileError::Noent) {
                println!("Try 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);

    let v = &image.into();
    for _ in 0..10 {
        let iter = right_store.append(None);

        right_store.set_value(&iter, 0, v);
        right_store.set_value(&iter, 1, &"I'm a child node with an image".into());
    }

    // 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>More Value changes: use `to_value` and `TreeStore::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;

use gtk::prelude::*;

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_store, iter) = tree_selection.get_selected().unwrap();
        println!("selected row {}", left_store.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 = [gdk::pixbuf::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 gdk::pixbuf::Pixbuf::new_from_file("./resources/eye.png") {
        Ok(i) => i,
        Err(e) => {
            println!("Error while creating image: {}", e);
            if e.typed::<glib::FileError>() == 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();
}
<|endoftext|>