<commit_before>// This file is part of sokoban-rs
// Copyright 2015 Sébastien Watteau
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This is an implementation of Sokoban in Rust.

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate clap;
extern crate sdl2;
extern crate xml;

use clap::App;
use sdl2::event::Event;
use sdl2::image::LoadTexture;
use sdl2::image::INIT_PNG;
use sdl2::keyboard::Keycode;
use sdl2::render::{Canvas, TextureCreator};
use sdl2::video::{Window, WindowContext};
use sdl2::Sdl;
use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use std::str::FromStr;
use xml::reader::EventReader;
use xml::reader::XmlEvent;

pub mod error;
pub mod game;
pub mod painter;
pub mod shadow;
pub mod tileset;

use game::{Direction, Level};
use painter::Painter;
use tileset::Tileset;

pub fn main() -> Result<(), Box<Error>> {
    // Read command line arguments
    let yml = load_yaml!("clap.yml");
    let matches = App::from_yaml(yml).get_matches();
    let width = value_t!(matches.value_of("width"), u32).unwrap_or(1024);
    let height = value_t!(matches.value_of("height"), u32).unwrap_or(768);
    let fullscreen = matches.is_present("fullscreen");
    let slc_file = matches.value_of("slc_file").unwrap();

    // Load the level collection file
    let levels = load_slc_file(slc_file)?;

    // Initialize SDL components
    let sdl = sdl2::init()?;
    let _ = sdl2::image::init(INIT_PNG)?;
    let ttf_context = sdl2::ttf::init()?;

    let window = create_window(&sdl, width, height, fullscreen)?;
    let mut canvas = window.into_canvas().build()?;
    let texture_creator = canvas.texture_creator();

    let mut painter = {
        let big_set = load_tileset(
            &texture_creator,
            "assets/image/tileset.png",
            101,
            171,
            83,
            40,
        )?;
        let small_set = load_tileset(
            &texture_creator,
            "assets/image/tileset-small.png",
            50,
            85,
            41,
            20,
        )?;
        let font = ttf_context.load_font("assets/font/RujisHandwritingFontv.2.0.ttf", 20)?;
        Painter::new(&mut canvas, big_set, small_set, font)
    };

    mainloop(&sdl, levels.iter(), &mut painter, &mut canvas);

    Ok(())
}

/// Builds levels from a level collection file in the SLC format.
fn load_slc_file<P: AsRef<Path>>(path: P) -> Result<Vec<Level>, error::SokobanError> {
    let mut levels = Vec::new();

    let parser = {
        let file = File::open(path.as_ref())?;
        EventReader::new(BufReader::new(file))
    };

    let mut level_title = String::new();
    let mut level_data = String::new();
    let mut reading_level = false;
    for event in parser {
        match event {
            Ok(XmlEvent::StartElement {
                ref name,
                ref attributes,
                ..
            }) => {
                if name.local_name == "L" {
                    reading_level = true;
                } else if name.local_name == "Level" {
                    if let Some(id) = attributes.iter().find(|&attr| attr.name.local_name == "Id") {
                        level_title = id.value.clone();
                    }
                }
            }
            Ok(XmlEvent::EndElement { name }) => {
                if name.local_name == "Level" {
                    let mut level = Level::from_str(&level_data)?;
                    level.set_title(level_title.clone());
                    levels.push(level);
                    level_data.clear();
                }
            }
            Ok(XmlEvent::Characters(ref data)) => {
                if reading_level {
                    level_data.push_str(data);
                    level_data.push('\n');
                }
            }
            _ => {}
        }
    }

    Ok(levels)
}

/// Creates the SDL window
fn create_window(
    sdl: &Sdl,
    width: u32,
    height: u32,
    fullscreen: bool,
) -> Result<Window, Box<Error>> {
    let mut window_builder = sdl.video()?.window("sokoban-rs", width, height);
    if fullscreen {
        window_builder.fullscreen();
    } else {
        window_builder.position_centered();
    }
    let window = window_builder.opengl().build()?;
    Ok(window)
}

/// Loads a tileset
fn load_tileset<P: AsRef<Path>>(
    texture_creator: &TextureCreator<WindowContext>,
    path: P,
    width: u32,
    height: u32,
    effective_height: u32,
    offset: i32,
) -> Result<Tileset, Box<Error>> {
    let texture = texture_creator.load_texture(path.as_ref())?;
    let tileset = Tileset::new(texture, width, height, effective_height, offset);
    Ok(tileset)
}

/// Main game event loop
fn mainloop<'a, I: Iterator<Item = &'a Level>>(
    sdl: &Sdl,
    mut levels: I,
    painter: &mut Painter,
    canvas: &mut Canvas<Window>,
) {
    let (mut reference_level, mut level) = match levels.next() {
        Some(l) => (l, l.clone()),
        None => {
            return;
        }
    };

    let mut running = true;
    let mut events = sdl.event_pump().unwrap();
    let mut skip = false;
    while running {
        if level.is_completed() || skip {
            match levels.next() {
                Some(l) => {
                    reference_level = l;
                    level = l.clone();
                    skip = false;
                }
                None => {
                    break;
                }
            }
        }

        painter.paint(canvas, &level);

        match events.wait_event() {
            Event::Quit { .. }
            | Event::KeyDown {
                keycode: Some(Keycode::Escape),
                ..
            } => running = false,
            Event::KeyDown {
                keycode: Some(Keycode::Left),
                ..
            } => {
                level.step(Direction::Left);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Right),
                ..
            } => {
                level.step(Direction::Right);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Up),
                ..
            } => {
                level.step(Direction::Up);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Down),
                ..
            } => {
                level.step(Direction::Down);
            }
            Event::KeyDown {
                keycode: Some(Keycode::R),
                ..
            } => {
                level = reference_level.clone();
            }
            Event::KeyDown {
                keycode: Some(Keycode::N),
                ..
            } => {
                skip = true;
            }
            _ => {}
        }
    }
}
<commit_msg>Use the `dyn` keyword<commit_after>// This file is part of sokoban-rs
// Copyright 2015 Sébastien Watteau
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This is an implementation of Sokoban in Rust.

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate clap;
extern crate sdl2;
extern crate xml;

use clap::App;
use sdl2::event::Event;
use sdl2::image::LoadTexture;
use sdl2::image::INIT_PNG;
use sdl2::keyboard::Keycode;
use sdl2::render::{Canvas, TextureCreator};
use sdl2::video::{Window, WindowContext};
use sdl2::Sdl;
use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use std::str::FromStr;
use xml::reader::EventReader;
use xml::reader::XmlEvent;

pub mod error;
pub mod game;
pub mod painter;
pub mod shadow;
pub mod tileset;

use game::{Direction, Level};
use painter::Painter;
use tileset::Tileset;

pub fn main() -> Result<(), Box<dyn Error>> {
    // Read command line arguments
    let yml = load_yaml!("clap.yml");
    let matches = App::from_yaml(yml).get_matches();
    let width = value_t!(matches.value_of("width"), u32).unwrap_or(1024);
    let height = value_t!(matches.value_of("height"), u32).unwrap_or(768);
    let fullscreen = matches.is_present("fullscreen");
    let slc_file = matches.value_of("slc_file").unwrap();

    // Load the level collection file
    let levels = load_slc_file(slc_file)?;

    // Initialize SDL components
    let sdl = sdl2::init()?;
    let _ = sdl2::image::init(INIT_PNG)?;
    let ttf_context = sdl2::ttf::init()?;

    let window = create_window(&sdl, width, height, fullscreen)?;
    let mut canvas = window.into_canvas().build()?;
    let texture_creator = canvas.texture_creator();

    let mut painter = {
        let big_set = load_tileset(
            &texture_creator,
            "assets/image/tileset.png",
            101,
            171,
            83,
            40,
        )?;
        let small_set = load_tileset(
            &texture_creator,
            "assets/image/tileset-small.png",
            50,
            85,
            41,
            20,
        )?;
        let font = ttf_context.load_font("assets/font/RujisHandwritingFontv.2.0.ttf", 20)?;
        Painter::new(&mut canvas, big_set, small_set, font)
    };

    mainloop(&sdl, levels.iter(), &mut painter, &mut canvas);

    Ok(())
}

/// Builds levels from a level collection file in the SLC format.
fn load_slc_file<P: AsRef<Path>>(path: P) -> Result<Vec<Level>, error::SokobanError> {
    let mut levels = Vec::new();

    let parser = {
        let file = File::open(path.as_ref())?;
        EventReader::new(BufReader::new(file))
    };

    let mut level_title = String::new();
    let mut level_data = String::new();
    let mut reading_level = false;
    for event in parser {
        match event {
            Ok(XmlEvent::StartElement {
                ref name,
                ref attributes,
                ..
            }) => {
                if name.local_name == "L" {
                    reading_level = true;
                } else if name.local_name == "Level" {
                    if let Some(id) = attributes.iter().find(|&attr| attr.name.local_name == "Id") {
                        level_title = id.value.clone();
                    }
                }
            }
            Ok(XmlEvent::EndElement { name }) => {
                if name.local_name == "Level" {
                    let mut level = Level::from_str(&level_data)?;
                    level.set_title(level_title.clone());
                    levels.push(level);
                    level_data.clear();
                }
            }
            Ok(XmlEvent::Characters(ref data)) => {
                if reading_level {
                    level_data.push_str(data);
                    level_data.push('\n');
                }
            }
            _ => {}
        }
    }

    Ok(levels)
}

/// Creates the SDL window
fn create_window(
    sdl: &Sdl,
    width: u32,
    height: u32,
    fullscreen: bool,
) -> Result<Window, Box<dyn Error>> {
    let mut window_builder = sdl.video()?.window("sokoban-rs", width, height);
    if fullscreen {
        window_builder.fullscreen();
    } else {
        window_builder.position_centered();
    }
    let window = window_builder.opengl().build()?;
    Ok(window)
}

/// Loads a tileset
fn load_tileset<P: AsRef<Path>>(
    texture_creator: &TextureCreator<WindowContext>,
    path: P,
    width: u32,
    height: u32,
    effective_height: u32,
    offset: i32,
) -> Result<Tileset, Box<dyn Error>> {
    let texture = texture_creator.load_texture(path.as_ref())?;
    let tileset = Tileset::new(texture, width, height, effective_height, offset);
    Ok(tileset)
}

