<commit_before>use std::ops::Deref;
use std::marker::PhantomData;
use std::io;
use std::collections::BTreeMap;
use iron::IronError;
use iron::prelude::*;
use iron::status;
use iron::headers::Cookie;
use hyper::header::{ContentType, SetCookie};

use serde_json;
use cookie::Cookie as CookiePair;
use serde_json::value::ToJson;
use exonum::crypto::PublicKey;
use exonum::crypto::SecretKey;
use router::Router;

use serde::{Serialize, Serializer};
use serde::de;
use serde::de::{Visitor, Deserialize, Deserializer};

use exonum::events::Error as EventsError;
use exonum::crypto::{HexValue, FromHexError, Hash, ToHex};
use exonum::storage::{Result as StorageResult, Error as StorageError};

#[derive(Debug)]
pub enum ApiError {
    Storage(StorageError),
    Events(EventsError),
    FromHex(FromHexError),
    Io(::std::io::Error),
    FileNotFound(Hash),
    NotFound,
    FileToBig,
    FileExists(Hash),
    IncorrectRequest,
    Unauthorized,
}

impl ::std::fmt::Display for ApiError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl ::std::error::Error for ApiError {
    fn description(&self) -> &str {
        match *self {
            ApiError::Storage(_) => "Storage",
            ApiError::Events(_) => "Events",
            ApiError::FromHex(_) => "FromHex",
            ApiError::Io(_) => "Io",
            ApiError::FileNotFound(_) => "FileNotFound",
            ApiError::NotFound => "NotFound",
            ApiError::FileToBig => "FileToBig",
            ApiError::FileExists(_) => "FileExists",
            ApiError::IncorrectRequest => "IncorrectRequest",
            ApiError::Unauthorized => "Unauthorized",
        }
    }
}

impl From<io::Error> for ApiError {
    fn from(e: io::Error) -> ApiError {
        ApiError::Io(e)
    }
}

impl From<StorageError> for ApiError {
    fn from(e: StorageError) -> ApiError {
        ApiError::Storage(e)
    }
}

impl From<EventsError> for ApiError {
    fn from(e: EventsError) -> ApiError {
        ApiError::Events(e)
    }
}

impl From<FromHexError> for ApiError {
    fn from(e: FromHexError) -> ApiError {
        ApiError::FromHex(e)
    }
}

impl From<ApiError> for IronError {
    fn from(e: ApiError) -> IronError {
        use std::error::Error;

        let mut body = BTreeMap::new();
        body.insert("type", e.description().into());
        let code = match e {
            ApiError::FileExists(hash) => {
                body.insert("hash", ToHex::to_hex(&hash));
                status::Conflict
            }
            ApiError::FileNotFound(hash) => {
                body.insert("hash", ToHex::to_hex(&hash));
                status::Conflict
            }
            _ => status::Conflict,
        };
        IronError {
            error: Box::new(e),
            response: Response::with((code, body.to_json().to_string())),
        }
    }
}

#[derive(Clone, Debug)]
pub struct HexField<T: AsRef<[u8]> + Clone>(pub T);

impl<T> Deref for HexField<T>
    where T: AsRef<[u8]> + Clone
{
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T> Serialize for HexField<T>
    where T: AsRef<[u8]> + Clone
{
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        ser.serialize_str(&self.0.as_ref().to_hex())
    }
}

struct HexVisitor<T>
    where T: AsRef<[u8]> + HexValue
{
    _p: PhantomData<T>,
}

impl<T> Visitor for HexVisitor<T>
    where T: AsRef<[u8]> + HexValue + Clone
{
    type Value = HexField<T>;

    fn visit_str<E>(&mut self, s: &str) -> Result<HexField<T>, E>
        where E: de::Error
    {
        let v = T::from_hex(s).map_err(|_| de::Error::custom("Invalid hex"))?;
        Ok(HexField(v))
    }
}

impl<T> Deserialize for HexField<T>
    where T: AsRef<[u8]> + HexValue + Clone
{
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        deserializer.deserialize_str(HexVisitor { _p: PhantomData })
    }
}

pub trait Api {
    fn load_hex_value_from_cookie<'a>(&self,
                                      request: &'a Request,
                                      key: &str)
                                      -> StorageResult<Vec<u8>> {
        if let Some(&Cookie(ref cookies)) = request.headers.get() {
            for cookie in cookies.iter() {
                match CookiePair::parse(cookie.as_str()) {
                    Ok(c) => {
                        if c.name() == key {
                            if let Ok(value) = HexValue::from_hex(c.value()) {
                                return Ok(value);
                            }
                        }
                    }
                    Err(_) => {}
                }
            }
        }
        Err(StorageError::new(format!("Unable to find value with given key {}", key)))
    }

    fn load_keypair_from_cookies(&self,
                                 request: &Request)
                                 -> Result<(PublicKey, SecretKey), ApiError> {
        let public_key =
            PublicKey::from_slice(self.load_hex_value_from_cookie(&request, "public_key")?
                .as_ref());
        let secret_key =
            SecretKey::from_slice(self.load_hex_value_from_cookie(&request, "secret_key")?
                .as_ref());

        let public_key = public_key.ok_or(ApiError::Unauthorized)?;
        let secret_key = secret_key.ok_or(ApiError::Unauthorized)?;
        Ok((public_key, secret_key))
    }

    fn ok_response_with_cookies(&self,
                                json: &serde_json::Value,
                                cookies: Option<Vec<String>>)
                                -> IronResult<Response> {
        let mut resp = Response::with((status::Ok, serde_json::to_string(json).unwrap()));
        resp.headers.set(ContentType::json());
        if let Some(cookies) = cookies {
            resp.headers.set(SetCookie(cookies));
        }
        Ok(resp)
    }

    fn ok_response(&self, json: &serde_json::Value) -> IronResult<Response> {
        self.ok_response_with_cookies(json, None)
    }

    fn wire<'b>(&self, router: &'b mut Router);
}

#[cfg(test)]
mod tests {
    use router::Router;
    use exonum::blockchain::Block;
    use exonum::crypto::Hash;
    use serde_json;
    use super::Api;

    #[test]
    fn test_json_response_for_complex_val() {
        let str_val = "sghdkgskgskldghshgsd";
        let complex_val = Block::new(24,
                                     2,
                                     &Hash::new([24; 32]),
                                     &Hash::new([34; 32]),
                                     &Hash::new([38; 32]));
        struct SampleAPI;
        impl Api for SampleAPI {
            fn wire<'b>(&self, _: &'b mut Router) {
                return;
            }
        }
        let stub = SampleAPI;
        let result = stub.ok_response(&serde_json::to_value(str_val));
        assert!(result.is_ok());
        let result = stub.ok_response(&serde_json::to_value(complex_val));
        assert!(result.is_ok());
        print!("{:?}", result);
    }
}
<commit_msg>Returned pretty print to api<commit_after>use std::ops::Deref;
use std::marker::PhantomData;
use std::io;
use std::collections::BTreeMap;
use iron::IronError;
use iron::prelude::*;
use iron::status;
use iron::headers::Cookie;
use hyper::header::{ContentType, SetCookie};

use serde_json;
use cookie::Cookie as CookiePair;
use serde_json::value::ToJson;
use exonum::crypto::PublicKey;
use exonum::crypto::SecretKey;
use router::Router;

use serde::{Serialize, Serializer};
use serde::de;
use serde::de::{Visitor, Deserialize, Deserializer};

use exonum::events::Error as EventsError;
use exonum::crypto::{HexValue, FromHexError, Hash, ToHex};
use exonum::storage::{Result as StorageResult, Error as StorageError};

#[derive(Debug)]
pub enum ApiError {
    Storage(StorageError),
    Events(EventsError),
    FromHex(FromHexError),
    Io(::std::io::Error),
    FileNotFound(Hash),
    NotFound,
    FileToBig,
    FileExists(Hash),
    IncorrectRequest,
    Unauthorized,
}

impl ::std::fmt::Display for ApiError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl ::std::error::Error for ApiError {
    fn description(&self) -> &str {
        match *self {
            ApiError::Storage(_) => "Storage",
            ApiError::Events(_) => "Events",
            ApiError::FromHex(_) => "FromHex",
            ApiError::Io(_) => "Io",
            ApiError::FileNotFound(_) => "FileNotFound",
            ApiError::NotFound => "NotFound",
            ApiError::FileToBig => "FileToBig",
            ApiError::FileExists(_) => "FileExists",
            ApiError::IncorrectRequest => "IncorrectRequest",
            ApiError::Unauthorized => "Unauthorized",
        }
    }
}

impl From<io::Error> for ApiError {
    fn from(e: io::Error) -> ApiError {
        ApiError::Io(e)
    }
}

impl From<StorageError> for ApiError {
    fn from(e: StorageError) -> ApiError {
        ApiError::Storage(e)
    }
}

impl From<EventsError> for ApiError {
    fn from(e: EventsError) -> ApiError {
        ApiError::Events(e)
    }
}

impl From<FromHexError> for ApiError {
    fn from(e: FromHexError) -> ApiError {
        ApiError::FromHex(e)
    }
}

impl From<ApiError> for IronError {
    fn from(e: ApiError) -> IronError {
        use std::error::Error;

        let mut body = BTreeMap::new();
        body.insert("type", e.description().into());
        let code = match e {
            ApiError::FileExists(hash) => {
                body.insert("hash", ToHex::to_hex(&hash));
                status::Conflict
            }
            ApiError::FileNotFound(hash) => {
                body.insert("hash", ToHex::to_hex(&hash));
                status::Conflict
            }
            _ => status::Conflict,
        };
        IronError {
            error: Box::new(e),
            response: Response::with((code, body.to_json().to_string())),
        }
    }
}

#[derive(Clone, Debug)]
pub struct HexField<T: AsRef<[u8]> + Clone>(pub T);

impl<T> Deref for HexField<T>
    where T: AsRef<[u8]> + Clone
{
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T> Serialize for HexField<T>
    where T: AsRef<[u8]> + Clone
{
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        ser.serialize_str(&self.0.as_ref().to_hex())
    }
}

struct HexVisitor<T>
    where T: AsRef<[u8]> + HexValue
{
    _p: PhantomData<T>,
}

impl<T> Visitor for HexVisitor<T>
    where T: AsRef<[u8]> + HexValue + Clone
{
    type Value = HexField<T>;

    fn visit_str<E>(&mut self, s: &str) -> Result<HexField<T>, E>
        where E: de::Error
    {
        let v = T::from_hex(s).map_err(|_| de::Error::custom("Invalid hex"))?;
        Ok(HexField(v))
    }
}

impl<T> Deserialize for HexField<T>
    where T: AsRef<[u8]> + HexValue + Clone
{
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        deserializer.deserialize_str(HexVisitor { _p: PhantomData })
    }
}

