<commit_before>//! Error types and conversion functions.

use std;
use std::error::Error;
use std::fmt;

use gfx;
use glutin;
use winit;

use gilrs;
use image;
use lyon;
use rodio::decoder::DecoderError;
use toml;
use zip;

/// An enum containing all kinds of game framework errors.
#[derive(Debug)]
pub enum GameError {
    /// An error in the filesystem layout
    FilesystemError(String),
    /// An error in the config file
    ConfigError(String),
    /// Happens when an `winit::EventsLoopProxy` attempts to
    /// wake up an `winit::EventsLoop` that no longer exists.
    EventLoopError(String),
    /// An error trying to load a resource, such as getting an invalid image file.
    ResourceLoadError(String),
    /// Unable to find a resource; the `Vec` is the paths it searched for and associated errors
    ResourceNotFound(String, Vec<(std::path::PathBuf, GameError)>),
    /// Something went wrong in the renderer
    RenderError(String),
    /// Something went wrong in the audio playback
    AudioError(String),
    /// Something went wrong trying to set or get window properties.
    WindowError(String),
    /// Something went wrong trying to create a window
    WindowCreationError(glutin::CreationError),
    /// Something went wrong trying to read from a file
    IOError(std::io::Error),
    /// Something went wrong trying to load/render a font
    FontError(String),
    /// Something went wrong applying video settings.
    VideoError(String),
    /// Something went wrong compiling shaders
    ShaderProgramError(gfx::shade::ProgramError),
    /// Something went wrong with `Gilrs`
    GamepadError(String),
    /// Something went wrong with the `lyon` shape-tesselation library.
    LyonError(String),
}

impl fmt::Display for GameError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GameError::ConfigError(ref s) => write!(f, "Config error: {}", s),
            GameError::ResourceLoadError(ref s) => write!(f, "Error loading resource: {}", s),
            GameError::ResourceNotFound(ref s, ref paths) => write!(
                f,
                "Resource not found: {}, searched in paths {:?}",
                s, paths
            ),
            GameError::WindowError(ref e) => write!(f, "Window creation error: {}", e),
            _ => write!(f, "GameError {:?}", self),
        }
    }
}

impl Error for GameError {
    fn cause(&self) -> Option<&dyn Error> {
        match *self {
            GameError::WindowCreationError(ref e) => Some(e),
            GameError::IOError(ref e) => Some(e),
            GameError::ShaderProgramError(ref e) => Some(e),
            _ => None,
        }
    }
}

/// A convenient result type consisting of a return type and a `GameError`
pub type GameResult<T = ()> = Result<T, GameError>;

impl From<std::io::Error> for GameError {
    fn from(e: std::io::Error) -> GameError {
        GameError::IOError(e)
    }
}

impl From<toml::de::Error> for GameError {
    fn from(e: toml::de::Error) -> GameError {
        let errstr = format!("TOML decode error: {}", e.description());

        GameError::ConfigError(errstr)
    }
}

impl From<toml::ser::Error> for GameError {
    fn from(e: toml::ser::Error) -> GameError {
        let errstr = format!("TOML error (possibly encoding?): {}", e.description());
        GameError::ConfigError(errstr)
    }
}

impl From<zip::result::ZipError> for GameError {
    fn from(e: zip::result::ZipError) -> GameError {
        let errstr = format!("Zip error: {}", e.description());
        GameError::ResourceLoadError(errstr)
    }
}

impl From<DecoderError> for GameError {
    fn from(e: DecoderError) -> GameError {
        let errstr = format!("Audio decoder error: {:?}", e);
        GameError::AudioError(errstr)
    }
}

impl From<image::ImageError> for GameError {
    fn from(e: image::ImageError) -> GameError {
        let errstr = format!("Image load error: {}", e.description());
        GameError::ResourceLoadError(errstr)
    }
}

impl From<gfx::PipelineStateError<std::string::String>> for GameError {
    fn from(e: gfx::PipelineStateError<std::string::String>) -> GameError {
        let errstr = format!(
            "Error constructing pipeline!\nThis should probably not be \
             happening; it probably means an error in a shader or \
             something.\nError was: {:?}",
            e
        );
        GameError::VideoError(errstr)
    }
}

impl From<gfx::mapping::Error> for GameError {
    fn from(e: gfx::mapping::Error) -> GameError {
        let errstr = format!("Buffer mapping error: {:?}", e);
        GameError::VideoError(errstr)
    }
}

