<commit_before>//! A text character

use internal;
use ImageSize;

/// Holds rendered character data.
pub struct Character<T: ImageSize> {
    /// The offset of character.
    pub offset: [f64, ..2],
    /// The size of character, including space.
    pub size: [f64, ..2],
    /// The texture of the character.
    pub texture: T,
}

impl<T: ImageSize> Character<T> {
    /// The left offset.
    pub fn left(&self) -> f64 {
        self.offset[0]
    }

    /// The top offset.
    pub fn top(&self) -> f64 {
        self.offset[1]
    }

    /// Gets width of character, including space to the next one.
    pub fn width(&self) -> f64 {
        self.size[0]
    }

    /// Sets height of character, including space to the next one.
    pub fn height(&self) -> f64 {
        self.size[1]
    }
}

/// Stores characters in a buffer and loads them by demand.
pub trait CharacterCache<T: ImageSize> {
    /// Get reference to character.
    fn character(
        &mut self,
        font_size: internal::FontSize,
        char: Char
    ) -> &Character<T>;
}

<commit_msg>Fixed `char` argument type<commit_after>//! A text character

use internal;
use ImageSize;

/// Holds rendered character data.
pub struct Character<T: ImageSize> {
    /// The offset of character.
    pub offset: [f64, ..2],
    /// The size of character, including space.
    pub size: [f64, ..2],
    /// The texture of the character.
    pub texture: T,
}

impl<T: ImageSize> Character<T> {
    /// The left offset.
    pub fn left(&self) -> f64 {
        self.offset[0]
    }

    /// The top offset.
    pub fn top(&self) -> f64 {
        self.offset[1]
    }

    /// Gets width of character, including space to the next one.
    pub fn width(&self) -> f64 {
        self.size[0]
    }

    /// Sets height of character, including space to the next one.
    pub fn height(&self) -> f64 {
        self.size[1]
    }
}

/// Stores characters in a buffer and loads them by demand.
pub trait CharacterCache<T: ImageSize> {
    /// Get reference to character.
    fn character(
        &mut self,
        font_size: internal::FontSize,
        ch: char
    ) -> &Character<T>;
}

<|endoftext|>


<commit_before>extern crate notify;
extern crate glob;

use std::process::Command as ShellCommand;
use std::sync::mpsc::channel;
use std::error::Error;

use self::notify::{RecommendedWatcher, Watcher};

use cli::Command;
use rules;

pub const FILENAME: &'static str = ".watch.yaml";

/// # `WatchCommand`
///
/// Starts watcher to listen the change events configured
/// in watch.yaml
///
pub struct WatchCommand {
    watches: Watches,
    verbose: bool,
}

impl WatchCommand {
    pub fn new(watches: Watches, verbose: bool) -> Self {
        WatchCommand { watches: watches , verbose: verbose }
    }
}

impl Command for WatchCommand {
    fn execute(&self) -> Result<(), String> {

        let (tx, rx) = channel();
        let mut watcher: RecommendedWatcher = match Watcher::new(tx) {
            Ok(w) => w,
            Err(err) => panic!("Error while trying watch. Cause: {:?}", err),
        };

        if let Err(err) = watcher.watch(".") {
            panic!("Unable to watch current directory. Cause: {:?}", err)
        }

        println!("Watching.");
        while let Ok(event) = rx.recv() {
            let path: &str = if let Some(ref path_buf) = event.path {
                path_buf.to_str().expect("Error while cast path buffer.")
            } else {
                ""
            };

            if let Some(shell_commands) = self.watches.watch(path) {

                if self.verbose { println!("path: {}", path) };

                clear_shell();
                for mut cmd in shell_commands {
                    if self.verbose { println!("command: {:?}", cmd) };
                    if let Err(error) = cmd.status() {
                        return Err(String::from(error.description()));
                    }
                }
            }
        }
        Ok(())
    }
}

/// # Watches
///
/// Represents all rules in the yaml config loaded.
///
#[derive(Debug)]
pub struct Watches {
    rules: Vec<rules::Rules>,
}
impl Watches {
    pub fn from_args(command: String) -> Self {
        let template = format!("
        - name: from command
          run: {command}
          change: '{path}'
        ",
         path = "**",
         command = command);

        Watches::load_from_str(&template)
    }

    pub fn from(plain_text: &str) -> Self {
        Watches::load_from_str(plain_text)
    }

    pub fn new(rules: Vec<rules::Rules>) -> Self {
        Watches { rules: rules }
    }

    fn load_from_str(plain_text: &str) -> Self {
        Watches { rules: rules::from_yaml(plain_text) }
    }

    /// Returns the first rule found for the given path
    ///
    pub fn watch(&self, path: &str) -> Option<Vec<ShellCommand>> {
        println!("rules {:?} path {:?}", self.rules, path);
        for rule in self.rules.iter()
            .filter(|r| !r.ignore(path) && r.watch(path)) {
            return Some(rule.to_command());
        };
        None
    }
}

fn clear_shell() {
    let _ = ShellCommand::new("clear").status();
}

#[cfg(test)]
mod tests {
    extern crate notify;
    extern crate yaml_rust;
    extern crate glob;

    use super::*;
    use std::process::Command as ShellCommand;

    #[test]
    fn it_loads_from_args() {
        let args = String::from("cargo build");
        let watches = Watches::from_args(args);

        assert!(watches.watch("src/main.rs").is_some());
        assert!(watches.watch("test/main.rs").is_some());
        assert!(watches.watch(".").is_some());

        let result = watches.watch(".").unwrap();
        let mut expected = ShellCommand::new("cargo");
        expected.arg("build");
        assert_eq!(format!("{:?}", vec![expected]), format!("{:?}", result));
    }

    #[test]
    fn it_watches_test_path() {
        let file_content = "
        - name: my tests
          run: 'cargo tests'
          change: 'tests/**'
        ";
        let watches = Watches::from(file_content);
        assert!(watches.watch("/Users/crosa/others/funzzy/tests/test.rs").is_some());
        assert!(watches.watch("tests/tests.rs").is_some());
        assert!(watches.watch("tests/ruby.rb").is_some());
        assert!(watches.watch("tests/folder/other.rs").is_some())
    }

    #[test]
    fn it_watches_specific_path() {
        let file_content = "
        - name: my tests
          run: 'cargo tests'
          change: './tests/foo/bar.rs'
        ";
        let watches = Watches::from(file_content);
        assert!(watches.watch("./tests/foo/bar.rs").is_some())
    }

    #[test]
    fn it_doesnot_watch_test_path() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'
        ";
        let watches = Watches::from(file_content);

        assert!(watches.watch("/Users/crosa/others/funzzy/events.yaml").is_none());
        assert!(watches.watch("tests/").is_none());
        assert!(watches.watch("tests/test.rs").is_none());
        assert!(watches.watch("tests/folder/other.rs").is_none());
    }

    #[test]
    fn it_creates_a_list_of_shell_commands() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'
        ";
        let watches = Watches::from(file_content);
        let result = watches.watch("src/test.rs").unwrap();
        let mut expected = ShellCommand::new("cargo");
        expected.arg("build");
        assert_eq!(format!("{:?}", vec![expected]), format!("{:?}", result))
    }

    #[test]
    fn it_works_with_more_than_one_command() {
        let file_content = "
        - name: my source
          run: ['cargo build', 'cargo test']
          change: 'src/**'
        ";
        let watches = Watches::from(file_content);
        let result = watches.watch("src/test.rs").unwrap();

        let mut expected: Vec<ShellCommand> = vec![];
        let mut cmd = ShellCommand::new("cargo");
        cmd.arg("build");
        expected.push(cmd);

        let mut cmd2 = ShellCommand::new("cargo");
        cmd2.arg("test");
        expected.push(cmd2);

        assert_eq!(format!("{:?}", expected), format!("{:?}", result))
    }

    #[test]
    fn it_works_with_multiples_items() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'

        - name: other
          run: 'cargo test'
          change: 'test/**'
        ";
        let watches = Watches::from(file_content);

        let result = watches.watch("test/test.rs").unwrap();
        let mut expected = ShellCommand::new("cargo");
        expected.arg("test");
        assert_eq!(format!("{:?}", expected), format!("{:?}", result[0]));

        let result_src = watches.watch("src/test.rs").unwrap();
        let mut expected_src = ShellCommand::new("cargo");
        expected_src.arg("build");
        assert_eq!(format!("{:?}", expected_src),
                   format!("{:?}", result_src[0]))
    }

    #[test]
    fn it_ignores_pattern() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'
          ignore: 'src/test/**'
        ";
        let watches = Watches::from(file_content);
        assert!(watches.watch("src/other.rb").is_some());
        assert!(watches.watch("src/test.txt").is_some());
        assert!(watches.watch("src/test/other.tmp").is_none())
    }

    #[test]
    fn it_ignores_a_list_of_patterns() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'
          ignore: ['src/test/**', 'src/tmp/**']
        ";
        let watches = Watches::from(file_content);
        assert!(watches.watch("src/other.rb").is_some());
        assert!(watches.watch("src/test.txt").is_some());
        assert!(watches.watch("src/tmp/test.txt").is_none());
        assert!(watches.watch("src/test/other.tmp").is_none())
    }
}
<commit_msg>fix: remove unecessary print<commit_after>extern crate notify;
extern crate glob;

use std::process::Command as ShellCommand;
use std::sync::mpsc::channel;
use std::error::Error;

use self::notify::{RecommendedWatcher, Watcher};

use cli::Command;
use rules;

pub const FILENAME: &'static str = ".watch.yaml";

/// # `WatchCommand`
///
/// Starts watcher to listen the change events configured
/// in watch.yaml
///
pub struct WatchCommand {
    watches: Watches,
    verbose: bool,
}

impl WatchCommand {
    pub fn new(watches: Watches, verbose: bool) -> Self {
        if verbose { println!("watches {:?}", watches); }
        WatchCommand { watches: watches , verbose: verbose }
    }
}

impl Command for WatchCommand {
    fn execute(&self) -> Result<(), String> {

        let (tx, rx) = channel();
        let mut watcher: RecommendedWatcher = match Watcher::new(tx) {
            Ok(w) => w,
            Err(err) => panic!("Error while trying watch. Cause: {:?}", err),
        };

        if let Err(err) = watcher.watch(".") {
            panic!("Unable to watch current directory. Cause: {:?}", err)
        }

        println!("Watching.");
        while let Ok(event) = rx.recv() {
            let path: &str = if let Some(ref path_buf) = event.path {
                path_buf.to_str().expect("Error while cast path buffer.")
            } else {
                ""
            };

            if let Some(shell_commands) = self.watches.watch(path) {

                if self.verbose { println!("path: {}", path) };

                clear_shell();
                for mut cmd in shell_commands {
                    if self.verbose { println!("command: {:?}", cmd) };
                    if let Err(error) = cmd.status() {
                        return Err(String::from(error.description()));
                    }
                }
            }
        }
        Ok(())
    }
}

/// # Watches
///
/// Represents all rules in the yaml config loaded.
///
#[derive(Debug)]
pub struct Watches {
    rules: Vec<rules::Rules>,
}
impl Watches {
    pub fn from_args(command: String) -> Self {
        let template = format!("
        - name: from command
          run: {command}
          change: '{path}'
        ",
         path = "**",
         command = command);

        Watches::load_from_str(&template)
    }

    pub fn from(plain_text: &str) -> Self {
        Watches::load_from_str(plain_text)
    }

    pub fn new(rules: Vec<rules::Rules>) -> Self {
        Watches { rules: rules }
    }

    fn load_from_str(plain_text: &str) -> Self {
        Watches { rules: rules::from_yaml(plain_text) }
    }

    /// Returns the first rule found for the given path
    ///
    pub fn watch(&self, path: &str) -> Option<Vec<ShellCommand>> {
        for rule in self.rules.iter()
            .filter(|r| !r.ignore(path) && r.watch(path)) {
            return Some(rule.to_command());
        };
        None
    }
}

fn clear_shell() {
    let _ = ShellCommand::new("clear").status();
}

#[cfg(test)]
mod tests {
    extern crate notify;
    extern crate yaml_rust;
    extern crate glob;

