<commit_before>//! FFI bindings to the wayland system libraries.
//!
//! The names exported by this crate should *not* be used directly, but though
//! the `ffi_dispatch` macro like this:
//!
//! ```ignore
//! ffi_dispatch!(HANDLE_NAME, func_name, arg1, arg2, arg3);
//! ```
//!
//! Where `HANDLE_NAME` is the name of the handle generated if the cargo feature
//! `dlopen` is on.
//!
//! For this to work, you must ensure every needed symbol is in scope (aka the static handle
//! if `dlopen` is on, the extern function if not). The easiest way to do this is to glob import
//! the appropriate module. For example:
//!
//! ```no_run
//! #[macro_use] extern crate wayland_sys;
//!
//! use wayland_sys::client::*;
//!
//! fn main() {
//!     let display_ptr = unsafe {
//!         ffi_dispatch!(WAYLAND_CLIENT_HANDLE, wl_display_connect, ::std::ptr::null())
//!     };
//! }
//! ```
//!
//! Each module except `common` corresponds to a system library. They all define a function named
//! `is_lib_available()` which returns a boolean depending on whether the lib could be loaded.
//! They always return true if the feature `dlopen` is absent, as the lib is then directly linked.

#![allow(dead_code, non_camel_case_types)]

#[macro_use]
extern crate dlib;

#[cfg(feature = "dlopen")]
#[macro_use]
extern crate lazy_static;

#[cfg(feature = "server")]
extern crate libc;

/// Magic pointer for wayland objects managed by wayland-client or wayland-server
///
/// This static serves no purpose other than existing, and thus providing a stable pointer
/// to something we know what it is.
///
/// It is used internally by wayland-client, wayland-server and wayland-scanner to ensure safety
/// regarding to wayland objects that are created by some other library.
pub static RUST_MANAGED: u8 = 42;

pub mod common;

#[cfg(feature = "client")]
pub mod client;

#[cfg(feature = "server")]
pub mod server;

#[cfg(all(feature = "egl", feature = "client"))]
pub mod egl;

#[cfg(all(feature = "cursor", feature = "client"))]
pub mod cursor;

#[cfg(feature = "server")]
pub use libc::{gid_t, pid_t, uid_t};

// Small hack while #[macro_reexport] is not stable

#[cfg(feature = "dlopen")]
#[macro_export]
macro_rules! ffi_dispatch(
    ($handle: ident, $func: ident, $($arg: expr),*) => (
        ($handle.$func)($($arg),*)
    )
);

#[cfg(not(feature = "dlopen"))]
#[macro_export]
macro_rules! ffi_dispatch(
    ($handle: ident, $func: ident, $($arg: expr),*) => (
        $func($($arg),*)
    )
);
<commit_msg>sys: don't test lib example which fails on missing feature<commit_after>//! FFI bindings to the wayland system libraries.
//!
//! The names exported by this crate should *not* be used directly, but though
//! the `ffi_dispatch` macro like this:
//!
//! ```ignore
//! ffi_dispatch!(HANDLE_NAME, func_name, arg1, arg2, arg3);
//! ```
//!
//! Where `HANDLE_NAME` is the name of the handle generated if the cargo feature
//! `dlopen` is on.
//!
//! For this to work, you must ensure every needed symbol is in scope (aka the static handle
//! if `dlopen` is on, the extern function if not). The easiest way to do this is to glob import
//! the appropriate module. For example:
//!
//! ```ignore
//! #[macro_use] extern crate wayland_sys;
//!
//! use wayland_sys::client::*;
//!
//! fn main() {
//!     let display_ptr = unsafe {
//!         ffi_dispatch!(WAYLAND_CLIENT_HANDLE, wl_display_connect, ::std::ptr::null())
//!     };
//! }
//! ```
//!
//! Each module except `common` corresponds to a system library. They all define a function named
//! `is_lib_available()` which returns a boolean depending on whether the lib could be loaded.
//! They always return true if the feature `dlopen` is absent, as the lib is then directly linked.

#![allow(dead_code, non_camel_case_types)]

#[macro_use]
extern crate dlib;

#[cfg(feature = "dlopen")]
#[macro_use]
extern crate lazy_static;

#[cfg(feature = "server")]
extern crate libc;

/// Magic pointer for wayland objects managed by wayland-client or wayland-server
///
/// This static serves no purpose other than existing, and thus providing a stable pointer
/// to something we know what it is.
///
/// It is used internally by wayland-client, wayland-server and wayland-scanner to ensure safety
/// regarding to wayland objects that are created by some other library.
pub static RUST_MANAGED: u8 = 42;

pub mod common;

#[cfg(feature = "client")]
pub mod client;

#[cfg(feature = "server")]
pub mod server;

#[cfg(all(feature = "egl", feature = "client"))]
pub mod egl;

#[cfg(all(feature = "cursor", feature = "client"))]
pub mod cursor;

#[cfg(feature = "server")]
pub use libc::{gid_t, pid_t, uid_t};

// Small hack while #[macro_reexport] is not stable

#[cfg(feature = "dlopen")]
#[macro_export]
macro_rules! ffi_dispatch(
    ($handle: ident, $func: ident, $($arg: expr),*) => (
        ($handle.$func)($($arg),*)
    )
);

#[cfg(not(feature = "dlopen"))]
#[macro_export]
macro_rules! ffi_dispatch(
    ($handle: ident, $func: ident, $($arg: expr),*) => (
        $func($($arg),*)
    )
);
<|endoftext|>


<commit_before>extern crate getopts;

use std::path::PathBuf;

pub fn build_opts() -> getopts::Options {
    let mut opts = getopts::Options::new();
    opts.optopt(
        "n",
        "",
        "Number of passphrases to generate (default 1)",
        "NUM",
    );
    opts.optopt("e", "", "Minimum entropy (default 60)", "MINENTROPY");
    opts.optopt("l", "", "NGram length (default 3, must be > 1)", "LENGTH");
    opts.optopt(
        "w",
        "",
        "Minimum word length for corpus (default 5)",
        "LENGTH",
    );
    opts.optflag("h", "help", "Display this help and exit");

    opts
}

pub fn parse_args(
    opts: &getopts::Options,
    args: &Vec<String>,
) -> Result<(Option<PathBuf>, usize, f64, usize, usize), &'static str> {
    let matches = opts
        .parse(&args[1..])
        .map_err(|_| "Failed to parse arguments.")?;

    if matches.opt_present("h") || matches.free.len() > 1 {
        return Err("Failed to parse arguments.");
    };

    let number = parse_flag_or_default(&matches, "n", 1)?;
    let min_entropy = parse_flag_or_default(&matches, "e", 60.0)?;
    let ngram_length = parse_flag_or_default(&matches, "l", 3)?;
    let min_word_length = parse_flag_or_default(&matches, "w", 5)?;

    if ngram_length < 2 {
        return Err("Ngram length must be greater than one.");
    };

    let filename = if matches.free.is_empty() || matches.free[0] == "-" {
        None
    } else {
        Some(PathBuf::from(matches.free[0].clone()))
    };

    Ok((filename, number, min_entropy, ngram_length, min_word_length))
}

pub fn print_usage(program: &str, opts: &getopts::Options) {
    let brief = format!("Usage: {} [FILE] [options]", program);
    print!("{}", opts.usage(&brief));
}

fn parse_flag_or_default<T: ::std::str::FromStr>(
    matches: &getopts::Matches,
    flag: &str,
    default: T,
) -> Result<T, &'static str> {
    matches
        .opt_str(flag)
        .map(|c| c.parse::<T>())
        .unwrap_or(Ok(default))
        .map_err(|_| "Failed to parse flag.")
}
<commit_msg>Move default args into constants<commit_after>extern crate getopts;

use std::path::PathBuf;

const DEFAULT_NUMBER: usize = 1;
const DEFAULT_MIN_ENTROPY: f64 = 60.0;
const DEFAULT_NGRAM_LENGTH: usize = 3;
const DEFAULT_MIN_WORD_LENGTH: usize = 5;

pub fn build_opts() -> getopts::Options {
    let mut opts = getopts::Options::new();
    opts.optopt(
        "n",
        "",
        &format!(
            "Number of passphrases to generate (default {})",
            DEFAULT_NUMBER
        ),
        "NUM",
    );
    opts.optopt(
        "e",
        "",
        &format!("Minimum entropy (default {})", DEFAULT_MIN_ENTROPY),
        "MINENTROPY",
    );
    opts.optopt(
        "l",
        "",
        &format!(
            "NGram length (default {}, must be > 1)",
            DEFAULT_NGRAM_LENGTH
        ),
        "LENGTH",
    );
    opts.optopt(
        "w",
        "",
        &format!(
            "Minimum word length for corpus (default {})",
            DEFAULT_MIN_WORD_LENGTH
        ),
        "LENGTH",
    );
    opts.optflag("h", "help", "Display this help and exit");

    opts
}

pub fn parse_args(
    opts: &getopts::Options,
    args: &Vec<String>,
) -> Result<(Option<PathBuf>, usize, f64, usize, usize), &'static str> {
    let matches = opts
        .parse(&args[1..])
        .map_err(|_| "Failed to parse arguments.")?;

    if matches.opt_present("h") || matches.free.len() > 1 {
        return Err("Failed to parse arguments.");
    };

    let number = parse_flag_or_default(&matches, "n", DEFAULT_NUMBER)?;
    let min_entropy = parse_flag_or_default(&matches, "e", DEFAULT_MIN_ENTROPY)?;
    let ngram_length = parse_flag_or_default(&matches, "l", DEFAULT_NGRAM_LENGTH)?;
    let min_word_length = parse_flag_or_default(&matches, "w", DEFAULT_MIN_WORD_LENGTH)?;

    if ngram_length < 2 {
        return Err("Ngram length must be greater than one.");
    };

    let filename = if matches.free.is_empty() || matches.free[0] == "-" {
        None
    } else {
        Some(PathBuf::from(matches.free[0].clone()))
    };

    Ok((filename, number, min_entropy, ngram_length, min_word_length))
}

pub fn print_usage(program: &str, opts: &getopts::Options) {
    let brief = format!("Usage: {} [FILE] [options]", program);
    print!("{}", opts.usage(&brief));
}

fn parse_flag_or_default<T: ::std::str::FromStr>(
    matches: &getopts::Matches,
    flag: &str,
    default: T,
) -> Result<T, &'static str> {
    matches
        .opt_str(flag)
        .map(|c| c.parse::<T>())
        .unwrap_or(Ok(default))
        .map_err(|_| "Failed to parse flag.")
}
<|endoftext|>


<commit_before>/*!
This atty module contains functions for detecting whether ripgrep is being fed
from (or to) a terminal. Windows and Unix do this differently, so implement
both here.
*/