pub trait Api {
    fn load_hex_value_from_cookie<'a>(&self,
                                      request: &'a Request,
                                      key: &str)
                                      -> StorageResult<Vec<u8>> {
        if let Some(&Cookie(ref cookies)) = request.headers.get() {
            for cookie in cookies.iter() {
                match CookiePair::parse(cookie.as_str()) {
                    Ok(c) => {
                        if c.name() == key {
                            if let Ok(value) = HexValue::from_hex(c.value()) {
                                return Ok(value);
                            }
                        }
                    }
                    Err(_) => {}
                }
            }
        }
        Err(StorageError::new(format!("Unable to find value with given key {}", key)))
    }

    fn load_keypair_from_cookies(&self,
                                 request: &Request)
                                 -> Result<(PublicKey, SecretKey), ApiError> {
        let public_key =
            PublicKey::from_slice(self.load_hex_value_from_cookie(&request, "public_key")?
                .as_ref());
        let secret_key =
            SecretKey::from_slice(self.load_hex_value_from_cookie(&request, "secret_key")?
                .as_ref());

        let public_key = public_key.ok_or(ApiError::Unauthorized)?;
        let secret_key = secret_key.ok_or(ApiError::Unauthorized)?;
        Ok((public_key, secret_key))
    }

    fn ok_response_with_cookies(&self,
                                json: &serde_json::Value,
                                cookies: Option<Vec<String>>)
                                -> IronResult<Response> {
        let mut resp = Response::with((status::Ok, serde_json::to_string_pretty(json).unwrap()));
        resp.headers.set(ContentType::json());
        if let Some(cookies) = cookies {
            resp.headers.set(SetCookie(cookies));
        }
        Ok(resp)
    }

    fn ok_response(&self, json: &serde_json::Value) -> IronResult<Response> {
        self.ok_response_with_cookies(json, None)
    }

    fn wire<'b>(&self, router: &'b mut Router);
}

#[cfg(test)]
mod tests {
    use router::Router;
    use exonum::blockchain::Block;
    use exonum::crypto::Hash;
    use serde_json;
    use super::Api;

    #[test]
    fn test_json_response_for_complex_val() {
        let str_val = "sghdkgskgskldghshgsd";
        let complex_val = Block::new(24,
                                     2,
                                     &Hash::new([24; 32]),
                                     &Hash::new([34; 32]),
                                     &Hash::new([38; 32]));
        struct SampleAPI;
        impl Api for SampleAPI {
            fn wire<'b>(&self, _: &'b mut Router) {
                return;
            }
        }
        let stub = SampleAPI;
        let result = stub.ok_response(&serde_json::to_value(str_val));
        assert!(result.is_ok());
        let result = stub.ok_response(&serde_json::to_value(complex_val));
        assert!(result.is_ok());
        print!("{:?}", result);
    }
}
<|endoftext|>


<commit_before>extern crate imageflow_core;

use imageflow_core::ffi::*;
use imageflow_types::*;
use imageflow_core::Context;
use criterion::{ criterion_group, criterion_main, Criterion};
use imageflow_core::graphics::bitmaps::*;
use imageflow_core::graphics::scaling::ScaleAndRenderParams;
use imageflow_core::graphics::color::WorkingFloatspace;
use std::time::Duration;

fn benchmark_transpose(ctx: &mut Criterion) {
    for w in (1000u32..3000u32).step_by(1373) {
        for h in (1000u32..3000u32).step_by(1373) {
            let c = Context::create().unwrap();
            let mut a = Bitmap::create_u8(w, h, PixelLayout::BGRA, true, true, ColorSpace::StandardRGB,BitmapCompositing::ReplaceSelf).unwrap();
            let mut a = unsafe {
                let mut a_bgra = a.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                a_bgra.fill_rect( 0u32, 0u32, w, h, &Color::Srgb(ColorSrgb::Hex("FF0000FF".to_string()))).unwrap();
                a_bgra
            };
            let mut b = Bitmap::create_u8(h,w, PixelLayout::BGRA, true, true, ColorSpace::StandardRGB,BitmapCompositing::ReplaceSelf).unwrap();
            let mut b = unsafe {
                let a_bgra=b.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                a_bgra
            };

            let mut group = ctx.benchmark_group(&format!("transpose w={} && h={}", w, h));

            // Now we can perform benchmarks with this group
            group.bench_function("C", |bencher| bencher.iter(|| {
                unsafe {
                    assert_eq!(flow_bitmap_bgra_transpose(c.flow_c(), &mut a as *mut BitmapBgra, &mut b as *mut BitmapBgra), true)
                }
            } ));
            group.bench_function("Rust", |bencher| bencher.iter(|| {
                unsafe {
                    assert_eq!(imageflow_core::graphics::transpose::flow_bitmap_bgra_transpose(&mut a as *mut BitmapBgra, &mut b as *mut BitmapBgra), Ok(()))
                }
            }));

            group.finish();
        }
    }
}

fn benchmark_flip_v(ctx: &mut Criterion) {
    let fmts=[PixelLayout::BGRA,PixelLayout::BGR];

    for &fmt in fmts.iter(){
        for w in (500u32..3000u32).step_by(2373){
            for h in (500u32..3000u32).step_by(2373){
                let c = Context::create().unwrap();
                let mut bitmap_a = Bitmap::create_u8(w, h, fmt, true, true, ColorSpace::StandardRGB,BitmapCompositing::ReplaceSelf).unwrap();
                let mut a = unsafe {
                    let mut a_bgra = bitmap_a.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                    a_bgra.fill_rect( 0u32, 0u32, w, h, &Color::Srgb(ColorSrgb::Hex("FF0000FF".to_string()))).unwrap();
                    a_bgra
                };

                let mut group = ctx.benchmark_group(&format!("flip_v w={} && h={} fmt={:?}",w,h,fmt));

                // Now we can perform benchmarks with this group
                group.bench_function("C", |bencher| bencher.iter(|| {
                    unsafe { assert_eq!(flow_bitmap_bgra_flip_vertical(c.flow_c(), &mut a as *mut BitmapBgra),true) }
                } ));
                group.bench_function("Rust", |b| b.iter(|| {
                    unsafe { assert_eq!(imageflow_core::graphics::flip::flow_bitmap_bgra_flip_vertical(&mut a as *mut BitmapBgra), Ok(())) }
                }));

                group.finish();

            }
        }
    }

}

fn benchmark_flip_h(ctx: &mut Criterion) {
    let fmts=[PixelLayout::BGRA,PixelLayout::BGR];

    for &fmt in fmts.iter(){
        for w in (500u32..3000u32).step_by(2373){
            for h in (500u32..3000u32).step_by(2373){
                let c = Context::create().unwrap();
                let mut a = Bitmap::create_u8(w, h, fmt, true, true, ColorSpace::StandardRGB,BitmapCompositing::ReplaceSelf).unwrap();
                let mut a = unsafe {
                    let mut a_bgra = a.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                    a_bgra.fill_rect( 0u32, 0u32, w, h, &Color::Srgb(ColorSrgb::Hex("FF0000FF".to_string()))).unwrap();
                    a_bgra
                };

                let mut group = ctx.benchmark_group(&format!("flip_h w={} && h={} fmt={:?}",w,h,fmt));

                // Now we can perform benchmarks with this group
                group.bench_function("C", |bencher| bencher.iter(|| {
                    unsafe { assert_eq!(flow_bitmap_bgra_flip_horizontal(c.flow_c(), &mut a as *mut BitmapBgra),true) }
                } ));
                group.bench_function("Rust", |b| b.iter(|| {
                    unsafe { assert_eq!(imageflow_core::graphics::flip::flow_bitmap_bgra_flip_horizontal(&mut a as *mut BitmapBgra), Ok(())) }
                }));

                group.finish();
            }
        }
    }

}