    use super::*;
    use std::process::Command as ShellCommand;

    #[test]
    fn it_loads_from_args() {
        let args = String::from("cargo build");
        let watches = Watches::from_args(args);

        assert!(watches.watch("src/main.rs").is_some());
        assert!(watches.watch("test/main.rs").is_some());
        assert!(watches.watch(".").is_some());

        let result = watches.watch(".").unwrap();
        let mut expected = ShellCommand::new("cargo");
        expected.arg("build");
        assert_eq!(format!("{:?}", vec![expected]), format!("{:?}", result));
    }

    #[test]
    fn it_watches_test_path() {
        let file_content = "
        - name: my tests
          run: 'cargo tests'
          change: 'tests/**'
        ";
        let watches = Watches::from(file_content);
        assert!(watches.watch("/Users/crosa/others/funzzy/tests/test.rs").is_some());
        assert!(watches.watch("tests/tests.rs").is_some());
        assert!(watches.watch("tests/ruby.rb").is_some());
        assert!(watches.watch("tests/folder/other.rs").is_some())
    }

    #[test]
    fn it_watches_specific_path() {
        let file_content = "
        - name: my tests
          run: 'cargo tests'
          change: './tests/foo/bar.rs'
        ";
        let watches = Watches::from(file_content);
        assert!(watches.watch("./tests/foo/bar.rs").is_some())
    }

    #[test]
    fn it_doesnot_watch_test_path() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'
        ";
        let watches = Watches::from(file_content);

        assert!(watches.watch("/Users/crosa/others/funzzy/events.yaml").is_none());
        assert!(watches.watch("tests/").is_none());
        assert!(watches.watch("tests/test.rs").is_none());
        assert!(watches.watch("tests/folder/other.rs").is_none());
    }

    #[test]
    fn it_creates_a_list_of_shell_commands() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'
        ";
        let watches = Watches::from(file_content);
        let result = watches.watch("src/test.rs").unwrap();
        let mut expected = ShellCommand::new("cargo");
        expected.arg("build");
        assert_eq!(format!("{:?}", vec![expected]), format!("{:?}", result))
    }

    #[test]
    fn it_works_with_more_than_one_command() {
        let file_content = "
        - name: my source
          run: ['cargo build', 'cargo test']
          change: 'src/**'
        ";
        let watches = Watches::from(file_content);
        let result = watches.watch("src/test.rs").unwrap();

        let mut expected: Vec<ShellCommand> = vec![];
        let mut cmd = ShellCommand::new("cargo");
        cmd.arg("build");
        expected.push(cmd);

        let mut cmd2 = ShellCommand::new("cargo");
        cmd2.arg("test");
        expected.push(cmd2);

        assert_eq!(format!("{:?}", expected), format!("{:?}", result))
    }

    #[test]
    fn it_works_with_multiples_items() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'

        - name: other
          run: 'cargo test'
          change: 'test/**'
        ";
        let watches = Watches::from(file_content);

        let result = watches.watch("test/test.rs").unwrap();
        let mut expected = ShellCommand::new("cargo");
        expected.arg("test");
        assert_eq!(format!("{:?}", expected), format!("{:?}", result[0]));

        let result_src = watches.watch("src/test.rs").unwrap();
        let mut expected_src = ShellCommand::new("cargo");
        expected_src.arg("build");
        assert_eq!(format!("{:?}", expected_src),
                   format!("{:?}", result_src[0]))
    }

    #[test]
    fn it_ignores_pattern() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'
          ignore: 'src/test/**'
        ";
        let watches = Watches::from(file_content);
        assert!(watches.watch("src/other.rb").is_some());
        assert!(watches.watch("src/test.txt").is_some());
        assert!(watches.watch("src/test/other.tmp").is_none())
    }

    #[test]
    fn it_ignores_a_list_of_patterns() {
        let file_content = "
        - name: my source
          run: 'cargo build'
          change: 'src/**'
          ignore: ['src/test/**', 'src/tmp/**']
        ";
        let watches = Watches::from(file_content);
        assert!(watches.watch("src/other.rb").is_some());
        assert!(watches.watch("src/test.txt").is_some());
        assert!(watches.watch("src/tmp/test.txt").is_none());
        assert!(watches.watch("src/test/other.tmp").is_none())
    }
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Started shell for balanced brackets<commit_after>fn generate_expression(size: &i32) -> Vec<char> {
    vec!['[', '[', ']', ']']
}

fn well_formed(expr: &Vec<char>) -> bool {
    true
}

fn main() {
    for n in (1..10) {
        let expr = generate_expression(&n);
        let wf = well_formed(&expr);

        println!("{:?} is {}", expr, if wf {"well formed"} else {"NOT well formed"});
    }
}
<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::default::Default;
use std::collections::BTreeMap;