#[cfg(unix)]
pub fn stdin_is_readable() -> bool {
    use std::fs::File;
    use std::os::unix::fs::FileTypeExt;
    use std::os::unix::io::{FromRawFd, IntoRawFd};
    use libc;

    let file = unsafe { File::from_raw_fd(libc::STDIN_FILENO) };
    let md = file.metadata();
    let _ = file.into_raw_fd();
    let ft = match md {
        Err(_) => return false,
        Ok(md) => md.file_type(),
    };
    ft.is_file() || ft.is_fifo()
}

#[cfg(windows)]
pub fn stdin_is_readable() -> bool {
    // ???
    true
}

#[cfg(unix)]
pub fn on_stdin() -> bool {
    use libc;
    0 < unsafe { libc::isatty(libc::STDIN_FILENO) }
}

#[cfg(unix)]
pub fn on_stdout() -> bool {
    use libc;
    0 < unsafe { libc::isatty(libc::STDOUT_FILENO) }
}

#[cfg(windows)]
pub fn on_stdin() -> bool {
    use kernel32;
    use winapi;

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

#[cfg(windows)]
pub fn on_stdout() -> bool {
    use kernel32;
    use winapi;

    unsafe {
        let fd = winapi::winbase::STD_OUTPUT_HANDLE;
        let mut out = 0;
        kernel32::GetConsoleMode(kernel32::GetStdHandle(fd), &mut out) != 0
    }
}
<commit_msg>On Windows, always consider stdin to be a tty.<commit_after>/*!
This atty module contains functions for detecting whether ripgrep is being fed
from (or to) a terminal. Windows and Unix do this differently, so implement
both here.
*/

#[cfg(unix)]
pub fn stdin_is_readable() -> bool {
    use std::fs::File;
    use std::os::unix::fs::FileTypeExt;
    use std::os::unix::io::{FromRawFd, IntoRawFd};
    use libc;

    let file = unsafe { File::from_raw_fd(libc::STDIN_FILENO) };
    let md = file.metadata();
    let _ = file.into_raw_fd();
    let ft = match md {
        Err(_) => return false,
        Ok(md) => md.file_type(),
    };
    ft.is_file() || ft.is_fifo()
}

#[cfg(windows)]
pub fn stdin_is_readable() -> bool {
    // ???
    true
}

/// Returns true if there is a tty on stdin.
#[cfg(unix)]
pub fn on_stdin() -> bool {
    use libc;
    0 < unsafe { libc::isatty(libc::STDIN_FILENO) }
}

/// Returns true if there is a tty on stdout.
#[cfg(unix)]
pub fn on_stdout() -> bool {
    use libc;
    0 < unsafe { libc::isatty(libc::STDOUT_FILENO) }
}

/// Returns true if there is a tty on stdin.
#[cfg(windows)]
pub fn on_stdin() -> bool {
    // BUG: https://github.com/BurntSushi/ripgrep/issues/19
    // It's not clear to me how to determine whether there is a tty on stdin.
    // Checking GetConsoleMode(GetStdHandle(stdin)) != 0 appears to report
    // that stdin is a pipe, even if it's not in a cygwin terminal, for
    // example.
    //
    // To fix this, we just assume there is always a tty on stdin. If Windows
    // users need to search stdin, they'll have to pass -. Ug.
    true
}

/// Returns true if there is a tty on stdout.
#[cfg(windows)]
pub fn on_stdout() -> bool {
    use kernel32;
    use winapi;

    unsafe {
        let fd = winapi::winbase::STD_OUTPUT_HANDLE;
        let mut out = 0;
        kernel32::GetConsoleMode(kernel32::GetStdHandle(fd), &mut out) != 0
    }
}
<|endoftext|>


<commit_before>
const KERNEL: [f32; 9] = [
    1./16., 2./16., 1./16.,
    2./16., 4./16., 2./16.,
    1./16., 2./16., 1./16.,
];

#[cfg(target_os = "macos")]
mod mac {
    use imgref::*;
    use std;
    use ffi::vImage_Buffer;
    use ffi::vImagePixelCount;
    use ffi::vImageConvolve_PlanarF;
    use ffi::vImage_Flags::kvImageEdgeExtend;
    use super::KERNEL;

    pub fn blur(src: ImgRef<f32>, tmp: &mut [f32], dst: ImgRefMut<f32>) {
        let srcbuf = vImage_Buffer {
            width: src.width() as vImagePixelCount,
            height: src.height() as vImagePixelCount,
            rowBytes: src.stride() * std::mem::size_of::<f32>(),
            data: src.buf.as_ptr(),
        };
        let mut dstbuf = vImage_Buffer {
            width: dst.width() as vImagePixelCount,
            height: dst.height() as vImagePixelCount,
            rowBytes: dst.stride() * std::mem::size_of::<f32>(),
            data: dst.buf.as_mut_ptr(),
        };

        do_blur(&srcbuf, tmp, &mut dstbuf, src.width(), src.height());
    }

    pub fn blur_in_place(srcdst: ImgRefMut<f32>, tmp: &mut [f32]) {
        let srcbuf = vImage_Buffer {
            width: srcdst.width() as vImagePixelCount,
            height: srcdst.height() as vImagePixelCount,
            rowBytes: srcdst.stride() * std::mem::size_of::<f32>(),
            data: srcdst.buf.as_ptr(),
        };
        let mut dstbuf = vImage_Buffer {
            width: srcdst.width() as vImagePixelCount,
            height: srcdst.height() as vImagePixelCount,
            rowBytes: srcdst.stride() * std::mem::size_of::<f32>(),
            data: srcdst.buf.as_mut_ptr(),
        };

        do_blur(&srcbuf, tmp, &mut dstbuf, srcdst.width(), srcdst.height());
    }

    pub fn do_blur(srcbuf: &vImage_Buffer<*const f32>, tmp: &mut [f32], dstbuf: &mut vImage_Buffer<*mut f32>, width: usize, height: usize) {
        assert_eq!(tmp.len(), width * height);

        unsafe {
            let mut tmpwrbuf = vImage_Buffer {
                width: width as vImagePixelCount,
                height: height as vImagePixelCount,
                rowBytes: width * std::mem::size_of::<f32>(),
                data: tmp.as_mut_ptr(),
            };
            let res = vImageConvolve_PlanarF(srcbuf, &mut tmpwrbuf, std::ptr::null_mut(), 0, 0, KERNEL.as_ptr(), 3, 3, 0., kvImageEdgeExtend);
            assert_eq!(0, res);

            let tmprbuf = vImage_Buffer {
                width: width as vImagePixelCount,
                height: height as vImagePixelCount,
                rowBytes: width * std::mem::size_of::<f32>(),
                data: tmp.as_ptr(),
            };
            let res = vImageConvolve_PlanarF(&tmprbuf, dstbuf, std::ptr::null_mut(), 0, 0, KERNEL.as_ptr(), 3, 3, 0., kvImageEdgeExtend);
            assert_eq!(0, res);
        }
    }
}

#[cfg(not(target_os = "macos"))]
mod portable {
    use imgref::*;

    use std::cmp::min;
    use super::KERNEL;

    #[inline]
    fn do3f(prev: &[f32], curr: &[f32], next: &[f32], i: usize) -> f32 {
        debug_assert!(i > 0);

        let c0 = i-1;
        let c1 = i;
        let c2 = i+1;

        unsafe {
            prev.get_unchecked(c0)*KERNEL[0] + prev.get_unchecked(c1)*KERNEL[1] + prev.get_unchecked(c2)*KERNEL[2] +
            curr.get_unchecked(c0)*KERNEL[3] + curr.get_unchecked(c1)*KERNEL[4] + curr.get_unchecked(c2)*KERNEL[5] +
            next.get_unchecked(c0)*KERNEL[6] + next.get_unchecked(c1)*KERNEL[7] + next.get_unchecked(c2)*KERNEL[8]
        }
    }

    fn do3(prev: &[f32], curr: &[f32], next: &[f32], i: usize, width: usize) -> f32 {
        let c0 = if i > 0 {i-1} else {0};
        let c1 = i;
        let c2 = min(i+1, width-1);

        prev[c0]*KERNEL[0] + prev[c1]*KERNEL[1] + prev[c2]*KERNEL[2] +
        curr[c0]*KERNEL[3] + curr[c1]*KERNEL[4] + curr[c2]*KERNEL[5] +
        next[c0]*KERNEL[6] + next[c1]*KERNEL[7] + next[c2]*KERNEL[8]
    }

    pub fn blur(src: ImgRef<f32>, tmp: &mut [f32], dst: ImgRefMut<f32>) {
        {
            let tmp_dst = ImgRefMut::new(tmp, dst.width(), dst.height());
            do_blur(src, tmp_dst);
        }
        let tmp_src = ImgRef::new(tmp, src.width(), src.height());
        do_blur(tmp_src, dst);
    }

    pub fn do_blur(src: ImgRef<f32>, dst: ImgRefMut<f32>) {
        assert_eq!(src.width(), dst.width());
        assert_eq!(src.height(), dst.height());
        assert!(src.width() > 0);
        assert!(src.width() < 1<<24);
        assert!(src.height() > 0);
        assert!(src.height() < 1<<24);
        debug_assert!(src.pixels().all(|p| p.is_finite()));

        let width = src.width();
        let height = src.height();
        let src_stride = src.stride();
        let dst_stride = dst.stride();
        let src = &src.buf[..];
        let dst = &mut dst.buf[..];

        let mut prev = &src[0..width];
        let mut curr = prev;
        let mut next = prev;
        for y in 0..height {
            prev = curr;
            curr = next;
            let next_start = (y+1)*src_stride;
            next = if y+1 < height {&src[next_start..next_start+width]} else {curr};

            let mut dstrow = &mut dst[y*dst_stride..y*dst_stride+width];

            dstrow[0] = do3(prev, curr, next, 0, width);
            for i in 1..width-1 {
                dstrow[i] = do3f(prev, curr, next, i);
            }
            if width > 1 {
                dstrow[width-1] = do3(prev, curr, next, width-1, width);
            }
        }
    }

    pub fn blur_in_place(srcdst: ImgRefMut<f32>, tmp: &mut [f32]) {
        {
            let tmp_dst = ImgRefMut::new(tmp, srcdst.width(), srcdst.height());
            do_blur(srcdst.new_buf(&srcdst.buf[..]), tmp_dst);
        }
        let tmp_src = ImgRef::new(tmp, srcdst.width(), srcdst.height());
        do_blur(tmp_src, srcdst);
    }
}

#[cfg(target_os = "macos")]
pub use self::mac::*;

#[cfg(not(target_os = "macos"))]
pub use self::portable::*;

#[cfg(test)]
use imgref::*;

#[test]
fn blur_zero() {
    let src = vec![0.25];

    let mut tmp = vec![-55.; 1];
    let mut dst = vec![-99.; 1];

    let mut src2 = src.clone();

    blur(ImgRef::new(&src[..], 1,1), &mut tmp[..], ImgRefMut::new(&mut dst[..], 1, 1));
    blur_in_place(ImgRefMut::new(&mut src2[..], 1, 1), &mut tmp[..]);

    assert_eq!(src2, dst);
    assert_eq!(0.25, dst[0]);
}

#[test]
fn blur_one() {
    blur_one_compare(Img::new(vec![
        0.,0.,0.,0.,0.,
        0.,0.,0.,0.,0.,
        0.,0.,1.,0.,0.,
        0.,0.,0.,0.,0.,
        0.,0.,0.,0.,0.,
    ], 5, 5));
}

#[test]
fn blur_one_stride() {
    let nan = 1./0.;
    blur_one_compare(Img::new_stride(vec![
        0.,0.,0.,0.,0., nan, -11.,
        0.,0.,0.,0.,0., 333., nan,
        0.,0.,1.,0.,0., nan, -11.,
        0.,0.,0.,0.,0., 333., nan,
        0.,0.,0.,0.,0., nan,
    ], 5, 5, 7));
}

#[cfg(test)]
fn blur_one_compare(src: ImgVec<f32>) {
    let mut tmp = vec![-55.; 5*5];
    let mut dst = vec![999.; 5*5];

    let mut src2 = src.clone();

    blur(src.as_ref(), &mut tmp[..], ImgRefMut::new(&mut dst[..], 5, 5));
    blur_in_place(src2.as_mut(), &mut tmp[..]);

    assert_eq!(src2.pixels().collect::<Vec<_>>(), dst);

    assert_eq!(1./256., dst[0]);
    assert_eq!(1./256., dst[5*5-1]);
    let center = 1./16.*1./16. + 2./16.*2./16. + 1./16.*1./16. +
                 2./16.*2./16. + 4./16.*4./16. + 2./16.*2./16. +
                 1./16.*1./16. + 2./16.*2./16. + 1./16.*1./16.;
    assert_eq!(center, dst[2*5+2]);
}

#[test]
fn blur_two() {
    let src = vec![
    0.,1.,1.,1.,
    1.,1.,1.,1.,
    1.,1.,1.,1.,
    1.,1.,1.,1.,
    ];
    let mut tmp = vec![-55.; 4*4];
    let mut dst = vec![999.; 4*4];

    let mut src2 = src.clone();

    blur(ImgRef::new(&src[..], 4,4), &mut tmp[..], ImgRefMut::new(&mut dst[..], 4, 4));
    blur_in_place(ImgRefMut::new(&mut src2[..], 4,4), &mut tmp[..]);

    assert_eq!(src2, dst);

    let z00 = 0.*1./16. + 0.*2./16. + 1.*1./16. +
              0.*2./16. + 0.*4./16. + 1.*2./16. +
              1.*1./16. + 1.*2./16. + 1.*1./16.;
    let z01 =                                   0.*1./16. + 1.*2./16. + 1.*1./16. +
                                                0.*2./16. + 1.*4./16. + 1.*2./16. +
                                                1.*1./16. + 1.*2./16. + 1.*1./16.;

    let z10 = 0.*1./16. + 0.*2./16. + 1.*1./16. +
              1.*2./16. + 1.*4./16. + 1.*2./16. +
              1.*1./16. + 1.*2./16. + 1.*1./16.;
    let z11 =                                   0.*1./16. + 1.*2./16. + 1.*1./16. +
                                                1.*2./16. + 1.*4./16. + 1.*2./16. +
                                                1.*1./16. + 1.*2./16. + 1.*1./16.;
    let exp = z00*1./16. + z00*2./16. + z01*1./16. +
              z00*2./16. + z00*4./16. + z01*2./16. +
              z10*1./16. + z10*2./16. + z11*1./16.;

    assert_eq!(1., dst[3]);
    assert_eq!(1., dst[3 * 4]);
    assert_eq!(1., dst[4 * 4 - 1]);
    assert_eq!(exp, dst[0]);
}
<commit_msg>Use Gaussian filter with standard deviation of 1.5<commit_after>
const KERNEL: [f32; 9] = [
    0.095332, 0.118095, 0.095332,
    0.118095, 0.146293, 0.118095,
    0.095332, 0.118095, 0.095332,
];

#[cfg(target_os = "macos")]
mod mac {
    use imgref::*;
    use std;
    use ffi::vImage_Buffer;
    use ffi::vImagePixelCount;
    use ffi::vImageConvolve_PlanarF;
    use ffi::vImage_Flags::kvImageEdgeExtend;
    use super::KERNEL;

    pub fn blur(src: ImgRef<f32>, tmp: &mut [f32], dst: ImgRefMut<f32>) {
        let srcbuf = vImage_Buffer {
            width: src.width() as vImagePixelCount,
            height: src.height() as vImagePixelCount,
            rowBytes: src.stride() * std::mem::size_of::<f32>(),
            data: src.buf.as_ptr(),
        };
        let mut dstbuf = vImage_Buffer {
            width: dst.width() as vImagePixelCount,
            height: dst.height() as vImagePixelCount,
            rowBytes: dst.stride() * std::mem::size_of::<f32>(),
            data: dst.buf.as_mut_ptr(),
        };

        do_blur(&srcbuf, tmp, &mut dstbuf, src.width(), src.height());
    }

    pub fn blur_in_place(srcdst: ImgRefMut<f32>, tmp: &mut [f32]) {
        let srcbuf = vImage_Buffer {
            width: srcdst.width() as vImagePixelCount,
            height: srcdst.height() as vImagePixelCount,
            rowBytes: srcdst.stride() * std::mem::size_of::<f32>(),
            data: srcdst.buf.as_ptr(),
        };
        let mut dstbuf = vImage_Buffer {
            width: srcdst.width() as vImagePixelCount,
            height: srcdst.height() as vImagePixelCount,
            rowBytes: srcdst.stride() * std::mem::size_of::<f32>(),
            data: srcdst.buf.as_mut_ptr(),
        };

        do_blur(&srcbuf, tmp, &mut dstbuf, srcdst.width(), srcdst.height());
    }

    pub fn do_blur(srcbuf: &vImage_Buffer<*const f32>, tmp: &mut [f32], dstbuf: &mut vImage_Buffer<*mut f32>, width: usize, height: usize) {
        assert_eq!(tmp.len(), width * height);

        unsafe {
            let mut tmpwrbuf = vImage_Buffer {
                width: width as vImagePixelCount,
                height: height as vImagePixelCount,
                rowBytes: width * std::mem::size_of::<f32>(),
                data: tmp.as_mut_ptr(),
            };
            let res = vImageConvolve_PlanarF(srcbuf, &mut tmpwrbuf, std::ptr::null_mut(), 0, 0, KERNEL.as_ptr(), 3, 3, 0., kvImageEdgeExtend);
            assert_eq!(0, res);

            let tmprbuf = vImage_Buffer {
                width: width as vImagePixelCount,
                height: height as vImagePixelCount,
                rowBytes: width * std::mem::size_of::<f32>(),
                data: tmp.as_ptr(),
            };
            let res = vImageConvolve_PlanarF(&tmprbuf, dstbuf, std::ptr::null_mut(), 0, 0, KERNEL.as_ptr(), 3, 3, 0., kvImageEdgeExtend);
            assert_eq!(0, res);
        }
    }
}

#[cfg(not(target_os = "macos"))]
mod portable {
    use imgref::*;

    use std::cmp::min;
    use super::KERNEL;

    #[inline]
    fn do3f(prev: &[f32], curr: &[f32], next: &[f32], i: usize) -> f32 {
        debug_assert!(i > 0);

        let c0 = i-1;
        let c1 = i;
        let c2 = i+1;

        unsafe {
            prev.get_unchecked(c0)*KERNEL[0] + prev.get_unchecked(c1)*KERNEL[1] + prev.get_unchecked(c2)*KERNEL[2] +
            curr.get_unchecked(c0)*KERNEL[3] + curr.get_unchecked(c1)*KERNEL[4] + curr.get_unchecked(c2)*KERNEL[5] +
            next.get_unchecked(c0)*KERNEL[6] + next.get_unchecked(c1)*KERNEL[7] + next.get_unchecked(c2)*KERNEL[8]
        }
    }

    fn do3(prev: &[f32], curr: &[f32], next: &[f32], i: usize, width: usize) -> f32 {
        let c0 = if i > 0 {i-1} else {0};
        let c1 = i;
        let c2 = min(i+1, width-1);

        prev[c0]*KERNEL[0] + prev[c1]*KERNEL[1] + prev[c2]*KERNEL[2] +
        curr[c0]*KERNEL[3] + curr[c1]*KERNEL[4] + curr[c2]*KERNEL[5] +
        next[c0]*KERNEL[6] + next[c1]*KERNEL[7] + next[c2]*KERNEL[8]
    }

    pub fn blur(src: ImgRef<f32>, tmp: &mut [f32], dst: ImgRefMut<f32>) {
        {
            let tmp_dst = ImgRefMut::new(tmp, dst.width(), dst.height());
            do_blur(src, tmp_dst);
        }
        let tmp_src = ImgRef::new(tmp, src.width(), src.height());
        do_blur(tmp_src, dst);
    }

    pub fn do_blur(src: ImgRef<f32>, dst: ImgRefMut<f32>) {
        assert_eq!(src.width(), dst.width());
        assert_eq!(src.height(), dst.height());
        assert!(src.width() > 0);
        assert!(src.width() < 1<<24);
        assert!(src.height() > 0);
        assert!(src.height() < 1<<24);
        debug_assert!(src.pixels().all(|p| p.is_finite()));

        let width = src.width();
        let height = src.height();
        let src_stride = src.stride();
        let dst_stride = dst.stride();
        let src = &src.buf[..];
        let dst = &mut dst.buf[..];

        let mut prev = &src[0..width];
        let mut curr = prev;
        let mut next = prev;
        for y in 0..height {
            prev = curr;
            curr = next;
            let next_start = (y+1)*src_stride;
            next = if y+1 < height {&src[next_start..next_start+width]} else {curr};

            let mut dstrow = &mut dst[y*dst_stride..y*dst_stride+width];

            dstrow[0] = do3(prev, curr, next, 0, width);
            for i in 1..width-1 {
                dstrow[i] = do3f(prev, curr, next, i);
            }
            if width > 1 {
                dstrow[width-1] = do3(prev, curr, next, width-1, width);
            }
        }
    }

    pub fn blur_in_place(srcdst: ImgRefMut<f32>, tmp: &mut [f32]) {
        {
            let tmp_dst = ImgRefMut::new(tmp, srcdst.width(), srcdst.height());
            do_blur(srcdst.new_buf(&srcdst.buf[..]), tmp_dst);
        }
        let tmp_src = ImgRef::new(tmp, srcdst.width(), srcdst.height());
        do_blur(tmp_src, srcdst);
    }
}

#[cfg(target_os = "macos")]
pub use self::mac::*;

#[cfg(not(target_os = "macos"))]
pub use self::portable::*;

#[cfg(test)]
use imgref::*;

#[test]
fn blur_zero() {
    let src = vec![0.25];

    let mut tmp = vec![-55.; 1];
    let mut dst = vec![-99.; 1];

    let mut src2 = src.clone();

    blur(ImgRef::new(&src[..], 1,1), &mut tmp[..], ImgRefMut::new(&mut dst[..], 1, 1));
    blur_in_place(ImgRefMut::new(&mut src2[..], 1, 1), &mut tmp[..]);

    assert_eq!(src2, dst);
    assert_eq!(0.25, dst[0]);
}

#[test]
fn blur_one() {
    blur_one_compare(Img::new(vec![
        0.,0.,0.,0.,0.,
        0.,0.,0.,0.,0.,
        0.,0.,1.,0.,0.,
        0.,0.,0.,0.,0.,
        0.,0.,0.,0.,0.,
    ], 5, 5));
}

#[test]
fn blur_one_stride() {
    let nan = 1./0.;
    blur_one_compare(Img::new_stride(vec![
        0.,0.,0.,0.,0., nan, -11.,
        0.,0.,0.,0.,0., 333., nan,
        0.,0.,1.,0.,0., nan, -11.,
        0.,0.,0.,0.,0., 333., nan,
        0.,0.,0.,0.,0., nan,
    ], 5, 5, 7));
}

#[cfg(test)]
fn blur_one_compare(src: ImgVec<f32>) {
    let mut tmp = vec![-55.; 5*5];
    let mut dst = vec![999.; 5*5];

    let mut src2 = src.clone();

    blur(src.as_ref(), &mut tmp[..], ImgRefMut::new(&mut dst[..], 5, 5));
    blur_in_place(src2.as_mut(), &mut tmp[..]);

    assert_eq!(src2.pixels().collect::<Vec<_>>(), dst);

    assert_eq!(1./256., dst[0]);
    assert_eq!(1./256., dst[5*5-1]);
    let center = 1./16.*1./16. + 2./16.*2./16. + 1./16.*1./16. +
                 2./16.*2./16. + 4./16.*4./16. + 2./16.*2./16. +
                 1./16.*1./16. + 2./16.*2./16. + 1./16.*1./16.;
    assert_eq!(center, dst[2*5+2]);
}

#[test]
fn blur_two() {
    let src = vec![
    0.,1.,1.,1.,
    1.,1.,1.,1.,
    1.,1.,1.,1.,
    1.,1.,1.,1.,
    ];
    let mut tmp = vec![-55.; 4*4];
    let mut dst = vec![999.; 4*4];

    let mut src2 = src.clone();

    blur(ImgRef::new(&src[..], 4,4), &mut tmp[..], ImgRefMut::new(&mut dst[..], 4, 4));
    blur_in_place(ImgRefMut::new(&mut src2[..], 4,4), &mut tmp[..]);

    assert_eq!(src2, dst);

    let z00 = 0.*1./16. + 0.*2./16. + 1.*1./16. +
              0.*2./16. + 0.*4./16. + 1.*2./16. +
              1.*1./16. + 1.*2./16. + 1.*1./16.;
    let z01 =                                   0.*1./16. + 1.*2./16. + 1.*1./16. +
                                                0.*2./16. + 1.*4./16. + 1.*2./16. +
                                                1.*1./16. + 1.*2./16. + 1.*1./16.;

    let z10 = 0.*1./16. + 0.*2./16. + 1.*1./16. +
              1.*2./16. + 1.*4./16. + 1.*2./16. +
              1.*1./16. + 1.*2./16. + 1.*1./16.;
    let z11 =                                   0.*1./16. + 1.*2./16. + 1.*1./16. +
                                                1.*2./16. + 1.*4./16. + 1.*2./16. +
                                                1.*1./16. + 1.*2./16. + 1.*1./16.;
    let exp = z00*1./16. + z00*2./16. + z01*1./16. +
              z00*2./16. + z00*4./16. + z01*2./16. +
              z10*1./16. + z10*2./16. + z11*1./16.;

    assert_eq!(1., dst[3]);
    assert_eq!(1., dst[3 * 4]);
    assert_eq!(1., dst[4 * 4 - 1]);
    assert_eq!(exp, dst[0]);
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use std::vec::Vec;

use data::{Entry, Hint};
use log::Log;

#[derive(Debug)]
pub struct KeyEntry {
    file_id: u32,
    entry_pos: u64,
    entry_size: u64,
    timestamp: u32,
}

pub type KeyDir = HashMap<Vec<u8>, KeyEntry>;

pub struct CaskInner {
    key_dir: KeyDir,
    log: Log,
}

impl CaskInner {
    pub fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        self.key_dir.get(key).and_then(|key_entry| {
            let entry = self.log.read_entry(key_entry.file_id, key_entry.entry_pos);
            if entry.deleted {
                None
            } else {
                Some(entry.value.into_owned())
            }
        })
    }

    pub fn put(&mut self, key: Vec<u8>, value: &[u8]) {
        let key_entry = {
            let entry = Entry::new(&*key, value);

            let (file_id, file_pos) = self.log.write_entry(&entry);

            KeyEntry {
                file_id: file_id,
                entry_pos: file_pos,
                entry_size: entry.size(),
                timestamp: entry.timestamp,
            }
        };

        self.key_dir.insert(key, key_entry);
    }

    pub fn delete(&mut self, key: &[u8]) {
        if self.key_dir.remove(key).is_some() {
            let entry = Entry::deleted(key);
            let _ = self.log.write_entry(&entry);
        }
    }
}

#[derive(Clone)]
pub struct Cask {
    inner: Arc<RwLock<CaskInner>>,
}

impl Cask {
    pub fn open(path: &str, sync: bool) -> Cask {
        info!("Opening database: {:?}", &path);
        let mut log = Log::open(path, sync);
        let mut key_dir = KeyDir::new();

        let files = log.find_files();

        for file_id in files {
            let mut f = |hint: Hint| {
                if hint.deleted {
                    key_dir.remove(&hint.key.into_owned());
                } else {
                    let key_entry = KeyEntry {
                        file_id: file_id,
                        entry_pos: hint.entry_pos,
                        entry_size: hint.entry_size(),
                        timestamp: hint.timestamp,
                    };
                    key_dir.insert(hint.key.into_owned(), key_entry);
                }
            };

            match log.hints(file_id) {
                Some(hints) => {
                    for hint in hints {
                        f(hint);
                    }
                }
                None => {
                    for hint in log.recreate_hints(file_id) {
                        f(hint);
                    }
                }
            }
        }

        info!("Opened database: {:?}", &path);

        Cask {
            inner: Arc::new(RwLock::new(CaskInner {
                log: log,
                key_dir: key_dir,
            })),
        }
    }

    pub fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        self.inner.read().unwrap().get(key)
    }

    pub fn put(&self, key: Vec<u8>, value: &[u8]) {
        self.inner.write().unwrap().put(key, value)
    }

    pub fn delete(&self, key: &[u8]) {
        self.inner.write().unwrap().delete(key)
    }
}
<commit_msg>rename keydir to index<commit_after>use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use std::vec::Vec;