/// Main game event loop
fn mainloop<'a, I: Iterator<Item = &'a Level>>(
    sdl: &Sdl,
    mut levels: I,
    painter: &mut Painter,
    canvas: &mut Canvas<Window>,
) {
    let (mut reference_level, mut level) = match levels.next() {
        Some(l) => (l, l.clone()),
        None => {
            return;
        }
    };

    let mut running = true;
    let mut events = sdl.event_pump().unwrap();
    let mut skip = false;
    while running {
        if level.is_completed() || skip {
            match levels.next() {
                Some(l) => {
                    reference_level = l;
                    level = l.clone();
                    skip = false;
                }
                None => {
                    break;
                }
            }
        }

        painter.paint(canvas, &level);

        match events.wait_event() {
            Event::Quit { .. }
            | Event::KeyDown {
                keycode: Some(Keycode::Escape),
                ..
            } => running = false,
            Event::KeyDown {
                keycode: Some(Keycode::Left),
                ..
            } => {
                level.step(Direction::Left);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Right),
                ..
            } => {
                level.step(Direction::Right);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Up),
                ..
            } => {
                level.step(Direction::Up);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Down),
                ..
            } => {
                level.step(Direction::Down);
            }
            Event::KeyDown {
                keycode: Some(Keycode::R),
                ..
            } => {
                level = reference_level.clone();
            }
            Event::KeyDown {
                keycode: Some(Keycode::N),
                ..
            } => {
                skip = true;
            }
            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>use std::net::TcpStream;
use std::io::prelude::*;
use std::str;

fn main() {
	let mut connection = TcpStream::connect("127.0.0.1:6667").unwrap();
	let _ = connection.write(b"Hello World\n");
	let mut bytes = connection.bytes();
	const COMMAND_BUF_SIZE: usize = 4096;
	let mut command_buf: [u8; COMMAND_BUF_SIZE] = [0; COMMAND_BUF_SIZE];
	let mut buf_ind = 0;
	let mut command_end = false;
	loop {
		match bytes.next() {
			Some(x) => {
				let next_char = x.unwrap();
				command_buf[buf_ind] = next_char;
				buf_ind = buf_ind + 1;
				if command_end && next_char == 10 {
					parse_command(&command_buf[0..(buf_ind-2)]);
					buf_ind = 0;
					command_end = false;
				} else if next_char == 102 {
					command_end = true;
				} else {
					command_end = false;
				}
				if buf_ind >= COMMAND_BUF_SIZE {
					buf_ind = 0;
				}
			},
			None => break,
		}
	}
}

fn parse_command(command: &[u8]) {
	println!("{}", str::from_utf8(command).unwrap());
}
<commit_msg>Clean up error handling<commit_after>use std::net::TcpStream;
use std::io::prelude::*;
use std::str;

fn main() {
	let connection = TcpStream::connect("127.0.0.1:6667");
	if connection.is_err() {
		return;
	}
	let mut bytes = connection.unwrap().bytes();
	const COMMAND_BUF_SIZE: usize = 4096;
	let mut command_buf: [u8; COMMAND_BUF_SIZE] = [0; COMMAND_BUF_SIZE];
	let mut buf_ind = 0;
	let mut command_end = false;
	loop {
		match bytes.next() {
			Some(x) => {
				if x.is_err() {
					break;
				}
				let next_char = x.unwrap();
				command_buf[buf_ind] = next_char;
				buf_ind = buf_ind + 1;
				if command_end && next_char == 10 {
					parse_command(&command_buf[0..(buf_ind-2)]);
					buf_ind = 0;
					command_end = false;
				} else if next_char == 102 {
					command_end = true;
				} else {
					command_end = false;
				}

				if buf_ind >= COMMAND_BUF_SIZE {
					buf_ind = 0;
				}
			},
			None => break,
		}
	}
}