use quire::validate as V;
use libc::uid_t;

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct DebianRepo {
    pub url: String,
    pub suite: String,
    pub components: Vec<String>,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct AptKey {
    pub server: Option<String>,
    pub keys: Vec<String>,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct PacmanRepo {
    pub name: String,
    pub url: String,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct TarInfo {
    pub url: String,
    pub sha256: Option<String>,
    pub path: PathBuf,
    pub subdir: PathBuf,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct TarInstallInfo {
    pub url: String,
    pub sha256: Option<String>,
    pub subdir: Option<PathBuf>,
    pub script: String,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct GitInfo {
    pub url: String,
    pub revision: Option<String>,
    pub branch: Option<String>,
    pub path: PathBuf,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct GitInstallInfo {
    pub url: String,
    pub revision: Option<String>,
    pub branch: Option<String>,
    pub subdir: PathBuf,
    pub script: String,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct FileInfo {
    pub name: PathBuf,
    pub contents: String,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct UbuntuReleaseInfo {
    pub version: String,
    pub keep_chfn_command: bool,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct UbuntuRepoInfo {
    pub url: String,
    pub suite: String,
    pub components: Vec<String>,
}

#[derive(Clone, RustcDecodable, Debug, RustcEncodable)]
pub struct PipSettings {
    pub find_links: Vec<String>,
    pub index_urls: Vec<String>,
    pub trusted_hosts: Vec<String>,
    pub dependencies: bool,
    pub cache_wheels: bool,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct GitSource {
    pub url: String,
    pub revision: Option<String>,
    pub branch: Option<String>,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub enum Source {
    Git(GitSource),
    Container(String),
    Directory,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub struct SubConfigInfo {
    pub source: Source,
    pub path: PathBuf,
    pub container: String,
    pub cache: Option<bool>,
    pub change_dir: Option<bool>,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub struct PyFreezeInfo {
    pub freeze_file: PathBuf,
    pub requirements: Option<PathBuf>,
    pub packages: Vec<String>,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub struct DownloadInfo {
    pub url: String,
    pub path: PathBuf,
    pub mode: u32,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub struct CopyInfo {
    pub source: PathBuf,
    pub path: PathBuf,
    pub owner_uid: Option<uid_t>,
    pub ignore_regex: String,
}

#[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
pub enum Builder {
    // -- Generic --
    Sh(String),
    Cmd(Vec<String>),
    Env(BTreeMap<String, String>),
    Depends(PathBuf),
    Tar(TarInfo),
    TarInstall(TarInstallInfo),
    Git(GitInfo),
    GitInstall(GitInstallInfo),
    Download(DownloadInfo),
    Text(BTreeMap<PathBuf, String>),
    Copy(CopyInfo),
    Remove(PathBuf),
    EnsureDir(PathBuf),
    EmptyDir(PathBuf),
    CacheDirs(BTreeMap<PathBuf, String>),
    //Busybox,

    // -- Generic --
    Install(Vec<String>),
    BuildDeps(Vec<String>),
    Container(String),
    SubConfig(SubConfigInfo),

    // -- Ubuntu --
    Ubuntu(String),
    UbuntuRelease(UbuntuReleaseInfo),
    UbuntuRepo(UbuntuRepoInfo),
    UbuntuUniverse,
    UbuntuPPA(String),

    // -- Ubuntu/Debian --
    //AddDebianRepo(DebianRepo),
    AptTrust(AptKey),

    // -- Arch --
    //ArchBase,
    //PacmanInstall(Vec<String>),
    //PacmanRemove(Vec<String>),
    //PacmanBuild(Path),
    //AddPacmanRepo(PacmanRepo),

    // -- Alpine --
    Alpine(String),
    //AlpineRemove(Vec<String>),

    // -- Docker --
    //DockerImage(String),
    //DockerPrivate(String),
    //Dockerfile(Path),

    // -- Languages --
    NpmInstall(Vec<String>),
    //PipRequirement(Path),
    //GemInstall(Vec<String>),

    // -- Python --
    PipConfig(PipSettings),
    Py2Install(Vec<String>),
    Py2Requirements(PathBuf),
    Py3Install(Vec<String>),
    Py3Requirements(PathBuf),
    PyFreeze(PyFreezeInfo),
}

pub fn builder_validator<'x>() -> V::Enum<'x> {
    V::Enum::new()
    .option("Install", V::Sequence::new(V::Scalar::new()))
    .option("BuildDeps", V::Sequence::new(V::Scalar::new()))
    .option("Container", V::Scalar::new())
    .option("SubConfig", V::Structure::new()
        .member("source", V::Enum::new()
            .option("Directory", V::Nothing)
            .option("Container", V::Scalar::new())
            .option("Git", V::Structure::new()
                .member("url", V::Scalar::new())
                .member("revision", V::Scalar::new().optional())
                .member("branch", V::Scalar::new().optional()))
            .optional()
            .default_tag("Directory"))
        .member("path".to_string(), V::Directory::new()
            .is_absolute(false)
            .default("vagga.yaml"))
        .member("container", V::Scalar::new())
        .member("cache", V::Scalar::new().optional())
        .member("change_dir", V::Scalar::new().optional()))
    .option("Text", V::Mapping::new(
        V::Directory::new().is_absolute(true),
        V::Scalar::new()))
    .option("Copy", V::Structure::new()
        .member("source", V::Scalar::new())
        .member("path", V::Directory::new().is_absolute(true))
        .member("ignore_regex", V::Scalar::new()
            .default(r#"(^|/)\.(git|hg|svn)($|/)|~$|\.bak$|\.orig$|^#.*#$"#))
        .member("owner_uid", V::Numeric::new().min(0).optional()))

    .option("Ubuntu", V::Scalar::new())
    .option("UbuntuRelease", V::Structure::new()
        .member("version", V::Scalar::new())
        .member("keep_chfn_command", V::Scalar::new().default(false)))
    .option("UbuntuRepo", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("suite", V::Scalar::new())
        .member("components", V::Sequence::new(V::Scalar::new())))
    .option("UbuntuPPA", V::Scalar::new())
    .option("UbuntuUniverse", V::Nothing)
    .option("AptTrust", V::Structure::new()
        .member("server", V::Scalar::new().optional())
        .member("keys", V::Sequence::new(V::Scalar::new())))
    .option("Sh", V::Scalar::new())
    .option("Cmd", V::Sequence::new(V::Scalar::new()))
    .option("Remove", V::Directory::new().is_absolute(true))
    .option("EnsureDir", V::Directory::new().is_absolute(true))
    .option("EmptyDir", V::Directory::new().is_absolute(true))
    .option("CacheDirs", V::Mapping::new(
        V::Directory::new().is_absolute(true),
        V::Scalar::new()))
    .option("Env", V::Mapping::new(
        V::Scalar::new(),
        V::Scalar::new()))
    .option("Depends", V::Scalar::new())
    .option("Git", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("revision", V::Scalar::new().optional())
        .member("branch", V::Scalar::new().optional())
        .member("path", V::Directory::new().is_absolute(true)))
    .option("GitInstall", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("revision", V::Scalar::new().optional())
        .member("branch", V::Scalar::new().optional())
        .member("subdir", V::Directory::new()
            .default(".").is_absolute(false))
        .member("script", V::Scalar::new()
                .default("./configure --prefix=/usr\n\
                          make\n\
                          make install\n")))
    .option("Tar", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("sha256", V::Scalar::new().optional())
        .member("path", V::Directory::new().is_absolute(true).default("/"))
        .member("subdir", V::Directory::new().default("").is_absolute(false)))
    .option("TarInstall", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("sha256", V::Scalar::new().optional())
        .member("subdir", V::Directory::new().optional().is_absolute(false))
        .member("script", V::Scalar::new()
                .default("./configure --prefix=/usr\n\
                          make\n\
                          make install\n")))
    .option("Download", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("path", V::Directory::new().is_absolute(true))
        .member("mode", V::Numeric::new().default(0o644).min(0).max(0o1777)))
    .option("Alpine", V::Scalar::new())

    // Python
    .option("PipConfig", V::Structure::new()
        .member("dependencies", V::Scalar::new().default(false).optional())
        .member("cache_wheels", V::Scalar::new().default(true))
        .member("find_links", V::Sequence::new(V::Scalar::new()))
        .member("index_urls", V::Sequence::new(V::Scalar::new()))
        .member("trusted_hosts", V::Sequence::new(V::Scalar::new())))
    .option("Py2Install", V::Sequence::new(V::Scalar::new()))
    .option("Py2Requirements", V::Scalar::new()
        .default("requirements.txt"))
    .option("Py3Install", V::Sequence::new(V::Scalar::new()))
    .option("Py3Requirements",
        V::Scalar::new().default("requirements.txt"))
    .option("PyFreeze", V::Structure::new()
        .member("freeze-file", V::Scalar::new().default("requirements.txt"))
        .member("requirements", V::Scalar::new().optional())
        .member("packages", V::Sequence::new(V::Scalar::new())))

    // Node.js
    .option("NpmInstall", V::Sequence::new(V::Scalar::new()))
}
<commit_msg>Add `.vagga` directory to ignore list of `!Copy`<commit_after>use std::path::PathBuf;
use std::default::Default;
use std::collections::BTreeMap;

use quire::validate as V;
use libc::uid_t;

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct DebianRepo {
    pub url: String,
    pub suite: String,
    pub components: Vec<String>,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct AptKey {
    pub server: Option<String>,
    pub keys: Vec<String>,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct PacmanRepo {
    pub name: String,
    pub url: String,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct TarInfo {
    pub url: String,
    pub sha256: Option<String>,
    pub path: PathBuf,
    pub subdir: PathBuf,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct TarInstallInfo {
    pub url: String,
    pub sha256: Option<String>,
    pub subdir: Option<PathBuf>,
    pub script: String,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct GitInfo {
    pub url: String,
    pub revision: Option<String>,
    pub branch: Option<String>,
    pub path: PathBuf,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct GitInstallInfo {
    pub url: String,
    pub revision: Option<String>,
    pub branch: Option<String>,
    pub subdir: PathBuf,
    pub script: String,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct FileInfo {
    pub name: PathBuf,
    pub contents: String,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct UbuntuReleaseInfo {
    pub version: String,
    pub keep_chfn_command: bool,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct UbuntuRepoInfo {
    pub url: String,
    pub suite: String,
    pub components: Vec<String>,
}

#[derive(Clone, RustcDecodable, Debug, RustcEncodable)]
pub struct PipSettings {
    pub find_links: Vec<String>,
    pub index_urls: Vec<String>,
    pub trusted_hosts: Vec<String>,
    pub dependencies: bool,
    pub cache_wheels: bool,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
pub struct GitSource {
    pub url: String,
    pub revision: Option<String>,
    pub branch: Option<String>,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub enum Source {
    Git(GitSource),
    Container(String),
    Directory,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub struct SubConfigInfo {
    pub source: Source,
    pub path: PathBuf,
    pub container: String,
    pub cache: Option<bool>,
    pub change_dir: Option<bool>,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub struct PyFreezeInfo {
    pub freeze_file: PathBuf,
    pub requirements: Option<PathBuf>,
    pub packages: Vec<String>,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub struct DownloadInfo {
    pub url: String,
    pub path: PathBuf,
    pub mode: u32,
}

#[derive(Clone, RustcDecodable, RustcEncodable, Debug)]
pub struct CopyInfo {
    pub source: PathBuf,
    pub path: PathBuf,
    pub owner_uid: Option<uid_t>,
    pub ignore_regex: String,
}

#[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
pub enum Builder {
    // -- Generic --
    Sh(String),
    Cmd(Vec<String>),
    Env(BTreeMap<String, String>),
    Depends(PathBuf),
    Tar(TarInfo),
    TarInstall(TarInstallInfo),
    Git(GitInfo),
    GitInstall(GitInstallInfo),
    Download(DownloadInfo),
    Text(BTreeMap<PathBuf, String>),
    Copy(CopyInfo),
    Remove(PathBuf),
    EnsureDir(PathBuf),
    EmptyDir(PathBuf),
    CacheDirs(BTreeMap<PathBuf, String>),
    //Busybox,

    // -- Generic --
    Install(Vec<String>),
    BuildDeps(Vec<String>),
    Container(String),
    SubConfig(SubConfigInfo),

    // -- Ubuntu --
    Ubuntu(String),
    UbuntuRelease(UbuntuReleaseInfo),
    UbuntuRepo(UbuntuRepoInfo),
    UbuntuUniverse,
    UbuntuPPA(String),

    // -- Ubuntu/Debian --
    //AddDebianRepo(DebianRepo),
    AptTrust(AptKey),

    // -- Arch --
    //ArchBase,
    //PacmanInstall(Vec<String>),
    //PacmanRemove(Vec<String>),
    //PacmanBuild(Path),
    //AddPacmanRepo(PacmanRepo),

    // -- Alpine --
    Alpine(String),
    //AlpineRemove(Vec<String>),

    // -- Docker --
    //DockerImage(String),
    //DockerPrivate(String),
    //Dockerfile(Path),

    // -- Languages --
    NpmInstall(Vec<String>),
    //PipRequirement(Path),
    //GemInstall(Vec<String>),

    // -- Python --
    PipConfig(PipSettings),
    Py2Install(Vec<String>),
    Py2Requirements(PathBuf),
    Py3Install(Vec<String>),
    Py3Requirements(PathBuf),
    PyFreeze(PyFreezeInfo),
}

pub fn builder_validator<'x>() -> V::Enum<'x> {
    V::Enum::new()
    .option("Install", V::Sequence::new(V::Scalar::new()))
    .option("BuildDeps", V::Sequence::new(V::Scalar::new()))
    .option("Container", V::Scalar::new())
    .option("SubConfig", V::Structure::new()
        .member("source", V::Enum::new()
            .option("Directory", V::Nothing)
            .option("Container", V::Scalar::new())
            .option("Git", V::Structure::new()
                .member("url", V::Scalar::new())
                .member("revision", V::Scalar::new().optional())
                .member("branch", V::Scalar::new().optional()))
            .optional()
            .default_tag("Directory"))
        .member("path".to_string(), V::Directory::new()
            .is_absolute(false)
            .default("vagga.yaml"))
        .member("container", V::Scalar::new())
        .member("cache", V::Scalar::new().optional())
        .member("change_dir", V::Scalar::new().optional()))
    .option("Text", V::Mapping::new(
        V::Directory::new().is_absolute(true),
        V::Scalar::new()))
    .option("Copy", V::Structure::new()
        .member("source", V::Scalar::new())
        .member("path", V::Directory::new().is_absolute(true))
        .member("ignore_regex", V::Scalar::new()
            .default(r#"(^|/)\.(git|hg|svn|vagga)($|/)\
                |~$|\.bak$|\.orig$|^#.*#$"#))
        .member("owner_uid", V::Numeric::new().min(0).optional()))

    .option("Ubuntu", V::Scalar::new())
    .option("UbuntuRelease", V::Structure::new()
        .member("version", V::Scalar::new())
        .member("keep_chfn_command", V::Scalar::new().default(false)))
    .option("UbuntuRepo", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("suite", V::Scalar::new())
        .member("components", V::Sequence::new(V::Scalar::new())))
    .option("UbuntuPPA", V::Scalar::new())
    .option("UbuntuUniverse", V::Nothing)
    .option("AptTrust", V::Structure::new()
        .member("server", V::Scalar::new().optional())
        .member("keys", V::Sequence::new(V::Scalar::new())))
    .option("Sh", V::Scalar::new())
    .option("Cmd", V::Sequence::new(V::Scalar::new()))
    .option("Remove", V::Directory::new().is_absolute(true))
    .option("EnsureDir", V::Directory::new().is_absolute(true))
    .option("EmptyDir", V::Directory::new().is_absolute(true))
    .option("CacheDirs", V::Mapping::new(
        V::Directory::new().is_absolute(true),
        V::Scalar::new()))
    .option("Env", V::Mapping::new(
        V::Scalar::new(),
        V::Scalar::new()))
    .option("Depends", V::Scalar::new())
    .option("Git", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("revision", V::Scalar::new().optional())
        .member("branch", V::Scalar::new().optional())
        .member("path", V::Directory::new().is_absolute(true)))
    .option("GitInstall", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("revision", V::Scalar::new().optional())
        .member("branch", V::Scalar::new().optional())
        .member("subdir", V::Directory::new()
            .default(".").is_absolute(false))
        .member("script", V::Scalar::new()
                .default("./configure --prefix=/usr\n\
                          make\n\
                          make install\n")))
    .option("Tar", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("sha256", V::Scalar::new().optional())
        .member("path", V::Directory::new().is_absolute(true).default("/"))
        .member("subdir", V::Directory::new().default("").is_absolute(false)))
    .option("TarInstall", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("sha256", V::Scalar::new().optional())
        .member("subdir", V::Directory::new().optional().is_absolute(false))
        .member("script", V::Scalar::new()
                .default("./configure --prefix=/usr\n\
                          make\n\
                          make install\n")))
    .option("Download", V::Structure::new()
        .member("url", V::Scalar::new())
        .member("path", V::Directory::new().is_absolute(true))
        .member("mode", V::Numeric::new().default(0o644).min(0).max(0o1777)))
    .option("Alpine", V::Scalar::new())

    // Python
    .option("PipConfig", V::Structure::new()
        .member("dependencies", V::Scalar::new().default(false).optional())
        .member("cache_wheels", V::Scalar::new().default(true))
        .member("find_links", V::Sequence::new(V::Scalar::new()))
        .member("index_urls", V::Sequence::new(V::Scalar::new()))
        .member("trusted_hosts", V::Sequence::new(V::Scalar::new())))
    .option("Py2Install", V::Sequence::new(V::Scalar::new()))
    .option("Py2Requirements", V::Scalar::new()
        .default("requirements.txt"))
    .option("Py3Install", V::Sequence::new(V::Scalar::new()))
    .option("Py3Requirements",
        V::Scalar::new().default("requirements.txt"))
    .option("PyFreeze", V::Structure::new()
        .member("freeze-file", V::Scalar::new().default("requirements.txt"))
        .member("requirements", V::Scalar::new().optional())
        .member("packages", V::Sequence::new(V::Scalar::new())))

    // Node.js
    .option("NpmInstall", V::Sequence::new(V::Scalar::new()))
}
<|endoftext|>


<commit_before>#![crate_name = "dirname"]
#![feature(collections, core, old_io, old_path, rustc_private)]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Derek Chiang <derekchiang93@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;

use std::old_io::print;

static VERSION: &'static str = "1.0.0";

pub fn uumain(args: Vec<String>) -> i32 {
    let program = args[0].clone();
    let opts = [
        getopts::optflag("z", "zero", "separate output with NUL rather than newline"),
        getopts::optflag("", "help", "display this help and exit"),
        getopts::optflag("", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), &opts) {
        Ok(m) => m,
        Err(f) => panic!("Invalid options\n{}", f)
    };

    if matches.opt_present("help") {
        println!("dirname {} - strip last component from file name", VERSION);
        println!("");
        println!("Usage:");
        println!("  {0} [OPTION] NAME...", program);
        println!("");
        print(getopts::usage("Output each NAME with its last non-slash component and trailing slashes
removed; if NAME contains no  /'s,  output  '.'  (meaning  the  current
directory).", &opts).as_slice());
        return 0;
    }

    if matches.opt_present("version") {
        println!("dirname version: {}", VERSION);
        return 0;
    }

    let separator = match matches.opt_present("zero") {
        true => "\0",
        false => "\n"
    };

    if !matches.free.is_empty() {
        for path in matches.free.iter() {
            let p = std::old_path::Path::new(path.clone());
            let d = std::str::from_utf8(p.dirname());
            if d.is_ok() {
                print(d.unwrap());
            }
            print(separator);
        }
    } else {
        println!("{0}: missing operand", program);
        println!("Try '{0} --help' for more information.", program);
        return 1;
    }

    0
}
<commit_msg>Fix dirname.<commit_after>#![crate_name = "dirname"]
#![feature(rustc_private)]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Derek Chiang <derekchiang93@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;

use std::path::Path;

static VERSION: &'static str = "1.0.0";

pub fn uumain(args: Vec<String>) -> i32 {
    let program = args[0].clone();
    let opts = [
        getopts::optflag("z", "zero", "separate output with NUL rather than newline"),
        getopts::optflag("", "help", "display this help and exit"),
        getopts::optflag("", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(&args[1..], &opts) {
        Ok(m) => m,
        Err(f) => panic!("Invalid options\n{}", f)
    };

    if matches.opt_present("help") {
        println!("dirname {} - strip last component from file name", VERSION);
        println!("");
        println!("Usage:");
        println!("  {0} [OPTION] NAME...", program);
        println!("");
        print!("{}", getopts::usage("Output each NAME with its last non-slash component and trailing slashes
removed; if NAME contains no  /'s,  output  '.'  (meaning  the  current
directory).", &opts));
        return 0;
    }

    if matches.opt_present("version") {
        println!("dirname version: {}", VERSION);
        return 0;
    }

    let separator = match matches.opt_present("zero") {
        true => "\0",
        false => "\n"
    };

    if !matches.free.is_empty() {
        for path in matches.free.iter() {
            let p = Path::new(path);
            let d = p.parent().unwrap().to_str();
            if d.is_some() {
                print!("{}", d.unwrap());
            }
            print!("{}", separator);
        }
    } else {
        println!("{0}: missing operand", program);
        println!("Try '{0} --help' for more information.", program);
        return 1;
    }

    0
}
<|endoftext|>


<commit_before>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An example of using perlin noise

extern mod noise;

use noise::Source;
use noise::sources::Perlin;

use std::io::{print,println};

static WIDTH: uint = 100;
static HEIGHT: uint = 100;

static GRADIENT: [&'static str, ..6] = [" ", "░", "▒", "▓", "█", "█"];

fn main() {
    let mut perlin = Perlin::new();
    perlin.frequency = 0.1;

    for y in range(0, HEIGHT / 2) {
        for x in range(0, WIDTH) {
            let val = perlin.get(
                x as f64,
                y as f64 * 2.0,
                0.0
            );

            let val = val * 0.5 + 0.5;

            print(GRADIENT[(val / 0.2) as int]);
        }
        println("");
    }
}
<commit_msg>replace "extern mod" with "extern crate"<commit_after>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An example of using perlin noise

extern crate noise;

use noise::Source;
use noise::sources::Perlin;

use std::io::{print,println};

static WIDTH: uint = 100;
static HEIGHT: uint = 100;

static GRADIENT: [&'static str, ..6] = [" ", "░", "▒", "▓", "█", "█"];

fn main() {
    let mut perlin = Perlin::new();
    perlin.frequency = 0.1;

    for y in range(0, HEIGHT / 2) {
        for x in range(0, WIDTH) {
            let val = perlin.get(
                x as f64,
                y as f64 * 2.0,
                0.0
            );

            let val = val * 0.5 + 0.5;

            print(GRADIENT[(val / 0.2) as int]);
        }
        println("");
    }
}
<|endoftext|>


<commit_before>//! Utilities for use with
//! [`DynamicBoundingVolumeTree`](struct.DynamicBoundingVolumeTree.html).
//!

use std::fmt::Debug;
use std::ops::{Deref, DerefMut};

use cgmath::prelude::*;
use cgmath::BaseFloat;

use Ray;
use prelude::*;
use super::{DynamicBoundingVolumeTree, TreeValue};
use super::visitor::ContinuousVisitor;

/// Trait used to simplify integration with the tree. Instead of keeping track of the node index,
/// fat factor and fat bounds, we provide a wrapper type, together with this trait.
pub trait ValueAabbWrapped: Clone + Debug {
    /// Bounding volume type
    type Bound: Aabb + Clone + Debug;

    /// Borrow the bounding volume
    fn bound(&self) -> &Self::Bound;
}

/// Provides an easier to use wrapper type for use with the DBVT.
///
/// # Examples
///
/// ```
/// # extern crate collision;
/// # extern crate cgmath;
///
/// use cgmath::{Point2, Vector2};
/// use cgmath::prelude::*;
/// use collision::{Aabb2, Ray2};
/// use collision::dbvt::{DynamicBoundingVolumeTree, ValueAabbWrapped,
///                       ValueAabbWrapper, query_ray_closest};
///
/// #[derive(Debug, Clone)]
/// struct Value {
///     id: u32,
///     bound: Aabb2<f32>,
/// }
///
/// impl Value {
///     fn new(id: u32, bound: Aabb2<f32>) -> Self {
///         Self { id, bound }
///     }
/// }
///
/// impl ValueAabbWrapped for Value {
///     type Bound = Aabb2<f32>;
///
///     fn bound(&self) -> &Self::Bound {
///         &self.bound
///     }
/// }
///
/// fn main() {
///     let mut tree = DynamicBoundingVolumeTree::<ValueAabbWrapper<Value>>::new();
///     tree.insert(Value::new(12, aabb2(0., 0., 10., 10.)).into());
///     tree.insert(Value::new(33, aabb2(15., 3., 3., 3.)).into());
///     tree.insert(Value::new(13, aabb2(-145., 34., 2., 2.)).into());
///     tree.insert(Value::new(66, aabb2(123., -10., 10., 10.)).into());
///     tree.insert(Value::new(1, aabb2(22., 50., 16., 16.)).into());
///     tree.insert(Value::new(76, aabb2(7., 3., 1., 1.)).into());
///     tree.insert(Value::new(99, aabb2(19., -12., 3., 3.)).into());
///     tree.do_refit();
///
///     let result = query_ray_closest(
///         &tree,
///         &Ray2::new(Point2::new(12., 12.), Vector2::new(0.5, -0.5).normalize()),
///     );
///     assert!(result.is_some());
///     let (v, p) = result.unwrap();
///     assert_eq!(33, v.id);
///     assert_eq!(Point2::new(18., 5.9999995), p);
/// }
///
/// fn aabb2(minx: f32, miny: f32, width: f32, height: f32) -> Aabb2<f32> {
///     Aabb2::new(
///         Point2::new(minx, miny),
///         Point2::new(minx + width, miny + height),
///     )
/// }
/// ```
///
#[derive(Clone, Debug)]
pub struct ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    index: usize,

    /// Fat factor, defaults to zero, can be changed. After changing, it will be used the next time
    /// the contained value's bounding volumes moves outside the current fat bound in the tree.
    pub fat_factor: <T::Bound as Aabb>::Diff,

    /// The value itself
    pub value: T,
}

impl<T> Deref for ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.value
    }
}

impl<T> DerefMut for ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.value
    }
}

impl<T> ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    pub fn new_impl(value: T, fat_factor: <T::Bound as Aabb>::Diff) -> Self {
        Self {
            index: 0,
            fat_factor,
            value,
        }
    }

    pub fn new(value: T) -> Self {
        Self::new_impl(value, <T::Bound as Aabb>::Diff::zero())
    }
}

impl<T> TreeValue for ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    type Bound = T::Bound;
    type Vector = <T::Bound as Aabb>::Diff;

    fn bound(&self) -> &Self::Bound {
        self.value.bound()
    }

    fn fat_bound(&self) -> Self::Bound {
        self.value.bound().add_margin(self.fat_factor)
    }

    fn set_index(&mut self, index: usize) {
        self.index = index;
    }

    fn index(&self) -> usize {
        self.index
    }
}

impl<T> From<T> for ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

/// Query the given tree for the closest value that intersects the given ray.
pub fn query_ray_closest<'a, S, T: 'a, P>(
    tree: &'a DynamicBoundingVolumeTree<T>,
    ray: &Ray<S, P, P::Diff>,
) -> Option<(&'a T, P)>
where
    S: BaseFloat,
    T: TreeValue,
    P: EuclideanSpace<Scalar = S>,
    P::Diff: VectorSpace<Scalar = S> + InnerSpace,
    T::Bound: Clone
        + Debug
        + Contains<T::Bound>
        + SurfaceArea<Scalar = S>
        + Union<T::Bound, Output = T::Bound>
        + Continuous<Ray<S, P, P::Diff>, Result = P>
        + Discrete<Ray<S, P, P::Diff>>,
{
    let mut saved = None;
    let mut tmin = S::infinity();
    let visitor = ContinuousVisitor::<Ray<S, P, P::Diff>, T>::new(&ray);
    for (value, point) in tree.query(&visitor) {
        let offset = point - ray.origin;
        let t = offset.dot(ray.direction);
        if t < tmin {
            tmin = t;
            saved = Some((value, point.clone()));
        }
    }
    saved
}

#[cfg(test)]
mod tests {

    use cgmath::{Point2, Vector2};

    use super::*;
    use super::super::*;
    use {Aabb2, Ray2};

    #[derive(Debug, Clone)]
    struct Value {
        id: u32,
        bound: Aabb2<f32>,
    }

    impl Value {
        fn new(id: u32, bound: Aabb2<f32>) -> Self {
            Self { id, bound }
        }
    }

    impl ValueAabbWrapped for Value {
        type Bound = Aabb2<f32>;

        fn bound(&self) -> &Self::Bound {
            &self.bound
        }
    }

    #[test]
    fn test() {
        let mut tree = DynamicBoundingVolumeTree::<ValueAabbWrapper<Value>>::new();
        tree.insert(Value::new(12, aabb2(0., 0., 10., 10.)).into());
        tree.insert(Value::new(33, aabb2(15., 3., 3., 3.)).into());
        tree.insert(Value::new(13, aabb2(-145., 34., 2., 2.)).into());
        tree.insert(Value::new(66, aabb2(123., -10., 10., 10.)).into());
        tree.insert(Value::new(1, aabb2(22., 50., 16., 16.)).into());
        tree.insert(Value::new(76, aabb2(7., 3., 1., 1.)).into());
        tree.insert(Value::new(99, aabb2(19., -12., 3., 3.)).into());
        tree.do_refit();

        let result = query_ray_closest(
            &tree,
            &Ray2::new(Point2::new(12., 12.), Vector2::new(0.5, -0.5).normalize()),
        );
        assert!(result.is_some());
        let (v, p) = result.unwrap();
        assert_eq!(33, v.id);
        assert_eq!(Point2::new(18., 5.9999995), p);
    }

    fn aabb2(minx: f32, miny: f32, width: f32, height: f32) -> Aabb2<f32> {
        Aabb2::new(
            Point2::new(minx, miny),
            Point2::new(minx + width, miny + height),
        )
    }
}
<commit_msg>Fixed compile error on nightly<commit_after>//! Utilities for use with
//! [`DynamicBoundingVolumeTree`](struct.DynamicBoundingVolumeTree.html).
//!

use std::fmt::Debug;
use std::ops::{Deref, DerefMut};

use cgmath::prelude::*;
use cgmath::BaseFloat;

use Ray;
use prelude::*;
use super::{DynamicBoundingVolumeTree, TreeValue};
use super::visitor::ContinuousVisitor;

/// Trait used to simplify integration with the tree. Instead of keeping track of the node index,
/// fat factor and fat bounds, we provide a wrapper type, together with this trait.
pub trait ValueAabbWrapped: Clone + Debug {
    /// Bounding volume type
    type Bound: Aabb + Clone + Debug;

    /// Borrow the bounding volume
    fn bound(&self) -> &Self::Bound;
}

/// Provides an easier to use wrapper type for use with the DBVT.
///
/// # Examples
///
/// ```
/// # extern crate collision;
/// # extern crate cgmath;
///
/// use cgmath::{Point2, Vector2};
/// use cgmath::prelude::*;
/// use collision::{Aabb2, Ray2};
/// use collision::dbvt::{DynamicBoundingVolumeTree, ValueAabbWrapped,
///                       ValueAabbWrapper, query_ray_closest};
///
/// #[derive(Debug, Clone)]
/// struct Value {
///     id: u32,
///     bound: Aabb2<f32>,
/// }
///
/// impl Value {
///     fn new(id: u32, bound: Aabb2<f32>) -> Self {
///         Self { id, bound }
///     }
/// }
///
/// impl ValueAabbWrapped for Value {
///     type Bound = Aabb2<f32>;
///
///     fn bound(&self) -> &Self::Bound {
///         &self.bound
///     }
/// }
///
/// fn main() {
///     let mut tree = DynamicBoundingVolumeTree::<ValueAabbWrapper<Value>>::new();
///     tree.insert(Value::new(12, aabb2(0., 0., 10., 10.)).into());
///     tree.insert(Value::new(33, aabb2(15., 3., 3., 3.)).into());
///     tree.insert(Value::new(13, aabb2(-145., 34., 2., 2.)).into());
///     tree.insert(Value::new(66, aabb2(123., -10., 10., 10.)).into());
///     tree.insert(Value::new(1, aabb2(22., 50., 16., 16.)).into());
///     tree.insert(Value::new(76, aabb2(7., 3., 1., 1.)).into());
///     tree.insert(Value::new(99, aabb2(19., -12., 3., 3.)).into());
///     tree.do_refit();
///
///     let result = query_ray_closest(
///         &tree,
///         &Ray2::new(Point2::new(12., 12.), Vector2::new(0.5, -0.5).normalize()),
///     );
///     assert!(result.is_some());
///     let (v, p) = result.unwrap();
///     assert_eq!(33, v.id);
///     assert_eq!(Point2::new(18., 5.9999995), p);
/// }
///
/// fn aabb2(minx: f32, miny: f32, width: f32, height: f32) -> Aabb2<f32> {
///     Aabb2::new(
///         Point2::new(minx, miny),
///         Point2::new(minx + width, miny + height),
///     )
/// }
/// ```
///
#[derive(Clone, Debug)]
pub struct ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    index: usize,

    /// Fat factor, defaults to zero, can be changed. After changing, it will be used the next time
    /// the contained value's bounding volumes moves outside the current fat bound in the tree.
    pub fat_factor: <T::Bound as Aabb>::Diff,

    /// The value itself
    pub value: T,
}

impl<T> Deref for ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.value
    }
}

impl<T> DerefMut for ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.value
    }
}

impl<T> ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    pub fn new_impl(value: T, fat_factor: <T::Bound as Aabb>::Diff) -> Self {
        Self {
            index: 0,
            fat_factor,
            value,
        }
    }

    pub fn new(value: T) -> Self {
        Self::new_impl(value, <T::Bound as Aabb>::Diff::zero())
    }
}

impl<T> TreeValue for ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug + VectorSpace,
{
    type Bound = T::Bound;
    type Vector = <T::Bound as Aabb>::Diff;

    fn bound(&self) -> &Self::Bound {
        self.value.bound()
    }

    fn fat_bound(&self) -> Self::Bound {
        self.value.bound().add_margin(self.fat_factor)
    }

    fn set_index(&mut self, index: usize) {
        self.index = index;
    }

    fn index(&self) -> usize {
        self.index
    }
}

impl<T> From<T> for ValueAabbWrapper<T>
where
    T: ValueAabbWrapped,
    <T::Bound as Aabb>::Diff: Clone + Debug,
{
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

/// Query the given tree for the closest value that intersects the given ray.
pub fn query_ray_closest<'a, S, T: 'a, P>(
    tree: &'a DynamicBoundingVolumeTree<T>,
    ray: &Ray<S, P, P::Diff>,
) -> Option<(&'a T, P)>
where
    S: BaseFloat,
    T: TreeValue,
    P: EuclideanSpace<Scalar = S>,
    P::Diff: VectorSpace<Scalar = S> + InnerSpace,
    T::Bound: Clone
        + Debug
        + Contains<T::Bound>
        + SurfaceArea<Scalar = S>
        + Union<T::Bound, Output = T::Bound>
        + Continuous<Ray<S, P, P::Diff>, Result = P>
        + Discrete<Ray<S, P, P::Diff>>,
{
    let mut saved = None;
    let mut tmin = S::infinity();
    let visitor = ContinuousVisitor::<Ray<S, P, P::Diff>, T>::new(&ray);
    for (value, point) in tree.query(&visitor) {
        let offset = point - ray.origin;
        let t = offset.dot(ray.direction);
        if t < tmin {
            tmin = t;
            saved = Some((value, point.clone()));
        }
    }
    saved
}

#[cfg(test)]
mod tests {

    use cgmath::{Point2, Vector2};

    use super::*;
    use super::super::*;
    use {Aabb2, Ray2};

    #[derive(Debug, Clone)]
    struct Value {
        id: u32,
        bound: Aabb2<f32>,
    }

    impl Value {
        fn new(id: u32, bound: Aabb2<f32>) -> Self {
            Self { id, bound }
        }
    }

    impl ValueAabbWrapped for Value {
        type Bound = Aabb2<f32>;

        fn bound(&self) -> &Self::Bound {
            &self.bound
        }
    }

    #[test]
    fn test() {
        let mut tree = DynamicBoundingVolumeTree::<ValueAabbWrapper<Value>>::new();
        tree.insert(Value::new(12, aabb2(0., 0., 10., 10.)).into());
        tree.insert(Value::new(33, aabb2(15., 3., 3., 3.)).into());
        tree.insert(Value::new(13, aabb2(-145., 34., 2., 2.)).into());
        tree.insert(Value::new(66, aabb2(123., -10., 10., 10.)).into());
        tree.insert(Value::new(1, aabb2(22., 50., 16., 16.)).into());
        tree.insert(Value::new(76, aabb2(7., 3., 1., 1.)).into());
        tree.insert(Value::new(99, aabb2(19., -12., 3., 3.)).into());
        tree.do_refit();

        let result = query_ray_closest(
            &tree,
            &Ray2::new(Point2::new(12., 12.), Vector2::new(0.5, -0.5).normalize()),
        );
        assert!(result.is_some());
        let (v, p) = result.unwrap();
        assert_eq!(33, v.id);
        assert_eq!(Point2::new(18., 5.9999995), p);
    }

    fn aabb2(minx: f32, miny: f32, width: f32, height: f32) -> Aabb2<f32> {
        Aabb2::new(
            Point2::new(minx, miny),
            Point2::new(minx + width, miny + height),
        )
    }
}
<|endoftext|>


<commit_before>use super::dsp::Dsp;
use super::super::apu::Apu;
use super::envelope::Envelope;
use super::brr_block_decoder::BrrBlockDecoder;
use super::dsp_helpers;
use super::gaussian::{KERNEL_SIZE, KERNEL};

const RESAMPLE_BUFFER_LEN: usize = 4;

#[derive(Clone, Copy)]
pub enum ResamplingMode {
    Linear,
    Gaussian
}

#[derive(Clone, Copy)]
pub struct VoiceOutput {
    pub left_out: i32,
    pub right_out: i32,
    pub last_voice_out: i32
}

impl VoiceOutput {
    pub fn default() -> VoiceOutput {
        VoiceOutput {
            left_out: 0,
            right_out: 0,
            last_voice_out: 0
        }
    }
}

pub const VOICE_BUFFER_LEN: usize = 128;

// TODO: If Rust had facilities for specifying arrray sizes with generic parameters,
// this could be removed in favor of a more generalized RingBuffer.
pub struct VoiceBuffer {
    pub buffer: Box<[VoiceOutput; VOICE_BUFFER_LEN]>,
    pub pos: i32
}

impl VoiceBuffer {
    pub fn new() -> VoiceBuffer {
        VoiceBuffer {
            buffer: Box::new([VoiceOutput::default(); VOICE_BUFFER_LEN]),
            pos: 0
        }
    }

    pub fn reset(&mut self) {
        for i in 0..VOICE_BUFFER_LEN {
            self.buffer[i] = VoiceOutput::default();
        }
        self.pos = 0;
    }

    pub fn write(&mut self, value: VoiceOutput) {
        self.buffer[self.pos as usize] = value;
        self.pos = (self.pos + 1) % (VOICE_BUFFER_LEN as i32);
    }
}

pub struct Voice {
    dsp: *mut Dsp,
    emulator: *mut Apu,

    pub envelope: Box<Envelope>,

    pub vol_left: u8,
    pub vol_right: u8,
    pub pitch_low: u8,
    pitch_high: u8,
    pub source: u8,
    pub pitch_mod: bool,
    pub noise_on: bool,
    pub echo_on: bool,

    sample_start_address: u32,
    loop_start_address: u32,
    brr_block_decoder: Box<BrrBlockDecoder>,
    sample_address: u32,
    sample_pos: i32,

    pub resampling_mode: ResamplingMode,
    resample_buffer: [i32; RESAMPLE_BUFFER_LEN],
    resample_buffer_pos: usize,

    pub output_buffer: Box<VoiceBuffer>,
    pub is_muted: bool
}

impl Voice {
    pub fn new(dsp: *mut Dsp, emulator: *mut Apu, resampling_mode: ResamplingMode) -> Voice {
        let mut ret = Voice {
            dsp: dsp,
            emulator: emulator,

            envelope: Box::new(Envelope::new(dsp)),

            vol_left: 0,
            vol_right: 0,
            pitch_low: 0,
            pitch_high: 0,
            source: 0,
            pitch_mod: false,
            noise_on: false,
            echo_on: false,

            sample_start_address: 0,
            loop_start_address: 0,
            brr_block_decoder: Box::new(BrrBlockDecoder::new()),
            sample_address: 0,
            sample_pos: 0,

            resampling_mode: resampling_mode,
            resample_buffer: [0; RESAMPLE_BUFFER_LEN],
            resample_buffer_pos: 0,

            output_buffer: Box::new(VoiceBuffer::new()),
            is_muted: false,
        };
        ret.reset();
        ret
    }

    #[inline]
    fn dsp(&self) -> &mut Dsp {
        unsafe {
            &mut (*self.dsp)
        }
    }

    #[inline]
    fn emulator(&self) -> &mut Apu {
        unsafe {
            &mut (*self.emulator)
        }
    }

    pub fn reset(&mut self) {
        self.envelope.reset();

        self.vol_left = 0;
        self.vol_right = 0;
        self.pitch_low = 0;
        self.pitch_high = 0x10;
        self.source = 0;
        self.pitch_mod = false;
        self.noise_on = false;

        self.sample_start_address = 0;
        self.loop_start_address = 0;
        self.brr_block_decoder.reset(0, 0);
        self.sample_address = 0;
        self.sample_pos = 0;

        for i in 0..RESAMPLE_BUFFER_LEN {
            self.resample_buffer[i] = 0;
        }
        self.resample_buffer_pos = 0;

        self.output_buffer.reset();
        self.is_muted = false;
    }

    pub fn render_sample(&mut self, last_voice_out: i32, noise: i32) -> VoiceOutput {
        let mut pitch = ((self.pitch_high as i32) << 8) | (self.pitch_low as i32);
        if self.pitch_mod {
            pitch += ((last_voice_out >> 5) * pitch) >> 10;
        }
        if pitch < 0 {
            pitch = 0;
        }
        if pitch > 0x3fff {
            pitch = 0x3fff;
        }

        let mut sample = if !self.noise_on {
            let s1 = self.resample_buffer[self.resample_buffer_pos];
            let s2 = self.resample_buffer[(self.resample_buffer_pos + 1) % RESAMPLE_BUFFER_LEN];
            let resampled = match self.resampling_mode {
                ResamplingMode::Linear => {
                    let p1 = self.sample_pos;
                    let p2 = 0x1000 - p1;
                    (s1 * p1 + s2 * p2) >> 12
                },
                ResamplingMode::Gaussian => {
                    let s3 = self.resample_buffer[(self.resample_buffer_pos + 2) % RESAMPLE_BUFFER_LEN];
                    let s4 = self.resample_buffer[(self.resample_buffer_pos + 3) % RESAMPLE_BUFFER_LEN];
                    let kernel_index = (self.sample_pos >> 2) as usize;
                    let p1 = KERNEL[kernel_index];
                    let p2 = KERNEL[(kernel_index + KERNEL_SIZE / 4) % KERNEL_SIZE];
                    let p3 = KERNEL[(kernel_index + KERNEL_SIZE / 2) % KERNEL_SIZE];
                    let p4 = KERNEL[(kernel_index + KERNEL_SIZE * 3 / 4) % KERNEL_SIZE];
                    (s1 * p1 + s2 * p2 + s3 * p3 + s4 * p4) >> 11
                }
            };
            dsp_helpers::clamp(resampled) & !1
        } else {
            ((noise * 2) as i16) as i32
        };

        self.envelope.tick();
        let env_level = self.envelope.level;

        sample = ((sample * env_level) >> 11) & !1;

        if self.brr_block_decoder.is_end && !self.brr_block_decoder.is_looping {
            self.envelope.key_off();
            self.envelope.level = 0;
        }

        self.sample_pos += pitch;
        while self.sample_pos >= 0x1000 {
            self.sample_pos -= 0x1000;
            self.read_next_sample();

            if self.brr_block_decoder.is_finished() {
                if self.brr_block_decoder.is_end && self.brr_block_decoder.is_looping {
                    self.read_entry();
                    self.sample_address = self.loop_start_address;
                }
                self.read_next_block();
            }
        }

        let ret =
            if !self.is_muted {
                VoiceOutput {
                    left_out: dsp_helpers::multiply_volume(sample, self.vol_left),
                    right_out: dsp_helpers::multiply_volume(sample, self.vol_right),
                    last_voice_out: sample
                }
            } else {
                VoiceOutput {
                    left_out: 0,
                    right_out: 0,
                    last_voice_out: 0
                }
            };
        self.output_buffer.write(ret);
        ret
    }

    pub fn set_pitch_high(&mut self, value: u8) {
        self.pitch_high = value & 0x3f;
    }

    pub fn key_on(&mut self) {
        self.read_entry();
        self.sample_address = self.sample_start_address;
        self.brr_block_decoder.reset(0, 0);
        self.read_next_block();
        self.sample_pos = 0;
        self.resample_buffer[self.resample_buffer_pos] = 0;
        self.read_next_sample();
        self.envelope.key_on();
    }

    pub fn key_off(&mut self) {
        self.envelope.key_off();
    }

    fn read_entry(&mut self) {
        self.sample_start_address = self.dsp().read_source_dir_start_address(self.source as i32);
        self.loop_start_address = self.dsp().read_source_dir_loop_address(self.source as i32);
    }

    fn read_next_block(&mut self) {
        let mut buf = [0; 9];
        for i in 0..9 {
            buf[i] = self.emulator().read_u8(self.sample_address + (i as u32));
        }
        self.brr_block_decoder.read(&buf);
        self.sample_address += 9;
    }

    fn read_next_sample(&mut self) {
        self.resample_buffer_pos = match self.resample_buffer_pos {
            0 => RESAMPLE_BUFFER_LEN - 1,
            x => x - 1
        };
        self.resample_buffer[self.resample_buffer_pos] = self.brr_block_decoder.read_next_sample() as i32;
    }
}
<commit_msg>Fixed most of the issues with gaussian resampling<commit_after>use super::dsp::Dsp;
use super::super::apu::Apu;
use super::envelope::Envelope;
use super::brr_block_decoder::BrrBlockDecoder;
use super::dsp_helpers;
use super::gaussian::{KERNEL_SIZE, KERNEL};

const RESAMPLE_BUFFER_LEN: usize = 4;

#[derive(Clone, Copy)]
pub enum ResamplingMode {
    Linear,
    Gaussian
}

#[derive(Clone, Copy)]
pub struct VoiceOutput {
    pub left_out: i32,
    pub right_out: i32,
    pub last_voice_out: i32
}

impl VoiceOutput {
    pub fn default() -> VoiceOutput {
        VoiceOutput {
            left_out: 0,
            right_out: 0,
            last_voice_out: 0
        }
    }
}

pub const VOICE_BUFFER_LEN: usize = 128;

// TODO: If Rust had facilities for specifying arrray sizes with generic parameters,
// this could be removed in favor of a more generalized RingBuffer.
pub struct VoiceBuffer {
    pub buffer: Box<[VoiceOutput; VOICE_BUFFER_LEN]>,
    pub pos: i32
}

impl VoiceBuffer {
    pub fn new() -> VoiceBuffer {
        VoiceBuffer {
            buffer: Box::new([VoiceOutput::default(); VOICE_BUFFER_LEN]),
            pos: 0
        }
    }

    pub fn reset(&mut self) {
        for i in 0..VOICE_BUFFER_LEN {
            self.buffer[i] = VoiceOutput::default();
        }
        self.pos = 0;
    }

    pub fn write(&mut self, value: VoiceOutput) {
        self.buffer[self.pos as usize] = value;
        self.pos = (self.pos + 1) % (VOICE_BUFFER_LEN as i32);
    }
}

pub struct Voice {
    dsp: *mut Dsp,
    emulator: *mut Apu,

    pub envelope: Box<Envelope>,

    pub vol_left: u8,
    pub vol_right: u8,
    pub pitch_low: u8,
    pitch_high: u8,
    pub source: u8,
    pub pitch_mod: bool,
    pub noise_on: bool,
    pub echo_on: bool,

    sample_start_address: u32,
    loop_start_address: u32,
    brr_block_decoder: Box<BrrBlockDecoder>,
    sample_address: u32,
    sample_pos: i32,

    pub resampling_mode: ResamplingMode,
    resample_buffer: [i32; RESAMPLE_BUFFER_LEN],
    resample_buffer_pos: usize,

    pub output_buffer: Box<VoiceBuffer>,
    pub is_muted: bool
}

impl Voice {
    pub fn new(dsp: *mut Dsp, emulator: *mut Apu, resampling_mode: ResamplingMode) -> Voice {
        let mut ret = Voice {
            dsp: dsp,
            emulator: emulator,

            envelope: Box::new(Envelope::new(dsp)),

            vol_left: 0,
            vol_right: 0,
            pitch_low: 0,
            pitch_high: 0,
            source: 0,
            pitch_mod: false,
            noise_on: false,
            echo_on: false,

            sample_start_address: 0,
            loop_start_address: 0,
            brr_block_decoder: Box::new(BrrBlockDecoder::new()),
            sample_address: 0,
            sample_pos: 0,

            resampling_mode: resampling_mode,
            resample_buffer: [0; RESAMPLE_BUFFER_LEN],
            resample_buffer_pos: 0,

            output_buffer: Box::new(VoiceBuffer::new()),
            is_muted: false,
        };
        ret.reset();
        ret
    }

    #[inline]
    fn dsp(&self) -> &mut Dsp {
        unsafe {
            &mut (*self.dsp)
        }
    }

    #[inline]
    fn emulator(&self) -> &mut Apu {
        unsafe {
            &mut (*self.emulator)
        }
    }

    pub fn reset(&mut self) {
        self.envelope.reset();

        self.vol_left = 0;
        self.vol_right = 0;
        self.pitch_low = 0;
        self.pitch_high = 0x10;
        self.source = 0;
        self.pitch_mod = false;
        self.noise_on = false;

        self.sample_start_address = 0;
        self.loop_start_address = 0;
        self.brr_block_decoder.reset(0, 0);
        self.sample_address = 0;
        self.sample_pos = 0;

        for i in 0..RESAMPLE_BUFFER_LEN {
            self.resample_buffer[i] = 0;
        }
        self.resample_buffer_pos = 0;

        self.output_buffer.reset();
        self.is_muted = false;
    }

    pub fn render_sample(&mut self, last_voice_out: i32, noise: i32) -> VoiceOutput {
        let mut pitch = ((self.pitch_high as i32) << 8) | (self.pitch_low as i32);
        if self.pitch_mod {
            pitch += ((last_voice_out >> 5) * pitch) >> 10;
        }
        if pitch < 0 {
            pitch = 0;
        }
        if pitch > 0x3fff {
            pitch = 0x3fff;
        }

        let mut sample = if !self.noise_on {
            let s1 = self.resample_buffer[self.resample_buffer_pos];
            let s2 = self.resample_buffer[(self.resample_buffer_pos + 1) % RESAMPLE_BUFFER_LEN];
            let resampled = match self.resampling_mode {
                ResamplingMode::Linear => {
                    let p1 = self.sample_pos;
                    let p2 = 0x1000 - p1;
                    (s1 * p1 + s2 * p2) >> 12
                },
                ResamplingMode::Gaussian => {
                    let s3 = self.resample_buffer[(self.resample_buffer_pos + 2) % RESAMPLE_BUFFER_LEN];
                    let s4 = self.resample_buffer[(self.resample_buffer_pos + 3) % RESAMPLE_BUFFER_LEN];
                    let kernel_index = (self.sample_pos >> 4) as usize;
                    let p1 = KERNEL[kernel_index];
                    let p2 = KERNEL[(kernel_index + KERNEL_SIZE / 4) % KERNEL_SIZE];
                    let p3 = KERNEL[(kernel_index + KERNEL_SIZE / 2) % KERNEL_SIZE];
                    let p4 = KERNEL[(kernel_index + KERNEL_SIZE * 3 / 4) % KERNEL_SIZE];
                    (s1 * p1 + s2 * p2 + s3 * p3 + s4 * p4) >> 11
                }
            };
            dsp_helpers::clamp(resampled) & !1
        } else {
            ((noise * 2) as i16) as i32
        };

        self.envelope.tick();
        let env_level = self.envelope.level;

        sample = ((sample * env_level) >> 11) & !1;

        if self.brr_block_decoder.is_end && !self.brr_block_decoder.is_looping {
            self.envelope.key_off();
            self.envelope.level = 0;
        }

        self.sample_pos += pitch;
        while self.sample_pos >= 0x1000 {
            self.sample_pos -= 0x1000;
            self.read_next_sample();

            if self.brr_block_decoder.is_finished() {
                if self.brr_block_decoder.is_end && self.brr_block_decoder.is_looping {
                    self.read_entry();
                    self.sample_address = self.loop_start_address;
                }
                self.read_next_block();
            }
        }

        let ret =
            if !self.is_muted {
                VoiceOutput {
                    left_out: dsp_helpers::multiply_volume(sample, self.vol_left),
                    right_out: dsp_helpers::multiply_volume(sample, self.vol_right),
                    last_voice_out: sample
                }
            } else {
                VoiceOutput {
                    left_out: 0,
                    right_out: 0,
                    last_voice_out: 0
                }
            };
        self.output_buffer.write(ret);
        ret
    }

    pub fn set_pitch_high(&mut self, value: u8) {
        self.pitch_high = value & 0x3f;
    }

    pub fn key_on(&mut self) {
        self.read_entry();
        self.sample_address = self.sample_start_address;
        self.brr_block_decoder.reset(0, 0);
        self.read_next_block();
        self.sample_pos = 0;
        self.resample_buffer[self.resample_buffer_pos] = 0;
        self.read_next_sample();
        self.envelope.key_on();
    }

    pub fn key_off(&mut self) {
        self.envelope.key_off();
    }

    fn read_entry(&mut self) {
        self.sample_start_address = self.dsp().read_source_dir_start_address(self.source as i32);
        self.loop_start_address = self.dsp().read_source_dir_loop_address(self.source as i32);
    }

    fn read_next_block(&mut self) {
        let mut buf = [0; 9];
        for i in 0..9 {
            buf[i] = self.emulator().read_u8(self.sample_address + (i as u32));
        }
        self.brr_block_decoder.read(&buf);
        self.sample_address += 9;
    }

    fn read_next_sample(&mut self) {
        self.resample_buffer_pos = match self.resample_buffer_pos {
            0 => RESAMPLE_BUFFER_LEN - 1,
            x => x - 1
        };
        self.resample_buffer[self.resample_buffer_pos] = self.brr_block_decoder.read_next_sample() as i32;
    }
}
<|endoftext|>


<commit_before>import core::option;
import core::ctypes::*;

export libc;
export libc_constants;
export pipe;
export fd_FILE;
export close;
export fclose;
export waitpid;
export getcwd;
export exec_suffix;
export target_os;
export dylib_filename;
export get_exe_path;
export fsync_fd;

// FIXME Refactor into unix_os module or some such. Doesn't
// seem to work right now.

#[nolink]
#[abi = "cdecl"]
native mod libc {
    fn read(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
    fn write(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
    fn fread(buf: *u8, size: size_t, n: size_t, f: libc::FILE) -> size_t;
    fn fwrite(buf: *u8, size: size_t, n: size_t, f: libc::FILE) -> size_t;
    fn open(s: str::sbuf, flags: c_int, mode: unsigned) -> fd_t;
    fn close(fd: fd_t) -> c_int;
    type FILE;
    fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE;
    fn fdopen(fd: fd_t, mode: str::sbuf) -> FILE;
    fn fflush(f: FILE) -> c_int;
    fn fsync(fd: fd_t) -> c_int;
    fn fileno(f: FILE) -> fd_t;
    fn fclose(f: FILE);
    fn fgetc(f: FILE) -> c_int;
    fn ungetc(c: c_int, f: FILE);
    fn feof(f: FILE) -> c_int;
    fn fseek(f: FILE, offset: long, whence: c_int) -> c_int;
    fn ftell(f: FILE) -> long;
    type dir;
    fn opendir(d: str::sbuf) -> dir;
    fn closedir(d: dir) -> c_int;
    type dirent;
    fn readdir(d: dir) -> dirent;
    fn getenv(n: str::sbuf) -> str::sbuf;
    fn setenv(n: str::sbuf, v: str::sbuf, overwrite: c_int) -> c_int;
    fn unsetenv(n: str::sbuf) -> c_int;
    fn pipe(buf: *mutable c_int) -> c_int;
    fn waitpid(pid: pid_t, &status: c_int, options: c_int) -> c_int;
    fn mkdir(s: str::sbuf, mode: c_int) -> c_int;
    fn rmdir(s: str::sbuf) -> c_int;
    fn chdir(s: str::sbuf) -> c_int;

    // FIXME: Needs varags
    fn fcntl(fd: fd_t, cmd: c_int) -> c_int;
}

mod libc_constants {
    const O_RDONLY: c_int    = 0i32;
    const O_WRONLY: c_int    = 1i32;
    const O_RDWR: c_int      = 2i32;
    const O_APPEND: c_int    = 8i32;
    const O_CREAT: c_int     = 512i32;
    const O_EXCL: c_int      = 2048i32;
    const O_TRUNC: c_int     = 1024i32;
    const O_TEXT: c_int      = 0i32;    // nonexistent in darwin libc
    const O_BINARY: c_int    = 0i32;    // nonexistent in darwin libc

    const S_IRUSR: unsigned  = 256u32;
    const S_IWUSR: unsigned  = 128u32;

    const F_FULLFSYNC: c_int = 51i32;
}

fn pipe() -> {in: fd_t, out: fd_t} {
    let fds = {mutable in: 0i32, mutable out: 0i32};
    assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0i32);
    ret {in: fds.in, out: fds.out};
}

fn fd_FILE(fd: fd_t) -> libc::FILE {
    ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) });
}

fn close(fd: fd_t) -> c_int {
    libc::close(fd)
}

fn fclose(file: libc::FILE) {
    libc::fclose(file)
}

fn waitpid(pid: pid_t) -> i32 {
    let status = 0i32;
    assert (os::libc::waitpid(pid, status, 0i32) != -1i32);
    ret status;
}

fn fsync_fd(fd: fd_t, level: io::fsync::level) -> c_int {
    alt level {
      io::fsync::fsync. { ret libc::fsync(fd); }
      _ {
        // According to man fnctl, the ok retval is only specified to be !=-1
        if (libc::fcntl(libc_constants::F_FULLFSYNC, fd) == -1 as c_int)
            { ret -1 as c_int; }
        else
            { ret 0 as c_int; }
      }
    }
}

#[abi = "cdecl"]
native mod rustrt {
    fn rust_getcwd() -> str;
}

fn getcwd() -> str { ret rustrt::rust_getcwd(); }

#[link_name = ""]               // FIXME remove after #[nolink] is snapshotted
#[nolink]
#[abi = "cdecl"]
native mod mac_libc {
    fn _NSGetExecutablePath(buf: str::sbuf,
                            bufsize: *mutable uint32_t) -> c_int;
}

fn exec_suffix() -> str { ret ""; }

fn target_os() -> str { ret "macos"; }

fn dylib_filename(base: str) -> str { ret "lib" + base + ".dylib"; }

fn get_exe_path() -> option::t<fs::path> {
    // FIXME: This doesn't handle the case where the buffer is too small
    let bufsize = 1023u32;
    let path = str::unsafe_from_bytes(vec::init_elt(0u8, bufsize as uint));
    ret str::as_buf(path, { |path_buf|
        if mac_libc::_NSGetExecutablePath(path_buf,
                                          ptr::mut_addr_of(bufsize)) == 0i32 {
            option::some(fs::dirname(path) + fs::path_sep())
        } else {
            option::none
        }
    });
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>libstd: Remove a bogus link_name attribute<commit_after>import core::option;
import core::ctypes::*;

export libc;
export libc_constants;
export pipe;
export fd_FILE;
export close;
export fclose;
export waitpid;
export getcwd;
export exec_suffix;
export target_os;
export dylib_filename;
export get_exe_path;
export fsync_fd;

// FIXME Refactor into unix_os module or some such. Doesn't
// seem to work right now.

#[nolink]
#[abi = "cdecl"]
native mod libc {
    fn read(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
    fn write(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
    fn fread(buf: *u8, size: size_t, n: size_t, f: libc::FILE) -> size_t;
    fn fwrite(buf: *u8, size: size_t, n: size_t, f: libc::FILE) -> size_t;
    fn open(s: str::sbuf, flags: c_int, mode: unsigned) -> fd_t;
    fn close(fd: fd_t) -> c_int;
    type FILE;
    fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE;
    fn fdopen(fd: fd_t, mode: str::sbuf) -> FILE;
    fn fflush(f: FILE) -> c_int;
    fn fsync(fd: fd_t) -> c_int;
    fn fileno(f: FILE) -> fd_t;
    fn fclose(f: FILE);
    fn fgetc(f: FILE) -> c_int;
    fn ungetc(c: c_int, f: FILE);
    fn feof(f: FILE) -> c_int;
    fn fseek(f: FILE, offset: long, whence: c_int) -> c_int;
    fn ftell(f: FILE) -> long;
    type dir;
    fn opendir(d: str::sbuf) -> dir;
    fn closedir(d: dir) -> c_int;
    type dirent;
    fn readdir(d: dir) -> dirent;
    fn getenv(n: str::sbuf) -> str::sbuf;
    fn setenv(n: str::sbuf, v: str::sbuf, overwrite: c_int) -> c_int;
    fn unsetenv(n: str::sbuf) -> c_int;
    fn pipe(buf: *mutable c_int) -> c_int;
    fn waitpid(pid: pid_t, &status: c_int, options: c_int) -> c_int;
    fn mkdir(s: str::sbuf, mode: c_int) -> c_int;
    fn rmdir(s: str::sbuf) -> c_int;
    fn chdir(s: str::sbuf) -> c_int;

    // FIXME: Needs varags
    fn fcntl(fd: fd_t, cmd: c_int) -> c_int;
}

mod libc_constants {
    const O_RDONLY: c_int    = 0i32;
    const O_WRONLY: c_int    = 1i32;
    const O_RDWR: c_int      = 2i32;
    const O_APPEND: c_int    = 8i32;
    const O_CREAT: c_int     = 512i32;
    const O_EXCL: c_int      = 2048i32;
    const O_TRUNC: c_int     = 1024i32;
    const O_TEXT: c_int      = 0i32;    // nonexistent in darwin libc
    const O_BINARY: c_int    = 0i32;    // nonexistent in darwin libc

    const S_IRUSR: unsigned  = 256u32;
    const S_IWUSR: unsigned  = 128u32;

    const F_FULLFSYNC: c_int = 51i32;
}

fn pipe() -> {in: fd_t, out: fd_t} {
    let fds = {mutable in: 0i32, mutable out: 0i32};
    assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0i32);
    ret {in: fds.in, out: fds.out};
}

fn fd_FILE(fd: fd_t) -> libc::FILE {
    ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) });
}

fn close(fd: fd_t) -> c_int {
    libc::close(fd)
}

fn fclose(file: libc::FILE) {
    libc::fclose(file)
}

fn waitpid(pid: pid_t) -> i32 {
    let status = 0i32;
    assert (os::libc::waitpid(pid, status, 0i32) != -1i32);
    ret status;
}

fn fsync_fd(fd: fd_t, level: io::fsync::level) -> c_int {
    alt level {
      io::fsync::fsync. { ret libc::fsync(fd); }
      _ {
        // According to man fnctl, the ok retval is only specified to be !=-1
        if (libc::fcntl(libc_constants::F_FULLFSYNC, fd) == -1 as c_int)
            { ret -1 as c_int; }
        else
            { ret 0 as c_int; }
      }
    }
}

#[abi = "cdecl"]
native mod rustrt {
    fn rust_getcwd() -> str;
}

fn getcwd() -> str { ret rustrt::rust_getcwd(); }

#[nolink]
#[abi = "cdecl"]
native mod mac_libc {
    fn _NSGetExecutablePath(buf: str::sbuf,
                            bufsize: *mutable uint32_t) -> c_int;
}

fn exec_suffix() -> str { ret ""; }

fn target_os() -> str { ret "macos"; }

fn dylib_filename(base: str) -> str { ret "lib" + base + ".dylib"; }

fn get_exe_path() -> option::t<fs::path> {
    // FIXME: This doesn't handle the case where the buffer is too small
    let bufsize = 1023u32;
    let path = str::unsafe_from_bytes(vec::init_elt(0u8, bufsize as uint));
    ret str::as_buf(path, { |path_buf|
        if mac_libc::_NSGetExecutablePath(path_buf,
                                          ptr::mut_addr_of(bufsize)) == 0i32 {
            option::some(fs::dirname(path) + fs::path_sep())
        } else {
            option::none
        }
    });
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before>use neb::ram::schema::Field;
use neb::ram::types::{TypeId, Id, key_hash, Map, Value};
use neb::ram::cell::{Cell, WriteError};
use neb::client::{Client as NebClient};
use neb::client::transaction::TxnError;
use bifrost::rpc::RPCError;

use server::schema::{MorpheusSchema, SchemaType, SchemaContainer, SchemaError};
use graph::vertex::Vertex;

use std::sync::Arc;
use serde::Serialize;

pub mod vertex;
pub mod edge;

pub enum NewVertexError {
    SchemaNotFound,
    SchemaNotVertex,
    CannotGenerateCellByData,
    DataNotMap,
    RPCError(RPCError),
    WriteError(WriteError),
}

#[derive(Clone, Copy, Serialize, Deserialize)]
pub enum CellType {
    Vertex,
    Edge(edge::EdgeType)
}

lazy_static! {
    pub static ref ID_LINKED_LIST: Vec<Field> = vec![
            Field::new(&String::from("next"), TypeId::Id as u32, true, false, None),
            Field::new(&String::from("list"), TypeId::Id as u32, false, true, None)
        ];
}

fn vertex_to_cell_for_write(schemas: &Arc<SchemaContainer>, vertex: Vertex) -> Result<Cell, NewVertexError> {
    let schema_id = vertex.schema;
    if let Some(stype) = schemas.schema_type(schema_id) {
        if stype != SchemaType::Vertex {
            return Err(NewVertexError::SchemaNotVertex)
        }
    } else {
        return Err(NewVertexError::SchemaNotFound)
    }
    let neb_schema = match schemas.get_neb_schema(schema_id) {
        Some(schema) => schema,
        None => return Err(NewVertexError::SchemaNotFound)
    };
    let mut data = {
        match vertex.data {
            Value::Map(mut map) => map,
            _ => return Err(NewVertexError::DataNotMap)
        }
    };
    data.insert_key_id(*vertex::INBOUND_KEY_ID, Value::Id(Id::unit_id()));
    data.insert_key_id(*vertex::OUTBOUND_KEY_ID, Value::Id(Id::unit_id()));
    data.insert_key_id(*vertex::INDIRECTED_KEY_ID, Value::Id(Id::unit_id()));
    match Cell::new(&neb_schema, Value::Map(data)) {
        Some(cell) => Ok(cell),
        None => return Err(NewVertexError::CannotGenerateCellByData)
    }
}

pub struct Graph {
    schemas: Arc<SchemaContainer>,
    neb_client: Arc<NebClient>
}

impl Graph {
    pub fn new_vertex_group(&self, schema: &mut MorpheusSchema) -> Result<(), SchemaError> {
        schema.schema_type = SchemaType::Vertex;
        self.schemas.new_schema(schema)
    }
    pub fn new_edge_group(&self, schema: &mut MorpheusSchema, edge_type: edge::EdgeType) -> Result<(), SchemaError> {
        if edge_type == edge::EdgeType::Simple {
            return Err(SchemaError::SimpleEdgeShouldNotHaveSchema)
        }
        schema.schema_type = SchemaType::Edge(edge_type);
        self.schemas.new_schema(schema)
    }
    pub fn new_vertex(&self, vertex: Vertex) -> Result<Vertex, NewVertexError> {
        let mut cell = vertex_to_cell_for_write(&self.schemas, vertex)?;
        let header = match self.neb_client.write_cell(&cell) {
            Ok(Ok(header)) => header,
            Ok(Err(e)) => return Err(NewVertexError::WriteError(e)),
            Err(e) => return Err(NewVertexError::RPCError(e))
        };
        cell.header = header;
        Ok(vertex::cell_to_vertex(cell))
    }
    // TODO: Update edge list
    pub fn remove_vertex(&self, id: &Id) -> Result<(), TxnError> {
        self.neb_client.transaction(|mut txn| {
            vertex::txn_remove(&mut txn, id)
        })
    }
    pub fn remove_vertex_by_key<K>(&self, schema_id: u32, key: &K) -> Result<(), TxnError>
        where K: Serialize {
        let id = Cell::encode_cell_key(schema_id, key);
        self.remove_vertex(&id)
    }
    pub fn update_vertex<U>(&self, id: &Id, update: U) -> Result<(), TxnError>
        where U: Fn(Vertex) -> Option<Vertex> {
        self.neb_client.transaction(|txn|{
            vertex::txn_update(txn, id, &update)
        })
    }
    pub fn update_vertex_by_key<K, U>(&self, schema_id: u32, key: &K, update: U)
        -> Result<(), TxnError>
        where K: Serialize, U: Fn(Vertex) -> Option<Vertex>{
        let id = Cell::encode_cell_key(schema_id, key);
        self.update_vertex(&id, update)
    }

}<commit_msg>read vertex<commit_after>use neb::ram::schema::Field;
use neb::ram::types::{TypeId, Id, key_hash, Map, Value};
use neb::ram::cell::{Cell, WriteError, ReadError};
use neb::client::{Client as NebClient};
use neb::client::transaction::TxnError;
use bifrost::rpc::RPCError;

use server::schema::{MorpheusSchema, SchemaType, SchemaContainer, SchemaError};
use graph::vertex::Vertex;

use std::sync::Arc;
use serde::Serialize;

pub mod vertex;
pub mod edge;

pub enum NewVertexError {
    SchemaNotFound,
    SchemaNotVertex,
    CannotGenerateCellByData,
    DataNotMap,
    RPCError(RPCError),
    WriteError(WriteError),
}

pub enum ReadVertexError {
    RPCError(RPCError),
    ReadError(ReadError),
}

#[derive(Clone, Copy, Serialize, Deserialize)]
pub enum CellType {
    Vertex,
    Edge(edge::EdgeType)
}

lazy_static! {
    pub static ref ID_LINKED_LIST: Vec<Field> = vec![
            Field::new(&String::from("next"), TypeId::Id as u32, true, false, None),
            Field::new(&String::from("list"), TypeId::Id as u32, false, true, None)
        ];
}

fn vertex_to_cell_for_write(schemas: &Arc<SchemaContainer>, vertex: Vertex) -> Result<Cell, NewVertexError> {
    let schema_id = vertex.schema;
    if let Some(stype) = schemas.schema_type(schema_id) {
        if stype != SchemaType::Vertex {
            return Err(NewVertexError::SchemaNotVertex)
        }
    } else {
        return Err(NewVertexError::SchemaNotFound)
    }
    let neb_schema = match schemas.get_neb_schema(schema_id) {
        Some(schema) => schema,
        None => return Err(NewVertexError::SchemaNotFound)
    };
    let mut data = {
        match vertex.data {
            Value::Map(mut map) => map,
            _ => return Err(NewVertexError::DataNotMap)
        }
    };
    data.insert_key_id(*vertex::INBOUND_KEY_ID, Value::Id(Id::unit_id()));
    data.insert_key_id(*vertex::OUTBOUND_KEY_ID, Value::Id(Id::unit_id()));
    data.insert_key_id(*vertex::INDIRECTED_KEY_ID, Value::Id(Id::unit_id()));
    match Cell::new(&neb_schema, Value::Map(data)) {
        Some(cell) => Ok(cell),
        None => return Err(NewVertexError::CannotGenerateCellByData)
    }
}

pub struct Graph {
    schemas: Arc<SchemaContainer>,
    neb_client: Arc<NebClient>
}

impl Graph {
    pub fn new_vertex_group(&self, schema: &mut MorpheusSchema) -> Result<(), SchemaError> {
        schema.schema_type = SchemaType::Vertex;
        self.schemas.new_schema(schema)
    }
    pub fn new_edge_group(&self, schema: &mut MorpheusSchema, edge_type: edge::EdgeType) -> Result<(), SchemaError> {
        if edge_type == edge::EdgeType::Simple {
            return Err(SchemaError::SimpleEdgeShouldNotHaveSchema)
        }
        schema.schema_type = SchemaType::Edge(edge_type);
        self.schemas.new_schema(schema)
    }
    pub fn new_vertex(&self, vertex: Vertex) -> Result<Vertex, NewVertexError> {
        let mut cell = vertex_to_cell_for_write(&self.schemas, vertex)?;
        let header = match self.neb_client.write_cell(&cell) {
            Ok(Ok(header)) => header,
            Ok(Err(e)) => return Err(NewVertexError::WriteError(e)),
            Err(e) => return Err(NewVertexError::RPCError(e))
        };
        cell.header = header;
        Ok(vertex::cell_to_vertex(cell))
    }
    // TODO: Update edge list
    pub fn remove_vertex(&self, id: &Id) -> Result<(), TxnError> {
        self.neb_client.transaction(|mut txn| {
            vertex::txn_remove(&mut txn, id)
        })
    }
    pub fn remove_vertex_by_key<K>(&self, schema_id: u32, key: &K) -> Result<(), TxnError>
        where K: Serialize {
        let id = Cell::encode_cell_key(schema_id, key);
        self.remove_vertex(&id)
    }
    pub fn update_vertex<U>(&self, id: &Id, update: U) -> Result<(), TxnError>
        where U: Fn(Vertex) -> Option<Vertex> {
        self.neb_client.transaction(|txn|{
            vertex::txn_update(txn, id, &update)
        })
    }
    pub fn update_vertex_by_key<K, U>(&self, schema_id: u32, key: &K, update: U)
        -> Result<(), TxnError>
        where K: Serialize, U: Fn(Vertex) -> Option<Vertex>{
        let id = Cell::encode_cell_key(schema_id, key);
        self.update_vertex(&id, update)
    }

    pub fn read_vertex(&self, id: &Id) -> Result<Option<Vertex>, ReadVertexError> {
        match self.neb_client.read_cell(id) {
            Err(e) => Err(ReadVertexError::RPCError(e)),
            Ok(Err(ReadError::CellDoesNotExisted)) => Ok(None),
            Ok(Err(e)) => Err(ReadVertexError::ReadError(e)),
            Ok(Ok(cell)) => Ok(Some(vertex::cell_to_vertex(cell)))
        }
    }
}<|endoftext|>


<commit_before>/// Module for 16 bit arithmetic (ALU instructions)

use gbe::cpu::CPU;

// ADD HL,BC 09 8
pub fn ADD_hl_bc(cpu: &mut CPU) {
    let rhs = cpu.reg.bc.get();
    cpu.compute_add16(rhs);
}

// ADD HL,DE 19 8
pub fn ADD_hl_de(cpu: &mut CPU) {
    let rhs = cpu.reg.de.get();
    cpu.compute_add16(rhs);
}

// ADD HL,HL 29 8
pub fn ADD_hl_hl(cpu: &mut CPU) {
    let rhs = cpu.reg.hl.get();
    cpu.compute_add16(rhs);
}

// ADD HL,SP 39 8
pub fn ADD_hl_sp(cpu: &mut CPU) {
    let rhs = cpu.reg.sp.get();
    cpu.compute_add16(rhs);
}
<commit_msg>Added remaining 16-bit ALU instructions<commit_after>/// Module for 16 bit arithmetic (ALU instructions)

use gbe::cpu::CPU;
use gbe::registers::Flags;

// ADD HL,BC 09 8
pub fn ADD_hl_bc(cpu: &mut CPU) {
    let rhs = cpu.reg.bc.get();
    cpu.compute_add16(rhs);
}

// ADD HL,DE 19 8
pub fn ADD_hl_de(cpu: &mut CPU) {
    let rhs = cpu.reg.de.get();
    cpu.compute_add16(rhs);
}

// ADD HL,HL 29 8
pub fn ADD_hl_hl(cpu: &mut CPU) {
    let rhs = cpu.reg.hl.get();
    cpu.compute_add16(rhs);
}

// ADD HL,SP 39 8
pub fn ADD_hl_sp(cpu: &mut CPU) {
    let rhs = cpu.reg.sp.get();
    cpu.compute_add16(rhs);
}

// ADD SP,# E8 16
pub fn ADD_sp_n(cpu: &mut CPU) {
    let value = cpu.get_immediate8() as u16;
    let sp = cpu.reg.sp.get();

    let result = sp.wrapping_add(value);

    // flags
    cpu.reg.clear_all_flags();

    if let None = sp.checked_add(value) {
        cpu.reg.set_flag(Flags::Carry);
    }

    if let None = (sp as u8).checked_add(value as u8) {
        cpu.reg.set_flag(Flags::HalfCarry);
    }

    cpu.reg.sp.set(sp);
}

// INC BC 03 8
pub fn INC_bc(cpu: &mut CPU) {
    cpu.reg.bc.add(1);
}

// INC DE 13 8
pub fn INC_de(cpu: &mut CPU) {
    cpu.reg.de.add(1);
}

// INC HL 23 8
pub fn INC_hl(cpu: &mut CPU) {
    cpu.reg.hl.add(1);
}

// INC SP 33 8
pub fn INC_sp(cpu: &mut CPU) {
    cpu.reg.sp.add(1);
}

// DEC BC 0B 8
pub fn DEC_bc(cpu: &mut CPU) {
    cpu.reg.bc.sub(1);
}

// DEC DE 1B 8
pub fn DEC_de(cpu: &mut CPU) {
    cpu.reg.de.sub(1);
}

// DEC HL 2B 8
pub fn DEC_hl(cpu: &mut CPU) {
    cpu.reg.hl.sub(1);
}

// DEC SP 3B 8
pub fn DEC_sp(cpu: &mut CPU) {
    cpu.reg.sp.sub(1);
}
<|endoftext|>