use data::{Entry, Hint};
use log::Log;

#[derive(Debug)]
pub struct IndexEntry {
    file_id: u32,
    entry_pos: u64,
    entry_size: u64,
    timestamp: u32,
}

pub type Index = HashMap<Vec<u8>, IndexEntry>;

pub struct CaskInner {
    index: Index,
    log: Log,
}

impl CaskInner {
    pub fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        self.index.get(key).and_then(|index_entry| {
            let entry = self.log.read_entry(index_entry.file_id, index_entry.entry_pos);
            if entry.deleted {
                None
            } else {
                Some(entry.value.into_owned())
            }
        })
    }

    pub fn put(&mut self, key: Vec<u8>, value: &[u8]) {
        let index_entry = {
            let entry = Entry::new(&*key, value);

            let (file_id, file_pos) = self.log.write_entry(&entry);

            IndexEntry {
                file_id: file_id,
                entry_pos: file_pos,
                entry_size: entry.size(),
                timestamp: entry.timestamp,
            }
        };

        self.index.insert(key, index_entry);
    }

    pub fn delete(&mut self, key: &[u8]) {
        if self.index.remove(key).is_some() {
            let entry = Entry::deleted(key);
            let _ = self.log.write_entry(&entry);
        }
    }
}

#[derive(Clone)]
pub struct Cask {
    inner: Arc<RwLock<CaskInner>>,
}