impl<S, D> From<gfx::CopyError<S, D>> for GameError
where
    S: fmt::Debug,
    D: fmt::Debug,
{
    fn from(e: gfx::CopyError<S, D>) -> GameError {
        let errstr = format!("Memory copy error: {:?}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::CombinedError> for GameError {
    fn from(e: gfx::CombinedError) -> GameError {
        let errstr = format!("Texture+view load error: {}", e.description());
        GameError::VideoError(errstr)
    }
}

impl From<gfx::texture::CreationError> for GameError {
    fn from(e: gfx::texture::CreationError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl From<gfx::ResourceViewError> for GameError {
    fn from(e: gfx::ResourceViewError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl From<gfx::TargetViewError> for GameError {
    fn from(e: gfx::TargetViewError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl<T> From<gfx::UpdateError<T>> for GameError
where
    T: fmt::Debug + fmt::Display + 'static,
{
    fn from(e: gfx::UpdateError<T>) -> GameError {
        let errstr = format!("Buffer update error: {}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::shade::ProgramError> for GameError {
    fn from(e: gfx::shade::ProgramError) -> GameError {
        GameError::ShaderProgramError(e)
    }
}

// TODO: improve winit/glutin error handling.

impl From<winit::EventsLoopClosed> for GameError {
    fn from(_: glutin::EventsLoopClosed) -> GameError {
        let e = "An event loop proxy attempted to wake up an event loop that no longer exists."
            .to_owned();
        GameError::EventLoopError(e)
    }
}

impl From<glutin::CreationError> for GameError {
    fn from(s: glutin::CreationError) -> GameError {
        GameError::WindowCreationError(s)
    }
}

impl From<glutin::ContextError> for GameError {
    fn from(s: glutin::ContextError) -> GameError {
        GameError::RenderError(format!("OpenGL context error: {}", s))
    }
}

impl From<gilrs::Error> for GameError {
    fn from(s: gilrs::Error) -> GameError {
        let errstr = format!("Gamepad error: {}", s);
        GameError::GamepadError(errstr)
    }
}

impl From<lyon::lyon_tessellation::TessellationError> for GameError {
    fn from(s: lyon::lyon_tessellation::TessellationError) -> GameError {
        let errstr = format!(
            "Error while tesselating shape (did you give it an infinity or NaN?): {:?}",
            s
        );
        GameError::LyonError(errstr)
    }
}

impl From<lyon::lyon_tessellation::geometry_builder::GeometryBuilderError> for GameError {
    fn from(s: lyon::lyon_tessellation::geometry_builder::GeometryBuilderError) -> GameError {
        let errstr = format!(
            "Error while building geometry (did you give it too many vertices?): {:?}",
            s
        );
        GameError::LyonError(errstr)
    }
}
<commit_msg>Make error type Clone<commit_after>//! Error types and conversion functions.

use std;
use std::error::Error;
use std::fmt;
use std::sync::Arc;

use gfx;
use glutin;
use winit;

use gilrs;
use image;
use lyon;
use rodio::decoder::DecoderError;
use toml;
use zip;

/// An enum containing all kinds of game framework errors.
#[derive(Debug, Clone)]
pub enum GameError {
    /// An error in the filesystem layout
    FilesystemError(String),
    /// An error in the config file
    ConfigError(String),
    /// Happens when an `winit::EventsLoopProxy` attempts to
    /// wake up an `winit::EventsLoop` that no longer exists.
    EventLoopError(String),
    /// An error trying to load a resource, such as getting an invalid image file.
    ResourceLoadError(String),
    /// Unable to find a resource; the `Vec` is the paths it searched for and associated errors
    ResourceNotFound(String, Vec<(std::path::PathBuf, GameError)>),
    /// Something went wrong in the renderer
    RenderError(String),
    /// Something went wrong in the audio playback
    AudioError(String),
    /// Something went wrong trying to set or get window properties.
    WindowError(String),
    /// Something went wrong trying to create a window
    WindowCreationError(Arc<glutin::CreationError>),
    /// Something went wrong trying to read from a file
    IOError(Arc<std::io::Error>),
    /// Something went wrong trying to load/render a font
    FontError(String),
    /// Something went wrong applying video settings.
    VideoError(String),
    /// Something went wrong compiling shaders
    ShaderProgramError(gfx::shade::ProgramError),
    /// Something went wrong with `Gilrs`
    GamepadError(String),
    /// Something went wrong with the `lyon` shape-tesselation library.
    LyonError(String),
}

impl fmt::Display for GameError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GameError::ConfigError(ref s) => write!(f, "Config error: {}", s),
            GameError::ResourceLoadError(ref s) => write!(f, "Error loading resource: {}", s),
            GameError::ResourceNotFound(ref s, ref paths) => write!(
                f,
                "Resource not found: {}, searched in paths {:?}",
                s, paths
            ),
            GameError::WindowError(ref e) => write!(f, "Window creation error: {}", e),
            _ => write!(f, "GameError {:?}", self),
        }
    }
}

impl Error for GameError {
    fn cause(&self) -> Option<&dyn Error> {
        match *self {
            GameError::WindowCreationError(ref e) => Some(&**e),
            GameError::IOError(ref e) => Some(&**e),
            GameError::ShaderProgramError(ref e) => Some(e),
            _ => None,
        }
    }
}

/// A convenient result type consisting of a return type and a `GameError`
pub type GameResult<T = ()> = Result<T, GameError>;

impl From<std::io::Error> for GameError {
    fn from(e: std::io::Error) -> GameError {
        GameError::IOError(Arc::new(e))
    }
}

impl From<toml::de::Error> for GameError {
    fn from(e: toml::de::Error) -> GameError {
        let errstr = format!("TOML decode error: {}", e.description());

        GameError::ConfigError(errstr)
    }
}

impl From<toml::ser::Error> for GameError {
    fn from(e: toml::ser::Error) -> GameError {
        let errstr = format!("TOML error (possibly encoding?): {}", e.description());
        GameError::ConfigError(errstr)
    }
}

impl From<zip::result::ZipError> for GameError {
    fn from(e: zip::result::ZipError) -> GameError {
        let errstr = format!("Zip error: {}", e.description());
        GameError::ResourceLoadError(errstr)
    }
}

impl From<DecoderError> for GameError {
    fn from(e: DecoderError) -> GameError {
        let errstr = format!("Audio decoder error: {:?}", e);
        GameError::AudioError(errstr)
    }
}

impl From<image::ImageError> for GameError {
    fn from(e: image::ImageError) -> GameError {
        let errstr = format!("Image load error: {}", e.description());
        GameError::ResourceLoadError(errstr)
    }
}

impl From<gfx::PipelineStateError<std::string::String>> for GameError {
    fn from(e: gfx::PipelineStateError<std::string::String>) -> GameError {
        let errstr = format!(
            "Error constructing pipeline!\nThis should probably not be \
             happening; it probably means an error in a shader or \
             something.\nError was: {:?}",
            e
        );
        GameError::VideoError(errstr)
    }
}

impl From<gfx::mapping::Error> for GameError {
    fn from(e: gfx::mapping::Error) -> GameError {
        let errstr = format!("Buffer mapping error: {:?}", e);
        GameError::VideoError(errstr)
    }
}

impl<S, D> From<gfx::CopyError<S, D>> for GameError
where
    S: fmt::Debug,
    D: fmt::Debug,
{
    fn from(e: gfx::CopyError<S, D>) -> GameError {
        let errstr = format!("Memory copy error: {:?}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::CombinedError> for GameError {
    fn from(e: gfx::CombinedError) -> GameError {
        let errstr = format!("Texture+view load error: {}", e.description());
        GameError::VideoError(errstr)
    }
}

impl From<gfx::texture::CreationError> for GameError {
    fn from(e: gfx::texture::CreationError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl From<gfx::ResourceViewError> for GameError {
    fn from(e: gfx::ResourceViewError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl From<gfx::TargetViewError> for GameError {
    fn from(e: gfx::TargetViewError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl<T> From<gfx::UpdateError<T>> for GameError
where
    T: fmt::Debug + fmt::Display + 'static,
{
    fn from(e: gfx::UpdateError<T>) -> GameError {
        let errstr = format!("Buffer update error: {}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::shade::ProgramError> for GameError {
    fn from(e: gfx::shade::ProgramError) -> GameError {
        GameError::ShaderProgramError(e)
    }
}

// TODO: improve winit/glutin error handling.

impl From<winit::EventsLoopClosed> for GameError {
    fn from(_: glutin::EventsLoopClosed) -> GameError {
        let e = "An event loop proxy attempted to wake up an event loop that no longer exists."
            .to_owned();
        GameError::EventLoopError(e)
    }
}

impl From<glutin::CreationError> for GameError {
    fn from(s: glutin::CreationError) -> GameError {
        GameError::WindowCreationError(Arc::new(s))
    }
}

impl From<glutin::ContextError> for GameError {
    fn from(s: glutin::ContextError) -> GameError {
        GameError::RenderError(format!("OpenGL context error: {}", s))
    }
}

impl From<gilrs::Error> for GameError {
    fn from(s: gilrs::Error) -> GameError {
        let errstr = format!("Gamepad error: {}", s);
        GameError::GamepadError(errstr)
    }
}

impl From<lyon::lyon_tessellation::TessellationError> for GameError {
    fn from(s: lyon::lyon_tessellation::TessellationError) -> GameError {
        let errstr = format!(
            "Error while tesselating shape (did you give it an infinity or NaN?): {:?}",
            s
        );
        GameError::LyonError(errstr)
    }
}

impl From<lyon::lyon_tessellation::geometry_builder::GeometryBuilderError> for GameError {
    fn from(s: lyon::lyon_tessellation::geometry_builder::GeometryBuilderError) -> GameError {
        let errstr = format!(
            "Error while building geometry (did you give it too many vertices?): {:?}",
            s
        );
        GameError::LyonError(errstr)
    }
}
<|endoftext|>


<commit_before>
use std::fmt;

#[derive(Debug, PartialEq)]
/// nccl Error type.
pub enum ErrorKind {
    KeyNotFound,
    IndentationError,
    NameError,
    NoValue,
    ParseError,
    FromStrError,
    FileError,
}

#[derive(Debug, PartialEq)]
pub struct NcclError {
    kind: ErrorKind,
    line: u64,
    message: String,
}

impl NcclError {
    pub fn new(kind: ErrorKind, message: &str, line: u64) -> Self {
        NcclError {
            kind: kind,
            message: message.to_owned(),
            line: line,
        }
    }
}

impl fmt::Display for NcclError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.kind {
            ErrorKind::ParseError | ErrorKind::IndentationError
                => write!(f, "An error has ocurred: {:?} on line {}\n\t{}", self.kind, self.line, self.message),
            _ => write!(f, "An error has ocurred: {:?}\n\t{}", self.kind, self.message)
        }
    }
}

<commit_msg>impl Error for NcclError<commit_after>
use std::fmt;
use std::error;

#[derive(Debug, PartialEq)]
/// nccl Error type.
pub enum ErrorKind {
    KeyNotFound,
    IndentationError,
    NameError,
    NoValue,
    ParseError,
    FromStrError,
    FileError,
}

#[derive(Debug, PartialEq)]
pub struct NcclError {
    kind: ErrorKind,
    line: u64,
    message: String,
}

impl NcclError {
    pub fn new(kind: ErrorKind, message: &str, line: u64) -> Self {
        NcclError {
            kind: kind,
            message: message.to_owned(),
            line: line,
        }
    }
}

impl fmt::Display for NcclError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.kind {
            ErrorKind::ParseError | ErrorKind::IndentationError
                => write!(f, "An error has ocurred: {:?} on line {}\n\t{}", self.kind, self.line, self.message),
            _ => write!(f, "An error has ocurred: {:?}\n\t{}", self.kind, self.message)
        }
    }
}

impl error::Error for NcclError {
    fn description(&self) -> &str {
        &match self.kind {
            ErrorKind::ParseError | ErrorKind::IndentationError
                => "An error has occurred while parsing.",
            _ => "An error has occurred while interacting with a Pair"
        }
    }
}

<|endoftext|>


<commit_before><commit_msg>Fixed compilation error<commit_after><|endoftext|>


<commit_before>use std::env;
use std::fs;
use std::path;

use clap;
use cobalt;
use ghp;

use args;
use error::*;

pub fn build_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("build")
        .about("build the cobalt project at the source dir")
        .args(&args::get_config_args())
        .arg(
            clap::Arg::with_name("import")
                .short("i")
                .long("import")
                .help("Import after build to gh-pages branch")
                .takes_value(false),
        )
        .arg(
            clap::Arg::with_name("branch")
                .short("b")
                .long("branch")
                .value_name("BRANCH")
                .help("Branch that will be used to import the site to")
                .default_value("gh-pages")
                .takes_value(true),
        )
        .arg(
            clap::Arg::with_name("message")
                .short("m")
                .long("message")
                .value_name("COMMIT-MESSAGE")
                .help("Commit message that will be used on import")
                .default_value("cobalt site import")
                .takes_value(true),
        )
}

pub fn build_command(matches: &clap::ArgMatches) -> Result<()> {
    let config = args::get_config(matches)?;
    let config = config.build()?;

    build(config.clone())?;
    info!("Build successful");

    if matches.is_present("import") {
        let branch = matches.value_of("branch").unwrap().to_string();
        let message = matches.value_of("message").unwrap().to_string();
        import(&config, &branch, &message)?
    }

    Ok(())
}

pub fn build(config: cobalt::Config) -> Result<()> {
    info!(
        "Building from {:?} into {:?}",
        config.source, config.destination
    );
    cobalt::build(config)?;

    Ok(())
}

pub fn clean_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("clean")
        .about("cleans directory set as destination")
        .args(&args::get_config_args())
}

pub fn clean_command(matches: &clap::ArgMatches) -> Result<()> {
    let config = args::get_config(matches)?;
    let config = config.build()?;

    clean(config)
}

pub fn clean(config: cobalt::Config) -> Result<()> {
    let cwd = env::current_dir().unwrap_or_else(|_| path::PathBuf::new());
    let destdir = config.destination.canonicalize();
    let destdir = match destdir {
        Ok(destdir) => destdir,
        Err(e) => {
            debug!("directory \"{:?}\" doesn't exist", &config.destination);
            debug!("{}", e);
            return Ok(());
        }
    };
    if cwd.starts_with(&destdir) {
        bail!(
            "Attempting to delete current directory ({:?}), \
             Cancelling the operation",
            destdir
        );
    }

    fs::remove_dir_all(&destdir)?;

    info!("directory \"{:?}\" removed", &destdir);

    Ok(())
}

pub fn import_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("import")
        .about("moves the contents of the dest folder to the gh-pages branch")
        .args(&args::get_config_args())
        .arg(
            clap::Arg::with_name("branch")
                .short("b")
                .long("branch")
                .value_name("BRANCH")
                .help("Branch that will be used to import the site to")
                .default_value("gh-pages")
                .takes_value(true),
        )
        .arg(
            clap::Arg::with_name("message")
                .short("m")
                .long("message")
                .value_name("COMMIT-MESSAGE")
                .help("Commit message that will be used on import")
                .default_value("cobalt site import")
                .takes_value(true),
        )
}

pub fn import_command(matches: &clap::ArgMatches) -> Result<()> {
    let config = args::get_config(matches)?;
    let config = config.build()?;

    let branch = matches.value_of("branch").unwrap().to_string();
    let message = matches.value_of("message").unwrap().to_string();
    import(&config, &branch, &message)?;

    Ok(())
}

fn import(config: &cobalt::Config, branch: &str, message: &str) -> Result<()> {
    info!("Importing {:?} to {}", config.destination, branch);

    if !config.destination.is_dir() {
        bail!("`{:?}` is not a directory", config.destination);
    }
    ghp::import_dir(&config.destination, branch, message)?;

    Ok(())
}
<commit_msg>fix(import): import is self-contained<commit_after>use std::env;
use std::fs;
use std::path;

use clap;
use cobalt;
use ghp;

use args;
use error::*;

pub fn build_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("build")
        .about("build the cobalt project at the source dir")
        .args(&args::get_config_args())
}

pub fn build_command(matches: &clap::ArgMatches) -> Result<()> {
    let config = args::get_config(matches)?;
    let config = config.build()?;

    build(config.clone())?;
    info!("Build successful");

    Ok(())
}

pub fn build(config: cobalt::Config) -> Result<()> {
    info!(
        "Building from {:?} into {:?}",
        config.source, config.destination
    );
    cobalt::build(config)?;

    Ok(())
}

pub fn clean_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("clean")
        .about("cleans `destination` directory")
        .args(&args::get_config_args())
}

pub fn clean_command(matches: &clap::ArgMatches) -> Result<()> {
    let config = args::get_config(matches)?;
    let config = config.build()?;

    clean(&config)
}

pub fn clean(config: &cobalt::Config) -> Result<()> {
    let cwd = env::current_dir().unwrap_or_else(|_| path::PathBuf::new());
    let destdir = config.destination.canonicalize();
    let destdir = match destdir {
        Ok(destdir) => destdir,
        Err(e) => {
            debug!("No \"{:?}\" to clean", &config.destination);
            debug!("{}", e);
            return Ok(());
        }
    };
    if cwd.starts_with(&destdir) {
        bail!(
            "Attempting to delete current directory ({:?}), \
             Cancelling the operation",
            destdir
        );
    }

    fs::remove_dir_all(&destdir)?;

    info!("directory \"{:?}\" removed", &destdir);

    Ok(())
}

pub fn import_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("import")
        .about("moves the contents of the dest folder to the gh-pages branch")
        .args(&args::get_config_args())
        .arg(
            clap::Arg::with_name("branch")
                .short("b")
                .long("branch")
                .value_name("BRANCH")
                .help("Branch that will be used to import the site to")
                .default_value("gh-pages")
                .takes_value(true),
        )
        .arg(
            clap::Arg::with_name("message")
                .short("m")
                .long("message")
                .value_name("COMMIT-MESSAGE")
                .help("Commit message that will be used on import")
                .default_value("cobalt site import")
                .takes_value(true),
        )
}

pub fn import_command(matches: &clap::ArgMatches) -> Result<()> {
    let config = args::get_config(matches)?;
    let config = config.build()?;

    clean(&config)?;
    build(config.clone())?;

    let branch = matches.value_of("branch").unwrap().to_string();
    let message = matches.value_of("message").unwrap().to_string();
    import(&config, &branch, &message)?;

    Ok(())
}

fn import(config: &cobalt::Config, branch: &str, message: &str) -> Result<()> {
    info!("Importing {:?} to {}", config.destination, branch);

    if !config.destination.is_dir() {
        bail!("`{:?}` is not a directory", config.destination);
    }
    ghp::import_dir(&config.destination, branch, message)?;

    Ok(())
}
<|endoftext|>


<commit_before>#![feature(link_args)]

extern crate fsevent;
use std::sync::mpsc::channel;
use std::thread::Thread;

#[allow(dead_code)]
fn main() {
  let (sender, receiver) = channel::<fsevent::Event>();

  let _t = Thread::spawn(move || {
    let fsevent = fsevent::FsEvent::new(sender);
    fsevent.append_path("../../");
    fsevent.observe();
  });

  loop {
    select! (
      val = receiver.recv() => {
        println!("{:?}", val);
      }
    )
  }
}
<commit_msg>Fix some rust warnings<commit_after>#![feature(link_args)]

extern crate fsevent;
use std::sync::mpsc::channel;
use std::thread::Thread;

#[allow(dead_code)]
#[allow(unstable)]
fn main() {
  let (sender, receiver) = channel::<fsevent::Event>();

  let _t = Thread::spawn(move || {
    let fsevent = fsevent::FsEvent::new(sender);
    fsevent.append_path("../../");
    fsevent.observe();
  });

  loop {
    select! (
      val = receiver.recv() => {
        println!("{:?}", val);
      }
    )
  }
}
<|endoftext|>


<commit_before>#[feature(globs)];

extern mod native;
extern mod extra;
extern mod glfw;
extern mod gl;
extern mod cgmath;
extern mod noise;

use std::cast;
use std::ptr;
use std::str;
use std::vec;
use std::libc;
use std::io::Timer;
use std::hashmap::HashSet;

use gl::types::*;

use cgmath::matrix::Matrix;
use cgmath::matrix::Mat3;
use cgmath::matrix::Mat4;
use cgmath::matrix::ToMat4;
use cgmath::vector::Vector;
use cgmath::vector::Vec3;
use cgmath::vector::Vec4;
use cgmath::angle::rad;

#[link(name="GLU")]
extern {}

mod chunk;
mod ratelimiter;

static vertex_shader_src : &'static str = r"
#version 110

uniform mat4 modelview;
uniform mat4 projection;

attribute vec3 position;
attribute vec3 normal;

varying vec4 frag_color;

const vec4 obj_diffuse = vec4(0.2, 0.6, 0.2, 1.0);
const vec3 light_direction = vec3(0.408248, -0.816497, 0.408248);
const vec4 light_diffuse = vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient = vec4(0.2, 0.2, 0.2, 1.0);

const float planet_radius = 6371000.0 / 10000.0;

void main() {
    vec4 eye_position = modelview * vec4(position, 1.0);

    /* Curvature of the planet */
    float distance_squared = pow(eye_position.x, 2) + pow(eye_position.z, 2);
    eye_position.y -= planet_radius - sqrt(pow(planet_radius, 2) - distance_squared);

    gl_Position = projection * eye_position;

    vec4 diffuse_factor
        = max(-dot(normal, light_direction), 0.0) * light_diffuse;
    vec4 ambient_diffuse_factor = diffuse_factor + light_ambient;

    frag_color = ambient_diffuse_factor * obj_diffuse;
}
";

static fragment_shader_src : &'static str = r"
#version 110

varying vec4 frag_color;

void main() {
    gl_FragColor = frag_color;
}
";

pub static WORLD_SIZE: uint = 4;
pub static CHUNK_SIZE: uint = 64;
pub static WORLD_SEED: u32 = 42;

static FRAME_TIME_TARGET_MS : u64 = 16;

struct GraphicsResources {
    program: GLuint,
    uniform_modelview: GLint,
    uniform_projection: GLint,
}

#[start]
fn start(argc: int, argv: **u8) -> int {
    do native::start(argc, argv) {
        main();
    }
}

fn main() {
   glfw::set_error_callback(~ErrorContext);

    do glfw::start {
        let mut window_width = 800;
        let mut window_height = 600;

        let window = glfw::Window::create(window_width, window_height, "Hello, I am a window.", glfw::Windowed)
            .expect("Failed to create GLFW window.");

        window.set_cursor_mode(glfw::CursorDisabled);
        window.make_context_current();

        gl::load_with(glfw::get_proc_address);

        gl::Enable(gl::DEPTH_TEST);
        gl::Enable(gl::CULL_FACE);

        glfw::set_swap_interval(1);

        let graphics_resources = load_graphics_resources();

        gl::UseProgram(graphics_resources.program);

        let mut chunk_loader = chunk::ChunkLoader::new(WORLD_SEED, &graphics_resources);

        window.set_key_callback(~KeyContext);

        let (fb_size_port, fb_size_chan): (Port<(u32,u32)>, Chan<(u32,u32)>) = std::comm::Chan::new();
        window.set_framebuffer_size_callback(~FramebufferSizeContext { chan: fb_size_chan });

        let mut fps_display_limiter = ratelimiter::RateLimiter::new(1000*1000*1000);
        let mut fps_frame_counter = 0;

        let mut camera_position = Vec3::<f32>::new(0.0f32, 20.0f32, 40.0f32);

        //let mut timer = Timer::new().unwrap();

        let mut needed_chunks : HashSet<(i64, i64)> = HashSet::new();
        let mut load_limiter = ratelimiter::RateLimiter::new(1000*1000*100);

        while !window.should_close() {
            let frame_start_time = extra::time::precise_time_ns();

            glfw::poll_events();

            loop {
                match fb_size_port.try_recv() {
                    Some((w,h)) => {
                        window_width = w;
                        window_height = h;
                    }
                    None => break
                }
            }

            let (cursor_x, cursor_y) = window.get_cursor_pos();
            let camera_angle_y = ((cursor_x * 0.0005) % 1.0) * std::f64::consts::PI * 2.0;
            let camera_angle_x = ((cursor_y * 0.0005) % 1.0) * std::f64::consts::PI * 2.0;

            let mut camera_velocity = Vec3::<f32>::new(0.0f32, 0.0f32, 0.0f32);

            match window.get_key(glfw::KeySpace) {
                glfw::Press => { camera_velocity.y += 1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyLeftControl) {
                glfw::Press => { camera_velocity.y += -1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyS) {
                glfw::Press => { camera_velocity.z += 1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyW) {
                glfw::Press => { camera_velocity.z += -1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyD) {
                glfw::Press => { camera_velocity.x += 1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyA) {
                glfw::Press => { camera_velocity.x += -1.0f32 }
                _ => {}
            }

            gl::Viewport(0,0, window_width as GLint, window_height as GLint);

            gl::ClearColor(0.0, 0.75, 1.0, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

            let projection = cgmath::projection::perspective(
                rad(1.57f32),
                window_width as f32 / window_height as f32,
                0.1f32, 1000.0f32);

            unsafe {
                gl::UniformMatrix4fv(graphics_resources.uniform_projection, 1, gl::FALSE, cast::transmute(&projection));
            }

            let camera_translation = Mat4::<f32>::from_cols(
                Vec4::<f32>::unit_x(),
                Vec4::<f32>::unit_y(),
                Vec4::<f32>::unit_z(),
                camera_position.mul_s(-1.0f32).extend(1.0f32));
            let camera_rotation_x = Mat3::<f32>::from_angle_x(rad(camera_angle_x as f32)).to_mat4();
            let camera_rotation_y = Mat3::<f32>::from_angle_y(rad(camera_angle_y as f32)).to_mat4();
            let camera = camera_rotation_x.mul_m(&camera_rotation_y).mul_m(&camera_translation);

            let inv_camera_rotation = Mat3::<f32>::from_euler(rad(-camera_angle_x as f32), rad(-camera_angle_y as f32), rad(0.0f32));
            let absolute_camera_velocity = inv_camera_rotation.mul_v(&camera_velocity).mul_s(0.5f32);
            camera_position.add_self_v(&absolute_camera_velocity);

            let coords = visible_chunks(camera_position.x as i64,
                                        camera_position.z as i64);

            for &(cx, cz) in coords.iter() {
                match chunk_loader.cache.find_mut(&(cx, cz)) {
                    Some(chunk) => {
                        chunk.touch();

                        let chunk_translation = Mat4::<f32>::from_cols(
                            Vec4::<f32>::unit_x(),
                            Vec4::<f32>::unit_y(),
                            Vec4::<f32>::unit_z(),
                            Vec4::<f32>::new(chunk.x as f32, 0.0f32, chunk.z as f32, 1.0f32));

                        let modelview = camera.mul_m(&chunk_translation);

                        gl::BindVertexArray(chunk.vao);

                        unsafe {
                            gl::UniformMatrix4fv(graphics_resources.uniform_modelview, 1, gl::FALSE, cast::transmute(&modelview));
                            gl::DrawElements(gl::TRIANGLES, chunk.num_elements as i32, gl::UNSIGNED_INT, ptr::null());
                        }

                        gl::BindVertexArray(0);
                    },
                    None => {
                        needed_chunks.insert((cx, cz));
                    }
                }
            }

            window.swap_buffers();

            check_gl("main loop");

            if !needed_chunks.is_empty() && load_limiter.limit() {
                let mut loaded = None;

                for &(cx, cz) in needed_chunks.iter() {
                    chunk_loader.load(cx, cz);
                    loaded = Some((cx, cz));
                    break;
                }

                match loaded {
                    Some((cx, cz)) => {
                        needed_chunks.remove(&(cx, cz));
                    },
                    None => {}
                }
            }

            fps_frame_counter += 1;
            if fps_display_limiter.limit() {
                println!("{} frames per second", fps_frame_counter);
                fps_frame_counter = 0;
            }

            let frame_end_time = extra::time::precise_time_ns();
            let frame_time_ms = (frame_end_time - frame_start_time)/(1000*1000);
            if (frame_time_ms < FRAME_TIME_TARGET_MS) {
                //timer.sleep(FRAME_TIME_TARGET_MS - frame_time_ms);
            }
        }
    }
}

fn visible_chunks(x: i64, z: i64) -> ~[(i64, i64)] {
    let mask : i64 = !(CHUNK_SIZE as i64 - 1);
    let mut coords = ~[];
    for ix in std::iter::range_inclusive(-(WORLD_SIZE as i64)/2, (WORLD_SIZE as i64)/2) {
        for iz in std::iter::range_inclusive(-(WORLD_SIZE as i64)/2, (WORLD_SIZE as i64)/2) {
            let cx : i64 = (x & mask) + ix*CHUNK_SIZE as i64;
            let cz : i64 = (z & mask) + iz*CHUNK_SIZE as i64;
            coords.push((cx, cz));
        }
    }
    coords
}

fn load_graphics_resources() -> GraphicsResources {
    let vs = compile_shader(vertex_shader_src.as_bytes(), gl::VERTEX_SHADER);
    let fs = compile_shader(fragment_shader_src.as_bytes(), gl::FRAGMENT_SHADER);
    let program = link_program(vs, fs);

    let uniform_modelview = unsafe { "modelview".with_c_str(|ptr| gl::GetUniformLocation(program, ptr)) };
    let uniform_projection = unsafe { "projection".with_c_str(|ptr| gl::GetUniformLocation(program, ptr)) };

    return GraphicsResources {
        program: program,
        uniform_modelview: uniform_modelview,
        uniform_projection: uniform_projection,
    };

}

extern "C" {
    fn gluErrorString(error: GLenum) -> *GLubyte;
}

fn check_gl(message : &str) {
    let err = gl::GetError();
    if (err != gl::NO_ERROR) {
        unsafe {
            let err = std::str::raw::from_c_str(gluErrorString(err) as *i8);
            fail!("GL error {} at {}", err, message);
        }
    }
}

fn compile_shader(src: &[u8], ty: GLenum) -> GLuint {
    let shader = gl::CreateShader(ty);
    unsafe {
        // Attempt to compile the shader
        //transmute is used here because `as` causes ICE
        //wait a sec, is `src` null-terminated properly?
        gl::ShaderSource(shader, 1, std::cast::transmute(std::ptr::to_unsafe_ptr(&src.as_ptr())), ptr::null());
        gl::CompileShader(shader);

        // Get the compile status
        let mut status = gl::FALSE as GLint;
        gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

        // Fail on error
        if status != (gl::TRUE as GLint) {
            let mut len = 0;
            gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
            let mut buf = vec::from_elem(len as uint - 1, 0u8);     // subtract 1 to skip the trailing null character
            gl::GetShaderInfoLog(shader, len, ptr::mut_null(), buf.as_mut_ptr() as *mut GLchar);
            fail!(str::raw::from_utf8(buf).to_owned());
        }
    }
    shader
}

fn link_program(vs: GLuint, fs: GLuint) -> GLuint {
    let program = gl::CreateProgram();
    gl::AttachShader(program, vs);
    gl::AttachShader(program, fs);
    gl::LinkProgram(program);
    unsafe {
        // Get the link status
        let mut status = gl::FALSE as GLint;
        gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

        // Fail on error
        if status != (gl::TRUE as GLint) {
            let mut len: GLint = 0;
            gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
            let mut buf = vec::from_elem(len as uint - 1, 0u8);     // subtract 1 to skip the trailing null character
            gl::GetProgramInfoLog(program, len, ptr::mut_null(), buf.as_mut_ptr() as *mut GLchar);
            fail!(str::raw::from_utf8(buf).to_owned());
        }
    }
    program
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
    fn call(&self, _: glfw::Error, description: ~str) {
        fail!("GLFW Error: {:s}", description);
    }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
    fn call(&self, window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
        match (action, key) {
            (glfw::Press, glfw::KeyEscape) => window.set_should_close(true),
            _ => {}
        }
    }
}

struct FramebufferSizeContext {
    chan: Chan<(u32,u32)>
}
impl glfw::FramebufferSizeCallback for FramebufferSizeContext {
    fn call(&self, _: &glfw::Window, width: i32, height: i32) {
        self.chan.send((width as u32,height as u32));
    }
}
<commit_msg>constant camera speed regardless of frame rate<commit_after>#[feature(globs)];

extern mod native;
extern mod extra;
extern mod glfw;
extern mod gl;
extern mod cgmath;
extern mod noise;

use std::cast;
use std::ptr;
use std::str;
use std::vec;
use std::libc;
use std::io::Timer;
use std::hashmap::HashSet;

use gl::types::*;

use cgmath::matrix::Matrix;
use cgmath::matrix::Mat3;
use cgmath::matrix::Mat4;
use cgmath::matrix::ToMat4;
use cgmath::vector::Vector;
use cgmath::vector::Vec3;
use cgmath::vector::Vec4;
use cgmath::angle::rad;

#[link(name="GLU")]
extern {}

mod chunk;
mod ratelimiter;

static vertex_shader_src : &'static str = r"
#version 110

uniform mat4 modelview;
uniform mat4 projection;

attribute vec3 position;
attribute vec3 normal;

varying vec4 frag_color;

const vec4 obj_diffuse = vec4(0.2, 0.6, 0.2, 1.0);
const vec3 light_direction = vec3(0.408248, -0.816497, 0.408248);
const vec4 light_diffuse = vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient = vec4(0.2, 0.2, 0.2, 1.0);

const float planet_radius = 6371000.0 / 10000.0;

void main() {
    vec4 eye_position = modelview * vec4(position, 1.0);

    /* Curvature of the planet */
    float distance_squared = pow(eye_position.x, 2) + pow(eye_position.z, 2);
    eye_position.y -= planet_radius - sqrt(pow(planet_radius, 2) - distance_squared);

    gl_Position = projection * eye_position;

    vec4 diffuse_factor
        = max(-dot(normal, light_direction), 0.0) * light_diffuse;
    vec4 ambient_diffuse_factor = diffuse_factor + light_ambient;

    frag_color = ambient_diffuse_factor * obj_diffuse;
}
";

static fragment_shader_src : &'static str = r"
#version 110

varying vec4 frag_color;

void main() {
    gl_FragColor = frag_color;
}
";

pub static WORLD_SIZE: uint = 4;
pub static CHUNK_SIZE: uint = 64;
pub static WORLD_SEED: u32 = 42;

static FRAME_TIME_TARGET_MS : u64 = 16;
static CAMERA_SPEED : f32 = 30.0f32;

struct GraphicsResources {
    program: GLuint,
    uniform_modelview: GLint,
    uniform_projection: GLint,
}

#[start]
fn start(argc: int, argv: **u8) -> int {
    do native::start(argc, argv) {
        main();
    }
}

fn main() {
   glfw::set_error_callback(~ErrorContext);

    do glfw::start {
        let mut window_width = 800;
        let mut window_height = 600;

        let window = glfw::Window::create(window_width, window_height, "Hello, I am a window.", glfw::Windowed)
            .expect("Failed to create GLFW window.");

        window.set_cursor_mode(glfw::CursorDisabled);
        window.make_context_current();

        gl::load_with(glfw::get_proc_address);

        gl::Enable(gl::DEPTH_TEST);
        gl::Enable(gl::CULL_FACE);

        glfw::set_swap_interval(1);

        let graphics_resources = load_graphics_resources();

        gl::UseProgram(graphics_resources.program);

        let mut chunk_loader = chunk::ChunkLoader::new(WORLD_SEED, &graphics_resources);

        window.set_key_callback(~KeyContext);

        let (fb_size_port, fb_size_chan): (Port<(u32,u32)>, Chan<(u32,u32)>) = std::comm::Chan::new();
        window.set_framebuffer_size_callback(~FramebufferSizeContext { chan: fb_size_chan });

        let mut fps_display_limiter = ratelimiter::RateLimiter::new(1000*1000*1000);
        let mut fps_frame_counter = 0;

        let mut camera_position = Vec3::<f32>::new(0.0f32, 20.0f32, 40.0f32);

        //let mut timer = Timer::new().unwrap();

        let mut needed_chunks : HashSet<(i64, i64)> = HashSet::new();
        let mut load_limiter = ratelimiter::RateLimiter::new(1000*1000*100);

        let mut last_tick = extra::time::precise_time_ns();

        while !window.should_close() {
            let frame_start_time = extra::time::precise_time_ns();

            glfw::poll_events();

            loop {
                match fb_size_port.try_recv() {
                    Some((w,h)) => {
                        window_width = w;
                        window_height = h;
                    }
                    None => break
                }
            }

            let (cursor_x, cursor_y) = window.get_cursor_pos();
            let camera_angle_y = ((cursor_x * 0.0005) % 1.0) * std::f64::consts::PI * 2.0;
            let camera_angle_x = ((cursor_y * 0.0005) % 1.0) * std::f64::consts::PI * 2.0;

            let mut camera_velocity = Vec3::<f32>::new(0.0f32, 0.0f32, 0.0f32);

            match window.get_key(glfw::KeySpace) {
                glfw::Press => { camera_velocity.y += 1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyLeftControl) {
                glfw::Press => { camera_velocity.y += -1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyS) {
                glfw::Press => { camera_velocity.z += 1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyW) {
                glfw::Press => { camera_velocity.z += -1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyD) {
                glfw::Press => { camera_velocity.x += 1.0f32 }
                _ => {}
            }

            match window.get_key(glfw::KeyA) {
                glfw::Press => { camera_velocity.x += -1.0f32 }
                _ => {}
            }

            let now = extra::time::precise_time_ns();
            let tick_length = (now - last_tick) as f32 / (1000 * 1000 * 1000) as f32;
            last_tick = now;

            gl::Viewport(0,0, window_width as GLint, window_height as GLint);

            gl::ClearColor(0.0, 0.75, 1.0, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

            let projection = cgmath::projection::perspective(
                rad(1.57f32),
                window_width as f32 / window_height as f32,
                0.1f32, 1000.0f32);

            unsafe {
                gl::UniformMatrix4fv(graphics_resources.uniform_projection, 1, gl::FALSE, cast::transmute(&projection));
            }

            let camera_translation = Mat4::<f32>::from_cols(
                Vec4::<f32>::unit_x(),
                Vec4::<f32>::unit_y(),
                Vec4::<f32>::unit_z(),
                camera_position.mul_s(-1.0f32).extend(1.0f32));
            let camera_rotation_x = Mat3::<f32>::from_angle_x(rad(camera_angle_x as f32)).to_mat4();
            let camera_rotation_y = Mat3::<f32>::from_angle_y(rad(camera_angle_y as f32)).to_mat4();
            let camera = camera_rotation_x.mul_m(&camera_rotation_y).mul_m(&camera_translation);

            let inv_camera_rotation = Mat3::<f32>::from_euler(rad(-camera_angle_x as f32), rad(-camera_angle_y as f32), rad(0.0f32));
            let absolute_camera_velocity = inv_camera_rotation.mul_v(&camera_velocity).mul_s(CAMERA_SPEED).mul_s(tick_length);
            camera_position.add_self_v(&absolute_camera_velocity);

            let coords = visible_chunks(camera_position.x as i64,
                                        camera_position.z as i64);

            for &(cx, cz) in coords.iter() {
                match chunk_loader.cache.find_mut(&(cx, cz)) {
                    Some(chunk) => {
                        chunk.touch();

                        let chunk_translation = Mat4::<f32>::from_cols(
                            Vec4::<f32>::unit_x(),
                            Vec4::<f32>::unit_y(),
                            Vec4::<f32>::unit_z(),
                            Vec4::<f32>::new(chunk.x as f32, 0.0f32, chunk.z as f32, 1.0f32));

                        let modelview = camera.mul_m(&chunk_translation);

                        gl::BindVertexArray(chunk.vao);

                        unsafe {
                            gl::UniformMatrix4fv(graphics_resources.uniform_modelview, 1, gl::FALSE, cast::transmute(&modelview));
                            gl::DrawElements(gl::TRIANGLES, chunk.num_elements as i32, gl::UNSIGNED_INT, ptr::null());
                        }

                        gl::BindVertexArray(0);
                    },
                    None => {
                        needed_chunks.insert((cx, cz));
                    }
                }
            }

            window.swap_buffers();

            check_gl("main loop");

            if !needed_chunks.is_empty() && load_limiter.limit() {
                let mut loaded = None;

                for &(cx, cz) in needed_chunks.iter() {
                    chunk_loader.load(cx, cz);
                    loaded = Some((cx, cz));
                    break;
                }

                match loaded {
                    Some((cx, cz)) => {
                        needed_chunks.remove(&(cx, cz));
                    },
                    None => {}
                }
            }

            fps_frame_counter += 1;
            if fps_display_limiter.limit() {
                println!("{} frames per second", fps_frame_counter);
                fps_frame_counter = 0;
            }

            let frame_end_time = extra::time::precise_time_ns();
            let frame_time_ms = (frame_end_time - frame_start_time)/(1000*1000);
            if (frame_time_ms < FRAME_TIME_TARGET_MS) {
                //timer.sleep(FRAME_TIME_TARGET_MS - frame_time_ms);
            }
        }
    }
}

fn visible_chunks(x: i64, z: i64) -> ~[(i64, i64)] {
    let mask : i64 = !(CHUNK_SIZE as i64 - 1);
    let mut coords = ~[];
    for ix in std::iter::range_inclusive(-(WORLD_SIZE as i64)/2, (WORLD_SIZE as i64)/2) {
        for iz in std::iter::range_inclusive(-(WORLD_SIZE as i64)/2, (WORLD_SIZE as i64)/2) {
            let cx : i64 = (x & mask) + ix*CHUNK_SIZE as i64;
            let cz : i64 = (z & mask) + iz*CHUNK_SIZE as i64;
            coords.push((cx, cz));
        }
    }
    coords
}

fn load_graphics_resources() -> GraphicsResources {
    let vs = compile_shader(vertex_shader_src.as_bytes(), gl::VERTEX_SHADER);
    let fs = compile_shader(fragment_shader_src.as_bytes(), gl::FRAGMENT_SHADER);
    let program = link_program(vs, fs);

    let uniform_modelview = unsafe { "modelview".with_c_str(|ptr| gl::GetUniformLocation(program, ptr)) };
    let uniform_projection = unsafe { "projection".with_c_str(|ptr| gl::GetUniformLocation(program, ptr)) };

    return GraphicsResources {
        program: program,
        uniform_modelview: uniform_modelview,
        uniform_projection: uniform_projection,
    };

}

extern "C" {
    fn gluErrorString(error: GLenum) -> *GLubyte;
}

fn check_gl(message : &str) {
    let err = gl::GetError();
    if (err != gl::NO_ERROR) {
        unsafe {
            let err = std::str::raw::from_c_str(gluErrorString(err) as *i8);
            fail!("GL error {} at {}", err, message);
        }
    }
}

fn compile_shader(src: &[u8], ty: GLenum) -> GLuint {
    let shader = gl::CreateShader(ty);
    unsafe {
        // Attempt to compile the shader
        //transmute is used here because `as` causes ICE
        //wait a sec, is `src` null-terminated properly?
        gl::ShaderSource(shader, 1, std::cast::transmute(std::ptr::to_unsafe_ptr(&src.as_ptr())), ptr::null());
        gl::CompileShader(shader);

        // Get the compile status
        let mut status = gl::FALSE as GLint;
        gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

        // Fail on error
        if status != (gl::TRUE as GLint) {
            let mut len = 0;
            gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
            let mut buf = vec::from_elem(len as uint - 1, 0u8);     // subtract 1 to skip the trailing null character
            gl::GetShaderInfoLog(shader, len, ptr::mut_null(), buf.as_mut_ptr() as *mut GLchar);
            fail!(str::raw::from_utf8(buf).to_owned());
        }
    }
    shader
}

fn link_program(vs: GLuint, fs: GLuint) -> GLuint {
    let program = gl::CreateProgram();
    gl::AttachShader(program, vs);
    gl::AttachShader(program, fs);
    gl::LinkProgram(program);
    unsafe {
        // Get the link status
        let mut status = gl::FALSE as GLint;
        gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

        // Fail on error
        if status != (gl::TRUE as GLint) {
            let mut len: GLint = 0;
            gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
            let mut buf = vec::from_elem(len as uint - 1, 0u8);     // subtract 1 to skip the trailing null character
            gl::GetProgramInfoLog(program, len, ptr::mut_null(), buf.as_mut_ptr() as *mut GLchar);
            fail!(str::raw::from_utf8(buf).to_owned());
        }
    }
    program
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
    fn call(&self, _: glfw::Error, description: ~str) {
        fail!("GLFW Error: {:s}", description);
    }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
    fn call(&self, window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
        match (action, key) {
            (glfw::Press, glfw::KeyEscape) => window.set_should_close(true),
            _ => {}
        }
    }
}

struct FramebufferSizeContext {
    chan: Chan<(u32,u32)>
}
impl glfw::FramebufferSizeCallback for FramebufferSizeContext {
    fn call(&self, _: &glfw::Window, width: i32, height: i32) {
        self.chan.send((width as u32,height as u32));
    }
}
<|endoftext|>


<commit_before>//! Runs rustfmt on the repository.

use crate::Build;
use std::process::Command;
use ignore::WalkBuilder;
use std::path::Path;
use build_helper::t;

fn rustfmt(build: &Build, path: &Path, check: bool) {
    let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| {
        eprintln!("./x.py fmt is not supported on this channel");
        std::process::exit(1);
    });

    let mut cmd = Command::new(&rustfmt_path);
    // avoid the submodule config paths from coming into play,
    // we only allow a single global config for the workspace for now
    cmd.arg("--config-path").arg(&build.src.canonicalize().unwrap());
    cmd.arg("--unstable-features");
    cmd.arg("--skip-children");
    if check {
        cmd.arg("--check");
    }
    cmd.arg(&path);
    let cmd_debug = format!("{:?}", cmd);
    let status = cmd.status().expect("executing rustfmt");
    assert!(status.success(), "running {} successful", cmd_debug);
}

#[derive(serde::Deserialize)]
struct RustfmtConfig {
    ignore: Vec<String>,
}

pub fn format(build: &Build, check: bool) {
    let mut builder = ignore::types::TypesBuilder::new();
    builder.add_defaults();
    builder.select("rust");
    let matcher = builder.build().unwrap();

    let rustfmt_config = t!(std::fs::read_to_string(build.src.join("rustfmt.toml")));
    let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
    let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src);
    for ignore in rustfmt_config.ignore {
        ignore_fmt.add(&format!("!{}", ignore)).expect(&ignore);
    }
    let ignore_fmt = ignore_fmt.build().unwrap();

    let walker = WalkBuilder::new(&build.src)
        .types(matcher)
        .overrides(ignore_fmt)
        .build();
    for entry in walker {
        let entry = t!(entry);
        if entry.file_type().map_or(false, |t| t.is_file()) {
            rustfmt(build, &entry.path(), check);
        }
    }
}
<commit_msg>Do not run if rustfmt.toml does not exist<commit_after>//! Runs rustfmt on the repository.

use crate::Build;
use std::process::Command;
use ignore::WalkBuilder;
use std::path::Path;
use build_helper::t;

fn rustfmt(build: &Build, path: &Path, check: bool) {
    let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| {
        eprintln!("./x.py fmt is not supported on this channel");
        std::process::exit(1);
    });

    let mut cmd = Command::new(&rustfmt_path);
    // avoid the submodule config paths from coming into play,
    // we only allow a single global config for the workspace for now
    cmd.arg("--config-path").arg(&build.src.canonicalize().unwrap());
    cmd.arg("--unstable-features");
    cmd.arg("--skip-children");
    if check {
        cmd.arg("--check");
    }
    cmd.arg(&path);
    let cmd_debug = format!("{:?}", cmd);
    let status = cmd.status().expect("executing rustfmt");
    assert!(status.success(), "running {} successful", cmd_debug);
}

#[derive(serde::Deserialize)]
struct RustfmtConfig {
    ignore: Vec<String>,
}

pub fn format(build: &Build, check: bool) {
    let mut builder = ignore::types::TypesBuilder::new();
    builder.add_defaults();
    builder.select("rust");
    let matcher = builder.build().unwrap();
    let rustfmt_config = build.src.join("rustfmt.toml");
    if !rustfmt_config.exists() {
        eprintln!("Not running formatting checks; rustfmt.toml does not exist.");
        eprintln!("This may happen in distributed tarballs.");
        return;
    }
    let rustfmt_config = t!(std::fs::read_to_string(&rustfmt_config));
    let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
    let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src);
    for ignore in rustfmt_config.ignore {
        ignore_fmt.add(&format!("!{}", ignore)).expect(&ignore);
    }
    let ignore_fmt = ignore_fmt.build().unwrap();

    let walker = WalkBuilder::new(&build.src)
        .types(matcher)
        .overrides(ignore_fmt)
        .build();
    for entry in walker {
        let entry = t!(entry);
        if entry.file_type().map_or(false, |t| t.is_file()) {
            rustfmt(build, &entry.path(), check);
        }
    }
}
<|endoftext|>


<commit_before>use proc_macro2::{Delimiter, Span};

use error::Result;
use parse::ParseBuffer;
#[cfg(any(feature = "full", feature = "derive"))]
use parse::ParseStream;
use private;
use token;

pub struct Parens<'a> {
    pub token: token::Paren,
    pub content: ParseBuffer<'a>,
}

pub struct Braces<'a> {
    pub token: token::Brace,
    pub content: ParseBuffer<'a>,
}

pub struct Brackets<'a> {
    pub token: token::Bracket,
    pub content: ParseBuffer<'a>,
}

#[cfg(any(feature = "full", feature = "derive"))]
pub struct Group<'a> {
    pub token: token::Group,
    pub content: ParseBuffer<'a>,
}

impl<'a> ParseBuffer<'a> {
    fn parse_delimited(&self, delimiter: Delimiter) -> Result<(Span, ParseBuffer<'a>)> {
        self.step(|cursor| {
            if let Some((content, span, rest)) = cursor.group(delimiter) {
                let unexpected = private::get_unexpected(self);
                let content =
                    private::new_parse_buffer(span, cursor.advance(content), unexpected);
                Ok(((span, content), rest))
            } else {
                let message = match delimiter {
                    Delimiter::Parenthesis => "expected parentheses",
                    Delimiter::Brace => "expected curly braces",
                    Delimiter::Bracket => "expected square brackets",
                    Delimiter::None => "expected invisible group",
                };
                Err(cursor.error(message))
            }
        })
    }

    // Not public API.
    #[doc(hidden)]
    pub fn parse_parens(&self) -> Result<Parens<'a>> {
        self.parse_delimited(Delimiter::Parenthesis)
            .map(|(span, content)| Parens {
                token: token::Paren(span),
                content: content,
            })
    }

    // Not public API.
    #[doc(hidden)]
    pub fn parse_braces(&self) -> Result<Braces<'a>> {
        self.parse_delimited(Delimiter::Brace)
            .map(|(span, content)| Braces {
                token: token::Brace(span),
                content: content,
            })
    }

    // Not public API.
    #[doc(hidden)]
    pub fn parse_brackets(&self) -> Result<Brackets<'a>> {
        self.parse_delimited(Delimiter::Bracket)
            .map(|(span, content)| Brackets {
                token: token::Bracket(span),
                content: content,
            })
    }
}

#[cfg(any(feature = "full", feature = "derive"))]
impl private {
    pub fn parse_group(input: ParseStream) -> Result<Group> {
        input.parse_delimited(Delimiter::None)
            .map(|(span, content)| Group {
                token: token::Group(span),
                content: content,
            })
    }
}

/// Parse a set of parentheses and expose their content to subsequent parsers.
#[macro_export]
macro_rules! parenthesized {
    ($content:ident in $cursor:expr) => {
        match $crate::parse::ParseBuffer::parse_parens(&$cursor) {
            $crate::export::Ok(parens) => {
                $content = parens.content;
                parens.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}

/// Parse a set of curly braces and expose their content to subsequent parsers.
///
/// ```rust
/// # extern crate syn;
/// #
/// use syn::{braced, token, Ident, Token};
/// use syn::parse::{Parse, ParseStream, Result};
/// use syn::punctuated::Punctuated;
/// #
/// # type Field = Ident;
///
/// // Parse a simplified struct syntax like:
/// //
/// //     struct S {
/// //         a: A,
/// //         b: B,
/// //     }
/// struct Struct {
///     pub struct_token: Token![struct],
///     pub ident: Ident,
///     pub brace_token: token::Brace,
///     pub fields: Punctuated<Field, Token![,]>,
/// }
///
/// impl Parse for Struct {
///     fn parse(input: ParseStream) -> Result<Self> {
///         let content;
///         Ok(Struct {
///             struct_token: input.parse()?,
///             ident: input.parse()?,
///             brace_token: braced!(content in input),
///             fields: content.parse_terminated(Field::parse)?,
///         })
///     }
/// }
/// ```
#[macro_export]
macro_rules! braced {
    ($content:ident in $cursor:expr) => {
        match $crate::parse::ParseBuffer::parse_braces(&$cursor) {
            $crate::export::Ok(braces) => {
                $content = braces.content;
                braces.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}

/// Parse a set of square brackets and expose their content to subsequent
/// parsers.
#[macro_export]
macro_rules! bracketed {
    ($content:ident in $cursor:expr) => {
        match $crate::parse::ParseBuffer::parse_brackets(&$cursor) {
            $crate::export::Ok(brackets) => {
                $content = brackets.content;
                brackets.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}
<commit_msg>Show Field struct in braced example<commit_after>use proc_macro2::{Delimiter, Span};

use error::Result;
use parse::ParseBuffer;
#[cfg(any(feature = "full", feature = "derive"))]
use parse::ParseStream;
use private;
use token;

pub struct Parens<'a> {
    pub token: token::Paren,
    pub content: ParseBuffer<'a>,
}

pub struct Braces<'a> {
    pub token: token::Brace,
    pub content: ParseBuffer<'a>,
}

pub struct Brackets<'a> {
    pub token: token::Bracket,
    pub content: ParseBuffer<'a>,
}

#[cfg(any(feature = "full", feature = "derive"))]
pub struct Group<'a> {
    pub token: token::Group,
    pub content: ParseBuffer<'a>,
}

impl<'a> ParseBuffer<'a> {
    fn parse_delimited(&self, delimiter: Delimiter) -> Result<(Span, ParseBuffer<'a>)> {
        self.step(|cursor| {
            if let Some((content, span, rest)) = cursor.group(delimiter) {
                let unexpected = private::get_unexpected(self);
                let content =
                    private::new_parse_buffer(span, cursor.advance(content), unexpected);
                Ok(((span, content), rest))
            } else {
                let message = match delimiter {
                    Delimiter::Parenthesis => "expected parentheses",
                    Delimiter::Brace => "expected curly braces",
                    Delimiter::Bracket => "expected square brackets",
                    Delimiter::None => "expected invisible group",
                };
                Err(cursor.error(message))
            }
        })
    }

    // Not public API.
    #[doc(hidden)]
    pub fn parse_parens(&self) -> Result<Parens<'a>> {
        self.parse_delimited(Delimiter::Parenthesis)
            .map(|(span, content)| Parens {
                token: token::Paren(span),
                content: content,
            })
    }

    // Not public API.
    #[doc(hidden)]
    pub fn parse_braces(&self) -> Result<Braces<'a>> {
        self.parse_delimited(Delimiter::Brace)
            .map(|(span, content)| Braces {
                token: token::Brace(span),
                content: content,
            })
    }

    // Not public API.
    #[doc(hidden)]
    pub fn parse_brackets(&self) -> Result<Brackets<'a>> {
        self.parse_delimited(Delimiter::Bracket)
            .map(|(span, content)| Brackets {
                token: token::Bracket(span),
                content: content,
            })
    }
}

#[cfg(any(feature = "full", feature = "derive"))]
impl private {
    pub fn parse_group(input: ParseStream) -> Result<Group> {
        input.parse_delimited(Delimiter::None)
            .map(|(span, content)| Group {
                token: token::Group(span),
                content: content,
            })
    }
}

/// Parse a set of parentheses and expose their content to subsequent parsers.
#[macro_export]
macro_rules! parenthesized {
    ($content:ident in $cursor:expr) => {
        match $crate::parse::ParseBuffer::parse_parens(&$cursor) {
            $crate::export::Ok(parens) => {
                $content = parens.content;
                parens.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}

/// Parse a set of curly braces and expose their content to subsequent parsers.
///
/// ```rust
/// # extern crate quote;
/// # use quote::quote;
/// #
/// extern crate syn;
///
/// use syn::{braced, token, Ident, Token, Type};
/// use syn::parse::{Parse, ParseStream, Result};
/// use syn::punctuated::Punctuated;
///
/// // Parse a simplified struct syntax like:
/// //
/// //     struct S {
/// //         a: A,
/// //         b: B,
/// //     }
/// struct Struct {
///     struct_token: Token![struct],
///     ident: Ident,
///     brace_token: token::Brace,
///     fields: Punctuated<Field, Token![,]>,
/// }
///
/// struct Field {
///     name: Ident,
///     colon_token: Token![:],
///     ty: Type,
/// }
///
/// impl Parse for Struct {
///     fn parse(input: ParseStream) -> Result<Self> {
///         let content;
///         Ok(Struct {
///             struct_token: input.parse()?,
///             ident: input.parse()?,
///             brace_token: braced!(content in input),
///             fields: content.parse_terminated(Field::parse)?,
///         })
///     }
/// }
///
/// impl Parse for Field {
///     fn parse(input: ParseStream) -> Result<Self> {
///         Ok(Field {
///             name: input.parse()?,
///             colon_token: input.parse()?,
///             ty: input.parse()?,
///         })
///     }
/// }
/// #
/// # fn main() {
/// #     let input = quote! {
/// #         struct S {
/// #             a: A,
/// #             b: B,
/// #         }
/// #     };
/// #     syn::parse2::<Struct>(input).unwrap();
/// # }
/// ```
#[macro_export]
macro_rules! braced {
    ($content:ident in $cursor:expr) => {
        match $crate::parse::ParseBuffer::parse_braces(&$cursor) {
            $crate::export::Ok(braces) => {
                $content = braces.content;
                braces.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}

/// Parse a set of square brackets and expose their content to subsequent
/// parsers.
#[macro_export]
macro_rules! bracketed {
    ($content:ident in $cursor:expr) => {
        match $crate::parse::ParseBuffer::parse_brackets(&$cursor) {
            $crate::export::Ok(brackets) => {
                $content = brackets.content;
                brackets.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}
<|endoftext|>


<commit_before>use std::collections::hash_map::{HashMap, RandomState};
use std::error;
use std::hash::{BuildHasher, Hash};
use {Command, Commands, Error, Record, Stack};

/// A group of either stacks or records.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Group<K: Hash + Eq, V, S = RandomState> where S: BuildHasher {
    map: HashMap<K, V, S>,
    active: Option<K>,
}

impl<K: Hash + Eq, V, S: BuildHasher> Group<K, V, S> {
    /// Returns a new group.
    #[inline]
    pub fn new() -> Group<K, V, RandomState> {
        Default::default()
    }

    /// Returns a new group with the given capacity.
    #[inline]
    pub fn with_capacity(capacity: usize) -> Group<K, V, RandomState> {
        Group::with_capacity_and_hasher(capacity, Default::default())
    }

    /// Returns a new group with the given hasher.
    #[inline]
    pub fn with_hasher(hash_builder: S) -> Group<K, V, S> {
        Group {
            map: HashMap::with_hasher(hash_builder),
            active: None,
        }
    }

    /// Returns a new group with the given capacity and hasher.
    #[inline]
    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Group<K, V, S> {
        Group {
            map: HashMap::with_capacity_and_hasher(capacity, hash_builder),
            active: None,
        }
    }

    /// Returns the capacity of the group.
    #[inline]
    pub fn capacity(&self) -> usize {
        self.map.capacity()
    }

    /// Returns the number of items in the group.
    #[inline]
    pub fn len(&self) -> usize {
        self.map.len()
    }

    /// Returns `true` if the group is empty.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.map.is_empty()
    }

    /// Inserts an item into the group.
    #[inline]
    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
        self.map.insert(k, v)
    }

    /// Removes an item from the group.
    #[inline]
    pub fn remove(&mut self, k: &K) -> Option<V> {
        self.map.remove(k)
    }

    /// Gets the current active item in the group.
    #[inline]
    pub fn get(&self) -> Option<&V> {
        self.active.as_ref().and_then(|active| self.map.get(active))
    }

    /// Sets the current active item in the group.
    #[inline]
    pub fn set<T: Into<Option<K>>>(&mut self, k: T) -> bool {
        match k.into() {
            Some(ref k) if !self.map.contains_key(k) => false,
            k => {
                self.active = k;
                true
            }
        }
    }
}

impl<K: Hash + Eq, R, S: BuildHasher> Group<K, Stack<R>, S> {
    /// Calls the [`push`] method on the active stack.
    ///
    /// [`push`]: stack/struct.Stack.html#method.push
    #[inline]
    pub fn push<C>(&mut self, cmd: C) -> Option<Result<(), Error<R>>>
    where
        C: Command<R> + 'static,
        R: 'static,
    {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .map(move |stack| stack.push(cmd))
    }

    /// Calls the [`pop`] method on the active stack.
    ///
    /// [`pop`]: stack/struct.Stack.html#method.pop
    #[inline]
    pub fn pop(&mut self) -> Option<Result<Box<Command<R>>, Error<R>>> {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .and_then(|stack| stack.pop())
    }
}

impl<'a, K: Hash + Eq, R, S: BuildHasher> Group<K, Record<'a, R>, S> {
    /// Calls the [`push`] method on the active record.
    ///
    /// [`push`]: record/struct.Record.html#method.push
    #[inline]
    pub fn push<C>(&mut self, cmd: C) -> Option<Result<Commands<R>, Error<R>>>
    where
        C: Command<R> + 'static,
        R: 'static,
    {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .map(move |record| record.push(cmd))
    }

    /// Calls the [`redo`] method on the active record.
    ///
    /// [`redo`]: record/struct.Record.html#method.redo
    #[inline]
    pub fn redo(&mut self) -> Option<Result<(), Box<error::Error>>> {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .and_then(|record| record.redo())
    }

    /// Calls the [`undo`] method on the active record.
    ///
    /// [`undo`]: record/struct.Record.html#method.undo
    #[inline]
    pub fn undo(&mut self) -> Option<Result<(), Box<error::Error>>> {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .and_then(|record| record.undo())
    }
}

impl<K: Hash + Eq, V, S: BuildHasher + Default> Default for Group<K, V, S> {
    #[inline]
    fn default() -> Group<K, V, S> {
        Group::with_hasher(Default::default())
    }
}
<commit_msg>Add signals to Group<commit_after>use std::collections::hash_map::{HashMap, RandomState};
use std::error;
use std::fmt::{self, Debug, Formatter};
use std::hash::{BuildHasher, Hash};
use {Command, Commands, Error, Record, Stack};

/// A group of either stacks or records.
pub struct Group<'a, K: Hash + Eq, V, S = RandomState> where S: BuildHasher {
    map: HashMap<K, V, S>,
    active: Option<K>,
    signals: Option<Box<FnMut(&K) + Send + Sync + 'a>>,
}

impl<'a, K: Hash + Eq, V, S: BuildHasher> Group<'a, K, V, S> {
    /// Returns a new group.
    #[inline]
    pub fn new() -> Group<'a, K, V, RandomState> {
        Default::default()
    }

    /// Returns a new group with the given capacity.
    #[inline]
    pub fn with_capacity(capacity: usize) -> Group<'a, K, V, RandomState> {
        Group::with_capacity_and_hasher(capacity, Default::default())
    }

    /// Returns a new group with the given hasher.
    #[inline]
    pub fn with_hasher(hash_builder: S) -> Group<'a, K, V, S> {
        Group {
            map: HashMap::with_hasher(hash_builder),
            active: None,
            signals: None,
        }
    }

    /// Returns a new group with the given capacity and hasher.
    #[inline]
    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Group<'a, K, V, S> {
        Group {
            map: HashMap::with_capacity_and_hasher(capacity, hash_builder),
            active: None,
            signals: None,
        }
    }

    /// Returns the capacity of the group.
    #[inline]
    pub fn capacity(&self) -> usize {
        self.map.capacity()
    }

    /// Returns the number of items in the group.
    #[inline]
    pub fn len(&self) -> usize {
        self.map.len()
    }

    /// Returns `true` if the group is empty.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.map.is_empty()
    }

    /// Inserts an item into the group.
    #[inline]
    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
        self.map.insert(k, v)
    }

    /// Removes an item from the group.
    #[inline]
    pub fn remove(&mut self, k: &K) -> Option<V> {
        self.map.remove(k)
    }

    /// Gets the current active item in the group.
    #[inline]
    pub fn get(&self) -> Option<&V> {
        self.active.as_ref().and_then(|active| self.map.get(active))
    }

    /// Sets the current active item in the group.
    #[inline]
    pub fn set<T: Into<Option<K>>>(&mut self, k: T) -> bool {
        match k.into() {
            Some(ref k) if !self.map.contains_key(k) => false,
            k => {
                self.active = k;
                if let (Some(k), Some(f)) = (self.active.as_ref(), self.signals.as_mut()) {
                    f(k);
                }
                true
            }
        }
    }
}

impl<'a, K: Hash + Eq, R, S: BuildHasher> Group<'a, K, Stack<R>, S> {
    /// Calls the [`push`] method on the active stack.
    ///
    /// [`push`]: stack/struct.Stack.html#method.push
    #[inline]
    pub fn push<C>(&mut self, cmd: C) -> Option<Result<(), Error<R>>>
    where
        C: Command<R> + 'static,
        R: 'static,
    {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .map(move |stack| stack.push(cmd))
    }

    /// Calls the [`pop`] method on the active stack.
    ///
    /// [`pop`]: stack/struct.Stack.html#method.pop
    #[inline]
    pub fn pop(&mut self) -> Option<Result<Box<Command<R>>, Error<R>>> {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .and_then(|stack| stack.pop())
    }
}

impl<'a, K: Hash + Eq, R, S: BuildHasher> Group<'a, K, Record<'a, R>, S> {
    /// Calls the [`push`] method on the active record.
    ///
    /// [`push`]: record/struct.Record.html#method.push
    #[inline]
    pub fn push<C>(&mut self, cmd: C) -> Option<Result<Commands<R>, Error<R>>>
    where
        C: Command<R> + 'static,
        R: 'static,
    {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .map(move |record| record.push(cmd))
    }

    /// Calls the [`redo`] method on the active record.
    ///
    /// [`redo`]: record/struct.Record.html#method.redo
    #[inline]
    pub fn redo(&mut self) -> Option<Result<(), Box<error::Error>>> {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .and_then(|record| record.redo())
    }

    /// Calls the [`undo`] method on the active record.
    ///
    /// [`undo`]: record/struct.Record.html#method.undo
    #[inline]
    pub fn undo(&mut self) -> Option<Result<(), Box<error::Error>>> {
        let map = &mut self.map;
        self.active
            .as_ref()
            .and_then(|active| map.get_mut(active))
            .and_then(|record| record.undo())
    }
}

impl<'a, K: Hash + Eq + Debug, V: Debug, S: BuildHasher> Debug for Group<'a, K, V, S> {
    #[inline]
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        f.debug_struct("Group")
            .field("map", &self.map)
            .field("active", &self.active)
            .finish()
    }
}

impl<'a, K: Hash + Eq, V, S: BuildHasher + Default> Default for Group<'a, K, V, S> {
    #[inline]
    fn default() -> Group<'a, K, V, S> {
        Group::with_hasher(Default::default())
    }
}
<|endoftext|>


<commit_before>//! The `image` element.

use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::aspect_ratio::AspectRatio;
use crate::attributes::Attributes;
use crate::bbox::BoundingBox;
use crate::document::AcquiredNodes;
use crate::drawing_ctx::DrawingCtx;
use crate::element::{Draw, ElementResult, SetAttributes};
use crate::error::*;
use crate::href::{is_href, set_href};
use crate::length::*;
use crate::node::{CascadedValues, Node};
use crate::parsers::ParseValue;
use crate::rect::Rect;
use crate::url_resolver::Href;

#[derive(Default)]
pub struct Image {
    x: Length<Horizontal>,
    y: Length<Vertical>,
    width: Length<Horizontal>,
    height: Length<Vertical>,
    aspect: AspectRatio,
    href: Option<Href>,
}

impl SetAttributes for Image {
    fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
        for (attr, value) in attrs.iter() {
            match attr.expanded() {
                expanded_name!("", "x") => self.x = attr.parse(value)?,
                expanded_name!("", "y") => self.y = attr.parse(value)?,
                expanded_name!("", "width") => {
                    self.width = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!("", "height") => {
                    self.height = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!("", "preserveAspectRatio") => self.aspect = attr.parse(value)?,

                // "path" is used by some older Adobe Illustrator versions
                ref a if is_href(a) || *a == expanded_name!("", "path") => {
                    let href = Href::parse(value)
                        .map_err(|_| ValueErrorKind::parse_error("could not parse href"))
                        .attribute(attr.clone())?;

                    set_href(a, &mut self.href, href);
                }

                _ => (),
            }
        }

        Ok(())
    }
}

impl Draw for Image {
    fn draw(
        &self,
        node: &Node,
        acquired_nodes: &mut AcquiredNodes<'_>,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx,
        clipping: bool,
    ) -> Result<BoundingBox, RenderingError> {
        let surface = match self.href {
            Some(Href::PlainUrl(ref url)) => match acquired_nodes.lookup_image(url) {
                Ok(surf) => surf,
                Err(e) => {
                    rsvg_log!("could not load image \"{}\": {}", url, e);
                    return Ok(draw_ctx.empty_bbox());
                }
            },
            Some(_) => {
                rsvg_log!(
                    "not rendering {} because its href cannot contain a fragment identifier",
                    node
                );

                return Ok(draw_ctx.empty_bbox());
            }
            None => return Ok(draw_ctx.empty_bbox()),
        };

        let values = cascaded.get();

        let params = draw_ctx.get_view_params();
        let x = self.x.normalize(&values, &params);
        let y = self.y.normalize(&values, &params);
        let w = self.width.normalize(&values, &params);
        let h = self.height.normalize(&values, &params);

        draw_ctx.draw_image(
            &surface,
            Rect::new(x, y, x + w, y + h),
            self.aspect,
            node,
            acquired_nodes,
            values,
            clipping,
        )
    }
}
<commit_msg>image: store href attr as a String<commit_after>//! The `image` element.

use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::aspect_ratio::AspectRatio;
use crate::attributes::Attributes;
use crate::bbox::BoundingBox;
use crate::document::AcquiredNodes;
use crate::drawing_ctx::DrawingCtx;
use crate::element::{Draw, ElementResult, SetAttributes};
use crate::error::*;
use crate::href::{is_href, set_href};
use crate::length::*;
use crate::node::{CascadedValues, Node};
use crate::parsers::ParseValue;
use crate::rect::Rect;

#[derive(Default)]
pub struct Image {
    x: Length<Horizontal>,
    y: Length<Vertical>,
    width: Length<Horizontal>,
    height: Length<Vertical>,
    aspect: AspectRatio,
    href: Option<String>,
}

impl SetAttributes for Image {
    fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
        for (attr, value) in attrs.iter() {
            match attr.expanded() {
                expanded_name!("", "x") => self.x = attr.parse(value)?,
                expanded_name!("", "y") => self.y = attr.parse(value)?,
                expanded_name!("", "width") => {
                    self.width = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!("", "height") => {
                    self.height = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!("", "preserveAspectRatio") => self.aspect = attr.parse(value)?,

                // "path" is used by some older Adobe Illustrator versions
                ref a if is_href(a) || *a == expanded_name!("", "path") => {
                    set_href(a, &mut self.href, value.to_string())
                }

                _ => (),
            }
        }

        Ok(())
    }
}

impl Draw for Image {
    fn draw(
        &self,
        node: &Node,
        acquired_nodes: &mut AcquiredNodes<'_>,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx,
        clipping: bool,
    ) -> Result<BoundingBox, RenderingError> {
        let surface = match self.href {
            Some(ref url) => match acquired_nodes.lookup_image(url) {
                Ok(surf) => surf,
                Err(e) => {
                    rsvg_log!("could not load image \"{}\": {}", url, e);
                    return Ok(draw_ctx.empty_bbox());
                }
            },
            None => return Ok(draw_ctx.empty_bbox()),
        };

        let values = cascaded.get();

        let params = draw_ctx.get_view_params();
        let x = self.x.normalize(&values, &params);
        let y = self.y.normalize(&values, &params);
        let w = self.width.normalize(&values, &params);
        let h = self.height.normalize(&values, &params);

        draw_ctx.draw_image(
            &surface,
            Rect::new(x, y, x + w, y + h),
            self.aspect,
            node,
            acquired_nodes,
            values,
            clipping,
        )
    }
}
<|endoftext|>


<commit_before>use super::vector3::Vector3;
use std::ops;

///Implements a matrix 3 x 3
#[derive(Clone, PartialEq, Debug)]
pub struct Matrix3x3 {
    pub r1: Vector3,
    pub r2: Vector3,
    pub r3: Vector3,
}

impl Matrix3x3 {

    ///Creates a new Matrix3x3 from 3 vector3 rows
    pub fn new(r1: Vector3, r2: Vector3, r3: Vector3) -> Matrix3x3 {
        Matrix3x3 {r1: r1, r2: r2, r3: r3}
    }

    ///Creates a new Matrix3x3 from 9 indexed floats
    pub fn new_idx(n1: f32, n2: f32, n3: f32, n4: f32, n5: f32, n6: f32, n7: f32, n8: f32, n9: f32)
                                                                                -> Matrix3x3 {

        Matrix3x3 {r1: Vector3::new(n1, n2, n3),
                   r2: Vector3::new(n4, n5, n6),
                   r3: Vector3::new(n7, n8, n9)}
    }

    #[allow(dead_code, non_snake_case)]
    pub fn IDENTITY() -> Matrix3x3 {
        Matrix3x3::new_idx(1f32, 0f32, 0f32, 0f32, 1f32, 0f32,
                           0f32, 0f32, 1f32)
    }

    ///Matrix 3x3 determinant
    pub fn det(self) -> f32 {
        (self.r1.x * self.r2.y * self.r3.z +
            self.r1.y * self.r2.z * self.r3.x +
            self.r1.z * self.r2.x * self.r3.y)
        - (self.r1.z * self.r2.y * self.r3.x +
            self.r1.y * self.r2.x * self.r3.z +
            self.r1.x * self.r2.z * self.r3.y)
    }
}

impl ops::Add for Matrix3x3 {
    type Output = Matrix3x3;

    ///Implements the Matrix 3x3 '+' trait
    fn add(self, new: Matrix3x3) -> Matrix3x3 {
        Matrix3x3::new(
            Vector3::new(self.r1.x + new.r1.x, self.r1.y + new.r1.y, self.r1.z + new.r1.z),
            Vector3::new(self.r2.x + new.r2.x, self.r2.y + new.r2.y, self.r2.z + new.r2.z),
            Vector3::new(self.r3.x + new.r3.x, self.r3.y + new.r3.y, self.r3.z + new.r3.z)
        )
    }
}

impl ops::Mul<Vector3> for Matrix3x3 {
    type Output = Vector3;

    ///Implements the transform matrix of a vector 3 into another vector 3.
    fn mul(self, vec: Vector3) -> Vector3 {
        Vector3 {x: self.r1 * vec.clone(),
            y: self.r2 * vec.clone(),
            z: self.r3 * vec.clone()}
    }
}

impl ops::Mul<f32> for Matrix3x3 {
    type Output = Matrix3x3;

    ///Implements the Matrix 3x3 '*' trait for `Matrix3x3 * f32` so that `(identity * value).det() == valueˆ3`.
    fn mul(self, value: f32) -> Matrix3x3 {
        Matrix3x3::new(
            Vector3::new(self.r1.x * value, self.r1.y * value, self.r1.z * value),
            Vector3::new(self.r2.x * value, self.r2.y * value, self.r2.z * value),
            Vector3::new(self.r3.x * value, self.r3.y * value, self.r3.z * value)
        )
    }
}

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

    #[test]
    fn matrix_created_new_from_3_vector3() {
        let actual = Matrix3x3::new(Vector3::new(1f32, 2f32, 3f32),
                                        Vector3::new(1f32, 2f32, 3f32),
                                        Vector3::new(1f32, 2f32, 3f32));
        let expected = Matrix3x3 {r1: Vector3::new(1f32, 2f32, 3f32),
                                        r2: Vector3::new(1f32, 2f32, 3f32),
                                        r3: Vector3::new(1f32, 2f32, 3f32)};
        assert_eq!(expected, actual);
    }

    #[test]
    fn matrix_created_new_from_9_floats() {
        let actual = Matrix3x3::new_idx(1f32, 1f32, 1f32, 1f32, 1f32, 1f32,
                                    1f32, 1f32, 1f32);
        let expected = Matrix3x3 {r1: Vector3::new(1f32, 1f32, 1f32),
                                            r2: Vector3::new(1f32, 1f32, 1f32),
                                            r3: Vector3::new(1f32, 1f32, 1f32)};
        assert_eq!(expected, actual);
    }

    #[test]
    fn vector_transform_by_matrix() {
        let vec = Vector3::new(1f32, 2f32, 3f32);
        let matrix = Matrix3x3::new_idx(1f32, 2f32, 3f32,
                                        4f32, 5f32, 6f32, 7f32, 8f32, 9f32);
        let actual = matrix * vec;
        let expected = Vector3::new(14f32, 32f32, 50f32);
        assert_eq!(expected, actual);
    }

    #[test]
    fn seq_maxtrix_det() {
        let matrix = Matrix3x3::new_idx(1f32, 2f32, 3f32,
                                        4f32, 5f32, 6f32, 7f32, 8f32, 5f32);
        let actual = matrix.det();
        let expected = 12f32;
        assert_eq!(expected, actual);
    }

    #[test]
    fn identity_matrix_has_det_1() {
        let identity = Matrix3x3::IDENTITY();
        assert_eq!(1f32, identity.det());
    }

    #[test]
    fn identity_plus_identity_has_det_8() {
        let identities = Matrix3x3::IDENTITY() + Matrix3x3::IDENTITY();
        assert_eq!(8f32, identities.det());
    }

    #[test]
    fn det_of_identity_times_3_is_27() {
        let identity_3 = Matrix3x3::IDENTITY() * 3f32;
        assert_eq!(27f32, identity_3.det());
    }
}<commit_msg>aM == Ma<commit_after>use super::vector3::Vector3;
use std::ops;

///Implements a matrix 3 x 3
#[derive(Clone, PartialEq, Debug)]
pub struct Matrix3x3 {
    pub r1: Vector3,
    pub r2: Vector3,
    pub r3: Vector3,
}

impl Matrix3x3 {

    ///Creates a new Matrix3x3 from 3 vector3 rows
    pub fn new(r1: Vector3, r2: Vector3, r3: Vector3) -> Matrix3x3 {
        Matrix3x3 {r1: r1, r2: r2, r3: r3}
    }

    ///Creates a new Matrix3x3 from 9 indexed floats
    pub fn new_idx(n1: f32, n2: f32, n3: f32, n4: f32, n5: f32, n6: f32, n7: f32, n8: f32, n9: f32)
                                                                                -> Matrix3x3 {

        Matrix3x3 {r1: Vector3::new(n1, n2, n3),
                   r2: Vector3::new(n4, n5, n6),
                   r3: Vector3::new(n7, n8, n9)}
    }

    #[allow(dead_code, non_snake_case)]
    pub fn IDENTITY() -> Matrix3x3 {
        Matrix3x3::new_idx(1f32, 0f32, 0f32, 0f32, 1f32, 0f32,
                           0f32, 0f32, 1f32)
    }

    ///Matrix 3x3 determinant
    pub fn det(self) -> f32 {
        (self.r1.x * self.r2.y * self.r3.z +
            self.r1.y * self.r2.z * self.r3.x +
            self.r1.z * self.r2.x * self.r3.y)
        - (self.r1.z * self.r2.y * self.r3.x +
            self.r1.y * self.r2.x * self.r3.z +
            self.r1.x * self.r2.z * self.r3.y)
    }
}

impl ops::Add for Matrix3x3 {
    type Output = Matrix3x3;

    ///Implements the Matrix 3x3 '+' trait
    fn add(self, new: Matrix3x3) -> Matrix3x3 {
        Matrix3x3::new(
            Vector3::new(self.r1.x + new.r1.x, self.r1.y + new.r1.y, self.r1.z + new.r1.z),
            Vector3::new(self.r2.x + new.r2.x, self.r2.y + new.r2.y, self.r2.z + new.r2.z),
            Vector3::new(self.r3.x + new.r3.x, self.r3.y + new.r3.y, self.r3.z + new.r3.z)
        )
    }
}

impl ops::Mul<Vector3> for Matrix3x3 {
    type Output = Vector3;

    ///Implements the transform matrix of a vector 3 into another vector 3.
    fn mul(self, vec: Vector3) -> Vector3 {
        Vector3 {x: self.r1 * vec.clone(),
            y: self.r2 * vec.clone(),
            z: self.r3 * vec.clone()}
    }
}

impl ops::Mul<f32> for Matrix3x3 {
    type Output = Matrix3x3;

    ///Implements the Matrix 3x3 '*' trait for `Matrix3x3 * f32` so that `(identity * value).det() == valueˆ3`.
    fn mul(self, value: f32) -> Matrix3x3 {
        Matrix3x3::new(
            Vector3::new(self.r1.x * value, self.r1.y * value, self.r1.z * value),
            Vector3::new(self.r2.x * value, self.r2.y * value, self.r2.z * value),
            Vector3::new(self.r3.x * value, self.r3.y * value, self.r3.z * value)
        )
    }
}

impl ops::Mul<Matrix3x3> for f32 {
    type Output = Matrix3x3;

    ///Implements the Matrix 3x3 '*' trait for `Matrix3x3 * f32` so that `(value * identity).det() == valueˆ3` and `ßM == Mß`˜.
    fn mul(self, m: Matrix3x3) -> Matrix3x3 {
        Matrix3x3::new(
            Vector3::new(m.r1.x * self, m.r1.y * self, m.r1.z * self),
            Vector3::new(m.r2.x * self, m.r2.y * self, m.r2.z * self),
            Vector3::new(m.r3.x * self, m.r3.y * self, m.r3.z * self)
        )
    }
}

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

    #[test]
    fn matrix_created_new_from_3_vector3() {
        let actual = Matrix3x3::new(Vector3::new(1f32, 2f32, 3f32),
                                        Vector3::new(1f32, 2f32, 3f32),
                                        Vector3::new(1f32, 2f32, 3f32));
        let expected = Matrix3x3 {r1: Vector3::new(1f32, 2f32, 3f32),
                                        r2: Vector3::new(1f32, 2f32, 3f32),
                                        r3: Vector3::new(1f32, 2f32, 3f32)};
        assert_eq!(expected, actual);
    }

    #[test]
    fn matrix_created_new_from_9_floats() {
        let actual = Matrix3x3::new_idx(1f32, 1f32, 1f32, 1f32, 1f32, 1f32,
                                    1f32, 1f32, 1f32);
        let expected = Matrix3x3 {r1: Vector3::new(1f32, 1f32, 1f32),
                                            r2: Vector3::new(1f32, 1f32, 1f32),
                                            r3: Vector3::new(1f32, 1f32, 1f32)};
        assert_eq!(expected, actual);
    }

    #[test]
    fn vector_transform_by_matrix() {
        let vec = Vector3::new(1f32, 2f32, 3f32);
        let matrix = Matrix3x3::new_idx(1f32, 2f32, 3f32,
                                        4f32, 5f32, 6f32, 7f32, 8f32, 9f32);
        let actual = matrix * vec;
        let expected = Vector3::new(14f32, 32f32, 50f32);
        assert_eq!(expected, actual);
    }

    #[test]
    fn seq_maxtrix_det() {
        let matrix = Matrix3x3::new_idx(1f32, 2f32, 3f32,
                                        4f32, 5f32, 6f32, 7f32, 8f32, 5f32);
        let actual = matrix.det();
        let expected = 12f32;
        assert_eq!(expected, actual);
    }

    #[test]
    fn identity_matrix_has_det_1() {
        let identity = Matrix3x3::IDENTITY();
        assert_eq!(1f32, identity.det());
    }

    #[test]
    fn identity_plus_identity_has_det_8() {
        let identities = Matrix3x3::IDENTITY() + Matrix3x3::IDENTITY();
        assert_eq!(8f32, identities.det());
    }

    #[test]
    fn det_of_identity_times_3_is_27() {
        let identity_3 = Matrix3x3::IDENTITY() * 3f32;
        assert_eq!(27f32, identity_3.det());
    }

    #[test]
    fn det_of_4_times_identity_is_64() {
        let identity_4 = 4f32 *  Matrix3x3::IDENTITY();
        assert_eq!(64f32, identity_4.det());
    }
}<|endoftext|>