fn parse_command(command: &[u8]) {
	let command_str = str::from_utf8(command);
	if command_str.is_err() {
		return;
	}
	println!("{}", command_str.unwrap());
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate regex;
extern crate time;

mod error;
mod post;

use clap::{App, Arg, ArgMatches, AppSettings, SubCommand};
use error::{Error, Result};
use regex::Regex;
use std::{env, fs, path};
use std::io::Write;

fn get_open_option(force: bool) -> fs::OpenOptions {
    if force {
        fs::OpenOptions::new().write(true).create(true).truncate(true).clone()
    }
    else {
        fs::OpenOptions::new().write(true).create_new(true).clone()
    }
}

fn init_empty_site(m: &ArgMatches) -> Result<()> {
    let dir = path::Path::new(m.value_of("dir").unwrap_or("."));
    let opt = get_open_option(m.is_present("force"));

    opt.open(dir.join(".config"))
       .map_err(|e| format!("failed to create `.config`: {}", e))?;
    opt.open(dir.join(".nojekyll"))
       .map_err(|e| format!("failed to create `.nojekyll`: {}", e))?;

    fs::DirBuilder::new()
        .recursive(m.is_present("force"))
        .create(dir.join("files"))
        .map_err(|e| format!("failed to create `files`: {}", e))?;

    Ok(())
}

fn create_post(m: &ArgMatches) -> Result<()> {
    let link = m.value_of("link").expect("failed to get the link of post");
    if !Regex::new(r"^[A-Za-z0-9]+(-[A-Za-z0-9]+)?$")?.is_match(link) {
        return Err(Error::from_string(format!("invalid link name `{}'", link)));
    }

    let now = time::now();

    let filename = format!("{}-{}.md", time::strftime("%Y-%m-%d", &now)?, link);
    let opt = get_open_option(m.is_present("force"));
    let mut file = opt.open(&filename)
                      .map_err(|e| format!("failed to create `{}': {}",
                                           filename, e))?;

    file.write(format!("%%\ntitle =\nlink = {}\ntimestamp = {}\n%%\n",
                       link, time::strftime("%Y-%m-%d %H:%M:%S", &now)?)
               .as_bytes())?;

    Ok(())
}

fn main() {
    let app = App::new(env::args().nth(0).unwrap())
        .settings(&[AppSettings::DisableVersion,
                    AppSettings::DeriveDisplayOrder,
                    AppSettings::UnifiedHelpMessage,
                    AppSettings::VersionlessSubcommands])
        .subcommand(SubCommand::with_name("init")
                    .about("Initialize an empty site")
                    .args(&[
                        Arg::from_usage("[dir] 'Directory for the site'"),
                        Arg::from_usage("-f, --force 'Overwrite existing \
                                        site metadata files'")
                    ]))
        .subcommand(SubCommand::with_name("post")
                    .about("Create a new post with the specified link name")
                    .args(&[
                        Arg::from_usage("<link> 'Link name of the post which'"),
                        Arg::from_usage("-f, --force 'Overwrite existing post'")
                    ]))
        .subcommand(SubCommand::with_name("gen")
                    .about("Generate the site"))
        .subcommand(SubCommand::with_name("view")
                    .about("View the site locally"))
        .get_matches();

    let ret = match app.subcommand() {
        ("init", Some(m)) => init_empty_site(m),
        ("gen",  Some(m)) => Ok(()),
        ("post", Some(m)) => create_post(m),
        ("view", Some(m)) => Ok(()),
        _ => Ok(())
    };

    if let Err(e) = ret {
        println!("{}", e)
    }
}
<commit_msg>Fix link name regex<commit_after>extern crate clap;
extern crate regex;
extern crate time;

mod error;
mod post;

use clap::{App, Arg, ArgMatches, AppSettings, SubCommand};
use error::{Error, Result};
use regex::Regex;
use std::{env, fs, path};
use std::io::Write;

fn get_open_option(force: bool) -> fs::OpenOptions {
    if force {
        fs::OpenOptions::new().write(true).create(true).truncate(true).clone()
    }
    else {
        fs::OpenOptions::new().write(true).create_new(true).clone()
    }
}

fn init_empty_site(m: &ArgMatches) -> Result<()> {
    let dir = path::Path::new(m.value_of("dir").unwrap_or("."));
    let opt = get_open_option(m.is_present("force"));

    opt.open(dir.join(".config"))
       .map_err(|e| format!("failed to create `.config`: {}", e))?;
    opt.open(dir.join(".nojekyll"))
       .map_err(|e| format!("failed to create `.nojekyll`: {}", e))?;

    fs::DirBuilder::new()
        .recursive(m.is_present("force"))
        .create(dir.join("files"))
        .map_err(|e| format!("failed to create `files`: {}", e))?;

    Ok(())
}

fn create_post(m: &ArgMatches) -> Result<()> {
    let link = m.value_of("link").expect("failed to get the link of post");
    if !Regex::new(r"^[A-Za-z0-9]+(-[A-Za-z0-9]+)*$")?.is_match(link) {
        return Err(Error::from_string(format!("invalid link name `{}'", link)));
    }

    let now = time::now();

    let filename = format!("{}-{}.md", time::strftime("%Y-%m-%d", &now)?, link);
    let opt = get_open_option(m.is_present("force"));
    let mut file = opt.open(&filename)
                      .map_err(|e| format!("failed to create `{}': {}",
                                           filename, e))?;

    file.write(format!("%%\ntitle =\nlink = {}\ntimestamp = {}\n%%\n",
                       link, time::strftime("%Y-%m-%d %H:%M:%S", &now)?)
               .as_bytes())?;

    Ok(())
}

fn main() {
    let app = App::new(env::args().nth(0).unwrap())
        .settings(&[AppSettings::DisableVersion,
                    AppSettings::DeriveDisplayOrder,
                    AppSettings::UnifiedHelpMessage,
                    AppSettings::VersionlessSubcommands])
        .subcommand(SubCommand::with_name("init")
                    .about("Initialize an empty site")
                    .args(&[
                        Arg::from_usage("[dir] 'Directory for the site'"),
                        Arg::from_usage("-f, --force 'Overwrite existing \
                                        site metadata files'")
                    ]))
        .subcommand(SubCommand::with_name("post")
                    .about("Create a new post with the specified link name")
                    .args(&[
                        Arg::from_usage("<link> 'Link name of the post which'"),
                        Arg::from_usage("-f, --force 'Overwrite existing post'")
                    ]))
        .subcommand(SubCommand::with_name("gen")
                    .about("Generate the site"))
        .subcommand(SubCommand::with_name("view")
                    .about("View the site locally"))
        .get_matches();

    let ret = match app.subcommand() {
        ("init", Some(m)) => init_empty_site(m),
        ("gen",  Some(m)) => Ok(()),
        ("post", Some(m)) => create_post(m),
        ("view", Some(m)) => Ok(()),
        _ => Ok(())
    };

    if let Err(e) = ret {
        println!("{}", e)
    }
}
<|endoftext|>


<commit_before>extern crate iron;
#[macro_use]
extern crate router;
extern crate staticfile;
extern crate mount;
extern crate urlencoded;
extern crate rustc_serialize;
extern crate html5ever;
extern crate regex;
extern crate uuid;

use std::net::SocketAddrV4;
use std::net::Ipv4Addr;
use std::path::Path;
use iron::prelude::*;
use iron::status;
use iron::mime::Mime;
use staticfile::Static;
use mount::Mount;
use router::{Router};
use urlencoded::UrlEncodedQuery;
use urlencoded::UrlEncodedBody;
use std::str::FromStr;

#[macro_use]
extern crate string_cache;
extern crate pink_spider;

use pink_spider::error::Error;
use pink_spider::scraper::extract;
use pink_spider::model::{Track, Entry, Provider};
use rustc_serialize::json::{ToJson, Json};

pub fn index_entries(req: &mut Request) -> IronResult<Response> {
    let (page, per_page) = pagination_params(req);
    let entries          = Entry::find(page, per_page);
    let json_obj: Json   = entries.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn index_tracks(req: &mut Request) -> IronResult<Response> {
    let (page, per_page) = pagination_params(req);
    let tracks  = Track::find(page, per_page);
    let json_obj: Json   = tracks.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn playlistify(req: &mut Request) -> IronResult<Response> {
    pub fn playlistify2(req: &mut Request) -> Result<Response, Error> {
        let ref params  = try!(req.get_ref::<UrlEncodedQuery>());
        let url         = try!(params.get("url").ok_or(Error::BadRequest));
        let defaults    = &vec!("false".to_string());
        let force_param = params.get("force").unwrap_or(defaults);
        let force       = force_param.len() > 0 && &force_param[0] == "true";
        let entry       = try!(find_or_playlistify_entry(&url[0], force));
        let json_obj    = entry.to_json() as Json;
        let json_str    = json_obj.to_string() as String;
        Ok(Response::with((status::Ok, application_json(), json_str)))
    }
    playlistify2(req).map_err(|err| IronError::from(err))
}

pub fn find_or_playlistify_entry(url: &str, force: bool) -> Result<Entry, Error> {
    match Entry::find_by_url(url) {
        Ok(entry) => {
            println!("Get entry from database cache: {}", url);
            if force {
                println!("Update entry: {}", url);
                let entry = try!(playlistify_entry(entry));
                Ok(entry)
            } else {
                Ok(entry)
            }
        },
        Err(_) => {
            let entry = try!(Entry::create_by_url(url.to_string()));
            let entry = try!(playlistify_entry(entry));
            println!("Create new entry to database cache: {}", url);
            Ok(entry)
        },
    }
}

pub fn playlistify_entry(entry: Entry) -> Result<Entry, Error> {
    let mut e = entry.clone();
    let product = try!(extract(&entry.url));
    match product.og_obj {
        Some(og_obj) => {
            e.title       = Some(og_obj.title);
            e.description = og_obj.description;
            e.locale      = og_obj.locale;
            e.visual_url  = og_obj.images.first().map(|i| i.url.clone());
        },
        None => (),
    }
    for t in product.tracks {
        let track = try!(Track::find_or_create(t.provider,
                                               t.title,
                                               t.url,
                                               t.identifier));
        match entry.tracks.iter().find(|&t| t.id == track.id) {
            Some(_) => (),
            None    => e.add_track(track.clone())
        }
    }
    try!(e.save());
    Ok(e)
}

pub fn show_track(req: &mut Request) -> IronResult<Response> {
    let ref track_id = req.extensions.get::<Router>().unwrap()
                          .find("track_id").unwrap();
    match Track::find_by_id(track_id) {
        Ok(track) => {
            Ok(Response::with((status::Ok,
                               application_json(),
                               track.to_json().to_string())))
        },
        Err(e) => Ok(e.as_response())
    }
}

pub fn show_track_by_provider_id(req: &mut Request) -> IronResult<Response> {
    let provider   = req.extensions.get::<Router>().unwrap().find("provider").unwrap();
    let identifier = req.extensions.get::<Router>().unwrap().find("id").unwrap();
    let p = &Provider::new(provider.to_string());
    match Track::find_by(p, identifier) {
        Ok(track) => {
            Ok(Response::with((status::Ok,
                               application_json(),
                               track.to_json().to_string())))
        },
        Err(e) => Ok(e.as_response())
    }
}

pub fn update_track(req: &mut Request) -> IronResult<Response> {
    let mut track = try!(Track::find_by_id(&query_as_string(req, "track_id")));
    match param_as_string(req, "title") {
        Some(title) => track.title = title,
        None        => println!("no title")
    }
    match param_as_string(req, "url") {
        Some(url) => track.url = url,
        None      => println!("no url")
    }
    try!(track.save());
    let res = track.to_json().to_string();
    Ok(Response::with((status::Ok, application_json(), res)))
}

fn param_as_string(req: &mut Request, key: &str) -> Option<String> {
    match req.get_ref::<UrlEncodedBody>() {
        Ok(ref params) => match params.get(key) {
            Some(val) => Some(val[0].clone()),
            None      => None
        },
        Err(_) => None
    }
}

fn query_as_string(req: &mut Request, key: &str) -> String {
    return req.extensions.get::<Router>().unwrap()
        .find(key).unwrap().to_string();
}

fn pagination_params(req: &mut Request) -> (i64, i64) {
    match req.get_ref::<UrlEncodedQuery>() {
        Ok(ref params) =>
            (params.get("page").unwrap()[0].to_string().parse::<i64>().unwrap(),
             params.get("per_page").unwrap()[0].to_string().parse::<i64>().unwrap()),
        Err(_) =>
            (0, 10)
    }
}

fn application_json() -> Mime {
    Mime::from_str("application/json").ok().unwrap()
}

pub fn main() {
    let path = Path::new("public");
    let mut mount = Mount::new();
    mount.mount("/web/", Static::new(Path::new(path)));
    let router = router!(
                         playlistify: get  "/playlistify"          => playlistify,
                          show_track: get  "/tracks/:track_id"     => show_track,
                        update_track: post "/tracks/:track_id"     => update_track,
           show_track_by_provider_id: get  "/tracks/:provider/:id" => show_track_by_provider_id,
                       index_entries: get  "/entries"              => index_entries,
                        index_tracks: get  "/tracks"               => index_tracks,
                                 web: get  "/*"                    => mount,
    );
    let port_str = match std::env::var("PORT") {
        Ok(n)    => n,
        Err(_) => "8080".to_string()
    };
    let port: u16 = match port_str.trim().parse() {
        Ok(n) => n,
        Err(_) => {
            println!("Faild to parse port");
            return;
        }
    };
    println!("PORT {}", port_str);
    let ip = Ipv4Addr::new(0, 0, 0, 0);
    Iron::new(router).http(SocketAddrV4::new(ip, port)).unwrap();
}
<commit_msg>Refactor router<commit_after>extern crate iron;
#[macro_use]
extern crate router;
extern crate staticfile;
extern crate mount;
extern crate urlencoded;
extern crate rustc_serialize;
extern crate html5ever;
extern crate regex;
extern crate uuid;

use std::net::SocketAddrV4;
use std::net::Ipv4Addr;
use std::path::Path;
use iron::prelude::*;
use iron::status;
use iron::mime::Mime;
use staticfile::Static;
use mount::Mount;
use router::{Router};
use urlencoded::UrlEncodedQuery;
use urlencoded::UrlEncodedBody;
use std::str::FromStr;

#[macro_use]
extern crate string_cache;
extern crate pink_spider;

use pink_spider::error::Error;
use pink_spider::scraper::extract;
use pink_spider::model::{Track, Entry, Provider};
use rustc_serialize::json::{ToJson, Json};

pub fn index_entries(req: &mut Request) -> IronResult<Response> {
    let (page, per_page) = pagination_params(req);
    let entries          = Entry::find(page, per_page);
    let json_obj: Json   = entries.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn index_tracks(req: &mut Request) -> IronResult<Response> {
    let (page, per_page) = pagination_params(req);
    let tracks  = Track::find(page, per_page);
    let json_obj: Json   = tracks.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn playlistify(req: &mut Request) -> IronResult<Response> {
    pub fn playlistify2(req: &mut Request) -> Result<Response, Error> {
        let ref params  = try!(req.get_ref::<UrlEncodedQuery>());
        let url         = try!(params.get("url").ok_or(Error::BadRequest));
        let defaults    = &vec!("false".to_string());
        let force_param = params.get("force").unwrap_or(defaults);
        let force       = force_param.len() > 0 && &force_param[0] == "true";
        let entry       = try!(find_or_playlistify_entry(&url[0], force));
        let json_obj    = entry.to_json() as Json;
        let json_str    = json_obj.to_string() as String;
        Ok(Response::with((status::Ok, application_json(), json_str)))
    }
    playlistify2(req).map_err(|err| IronError::from(err))
}

pub fn find_or_playlistify_entry(url: &str, force: bool) -> Result<Entry, Error> {
    match Entry::find_by_url(url) {
        Ok(entry) => {
            println!("Get entry from database cache: {}", url);
            if force {
                println!("Update entry: {}", url);
                let entry = try!(playlistify_entry(entry));
                Ok(entry)
            } else {
                Ok(entry)
            }
        },
        Err(_) => {
            let entry = try!(Entry::create_by_url(url.to_string()));
            let entry = try!(playlistify_entry(entry));
            println!("Create new entry to database cache: {}", url);
            Ok(entry)
        },
    }
}

pub fn playlistify_entry(entry: Entry) -> Result<Entry, Error> {
    let mut e = entry.clone();
    let product = try!(extract(&entry.url));
    match product.og_obj {
        Some(og_obj) => {
            e.title       = Some(og_obj.title);
            e.description = og_obj.description;
            e.locale      = og_obj.locale;
            e.visual_url  = og_obj.images.first().map(|i| i.url.clone());
        },
        None => (),
    }
    for t in product.tracks {
        let track = try!(Track::find_or_create(t.provider,
                                               t.title,
                                               t.url,
                                               t.identifier));
        match entry.tracks.iter().find(|&t| t.id == track.id) {
            Some(_) => (),
            None    => e.add_track(track.clone())
        }
    }
    try!(e.save());
    Ok(e)
}

pub fn show_track_by_id(req: &mut Request) -> IronResult<Response> {
    let ref track_id = req.extensions.get::<Router>().unwrap()
                          .find("track_id").unwrap();
    match Track::find_by_id(track_id) {
        Ok(track) => {
            Ok(Response::with((status::Ok,
                               application_json(),
                               track.to_json().to_string())))
        },
        Err(e) => Ok(e.as_response())
    }
}

pub fn show_track(req: &mut Request) -> IronResult<Response> {
    let provider   = req.extensions.get::<Router>().unwrap().find("provider").unwrap();
    let identifier = req.extensions.get::<Router>().unwrap().find("id").unwrap();
    let p = &Provider::new(provider.to_string());
    match Track::find_by(p, identifier) {
        Ok(track) => {
            Ok(Response::with((status::Ok,
                               application_json(),
                               track.to_json().to_string())))
        },
        Err(e) => Ok(e.as_response())
    }
}

pub fn update_track(req: &mut Request) -> IronResult<Response> {
    let mut track = try!(Track::find_by_id(&query_as_string(req, "track_id")));
    match param_as_string(req, "title") {
        Some(title) => track.title = title,
        None        => println!("no title")
    }
    match param_as_string(req, "url") {
        Some(url) => track.url = url,
        None      => println!("no url")
    }
    try!(track.save());
    let res = track.to_json().to_string();
    Ok(Response::with((status::Ok, application_json(), res)))
}

fn param_as_string(req: &mut Request, key: &str) -> Option<String> {
    match req.get_ref::<UrlEncodedBody>() {
        Ok(ref params) => match params.get(key) {
            Some(val) => Some(val[0].clone()),
            None      => None
        },
        Err(_) => None
    }
}

fn query_as_string(req: &mut Request, key: &str) -> String {
    return req.extensions.get::<Router>().unwrap()
        .find(key).unwrap().to_string();
}

fn pagination_params(req: &mut Request) -> (i64, i64) {
    match req.get_ref::<UrlEncodedQuery>() {
        Ok(ref params) =>
            (params.get("page").unwrap()[0].to_string().parse::<i64>().unwrap(),
             params.get("per_page").unwrap()[0].to_string().parse::<i64>().unwrap()),
        Err(_) =>
            (0, 10)
    }
}

fn application_json() -> Mime {
    Mime::from_str("application/json").ok().unwrap()
}

pub fn main() {
    let path = Path::new("public");
    let mut mount = Mount::new();
    mount.mount("/web/", Static::new(Path::new(path)));
    let router = router!(
        playlistify:      get  "/playlistify"          => playlistify,
        show_track_by_id: get  "/tracks/:track_id"     => show_track_by_id,
        update_track:     post "/tracks/:track_id"     => update_track,
        show_track:       get  "/tracks/:provider/:id" => show_track,
        index_entries:    get  "/entries"              => index_entries,
        index_tracks:     get  "/tracks"               => index_tracks,
        web:              get  "/*"                    => mount,
    );
    let port_str = match std::env::var("PORT") {
        Ok(n)    => n,
        Err(_) => "8080".to_string()
    };
    let port: u16 = match port_str.trim().parse() {
        Ok(n) => n,
        Err(_) => {
            println!("Faild to parse port");
            return;
        }
    };
    println!("PORT {}", port_str);
    let ip = Ipv4Addr::new(0, 0, 0, 0);
    Iron::new(router).http(SocketAddrV4::new(ip, port)).unwrap();
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate linkerd_tcp;

use clap::{Arg, App};
use linkerd_tcp::app::{self, Runner};
use std::fs;
use std::io::Read;
use std::thread;

fn main() {
    // Configure the logger from the RUST_LOG environment variable.
    drop(env_logger::init());

    // Parse and load command-line options.
    let opts = mk_app().get_matches();
    let config_path = opts.value_of(CONFIG_PATH_ARG).unwrap();
    let config_str: String = {
        let mut s = String::new();
        fs::File::open(config_path)
            .unwrap()
            .read_to_string(&mut s)
            .unwrap();
        s
    };

    let config = app::config::from_str(&config_str).expect("configuration error");

    // Process the configuration, splitting it into two threads. These threads are
    // connected by synchronization primitives as needed, but no work is being done yet.
    // Next, we'll attach each of these to a reactor in an independent thread, driving
    // both admin and serving work.
    let (admin, proxies) = app::configure(config);

    // Run admin in a new thread.
    let admin_thread = thread::Builder::new()
        .name("admin".into())
        .spawn(move || admin.run().expect("could not run admin"))
        .expect("could not spawn admin thread");

    proxies.run().expect("could not run proxies");
    admin_thread.join().expect("admin thread failed to join");
    info!("Closing.")
}

static CONFIG_PATH_ARG: &'static str = "PATH";

fn mk_app() -> App<'static, 'static> {
    App::new(crate_name!())
        .version(crate_version!())
        .about(crate_description!())
        .arg(Arg::with_name(CONFIG_PATH_ARG)
            .required(true)
            .index(1)
            .help("Config file path."))
}
<commit_msg>Reorganize main.rs for clarity<commit_after>#[macro_use]
extern crate clap;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate linkerd_tcp;

use clap::{Arg, App};
use linkerd_tcp::app::{self, Runner};
use std::fs;
use std::io::Read;
use std::thread;

static CONFIG_PATH_ARG: &'static str = "PATH";

fn main() {
    // Configure the logger from the RUST_LOG environment variable.
    drop(env_logger::init());

    // Load command-line options.
    let opts = App::new(crate_name!())
        .version(crate_version!())
        .about(crate_description!())
        .arg(Arg::with_name(CONFIG_PATH_ARG)
            .required(true)
            .index(1)
            .help("Config file path."))
        .get_matches();

    // Parse configuration file.
    let config = {
        let path = opts.value_of(CONFIG_PATH_ARG).unwrap();
        let mut txt = String::new();
        fs::File::open(path)
            .unwrap()
            .read_to_string(&mut txt)
            .expect("failed to read config");
        app::config::from_str(&txt).expect("configuration error")
    };

    // Process the configuration, splitting it into two threads. These threads are
    // connected by synchronization primitives as needed, but no work is being done yet.
    // Next, we'll attach each of these to a reactor in an independent thread, driving
    // both admin and serving work.
    let (admin, proxies) = app::configure(config);

    // Run admin in a new thread.
    let admin_thread = thread::Builder::new()
        .name("admin".into())
        .spawn(move || admin.run().expect("could not run admin"))
        .expect("could not spawn admin thread");

    proxies.run().expect("could not run proxies");
    admin_thread.join().expect("admin thread failed to join");
    info!("Closing.")
}
<|endoftext|>


<commit_before>extern crate docopt;
extern crate serde_json;
extern crate vegas_lattice;

use std::error::Error;
use std::fs::File;
use std::io::{self, Read};

use docopt::{ArgvMap, Docopt};
use vegas_lattice::{Axis, Lattice};

const USAGE: &'static str = "
Vegas lattice.

Usage:
    vegas-lattice check [<input>]
    vegas-lattice compress [<input>]
    vegas-lattice drop [-x -y -z] [<input>]
    vegas-lattice expand [--x=<x> --y=<y> --z=<z>] [<input>]
    vegas-lattice (-h | --help)
    vegas-lattice --version

Options:
    -h --help       Show this message.
    --version       Show version and exit.
";

fn read(input: &str) -> Result<Lattice, Box<Error>> {
    let mut data = String::new();
    if !input.is_empty() {
        let mut file = File::open(input)?;
        file.read_to_string(&mut data)?;
    } else {
        io::stdin().read_to_string(&mut data)?;
    };
    let lattice: Lattice = data.parse()?;
    Ok(lattice)
}

fn write_compressed(lattice: Lattice) {
    println!("{}", serde_json::to_string(&lattice).unwrap());
}

fn write(lattice: Lattice) {
    println!("{}", serde_json::to_string_pretty(&lattice).unwrap());
}

fn check(args: ArgvMap) -> Result<(), Box<Error>> {
    let lattice = read(args.get_str("<input>"))?;
    write(lattice);
    Ok(())
}

fn compress(args: ArgvMap) -> Result<(), Box<Error>> {
    let lattice = read(args.get_str("<input>"))?;
    write_compressed(lattice);
    Ok(())
}

fn drop(args: ArgvMap) -> Result<(), Box<Error>> {
    let mut lattice = read(args.get_str("<input>"))?;
    if args.get_bool("-x") {
        lattice = lattice.drop(Axis::X);
    }
    if args.get_bool("-y") {
        lattice = lattice.drop(Axis::Y);
    }
    if args.get_bool("-z") {
        lattice = lattice.drop(Axis::Z);
    }
    write(lattice);
    Ok(())
}

fn axis_map<'a>() -> Vec<(&'a str, Axis)> {
    vec![("--x", Axis::X), ("--y", Axis::Y), ("--z", Axis::Z)]
}

fn expand(args: ArgvMap) -> Result<(), Box<Error>> {
    let map = axis_map();
    let mut lattice = read(args.get_str("<input>"))?;
    for (flag, axis) in map.into_iter() {
        let string_value = args.get_str(flag);
        if !string_value.is_empty() {
            let size: usize = string_value.parse()?;
            lattice = lattice.expand_along(axis, size);
        }
    }
    write(lattice);
    Ok(())
}

fn check_error(res: Result<(), Box<Error>>) {
    match res {
        Err(e) => {
            eprintln!("{}", e);
            std::process::exit(1);
        },
        _ => {},
    }
}

fn main() {
    let args = Docopt::new(USAGE)
        .and_then(|doc| doc.version(Some("0.0.1".to_string())).parse())
        .unwrap_or_else(|e| e.exit());

    if args.get_bool("check") {
        check_error(check(args));
    } else if args.get_bool("compress") {
        check_error(compress(args));
    } else if args.get_bool("drop") {
        check_error(drop(args));
    } else if args.get_bool("expand") {
        check_error(expand(args));
    } else {
        println!("{:?}", args);
    }
}<commit_msg>Refactor those things.<commit_after>extern crate docopt;
extern crate serde_json;
extern crate vegas_lattice;

use std::error::Error;
use std::fs::File;
use std::io::{self, Read};

use docopt::{ArgvMap, Docopt};
use vegas_lattice::{Axis, Lattice};

const USAGE: &'static str = "
Vegas lattice.

Usage:
    vegas-lattice check [<input>]
    vegas-lattice compress [<input>]
    vegas-lattice drop [-x -y -z] [<input>]
    vegas-lattice expand [--x=<x> --y=<y> --z=<z>] [<input>]
    vegas-lattice (-h | --help)
    vegas-lattice --version

Options:
    -h --help       Show this message.
    --version       Show version and exit.
";

fn read(input: &str) -> Result<Lattice, Box<Error>> {
    let mut data = String::new();
    if !input.is_empty() {
        let mut file = File::open(input)?;
        file.read_to_string(&mut data)?;
    } else {
        io::stdin().read_to_string(&mut data)?;
    };
    let lattice: Lattice = data.parse()?;
    Ok(lattice)
}

fn write_compressed(lattice: Lattice) {
    println!("{}", serde_json::to_string(&lattice).unwrap());
}

fn write(lattice: Lattice) {
    println!("{}", serde_json::to_string_pretty(&lattice).unwrap());
}

fn check(args: ArgvMap) -> Result<(), Box<Error>> {
    let lattice = read(args.get_str("<input>"))?;
    write(lattice);
    Ok(())
}

fn compress(args: ArgvMap) -> Result<(), Box<Error>> {
    let lattice = read(args.get_str("<input>"))?;
    write_compressed(lattice);
    Ok(())
}

fn axis_map<'a>(prefix: Option<String>) -> Vec<(String, Axis)> {
    let axes = vec![("x", Axis::X), ("y", Axis::Y), ("z", Axis::Z)];
    match prefix {
        Some(p) => axes.into_iter().map(|(k, i)| (format!("{}{}", p, k), i)).collect(),
        None => axes.into_iter().map(|(k, i)| (k.to_string(), i)).collect(),
    }
}

fn drop(args: ArgvMap) -> Result<(), Box<Error>> {
    let mut lattice = read(args.get_str("<input>"))?;
    for (key, axis) in axis_map(Some("-".to_string())) {
        if args.get_bool(&key) {
            lattice = lattice.drop(axis);
        }
    }
    write(lattice);
    Ok(())
}

fn expand(args: ArgvMap) -> Result<(), Box<Error>> {
    let map = axis_map(Some("--".to_string()));
    let mut lattice = read(args.get_str("<input>"))?;
    for (flag, axis) in map.into_iter() {
        let string_value = args.get_str(&flag);
        if !string_value.is_empty() {
            let size: usize = string_value.parse()?;
            lattice = lattice.expand_along(axis, size);
        }
    }
    write(lattice);
    Ok(())
}

fn check_error(res: Result<(), Box<Error>>) {
    match res {
        Err(e) => {
            eprintln!("{}", e);
            std::process::exit(1);
        },
        _ => {},
    }
}

fn main() {
    let args = Docopt::new(USAGE)
        .and_then(|doc| doc.version(Some("0.0.1".to_string())).parse())
        .unwrap_or_else(|e| e.exit());

    if args.get_bool("check") {
        check_error(check(args));
    } else if args.get_bool("compress") {
        check_error(compress(args));
    } else if args.get_bool("drop") {
        check_error(drop(args));
    } else if args.get_bool("expand") {
        check_error(expand(args));
    } else {
        println!("{:?}", args);
    }
}<|endoftext|>


<commit_before>extern crate sdl2;
extern crate sdl2_image;
extern crate chrono;
extern crate conv;
#[macro_use]
extern crate json;

mod game;
mod views;
mod data;

fn main() {
  ::game::spawn("Hacknslash", |game| {
    Box::new(::views::GameView::new(game))
  });
}
<commit_msg>Remove dead code<commit_after>extern crate sdl2;
extern crate sdl2_image;
extern crate chrono;
extern crate conv;
#[macro_use]
extern crate json;

mod game;
mod views;
mod data;

fn main() {
  game::spawn("Hacknslash", |game| {
    Box::new(views::GameView::new(game))
  });
}
<|endoftext|>


<commit_before>/// A genetic algorithm in Rust
/// Copyright (C) 2015  Andrew Schwartzmeyer

#[macro_use]
extern crate clap;
extern crate rand;
extern crate time;

use clap::App;
use rand::Rng;
use rand::distributions;
use time::precise_time_s;
use std::thread;
use individual::Individual;

mod individual;

/// Tournament selection from 4 random individuals
fn select<R: Rng>(population: &[Individual], rng: &mut R) -> Individual {
    if let Some(selected) = (0..4).map(|_| rng.choose(population)).min() {
        selected.unwrap().clone()
    } else {
        unimplemented!();
    }
}

/// Setup and run algorithm to search for solution
fn main() {
    let matches = App::new("rust-genetic-algorithm")
        .version(&crate_version!()[..])
        .author("Andrew Schwartzmeyer <andrew@schwartzmeyer.com")
        .about("A genetic algorithm in Rust for Schwefel's function.")
        .args_from_usage(
            "[-d --dimension <30>] 'Sets the dimension of the hypercube'
             [-p --population <256>] 'Sets the size of the population'
             [-i --iterations <5000>] 'Sets maximum number of generations'
             --verbose 'Print fitness every 10th generation'")
        .get_matches();
    let dimension = value_t!(matches.value_of("d"), usize).unwrap_or(30);
    let population_size = value_t!(matches.value_of("p"), usize).unwrap_or(256);
    let iterations = value_t!(matches.value_of("i"), usize).unwrap_or(5000);
    let verbose = matches.is_present("verbose");

    let mut rng = rand::thread_rng();
    let range = distributions::Range::new(-500_f64, 500_f64);

    // initialize population individuals
    let mut population: Vec<_> = (0..population_size).map(|_| {
        Individual::new(dimension, &range, &mut rng)
    }).collect();

    let start_time = precise_time_s();
    // search with generations
    for i in 0..iterations {
        // select, mutate, and recombine individuals for next generation
        let mut offspring: Vec<Individual> = Vec::with_capacity(population.len());
        for _ in 0..population.len()/2 {
            let (mut x, mut y) = (select(&population, &mut rng),
                                  select(&population, &mut rng));
            x.mutate(&range, &mut rng);
            y.mutate(&range, &mut rng);
            Individual::combine(&mut x, &mut y, &mut rng);
            offspring.push(x);
            offspring.push(y);
        }
        assert!(offspring.len() == population.len());

        // replace 2 random individuals with elite of prior generation
        for _ in 0..2 {
            if let Some(x) = population.iter().min() {
                offspring[rng.gen_range(0, population.len())] = x.clone();
            }
        }

        // replace population with next generation
        population = offspring;

        // examine best individual for convergence
        if let Some(x) = population.iter().min() {
            if verbose && i % 10 == 0 {
                let fitness = x.fitness;
                thread::spawn(move || {
                    println!("{}th fitness {}", i, fitness)
                });
            }
            if x.fitness < 0.05_f64 {
                let duration = precise_time_s() - start_time;
                println!("{}th solution converged at {} in {} seconds: {:?}",
                         i, x.fitness, duration, x.solution);
                return;
            }
        } else { unimplemented!() }
    }
    println!("Failed to converge.");
}
<commit_msg>Add enum Problem for positional argument<commit_after>/// A genetic algorithm in Rust
/// Copyright (C) 2015  Andrew Schwartzmeyer

#[macro_use]
extern crate clap;
extern crate rand;
extern crate time;

use clap::App;
use rand::Rng;
use rand::distributions;
use time::precise_time_s;
use std::thread;
use individual::Individual;

mod individual;

arg_enum!{
    #[derive(Copy, Clone)]
    pub enum Problem {
        Schwefel
    }
}

/// Tournament selection from 4 random individuals
fn select<R: Rng>(population: &[Individual], rng: &mut R) -> Individual {
    if let Some(selected) = (0..4).map(|_| rng.choose(population)).min() {
        selected.unwrap().clone()
    } else {
        unimplemented!();
    }
}

/// Setup and run algorithm to search for solution
fn main() {
    let matches = App::new("rust-genetic-algorithm")
        .version(&crate_version!()[..])
        .author("Andrew Schwartzmeyer <andrew@schwartzmeyer.com")
        .about("A genetic algorithm in Rust for Schwefel's function.")
        .args_from_usage(
            "[<problem>] 'The problem to solve'
             [-d --dimension <30>] 'Sets the dimension of the hypercube'
             [-p --population <256>] 'Sets the size of the population'
             [-i --iterations <5000>] 'Sets maximum number of generations'
             --verbose 'Print fitness every 10th generation'")
        .get_matches();
    let problem = value_t!(matches.value_of("problem"), Problem)
        .unwrap_or(Problem::Schwefel);
    let dimension = value_t!(matches.value_of("d"), usize).unwrap_or(30);
    let population_size = value_t!(matches.value_of("p"), usize).unwrap_or(256);
    let iterations = value_t!(matches.value_of("i"), usize).unwrap_or(5000);
    let verbose = matches.is_present("verbose");

    let mut rng = rand::thread_rng();
    let range = distributions::Range::new(-500_f64, 500_f64);

    // initialize population individuals
    let mut population: Vec<_> = (0..population_size).map(|_| {
        Individual::new(dimension, &range, &mut rng)
    }).collect();

    let start_time = precise_time_s();
    // search with generations
    for i in 0..iterations {
        // select, mutate, and recombine individuals for next generation
        let mut offspring: Vec<Individual> = Vec::with_capacity(population.len());
        for _ in 0..population.len()/2 {
            let (mut x, mut y) = (select(&population, &mut rng),
                                  select(&population, &mut rng));
            x.mutate(&range, &mut rng);
            y.mutate(&range, &mut rng);
            Individual::combine(&mut x, &mut y, &mut rng);
            offspring.push(x);
            offspring.push(y);
        }
        assert!(offspring.len() == population.len());

        // replace 2 random individuals with elite of prior generation
        for _ in 0..2 {
            if let Some(x) = population.iter().min() {
                offspring[rng.gen_range(0, population.len())] = x.clone();
            }
        }

        // replace population with next generation
        population = offspring;

        // examine best individual for convergence
        if let Some(x) = population.iter().min() {
            if verbose && i % 10 == 0 {
                let fitness = x.fitness;
                thread::spawn(move || {
                    println!("{}th fitness {}", i, fitness)
                });
            }
            if x.fitness < 0.05_f64 {
                let duration = precise_time_s() - start_time;
                println!("{}th solution converged at {} in {} seconds: {:?}",
                         i, x.fitness, duration, x.solution);
                return;
            }
        } else { unimplemented!() }
    }
    println!("Failed to converge.");
}
<|endoftext|>


<commit_before>#![feature(io, slice_patterns, vec_resize)]
use std::collections::BTreeMap;
use std::fs;
use std::io;
use std::io::{Read, Write};
use std::path::Path;

#[derive(Debug)]
enum ParserResult {
    Something(Op),
    Nothing,
    EOF
}

use ParserResult::*;

#[derive(Debug)]
enum Op {
    Add(u8),
    Mov(isize),
    In,
    Out,
    Loop(OpStream),

    // extra optimized ops
    Transfer(u8, Vec<(isize, u8)>)
}

use Op::*;

#[derive(Debug)]
struct OpStream {
    ops: Vec<Op>
}

impl OpStream {
    fn add(&mut self, op: Op) {
        self.ops.push(op);
    }

    fn optimize(&mut self) {
        let mut i = 0;
        while i < self.ops.len() {
            match &self.ops[i..] {
                [Add(a), Add(b), ..] => {
                    self.ops[i] = Add(a.wrapping_add(b));
                    self.ops.remove(i + 1);
                }
                [Mov(a), Mov(b), ..] => {
                    self.ops[i] = Mov(a + b);
                    self.ops.remove(i + 1);
                }
                [Add(0), ..] | [Mov(0), ..] => {
                    self.ops.remove(i);
                }
                [Loop(_), ..] => {
                    let mut maybe_new_op = None;

                    if let &mut Loop(ref mut stream) = &mut self.ops[i] {
                        stream.optimize();
                        maybe_new_op = stream.find_alternative();
                    }

                    if let Some(new_op) = maybe_new_op {
                        self.ops[i] = new_op;
                    }

                    i += 1
                }
                _ => i += 1
            }
        }
    }

    fn find_alternative(&self) -> Option<Op> {
        let mut map: BTreeMap<isize, u8> = BTreeMap::new();
        let mut rel_index = 0;

        for op in &self.ops[..] {
            match op {
                &Add(x) => {
                    let new_val = map.get(&rel_index).unwrap_or(&0).wrapping_add(x);
                    map.insert(rel_index, new_val);
                }
                &Mov(x) => {
                    rel_index += x;
                }
                _ => {
                    return None;
                }
            }
        }

        if rel_index != 0 {
            return None;
        }

        match map.remove(&0) {
            Some(summand) => Some(Transfer(summand, map.into_iter().collect())),
            None => None
        }
    }

    fn get(&self) -> &[Op] {
        &self.ops[..]
    }

    fn new() -> OpStream {
        OpStream { ops: Vec::new() }
    }
}

static ZERO: u8 = 0;

struct State {
    index: usize,
    memory: Vec<u8>
}

impl State {
    fn new() -> State {
        State { index: 0, memory: vec![] }
    }

    fn rel_index(&self, relative: isize) -> usize {
        (self.index as isize + relative) as usize
    }

    fn step(&mut self, op: &Op) -> bool {
        match op {
            &Add(i) => {
                self[0] = self[0].wrapping_add(i);
            }
            &Mov(n) => {
                self.index = self.rel_index(n);
            }
            &In => {
                let mut c = [0u8];
                if io::stdin().read(&mut c).unwrap() == 0 {
                    return false;
                }
                self[0] = c[0];
            }
            &Out => {
                io::stdout().write(&[self[0]]).unwrap();
            }
            &Loop(ref ops) => {
                while self[0] != 0 {
                    if !self.run(ops.get()) {
                        return false;
                    }
                }
            }
            &Transfer(d, ref map) => {
                let n = match (self[0], d) {
                    (0, _) => 0,
                    (x, 0xff) => x,
                    (x, 0x01) => 0u8.wrapping_sub(x),
                    (x, _) => {
                        let mut _v = x;
                        let mut _n = 0;
                        while _v != 0 {
                            _v = _v.wrapping_add(d);
                            _n += 1
                        }
                        _n
                    }
                };

                if n > 0 {
                    self[0] = 0;
                    for &(k, v) in &map[..] {
                        self[k] = self[k].wrapping_add(v.wrapping_mul(n));
                    }
                }
            }
        }
        return true;
    }

    fn run(&mut self, ops: &[Op]) -> bool {
        for op in ops {
            if !self.step(op) {
                return false;
            }
        }
        return true;
    }
}

impl std::ops::Index<isize> for State {
    type Output = u8;
    fn index(&self, _index: isize) -> &u8 {
        let idx = self.rel_index(_index);
        if idx >= self.memory.len() {
            &ZERO
        } else {
            &self.memory[idx]
        }
    }
}

impl std::ops::IndexMut<isize> for State {
    fn index_mut(&mut self, _index: isize) -> &mut u8 {
        let idx = self.rel_index(_index);
        if idx >= self.memory.len() {
            self.memory.resize(idx * 2 + 1, 0);
        }
        &mut self.memory[idx]
    }
}

fn main() {
    let filenames: Vec<String> = std::iter::FromIterator::from_iter(std::env::args());

    for filename in &filenames[1..] {
        match reader(&Path::new(filename)) {
            Ok(reader) => {
                let mut chars = reader.chars().peekable();

                let mut opstream = OpStream::new();
                loop {
                    match parse(&mut chars) {
                        Something(op) => opstream.add(op),
                        EOF => break,
                        _ => {}
                    }
                }

                opstream.optimize();

                State::new().run(opstream.get());
            }
            Err(e) => {
                writeln!(&mut io::stderr(), "Error while processing {}: {}", filename, e).unwrap();
            }
        }
    }
}

fn parse<T: io::Read>(mut chars: &mut std::iter::Peekable<io::Chars<T>>) -> ParserResult {
    match chars.next() {
        Some(Ok(c)) => match c {
            '+' => Something(Add(0x01)),
            '-' => Something(Add(0xff)),
            '<' => Something(Mov(-1)),
            '>' => Something(Mov(1)),
            ',' => Something(In),
            '.' => Something(Out),
            '[' => {
                let mut childstream = OpStream::new();
                while match chars.peek() {
                    Some(&Ok(c)) => c != ']',
                    _ => panic!("Unterminated loop")
                } {
                    if let Something(op) = parse(&mut chars) {
                        childstream.add(op)
                    }
                }
                chars.next();
                Something(Loop(childstream))
            },
            _ => Nothing  // other characters
        },
        _ => EOF  // XXX: really?
    }
}

fn reader(path: &Path) -> Result<io::BufReader<fs::File>, io::Error> {
    fs::File::open(path).map(|f| io::BufReader::new(f))
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::Read;
    use super::{parse, ParserResult, State, OpStream};
    use super::Op::*;

    macro_rules! assert_let(
        ($test:pat, $value:expr, $then:block) => (
            if let $test = $value {
                $then
            } else {
                panic!("{:?} doesn't match {}", $value, stringify!($test))
            }
        );
        ($test:pat, $value:expr) => (
            assert_let!($test, $value, {})
        );
    );

    #[test]
    fn test_state_index() {
        let mut state = State { index: 0, memory: vec![23, 0, 0, 0, 0, 42] };
        assert_eq!(23, state[0]);
        state.index = 5;
        assert_eq!(42, state[0]);
    }

    #[test]
    fn test_state_index_mut() {
        let mut state = State::new();
        state[0] = 23;
        assert_eq!(23, state.memory[state.index]);
        state.index = 5;
        state[0] = 42;
        assert_eq!(42, state.memory[state.index]);
    }

    #[test]
    fn test_state_step_add() {
        let mut state = State::new();
        state.step(&Add(23));
        assert_eq!(23, state[0]);
        state.step(&Add(42));
        assert_eq!(65, state[0]);
        state.step(&Add(190));
        assert_eq!(255, state[0]);
    }

    #[test]
    fn test_state_step_mov() {
        let mut state = State::new();
        state.step(&Mov(1));
        assert_eq!(1, state.index);
        state.step(&Mov(42));
        assert_eq!(43, state.index);
        state.step(&Mov(-1));
        assert_eq!(42, state.index);
    }

    #[test]
    fn test_state_step_loop() {
        let mut state = State::new();
        state[0] = 23;
        state.step(&Loop(OpStream { ops: vec![Add(1)] }));
        assert_eq!(0, state[0]);
    }

    #[test]
    fn test_state_step_transfer() {
        let mut state = State::new();
        state[0] = 15;
        state[1] = 7;
        state.step(&Transfer(5, vec![(1, 2)]));
        assert_eq!(0, state[0]);
        assert_eq!(1, state[1]);
    }

    #[test]
    fn test_opstream_new_empty() {
        let opstream = OpStream::new();
        assert_eq!(0, opstream.ops.len());
    }

    #[test]
    fn test_opstream_optimize() {
        let mut opstream = OpStream::new();
        opstream.add(Mov(1));
        opstream.add(Mov(1));
        opstream.add(Add(0x01));
        opstream.add(Add(0xff));
        opstream.add(Add(0xff));
        opstream.add(Mov(1));
        opstream.add(Mov(-1));
        let mut opstream2 = OpStream::new();
        opstream2.add(Mov(2));
        opstream2.add(Mov(3));
        opstream.add(Loop(opstream2));
        opstream.optimize();

        assert_let!([Mov(2), Add(0xff), Loop(ref s2)], &opstream.ops[..], {
            assert_let!([Mov(5)], &s2.ops[..]);
        });
    }

    #[test]
    fn test_parse() {
        let input = b"+-[+.,]+";
        let mut chars = io::BufReader::new(&input[..]).chars().peekable();
        assert_let!(ParserResult::Something(Add(0x01)), parse(&mut chars));
        assert_let!(ParserResult::Something(Add(0xff)), parse(&mut chars));
        assert_let!(ParserResult::Something(Loop(loop_op)), parse(&mut chars), {
            assert_let!([Add(1), Out, In], &loop_op.ops[..]);
        });
        assert_let!(ParserResult::Something(Add(1)), parse(&mut chars));
    }
}
<commit_msg>refactor: simplify transfer computation<commit_after>#![feature(io, slice_patterns, vec_resize)]
use std::collections::BTreeMap;
use std::fs;
use std::io;
use std::io::{Read, Write};
use std::path::Path;

#[derive(Debug)]
enum ParserResult {
    Something(Op),
    Nothing,
    EOF
}

use ParserResult::*;

#[derive(Debug)]
enum Op {
    Add(u8),
    Mov(isize),
    In,
    Out,
    Loop(OpStream),

    // extra optimized ops
    Transfer(u8, Vec<(isize, u8)>)
}

use Op::*;

#[derive(Debug)]
struct OpStream {
    ops: Vec<Op>
}

impl OpStream {
    fn add(&mut self, op: Op) {
        self.ops.push(op);
    }

    fn optimize(&mut self) {
        let mut i = 0;
        while i < self.ops.len() {
            match &self.ops[i..] {
                [Add(a), Add(b), ..] => {
                    self.ops[i] = Add(a.wrapping_add(b));
                    self.ops.remove(i + 1);
                }
                [Mov(a), Mov(b), ..] => {
                    self.ops[i] = Mov(a + b);
                    self.ops.remove(i + 1);
                }
                [Add(0), ..] | [Mov(0), ..] => {
                    self.ops.remove(i);
                }
                [Loop(_), ..] => {
                    let mut maybe_new_op = None;

                    if let &mut Loop(ref mut stream) = &mut self.ops[i] {
                        stream.optimize();
                        maybe_new_op = stream.find_alternative();
                    }

                    if let Some(new_op) = maybe_new_op {
                        self.ops[i] = new_op;
                    }

                    i += 1
                }
                _ => i += 1
            }
        }
    }

    fn find_alternative(&self) -> Option<Op> {
        let mut map: BTreeMap<isize, u8> = BTreeMap::new();
        let mut rel_index = 0;

        for op in &self.ops[..] {
            match op {
                &Add(x) => {
                    let new_val = map.get(&rel_index).unwrap_or(&0).wrapping_add(x);
                    map.insert(rel_index, new_val);
                }
                &Mov(x) => {
                    rel_index += x;
                }
                _ => {
                    return None;
                }
            }
        }

        if rel_index != 0 {
            return None;
        }

        match map.remove(&0) {
            Some(summand) => Some(Transfer(summand, map.into_iter().collect())),
            None => None
        }
    }

    fn get(&self) -> &[Op] {
        &self.ops[..]
    }

    fn new() -> OpStream {
        OpStream { ops: Vec::new() }
    }
}

static ZERO: u8 = 0;

struct State {
    index: usize,
    memory: Vec<u8>
}

impl State {
    fn new() -> State {
        State { index: 0, memory: vec![] }
    }

    fn rel_index(&self, relative: isize) -> usize {
        (self.index as isize + relative) as usize
    }

    fn step(&mut self, op: &Op) -> bool {
        match op {
            &Add(i) => {
                self[0] = self[0].wrapping_add(i);
            }
            &Mov(n) => {
                self.index = self.rel_index(n);
            }
            &In => {
                let mut c = [0u8];
                if io::stdin().read(&mut c).unwrap() == 0 {
                    return false;
                }
                self[0] = c[0];
            }
            &Out => {
                io::stdout().write(&[self[0]]).unwrap();
            }
            &Loop(ref ops) => {
                while self[0] != 0 {
                    if !self.run(ops.get()) {
                        return false;
                    }
                }
            }
            &Transfer(d, ref map) => {
                if self[0] == 0 {
                    return true
                }

                let mut _v = self[0];
                let mut _n = 0;

                while _v != 0 {
                    _v = _v.wrapping_add(d);
                    _n += 1
                }

                self[0] = 0;
                for &(k, v) in &map[..] {
                    self[k] = self[k].wrapping_add(v.wrapping_mul(_n));
                }
            }
        }
        return true;
    }

    fn run(&mut self, ops: &[Op]) -> bool {
        for op in ops {
            if !self.step(op) {
                return false;
            }
        }
        return true;
    }
}

impl std::ops::Index<isize> for State {
    type Output = u8;
    fn index(&self, _index: isize) -> &u8 {
        let idx = self.rel_index(_index);
        if idx >= self.memory.len() {
            &ZERO
        } else {
            &self.memory[idx]
        }
    }
}

impl std::ops::IndexMut<isize> for State {
    fn index_mut(&mut self, _index: isize) -> &mut u8 {
        let idx = self.rel_index(_index);
        if idx >= self.memory.len() {
            self.memory.resize(idx * 2 + 1, 0);
        }
        &mut self.memory[idx]
    }
}

fn main() {
    let filenames: Vec<String> = std::iter::FromIterator::from_iter(std::env::args());

    for filename in &filenames[1..] {
        match reader(&Path::new(filename)) {
            Ok(reader) => {
                let mut chars = reader.chars().peekable();

                let mut opstream = OpStream::new();
                loop {
                    match parse(&mut chars) {
                        Something(op) => opstream.add(op),
                        EOF => break,
                        _ => {}
                    }
                }

                opstream.optimize();

                State::new().run(opstream.get());
            }
            Err(e) => {
                writeln!(&mut io::stderr(), "Error while processing {}: {}", filename, e).unwrap();
            }
        }
    }
}

fn parse<T: io::Read>(mut chars: &mut std::iter::Peekable<io::Chars<T>>) -> ParserResult {
    match chars.next() {
        Some(Ok(c)) => match c {
            '+' => Something(Add(0x01)),
            '-' => Something(Add(0xff)),
            '<' => Something(Mov(-1)),
            '>' => Something(Mov(1)),
            ',' => Something(In),
            '.' => Something(Out),
            '[' => {
                let mut childstream = OpStream::new();
                while match chars.peek() {
                    Some(&Ok(c)) => c != ']',
                    _ => panic!("Unterminated loop")
                } {
                    if let Something(op) = parse(&mut chars) {
                        childstream.add(op)
                    }
                }
                chars.next();
                Something(Loop(childstream))
            },
            _ => Nothing  // other characters
        },
        _ => EOF  // XXX: really?
    }
}

fn reader(path: &Path) -> Result<io::BufReader<fs::File>, io::Error> {
    fs::File::open(path).map(|f| io::BufReader::new(f))
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::Read;
    use super::{parse, ParserResult, State, OpStream};
    use super::Op::*;

    macro_rules! assert_let(
        ($test:pat, $value:expr, $then:block) => (
            if let $test = $value {
                $then
            } else {
                panic!("{:?} doesn't match {}", $value, stringify!($test))
            }
        );
        ($test:pat, $value:expr) => (
            assert_let!($test, $value, {})
        );
    );

    #[test]
    fn test_state_index() {
        let mut state = State { index: 0, memory: vec![23, 0, 0, 0, 0, 42] };
        assert_eq!(23, state[0]);
        state.index = 5;
        assert_eq!(42, state[0]);
    }

    #[test]
    fn test_state_index_mut() {
        let mut state = State::new();
        state[0] = 23;
        assert_eq!(23, state.memory[state.index]);
        state.index = 5;
        state[0] = 42;
        assert_eq!(42, state.memory[state.index]);
    }

    #[test]
    fn test_state_step_add() {
        let mut state = State::new();
        state.step(&Add(23));
        assert_eq!(23, state[0]);
        state.step(&Add(42));
        assert_eq!(65, state[0]);
        state.step(&Add(190));
        assert_eq!(255, state[0]);
    }

    #[test]
    fn test_state_step_mov() {
        let mut state = State::new();
        state.step(&Mov(1));
        assert_eq!(1, state.index);
        state.step(&Mov(42));
        assert_eq!(43, state.index);
        state.step(&Mov(-1));
        assert_eq!(42, state.index);
    }

    #[test]
    fn test_state_step_loop() {
        let mut state = State::new();
        state[0] = 23;
        state.step(&Loop(OpStream { ops: vec![Add(1)] }));
        assert_eq!(0, state[0]);
    }

    #[test]
    fn test_state_step_transfer() {
        let mut state = State::new();
        state[0] = 15;
        state[1] = 7;
        state.step(&Transfer(5, vec![(1, 2)]));
        assert_eq!(0, state[0]);
        assert_eq!(1, state[1]);
    }

    #[test]
    fn test_opstream_new_empty() {
        let opstream = OpStream::new();
        assert_eq!(0, opstream.ops.len());
    }

    #[test]
    fn test_opstream_optimize() {
        let mut opstream = OpStream::new();
        opstream.add(Mov(1));
        opstream.add(Mov(1));
        opstream.add(Add(0x01));
        opstream.add(Add(0xff));
        opstream.add(Add(0xff));
        opstream.add(Mov(1));
        opstream.add(Mov(-1));
        let mut opstream2 = OpStream::new();
        opstream2.add(Mov(2));
        opstream2.add(Mov(3));
        opstream.add(Loop(opstream2));
        opstream.optimize();

        assert_let!([Mov(2), Add(0xff), Loop(ref s2)], &opstream.ops[..], {
            assert_let!([Mov(5)], &s2.ops[..]);
        });
    }

    #[test]
    fn test_parse() {
        let input = b"+-[+.,]+";
        let mut chars = io::BufReader::new(&input[..]).chars().peekable();
        assert_let!(ParserResult::Something(Add(0x01)), parse(&mut chars));
        assert_let!(ParserResult::Something(Add(0xff)), parse(&mut chars));
        assert_let!(ParserResult::Something(Loop(loop_op)), parse(&mut chars), {
            assert_let!([Add(1), Out, In], &loop_op.ops[..]);
        });
        assert_let!(ParserResult::Something(Add(1)), parse(&mut chars));
    }
}
<|endoftext|>


<commit_before>extern crate bismuth;
#[macro_use]
extern crate gfx;
extern crate gfx_window_glutin;
extern crate glutin;
extern crate num;

use bismuth::{cube, edit, render};
use bismuth::prelude::*;
use gfx::{format, Device};
use gfx::traits::FactoryExt;

const CLEAR_COLOR: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

fn new_root() -> cube::Root {
    let width = cube::MAX_WIDTH;
    let cursor = edit::Selection::at_point(&UPoint3::new(0, 0, 0), width - 3)
        .span(&UVector3::new(7, 1, 7))
        .to_cursor();
    let mut root = cube::Root::new(width);
    root.to_cube_mut().subdivide_to_cursor(&cursor);
    let _ = root.to_cube_mut().at_point_mut(&UPoint3::new(0, 0, 0), width - 2).join();
    for mut cube in root.to_cube_mut().iter_cursor_mut(&cursor) {
        for mut cube in cube.iter_mut() {
            if let Some(leaf) = cube.try_as_leaf_mut() {
                for axis in cube::Axis::range() {
                    for edge in leaf.geometry.edges_mut(axis.into()) {
                        edge.set_front(2);
                        edge.set_back(14);
                    }
                }
            }
        }
    }
    root
}

fn main() {
    let (window, mut device, mut factory, color, _) =
        gfx_window_glutin::init::<format::Rgba8,
                                  format::DepthStencil>(glutin::WindowBuilder::new()
            .with_title("Bismuth")
            .with_dimensions(640, 480)
            .with_vsync());
    let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into();
    let state = factory.create_pipeline_simple(include_bytes!("shader/cube.v.glsl"),
                                               include_bytes!("shader/cube.f.glsl"),
                                               render::pipeline::new())
        .unwrap();

    let root = new_root();
    let transform = {
        let midpoint: FPoint3 = root.partition().midpoint().into_space();
        let camera = FPoint3::new(midpoint.x * 0.25, -midpoint.y, -midpoint.z * 2.0);
        let view = render::look_at_cube(&root, &camera);
        let projection = render::projection_from_window(&window);
        projection * view
    };
    let (vertex_buffer, slice) = render::vertex_buffer_from_cube(&root.to_cube(), &mut factory);
    let data = render::pipeline::Data {
        vertex_buffer: vertex_buffer,
        transform: *transform.as_ref(),
        output: color,
    };

    'main: loop {
        for event in window.poll_events() {
            match event {
                glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) |
                glutin::Event::Closed => break 'main,
                _ => {}
            }
        }

        encoder.clear(&data.output, CLEAR_COLOR);
        encoder.draw(&slice, &state, &data);
        encoder.flush(&mut device);
        window.swap_buffers().unwrap();
        device.cleanup();
    }
}
<commit_msg>Iterate over `subdivide_to_cursor` output.<commit_after>extern crate bismuth;
#[macro_use]
extern crate gfx;
extern crate gfx_window_glutin;
extern crate glutin;
extern crate num;

use bismuth::cube::{Axis, MAX_WIDTH, Root};
use bismuth::edit::Selection;
use bismuth::render;
use bismuth::prelude::*;
use gfx::{format, Device};
use gfx::traits::FactoryExt;

const CLEAR_COLOR: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

fn new_root() -> Root {
    let width = MAX_WIDTH;
    let cursor = Selection::at_point(&UPoint3::new(0, 0, 0), width - 3)
        .span(&UVector3::new(7, 1, 7))
        .to_cursor();
    let mut root = Root::new(width);
    for mut cube in root.to_cube_mut().subdivide_to_cursor(&cursor).iter_mut() {
        for mut cube in cube.iter_mut() {
            if let Some(leaf) = cube.try_as_leaf_mut() {
                for axis in Axis::range() {
                    for edge in leaf.geometry.edges_mut(axis.into()) {
                        edge.set_front(2);
                        edge.set_back(14);
                    }
                }
            }
        }
    }
    root
}

fn main() {
    let (window, mut device, mut factory, color, _) =
        gfx_window_glutin::init::<format::Rgba8,
                                  format::DepthStencil>(glutin::WindowBuilder::new()
            .with_title("Bismuth")
            .with_dimensions(640, 480)
            .with_vsync());
    let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into();
    let state = factory.create_pipeline_simple(include_bytes!("shader/cube.v.glsl"),
                                               include_bytes!("shader/cube.f.glsl"),
                                               render::pipeline::new())
        .unwrap();

    let root = new_root();
    let transform = {
        let midpoint: FPoint3 = root.partition().midpoint().into_space();
        let camera = FPoint3::new(midpoint.x * 0.25, -midpoint.y, -midpoint.z * 2.0);
        let view = render::look_at_cube(&root, &camera);
        let projection = render::projection_from_window(&window);
        projection * view
    };
    let (vertex_buffer, slice) = render::vertex_buffer_from_cube(&root.to_cube(), &mut factory);
    let data = render::pipeline::Data {
        vertex_buffer: vertex_buffer,
        transform: *transform.as_ref(),
        output: color,
    };

    'main: loop {
        for event in window.poll_events() {
            match event {
                glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) |
                glutin::Event::Closed => break 'main,
                _ => {}
            }
        }

        encoder.clear(&data.output, CLEAR_COLOR);
        encoder.draw(&slice, &state, &data);
        encoder.flush(&mut device);
        window.swap_buffers().unwrap();
        device.cleanup();
    }
}
<|endoftext|>


<commit_before>#![feature(std_misc, test)]

extern crate threadpool;
extern crate rand;
extern crate num_cpus;

extern crate piston;
extern crate opengl_graphics;
extern crate graphics;
extern crate glutin_window;

use opengl_graphics::{GlGraphics, OpenGL};
use glutin_window::GlutinWindow as Window;
use piston::window::{AdvancedWindow, WindowSettings};
use piston::input::{Key, Button};
use piston::event::*;

mod board;

const SCALE: f64 = 3.0;
const X_SZ: u32 = 800;
const Y_SZ: u32 = 600;

fn scale_dimension(x: u32) -> usize {
    (x as f64 / SCALE).floor() as usize
}

#[cfg(not(test))]
fn main() {
    let (rows, cols) = (scale_dimension(X_SZ), scale_dimension(Y_SZ));
    let mut brd = board::Board::new(rows, cols).random();
    let ref mut worker_pool = board::WorkerPool::new_with_default_size();

    let opengl = OpenGL::_3_2;
    let window = Window::new(
        opengl,
        WindowSettings::new("Life", [X_SZ, Y_SZ])
        .exit_on_esc(true)
    );
    let ref mut gl = GlGraphics::new(opengl);
    let rect = graphics::Rectangle::new([1.0; 4]);
    let mut running = true;

    for e in window.events() {
        if let Some(Button::Keyboard(key)) = e.press_args() {
            match key {
                Key::R     => brd = brd.random(),
                Key::Space => running = !running,
                _          => {}
            };
        }

        if let Some(args) = e.render_args() {
            gl.draw(args.viewport(), |c, g| {
                graphics::clear([0.0; 4], g);
                for (x, y, val) in brd.cells() {
                    if !val { continue; }
                    rect.draw(
                        [y as f64 * SCALE, x as f64 * SCALE, SCALE, SCALE],
                        &c.draw_state, c.transform, g
                    );
                }
                if running {
                    brd = brd.parallel_next_generation(worker_pool);
                }
            });
        }
    }
}
<commit_msg>Update independent of rendering<commit_after>#![feature(std_misc, test)]

extern crate threadpool;
extern crate rand;
extern crate num_cpus;

extern crate piston;
extern crate opengl_graphics;
extern crate graphics;
extern crate glutin_window;

use opengl_graphics::{GlGraphics, OpenGL};
use glutin_window::GlutinWindow as Window;
use piston::window::{AdvancedWindow, WindowSettings};
use piston::input::{Key, Button};
use piston::event::*;

mod board;

const SCALE: f64 = 2.0;
const X_SZ: u32 = 800;
const Y_SZ: u32 = 600;

fn scale_dimension(x: u32) -> usize {
    (x as f64 / SCALE).floor() as usize
}

#[cfg(not(test))]
fn main() {
    let (rows, cols) = (scale_dimension(X_SZ), scale_dimension(Y_SZ));
    let mut brd = board::Board::new(rows, cols).random();
    let ref mut worker_pool = board::WorkerPool::new_with_default_size();

    let opengl = OpenGL::_3_2;
    let window = Window::new(
        opengl,
        WindowSettings::new("Life", [X_SZ, Y_SZ])
        .exit_on_esc(true)
    );
    let ref mut gl = GlGraphics::new(opengl);
    let rect = graphics::Rectangle::new([1.0; 4]);
    let mut running = true;

    for e in window.events() {
        if let Some(Button::Keyboard(key)) = e.press_args() {
            match key {
                Key::R     => brd = brd.random(),
                Key::Space => running = !running,
                _          => {}
            };
        }

        if let Some(args) = e.render_args() {
            gl.draw(args.viewport(), |c, g| {
                graphics::clear([0.0; 4], g);
                for (x, y, val) in brd.cells() {
                    if !val { continue; }
                    rect.draw(
                        [y as f64 * SCALE, x as f64 * SCALE, SCALE, SCALE],
                        &c.draw_state, c.transform, g
                    );
                }
            });
        }

        if let Some(args) = e.update_args() {
            if running {
                brd = brd.parallel_next_generation(worker_pool);
            }
        }
    }
}
<|endoftext|>