impl Cask {
    pub fn open(path: &str, sync: bool) -> Cask {
        info!("Opening database: {:?}", &path);
        let mut log = Log::open(path, sync);
        let mut index = Index::new();

        let files = log.find_files();

        for file_id in files {
            let mut f = |hint: Hint| {
                if hint.deleted {
                    index.remove(&hint.key.into_owned());
                } else {
                    let index_entry = IndexEntry {
                        file_id: file_id,
                        entry_pos: hint.entry_pos,
                        entry_size: hint.entry_size(),
                        timestamp: hint.timestamp,
                    };
                    index.insert(hint.key.into_owned(), index_entry);
                }
            };

            match log.hints(file_id) {
                Some(hints) => {
                    for hint in hints {
                        f(hint);
                    }
                }
                None => {
                    for hint in log.recreate_hints(file_id) {
                        f(hint);
                    }
                }
            }
        }

        info!("Opened database: {:?}", &path);

        Cask {
            inner: Arc::new(RwLock::new(CaskInner {
                log: log,
                index: index,
            })),
        }
    }

    pub fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        self.inner.read().unwrap().get(key)
    }

    pub fn put(&self, key: Vec<u8>, value: &[u8]) {
        self.inner.write().unwrap().put(key, value)
    }

    pub fn delete(&self, key: &[u8]) {
        self.inner.write().unwrap().delete(key)
    }
}
<|endoftext|>


<commit_before>use activation_function::ActivationFunction;
use acyclic_network::{NodeType, Network};
pub use acyclic_network::NodeIndex as CppnNodeIndex;
use fixedbitset::FixedBitSet;

pub trait CppnNodeType: NodeType + ActivationFunction {
    fn is_input_node(&self) -> bool;
    fn is_output_node(&self) -> bool;
}

/// A concrete implementation of a CppnNodeType.
#[derive(Clone, Debug)]
pub enum CppnNode<A: ActivationFunction> {
    Bias,
    Input,
    Output,
    Hidden(A),
}

const CPPN_BIAS_WEIGHT: f64 = 1.0;
impl<A: ActivationFunction> ActivationFunction for CppnNode<A> {
    fn formula(&self) -> &'static str {
        // XXX
        ""
    }

    fn calculate(&self, input: f64) -> f64 {
        match *self {
            CppnNode::Hidden(ref activation_function) => {
                // apply activation function on `input`
                activation_function.calculate(input)
            }
            CppnNode::Input | CppnNode::Output => {
                // Simply pass on the input signal.
                input
            }
            CppnNode::Bias => CPPN_BIAS_WEIGHT,
        }
    }
}

impl<A: ActivationFunction> NodeType for CppnNode<A> {
    fn accept_incoming_links(&self) -> bool {
        match *self {
            CppnNode::Input | CppnNode::Bias => false,
            _ => true,
        }
    }