fn benchmark_scale_2d(ctx: &mut Criterion) {
    let fmts=[PixelLayout::BGRA];
    let float_spaces=[Floatspace::Srgb,Floatspace::Linear];
    for &float_space in float_spaces.iter(){
        for &fmt in fmts.iter(){
            for w in (500u32..4000u32).step_by(2400){
                for h in (500u32..4000u32).step_by(2400){
                    let c = Context::create().unwrap();
                    let mut bitmap_a = Bitmap::create_u8(w, h, PixelLayout::BGRA, true, true, ColorSpace::LinearRGB,BitmapCompositing::ReplaceSelf).unwrap();
                    let mut a = unsafe {
                        let mut a_bgra = bitmap_a.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                        a_bgra.fill_rect( 0u32, 0u32, w, h, &Color::Srgb(ColorSrgb::Hex("FF0000FF".to_string()))).unwrap();
                        a_bgra
                    };
                    let mut bitmap_b = Bitmap::create_u8(800u32,800u32, PixelLayout::BGRA, true, true, ColorSpace::LinearRGB,BitmapCompositing::ReplaceSelf).unwrap();
                    let mut b = unsafe {
                        let a_bgra=bitmap_b.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                        a_bgra
                    };
                    let scale_c =Scale2dRenderToCanvas1d{
                        x: 0u32,
                        y: 0u32,
                        w:800u32,
                        h:800u32,
                        sharpen_percent_goal: 0.0,
                        interpolation_filter: Filter::Robidoux,
                        scale_in_colorspace: float_space
                    };

                    let scale_rust = ScaleAndRenderParams{
                        x: 0u32,
                        y: 0u32,
                        w:800u32,
                        h:800u32,
                        sharpen_percent_goal: 0.0,
                        interpolation_filter: imageflow_core::graphics::weights::Filter::Robidoux,
                        scale_in_colorspace: match float_space{
                            Floatspace::Srgb => WorkingFloatspace::StandardRGB,
                            Floatspace::Linear => WorkingFloatspace::LinearRGB
                        }
                    };

                    let mut group = ctx.benchmark_group(&format!("scale_2d w={} && h={} fmt={:?} float_space={:?}",w,h,fmt,float_space));

                    group.measurement_time(Duration::from_secs(10));

                    // Now we can perform benchmarks with this group
                    group.bench_function("C", |bencher| bencher.iter(|| {
                        unsafe { assert_eq!(flow_node_execute_scale2d_render1d(c.flow_c(),
                                                                               &mut a as *mut BitmapBgra,
                                                                               &mut b as *mut BitmapBgra,
                                                                               &scale_c), true) }
                    } ));
                    group.bench_function("Rust", |b| b.iter(|| {
                        unsafe { assert_eq!(imageflow_core::graphics::scaling::flow_node_execute_scale2d_render1d(
                            bitmap_a.get_window_u8().unwrap(),bitmap_b.get_window_u8().unwrap(),&scale_rust), Ok(())) }
                    }));

                    group.finish();
                }
            }
        }
    }
}
//
extern "C" {
    pub fn flow_scale_spatial_srgb_7x7(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_6x6(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_5x5(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_4x4(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_3x3(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_2x2(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_1x1(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_7x7(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_6x6(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_5x5(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_4x4(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_3x3(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_2x2(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_1x1(input:*const u8, output_rows:*const*mut u8, output_col:u32);
}

fn benchmark_downscaling(ctx: &mut Criterion) {
    unsafe {
        let mut output = Vec::with_capacity(8);

        for _ in 0..8 {
            output.push(
                {
                    let mut temp = Vec::with_capacity(8);
                    for _ in 0..8 {
                        temp.push(0u8);
                    }
                    let ptr = temp.as_mut_ptr();
                    std::mem::forget(temp);
                    ptr
                }
            )
        }
        let ptr = output.as_mut_ptr();
        let mut input = Vec::with_capacity(64);
        for _ in 0..64 {
            input.push(0);
        }
        let input_ptr = input.as_ptr();
        std::mem::forget(output);
        std::mem::forget(input);
        let funs = [flow_scale_spatial_srgb_7x7,
            flow_scale_spatial_srgb_6x6,
            flow_scale_spatial_srgb_5x5,
            flow_scale_spatial_srgb_4x4,
            flow_scale_spatial_srgb_3x3, flow_scale_spatial_srgb_2x2,
            flow_scale_spatial_srgb_1x1, flow_scale_spatial_7x7, flow_scale_spatial_6x6,
            flow_scale_spatial_5x5, flow_scale_spatial_4x4, flow_scale_spatial_3x3,
            flow_scale_spatial_2x2, flow_scale_spatial_1x1
        ];

        for (i,&fun) in funs.iter().enumerate() {
            ctx.bench_function(&format!("downscale function={}",i), |bn| bn.iter(|| {
                fun(input_ptr, ptr, 0)
            }));
        }
    }
}
criterion_group!(benches, benchmark_scale_2d,benchmark_transpose,/*benchmark_downscaling,*/benchmark_flip_h,benchmark_flip_v);
criterion_main!(benches);

<commit_msg>fix memory leak<commit_after>extern crate imageflow_core;

use imageflow_core::ffi::*;
use imageflow_types::*;
use imageflow_core::Context;
use criterion::{ criterion_group, criterion_main, Criterion};
use imageflow_core::graphics::bitmaps::*;
use imageflow_core::graphics::scaling::ScaleAndRenderParams;
use imageflow_core::graphics::color::WorkingFloatspace;
use std::time::Duration;
use itertools::Itertools;

fn benchmark_transpose(ctx: &mut Criterion) {
    for w in (1000u32..3000u32).step_by(1373) {
        for h in (1000u32..3000u32).step_by(1373) {
            let c = Context::create().unwrap();
            let mut a = Bitmap::create_u8(w, h, PixelLayout::BGRA, true, true, ColorSpace::StandardRGB,BitmapCompositing::ReplaceSelf).unwrap();
            let mut a = unsafe {
                let mut a_bgra = a.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                a_bgra.fill_rect( 0u32, 0u32, w, h, &Color::Srgb(ColorSrgb::Hex("FF0000FF".to_string()))).unwrap();
                a_bgra
            };
            let mut b = Bitmap::create_u8(h,w, PixelLayout::BGRA, true, true, ColorSpace::StandardRGB,BitmapCompositing::ReplaceSelf).unwrap();
            let mut b = unsafe {
                let a_bgra=b.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                a_bgra
            };

            let mut group = ctx.benchmark_group(&format!("transpose w={} && h={}", w, h));

            // Now we can perform benchmarks with this group
            group.bench_function("C", |bencher| bencher.iter(|| {
                unsafe {
                    assert_eq!(flow_bitmap_bgra_transpose(c.flow_c(), &mut a as *mut BitmapBgra, &mut b as *mut BitmapBgra), true)
                }
            } ));
            group.bench_function("Rust", |bencher| bencher.iter(|| {
                unsafe {
                    assert_eq!(imageflow_core::graphics::transpose::flow_bitmap_bgra_transpose(&mut a as *mut BitmapBgra, &mut b as *mut BitmapBgra), Ok(()))
                }
            }));

            group.finish();
        }
    }
}

fn benchmark_flip_v(ctx: &mut Criterion) {
    let fmts=[PixelLayout::BGRA,PixelLayout::BGR];

    for &fmt in fmts.iter(){
        for w in (500u32..3000u32).step_by(2373){
            for h in (500u32..3000u32).step_by(2373){
                let c = Context::create().unwrap();
                let mut bitmap_a = Bitmap::create_u8(w, h, fmt, true, true, ColorSpace::StandardRGB,BitmapCompositing::ReplaceSelf).unwrap();
                let mut a = unsafe {
                    let mut a_bgra = bitmap_a.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                    a_bgra.fill_rect( 0u32, 0u32, w, h, &Color::Srgb(ColorSrgb::Hex("FF0000FF".to_string()))).unwrap();
                    a_bgra
                };

                let mut group = ctx.benchmark_group(&format!("flip_v w={} && h={} fmt={:?}",w,h,fmt));

                // Now we can perform benchmarks with this group
                group.bench_function("C", |bencher| bencher.iter(|| {
                    unsafe { assert_eq!(flow_bitmap_bgra_flip_vertical(c.flow_c(), &mut a as *mut BitmapBgra),true) }
                } ));
                group.bench_function("Rust", |b| b.iter(|| {
                    unsafe { assert_eq!(imageflow_core::graphics::flip::flow_bitmap_bgra_flip_vertical(&mut a as *mut BitmapBgra), Ok(())) }
                }));

                group.finish();

            }
        }
    }

}

fn benchmark_flip_h(ctx: &mut Criterion) {
    let fmts=[PixelLayout::BGRA,PixelLayout::BGR];

    for &fmt in fmts.iter(){
        for w in (500u32..3000u32).step_by(2373){
            for h in (500u32..3000u32).step_by(2373){
                let c = Context::create().unwrap();
                let mut a = Bitmap::create_u8(w, h, fmt, true, true, ColorSpace::StandardRGB,BitmapCompositing::ReplaceSelf).unwrap();
                let mut a = unsafe {
                    let mut a_bgra = a.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                    a_bgra.fill_rect( 0u32, 0u32, w, h, &Color::Srgb(ColorSrgb::Hex("FF0000FF".to_string()))).unwrap();
                    a_bgra
                };

                let mut group = ctx.benchmark_group(&format!("flip_h w={} && h={} fmt={:?}",w,h,fmt));

                // Now we can perform benchmarks with this group
                group.bench_function("C", |bencher| bencher.iter(|| {
                    unsafe { assert_eq!(flow_bitmap_bgra_flip_horizontal(c.flow_c(), &mut a as *mut BitmapBgra),true) }
                } ));
                group.bench_function("Rust", |b| b.iter(|| {
                    unsafe { assert_eq!(imageflow_core::graphics::flip::flow_bitmap_bgra_flip_horizontal(&mut a as *mut BitmapBgra), Ok(())) }
                }));

                group.finish();
            }
        }
    }

}

fn benchmark_scale_2d(ctx: &mut Criterion) {
    let fmts=[PixelLayout::BGRA];
    let float_spaces=[Floatspace::Srgb,Floatspace::Linear];
    for &float_space in float_spaces.iter(){
        for &fmt in fmts.iter(){
            for w in (500u32..4000u32).step_by(2400){
                for h in (500u32..4000u32).step_by(2400){
                    let c = Context::create().unwrap();
                    let mut bitmap_a = Bitmap::create_u8(w, h, PixelLayout::BGRA, true, true, ColorSpace::LinearRGB,BitmapCompositing::ReplaceSelf).unwrap();
                    let mut a = unsafe {
                        let mut a_bgra = bitmap_a.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                        a_bgra.fill_rect( 0u32, 0u32, w, h, &Color::Srgb(ColorSrgb::Hex("FF0000FF".to_string()))).unwrap();
                        a_bgra
                    };
                    let mut bitmap_b = Bitmap::create_u8(800u32,800u32, PixelLayout::BGRA, true, true, ColorSpace::LinearRGB,BitmapCompositing::ReplaceSelf).unwrap();
                    let mut b = unsafe {
                        let a_bgra=bitmap_b.get_window_u8().unwrap().to_bitmap_bgra().unwrap();
                        a_bgra
                    };
                    let scale_c =Scale2dRenderToCanvas1d{
                        x: 0u32,
                        y: 0u32,
                        w:800u32,
                        h:800u32,
                        sharpen_percent_goal: 0.0,
                        interpolation_filter: Filter::Robidoux,
                        scale_in_colorspace: float_space
                    };

                    let scale_rust = ScaleAndRenderParams{
                        x: 0u32,
                        y: 0u32,
                        w:800u32,
                        h:800u32,
                        sharpen_percent_goal: 0.0,
                        interpolation_filter: imageflow_core::graphics::weights::Filter::Robidoux,
                        scale_in_colorspace: match float_space{
                            Floatspace::Srgb => WorkingFloatspace::StandardRGB,
                            Floatspace::Linear => WorkingFloatspace::LinearRGB
                        }
                    };

                    let mut group = ctx.benchmark_group(&format!("scale_2d w={} && h={} fmt={:?} float_space={:?}",w,h,fmt,float_space));

                    group.measurement_time(Duration::from_secs(10));

                    // Now we can perform benchmarks with this group
                    group.bench_function("C", |bencher| bencher.iter(|| {
                        unsafe { assert_eq!(flow_node_execute_scale2d_render1d(c.flow_c(),
                                                                               &mut a as *mut BitmapBgra,
                                                                               &mut b as *mut BitmapBgra,
                                                                               &scale_c), true) }
                    } ));
                    group.bench_function("Rust", |b| b.iter(|| {
                        unsafe { assert_eq!(imageflow_core::graphics::scaling::flow_node_execute_scale2d_render1d(
                            bitmap_a.get_window_u8().unwrap(),bitmap_b.get_window_u8().unwrap(),&scale_rust), Ok(())) }
                    }));

                    group.finish();
                }
            }
        }
    }
}
//
extern "C" {
    pub fn flow_scale_spatial_srgb_7x7(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_6x6(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_5x5(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_4x4(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_3x3(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_2x2(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_srgb_1x1(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_7x7(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_6x6(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_5x5(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_4x4(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_3x3(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_2x2(input:*const u8, output_rows:*const*mut u8, output_col:u32);
    pub fn flow_scale_spatial_1x1(input:*const u8, output_rows:*const*mut u8, output_col:u32);
}

fn benchmark_downscaling(ctx: &mut Criterion) {
    let mut output = [[0u8; 8]; 8];
    let input = [0u8; 64];
    let input_ptr = input.as_ptr();
    let mut row = output.iter_mut().map(|ele| ele.as_mut_ptr()).collect_vec();
    let funs = [flow_scale_spatial_srgb_7x7,
        flow_scale_spatial_srgb_6x6,
        flow_scale_spatial_srgb_5x5,
        flow_scale_spatial_srgb_4x4,
        flow_scale_spatial_srgb_3x3, flow_scale_spatial_srgb_2x2,
        flow_scale_spatial_srgb_1x1, flow_scale_spatial_7x7, flow_scale_spatial_6x6,
        flow_scale_spatial_5x5, flow_scale_spatial_4x4, flow_scale_spatial_3x3,
        flow_scale_spatial_2x2, flow_scale_spatial_1x1
    ];

    for (i, &fun) in funs.iter().enumerate() {
        ctx.bench_function(&format!("downscale function={}", i), |bn| bn.iter(|| {
            unsafe { fun(input_ptr, row.as_mut_ptr(), 0) }
        }));
    }
}
criterion_group!(benches ,benchmark_scale_2d,benchmark_transpose,benchmark_downscaling,benchmark_flip_h,benchmark_flip_v);
criterion_main!(benches);

<|endoftext|>


<commit_before>fn each(v: &mut [u32], op: &fn(v: &mut u32)) {
	let mut n = 0;
	while n < v.len() {
		op(&mut v[n]);
		n += 1;
	}
}

struct Mem {
	data:	[u8, ..4096]
}

impl Mem {
	fn read(&self, addr: u32) -> u8 {
		self.data[addr]
	}

	fn read_word(&self, addr: u32) -> u32 {
		let b1 = self.read(addr) as u32;
		let b2 = self.read(addr + 1) as u32;
		let b3 = self.read(addr + 2) as u32;
		let b4 = self.read(addr + 3) as u32;

		(b1 << 24) | (b2 << 16) | (b3 << 8) | b4
	}

	fn write(&mut self, addr: u32, val: u8) {
		self.data[addr] = val;
	}
}

struct Beta {
	pc:			u32,
	register:	[u32, ..31],
	mem:		Mem
}

impl Beta {
	fn reset(&mut self) {
		self.pc = 0;
		do each(self.register) |r| { *r = 0; }

		//println(fmt!("reset. pc at %d", self.pc as int));
	}

	fn tick(&mut self) {
		let instruction: u32 = self.mem.read_word(self.pc);

		self.pc += 4;
		//println(fmt!("tick. pc at %d", self.pc as int));
	}
}

fn main() {
	let mut b = ~Beta {
		pc: 10u32,
		register: [3u32, ..31],
		mem: Mem {
			data: [0u8, ..4*1024]
		}
	};

	b.reset();
	b.tick();
	println("success");
}
<commit_msg>Opcode decoding.<commit_after>fn each(v: &mut [u32], op: &fn(v: &mut u32)) {
	let mut n = 0;
	while n < v.len() {
		op(&mut v[n]);
		n += 1;
	}
}

struct Mem {
	data:	[u8, ..4096]
}

impl Mem {
	fn read(&self, addr: u32) -> u8 {
		self.data[addr]
	}

	fn read_word(&self, addr: u32) -> u32 {
		let b1 = self.read(addr) as u32;
		let b2 = self.read(addr + 1) as u32;
		let b3 = self.read(addr + 2) as u32;
		let b4 = self.read(addr + 3) as u32;

		(b1 << 24) | (b2 << 16) | (b3 << 8) | b4
	}

	fn write(&mut self, addr: u32, val: u8) {
		self.data[addr] = val;
	}
}

struct Beta {
	pc:			u32,
	register:	[u32, ..31],
	mem:		Mem
}

impl Beta {
	fn reset(&mut self) {
		self.pc = 0;
		do each(self.register) |r| { *r = 0; }

		//println(fmt!("reset. pc at %d", self.pc as int));
	}

	fn tick(&mut self) {
		let instruction: u32 = self.mem.read_word(self.pc);

		// decode invariant part of instruction format
		let op = instruction >> 26;
		let r_c = instruction >> 21;
		let r_a = instruction >> 16;

		println(fmt!("op: %d", op as int));

		match op {
			0x20 => println("ADD"),
			0x30 => println("ADDC"),
			0x28 => println("AND"),
			0x38 => println("ANDC"),
			0x1C => println("BEQ"),
			0x1D => println("BNE"),
			0x24 => println("CMPEQ"),
			0x34 => println("CMPEQC"),
			0x26 => println("CMPLE"),
			0x36 => println("CMPLEC"),
			0x25 => println("CMPLT"),
			0x35 => println("CMPLTC"),
			0x23 => println("DIV"),
			0x33 => println("DIVC"),
			0x1B => println("JMP"),
			0x18 => println("LD"),
			0x1F => println("LDR"),
			0x22 => println("MUL"),
			0x32 => println("MULC"),
			0x29 => println("OR"),
			0x39 => println("ORC"),
			0x2C => println("SHL"),
			0x3C => println("SHLC"),
			0x2D => println("SHR"),
			0x3D => println("SHRC"),
			0x2E => println("SRA"),
			0x3E => println("SRAC"),
			0x21 => println("SUB"),
			0x31 => println("SUBC"),
			0x19 => println("ST"),
			0x2A => println("XOR"),
			0x3A => println("XORC"),
			0x2B => println("XNOR"),
			0x3B => println("XNORC"),
			_ => fail!("Unrecognized opcode.")
		}

		self.pc += 4;
		//println(fmt!("tick. pc at %d", self.pc as int));
	}
}

fn main() {
	let mut b = ~Beta {
		pc: 10u32,
		register: [3u32, ..31],
		mem: Mem {
			data: [0u8, ..4*1024]
		}
	};

	b.reset();
	b.tick();
	println("success");
}
<|endoftext|>


<commit_before>use std::io;

use futures::{Future, Poll};

use {AsyncRead, AsyncWrite};

/// A future which will copy all data from a reader into a writer.
///
/// Created by the [`copy`] function, this future will resolve to the number of
/// bytes copied or an error if one happens.
///
/// [`copy`]: fn.copy.html
#[derive(Debug)]
pub struct Copy<R, W> {
    reader: Option<R>,
    read_done: bool,
    writer: Option<W>,
    pos: usize,
    cap: usize,
    amt: u64,
    buf: Box<[u8]>,
}

/// Creates a future which represents copying all the bytes from one object to
/// another.
///
/// The returned future will copy all the bytes read from `reader` into the
/// `writer` specified. This future will only complete once the `reader` has hit
/// EOF and all bytes have been written to and flushed from the `writer`
/// provided.
///
/// On success the number of bytes is returned and the `reader` and `writer` are
/// consumed. On error the error is returned and the I/O objects are consumed as
/// well.
pub fn copy<R, W>(reader: R, writer: W) -> Copy<R, W>
    where R: AsyncRead,
          W: AsyncWrite,
{
    Copy {
        reader: Some(reader),
        read_done: false,
        writer: Some(writer),
        amt: 0,
        pos: 0,
        cap: 0,
        buf: Box::new([0; 2048]),
    }
}

impl<R, W> Future for Copy<R, W>
    where R: AsyncRead,
          W: AsyncWrite,
{
    type Item = (u64, R, W);
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(u64, R, W), io::Error> {
        loop {
            // If our buffer is empty, then we need to read some data to
            // continue.
            if self.pos == self.cap && !self.read_done {
                let reader = self.reader.as_mut().unwrap();
                let n = try_nb!(reader.read(&mut self.buf));
                if n == 0 {
                    self.read_done = true;
                } else {
                    self.pos = 0;
                    self.cap = n;
                }
            }

            // If our buffer has some data, let's write it out!
            while self.pos < self.cap {
                let writer = self.writer.as_mut().unwrap();
                let i = try_nb!(writer.write(&self.buf[self.pos..self.cap]));
                self.pos += i;
                self.amt += i as u64;
            }

            // If we've written al the data and we've seen EOF, flush out the
            // data and finish the transfer.
            // done with the entire transfer.
            if self.pos == self.cap && self.read_done {
                try_nb!(self.writer.as_mut().unwrap().flush());
                let reader = self.reader.take().unwrap();
                let writer = self.writer.take().unwrap();
                return Ok((self.amt, reader, writer).into())
            }
        }
    }
}
<commit_msg>Check for zero byte writings<commit_after>use std::io;

use futures::{Future, Poll};

use {AsyncRead, AsyncWrite};

/// A future which will copy all data from a reader into a writer.
///
/// Created by the [`copy`] function, this future will resolve to the number of
/// bytes copied or an error if one happens.
///
/// [`copy`]: fn.copy.html
#[derive(Debug)]
pub struct Copy<R, W> {
    reader: Option<R>,
    read_done: bool,
    writer: Option<W>,
    pos: usize,
    cap: usize,
    amt: u64,
    buf: Box<[u8]>,
}

/// Creates a future which represents copying all the bytes from one object to
/// another.
///
/// The returned future will copy all the bytes read from `reader` into the
/// `writer` specified. This future will only complete once the `reader` has hit
/// EOF and all bytes have been written to and flushed from the `writer`
/// provided.
///
/// On success the number of bytes is returned and the `reader` and `writer` are
/// consumed. On error the error is returned and the I/O objects are consumed as
/// well.
pub fn copy<R, W>(reader: R, writer: W) -> Copy<R, W>
    where R: AsyncRead,
          W: AsyncWrite,
{
    Copy {
        reader: Some(reader),
        read_done: false,
        writer: Some(writer),
        amt: 0,
        pos: 0,
        cap: 0,
        buf: Box::new([0; 2048]),
    }
}

impl<R, W> Future for Copy<R, W>
    where R: AsyncRead,
          W: AsyncWrite,
{
    type Item = (u64, R, W);
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(u64, R, W), io::Error> {
        loop {
            // If our buffer is empty, then we need to read some data to
            // continue.
            if self.pos == self.cap && !self.read_done {
                let reader = self.reader.as_mut().unwrap();
                let n = try_nb!(reader.read(&mut self.buf));
                if n == 0 {
                    self.read_done = true;
                } else {
                    self.pos = 0;
                    self.cap = n;
                }
            }

            // If our buffer has some data, let's write it out!
            while self.pos < self.cap {
                let writer = self.writer.as_mut().unwrap();
                let i = try_nb!(writer.write(&self.buf[self.pos..self.cap]));
                if i == 0 {
                    return Err(io::Error::new(io::ErrorKind::WriteZero,
                                              "write zero byte into writer"));
                } else {
                    self.pos += i;
                    self.amt += i as u64;
                }
            }

            // If we've written al the data and we've seen EOF, flush out the
            // data and finish the transfer.
            // done with the entire transfer.
            if self.pos == self.cap && self.read_done {
                try_nb!(self.writer.as_mut().unwrap().flush());
                let reader = self.reader.take().unwrap();
                let writer = self.writer.take().unwrap();
                return Ok((self.amt, reader, writer).into())
            }
        }
    }
}
<|endoftext|>


<commit_before>
use std::env::{remove_var, var};
use std::path::PathBuf;
use std::process::Command;

macro_rules! variable(($name:expr) => (var($name).unwrap()));

fn main() {
    let root = PathBuf::from(".");
    let source = PathBuf::from("fftw-3.3.6-pl1");
    let output = PathBuf::from(variable!("OUT_DIR").replace(r"\", "/"));

    remove_var("TARGET");
    if !source.exists() {
        run(Command::new("wget")
            .arg("http://www.fftw.org/fftw-3.3.6-pl1.tar.gz")
            .current_dir(&root));
        run(Command::new("tar").args(&["zxvf", "fftw-3.3.6-pl1.tar.gz"]).current_dir(&root));
    }
    run(Command::new("./configure").arg("--enable-shared").current_dir(&source));

    run(Command::new("make")
        .arg(format!("-j{}", variable!("NUM_JOBS")))
        .current_dir(&source));

    run(Command::new("make")
        .arg("install")
        .arg(format!("DESTDIR={}", output.display()))
        .current_dir(&source));

    println!("cargo:rustc-link-search={}",
             output.join("usr/local/lib").display());
    println!("cargo:rustc-link-lib=dylib=fftw3");
    println!("cargo:rustc-link-lib=dylib=fftw3f");
}

fn run(command: &mut Command) {
    println!("Running: {:?}", command);
    match command.status() {
        Ok(status) => {
            if !status.success() {
                panic!("`{:?}` failed: {}", command, status);
            }
        }
        Err(error) => {
            panic!("failed to execute `{:?}`: {}", command, error);
        }
    }
}
<commit_msg>fftw-sys: add --enable-single<commit_after>
use std::env::{remove_var, var};
use std::path::PathBuf;
use std::process::Command;

macro_rules! variable(($name:expr) => (var($name).unwrap()));

fn main() {
    let root = PathBuf::from(".");
    let source = PathBuf::from("fftw-3.3.6-pl1");
    let output = PathBuf::from(variable!("OUT_DIR").replace(r"\", "/"));

    remove_var("TARGET");
    if !source.exists() {
        run(Command::new("wget")
            .arg("http://www.fftw.org/fftw-3.3.6-pl1.tar.gz")
            .current_dir(&root));
        run(Command::new("tar").args(&["zxvf", "fftw-3.3.6-pl1.tar.gz"]).current_dir(&root));
    }
    run(Command::new("./configure")
        .args(&["--enable-shared", "--enable-single"])
        .current_dir(&source));

    run(Command::new("make")
        .arg(format!("-j{}", variable!("NUM_JOBS")))
        .current_dir(&source));

    run(Command::new("make")
        .arg("install")
        .arg(format!("DESTDIR={}", output.display()))
        .current_dir(&source));

    println!("cargo:rustc-link-search={}",
             output.join("usr/local/lib").display());
    println!("cargo:rustc-link-lib=dylib=fftw3");
    println!("cargo:rustc-link-lib=dylib=fftw3f");
}

fn run(command: &mut Command) {
    println!("Running: {:?}", command);
    match command.status() {
        Ok(status) => {
            if !status.success() {
                panic!("`{:?}` failed: {}", command, status);
            }
        }
        Err(error) => {
            panic!("failed to execute `{:?}`: {}", command, error);
        }
    }
}
<|endoftext|>


<commit_before>/*
    TODO:
    1. Copy downloaded files to other places. (Completed)
    2. Verify the downloaded package.
    3. Make it support repos someday.
*/
extern crate hyper;
use self::hyper::client;

macro_rules! custom_try {
    ($x:expr) => (match $x {
        Ok(x) => x,
        Err(why) => panic!("An error occured during package downloading. {}", why),
    });
}

pub fn download_file(url: &str, output: &Path) {
    let client = Client::new();
    let response = custom_try!(client.get(url).send());
    let mut target = custom_try!(File::create(output));

    for byte in response.bytes() {
        target.write(&[byte.unwrap()]);
    }
}<commit_msg>Add missing modules back<commit_after>/*
    TODO:
    1. Copy downloaded files to other places. (Completed)
    2. Verify the downloaded package.
    3. Make it support repos someday.
*/
extern crate hyper;
use self::hyper::Client;
use std::fs::File;
use std::io::{ Read, Write };
use std::path::Path;

macro_rules! custom_try {
    ($x:expr) => (match $x {
        Ok(x) => x,
        Err(why) => panic!("An error occured during package downloading. {}", why),
    });
}

pub fn download_file(url: &str, output: &Path) {
    let client = Client::new();
    let response = custom_try!(client.get(url).send());
    let mut target = custom_try!(File::create(output));

    for byte in response.bytes() {
        target.write(&[byte.unwrap()]);
    }
}<|endoftext|>


<commit_before>extern crate rand;

use glium::{self, DrawParameters, LinearBlendingFactor, Program, VertexBuffer};
use glium::draw_parameters::{BlendingFunction, DepthTest};
use super::camera::Camera;
use util::ToArr;
use base::math::*;
use base::world::PillarIndex;
use GameContext;
use std::rc::Rc;

const BOX_SIZE: f32 = 20.0;

#[derive(Copy, Clone)]
pub struct Vertex {
    point: [f32; 3],
}
implement_vertex!(Vertex, point);

#[derive(Debug, Copy, Clone)]
pub enum Form {
    #[allow(dead_code)]
    None = 0,
    #[allow(dead_code)]
    Rain = 1,
    #[allow(dead_code)]
    Snow = 2,
    #[allow(dead_code)]
    Pollen = 3,
}

#[derive(Debug, Copy, Clone)]
pub enum Strength {
    #[allow(dead_code)]
    Weak = 1,
    #[allow(dead_code)]
    Medium = 2,
    #[allow(dead_code)]
    Heavy = 3,
}

#[derive(Copy, Clone)]
pub struct Particle {
    vertices: [Vertex; 4],
    position: Point3<f32>,
    velocity: f32,
    trans_x: f32,
    trans_y: f32,
    trans_z: f32,
}

#[derive(Copy, Clone)]
pub struct Instance {
    position: [f32; 3],
}
implement_vertex!(Instance, position);

impl Particle {
    pub fn new(cam_pos: Point3<f32>) -> Particle {
        let mut radius: f32 = 0.0;
        let mut spawn = false;

        // loop provides better distribution of particles, by rolling a dice
        // which equalizes the chance for every radius inside the circle
        while !spawn {
            radius = rand::random::<f32>();

            let dice = rand::random::<f32>();

            spawn = dice < radius;
        }

        radius = radius * BOX_SIZE;

        let angle = Rad::new(rand::random::<f32>() * 6.28);

        let mut velocity = rand::random::<f32>();
        if velocity < 0.25 {
            velocity = velocity + 0.25;
        }
        if velocity > 0.75 {
            velocity = velocity - 0.25;
        }

        Particle {
            vertices: [Vertex { point: [1.0, 1.0, 0.0] },
                       Vertex { point: [-1.0, 1.0, 0.0] },
                       Vertex { point: [1.0, -1.0, 0.0] },
                       Vertex { point: [-1.0, -1.0, 0.0] }],
            position: Point3::new(cam_pos.x + radius * Rad::sin(angle),
                                  cam_pos.y + radius * Rad::cos(angle),
                                  cam_pos.z + BOX_SIZE),
            velocity: velocity,
            trans_x: rand::random::<f32>() * 6.28,
            trans_y: rand::random::<f32>() * 6.28,
            trans_z: rand::random::<f32>() * 6.28,
        }
    }
}

pub struct Weather {
    particles: Vec<Particle>,
    program: Program,
    indices: glium::index::NoIndices,
    context: Rc<GameContext>,
    camera: Camera,
    particle_buf: VertexBuffer<Instance>,
    actual_buf: VertexBuffer<Instance>,
    form: Form,
    strength: Strength,
    time: f32,
}

impl Weather {
    pub fn new(context: Rc<GameContext>) -> Weather {
        let vec: Vec<Particle> = Vec::new();
        let index_buffer = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip);
        let weather_program = context.load_program("weather").unwrap();
        let camera = Camera::default();
        let sections = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        let sections2 = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        Weather {
            particles: vec,
            program: weather_program,
            indices: index_buffer,
            context: context,
            camera: camera,
            particle_buf: sections,
            actual_buf: sections2,
            form: Form::Rain,
            strength: Strength::Weak,
            time: 0.0,
        }
    }

    pub fn draw<S: glium::Surface>(&mut self, surface: &mut S, camera: &Camera) {
        if self.form as u8 == 0 {
            return;
        }

        let params = DrawParameters {
            depth: glium::Depth {
                write: true,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            blend: glium::Blend {
                color: BlendingFunction::Addition {
                    source: LinearBlendingFactor::SourceAlpha,
                    destination: LinearBlendingFactor::OneMinusSourceAlpha,
                },
                ..Default::default()
            },
            ..Default::default()
        };

        let buffer = vec![Vertex { point: [1.0, 1.0, 0.0] },
                          Vertex { point: [-1.0, 1.0, 0.0] },
                          Vertex { point: [1.0, -1.0, 0.0] },
                          Vertex { point: [-1.0, -1.0, 0.0] }];
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &buffer).unwrap();
        let mut scaling = Matrix4::from_cols(Vector4f::new(1.0, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 1.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 1.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
        let view = camera.view_matrix();
        let mut color = Vector4f::new(0.0, 0.0, 0.0, 0.0);
        match self.form {
            Form::Snow => {
                color = Vector4f::new(0.7, 0.7, 0.7, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Rain => {
                color = Vector4f::new(0.35, 0.43, 0.47, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.01, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.5, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Pollen => {
                color = Vector4f::new(0.5, 0.5, 0.5, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            _ => (),
        };

        let uniforms = uniform!{
                form: self.form as i32,
                view_matrix: view.to_arr(),
                proj_matrix: camera.proj_matrix().to_arr(),
                scaling_matrix: scaling.to_arr(),
                color: color.to_arr(),
            };

        surface.draw((&vertex_buffer, self.actual_buf.per_instance().unwrap()),
                  &self.indices,
                  &self.program,
                  &uniforms,
                  &params)
            .unwrap();

    }

    pub fn update(&mut self, camera: &Camera, time: f32, world_manager: &super::WorldManager) {
        if self.time == time {
            return;
        } else {
            self.time += 1.0;
        }
        if self.form as u8 == 0 {
            return;
        }
        self.camera = *camera;
        let max_count: usize;
        match self.form {
            Form::Pollen => max_count = 25 * self.strength as usize,
            _ => max_count = 750 * self.strength as usize,
        }
        if self.particles.len() < max_count {
            let count = max_count / 10;
            for _ in 0..count {
                self.particles.push(Particle::new(camera.position));
            }
            let mut tmp = Vec::new();
            for particle in self.particles.iter() {
                tmp.push(Instance {
                    position: [particle.position.x, particle.position.y, particle.position.z],
                })
            }
            let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp).unwrap();
            self.particle_buf = vertex_buffer;
        }

        let mut mapping = self.particle_buf.map();
        let mut tmp2 = Vec::new();
        for (particle, instance) in &mut self.particles.iter_mut().zip(mapping.iter_mut()) {
            match self.form {
                Form::Snow => {
                    instance.position[2] = instance.position[2] - (particle.velocity * 0.1);
                    instance.position[0] += particle.trans_x.sin() * 0.05;
                    instance.position[1] += particle.trans_y.cos() * 0.05;
                    particle.trans_y += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                }

                Form::Rain => {
                    instance.position[2] = instance.position[2] - ((particle.velocity + 0.5) * 1.0)
                }
                Form::Pollen => {
                    instance.position[0] += particle.trans_x.sin() * 0.025;
                    instance.position[1] += particle.trans_y.cos() * 0.025;
                    instance.position[2] += (particle.trans_z.sin() - 0.7) * 0.01;
                    particle.trans_y += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_z += 3.14 * 0.005 * (rand::random::<f32>() - 0.1);
                }
                _ => (),

            }

            let pix_vec = Point2::new(instance.position[0], instance.position[1]);
            let cam_vec = Point2::new(camera.position.x, camera.position.y);
            let tmp = pix_vec - cam_vec;
            let len = ((tmp.x * tmp.x) + (tmp.y * tmp.y)).sqrt();

            let size = match self.form {
                Form::Pollen => BOX_SIZE / 4.0,
                _ => 1.0,
            };

            if len > BOX_SIZE - size || len < -BOX_SIZE - size {
                instance.position[0] = instance.position[0] - (1.95 * tmp.x);
                instance.position[1] = instance.position[1] - (1.95 * tmp.y);
            }
            if instance.position[2] < self.camera.position.z - BOX_SIZE / size {
                instance.position[2] += 1.9 * (BOX_SIZE / size);
            }
            if instance.position[2] > self.camera.position.z + BOX_SIZE / size {
                instance.position[2] -= 1.9 * (BOX_SIZE / size);
            }
            let tmp_point = Point3::new(instance.position[0],
                                        instance.position[1],
                                        instance.position[2]);
            let mut height = 0.0;

            let world = world_manager.get_world();
            let relevant_pos = Point2f::new(instance.position[0], instance.position[1]);
            let pillar_index = PillarIndex(AxialPoint::from_real(relevant_pos));
            let vec_len = world.pillar_at(pillar_index)
                .map(|pillar| pillar.sections().len())
                .unwrap_or(0);
            let pillar_vec = world.pillar_at(pillar_index).map(|pillar| pillar.sections());
            if pillar_vec.is_some() {
                let new_pillar_vec = pillar_vec.unwrap();

                if vec_len == 1 {
                    height = new_pillar_vec[0].top.to_real();
                } else {
                    for i in 0..vec_len {
                        if i != vec_len - 1 {
                            if new_pillar_vec[i].top.to_real() < instance.position[2] &&
                               instance.position[2] < new_pillar_vec[i + 1].bottom.to_real() {
                                height = new_pillar_vec[i].top.to_real();
                                break;
                            } else {
                                continue;
                            }
                        } else {
                            height = new_pillar_vec[i].top.to_real();
                            break;
                        }
                    }
                }
            }
            // let vec = world.pillar_at(pillar_index);
            if ((tmp_point - camera.position).dot(camera.get_look_at_vector())) > 0.0 &&
               instance.position[2] > height {
                tmp2.push(Instance {
                    position: [instance.position[0], instance.position[1], instance.position[2]],
                })
            }
        }
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp2).unwrap();

        self.actual_buf = vertex_buffer;
    }

    pub fn set_weather(&mut self, form: Form, strength: Strength) {
        self.form = form;
        self.strength = strength;
    }
}
<commit_msg>set default weather to none<commit_after>extern crate rand;

use glium::{self, DrawParameters, LinearBlendingFactor, Program, VertexBuffer};
use glium::draw_parameters::{BlendingFunction, DepthTest};
use super::camera::Camera;
use util::ToArr;
use base::math::*;
use base::world::PillarIndex;
use GameContext;
use std::rc::Rc;

const BOX_SIZE: f32 = 20.0;

#[derive(Copy, Clone)]
pub struct Vertex {
    point: [f32; 3],
}
implement_vertex!(Vertex, point);

#[derive(Debug, Copy, Clone)]
pub enum Form {
    #[allow(dead_code)]
    None = 0,
    #[allow(dead_code)]
    Rain = 1,
    #[allow(dead_code)]
    Snow = 2,
    #[allow(dead_code)]
    Pollen = 3,
}

#[derive(Debug, Copy, Clone)]
pub enum Strength {
    #[allow(dead_code)]
    Weak = 1,
    #[allow(dead_code)]
    Medium = 2,
    #[allow(dead_code)]
    Heavy = 3,
}

#[derive(Copy, Clone)]
pub struct Particle {
    vertices: [Vertex; 4],
    position: Point3<f32>,
    velocity: f32,
    trans_x: f32,
    trans_y: f32,
    trans_z: f32,
}

#[derive(Copy, Clone)]
pub struct Instance {
    position: [f32; 3],
}
implement_vertex!(Instance, position);

impl Particle {
    pub fn new(cam_pos: Point3<f32>) -> Particle {
        let mut radius: f32 = 0.0;
        let mut spawn = false;

        // loop provides better distribution of particles, by rolling a dice
        // which equalizes the chance for every radius inside the circle
        while !spawn {
            radius = rand::random::<f32>();

            let dice = rand::random::<f32>();

            spawn = dice < radius;
        }

        radius = radius * BOX_SIZE;

        let angle = Rad::new(rand::random::<f32>() * 6.28);

        let mut velocity = rand::random::<f32>();
        if velocity < 0.25 {
            velocity = velocity + 0.25;
        }
        if velocity > 0.75 {
            velocity = velocity - 0.25;
        }

        Particle {
            vertices: [Vertex { point: [1.0, 1.0, 0.0] },
                       Vertex { point: [-1.0, 1.0, 0.0] },
                       Vertex { point: [1.0, -1.0, 0.0] },
                       Vertex { point: [-1.0, -1.0, 0.0] }],
            position: Point3::new(cam_pos.x + radius * Rad::sin(angle),
                                  cam_pos.y + radius * Rad::cos(angle),
                                  cam_pos.z + BOX_SIZE),
            velocity: velocity,
            trans_x: rand::random::<f32>() * 6.28,
            trans_y: rand::random::<f32>() * 6.28,
            trans_z: rand::random::<f32>() * 6.28,
        }
    }
}

pub struct Weather {
    particles: Vec<Particle>,
    program: Program,
    indices: glium::index::NoIndices,
    context: Rc<GameContext>,
    camera: Camera,
    particle_buf: VertexBuffer<Instance>,
    actual_buf: VertexBuffer<Instance>,
    form: Form,
    strength: Strength,
    time: f32,
}

impl Weather {
    pub fn new(context: Rc<GameContext>) -> Weather {
        let vec: Vec<Particle> = Vec::new();
        let index_buffer = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip);
        let weather_program = context.load_program("weather").unwrap();
        let camera = Camera::default();
        let sections = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        let sections2 = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        Weather {
            particles: vec,
            program: weather_program,
            indices: index_buffer,
            context: context,
            camera: camera,
            particle_buf: sections,
            actual_buf: sections2,
            form: Form::None,
            strength: Strength::Weak,
            time: 0.0,
        }
    }

    pub fn draw<S: glium::Surface>(&mut self, surface: &mut S, camera: &Camera) {
        if self.form as u8 == 0 {
            return;
        }

        let params = DrawParameters {
            depth: glium::Depth {
                write: true,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            blend: glium::Blend {
                color: BlendingFunction::Addition {
                    source: LinearBlendingFactor::SourceAlpha,
                    destination: LinearBlendingFactor::OneMinusSourceAlpha,
                },
                ..Default::default()
            },
            ..Default::default()
        };

        let buffer = vec![Vertex { point: [1.0, 1.0, 0.0] },
                          Vertex { point: [-1.0, 1.0, 0.0] },
                          Vertex { point: [1.0, -1.0, 0.0] },
                          Vertex { point: [-1.0, -1.0, 0.0] }];
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &buffer).unwrap();
        let mut scaling = Matrix4::from_cols(Vector4f::new(1.0, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 1.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 1.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
        let view = camera.view_matrix();
        let mut color = Vector4f::new(0.0, 0.0, 0.0, 0.0);
        match self.form {
            Form::Snow => {
                color = Vector4f::new(0.7, 0.7, 0.7, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Rain => {
                color = Vector4f::new(0.35, 0.43, 0.47, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.01, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.5, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Pollen => {
                color = Vector4f::new(0.5, 0.5, 0.5, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            _ => (),
        };

        let uniforms = uniform!{
                form: self.form as i32,
                view_matrix: view.to_arr(),
                proj_matrix: camera.proj_matrix().to_arr(),
                scaling_matrix: scaling.to_arr(),
                color: color.to_arr(),
            };

        surface.draw((&vertex_buffer, self.actual_buf.per_instance().unwrap()),
                  &self.indices,
                  &self.program,
                  &uniforms,
                  &params)
            .unwrap();

    }

    pub fn update(&mut self, camera: &Camera, time: f32, world_manager: &super::WorldManager) {
        if self.time == time {
            return;
        } else {
            self.time += 1.0;
        }
        if self.form as u8 == 0 {
            return;
        }
        self.camera = *camera;
        let max_count: usize;
        match self.form {
            Form::Pollen => max_count = 25 * self.strength as usize,
            _ => max_count = 750 * self.strength as usize,
        }
        if self.particles.len() < max_count {
            let count = max_count / 10;
            for _ in 0..count {
                self.particles.push(Particle::new(camera.position));
            }
            let mut tmp = Vec::new();
            for particle in self.particles.iter() {
                tmp.push(Instance {
                    position: [particle.position.x, particle.position.y, particle.position.z],
                })
            }
            let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp).unwrap();
            self.particle_buf = vertex_buffer;
        }

        let mut mapping = self.particle_buf.map();
        let mut tmp2 = Vec::new();
        for (particle, instance) in &mut self.particles.iter_mut().zip(mapping.iter_mut()) {
            match self.form {
                Form::Snow => {
                    instance.position[2] = instance.position[2] - (particle.velocity * 0.1);
                    instance.position[0] += particle.trans_x.sin() * 0.05;
                    instance.position[1] += particle.trans_y.cos() * 0.05;
                    particle.trans_y += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                }

                Form::Rain => {
                    instance.position[2] = instance.position[2] - ((particle.velocity + 0.5) * 1.0)
                }
                Form::Pollen => {
                    instance.position[0] += particle.trans_x.sin() * 0.025;
                    instance.position[1] += particle.trans_y.cos() * 0.025;
                    instance.position[2] += (particle.trans_z.sin() - 0.7) * 0.01;
                    particle.trans_y += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_z += 3.14 * 0.005 * (rand::random::<f32>() - 0.1);
                }
                _ => (),

            }

            let pix_vec = Point2::new(instance.position[0], instance.position[1]);
            let cam_vec = Point2::new(camera.position.x, camera.position.y);
            let tmp = pix_vec - cam_vec;
            let len = ((tmp.x * tmp.x) + (tmp.y * tmp.y)).sqrt();

            let size = match self.form {
                Form::Pollen => BOX_SIZE / 4.0,
                _ => 1.0,
            };

            if len > BOX_SIZE - size || len < -BOX_SIZE - size {
                instance.position[0] = instance.position[0] - (1.95 * tmp.x);
                instance.position[1] = instance.position[1] - (1.95 * tmp.y);
            }
            if instance.position[2] < self.camera.position.z - BOX_SIZE / size {
                instance.position[2] += 1.9 * (BOX_SIZE / size);
            }
            if instance.position[2] > self.camera.position.z + BOX_SIZE / size {
                instance.position[2] -= 1.9 * (BOX_SIZE / size);
            }
            let tmp_point = Point3::new(instance.position[0],
                                        instance.position[1],
                                        instance.position[2]);
            let mut height = 0.0;

            let world = world_manager.get_world();
            let relevant_pos = Point2f::new(instance.position[0], instance.position[1]);
            let pillar_index = PillarIndex(AxialPoint::from_real(relevant_pos));
            let vec_len = world.pillar_at(pillar_index)
                .map(|pillar| pillar.sections().len())
                .unwrap_or(0);
            let pillar_vec = world.pillar_at(pillar_index).map(|pillar| pillar.sections());
            if pillar_vec.is_some() {
                let new_pillar_vec = pillar_vec.unwrap();

                if vec_len == 1 {
                    height = new_pillar_vec[0].top.to_real();
                } else {
                    for i in 0..vec_len {
                        if i != vec_len - 1 {
                            if new_pillar_vec[i].top.to_real() < instance.position[2] &&
                               instance.position[2] < new_pillar_vec[i + 1].bottom.to_real() {
                                height = new_pillar_vec[i].top.to_real();
                                break;
                            } else {
                                continue;
                            }
                        } else {
                            height = new_pillar_vec[i].top.to_real();
                            break;
                        }
                    }
                }
            }
            // let vec = world.pillar_at(pillar_index);
            if ((tmp_point - camera.position).dot(camera.get_look_at_vector())) > 0.0 &&
               instance.position[2] > height {
                tmp2.push(Instance {
                    position: [instance.position[0], instance.position[1], instance.position[2]],
                })
            }
        }
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp2).unwrap();

        self.actual_buf = vertex_buffer;
    }

    pub fn set_weather(&mut self, form: Form, strength: Strength) {
        self.form = form;
        self.strength = strength;
    }
}
<|endoftext|>


<commit_before>/// # Module variables

use std::ops::{Add, Mul, Sub, Neg};
use self::LpExpression::*;
use std::convert::Into;
use std::rc::Rc;

/// Type of variables. Using to initialize a linear programming variable
///
/// # Exemples
///
/// ```
/// use lp_modeler::variables::{LpVariable, LpType};
///
/// let ref a1 = LpVariable::new("a1", LpType::Integer)
///     .lower_bound(10)
///     .upper_bound(20);
///
/// ```
pub enum LpType {
    /// Binary variable
    Binary,
    /// Integer variable
    Integer,
    /// Reel variable
    Continuous
}

#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub enum LpExpression {
    BinaryVariable {
        name: String,
    },
    IntegerVariable {
        name: String,
        lower_bound: Option<i32>,
        upper_bound: Option<i32>,
    },
    ContinuousVariable {
        name: String,
        lower_bound: Option<i32>,
        upper_bound: Option<i32>,
    },
    MulExpr(Rc<LpExpression>, Rc<LpExpression>),
    AddExpr(Rc<LpExpression>, Rc<LpExpression>),
    SubExpr(Rc<LpExpression>, Rc<LpExpression>),
    LitVal(i32),
    EmptyExpr
}

pub struct LpVariable;

#[derive(Debug, Clone)]
pub enum Constraint {
    Greater,
    Less,
    GreaterOrEqual,
    LessOrEqual,
    Equal
}

#[derive(Debug, Clone)]
pub struct LpConstraint(pub LpExpression, pub Constraint, pub LpExpression);

impl LpVariable {
    pub fn new<S: Into<String>>(name: S, var_type: LpType) -> LpExpression {
        match var_type {
            LpType::Binary => BinaryVariable { name: name.into() },
            LpType::Integer => IntegerVariable { name: name.into(), lower_bound: None, upper_bound: None },
            LpType::Continuous => ContinuousVariable { name: name.into(), lower_bound: None, upper_bound: None }
        }
    }

}

#[allow(dead_code)]
impl LpExpression {
    pub fn lower_bound(&self, lw: i32) -> LpExpression {
        match self {
            &BinaryVariable { name: ref n } =>
                BinaryVariable {
                    name: n.clone()
                },
            &IntegerVariable { name: ref n, lower_bound: _, upper_bound: u } =>
                IntegerVariable {
                    name: n.clone(),
                    lower_bound: Some(lw),
                    upper_bound: u
                },
            &ContinuousVariable { name: ref n, lower_bound: _, upper_bound: u } =>
                ContinuousVariable {
                    name: n.clone(),
                    lower_bound: Some(lw),
                    upper_bound: u
                },
            _ => self.clone()
        }
    }
    pub fn upper_bound(&self, up: i32) -> LpExpression {
        match self {
            &BinaryVariable { name: ref n } =>
                BinaryVariable {
                    name: n.clone()
                },
            &IntegerVariable { name: ref n, lower_bound: l, upper_bound: _ } =>
                IntegerVariable {
                    name: n.clone(),
                    lower_bound: l,
                    upper_bound: Some(up)
                },
            &ContinuousVariable { name: ref n, lower_bound: l, upper_bound: _ } =>
                ContinuousVariable {
                    name: n.clone(),
                    lower_bound: l,
                    upper_bound: Some(up)
                },
            _ => self.clone()
        }
    }

}

pub trait LpOperations<T> where T: Into<LpExpression> {
    fn lt(&self, lhs_expr: T) -> LpConstraint;
    fn le(&self, lhs_expr: T) -> LpConstraint;
    fn gt(&self, lhs_expr: T) -> LpConstraint;
    fn ge(&self, lhs_expr: T) -> LpConstraint;
    fn equal(&self, lhs_expr: T) -> LpConstraint;
}

impl Into<LpExpression> for i32 {
    fn into(self) -> LpExpression {
        LitVal(self)
    }
}

impl<'a> Into<LpExpression> for &'a LpExpression {
    fn into(self) -> LpExpression {
        self.clone()
    }
}

fn general_form_constraints(cstr: &LpConstraint) -> LpConstraint {
    // TODO: Optimize tailrec
    fn dfs(expr: &LpExpression, acc: i32) -> i32 {
        match expr {
            &MulExpr(ref rc_e1, ref rc_e2) => {
                let ref e1 = **rc_e1;
                let ref e2 = **rc_e2;
                if let &LitVal(ref x) = e1 {
                    if let &LitVal(ref y) = e2 {
                        acc+x*y
                    }else{
                        dfs(e2, acc)
                    }
                }else{
                    if let &LitVal(ref y) = e2 {
                        dfs(e1, acc+y)
                    }else {
                        dfs(e1, acc) + dfs(e2, 0)
                    }
                }
            },
            &AddExpr(ref rc_e1, ref rc_e2) => {
                let ref e1 = **rc_e1;
                let ref e2 = **rc_e2;
                if let &LitVal(ref x) = e1 {
                    if let &LitVal(ref y) = e2 {
                        acc+x+y
                    }else {
                        dfs(e2, acc+x)
                    }
                }else{
                    if let &LitVal(ref y) = e2 {
                        dfs(e1, acc+y)
                    }else {
                        dfs(e1, acc) + dfs(e2, 0)
                    }
                }
            },
            &SubExpr(ref rc_e1, ref rc_e2) => {
                let ref e1 = **rc_e1;
                let ref e2 = **rc_e2;
                if let &LitVal(ref x) = e1 {
                    if let &LitVal(ref y) = e2 {
                        acc+x-y
                    }else {
                        dfs(e2, acc+x)
                    }
                }else{
                    if let &LitVal(ref y) = e2 {
                        dfs(e1, acc-y)
                    }else {
                        dfs(e1, acc) - dfs(e2, 0)
                    }
                }
            },
            _ => acc
        }
    }
    let &LpConstraint(ref lhs, ref op, ref rhs) = cstr;
    let mut new_cstr;
    if let &LitVal(0) = rhs {
        new_cstr = cstr.clone();
    }else{
        let constant = dfs(&(lhs - rhs), 0);
        new_cstr = LpConstraint(lhs - rhs, op.clone(), LitVal(constant));
    }
    println!("{:?}\n\n", new_cstr);

    //TODO: put the rhs into the lhs ; Search the total of the constants ; put them on the right ;
    //TODO: and remove them on the left
    new_cstr
    //cstr.clone()
}

// <LpExr> op <LpExpr> where LpExpr is implicit
impl<T: Into<LpExpression> + Clone, U> LpOperations<T> for U where U: Into<LpExpression> + Clone {
    fn lt(&self, lhs_expr: T) -> LpConstraint {
        let c = LpConstraint(self.clone().into(), Constraint::Less, lhs_expr.clone().into());
        let _ = general_form_constraints(&c);
        c
    }
    fn le(&self, lhs_expr: T) -> LpConstraint {
        let c = LpConstraint(self.clone().into(), Constraint::LessOrEqual, lhs_expr.clone().into());
        let c = general_form_constraints(&c);
        c.clone()
    }
    fn gt(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::Greater, lhs_expr.clone().into())
    }
    fn ge(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::GreaterOrEqual, lhs_expr.clone().into())
    }
    fn equal( &self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::Equal, lhs_expr.clone().into())
    }
}

// LpExpr + (LpExpr, &LpExpr, i32)
impl<T> Add<T> for LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn add(self, _rhs: T) -> LpExpression {
        AddExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// &LpExpr + (LpExpr, &LpExpr, i32)
impl<'a, T> Add<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn add(self, _rhs: T) -> LpExpression {
        AddExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// i32 + &LpExpr
impl<'a> Add<&'a LpExpression> for i32 {
    type Output = LpExpression;
    fn add(self, _rhs: &'a LpExpression) -> LpExpression {
        AddExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}

// LpExpr - (LpExpr, &LpExpr, i32)
impl<T> Sub<T> for LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn sub(self, _rhs: T) -> LpExpression {
        SubExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// &LpExpr - (LpExpr, &LpExpr, i32)
impl<'a, T> Sub<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn sub(self, _rhs: T) -> LpExpression {
        SubExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// i32 - &LpExpr
impl<'a> Sub<&'a LpExpression> for i32 {
    type Output = LpExpression;
    fn sub(self, _rhs: &'a LpExpression) -> LpExpression {
        SubExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}

impl<'a> Neg for &'a LpExpression {
    type Output = LpExpression;
    fn neg(self) -> LpExpression {
        MulExpr(Rc::new(LitVal(-1)), Rc::new(self.clone()))
    }
}

// i32 * LpExpr
impl Mul<LpExpression> for i32 {
    type Output = LpExpression;
    fn mul(self, _rhs: LpExpression) -> LpExpression {
        LpExpression::MulExpr(Rc::new(LitVal(self)), Rc::new(_rhs))
    }
}

// i32 * &LpExp
impl<'a> Mul<&'a LpExpression> for i32 {
    type Output = LpExpression;

    fn mul(self, _rhs: &'a LpExpression) -> LpExpression {
        MulExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}

/// make a complete expression or a constraint with a vector of expressions
///
/// # Exemples
///
/// ```
/// use lp_modeler::problem::{LpObjective, LpProblem};
/// use lp_modeler::variables::{LpVariable, LpType, lp_sum, LpOperations};
///
/// let mut problem = LpProblem::new("My Problem", LpObjective::Maximize);
/// let ref a = LpVariable::new("a", LpType::Binary);
/// let ref b = LpVariable::new("b", LpType::Binary);
/// let ref c = LpVariable::new("c", LpType::Binary);
///
/// let ref v = vec!(a, b, c);
/// problem += lp_sum(v).equal(10);
/// ```
///
pub fn lp_sum<T>(expr: &Vec<T>) -> LpExpression where T : Into<LpExpression> + Clone {

    let mut expr = expr.clone();
    if let Some(e1) = expr.pop() {
        if let Some(e2) = expr.pop() {
            expr.push(e2);
            AddExpr(Rc::new(e1.into()), Rc::new(lp_sum(&expr)))
        } else {
            e1.into()
        }
    }else{
        EmptyExpr
    }
}

<commit_msg>Removing constant on the left side of the cstr<commit_after>/// # Module variables

use std::ops::{Add, Mul, Sub, Neg};
use self::LpExpression::*;
use std::convert::Into;
use std::rc::Rc;

/// Type of variables. Using to initialize a linear programming variable
///
/// # Exemples
///
/// ```
/// use lp_modeler::variables::{LpVariable, LpType};
///
/// let ref a1 = LpVariable::new("a1", LpType::Integer)
///     .lower_bound(10)
///     .upper_bound(20);
///
/// ```
pub enum LpType {
    /// Binary variable
    Binary,
    /// Integer variable
    Integer,
    /// Reel variable
    Continuous
}

#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub enum LpExpression {
    BinaryVariable {
        name: String,
    },
    IntegerVariable {
        name: String,
        lower_bound: Option<i32>,
        upper_bound: Option<i32>,
    },
    ContinuousVariable {
        name: String,
        lower_bound: Option<i32>,
        upper_bound: Option<i32>,
    },
    MulExpr(Rc<LpExpression>, Rc<LpExpression>),
    AddExpr(Rc<LpExpression>, Rc<LpExpression>),
    SubExpr(Rc<LpExpression>, Rc<LpExpression>),
    LitVal(i32),
    EmptyExpr
}

pub struct LpVariable;

#[derive(Debug, Clone)]
pub enum Constraint {
    Greater,
    Less,
    GreaterOrEqual,
    LessOrEqual,
    Equal
}

#[derive(Debug, Clone)]
pub struct LpConstraint(pub LpExpression, pub Constraint, pub LpExpression);

impl LpVariable {
    pub fn new<S: Into<String>>(name: S, var_type: LpType) -> LpExpression {
        match var_type {
            LpType::Binary => BinaryVariable { name: name.into() },
            LpType::Integer => IntegerVariable { name: name.into(), lower_bound: None, upper_bound: None },
            LpType::Continuous => ContinuousVariable { name: name.into(), lower_bound: None, upper_bound: None }
        }
    }

}

#[allow(dead_code)]
impl LpExpression {
    pub fn lower_bound(&self, lw: i32) -> LpExpression {
        match self {
            &BinaryVariable { name: ref n } =>
                BinaryVariable {
                    name: n.clone()
                },
            &IntegerVariable { name: ref n, lower_bound: _, upper_bound: u } =>
                IntegerVariable {
                    name: n.clone(),
                    lower_bound: Some(lw),
                    upper_bound: u
                },
            &ContinuousVariable { name: ref n, lower_bound: _, upper_bound: u } =>
                ContinuousVariable {
                    name: n.clone(),
                    lower_bound: Some(lw),
                    upper_bound: u
                },
            _ => self.clone()
        }
    }
    pub fn upper_bound(&self, up: i32) -> LpExpression {
        match self {
            &BinaryVariable { name: ref n } =>
                BinaryVariable {
                    name: n.clone()
                },
            &IntegerVariable { name: ref n, lower_bound: l, upper_bound: _ } =>
                IntegerVariable {
                    name: n.clone(),
                    lower_bound: l,
                    upper_bound: Some(up)
                },
            &ContinuousVariable { name: ref n, lower_bound: l, upper_bound: _ } =>
                ContinuousVariable {
                    name: n.clone(),
                    lower_bound: l,
                    upper_bound: Some(up)
                },
            _ => self.clone()
        }
    }

}

pub trait LpOperations<T> where T: Into<LpExpression> {
    fn lt(&self, lhs_expr: T) -> LpConstraint;
    fn le(&self, lhs_expr: T) -> LpConstraint;
    fn gt(&self, lhs_expr: T) -> LpConstraint;
    fn ge(&self, lhs_expr: T) -> LpConstraint;
    fn equal(&self, lhs_expr: T) -> LpConstraint;
}

impl Into<LpExpression> for i32 {
    fn into(self) -> LpExpression {
        LitVal(self)
    }
}

impl<'a> Into<LpExpression> for &'a LpExpression {
    fn into(self) -> LpExpression {
        self.clone()
    }
}

fn general_form_constraints(cstr: &LpConstraint) -> LpConstraint {
    // TODO: Optimize tailrec
    fn dfs(expr: &LpExpression, acc: i32, acc_expr: &LpExpression) -> (i32, LpExpression) {
        match expr {
            &MulExpr(ref rc_e1, ref rc_e2) => {
                let ref e1 = **rc_e1;
                let ref e2 = **rc_e2;
                if let &LitVal(ref x) = e1 {
                    if let &LitVal(ref y) = e2 {
                        (acc+x*y, acc_expr.clone())
                    }else{
                        dfs(e2, acc, acc_expr)
                    }
                }else{
                    if let &LitVal(ref y) = e2 {
                        dfs(e1, acc+y, acc_expr)
                    }else {
                        let (ac, ae) = dfs(e1, acc, acc_expr);
                        dfs(e2, ac+0, acc_expr)
                    }
                }
            },
            &AddExpr(ref rc_e1, ref rc_e2) => {
                let ref e1 = **rc_e1;
                let ref e2 = **rc_e2;
                if let &LitVal(ref x) = e1 {
                    if let &LitVal(ref y) = e2 {
                        (acc+x+y, acc_expr.clone())
                    }else {
                        dfs(e2, acc+x, acc_expr)
                    }
                }else{
                    if let &LitVal(ref y) = e2 {
                        dfs(e1, acc+y, acc_expr)
                    }else {
                        let (ac, ae) = dfs(e1, acc, acc_expr);
                        dfs(e2, ac+0, acc_expr)
                    }
                }
            },
            &SubExpr(ref rc_e1, ref rc_e2) => {
                let ref e1 = **rc_e1;
                let ref e2 = **rc_e2;
                if let &LitVal(ref x) = e1 {
                    if let &LitVal(ref y) = e2 {
                        (acc+x-y, acc_expr.clone())
                    }else {
                        dfs(e2, acc+x, acc_expr)
                    }
                }else{
                    if let &LitVal(ref y) = e2 {
                        dfs(e1, acc-y, acc_expr)
                    }else {
                        let (ac1, ae1) = dfs(e1, acc, acc_expr);
                        let (ac2, ae2) = dfs(e2, 0, acc_expr);
                        (ac1-ac2, acc_expr.clone())
                    }
                }
            },
            _ => (acc, acc_expr.clone())
        }
    }
    let &LpConstraint(ref lhs, ref op, ref rhs) = cstr;
    let mut new_cstr;
    if let &LitVal(0) = rhs {
        new_cstr = cstr.clone();
    }else{
        let (constant, new_expr) = dfs(&(lhs - rhs), 0, &EmptyExpr);
        println!("-> {:?}", new_expr);
        new_cstr = LpConstraint(lhs - rhs, op.clone(), LitVal(constant));
    }
    println!("{:?}\n\n", new_cstr);

    //TODO: put the rhs into the lhs ; Search the total of the constants ; put them on the right ;
    //TODO: and remove them on the left
    new_cstr
    //cstr.clone()
}

// <LpExr> op <LpExpr> where LpExpr is implicit
impl<T: Into<LpExpression> + Clone, U> LpOperations<T> for U where U: Into<LpExpression> + Clone {
    fn lt(&self, lhs_expr: T) -> LpConstraint {
        let c = LpConstraint(self.clone().into(), Constraint::Less, lhs_expr.clone().into());
        let _ = general_form_constraints(&c);
        c
    }
    fn le(&self, lhs_expr: T) -> LpConstraint {
        let c = LpConstraint(self.clone().into(), Constraint::LessOrEqual, lhs_expr.clone().into());
        let c = general_form_constraints(&c);
        c.clone()
    }
    fn gt(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::Greater, lhs_expr.clone().into())
    }
    fn ge(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::GreaterOrEqual, lhs_expr.clone().into())
    }
    fn equal( &self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::Equal, lhs_expr.clone().into())
    }
}

// LpExpr + (LpExpr, &LpExpr, i32)
impl<T> Add<T> for LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn add(self, _rhs: T) -> LpExpression {
        AddExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// &LpExpr + (LpExpr, &LpExpr, i32)
impl<'a, T> Add<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn add(self, _rhs: T) -> LpExpression {
        AddExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// i32 + &LpExpr
impl<'a> Add<&'a LpExpression> for i32 {
    type Output = LpExpression;
    fn add(self, _rhs: &'a LpExpression) -> LpExpression {
        AddExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}

// LpExpr - (LpExpr, &LpExpr, i32)
impl<T> Sub<T> for LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn sub(self, _rhs: T) -> LpExpression {
        SubExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// &LpExpr - (LpExpr, &LpExpr, i32)
impl<'a, T> Sub<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn sub(self, _rhs: T) -> LpExpression {
        SubExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// i32 - &LpExpr
impl<'a> Sub<&'a LpExpression> for i32 {
    type Output = LpExpression;
    fn sub(self, _rhs: &'a LpExpression) -> LpExpression {
        SubExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}

impl<'a> Neg for &'a LpExpression {
    type Output = LpExpression;
    fn neg(self) -> LpExpression {
        MulExpr(Rc::new(LitVal(-1)), Rc::new(self.clone()))
    }
}

// i32 * LpExpr
impl Mul<LpExpression> for i32 {
    type Output = LpExpression;
    fn mul(self, _rhs: LpExpression) -> LpExpression {
        LpExpression::MulExpr(Rc::new(LitVal(self)), Rc::new(_rhs))
    }
}

// i32 * &LpExp
impl<'a> Mul<&'a LpExpression> for i32 {
    type Output = LpExpression;

    fn mul(self, _rhs: &'a LpExpression) -> LpExpression {
        MulExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}

/// make a complete expression or a constraint with a vector of expressions
///
/// # Exemples
///
/// ```
/// use lp_modeler::problem::{LpObjective, LpProblem};
/// use lp_modeler::variables::{LpVariable, LpType, lp_sum, LpOperations};
///
/// let mut problem = LpProblem::new("My Problem", LpObjective::Maximize);
/// let ref a = LpVariable::new("a", LpType::Binary);
/// let ref b = LpVariable::new("b", LpType::Binary);
/// let ref c = LpVariable::new("c", LpType::Binary);
///
/// let ref v = vec!(a, b, c);
/// problem += lp_sum(v).equal(10);
/// ```
///
pub fn lp_sum<T>(expr: &Vec<T>) -> LpExpression where T : Into<LpExpression> + Clone {

    let mut expr = expr.clone();
    if let Some(e1) = expr.pop() {
        if let Some(e2) = expr.pop() {
            expr.push(e2);
            AddExpr(Rc::new(e1.into()), Rc::new(lp_sum(&expr)))
        } else {
            e1.into()
        }
    }else{
        EmptyExpr
    }
}

<|endoftext|>


<commit_before>//! Receive and decode voice-related data units.

mod descramble;
mod rand;

pub mod control;
pub mod crypto;
pub mod frame;
pub mod frame_group;
pub mod header;
pub mod term;
<commit_msg>Make all voice modules public<commit_after>//! Receive and decode voice-related data units.

pub mod control;
pub mod crypto;
pub mod descramble;
pub mod frame;
pub mod frame_group;
pub mod header;
pub mod rand;
pub mod term;
<|endoftext|>