    fn accept_outgoing_links(&self) -> bool {
        match *self {
            CppnNode::Output => false,
            _ => true,
        }
    }
}

impl<A: ActivationFunction> CppnNodeType for CppnNode<A> {
    fn is_input_node(&self) -> bool {
        match *self {
            CppnNode::Input => true,
            _ => false,
        }
    }
    fn is_output_node(&self) -> bool {
        match *self {
            CppnNode::Output => true,
            _ => false,
        }
    }
}

pub type CppnGraph<N: CppnNodeType> = Network<N, f64>;

/// Represents a Compositional Pattern Producing Network (CPPN)
pub struct Cppn<'a, N: CppnNodeType + 'a> {
    graph: &'a CppnGraph<N>,
    inputs: Vec<CppnNodeIndex>,
    outputs: Vec<CppnNodeIndex>,

    // For each node in `graph` there exists a corresponding field in `incoming_signals` describing
    // the sum of all input signals for that node.  We could store it inline in the `CppnNode`, but
    // this would require to make the whole CppnGraph mutable.
    incoming_signals: Vec<f64>,
}

impl<'a, N: CppnNodeType> Cppn<'a, N> {
    pub fn new(graph: &'a CppnGraph<N>) -> Cppn<'a, N> {
        let mut inputs = Vec::new();
        let mut outputs = Vec::new();

        graph.each_node_with_index(|node, index| {
            if node.node_type().is_input_node() {
                inputs.push(index);
            }
            if node.node_type().is_output_node() {
                outputs.push(index);
            }
        });

        Cppn {
            graph: graph,
            inputs: inputs,
            outputs: outputs,
            incoming_signals: graph.nodes().iter().map(|_| 0.0).collect(),
        }
    }

    fn set_signal(&mut self, node_idx: CppnNodeIndex, value: f64) {
        self.incoming_signals[node_idx.index()] = value;
    }

    fn reset_signals(&mut self) {
        for value in self.incoming_signals.iter_mut() {
            *value = 0.0;
        }
    }

    /// Forward-propagate the signals starting from `from_nodes`. We use
    /// breadth-first-search (BFS).
    fn propagate_signals(&mut self, mut nodes: Vec<CppnNodeIndex>, mut seen: FixedBitSet) {
        while let Some(node_idx) = nodes.pop() {
            let input = self.incoming_signals[node_idx.index()];
            let output = self.graph.node(node_idx).node_type().calculate(input);

            // propagate output signal to outgoing links.
            self.graph.each_active_forward_link_of_node(node_idx, |out_node_idx, weight| {
                let out_node = out_node_idx.index();
                self.incoming_signals[out_node] += weight * output;
                if !seen.contains(out_node) {
                    seen.insert(out_node);
                    nodes.push(out_node_idx);
                }
            });
        }
    }

    /// Calculate all outputs
    pub fn calculate(&mut self, inputs: &[&[f64]]) -> Vec<f64> {
        assert!(self.incoming_signals.len() == self.graph.nodes().len());
        self.reset_signals();

        let mut nodes = Vec::new(); // XXX: worst case capacity
        let mut seen = FixedBitSet::with_capacity(self.incoming_signals.len());

        // assign all inputs
        let mut i = 0;
        for input_list in inputs.iter() {
            for &input in input_list.iter() {
                let input_idx = self.inputs[i];
                self.set_signal(input_idx, input);
                nodes.push(input_idx);
                seen.insert(input_idx.index());
                i += 1;
            }
        }
        assert!(i == self.inputs.len());

        // propagate the signals starting from the input signals.
        self.propagate_signals(nodes, seen);

        self.outputs
            .iter()
            .map(|&node_idx| self.incoming_signals[node_idx.index()])
            .collect()
    }
}

#[test]
fn test_cycle() {
    use super::bipolar::BipolarActivationFunction as AF;
    let mut g = CppnGraph::new();
    let i1 = g.add_node(CppnNode::Input);
    let h1 = g.add_node(CppnNode::Hidden(AF::Identity));
    let h2 = g.add_node(CppnNode::Hidden(AF::Identity));
    assert_eq!(true, g.valid_link(i1, i1).is_err());
    assert_eq!(true, g.valid_link(h1, h1).is_err());

    assert_eq!(true, g.valid_link(h1, i1).is_err());
    assert_eq!(Ok(()), g.valid_link(i1, h1));
    assert_eq!(Ok(()), g.valid_link(i1, h2));
    assert_eq!(Ok(()), g.valid_link(h1, h2));

    g.add_link(i1, h1, 0.0);
    assert_eq!(true, g.link_would_cycle(h1, i1));
    assert_eq!(false, g.link_would_cycle(i1, h1));
    assert_eq!(false, g.link_would_cycle(i1, h2));
    assert_eq!(true, g.link_would_cycle(i1, i1));
    assert_eq!(false, g.link_would_cycle(h1, h2));
    assert_eq!(false, g.link_would_cycle(h2, h1));
    assert_eq!(false, g.link_would_cycle(h2, i1));

    g.add_link(h1, h2, 0.0);
    assert_eq!(true, g.link_would_cycle(h2, i1));
    assert_eq!(true, g.link_would_cycle(h1, i1));
    assert_eq!(true, g.link_would_cycle(h2, h1));
    assert_eq!(false, g.link_would_cycle(i1, h2));
}

#[test]
fn test_simple_cppn() {
    use super::bipolar::BipolarActivationFunction as AF;

    let mut g = CppnGraph::new();
    let i1 = g.add_node(CppnNode::Input);
    let h1 = g.add_node(CppnNode::Hidden(AF::Linear));
    let o1 = g.add_node(CppnNode::Output);
    g.add_link(i1, h1, 0.5);
    g.add_link(h1, o1, 1.0);

    let mut cppn = Cppn::new(&g);

    assert_eq!(vec![0.5 * 0.5], cppn.calculate(&[&[0.5]]));
    assert_eq!(vec![1.0], cppn.calculate(&[&[4.0]]));
    assert_eq!(vec![-1.0], cppn.calculate(&[&[-4.0]]));
}

#[test]
fn test_find_random_unconnected_link_no_cycle() {
    use rand;
    use super::bipolar::BipolarActivationFunction as AF;

    let mut g = CppnGraph::<CppnNode<AF>>::new();
    let i1 = g.add_node(CppnNode::Input);
    let o1 = g.add_node(CppnNode::Output);
    let o2 = g.add_node(CppnNode::Output);

    let mut rng = rand::thread_rng();

    let link = g.find_random_unconnected_link_no_cycle(&mut rng);
    assert_eq!(true, link.is_some());
    let l = link.unwrap();
    assert!((i1, o1) == l || (i1, o2) == l);

    g.add_link(i1, o2, 0.0);
    let link = g.find_random_unconnected_link_no_cycle(&mut rng);
    assert_eq!(true, link.is_some());
    assert_eq!((i1, o1), link.unwrap());

    g.add_link(i1, o1, 0.0);
    let link = g.find_random_unconnected_link_no_cycle(&mut rng);
    assert_eq!(false, link.is_some());
}
<commit_msg>Start from all nodes with zero in degree, instead of just from the input nodes. Before that commit, Bias nodes were not respected.<commit_after>use activation_function::ActivationFunction;
use acyclic_network::{NodeType, Network};
pub use acyclic_network::NodeIndex as CppnNodeIndex;
use fixedbitset::FixedBitSet;

pub trait CppnNodeType: NodeType + ActivationFunction {
    fn is_input_node(&self) -> bool;
    fn is_output_node(&self) -> bool;
}

/// A concrete implementation of a CppnNodeType.
#[derive(Clone, Debug)]
pub enum CppnNode<A: ActivationFunction> {
    Bias,
    Input,
    Output,
    Hidden(A),
}

const CPPN_BIAS_WEIGHT: f64 = 1.0;
impl<A: ActivationFunction> ActivationFunction for CppnNode<A> {
    fn formula(&self) -> &'static str {
        // XXX
        ""
    }

    fn calculate(&self, input: f64) -> f64 {
        match *self {
            CppnNode::Hidden(ref activation_function) => {
                // apply activation function on `input`
                activation_function.calculate(input)
            }
            CppnNode::Input | CppnNode::Output => {
                // Simply pass on the input signal.
                input
            }
            CppnNode::Bias => CPPN_BIAS_WEIGHT,
        }
    }
}

impl<A: ActivationFunction> NodeType for CppnNode<A> {
    fn accept_incoming_links(&self) -> bool {
        match *self {
            CppnNode::Input | CppnNode::Bias => false,
            _ => true,
        }
    }

    fn accept_outgoing_links(&self) -> bool {
        match *self {
            CppnNode::Output => false,
            _ => true,
        }
    }
}

impl<A: ActivationFunction> CppnNodeType for CppnNode<A> {
    fn is_input_node(&self) -> bool {
        match *self {
            CppnNode::Input => true,
            _ => false,
        }
    }
    fn is_output_node(&self) -> bool {
        match *self {
            CppnNode::Output => true,
            _ => false,
        }
    }
}

pub type CppnGraph<N: CppnNodeType> = Network<N, f64>;

/// Represents a Compositional Pattern Producing Network (CPPN)
pub struct Cppn<'a, N: CppnNodeType + 'a> {
    graph: &'a CppnGraph<N>,
    inputs: Vec<CppnNodeIndex>,
    outputs: Vec<CppnNodeIndex>,

    // For each node in `graph` there exists a corresponding field in `incoming_signals` describing
    // the sum of all input signals for that node.  We could store it inline in the `CppnNode`, but
    // this would require to make the whole CppnGraph mutable.
    incoming_signals: Vec<f64>,
}

impl<'a, N: CppnNodeType> Cppn<'a, N> {
    pub fn new(graph: &'a CppnGraph<N>) -> Cppn<'a, N> {
        let mut inputs = Vec::new();
        let mut outputs = Vec::new();

        graph.each_node_with_index(|node, index| {
            if node.node_type().is_input_node() {
                inputs.push(index);
            }
            if node.node_type().is_output_node() {
                outputs.push(index);
            }
        });

        Cppn {
            graph: graph,
            inputs: inputs,
            outputs: outputs,
            incoming_signals: graph.nodes().iter().map(|_| 0.0).collect(),
        }
    }

    fn set_signal(&mut self, node_idx: CppnNodeIndex, value: f64) {
        self.incoming_signals[node_idx.index()] = value;
    }

    fn reset_signals(&mut self) {
        for value in self.incoming_signals.iter_mut() {
            *value = 0.0;
        }
    }

    /// Forward-propagate the signals starting from `from_nodes`. We use
    /// breadth-first-search (BFS).
    fn propagate_signals(&mut self, mut nodes: Vec<CppnNodeIndex>, mut seen: FixedBitSet) {
        while let Some(node_idx) = nodes.pop() {
            let input = self.incoming_signals[node_idx.index()];
            let output = self.graph.node(node_idx).node_type().calculate(input);

            // propagate output signal to outgoing links.
            self.graph.each_active_forward_link_of_node(node_idx, |out_node_idx, weight| {
                let out_node = out_node_idx.index();
                self.incoming_signals[out_node] += weight * output;
                if !seen.contains(out_node) {
                    seen.insert(out_node);
                    nodes.push(out_node_idx);
                }
            });
        }
    }

    /// Calculate all outputs
    pub fn calculate(&mut self, inputs: &[&[f64]]) -> Vec<f64> {
        assert!(self.incoming_signals.len() == self.graph.nodes().len());
        self.reset_signals();

        // assign all inputs
        let mut i = 0;
        for input_list in inputs.iter() {
            for &input in input_list.iter() {
                let input_idx = self.inputs[i];
                self.set_signal(input_idx, input);
                i += 1;
            }
        }
        assert!(i == self.inputs.len());

        let mut nodes = Vec::new(); // XXX: worst case capacity
        let mut seen = FixedBitSet::with_capacity(self.incoming_signals.len());

        // start from all nodes which have zero in_degree()
        self.graph.each_node_with_index(|node, index| {
            if node.in_degree() == 0 {
                nodes.push(index);
                seen.insert(index.index());
            }
        });

        // propagate the signals starting from the nodes with zero in degree.
        self.propagate_signals(nodes, seen);

        self.outputs
            .iter()
            .map(|&node_idx| self.incoming_signals[node_idx.index()])
            .collect()
    }
}

#[test]
fn test_cycle() {
    use super::bipolar::BipolarActivationFunction as AF;
    let mut g = CppnGraph::new();
    let i1 = g.add_node(CppnNode::Input);
    let h1 = g.add_node(CppnNode::Hidden(AF::Identity));
    let h2 = g.add_node(CppnNode::Hidden(AF::Identity));
    assert_eq!(true, g.valid_link(i1, i1).is_err());
    assert_eq!(true, g.valid_link(h1, h1).is_err());

    assert_eq!(true, g.valid_link(h1, i1).is_err());
    assert_eq!(Ok(()), g.valid_link(i1, h1));
    assert_eq!(Ok(()), g.valid_link(i1, h2));
    assert_eq!(Ok(()), g.valid_link(h1, h2));

    g.add_link(i1, h1, 0.0);
    assert_eq!(true, g.link_would_cycle(h1, i1));
    assert_eq!(false, g.link_would_cycle(i1, h1));
    assert_eq!(false, g.link_would_cycle(i1, h2));
    assert_eq!(true, g.link_would_cycle(i1, i1));
    assert_eq!(false, g.link_would_cycle(h1, h2));
    assert_eq!(false, g.link_would_cycle(h2, h1));
    assert_eq!(false, g.link_would_cycle(h2, i1));

    g.add_link(h1, h2, 0.0);
    assert_eq!(true, g.link_would_cycle(h2, i1));
    assert_eq!(true, g.link_would_cycle(h1, i1));
    assert_eq!(true, g.link_would_cycle(h2, h1));
    assert_eq!(false, g.link_would_cycle(i1, h2));
}

#[test]
fn test_simple_cppn() {
    use super::bipolar::BipolarActivationFunction as AF;

    let mut g = CppnGraph::new();
    let i1 = g.add_node(CppnNode::Input);
    let h1 = g.add_node(CppnNode::Hidden(AF::Linear));
    let o1 = g.add_node(CppnNode::Output);
    g.add_link(i1, h1, 0.5);
    g.add_link(h1, o1, 1.0);

    let mut cppn = Cppn::new(&g);

    assert_eq!(vec![0.5 * 0.5], cppn.calculate(&[&[0.5]]));
    assert_eq!(vec![1.0], cppn.calculate(&[&[4.0]]));
    assert_eq!(vec![-1.0], cppn.calculate(&[&[-4.0]]));
}

#[test]
fn test_find_random_unconnected_link_no_cycle() {
    use rand;
    use super::bipolar::BipolarActivationFunction as AF;

    let mut g = CppnGraph::<CppnNode<AF>>::new();
    let i1 = g.add_node(CppnNode::Input);
    let o1 = g.add_node(CppnNode::Output);
    let o2 = g.add_node(CppnNode::Output);

    let mut rng = rand::thread_rng();

    let link = g.find_random_unconnected_link_no_cycle(&mut rng);
    assert_eq!(true, link.is_some());
    let l = link.unwrap();
    assert!((i1, o1) == l || (i1, o2) == l);

    g.add_link(i1, o2, 0.0);
    let link = g.find_random_unconnected_link_no_cycle(&mut rng);
    assert_eq!(true, link.is_some());
    assert_eq!((i1, o1), link.unwrap());

    g.add_link(i1, o1, 0.0);
    let link = g.find_random_unconnected_link_no_cycle(&mut rng);
    assert_eq!(false, link.is_some());
}
<|endoftext|>


<commit_before>extern crate sdl2;

use std::path::Path;

use sdl2::event::{Event};
use sdl2::surface::{Surface};

fn main() {
    let ctx = sdl2::init().unwrap();
    let video_ctx = ctx.video().unwrap();

    let window  = match video_ctx.window("eg05", 640, 480).position_centered().opengl().build() {
        Ok(window) => window,
        Err(err)   => panic!("failed to create window: {}", err)
    };

    let mut renderer = match window.renderer().build() {
        Ok(renderer) => renderer,
        Err(err) => panic!("failed to create renderer: {}", err)
    };

    // Load a surface.
    // Surfaces live in system RAM, so they aren't ideal for performance.
    let surface = match Surface::load_bmp(&Path::new("res/ice-troll.bmp")) {
        Ok(surface) => surface,
        Err(err)    => panic!("failed to load surface: {}", err)
    };

    // Convert a surface to a texture.
    // Textures can be used more efficiently by the GPU. (If one is available.)
    let texture = match renderer.create_texture_from_surface(&surface) {
        Ok(texture) => texture,
        Err(err)    => panic!("failed to convert surface: {:?}", err)
    };

    let _ = renderer.clear();
    // Display the texture.
    // Omitting the src & dst Rect arguments will cause our image to stretch across the entire buffer.
    // Try passing Some(surface.rect()) for src & dst instead of None & see how things change.
    let _ = renderer.copy(&texture, None, None);
    let _ = renderer.present();

    let mut events = ctx.event_pump().unwrap();

    // loop until we receive a QuitEvent
    'event : loop {
        for event in events.poll_iter() {
            match event {
                Event::Quit{..} => break 'event,
                _               => continue
            }
        }
    }
}

<commit_msg>eg05: small event loop improvements<commit_after>extern crate sdl2;

use std::path::Path;

use sdl2::event::{Event,WindowEventId};
use sdl2::surface::{Surface};
use sdl2::keyboard::Keycode;

fn main() {
    let ctx = sdl2::init().unwrap();
    let video_ctx = ctx.video().unwrap();

    let window  = match video_ctx.window("eg05", 640, 480).position_centered().opengl().build() {
        Ok(window) => window,
        Err(err)   => panic!("failed to create window: {}", err)
    };

    let mut renderer = match window.renderer().build() {
        Ok(renderer) => renderer,
        Err(err) => panic!("failed to create renderer: {}", err)
    };

    // Load a surface.
    // Surfaces live in system RAM, so they aren't ideal for performance.
    let surface = match Surface::load_bmp(&Path::new("res/ice-troll.bmp")) {
        Ok(surface) => surface,
        Err(err)    => panic!("failed to load surface: {}", err)
    };

    // Convert a surface to a texture.
    // Textures can be used more efficiently by the GPU. (If one is available.)
    let texture = match renderer.create_texture_from_surface(&surface) {
        Ok(texture) => texture,
        Err(err)    => panic!("failed to convert surface: {:?}", err)
    };

    let _ = renderer.clear();
    // Display the texture.
    // Omitting the src & dst Rect arguments will cause our image to stretch across the entire buffer.
    // Try passing Some(surface.rect()) for src & dst instead of None & see how things change.
    let _ = renderer.copy(&texture, None, None);
    let _ = renderer.present();

    let mut events = ctx.event_pump().unwrap();

    // loop until we receive a QuitEvent or press escape.
    'event : loop {
        for event in events.wait_iter() {
            match event {
                Event::Quit{..} => break 'event,
                Event::Window {win_event_id, ..} => {
                    match win_event_id {
                        // refresh our window, for example if it is no longer
                        // covered by other windows.
                        WindowEventId::Exposed => renderer.present(),
                        _ => (),
                    }
                }
                Event::KeyDown {keycode: Some(keycode), ..} => {
                    if keycode == Keycode::Escape {
                        break 'event
                    }
                }
                _               => continue
            }
        }
    }
}

<|endoftext|>


<commit_before>use parser::{parse};
use ast::Expr::*;
use ast::UnOp::*;
use ast::BinOp::*;
use ast::Dec::*;
use ast::*;

fn subst(e: Expr, x: Expr, v: Expr) -> Expr {
  let sub = |e1: Expr| subst(e1.clone(), x.clone(), v.clone());

  match (e.clone(), x.clone()) {
    (Var(ref s1), Var(ref s2)) if s1 == s2 => v.clone(),
    (FnCall(v1, xs), _) => {
      let xs2 = xs.iter().map(|xn| sub(xn.clone())).collect();

      FnCall(Box::new(sub(*v1)), xs2)
    },
    (Var(_), _) => e,
    (Int(_), _) => e,
    (Bool(_), _) => e,
    (Addr(_), _) => e,
    (Bop(op, e1, e2), _) => {
      Bop(
        op,
        Box::new(sub(*e1)),
        Box::new(sub(*e2))
      )
    },
    (Assign(e1, e2, e3), _) => {
      Assign(
        Box::new(sub(*e1)),
        Box::new(sub(*e2)),
        Box::new(sub(*e3))
      )
    },
    (Uop(op, e1), _) => Uop(op, Box::new(sub(*e1))),
    (Ternary(e1, e2, e3), _) => {
      Ternary(
        Box::new(sub(*e1)),
        Box::new(sub(*e2)),
        Box::new(sub(*e3))
      )
    },
    (Decl(d, y, e1, e2), _) => {
      let e2s = if *y == x {
        *e2
      } else {
        sub(*e2)
      };

      Decl(
        d,
        Box::new(*y),
        Box::new(sub(*e1)),
        Box::new(e2s)
      )
    },
    (Func(name, e1, xs), _) => {
      match xs.iter().find(|y| **y == x) {
        Some(_) => e,
        None if name == Some(Box::new(x.clone())) => e,
        None => Func(name, Box::new(sub(*e1)), xs)
      }
    }
  }
}

pub fn step(mut state: State) -> State {
  let st_step = |s: &mut State, e1: &Expr| step(s.with(e1.clone())).expr;

  debug!("step(e) : {:?}", state.expr);
  debug!("step(state) : {:?}", state.mem);
  let e1 = match state.expr.clone() {
    Addr(addr) => {
      state.get(addr)
    },
    /**
     * Values are ineligible for step
     */
    Int(_) | Bool(_) | Func(_, _, _) | Var(_) => {
      debug!("stepping on a value {:?}", state.expr);
      panic!("stepping on a value");
    },
    /**
     * Base cases
     */
    Uop(Not, ref e1) if e1.is_bool() => {
      Bool(!e1.to_bool())
    },
    Uop(Neg, ref e1) if e1.is_int() => {
      Int(-1 * e1.to_int())
    },
    Bop(And, ref e1, ref e2) if e1.is_bool() && e2.is_bool() => {
      Bool(e1.to_bool() && e2.to_bool())
    },
    Bop(Or, ref e1, ref e2) if e1.is_bool() && e2.is_bool() => {
      Bool(e1.to_bool() || e2.to_bool())
    },
    Bop(Eq, ref e1, ref e2) if e1.is_value() && e2.is_value() => {
      Bool(*e1 == *e2)
    },
    Bop(Ne, ref e1, ref e2) if e1.is_value() && e2.is_value() => {
      Bool(*e1 != *e2)
    },
    Bop(Mod, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      let n1 = e1.to_int();
      let n2 = e2.to_int();

      // rust % gives the remainder, not modulus
      let result = ((n1 % n2) + n2) % n2;

      Int(result)
    },
    Bop(Lt, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() < e2.to_int())
    },
    Bop(Gt, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() > e2.to_int())
    },
    Bop(Leq, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() <= e2.to_int())
    },
    Bop(Geq, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() >= e2.to_int())
    },
    Bop(Plus, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() + e2.to_int())
    },
    Bop(Minus, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() - e2.to_int())
    },
    Bop(Times, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() * e2.to_int())
    },
    Bop(Div, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() / e2.to_int())
    },
    Bop(Seq, ref e1, ref e2) if e1.is_value() => {
      *e2.clone()
    },
    Assign(ref v1, ref v2, ref e3) if v1.is_addr() && v2.is_value() => {
      let addr = v1.to_addr();
      state.assign(addr.clone(), *v2.clone());
      debug!("done assigning {:?}", state.mem);
      *e3.clone()
    },
    Ternary(ref e1, ref e2, ref e3) if e1.is_value() => {
      match e1.to_bool() {
        true => *e2.clone(),
        false => *e3.clone(),
      }
    },
    Decl(ref dconst, ref x, ref v1, ref e2) if *dconst == DConst && v1.is_value() => {
      subst(*e2.clone(), *x.clone(), *v1.clone())
    },
    Decl(ref dvar, ref x, ref v1, ref e2) if *dvar == DVar && v1.is_value() => {
      let addr = state.alloc(*v1.clone());
      subst(*e2.clone(), *x.clone(), Expr::Addr(addr))
    },
    FnCall(ref v1, ref es) if v1.is_func() => {
      match **v1 {
        Func(ref name, ref e1, ref xs) => {
          // sub the params
          let exp = xs.iter().zip(es.iter())
            .fold(*e1.clone(), |exp, (xn, en)| subst(exp, xn.clone(), en.clone()));

          // sub the fn body for named functions
          match *name {
            None => exp,
            Some(ref s) => subst(exp, *s.clone(), *v1.clone())
          }
        },
        _ => {
          debug!("expected a Func, got {:?}", v1);
          panic!()
        },
      }
    },
    /**
     * Search Cases
     */
    Bop(ref op, ref v1, ref e2) if v1.is_value() => {
      Bop(
        op.clone(),
        Box::new(*v1.clone()),
        Box::new(st_step(&mut state, e2))
      )
    },
    Bop(op, e1, e2) => {
      Bop(op, Box::new(st_step(&mut state, &*e1)), e2)
    },
    Assign(ref e1, ref e2, ref e3) if e2.is_value() => {
      Assign(e1.clone(), e2.clone(), Box::new(st_step(&mut state, &*e3)))
    },
    Assign(e1, e2, e3) => {
      Assign(e1, Box::new(st_step(&mut state, &*e2)), e3)
    },
    Uop(op, e1) => {
      Uop(op, Box::new(st_step(&mut state, &*e1)))
    },
    Ternary(e1, e2, e3) => {
      Ternary(Box::new(st_step(&mut state, &*e1)), e2, e3)
    },
    Decl(ref dt, ref addr, ref v1, ref e2) if v1.is_value() => {
      Decl(
        dt.clone(),
        Box::new(*addr.clone()),
        Box::new(*v1.clone()),
        Box::new(st_step(&mut state, e2))
      )
    },
    Decl(dt, addr, e1, e2) => {
      Decl(dt, Box::new(*addr.clone()), Box::new(st_step(&mut state, &*e1)), e2)
    },
    FnCall(ref v1, ref mut args) if v1.is_value() => {
      let mut found_first = true;

      for x in args.iter_mut() {
        if x.is_value() && found_first == true {
          found_first = false;
          *x = st_step(&mut state, x);
        }
      }

      FnCall(Box::new(*v1.clone()), args.clone())
    }
    FnCall(e1, args) => {
      FnCall(Box::new(st_step(&mut state, &*e1)), args)
    }
  };

  debug!("returning with mem {:?}" , state.mem);
  debug!("returning with e {:?}" , state.expr);
  state.with(e1)
}

pub fn boxx(input: &str) -> Expr {
  let mut state = State::from(parse(input));

  let mut num_iterations = 0;

  loop {
    num_iterations += 1;
    if state.expr.is_value() {
      debug!("--- iterations: {}", num_iterations);
      return state.expr
    } else {
      state = step(state)
    }
  }
}
<commit_msg>when checked by is_value, expr name should be v<commit_after>use parser::{parse};
use ast::Expr::*;
use ast::UnOp::*;
use ast::BinOp::*;
use ast::Dec::*;
use ast::*;

fn subst(e: Expr, x: Expr, v: Expr) -> Expr {
  let sub = |e1: Expr| subst(e1.clone(), x.clone(), v.clone());

  match (e.clone(), x.clone()) {
    (Var(ref s1), Var(ref s2)) if s1 == s2 => v.clone(),
    (FnCall(v1, xs), _) => {
      let xs2 = xs.iter().map(|xn| sub(xn.clone())).collect();

      FnCall(Box::new(sub(*v1)), xs2)
    },
    (Var(_), _) => e,
    (Int(_), _) => e,
    (Bool(_), _) => e,
    (Addr(_), _) => e,
    (Bop(op, e1, e2), _) => {
      Bop(
        op,
        Box::new(sub(*e1)),
        Box::new(sub(*e2))
      )
    },
    (Assign(e1, e2, e3), _) => {
      Assign(
        Box::new(sub(*e1)),
        Box::new(sub(*e2)),
        Box::new(sub(*e3))
      )
    },
    (Uop(op, e1), _) => Uop(op, Box::new(sub(*e1))),
    (Ternary(e1, e2, e3), _) => {
      Ternary(
        Box::new(sub(*e1)),
        Box::new(sub(*e2)),
        Box::new(sub(*e3))
      )
    },
    (Decl(d, y, e1, e2), _) => {
      let e2s = if *y == x {
        *e2
      } else {
        sub(*e2)
      };

      Decl(
        d,
        Box::new(*y),
        Box::new(sub(*e1)),
        Box::new(e2s)
      )
    },
    (Func(name, e1, xs), _) => {
      match xs.iter().find(|y| **y == x) {
        Some(_) => e,
        None if name == Some(Box::new(x.clone())) => e,
        None => Func(name, Box::new(sub(*e1)), xs)
      }
    }
  }
}

pub fn step(mut state: State) -> State {
  let st_step = |s: &mut State, e1: &Expr| step(s.with(e1.clone())).expr;

  debug!("step(e) : {:?}", state.expr);
  debug!("step(state) : {:?}", state.mem);
  let e1 = match state.expr.clone() {
    Addr(addr) => {
      state.get(addr)
    },
    /**
     * Values are ineligible for step
     */
    Int(_) | Bool(_) | Func(_, _, _) | Var(_) => {
      debug!("stepping on a value {:?}", state.expr);
      panic!("stepping on a value");
    },
    /**
     * Base cases
     */
    Uop(Not, ref e1) if e1.is_bool() => {
      Bool(!e1.to_bool())
    },
    Uop(Neg, ref e1) if e1.is_int() => {
      Int(-1 * e1.to_int())
    },
    Bop(And, ref e1, ref e2) if e1.is_bool() && e2.is_bool() => {
      Bool(e1.to_bool() && e2.to_bool())
    },
    Bop(Or, ref e1, ref e2) if e1.is_bool() && e2.is_bool() => {
      Bool(e1.to_bool() || e2.to_bool())
    },
    Bop(Eq, ref e1, ref e2) if e1.is_value() && e2.is_value() => {
      Bool(*e1 == *e2)
    },
    Bop(Ne, ref e1, ref e2) if e1.is_value() && e2.is_value() => {
      Bool(*e1 != *e2)
    },
    Bop(Mod, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      let n1 = e1.to_int();
      let n2 = e2.to_int();

      // rust % gives the remainder, not modulus
      let result = ((n1 % n2) + n2) % n2;

      Int(result)
    },
    Bop(Lt, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() < e2.to_int())
    },
    Bop(Gt, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() > e2.to_int())
    },
    Bop(Leq, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() <= e2.to_int())
    },
    Bop(Geq, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() >= e2.to_int())
    },
    Bop(Plus, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() + e2.to_int())
    },
    Bop(Minus, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() - e2.to_int())
    },
    Bop(Times, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() * e2.to_int())
    },
    Bop(Div, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() / e2.to_int())
    },
    Bop(Seq, ref v1, ref e2) if v1.is_value() => {
      *e2.clone()
    },
    Assign(ref v1, ref v2, ref e3) if v1.is_addr() && v2.is_value() => {
      let addr = v1.to_addr();
      state.assign(addr.clone(), *v2.clone());
      debug!("done assigning {:?}", state.mem);
      *e3.clone()
    },
    Ternary(ref v1, ref e2, ref e3) if v1.is_value() => {
      match v1.to_bool() {
        true => *e2.clone(),
        false => *e3.clone(),
      }
    },
    Decl(ref dconst, ref x, ref v1, ref e2) if *dconst == DConst && v1.is_value() => {
      subst(*e2.clone(), *x.clone(), *v1.clone())
    },
    Decl(ref dvar, ref x, ref v1, ref e2) if *dvar == DVar && v1.is_value() => {
      let addr = state.alloc(*v1.clone());
      subst(*e2.clone(), *x.clone(), Expr::Addr(addr))
    },
    FnCall(ref v1, ref es) if v1.is_func() => {
      match **v1 {
        Func(ref name, ref e1, ref xs) => {
          // sub the params
          let exp = xs.iter().zip(es.iter())
            .fold(*e1.clone(), |exp, (xn, en)| subst(exp, xn.clone(), en.clone()));

          // sub the fn body for named functions
          match *name {
            None => exp,
            Some(ref s) => subst(exp, *s.clone(), *v1.clone())
          }
        },
        _ => {
          debug!("expected a Func, got {:?}", v1);
          panic!()
        },
      }
    },
    /**
     * Search Cases
     */
    Bop(ref op, ref v1, ref e2) if v1.is_value() => {
      Bop(
        op.clone(),
        Box::new(*v1.clone()),
        Box::new(st_step(&mut state, e2))
      )
    },
    Bop(op, e1, e2) => {
      Bop(op, Box::new(st_step(&mut state, &*e1)), e2)
    },
    Assign(ref e1, ref v2, ref e3) if v2.is_value() => {
      Assign(e1.clone(), v2.clone(), Box::new(st_step(&mut state, &*e3)))
    },
    Assign(e1, e2, e3) => {
      Assign(e1, Box::new(st_step(&mut state, &*e2)), e3)
    },
    Uop(op, e1) => {
      Uop(op, Box::new(st_step(&mut state, &*e1)))
    },
    Ternary(e1, e2, e3) => {
      Ternary(Box::new(st_step(&mut state, &*e1)), e2, e3)
    },
    Decl(ref dt, ref addr, ref v1, ref e2) if v1.is_value() => {
      Decl(
        dt.clone(),
        Box::new(*addr.clone()),
        Box::new(*v1.clone()),
        Box::new(st_step(&mut state, e2))
      )
    },
    Decl(dt, addr, e1, e2) => {
      Decl(dt, Box::new(*addr.clone()), Box::new(st_step(&mut state, &*e1)), e2)
    },
    FnCall(ref v1, ref mut args) if v1.is_value() => {
      let mut found_first = true;

      for x in args.iter_mut() {
        if x.is_value() && found_first == true {
          found_first = false;
          *x = st_step(&mut state, x);
        }
      }

      FnCall(Box::new(*v1.clone()), args.clone())
    }
    FnCall(e1, args) => {
      FnCall(Box::new(st_step(&mut state, &*e1)), args)
    }
  };

  debug!("returning with mem {:?}" , state.mem);
  debug!("returning with e {:?}" , state.expr);
  state.with(e1)
}

pub fn boxx(input: &str) -> Expr {
  let mut state = State::from(parse(input));

  let mut num_iterations = 0;

  loop {
    num_iterations += 1;
    if state.expr.is_value() {
      debug!("--- iterations: {}", num_iterations);
      return state.expr
    } else {
      state = step(state)
    }
  }
}
<|endoftext|>


<commit_before>use piston_window::*;
use piston_window::types::Color;

use board::Board;
use tetromino::*;
use settings::*;

enum GameState {
    Playing,
    Paused
}

pub trait Game {
    fn on_input(&mut self, input: Input);
    fn on_update(&mut self, update_args: UpdateArgs);
    fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow);
}

pub trait Renderer {
    fn render(&self, context: Context, graphics: &mut G2d);
}

pub trait GridRenderer {
    fn render(&self, x: i32, y: i32, context: Context, graphics: &mut G2d);
}

pub struct Rustris {
    board: Board,
    current_piece: Piece,
    next_piece: Piece,
    score: u32,
    level: u32,
    time_since_moved: f64,
    time_per_tick: f64
    // state: GameState
}
impl Rustris {
    pub fn new() -> Rustris {
        Rustris {
            board: Board::new(),
            current_piece: create_random_piece(),
            next_piece: create_random_piece(),
            score: 0,
            level: 1,
            time_since_moved: 0.0,
            time_per_tick: 0.3  //For testing
        }
    }

    pub fn reset(&mut self) {

    }

    pub fn set_current_piece(&mut self, piece: Piece) {
        // TODO: Add tests for this
        if self.is_valid_board_position(&piece) {
            self.current_piece = piece;
        }
    }

    fn is_valid_board_position(&self, piece: &Piece) -> bool {
        // TODO: Add tests for this
        piece.blocks_iter().all(|block| {
            (block.x >= 0 && block.x < WIDTH_IN_BLOCKS as i32 &&
             block.y >= 0 && block.y < HEIGHT_IN_BLOCKS as i32 &&
             !self.board.is_space_occupied(block))
        })
    }

    fn has_landed(&self, piece: &Piece) -> bool {
        // TODO: Add tests for this
        piece.blocks_iter().any(|block| {
            block.y >= HEIGHT_IN_BLOCKS as i32 ||
            self.board.is_space_occupied(block)
        })
    }
}
impl Game for Rustris {
    fn on_input(&mut self, input: Input) {
        match input {
            Input::Press(key) => {
                match key {
                    Button::Keyboard(Key::Up) => {
                        let rotated = self.current_piece.rotated();
                        self.set_current_piece(rotated);
                    }
                    Button::Keyboard(Key::Down) => {

                    }
                    Button::Keyboard(Key::Left) => {
                        let moved = self.current_piece.moved(Direction::Left);
                        self.set_current_piece(moved);
                    }
                    Button::Keyboard(Key::Right) => {
                        let moved = self.current_piece.moved(Direction::Right);
                        self.set_current_piece(moved);
                    }
                    Button::Keyboard(Key::Space) => {

                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }

    fn on_update(&mut self, update_args: UpdateArgs) {
        self.time_since_moved += update_args.dt;
        // TODO: The threshold needs to be able to be updated
        // as the game progresses
        if self.time_since_moved >= self.time_per_tick {
            self.time_since_moved -= self.time_per_tick;
            let moved = self.current_piece.moved(Direction::Down);
            if self.has_landed(&moved) {
                self.board.set_piece(&self.current_piece);
                let next = self.next_piece;
                self.set_current_piece(next);
                self.next_piece = create_random_piece();
            } else {
                self.set_current_piece(moved);
            }
        }
    }

    fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow) {
        e.draw_2d(|c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            self.board.render(c, g);
            self.current_piece.render(c, g);
        });
    }
}

// TODO: Move this into its own module
pub fn render_square_in_grid(x: i32, y: i32, color: Color, context: Context, graphics: &mut G2d) {
    let square = rectangle::square(
        0.0, 0.0, BLOCK_SIZE - (2.0 * GRID_LINE_WIDTH)
    );
    let transform = context.transform
        // Translate the origin of the transform based on where the grid starts
        .trans(GRID_X_OFFSET, GRID_Y_OFFSET)
        // Translate the square into the first grid cell (off of the bounding box)
        .trans(GRID_LINE_WIDTH, GRID_LINE_WIDTH)
        // Translate the square into the proper grid cell based on the grid x and y position
        .trans((x as f64)*BLOCK_SIZE, (y as f64)*BLOCK_SIZE);
    rectangle(color, square, transform, graphics);
}
<commit_msg>added a lines property and extracted an update method from on_update<commit_after>use piston_window::*;
use piston_window::types::Color;

use board::Board;
use tetromino::*;
use settings::*;

enum GameState {
    Playing,
    Paused
}

pub trait Game {
    fn on_input(&mut self, input: Input);
    fn on_update(&mut self, update_args: UpdateArgs);
    fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow);
}

pub trait Renderer {
    fn render(&self, context: Context, graphics: &mut G2d);
}

pub trait GridRenderer {
    fn render(&self, x: i32, y: i32, context: Context, graphics: &mut G2d);
}

pub struct Rustris {
    board: Board,
    current_piece: Piece,
    next_piece: Piece,
    score: u32,
    level: u32,
    lines: u32,
    time_since_moved: f64,
    time_per_tick: f64
    // state: GameState
}
impl Rustris {
    pub fn new() -> Rustris {
        Rustris {
            board: Board::new(),
            current_piece: create_random_piece(),
            next_piece: create_random_piece(),
            score: 0,
            level: 1,
            lines: 0,
            time_since_moved: 0.0,
            time_per_tick: 0.3  //For testing
        }
    }

    pub fn reset(&mut self) {

    }

    pub fn set_current_piece(&mut self, piece: Piece) {
        // TODO: Add tests for this
        if self.is_valid_board_position(&piece) {
            self.current_piece = piece;
        }
    }

    fn is_valid_board_position(&self, piece: &Piece) -> bool {
        // TODO: Add tests for this
        piece.blocks_iter().all(|block| {
            (block.x >= 0 && block.x < WIDTH_IN_BLOCKS as i32 &&
             block.y >= 0 && block.y < HEIGHT_IN_BLOCKS as i32 &&
             !self.board.is_space_occupied(block))
        })
    }

    fn has_landed(&self, piece: &Piece) -> bool {
        // TODO: Add tests for this
        piece.blocks_iter().any(|block| {
            block.y >= HEIGHT_IN_BLOCKS as i32 ||
            self.board.is_space_occupied(block)
        })
    }

    fn update(&mut self) {
        let moved = self.current_piece.moved(Direction::Down);
        if self.has_landed(&moved) {
            self.board.set_piece(&self.current_piece);
            let next = self.next_piece;
            self.set_current_piece(next);
            self.next_piece = create_random_piece();
        } else {
            self.set_current_piece(moved);
        }
    }
}
impl Game for Rustris {
    fn on_input(&mut self, input: Input) {
        match input {
            Input::Press(key) => {
                match key {
                    Button::Keyboard(Key::Up) => {
                        let rotated = self.current_piece.rotated();
                        self.set_current_piece(rotated);
                    }
                    Button::Keyboard(Key::Down) => {

                    }
                    Button::Keyboard(Key::Left) => {
                        let moved = self.current_piece.moved(Direction::Left);
                        self.set_current_piece(moved);
                    }
                    Button::Keyboard(Key::Right) => {
                        let moved = self.current_piece.moved(Direction::Right);
                        self.set_current_piece(moved);
                    }
                    Button::Keyboard(Key::Space) => {

                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }

    fn on_update(&mut self, update_args: UpdateArgs) {
        self.time_since_moved += update_args.dt;
        // TODO: The threshold needs to be able to be updated
        // as the game progresses
        if self.time_since_moved >= self.time_per_tick {
            self.time_since_moved -= self.time_per_tick;
            self.update();
        }
    }

    fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow) {
        e.draw_2d(|c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            self.board.render(c, g);
            self.current_piece.render(c, g);
        });
    }
}

// TODO: Move this into its own module
pub fn render_square_in_grid(x: i32, y: i32, color: Color, context: Context, graphics: &mut G2d) {
    let square = rectangle::square(
        0.0, 0.0, BLOCK_SIZE - (2.0 * GRID_LINE_WIDTH)
    );
    let transform = context.transform
        // Translate the origin of the transform based on where the grid starts
        .trans(GRID_X_OFFSET, GRID_Y_OFFSET)
        // Translate the square into the first grid cell (off of the bounding box)
        .trans(GRID_LINE_WIDTH, GRID_LINE_WIDTH)
        // Translate the square into the proper grid cell based on the grid x and y position
        .trans((x as f64)*BLOCK_SIZE, (y as f64)*BLOCK_SIZE);
    rectangle(color, square, transform, graphics);
}
<|endoftext|>