<commit_before>#[macro_use]
extern crate serde_derive;

extern crate serde;

extern crate toml;
extern crate clap;

use clap::{App, Arg, ArgMatches};
use std::path::Path;
use std::fs::{create_dir, File};
use std::io::prelude::*;

#[derive(Serialize, Deserialize)]
struct Config {
    data_dir: Option<String>,
}

const CONFIG_PATH: &'static str = "/etc/blochs/";
const CONFIG_FILE_NAME: &'static str = "server.toml";
const DEFAULT_DATA_DIR: &'static str = "/var/lib/blochs/";

fn main() {
    let options = get_provided_options();

    let config_path = Path::new(CONFIG_PATH);
    if !config_path.exists() {
        match create_dir(CONFIG_PATH) {
            Err(err) => panic!("Could not create the config directory under {}: {}", CONFIG_PATH, err),
            Ok(_) => {}
        };
    }

    let config_file_path = config_path.join(CONFIG_FILE_NAME);
    let mut read_config_file = match File::open(config_file_path.as_path()) {
        Ok(file) => file,
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    let mut actual_content = String::new();
    match read_config_file.read_to_string(&mut actual_content) {
        Ok(_) => {},
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    let mut config_values: Config = toml::from_str(&actual_content).unwrap();

    let config_or_default_data_dir = config_values.data_dir.unwrap_or(DEFAULT_DATA_DIR.to_string());

    let new_data_dir = options.value_of("data.dir").unwrap_or(&config_or_default_data_dir);

    config_values.data_dir = Some(new_data_dir.to_string());

    let new_config_content = toml::to_string(&config_values).unwrap();

    let mut write_config_file = match File::create(config_file_path.as_path()) {
        Ok(file) => file,
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    match write_config_file.write_all(new_config_content.as_bytes()) {
        Ok(_) => println!("New config saved at {}:\n\n{}", config_file_path.display(), new_config_content),
        Err(why) => panic!("Could not write config file {:?}: {}", config_file_path.display(), why),
    };
}

fn get_provided_options<'a>() -> ArgMatches<'a> {
    return App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .arg(Arg::with_name("data.dir")
            .long("data-dir")
            .value_name("DIR")
            .help(&format!("Sets where database data will be stored (default {})", DEFAULT_DATA_DIR))
        ).get_matches();
}
<commit_msg>extract path creation to a function<commit_after>#[macro_use]
extern crate serde_derive;

extern crate serde;

extern crate toml;
extern crate clap;

use clap::{App, Arg, ArgMatches};
use std::path::Path;
use std::fs::{create_dir, File};
use std::io::prelude::*;

#[derive(Serialize, Deserialize)]
struct Config {
    data_dir: Option<String>,
}

const CONFIG_PATH: &'static str = "/etc/blochs/";
const CONFIG_FILE_NAME: &'static str = "server.toml";
const DEFAULT_DATA_DIR: &'static str = "/var/lib/blochs/";

fn main() {
    let options = get_provided_options();

    let config_path = Path::new(CONFIG_PATH);
    ensure_dir_exists(&config_path);

    let config_file_path = config_path.join(CONFIG_FILE_NAME);
    let mut read_config_file = match File::open(config_file_path.as_path()) {
        Ok(file) => file,
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    let mut actual_content = String::new();
    match read_config_file.read_to_string(&mut actual_content) {
        Ok(_) => {},
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    let mut config_values: Config = toml::from_str(&actual_content).unwrap();

    let config_or_default_data_dir = config_values.data_dir.unwrap_or(DEFAULT_DATA_DIR.to_string());

    let new_data_dir = options.value_of("data.dir").unwrap_or(&config_or_default_data_dir);

    config_values.data_dir = Some(new_data_dir.to_string());

    let new_config_content = toml::to_string(&config_values).unwrap();

    let mut write_config_file = match File::create(config_file_path.as_path()) {
        Ok(file) => file,
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    match write_config_file.write_all(new_config_content.as_bytes()) {
        Ok(_) => println!("New config saved at {}:\n\n{}", config_file_path.display(), new_config_content),
        Err(why) => panic!("Could not write config file {:?}: {}", config_file_path.display(), why),
    };
}

fn ensure_dir_exists(path: &Path) {
    if !path.exists() {
        match create_dir(path) {
            Err(err) => panic!("Could not create directory under {}: {}", path.display(), err),
            Ok(_) => {}
        };
    }
}

fn get_provided_options<'a>() -> ArgMatches<'a> {
    return App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .arg(Arg::with_name("data.dir")
            .long("data-dir")
            .value_name("DIR")
            .help(&format!("Sets where database data will be stored (default {})", DEFAULT_DATA_DIR))
        ).get_matches();
}
<|endoftext|>


<commit_before>#![feature(test)]
extern crate test;

extern crate onmf;

extern crate nalgebra;
use self::nalgebra::{DMat};

extern crate rand;
use rand::{StdRng, SeedableRng};

extern crate num;
use num::{Float};

macro_rules! bench_ortho_nmf {
    ($bencher:expr, $float:ty, $nhidden:expr, $nobserved:expr, $nsamples:expr) => {{
        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng: StdRng = SeedableRng::from_seed(seed);

        let mut ortho_nmf = onmf::OrthogonalNMF::<$float>::init_random01(
            $nhidden, $nobserved, $nsamples, &mut rng);

        let samples = DMat::<$float>::new_ones($nsamples, $nobserved);

        let alpha: $float = 0.1 * 1.01.powi(0);
        $bencher.iter(|| {
            ortho_nmf.iterate(alpha, &samples);
        });
    }}
}

#[bench]
fn bench_ortho_nmf_f64_10_256_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 256, 11);
}
#[bench]
fn bench_ortho_nmf_f32_10_256_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 256, 11);
}

#[bench]
fn bench_ortho_nmf_f64_10_256_20(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 256, 20);
}
#[bench]
fn bench_ortho_nmf_f32_10_256_20(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 256, 20);
}

#[bench]
fn bench_ortho_nmf_f64_10_256_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 256, 30);
}
#[bench]
fn bench_ortho_nmf_f32_10_256_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 256, 30);
}

#[bench]
fn bench_ortho_nmf_f64_10_512_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 512, 11);
}
#[bench]
fn bench_ortho_nmf_f32_10_512_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 512, 11);
}

#[bench]
fn bench_ortho_nmf_f64_20_512_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 20, 512, 30);
}
#[bench]
fn bench_ortho_nmf_f32_20_512_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 20, 512, 30);
}
<commit_msg>benchmark ortho nmf blas against normal ortho nmf<commit_after>#![feature(test)]
extern crate test;

extern crate onmf;

extern crate nalgebra;
use self::nalgebra::{DMat};

extern crate rand;
use rand::{StdRng, SeedableRng};

extern crate num;
use num::{Float};

extern crate ndarray;
use ndarray::{ArrayBase};

macro_rules! bench_ortho_nmf {
    ($bencher:expr, $float:ty, $nhidden:expr, $nobserved:expr, $nsamples:expr) => {{
        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng: StdRng = SeedableRng::from_seed(seed);

        let mut ortho_nmf = onmf::OrthogonalNMF::<$float>::init_random01(
            $nhidden, $nobserved, $nsamples, &mut rng);

        let samples = DMat::<$float>::new_ones($nsamples, $nobserved);

        let alpha: $float = 0.1 * 1.01.powi(0);
        $bencher.iter(|| {
            ortho_nmf.iterate(alpha, &samples);
        });
    }}
}

macro_rules! bench_ortho_nmf_blas {
    ($bencher:expr, $nhidden:expr, $nobserved:expr, $nsamples:expr) => {{
        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng: StdRng = SeedableRng::from_seed(seed);

        let mut ortho_nmf = onmf::OrthogonalNMFBlas::init_random01(
            $nhidden, $nobserved, $nsamples, &mut rng);

        let mut samples = ArrayBase::<Vec<f64>, (usize, usize)>::from_elem(($nsamples, $nobserved), 1.);

        let alpha: f64 = 0.1 * 1.01.powi(0);
        $bencher.iter(|| {
            ortho_nmf.iterate(alpha, &mut samples);
        });
    }}
}

#[bench]
fn bench_ortho_nmf_f64_10_256_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 256, 11);
}
#[bench]
fn bench_ortho_nmf_f32_10_256_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 256, 11);
}
#[bench]
fn bench_ortho_nmf_blas_10_256_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf_blas!(bencher, 10, 256, 11);
}

#[bench]
fn bench_ortho_nmf_f64_10_256_20(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 256, 20);
}
#[bench]
fn bench_ortho_nmf_f32_10_256_20(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 256, 20);
}
#[bench]
fn bench_ortho_nmf_blas_10_256_20(bencher: &mut test::Bencher) {
    bench_ortho_nmf_blas!(bencher, 10, 256, 20);
}

#[bench]
fn bench_ortho_nmf_f64_10_256_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 256, 30);
}
#[bench]
fn bench_ortho_nmf_f32_10_256_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 256, 30);
}
#[bench]
fn bench_ortho_nmf_blas_10_256_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf_blas!(bencher, 10, 256, 30);
}

#[bench]
fn bench_ortho_nmf_f64_10_512_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 512, 11);
}
#[bench]
fn bench_ortho_nmf_f32_10_512_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 512, 11);
}
#[bench]
fn bench_ortho_nmf_blas_10_512_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf_blas!(bencher, 10, 512, 11);
}

#[bench]
fn bench_ortho_nmf_f64_20_512_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 20, 512, 30);
}
#[bench]
fn bench_ortho_nmf_f32_20_512_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 20, 512, 30);
}
#[bench]
fn bench_ortho_nmf_blas_20_512_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf_blas!(bencher, 20, 512, 30);
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::account_address::AccountAddress;
use anyhow::{ensure, Error, Result};
#[cfg(feature = "fuzzing")]
use proptest_derive::Arbitrary;
#[cfg(feature = "fuzzing")]
use rand::{rngs::OsRng, RngCore};
use serde::{de, ser, Deserialize, Serialize};
use std::{
    cmp::{Ord, Ordering, PartialOrd},
    convert::TryFrom,
    fmt,
    hash::Hash,
};

/// Size of an event key.
pub const EVENT_KEY_LENGTH: usize = AccountAddress::LENGTH + 8;

/// A struct that represents a globally unique id for an Event stream that a user can listen to.
#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
pub struct EventKey([u8; EVENT_KEY_LENGTH]);

impl EventKey {
    /// Construct a new EventKey from a byte array slice.
    pub fn new(key: [u8; EVENT_KEY_LENGTH]) -> Self {
        EventKey(key)
    }

    /// Get the byte representation of the event key.
    pub fn as_bytes(&self) -> &[u8] {
        &self.0
    }

    /// Convert event key into a byte array.
    pub fn to_vec(&self) -> Vec<u8> {
        self.0.to_vec()
    }

    #[cfg(feature = "fuzzing")]
    /// Create a random event key for testing
    pub fn random() -> Self {
        let mut rng = OsRng::new().expect("can't access OsRng");
        let salt = rng.next_u64();
        EventKey::new_from_address(&AccountAddress::random(), salt)
    }

    /// Create a unique handle by using an AccountAddress and a counter.
    pub fn new_from_address(addr: &AccountAddress, salt: u64) -> Self {
        let mut output_bytes = [0; EVENT_KEY_LENGTH];
        let (lhs, rhs) = output_bytes.split_at_mut(8);
        lhs.copy_from_slice(&salt.to_le_bytes());
        rhs.copy_from_slice(addr.as_ref());
        EventKey(output_bytes)
    }
}

// Rust doesn't support deriving traits for array size greater than 32. We'll implement those traits
// by hand for now
impl PartialEq for EventKey {
    #[inline]
    fn eq(&self, other: &EventKey) -> bool {
        self.as_bytes() == other.as_bytes()
    }
}

impl Eq for EventKey {}

impl PartialOrd for EventKey {
    fn partial_cmp(&self, other: &EventKey) -> Option<Ordering> {
        PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
    }
    #[inline]
    fn lt(&self, other: &EventKey) -> bool {
        PartialOrd::lt(self.as_bytes(), other.as_bytes())
    }
    #[inline]
    fn le(&self, other: &EventKey) -> bool {
        PartialOrd::le(self.as_bytes(), other.as_bytes())
    }
    #[inline]
    fn ge(&self, other: &EventKey) -> bool {
        PartialOrd::ge(self.as_bytes(), other.as_bytes())
    }
    #[inline]
    fn gt(&self, other: &EventKey) -> bool {
        PartialOrd::gt(self.as_bytes(), other.as_bytes())
    }
}

impl Ord for EventKey {
    #[inline]
    fn cmp(&self, other: &EventKey) -> Ordering {
        Ord::cmp(self.as_bytes(), other.as_bytes())
    }
}

impl Clone for EventKey {
    fn clone(&self) -> Self {
        let mut key = [0; EVENT_KEY_LENGTH];
        key.copy_from_slice(self.as_bytes());
        Self(key)
    }
}

impl fmt::Debug for EventKey {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "EventKey({:?})", self.as_bytes())
    }
}

impl Copy for EventKey {}

impl Hash for EventKey {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        Hash::hash(self.as_bytes(), state)
    }
}
// TODO(#1307)
impl ser::Serialize for EventKey {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        serializer.serialize_bytes(&self.0)
    }
}

impl<'de> de::Deserialize<'de> for EventKey {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        struct EventKeyVisitor;

        impl<'de> de::Visitor<'de> for EventKeyVisitor {
            type Value = EventKey;

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                formatter.write_str("EventKey in bytes")
            }

            fn visit_bytes<E>(self, value: &[u8]) -> std::result::Result<Self::Value, E>
            where
                E: de::Error,
            {
                EventKey::try_from(value).map_err(E::custom)
            }
        }

        deserializer.deserialize_bytes(EventKeyVisitor)
    }
}

impl TryFrom<&[u8]> for EventKey {
    type Error = Error;

    /// Tries to convert the provided byte array into Event Key.
    fn try_from(bytes: &[u8]) -> Result<EventKey> {
        ensure!(
            bytes.len() == EVENT_KEY_LENGTH,
            "The Address {:?} is of invalid length",
            bytes
        );
        let mut addr = [0u8; EVENT_KEY_LENGTH];
        addr.copy_from_slice(bytes);
        Ok(EventKey(addr))
    }
}

/// A Rust representation of an Event Handle Resource.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EventHandle {
    /// Number of events in the event stream.
    count: u64,
    /// The associated globally unique key that is used as the key to the EventStore.
    key: EventKey,
}

impl EventHandle {
    /// Constructs a new Event Handle
    pub fn new(key: EventKey, count: u64) -> Self {
        EventHandle { key, count }
    }

    /// Return the key to where this event is stored in EventStore.
    pub fn key(&self) -> &EventKey {
        &self.key
    }
    /// Return the counter for the handle
    pub fn count(&self) -> u64 {
        self.count
    }

    #[cfg(feature = "fuzzing")]
    pub fn count_mut(&mut self) -> &mut u64 {
        &mut self.count
    }

    #[cfg(feature = "fuzzing")]
    /// Create a random event handle for testing
    pub fn random_handle(count: u64) -> Self {
        Self {
            key: EventKey::random(),
            count,
        }
    }

    #[cfg(feature = "fuzzing")]
    /// Derive a unique handle by using an AccountAddress and a counter.
    pub fn new_from_address(addr: &AccountAddress, salt: u64) -> Self {
        Self {
            key: EventKey::new_from_address(addr, salt),
            count: 0,
        }
    }
}

impl fmt::LowerHex for EventKey {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", hex::encode(self.as_bytes()))
    }
}

impl fmt::Display for EventKey {
    fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
        // Forward to the LowerHex impl with a "0x" prepended (the # flag).
        write!(f, "{:#x}", self)
    }
}
<commit_msg>[types] derive standard traits for EventKey<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::account_address::AccountAddress;
use anyhow::{ensure, Error, Result};
#[cfg(feature = "fuzzing")]
use proptest_derive::Arbitrary;
#[cfg(feature = "fuzzing")]
use rand::{rngs::OsRng, RngCore};
use serde::{de, ser, Deserialize, Serialize};
use std::{convert::TryFrom, fmt};

/// Size of an event key.
pub const EVENT_KEY_LENGTH: usize = AccountAddress::LENGTH + 8;

/// A struct that represents a globally unique id for an Event stream that a user can listen to.e
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
pub struct EventKey([u8; EVENT_KEY_LENGTH]);

impl EventKey {
    /// Construct a new EventKey from a byte array slice.
    pub fn new(key: [u8; EVENT_KEY_LENGTH]) -> Self {
        EventKey(key)
    }

    /// Get the byte representation of the event key.
    pub fn as_bytes(&self) -> &[u8] {
        &self.0
    }

    /// Convert event key into a byte array.
    pub fn to_vec(&self) -> Vec<u8> {
        self.0.to_vec()
    }

    #[cfg(feature = "fuzzing")]
    /// Create a random event key for testing
    pub fn random() -> Self {
        let mut rng = OsRng::new().expect("can't access OsRng");
        let salt = rng.next_u64();
        EventKey::new_from_address(&AccountAddress::random(), salt)
    }

    /// Create a unique handle by using an AccountAddress and a counter.
    pub fn new_from_address(addr: &AccountAddress, salt: u64) -> Self {
        let mut output_bytes = [0; EVENT_KEY_LENGTH];
        let (lhs, rhs) = output_bytes.split_at_mut(8);
        lhs.copy_from_slice(&salt.to_le_bytes());
        rhs.copy_from_slice(addr.as_ref());
        EventKey(output_bytes)
    }
}

// TODO(#1307)
impl ser::Serialize for EventKey {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        serializer.serialize_bytes(&self.0)
    }
}

impl<'de> de::Deserialize<'de> for EventKey {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        struct EventKeyVisitor;

        impl<'de> de::Visitor<'de> for EventKeyVisitor {
            type Value = EventKey;

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                formatter.write_str("EventKey in bytes")
            }

            fn visit_bytes<E>(self, value: &[u8]) -> std::result::Result<Self::Value, E>
            where
                E: de::Error,
            {
                EventKey::try_from(value).map_err(E::custom)
            }
        }

        deserializer.deserialize_bytes(EventKeyVisitor)
    }
}

impl TryFrom<&[u8]> for EventKey {
    type Error = Error;

    /// Tries to convert the provided byte array into Event Key.
    fn try_from(bytes: &[u8]) -> Result<EventKey> {
        ensure!(
            bytes.len() == EVENT_KEY_LENGTH,
            "The Address {:?} is of invalid length",
            bytes
        );
        let mut addr = [0u8; EVENT_KEY_LENGTH];
        addr.copy_from_slice(bytes);
        Ok(EventKey(addr))
    }
}

/// A Rust representation of an Event Handle Resource.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EventHandle {
    /// Number of events in the event stream.
    count: u64,
    /// The associated globally unique key that is used as the key to the EventStore.
    key: EventKey,
}

impl EventHandle {
    /// Constructs a new Event Handle
    pub fn new(key: EventKey, count: u64) -> Self {
        EventHandle { key, count }
    }

    /// Return the key to where this event is stored in EventStore.
    pub fn key(&self) -> &EventKey {
        &self.key
    }
    /// Return the counter for the handle
    pub fn count(&self) -> u64 {
        self.count
    }

    #[cfg(feature = "fuzzing")]
    pub fn count_mut(&mut self) -> &mut u64 {
        &mut self.count
    }

    #[cfg(feature = "fuzzing")]
    /// Create a random event handle for testing
    pub fn random_handle(count: u64) -> Self {
        Self {
            key: EventKey::random(),
            count,
        }
    }

    #[cfg(feature = "fuzzing")]
    /// Derive a unique handle by using an AccountAddress and a counter.
    pub fn new_from_address(addr: &AccountAddress, salt: u64) -> Self {
        Self {
            key: EventKey::new_from_address(addr, salt),
            count: 0,
        }
    }
}

impl fmt::LowerHex for EventKey {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", hex::encode(self.as_bytes()))
    }
}

impl fmt::Display for EventKey {
    fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
        // Forward to the LowerHex impl with a "0x" prepended (the # flag).
        write!(f, "{:#x}", self)
    }
}
<|endoftext|>


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

use self::chain::types::NoopAdapter;
use self::chain::types::Options;
use self::chain::Chain;
use self::core::core::hash::Hashed;
use self::core::core::verifier_cache::LruVerifierCache;
use self::core::core::Block;
use self::core::genesis;
use self::core::global::ChainTypes;
use self::core::libtx::{self, reward};
use self::core::{consensus, global, pow};
use self::keychain::{ExtKeychainPath, Keychain};
use self::util::RwLock;
use chrono::Duration;
use grin_chain as chain;
use grin_core as core;
use grin_keychain as keychain;
use grin_util as util;
use std::fs;
use std::sync::Arc;

pub fn clean_output_dir(dir_name: &str) {
	let _ = fs::remove_dir_all(dir_name);
}

pub fn init_chain(dir_name: &str, genesis: Block) -> Chain {
	let verifier_cache = Arc::new(RwLock::new(LruVerifierCache::new()));
	Chain::init(
		dir_name.to_string(),
		Arc::new(NoopAdapter {}),
		genesis,
		pow::verify_size,
		verifier_cache,
		false,
	)
	.unwrap()
}

/// Build genesis block with reward (non-empty, like we have in mainnet).
fn genesis_block<K>(keychain: &K) -> Block
where
	K: Keychain,
{
	let key_id = keychain::ExtKeychain::derive_key_id(0, 1, 0, 0, 0);
	let reward = reward::output(
		keychain,
		&libtx::ProofBuilder::new(keychain),
		&key_id,
		0,
		false,
	)
	.unwrap();

	genesis::genesis_dev().with_reward(reward.0, reward.1)
}

/// Mine a chain of specified length to assist with automated tests.
/// Probably a good idea to call clean_output_dir at the beginning and end of each test.
pub fn mine_chain(dir_name: &str, chain_length: u64) -> Chain {
	global::set_mining_mode(ChainTypes::AutomatedTesting);
	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
	let genesis = genesis_block(&keychain);
	let mut chain = init_chain(dir_name, genesis.clone());
	mine_some_on_top(&mut chain, chain_length, &keychain);
	chain
}

fn mine_some_on_top<K>(chain: &mut Chain, chain_length: u64, keychain: &K)
where
	K: Keychain,
{
	for n in 1..chain_length {
		let prev = chain.head_header().unwrap();
		let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
		let pk = ExtKeychainPath::new(1, n as u32, 0, 0, 0).to_identifier();
		let reward =
			libtx::reward::output(keychain, &libtx::ProofBuilder::new(keychain), &pk, 0, false)
				.unwrap();
		let mut b =
			core::core::Block::new(&prev, vec![], next_header_info.clone().difficulty, reward)
				.unwrap();
		b.header.timestamp = prev.timestamp + Duration::seconds(60);
		b.header.pow.secondary_scaling = next_header_info.secondary_scaling;

		chain.set_txhashset_roots(&mut b).unwrap();

		let edge_bits = if n == 2 {
			global::min_edge_bits() + 1
		} else {
			global::min_edge_bits()
		};
		b.header.pow.proof.edge_bits = edge_bits;
		pow::pow_size(
			&mut b.header,
			next_header_info.difficulty,
			global::proofsize(),
			edge_bits,
		)
		.unwrap();
		b.header.pow.proof.edge_bits = edge_bits;

		let bhash = b.hash();
		chain.process_block(b, Options::MINE).unwrap();

		// checking our new head
		let head = chain.head().unwrap();
		assert_eq!(head.height, n);
		assert_eq!(head.last_block_h, bhash);

		// now check the block_header of the head
		let header = chain.head_header().unwrap();
		assert_eq!(header.height, n);
		assert_eq!(header.hash(), bhash);

		// now check the block itself
		let block = chain.get_block(&header.hash()).unwrap();
		assert_eq!(block.header.height, n);
		assert_eq!(block.hash(), bhash);
		assert_eq!(block.outputs().len(), 1);

		// now check the block height index
		let header_by_height = chain.get_header_by_height(n).unwrap();
		assert_eq!(header_by_height.hash(), bhash);

		chain.validate(false).unwrap();
	}
}
<commit_msg>cleanup weird egde_bits handling in tests (#3316)<commit_after>// Copyright 2020 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use self::chain::types::NoopAdapter;
use self::chain::types::Options;
use self::chain::Chain;
use self::core::core::hash::Hashed;
use self::core::core::verifier_cache::LruVerifierCache;
use self::core::core::Block;
use self::core::genesis;
use self::core::global::ChainTypes;
use self::core::libtx::{self, reward};
use self::core::{consensus, global, pow};
use self::keychain::{ExtKeychainPath, Keychain};
use self::util::RwLock;
use chrono::Duration;
use grin_chain as chain;
use grin_core as core;
use grin_keychain as keychain;
use grin_util as util;
use std::fs;
use std::sync::Arc;

pub fn clean_output_dir(dir_name: &str) {
	let _ = fs::remove_dir_all(dir_name);
}

pub fn init_chain(dir_name: &str, genesis: Block) -> Chain {
	let verifier_cache = Arc::new(RwLock::new(LruVerifierCache::new()));
	Chain::init(
		dir_name.to_string(),
		Arc::new(NoopAdapter {}),
		genesis,
		pow::verify_size,
		verifier_cache,
		false,
	)
	.unwrap()
}

/// Build genesis block with reward (non-empty, like we have in mainnet).
fn genesis_block<K>(keychain: &K) -> Block
where
	K: Keychain,
{
	let key_id = keychain::ExtKeychain::derive_key_id(0, 1, 0, 0, 0);
	let reward = reward::output(
		keychain,
		&libtx::ProofBuilder::new(keychain),
		&key_id,
		0,
		false,
	)
	.unwrap();

	genesis::genesis_dev().with_reward(reward.0, reward.1)
}

/// Mine a chain of specified length to assist with automated tests.
/// Probably a good idea to call clean_output_dir at the beginning and end of each test.
pub fn mine_chain(dir_name: &str, chain_length: u64) -> Chain {
	global::set_mining_mode(ChainTypes::AutomatedTesting);
	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
	let genesis = genesis_block(&keychain);
	let mut chain = init_chain(dir_name, genesis.clone());
	mine_some_on_top(&mut chain, chain_length, &keychain);
	chain
}

fn mine_some_on_top<K>(chain: &mut Chain, chain_length: u64, keychain: &K)
where
	K: Keychain,
{
	for n in 1..chain_length {
		let prev = chain.head_header().unwrap();
		let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
		let pk = ExtKeychainPath::new(1, n as u32, 0, 0, 0).to_identifier();
		let reward =
			libtx::reward::output(keychain, &libtx::ProofBuilder::new(keychain), &pk, 0, false)
				.unwrap();
		let mut b =
			core::core::Block::new(&prev, vec![], next_header_info.clone().difficulty, reward)
				.unwrap();
		b.header.timestamp = prev.timestamp + Duration::seconds(60);
		b.header.pow.secondary_scaling = next_header_info.secondary_scaling;

		chain.set_txhashset_roots(&mut b).unwrap();

		let edge_bits = global::min_edge_bits();
		b.header.pow.proof.edge_bits = edge_bits;
		pow::pow_size(
			&mut b.header,
			next_header_info.difficulty,
			global::proofsize(),
			edge_bits,
		)
		.unwrap();

		let bhash = b.hash();
		chain.process_block(b, Options::MINE).unwrap();

		// checking our new head
		let head = chain.head().unwrap();
		assert_eq!(head.height, n);
		assert_eq!(head.last_block_h, bhash);

		// now check the block_header of the head
		let header = chain.head_header().unwrap();
		assert_eq!(header.height, n);
		assert_eq!(header.hash(), bhash);

		// now check the block itself
		let block = chain.get_block(&header.hash()).unwrap();
		assert_eq!(block.header.height, n);
		assert_eq!(block.hash(), bhash);
		assert_eq!(block.outputs().len(), 1);

		// now check the block height index
		let header_by_height = chain.get_header_by_height(n).unwrap();
		assert_eq!(header_by_height.hash(), bhash);

		chain.validate(false).unwrap();
	}
}
<|endoftext|>


<commit_before>use std::vec::Vec;

use engine::{Actor, Map};
use engine::builders::MapFromString;
use util::units::{Direction, Point};

pub struct World {
    pub player: Actor,
    pub actors: Vec<Actor>,
    pub map: Map,
}

impl World {

    pub fn new() -> World {
        World {
            player: Actor::new("Player".to_string(), Point::new(1, 1), 100, '@'),
            actors: Vec::new(),
            map: Map::from_builder(MapFromString::new("")),
        }
    }

    pub fn walk(&mut self, direction: Direction) {
        if !self.map.is_walkable(self.player.pos) { return; }

        self.player.walk(direction);
    }

}
<commit_msg>Add a small 5x5 test map<commit_after>use std::vec::Vec;

use engine::{Actor, Map};
use engine::builders::MapFromString;
use util::units::{Direction, Point};

pub struct World {
    pub player: Actor,
    pub actors: Vec<Actor>,
    pub map: Map,
}

impl World {

    pub fn new() -> World {
        World {
            player: Actor::new("Player".to_string(), Point::new(1, 1), 100, '@'),
            actors: Vec::new(),
            map: Map::from_builder(MapFromString::new("#####\n#   #\n#   #\n#   #\n#####")),
        }
    }

    pub fn walk(&mut self, direction: Direction) {
        if !self.map.is_walkable(self.player.pos) { return; }

        self.player.walk(direction);
    }

}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use ast::{Function, Expr, Statement};
use rich_number::RichNumber;
use prelude::setup_prelude;

const LOWEST_PRECEDENCE: u8 = 0;
const HIGHEST_PRECEDENCE: u8 = 9;
const FUNCTION_PRECEDENCE: u8 = HIGHEST_PRECEDENCE;

#[derive(PartialEq, Debug)]
pub enum EvalError {
    UnknownSymbol(String),
}

pub type EvalResult = Result<ContextItem, EvalError>;

#[derive(Eq, PartialEq, Debug, Clone)]
pub enum Fixity {
    Prefix,
    Infix,
    Postfix,
}

#[derive(PartialEq, Debug, Clone)]
pub enum ContextItem {
    Number(RichNumber),
    Definition {
        // number from 0 to 9 where 9 is the highest precedence
        precedence: u8,
        fixity: Fixity,
        function: Function,
    },
    BuiltInMethod(fn(Vec<ContextItem>) -> EvalResult),
    Constant(String),
    Boolean(bool),
    Nothing,
}

impl ContextItem {
    pub fn unwrap_number(self) -> RichNumber {
        match self {
            ContextItem::Number(num) => num,
            _ => panic!("Expected to unwrap a Number"),
        }
    }

    pub fn unwrap_boolean(self) -> bool {
        match self {
            ContextItem::Boolean(value) => value,
            _ => panic!("Expected to unwrap a Boolean"),
        }
    }
}

pub struct EvalContext {
    symbol_table: HashMap<String, ContextItem>,
}

impl EvalContext {
    pub fn new() -> EvalContext {
        EvalContext {
            symbol_table: HashMap::new(),
        }
    }

    pub fn prelude() -> EvalContext {
        let mut context = EvalContext::new();
        setup_prelude(&mut context);
        context
    }

    /// Gets a single value without evaluating it from the current context
    pub fn get(&self, name: &str) -> Option<ContextItem> {
        self.symbol_table.get(name).map(|item| (*item).clone())
    }

    /// Convenience method for setting a number in the context
    pub fn set_number(&mut self, name: &str, value: RichNumber) {
        self.set(name, ContextItem::Number(value))
    }

    /// Defines a function in the context
    pub fn define(&mut self, name: &str, fixity: Fixity, precedence: u8, function: Function) {
        debug_assert!(precedence >= LOWEST_PRECEDENCE && precedence <= HIGHEST_PRECEDENCE);

        self.set(name, ContextItem::Definition {
            fixity: fixity,
            precedence: precedence,
            function: function,
        });
    }

    /// Defines a function linked to actual code rather than an expression
    pub fn define_builtin_method<F>(
        &mut self,
        name: &str,
        method: fn(Vec<ContextItem>
    ) -> EvalResult) {

        self.set(name, ContextItem::BuiltInMethod(method));
    }

    /// Creates a constant value
    pub fn set_constant(&mut self, name: &str, value: String) {
        self.set(name, ContextItem::Constant(value));
    }

    /// Creates a boolean value
    pub fn set_boolean(&mut self, name: &str, value: bool) {
        self.set(name, ContextItem::Boolean(value));
    }

    /// Adds to the current context (silently replaces if already present)
    pub fn set(&mut self, name: &str, value: ContextItem) {
        self.symbol_table.insert(name.to_owned(), value);
    }

    pub fn apply(&mut self, statement: Statement) -> EvalResult {
        match statement {
            Statement::NamedFunction {name, definition} => {
                self.define(&name, Fixity::Prefix, FUNCTION_PRECEDENCE, definition);
                Ok(ContextItem::Nothing)
            },
            Statement::AnonymousFunction(_) => Ok(ContextItem::Nothing),
            Statement::Assignment {name, value} => {
                let value = try!(self.evaluate(value));
                self.set(&name, value);
                Ok(ContextItem::Nothing)
            },
            Statement::Expression(value) => self.evaluate(value),
        }
    }

    fn evaluate(&mut self, expr: Expr) -> EvalResult {
        unimplemented!();
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ast::*;
    use api::parse;
    use rich_number::RichNumber;

    #[test]
    fn get_set_in_context() {
        let mut context = EvalContext::new();
        assert_eq!(context.get("a"), None);

        let value = RichNumber::from(2f64);
        context.set_number("a", value.clone());
        assert_eq!(context.get("a").map(|n| n.unwrap_number()), Some(value));
    }

    #[test]
    fn define_variable() {
        let mut context = EvalContext::new();
        apply_string(&mut context, "x = 3");

        assert_eq!(context.get("x").map(|n| n.unwrap_number()), Some(RichNumber::from(3f64)));
    }

    #[test]
    fn basic_operators_and_precedence() {
        let result = apply_single("2 * 3 ** 2 - (100e-1 + -77.2) / 13").unwrap();
        assert_eq!(result.unwrap_number(), RichNumber::from(23.1692307692f64));
    }

    fn test_single_boolean(string: &str, expected: bool) {
        let result = apply_single(string).unwrap();
        assert_eq!(result.unwrap_boolean(), expected);
    }

    fn apply_single(string: &str) -> EvalResult {
        let mut context = EvalContext::new();
        let statement = parse_statement(string);

        context.apply(statement)
    }

    fn parse_statement(string: &str) -> Statement {
        let mut parsed = parse(string).unwrap();
        assert!(parsed.len() == 1, "parse_statement() was passed more than one statement");

        parsed.pop().unwrap()
    }

    fn apply_string(mut context: &mut EvalContext, string: &str) {
        apply_program(context, parse(string).unwrap());
    }

    fn apply_program(mut context: &mut EvalContext, program: Program) {
        for statement in program {
            context.apply(statement).expect("Error while applying statement");
        }
    }
}

<commit_msg>Converting expressions to EvalTreeNodes<commit_after>use std::collections::HashMap;

use ast::{Function, Expr, ExprItem, Term, Statement};
use rich_number::RichNumber;
use prelude::setup_prelude;

const LOWEST_PRECEDENCE: u8 = 0;
const HIGHEST_PRECEDENCE: u8 = 9;
const FUNCTION_PRECEDENCE: u8 = HIGHEST_PRECEDENCE;

#[derive(PartialEq, Debug)]
pub enum EvalError {
    UnknownSymbol(String),
}

pub type EvalResult = Result<ContextItem, EvalError>;

#[derive(Debug, Clone)]
struct EvalTreeNode {
    item: ContextItem,
    children: Vec<EvalTreeNode>,
}

impl EvalTreeNode {
    fn new(item: ContextItem) -> EvalTreeNode {
        EvalTreeNode {
            item: item,
            children: Vec::new(),
        }
    }
}

#[derive(Eq, PartialEq, Debug, Clone)]
pub enum Fixity {
    Prefix,
    Infix,
    Postfix,
}

#[derive(PartialEq, Debug, Clone)]
pub enum ContextItem {
    Number(RichNumber),
    Definition {
        // number from 0 to 9 where 9 is the highest precedence
        precedence: u8,
        fixity: Fixity,
        function: Function,
    },
    BuiltInMethod(fn(Vec<ContextItem>) -> EvalResult),
    Constant(String),
    Boolean(bool),
    Nothing,
}

impl ContextItem {
    pub fn unwrap_number(self) -> RichNumber {
        match self {
            ContextItem::Number(num) => num,
            _ => panic!("Expected to unwrap a Number"),
        }
    }

    pub fn unwrap_boolean(self) -> bool {
        match self {
            ContextItem::Boolean(value) => value,
            _ => panic!("Expected to unwrap a Boolean"),
        }
    }
}

pub struct EvalContext {
    symbol_table: HashMap<String, ContextItem>,
}

impl EvalContext {
    pub fn new() -> EvalContext {
        EvalContext {
            symbol_table: HashMap::new(),
        }
    }

    pub fn prelude() -> EvalContext {
        let mut context = EvalContext::new();
        setup_prelude(&mut context);
        context
    }

    /// Gets a single value without evaluating it from the current context
    pub fn get(&self, name: &str) -> Option<ContextItem> {
        self.symbol_table.get(name).map(|item| (*item).clone())
    }

    /// Convenience method for setting a number in the context
    pub fn set_number(&mut self, name: &str, value: RichNumber) {
        self.set(name, ContextItem::Number(value))
    }

    /// Defines a function in the context
    pub fn define(&mut self, name: &str, fixity: Fixity, precedence: u8, function: Function) {
        debug_assert!(precedence >= LOWEST_PRECEDENCE && precedence <= HIGHEST_PRECEDENCE);

        self.set(name, ContextItem::Definition {
            fixity: fixity,
            precedence: precedence,
            function: function,
        });
    }

    /// Defines a function linked to actual code rather than an expression
    pub fn define_builtin_method<F>(
        &mut self,
        name: &str,
        method: fn(Vec<ContextItem>
    ) -> EvalResult) {

        self.set(name, ContextItem::BuiltInMethod(method));
    }

    /// Creates a constant value
    pub fn set_constant(&mut self, name: &str, value: String) {
        self.set(name, ContextItem::Constant(value));
    }

    /// Creates a boolean value
    pub fn set_boolean(&mut self, name: &str, value: bool) {
        self.set(name, ContextItem::Boolean(value));
    }

    /// Adds to the current context (silently replaces if already present)
    pub fn set(&mut self, name: &str, value: ContextItem) {
        self.symbol_table.insert(name.to_owned(), value);
    }

    pub fn apply(&mut self, statement: Statement) -> EvalResult {
        match statement {
            Statement::NamedFunction {name, definition} => {
                self.define(&name, Fixity::Prefix, FUNCTION_PRECEDENCE, definition);
                Ok(ContextItem::Nothing)
            },
            Statement::AnonymousFunction(_) => Ok(ContextItem::Nothing),
            Statement::Assignment {name, value} => {
                let value = try!(self.evaluate(value));
                self.set(&name, value);
                Ok(ContextItem::Nothing)
            },
            Statement::Expression(value) => self.evaluate(value),
        }
    }

    fn evaluate(&mut self, expr: Expr) -> EvalResult {
        let root = try!(self.build_eval_tree(expr));

        unimplemented!();
    }

    /// Builds an evaluation tree and returns the root node
    fn build_eval_tree(&self, expr: Expr) -> Result<EvalTreeNode, EvalError> {
        let nodes = try!(self.convert_to_nodes(expr));

        unimplemented!();
    }

    fn convert_to_nodes(&self, expr: Expr) -> Result<Vec<EvalTreeNode>, EvalError> {
        let mut nodes: Vec<EvalTreeNode> = Vec::new();

        for item in expr.into_iter() {
            nodes.push(match item {
                ExprItem::AnonymousFunction(function) => {
                    EvalTreeNode::new(ContextItem::Definition {
                        precedence: FUNCTION_PRECEDENCE,
                        fixity: Fixity::Prefix,
                        function: function,
                    })
                },
                ExprItem::SingleTerm(term) => match term {
                    Term::Symbol(sym) => {
                        let item = self.get(&sym);
                        if item.is_none() {
                            return Err(EvalError::UnknownSymbol(sym));
                        }
                        EvalTreeNode::new(item.unwrap())
                    },
                    Term::Number(num) => {
                        EvalTreeNode::new(
                            ContextItem::Number(
                                RichNumber::from(num)
                            )
                        )
                    },
                    Term::StringLiteral(value) => {
                        EvalTreeNode::new(
                            ContextItem::Constant(value)
                        )
                    },
                },
                ExprItem::Group(expr) => try!(self.build_eval_tree(expr)),
            });
        }

        Ok(nodes)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ast::*;
    use api::parse;
    use rich_number::RichNumber;

    #[test]
    fn get_set_in_context() {
        let mut context = EvalContext::new();
        assert_eq!(context.get("a"), None);

        let value = RichNumber::from(2f64);
        context.set_number("a", value.clone());
        assert_eq!(context.get("a").map(|n| n.unwrap_number()), Some(value));
    }

    #[test]
    fn define_variable() {
        let mut context = EvalContext::new();
        apply_string(&mut context, "x = 3");

        assert_eq!(context.get("x").map(|n| n.unwrap_number()), Some(RichNumber::from(3f64)));
    }

    #[test]
    fn basic_operators_and_precedence() {
        let result = apply_single("2 * 3 ** 2 - (100e-1 + -77.2) / 13").unwrap();
        assert_eq!(result.unwrap_number(), RichNumber::from(23.1692307692f64));
    }

    fn test_single_boolean(string: &str, expected: bool) {
        let result = apply_single(string).unwrap();
        assert_eq!(result.unwrap_boolean(), expected);
    }

    fn apply_single(string: &str) -> EvalResult {
        let mut context = EvalContext::new();
        let statement = parse_statement(string);

        context.apply(statement)
    }

    fn parse_statement(string: &str) -> Statement {
        let mut parsed = parse(string).unwrap();
        assert!(parsed.len() == 1, "parse_statement() was passed more than one statement");

        parsed.pop().unwrap()
    }

    fn apply_string(mut context: &mut EvalContext, string: &str) {
        apply_program(context, parse(string).unwrap());
    }

    fn apply_program(mut context: &mut EvalContext, program: Program) {
        for statement in program {
            context.apply(statement).expect("Error while applying statement");
        }
    }
}

<|endoftext|>


<commit_before>use std::iter::AdditiveIterator;
use std::num::{min, max, sqrt, next_power_of_two};
use std::vec;
use std::iter::Iterator;

use cgmath::aabb::{Aabb, Aabb2};
use cgmath::point::{Point, Point2};
use cgmath::vector::Vec2;

use calx::pack_rect::pack_rects;
use calx::rectutil::RectUtil;
use texture::Texture;
use stb;

#[deriving(Clone)]
pub struct Sprite {
    priv bounds: Aabb2<int>,
    priv data: ~[u8],
}

impl Sprite {
    // Only supporting alpha channel for now.
    pub fn new_alpha(bounds: &Aabb2<int>, data: ~[u8]) -> Sprite {
        let bpp = 1;
        assert!(data.len() / bpp == bounds.volume() as uint);

        let mut ret = Sprite {
            bounds: *bounds,
            data: data
        };
        ret.crop();
        ret
    }

    #[inline]
    pub fn contains(&self, pos: &Point2<int>) -> bool {
        self.bounds.contains(pos)
    }

    #[inline]
    pub fn at(&self, pos: &Point2<int>) -> u8 {
        if self.contains(pos) {
            self.data[self.bounds.scan_pos(pos)]
        } else {
            0u8
        }
    }

    pub fn crop(&mut self) {
        let (mut min_x, mut min_y) = (self.bounds.max().x, self.bounds.max().y);
        let (mut max_x, mut max_y) = (self.bounds.min().x - 1, self.bounds.min().y - 1);
        for p in self.bounds.points() {
            if self.at(&p) > 0u8 {
                min_x = min(min_x, p.x);
                min_y = min(min_y, p.y);
                max_x = max(max_x, p.x + 1);
                max_y = max(max_y, p.y + 1);
            }
        }
        if min_x >= max_x || min_y >= max_y {
            // Empty area.
            self.data = ~[];
            self.bounds = RectUtil::new(0, 0, 0, 0);
            return;
        }
        // TODO: Shrink bounds, create new data array.
    }
}

pub struct AtlasRect {
    bounds: Aabb2<f32>,
    texcoords: Aabb2<f32>,
}

impl AtlasRect {
    pub fn new(
        bounds_intrect: &Aabb2<int>,
        tex_intrect: &Aabb2<int>,
        tex_dim: &Vec2<int>) -> AtlasRect {
        let tex_scale = Vec2::new(1f32 / tex_dim.x as f32, 1f32 / tex_dim.y as f32);
        return AtlasRect {
            bounds: to_float_rect(bounds_intrect, &Vec2::new(1f32, 1f32)),
            texcoords: to_float_rect(tex_intrect, &tex_scale),
        };

        fn to_float_rect(rect: &Aabb2<int>, scale: &Vec2<f32>) -> Aabb2<f32> {
            RectUtil::new(
                rect.min().x as f32 * scale.x, rect.min().y as f32 * scale.y,
                rect.max().x as f32 * scale.x, rect.max().y as f32 * scale.y)
        }
    }
}

pub struct Atlas {
    sprites: ~[~Sprite],
    rects: ~[AtlasRect],
    is_dirty: bool,
    texture: ~Texture,
}

impl Atlas {
    pub fn new() -> Atlas {
        Atlas {
            sprites: ~[],
            rects: ~[],
            is_dirty: true,
            texture: ~Texture::new_alpha(0, 0, []),
        }
    }

    pub fn dirty(&mut self) {
        self.is_dirty = true;
    }

    pub fn clean(&mut self) {
        // Already good?
        if !self.is_dirty { return; }

        // Create gaps between the sprites to prevent edge artifacts.
        let dims = self.sprites.map(|s| s.bounds.dim() + Vec2::new(1, 1));
        let total_volume = dims.iter().map(|&v| v.x * v.y).sum();
        let atlas_dim = next_power_of_two(sqrt(total_volume as f64) as uint) as int;

        let base = RectUtil::new(0, 0, atlas_dim, atlas_dim);
        let (base, pack) = pack_rects(&base, dims);
        // Cut off the extra padding
        let pack : ~[Aabb2<int>] = pack.iter().map(|&rect| Aabb2::new(
                rect.min(), &rect.max().add_v(&Vec2::new(-1, -1)))).collect();

        let mut tex_data = vec::from_elem(base.volume() as uint, 0u8);

        assert!(pack.len() == self.sprites.len());
        self.rects = ~[];

        for i in range(0, self.sprites.len()) {
            paint_sprite(
                self.sprites[i], tex_data, &pack[i].min().to_vec(), base.dim().x);
            self.rects.push(AtlasRect::new(
                    &self.sprites[i].bounds, &pack[i], &base.dim()));
        }

        self.texture = ~Texture::new_alpha(base.dim().x as uint, base.dim().y as uint, tex_data);
        self.is_dirty = false;

        fn paint_sprite(sprite: &Sprite, tex_data: &mut [u8], offset: &Vec2<int>, tex_pitch: int) {
            let offset = offset - sprite.bounds.min().to_vec();
            for p in sprite.bounds.points() {
                tex_data[p.x + offset.x + (p.y + offset.y) * tex_pitch] = sprite.at(&p);
            }
        }
    }

    pub fn push(&mut self, sprite: ~Sprite) {
        self.dirty();
        self.sprites.push(sprite);
    }

    pub fn push_ttf(
        &mut self, ttf_data: ~[u8], size: f32,
        start_char: uint, num_chars: uint) {
        let font = stb::truetype::Font::new(ttf_data).expect("Bad ttf data.");
        for i in range(start_char, start_char + num_chars) {
            let glyph = font.glyph(i, size).expect("Font missing expected char");
            let min = Point2::new(glyph.xOffset as int, glyph.yOffset as int);
            let max = min.add_v(&Vec2::new(glyph.width, glyph.height));
            self.push(~Sprite::new_alpha(&Aabb2::new(&min, &max), glyph.pixels));
        }
    }

    pub fn len(&self) -> uint {
        self.sprites.len()
    }

    pub fn get(&mut self, i: uint) -> AtlasRect {
        self.clean();
        self.rects[i]
    }

    pub fn bind(&mut self) {
        self.clean();
        self.texture.bind();
    }
}
<commit_msg>Crop atlased sprites<commit_after>use std::iter::AdditiveIterator;
use std::num::{min, max, sqrt, next_power_of_two};
use std::vec;
use std::iter::Iterator;

use cgmath::aabb::{Aabb, Aabb2};
use cgmath::point::{Point, Point2};
use cgmath::vector::Vec2;

use calx::pack_rect::pack_rects;
use calx::rectutil::RectUtil;
use texture::Texture;
use stb;

#[deriving(Clone)]
pub struct Sprite {
    priv bounds: Aabb2<int>,
    priv data: ~[u8],
}

impl Sprite {
    // Only supporting alpha channel for now.
    pub fn new_alpha(bounds: &Aabb2<int>, data: ~[u8]) -> Sprite {
        let bpp = 1;
        assert!(data.len() / bpp == bounds.volume() as uint);

        let mut ret = Sprite {
            bounds: *bounds,
            data: data
        };
        ret.crop();
        ret
    }

    #[inline]
    pub fn contains(&self, pos: &Point2<int>) -> bool {
        self.bounds.contains(pos)
    }

    #[inline]
    pub fn at(&self, pos: &Point2<int>) -> u8 {
        if self.contains(pos) {
            self.data[self.bounds.scan_pos(pos)]
        } else {
            0u8
        }
    }

    pub fn crop(&mut self) {
        let (mut min_x, mut min_y) = (self.bounds.max().x, self.bounds.max().y);
        let (mut max_x, mut max_y) = (self.bounds.min().x - 1, self.bounds.min().y - 1);
        for p in self.bounds.points() {
            if self.at(&p) > 0u8 {
                min_x = min(min_x, p.x);
                min_y = min(min_y, p.y);
                max_x = max(max_x, p.x + 1);
                max_y = max(max_y, p.y + 1);
            }
        }
        if min_x >= max_x || min_y >= max_y {
            // Empty area.
            self.data = ~[];
            self.bounds = RectUtil::new(0, 0, 0, 0);
            return;
        }
        let new_bounds : Aabb2<int> = RectUtil::new(min_x, min_y, max_x, max_y);
        if new_bounds != self.bounds {
            assert!(
                new_bounds.min().x > self.bounds.min().x ||
                new_bounds.min().y > self.bounds.min().y ||
                new_bounds.max().x < self.bounds.max().x ||
                new_bounds.max().y < self.bounds.max().y);
            let mut new_data = vec::from_elem(new_bounds.volume() as uint, 0u8);
            for p in new_bounds.points() {
                new_data[new_bounds.scan_pos(&p)] =
                    self.data[self.bounds.scan_pos(&p)];
            }
            self.data = new_data;
            self.bounds = new_bounds;
        }
    }
}

pub struct AtlasRect {
    bounds: Aabb2<f32>,
    texcoords: Aabb2<f32>,
}

impl AtlasRect {
    pub fn new(
        bounds_intrect: &Aabb2<int>,
        tex_intrect: &Aabb2<int>,
        tex_dim: &Vec2<int>) -> AtlasRect {
        let tex_scale = Vec2::new(1f32 / tex_dim.x as f32, 1f32 / tex_dim.y as f32);
        return AtlasRect {
            bounds: to_float_rect(bounds_intrect, &Vec2::new(1f32, 1f32)),
            texcoords: to_float_rect(tex_intrect, &tex_scale),
        };

        fn to_float_rect(rect: &Aabb2<int>, scale: &Vec2<f32>) -> Aabb2<f32> {
            RectUtil::new(
                rect.min().x as f32 * scale.x, rect.min().y as f32 * scale.y,
                rect.max().x as f32 * scale.x, rect.max().y as f32 * scale.y)
        }
    }
}

pub struct Atlas {
    sprites: ~[~Sprite],
    rects: ~[AtlasRect],
    is_dirty: bool,
    texture: ~Texture,
}

impl Atlas {
    pub fn new() -> Atlas {
        Atlas {
            sprites: ~[],
            rects: ~[],
            is_dirty: true,
            texture: ~Texture::new_alpha(0, 0, []),
        }
    }

    pub fn dirty(&mut self) {
        self.is_dirty = true;
    }

    pub fn clean(&mut self) {
        // Already good?
        if !self.is_dirty { return; }

        // Create gaps between the sprites to prevent edge artifacts.
        let dims = self.sprites.map(|s| s.bounds.dim() + Vec2::new(1, 1));
        let total_volume = dims.iter().map(|&v| v.x * v.y).sum();
        let atlas_dim = next_power_of_two(sqrt(total_volume as f64) as uint) as int;

        let base = RectUtil::new(0, 0, atlas_dim, atlas_dim);
        let (base, pack) = pack_rects(&base, dims);
        // Cut off the extra padding
        let pack : ~[Aabb2<int>] = pack.iter().map(|&rect| Aabb2::new(
                rect.min(), &rect.max().add_v(&Vec2::new(-1, -1)))).collect();

        let mut tex_data = vec::from_elem(base.volume() as uint, 0u8);

        assert!(pack.len() == self.sprites.len());
        self.rects = ~[];

        for i in range(0, self.sprites.len()) {
            paint_sprite(
                self.sprites[i], tex_data, &pack[i].min().to_vec(), base.dim().x);
            self.rects.push(AtlasRect::new(
                    &self.sprites[i].bounds, &pack[i], &base.dim()));
        }

        self.texture = ~Texture::new_alpha(base.dim().x as uint, base.dim().y as uint, tex_data);
        self.is_dirty = false;

        fn paint_sprite(sprite: &Sprite, tex_data: &mut [u8], offset: &Vec2<int>, tex_pitch: int) {
            let offset = offset - sprite.bounds.min().to_vec();
            for p in sprite.bounds.points() {
                tex_data[p.x + offset.x + (p.y + offset.y) * tex_pitch] = sprite.at(&p);
            }
        }
    }

    pub fn push(&mut self, sprite: ~Sprite) {
        self.dirty();
        self.sprites.push(sprite);
    }

    pub fn push_ttf(
        &mut self, ttf_data: ~[u8], size: f32,
        start_char: uint, num_chars: uint) {
        let font = stb::truetype::Font::new(ttf_data).expect("Bad ttf data.");
        for i in range(start_char, start_char + num_chars) {
            let glyph = font.glyph(i, size).expect("Font missing expected char");
            let min = Point2::new(glyph.xOffset as int, glyph.yOffset as int);
            let max = min.add_v(&Vec2::new(glyph.width, glyph.height));
            self.push(~Sprite::new_alpha(&Aabb2::new(&min, &max), glyph.pixels));
        }
    }

    pub fn len(&self) -> uint {
        self.sprites.len()
    }

    pub fn get(&mut self, i: uint) -> AtlasRect {
        self.clean();
        self.rects[i]
    }

    pub fn bind(&mut self) {
        self.clean();
        self.texture.bind();
    }
}
<|endoftext|>


<commit_before>#![cfg(feature = "use_std")]

use std::collections::HashMap;
use std::hash::Hash;
use std::iter::Iterator;

pub fn new<I, K, V>(iter: I) -> GroupingMap<I>
where
    I: Iterator<Item = (K, V)>,
    K: Hash + Eq,
{
    GroupingMap { iter }
}

pub struct GroupingMap<I> {
    iter: I,
}

impl<I, K, V> GroupingMap<I>
where
    I: Iterator<Item = (K, V)>,
    K: Hash + Eq,
{
    pub fn aggregate<FO, R>(mut self, mut operation: FO) -> HashMap<K, R>
    where
        FO: FnMut(Option<R>, &K, V) -> Option<R>,
    {
        let mut destination_map = HashMap::new();

        for (key, val) in self.iter {
            let acc = destination_map.remove(&key);
            if let Some(op_res) = operation(acc, &key, val) {
                destination_map.insert(key, op_res);
            }
        }

        destination_map
    }

    pub fn fold<FO, R>(self, init: R, mut operation: FO) -> HashMap<K, R>
    where
        R: Clone,
        FO: FnMut(R, &K, V) -> R,
    {
        self.aggregate(|acc, key, val| {
            let acc = acc.unwrap_or_else(|| init.clone());
            Some(operation(acc, key, val))
        })
    }

    pub fn fold_first<FO>(self, mut operation: FO) -> HashMap<K, V>
    where
        FO: FnMut(V, &K, V) -> V,
    {
        self.aggregate(|acc, key, val| {
            Some(match acc {
                Some(acc) => operation(acc, key, val),
                None => val,
            })
        })
    }

    pub fn collect<C>(self) -> HashMap<K, C>
    where
        C: Default + Extend<V>,
    {
        self.aggregate(|acc, _, v| {
            let mut acc = acc.unwrap_or_else(C::default);
            acc.extend(Some(v));
            Some(acc)
        })
    }

    pub fn count(self) -> HashMap<K, usize> {
        self.fold(0, |acc, _, _| acc + 1)
    }
}
<commit_msg>Added GroupingMap doc<commit_after>#![cfg(feature = "use_std")]

use std::collections::HashMap;
use std::hash::Hash;
use std::iter::Iterator;

/// Creates a new `GroupingMap` from `iter`
pub fn new<I, K, V>(iter: I) -> GroupingMap<I>
where
    I: Iterator<Item = (K, V)>,
    K: Hash + Eq,
{
    GroupingMap { iter }
}

/// `GroupingMap` is an intermediate struct for efficient "group-and-fold" operations.
/// It groups elements by their key and at the same time fold each group
/// using some aggregating operation.
///
/// No method on this struct performs temporary allocations.
///
// See [`.into_grouping_map()`](../trait.Itertools.html#method.into_grouping_map)
// for more information.
pub struct GroupingMap<I> {
    iter: I,
}

impl<I, K, V> GroupingMap<I>
where
    I: Iterator<Item = (K, V)>,
    K: Hash + Eq,
{
    pub fn aggregate<FO, R>(mut self, mut operation: FO) -> HashMap<K, R>
    where
        FO: FnMut(Option<R>, &K, V) -> Option<R>,
    {
        let mut destination_map = HashMap::new();

        for (key, val) in self.iter {
            let acc = destination_map.remove(&key);
            if let Some(op_res) = operation(acc, &key, val) {
                destination_map.insert(key, op_res);
            }
        }

        destination_map
    }

    pub fn fold<FO, R>(self, init: R, mut operation: FO) -> HashMap<K, R>
    where
        R: Clone,
        FO: FnMut(R, &K, V) -> R,
    {
        self.aggregate(|acc, key, val| {
            let acc = acc.unwrap_or_else(|| init.clone());
            Some(operation(acc, key, val))
        })
    }

    pub fn fold_first<FO>(self, mut operation: FO) -> HashMap<K, V>
    where
        FO: FnMut(V, &K, V) -> V,
    {
        self.aggregate(|acc, key, val| {
            Some(match acc {
                Some(acc) => operation(acc, key, val),
                None => val,
            })
        })
    }

    pub fn collect<C>(self) -> HashMap<K, C>
    where
        C: Default + Extend<V>,
    {
        self.aggregate(|acc, _, v| {
            let mut acc = acc.unwrap_or_else(C::default);
            acc.extend(Some(v));
            Some(acc)
        })
    }

    pub fn count(self) -> HashMap<K, usize> {
        self.fold(0, |acc, _, _| acc + 1)
    }
}
<|endoftext|>


<commit_before>use buffer::{Buffer, BufferSlice, BufferMutSlice, BufferAny, BufferType};
use buffer::{BufferMode, BufferCreationError};
use gl;
use BufferExt;
use GlObject;

use backend::Facade;

use index::IndicesSource;
use index::Index;
use index::IndexType;
use index::PrimitiveType;

use std::ops::{Deref, DerefMut};
use utils::range::RangeArgument;

/// Error that can happen while creating an index buffer.
#[derive(Debug, Copy, Clone)]
pub enum CreationError {
    /// The type of index is not supported by the backend.
    IndexTypeNotSupported,

    /// The type of primitives is not supported by the backend.
    PrimitiveTypeNotSupported,

    /// An error happened while creating the buffer.
    BufferCreationError(BufferCreationError),
}

impl From<BufferCreationError> for CreationError {
    #[inline]
    fn from(err: BufferCreationError) -> CreationError {
        CreationError::BufferCreationError(err)
    }
}

/// A list of indices loaded in the graphics card's memory.
#[derive(Debug)]
pub struct IndexBuffer<T> where T: Index {
    buffer: Buffer<[T]>,
    primitives: PrimitiveType,
}

impl<T> IndexBuffer<T> where T: Index {
    /// Builds a new index buffer from a list of indices and a primitive type.
    #[inline]
    pub fn new<F>(facade: &F, prim: PrimitiveType, data: &[T])
                  -> Result<IndexBuffer<T>, CreationError>
                  where F: Facade
    {
        IndexBuffer::new_impl(facade, prim, data, BufferMode::Default)
    }

    /// Builds a new index buffer from a list of indices and a primitive type.
    #[inline]
    pub fn dynamic<F>(facade: &F, prim: PrimitiveType, data: &[T])
                      -> Result<IndexBuffer<T>, CreationError>
                      where F: Facade
    {
        IndexBuffer::new_impl(facade, prim, data, BufferMode::Dynamic)
    }

    /// Builds a new index buffer from a list of indices and a primitive type.
    #[inline]
    pub fn persistent<F>(facade: &F, prim: PrimitiveType, data: &[T])
                         -> Result<IndexBuffer<T>, CreationError>
                         where F: Facade
    {
        IndexBuffer::new_impl(facade, prim, data, BufferMode::Persistent)
    }

    /// Builds a new index buffer from a list of indices and a primitive type.
    #[inline]
    pub fn immutable<F>(facade: &F, prim: PrimitiveType, data: &[T])
                        -> Result<IndexBuffer<T>, CreationError>
                        where F: Facade
    {
        IndexBuffer::new_impl(facade, prim, data, BufferMode::Immutable)
    }

    #[inline]
    fn new_impl<F>(facade: &F, prim: PrimitiveType, data: &[T], mode: BufferMode)
                   -> Result<IndexBuffer<T>, CreationError>
                   where F: Facade
    {
        if !prim.is_supported(facade) {
            return Err(CreationError::PrimitiveTypeNotSupported);
        }

        if !T::is_supported(facade) {
            return Err(CreationError::IndexTypeNotSupported);
        }

        Ok(IndexBuffer {
            buffer: try!(Buffer::new(facade, data, BufferType::ElementArrayBuffer, mode)).into(),
            primitives: prim,
        })
    }

    /// Builds a new empty index buffer.
    #[inline]
    pub fn empty<F>(facade: &F, prim: PrimitiveType, len: usize)
                    -> Result<IndexBuffer<T>, CreationError>
                    where F: Facade
    {
        IndexBuffer::empty_impl(facade, prim, len, BufferMode::Default)
    }

    /// Builds a new empty index buffer.
    #[inline]
    pub fn empty_dynamic<F>(facade: &F, prim: PrimitiveType, len: usize)
                            -> Result<IndexBuffer<T>, CreationError>
                            where F: Facade
    {
        IndexBuffer::empty_impl(facade, prim, len, BufferMode::Dynamic)
    }

    /// Builds a new empty index buffer.
    #[inline]
    pub fn empty_persistent<F>(facade: &F, prim: PrimitiveType, len: usize)
                               -> Result<IndexBuffer<T>, CreationError>
                               where F: Facade
    {
        IndexBuffer::empty_impl(facade, prim, len, BufferMode::Persistent)
    }

    /// Builds a new empty index buffer.
    #[inline]
    pub fn empty_immutable<F>(facade: &F, prim: PrimitiveType, len: usize)
                              -> Result<IndexBuffer<T>, CreationError>
                              where F: Facade
    {
        IndexBuffer::empty_impl(facade, prim, len, BufferMode::Immutable)
    }

    #[inline]
    fn empty_impl<F>(facade: &F, prim: PrimitiveType, len: usize, mode: BufferMode)
                     -> Result<IndexBuffer<T>, CreationError>
                     where F: Facade
    {
        if !prim.is_supported(facade) {
            return Err(CreationError::PrimitiveTypeNotSupported);
        }

        if !T::is_supported(facade) {
            return Err(CreationError::IndexTypeNotSupported);
        }

        Ok(IndexBuffer {
            buffer: try!(Buffer::empty_array(facade, BufferType::ElementArrayBuffer, len,
                                                 mode)).into(),
            primitives: prim,
        })
    }

    /// Returns the type of primitives associated with this index buffer.
    #[inline]
    pub fn get_primitives_type(&self) -> PrimitiveType {
        self.primitives
    }

    /// Returns the data type of the indices inside this index buffer.
    #[inline]
    pub fn get_indices_type(&self) -> IndexType {
        <T as Index>::get_type()
    }

    /// Returns `None` if out of range.
    #[inline]
    pub fn slice<R: RangeArgument<usize>>(&self, range: R) -> Option<IndexBufferSlice<T>> {
        self.buffer.slice(range).map(|b| {
            IndexBufferSlice {
                buffer: b,
                primitives: self.primitives,
            }
        })
    }
}

impl<T> Deref for IndexBuffer<T> where T: Index {
    type Target = Buffer<[T]>;

    #[inline]
    fn deref(&self) -> &Buffer<[T]> {
        &self.buffer
    }
}

impl<T> DerefMut for IndexBuffer<T> where T: Index {
    #[inline]
    fn deref_mut(&mut self) -> &mut Buffer<[T]> {
        &mut self.buffer
    }
}

impl<'a, T> From<&'a IndexBuffer<T>> for BufferSlice<'a, [T]> where T: Index {
    #[inline]
    fn from(b: &'a IndexBuffer<T>) -> BufferSlice<'a, [T]> {
        let b: &Buffer<[T]> = &*b;
        b.as_slice()
    }
}

impl<'a, T> From<&'a mut IndexBuffer<T>> for BufferMutSlice<'a, [T]> where T: Index {
    #[inline]
    fn from(b: &'a mut IndexBuffer<T>) -> BufferMutSlice<'a, [T]> {
        let b: &mut Buffer<[T]> = &mut *b;
        b.as_mut_slice()
    }
}

// TODO: remove this
impl<T> GlObject for IndexBuffer<T> where T: Index {
    type Id = gl::types::GLuint;

    #[inline]
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_buffer_id()
    }
}

impl<'a, T> From<&'a IndexBuffer<T>> for IndicesSource<'a> where T: Index {
    #[inline]
    fn from(buf: &'a IndexBuffer<T>) -> IndicesSource<'a> {
        IndicesSource::IndexBuffer {
            buffer: buf.buffer.as_slice_any(),
            data_type: buf.get_indices_type(),
            primitives: buf.primitives,
        }
    }
}

/// Slice of an `IndexBuffer`.
#[derive(Debug)]
pub struct IndexBufferSlice<'a, T: 'a> where T: Index {
    buffer: BufferSlice<'a, [T]>,
    primitives: PrimitiveType,
}

impl<'a, T: 'a> IndexBufferSlice<'a, T> where T: Index {
    /// Returns the type of primitives associated with this index buffer.
    #[inline]
    pub fn get_primitives_type(&self) -> PrimitiveType {
        self.primitives
    }

    /// Returns the data type of the indices inside this index buffer.
    #[inline]
    pub fn get_indices_type(&self) -> IndexType {
        <T as Index>::get_type()
    }

    /// Returns `None` if out of range.
    #[inline]
    pub fn slice<R: RangeArgument<usize>>(&self, range: R) -> Option<IndexBufferSlice<'a, T>> {
        self.buffer.slice(range).map(|b| {
            IndexBufferSlice {
                buffer: b,
                primitives: self.primitives,
            }
        })
    }
}

impl<'a, T> Deref for IndexBufferSlice<'a, T> where T: Index {
    type Target = BufferSlice<'a, [T]>;

    #[inline]
    fn deref(&self) -> &BufferSlice<'a, [T]> {
        &self.buffer
    }
}

impl<'a, T> DerefMut for IndexBufferSlice<'a, T> where T: Index {
    #[inline]
    fn deref_mut(&mut self) -> &mut BufferSlice<'a, [T]> {
        &mut self.buffer
    }
}

impl<'a, T> From<IndexBufferSlice<'a, T>> for BufferSlice<'a, [T]> where T: Index {
    #[inline]
    fn from(b: IndexBufferSlice<'a, T>) -> BufferSlice<'a, [T]> {
        b.buffer
    }
}

impl<'a, T> From<IndexBufferSlice<'a, T>> for IndicesSource<'a> where T: Index {
    #[inline]
    fn from(buf: IndexBufferSlice<'a, T>) -> IndicesSource<'a> {
        IndicesSource::IndexBuffer {
            buffer: buf.buffer.as_slice_any(),
            data_type: buf.get_indices_type(),
            primitives: buf.primitives,
        }
    }
}

impl<'a, 'r, T> From<&'r IndexBufferSlice<'a, T>> for IndicesSource<'a> where T: Index {
    #[inline]
    fn from(buf: &'r IndexBufferSlice<'a, T>) -> IndicesSource<'a> {
        IndicesSource::IndexBuffer {
            buffer: buf.buffer.as_slice_any(),
            data_type: buf.get_indices_type(),
            primitives: buf.primitives,
        }
    }
}

/// An `IndexBuffer` without any type information.
///
/// Makes it easier to store in a `Vec` or return from a function, for example.
#[derive(Debug)]
pub struct IndexBufferAny {
    buffer: BufferAny,
    primitives: PrimitiveType,
    data_type: IndexType,
}

impl IndexBufferAny {
    /// Returns the type of primitives associated with this index buffer.
    #[inline]
    pub fn get_primitives_type(&self) -> PrimitiveType {
        self.primitives
    }

    /// Returns the data type of the indices inside this index buffer.
    #[inline]
    pub fn get_indices_type(&self) -> IndexType {
        self.data_type
    }
}

impl Deref for IndexBufferAny {
    type Target = BufferAny;

    #[inline]
    fn deref(&self) -> &BufferAny {
        &self.buffer
    }
}

impl DerefMut for IndexBufferAny {
    #[inline]
    fn deref_mut(&mut self) -> &mut BufferAny {
        &mut self.buffer
    }
}

impl<T> From<IndexBuffer<T>> for IndexBufferAny where T: Index {
    #[inline]
    fn from(buffer: IndexBuffer<T>) -> IndexBufferAny {
        let ty = buffer.get_indices_type();

        IndexBufferAny {
            buffer: buffer.buffer.into(),
            data_type: ty,
            primitives: buffer.primitives,
        }
    }
}

impl<'a> From<&'a IndexBufferAny> for IndicesSource<'a> {
    #[inline]
    fn from(buf: &'a IndexBufferAny) -> IndicesSource<'a> {
        IndicesSource::IndexBuffer {
            buffer: buf.buffer.as_slice_any(),
            data_type: buf.data_type,
            primitives: buf.primitives,
        }
    }
}
<commit_msg>src/index/buffer.rs: CreationError fixed<commit_after>use buffer::{Buffer, BufferSlice, BufferMutSlice, BufferAny, BufferType};
use buffer::{BufferMode, BufferCreationError};
use gl;
use BufferExt;
use GlObject;

use backend::Facade;

use index::IndicesSource;
use index::Index;
use index::IndexType;
use index::PrimitiveType;

use std::ops::{Deref, DerefMut};
use std::fmt;
use std::error::Error;
use utils::range::RangeArgument;

/// Error that can happen while creating an index buffer.
#[derive(Debug, Copy, Clone)]
pub enum CreationError {
    /// The type of index is not supported by the backend.
    IndexTypeNotSupported,

    /// The type of primitives is not supported by the backend.
    PrimitiveTypeNotSupported,

    /// An error happened while creating the buffer.
    BufferCreationError(BufferCreationError),
}

impl fmt::Display for CreationError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.description())
    }
}

impl Error for CreationError {
    fn description(&self) -> &str {
        use self::CreationError::*;
        match *self {
            IndexTypeNotSupported
                => "The type of index is not supported by the backend",
            PrimitiveTypeNotSupported
                => "The type of primitives is not supported by the backend",
            BufferCreationError(_)
                => "An error happened while creating the buffer",
        }
    }

    fn cause(&self) -> Option<&Error> {
        use self::CreationError::*;
        match *self {
            BufferCreationError(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<BufferCreationError> for CreationError {
    #[inline]
    fn from(err: BufferCreationError) -> CreationError {
        CreationError::BufferCreationError(err)
    }
}

/// A list of indices loaded in the graphics card's memory.
#[derive(Debug)]
pub struct IndexBuffer<T> where T: Index {
    buffer: Buffer<[T]>,
    primitives: PrimitiveType,
}

impl<T> IndexBuffer<T> where T: Index {
    /// Builds a new index buffer from a list of indices and a primitive type.
    #[inline]
    pub fn new<F>(facade: &F, prim: PrimitiveType, data: &[T])
                  -> Result<IndexBuffer<T>, CreationError>
                  where F: Facade
    {
        IndexBuffer::new_impl(facade, prim, data, BufferMode::Default)
    }

    /// Builds a new index buffer from a list of indices and a primitive type.
    #[inline]
    pub fn dynamic<F>(facade: &F, prim: PrimitiveType, data: &[T])
                      -> Result<IndexBuffer<T>, CreationError>
                      where F: Facade
    {
        IndexBuffer::new_impl(facade, prim, data, BufferMode::Dynamic)
    }

    /// Builds a new index buffer from a list of indices and a primitive type.
    #[inline]
    pub fn persistent<F>(facade: &F, prim: PrimitiveType, data: &[T])
                         -> Result<IndexBuffer<T>, CreationError>
                         where F: Facade
    {
        IndexBuffer::new_impl(facade, prim, data, BufferMode::Persistent)
    }

    /// Builds a new index buffer from a list of indices and a primitive type.
    #[inline]
    pub fn immutable<F>(facade: &F, prim: PrimitiveType, data: &[T])
                        -> Result<IndexBuffer<T>, CreationError>
                        where F: Facade
    {
        IndexBuffer::new_impl(facade, prim, data, BufferMode::Immutable)
    }

    #[inline]
    fn new_impl<F>(facade: &F, prim: PrimitiveType, data: &[T], mode: BufferMode)
                   -> Result<IndexBuffer<T>, CreationError>
                   where F: Facade
    {
        if !prim.is_supported(facade) {
            return Err(CreationError::PrimitiveTypeNotSupported);
        }

        if !T::is_supported(facade) {
            return Err(CreationError::IndexTypeNotSupported);
        }

        Ok(IndexBuffer {
            buffer: try!(Buffer::new(facade, data, BufferType::ElementArrayBuffer, mode)).into(),
            primitives: prim,
        })
    }

    /// Builds a new empty index buffer.
    #[inline]
    pub fn empty<F>(facade: &F, prim: PrimitiveType, len: usize)
                    -> Result<IndexBuffer<T>, CreationError>
                    where F: Facade
    {
        IndexBuffer::empty_impl(facade, prim, len, BufferMode::Default)
    }

    /// Builds a new empty index buffer.
    #[inline]
    pub fn empty_dynamic<F>(facade: &F, prim: PrimitiveType, len: usize)
                            -> Result<IndexBuffer<T>, CreationError>
                            where F: Facade
    {
        IndexBuffer::empty_impl(facade, prim, len, BufferMode::Dynamic)
    }

    /// Builds a new empty index buffer.
    #[inline]
    pub fn empty_persistent<F>(facade: &F, prim: PrimitiveType, len: usize)
                               -> Result<IndexBuffer<T>, CreationError>
                               where F: Facade
    {
        IndexBuffer::empty_impl(facade, prim, len, BufferMode::Persistent)
    }

    /// Builds a new empty index buffer.
    #[inline]
    pub fn empty_immutable<F>(facade: &F, prim: PrimitiveType, len: usize)
                              -> Result<IndexBuffer<T>, CreationError>
                              where F: Facade
    {
        IndexBuffer::empty_impl(facade, prim, len, BufferMode::Immutable)
    }

    #[inline]
    fn empty_impl<F>(facade: &F, prim: PrimitiveType, len: usize, mode: BufferMode)
                     -> Result<IndexBuffer<T>, CreationError>
                     where F: Facade
    {
        if !prim.is_supported(facade) {
            return Err(CreationError::PrimitiveTypeNotSupported);
        }

        if !T::is_supported(facade) {
            return Err(CreationError::IndexTypeNotSupported);
        }

        Ok(IndexBuffer {
            buffer: try!(Buffer::empty_array(facade, BufferType::ElementArrayBuffer, len,
                                                 mode)).into(),
            primitives: prim,
        })
    }

    /// Returns the type of primitives associated with this index buffer.
    #[inline]
    pub fn get_primitives_type(&self) -> PrimitiveType {
        self.primitives
    }

    /// Returns the data type of the indices inside this index buffer.
    #[inline]
    pub fn get_indices_type(&self) -> IndexType {
        <T as Index>::get_type()
    }

    /// Returns `None` if out of range.
    #[inline]
    pub fn slice<R: RangeArgument<usize>>(&self, range: R) -> Option<IndexBufferSlice<T>> {
        self.buffer.slice(range).map(|b| {
            IndexBufferSlice {
                buffer: b,
                primitives: self.primitives,
            }
        })
    }
}

impl<T> Deref for IndexBuffer<T> where T: Index {
    type Target = Buffer<[T]>;

    #[inline]
    fn deref(&self) -> &Buffer<[T]> {
        &self.buffer
    }
}

impl<T> DerefMut for IndexBuffer<T> where T: Index {
    #[inline]
    fn deref_mut(&mut self) -> &mut Buffer<[T]> {
        &mut self.buffer
    }
}

impl<'a, T> From<&'a IndexBuffer<T>> for BufferSlice<'a, [T]> where T: Index {
    #[inline]
    fn from(b: &'a IndexBuffer<T>) -> BufferSlice<'a, [T]> {
        let b: &Buffer<[T]> = &*b;
        b.as_slice()
    }
}

impl<'a, T> From<&'a mut IndexBuffer<T>> for BufferMutSlice<'a, [T]> where T: Index {
    #[inline]
    fn from(b: &'a mut IndexBuffer<T>) -> BufferMutSlice<'a, [T]> {
        let b: &mut Buffer<[T]> = &mut *b;
        b.as_mut_slice()
    }
}

// TODO: remove this
impl<T> GlObject for IndexBuffer<T> where T: Index {
    type Id = gl::types::GLuint;

    #[inline]
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_buffer_id()
    }
}

impl<'a, T> From<&'a IndexBuffer<T>> for IndicesSource<'a> where T: Index {
    #[inline]
    fn from(buf: &'a IndexBuffer<T>) -> IndicesSource<'a> {
        IndicesSource::IndexBuffer {
            buffer: buf.buffer.as_slice_any(),
            data_type: buf.get_indices_type(),
            primitives: buf.primitives,
        }
    }
}

/// Slice of an `IndexBuffer`.
#[derive(Debug)]
pub struct IndexBufferSlice<'a, T: 'a> where T: Index {
    buffer: BufferSlice<'a, [T]>,
    primitives: PrimitiveType,
}

impl<'a, T: 'a> IndexBufferSlice<'a, T> where T: Index {
    /// Returns the type of primitives associated with this index buffer.
    #[inline]
    pub fn get_primitives_type(&self) -> PrimitiveType {
        self.primitives
    }

    /// Returns the data type of the indices inside this index buffer.
    #[inline]
    pub fn get_indices_type(&self) -> IndexType {
        <T as Index>::get_type()
    }

    /// Returns `None` if out of range.
    #[inline]
    pub fn slice<R: RangeArgument<usize>>(&self, range: R) -> Option<IndexBufferSlice<'a, T>> {
        self.buffer.slice(range).map(|b| {
            IndexBufferSlice {
                buffer: b,
                primitives: self.primitives,
            }
        })
    }
}

impl<'a, T> Deref for IndexBufferSlice<'a, T> where T: Index {
    type Target = BufferSlice<'a, [T]>;

    #[inline]
    fn deref(&self) -> &BufferSlice<'a, [T]> {
        &self.buffer
    }
}

impl<'a, T> DerefMut for IndexBufferSlice<'a, T> where T: Index {
    #[inline]
    fn deref_mut(&mut self) -> &mut BufferSlice<'a, [T]> {
        &mut self.buffer
    }
}

impl<'a, T> From<IndexBufferSlice<'a, T>> for BufferSlice<'a, [T]> where T: Index {
    #[inline]
    fn from(b: IndexBufferSlice<'a, T>) -> BufferSlice<'a, [T]> {
        b.buffer
    }
}

impl<'a, T> From<IndexBufferSlice<'a, T>> for IndicesSource<'a> where T: Index {
    #[inline]
    fn from(buf: IndexBufferSlice<'a, T>) -> IndicesSource<'a> {
        IndicesSource::IndexBuffer {
            buffer: buf.buffer.as_slice_any(),
            data_type: buf.get_indices_type(),
            primitives: buf.primitives,
        }
    }
}

impl<'a, 'r, T> From<&'r IndexBufferSlice<'a, T>> for IndicesSource<'a> where T: Index {
    #[inline]
    fn from(buf: &'r IndexBufferSlice<'a, T>) -> IndicesSource<'a> {
        IndicesSource::IndexBuffer {
            buffer: buf.buffer.as_slice_any(),
            data_type: buf.get_indices_type(),
            primitives: buf.primitives,
        }
    }
}

/// An `IndexBuffer` without any type information.
///
/// Makes it easier to store in a `Vec` or return from a function, for example.
#[derive(Debug)]
pub struct IndexBufferAny {
    buffer: BufferAny,
    primitives: PrimitiveType,
    data_type: IndexType,
}

impl IndexBufferAny {
    /// Returns the type of primitives associated with this index buffer.
    #[inline]
    pub fn get_primitives_type(&self) -> PrimitiveType {
        self.primitives
    }

    /// Returns the data type of the indices inside this index buffer.
    #[inline]
    pub fn get_indices_type(&self) -> IndexType {
        self.data_type
    }
}

impl Deref for IndexBufferAny {
    type Target = BufferAny;

    #[inline]
    fn deref(&self) -> &BufferAny {
        &self.buffer
    }
}

impl DerefMut for IndexBufferAny {
    #[inline]
    fn deref_mut(&mut self) -> &mut BufferAny {
        &mut self.buffer
    }
}

impl<T> From<IndexBuffer<T>> for IndexBufferAny where T: Index {
    #[inline]
    fn from(buffer: IndexBuffer<T>) -> IndexBufferAny {
        let ty = buffer.get_indices_type();

        IndexBufferAny {
            buffer: buffer.buffer.into(),
            data_type: ty,
            primitives: buffer.primitives,
        }
    }
}

impl<'a> From<&'a IndexBufferAny> for IndicesSource<'a> {
    #[inline]
    fn from(buf: &'a IndexBufferAny) -> IndicesSource<'a> {
        IndicesSource::IndexBuffer {
            buffer: buf.buffer.as_slice_any(),
            data_type: buf.data_type,
            primitives: buf.primitives,
        }
    }
}
<|endoftext|>


<commit_before>#![recursion_limit = "128"]
extern crate proc_macro;
extern crate proc_macro2;

use proc_macro::TokenStream;

use quote::quote;
use syn;
use syn::Error;
use syn::ItemFn;

/// Procedural attribute macro. This is meant to be applied to a binary's async
/// `main()`, transforming into a function that returns a type acceptable for
/// `main()`. In other words, this will not compile with libtock-rs:
///     async fn main() {}
/// and this will:
///     #[libtock::main]
///     async fn main() {}
#[proc_macro_attribute]
pub fn main(_: TokenStream, input: TokenStream) -> TokenStream {
    generate_main_wrapped(input.into()).into()
}

fn generate_main_wrapped(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
    try_generate_main_wrapped(input).unwrap_or_else(|err| err.to_compile_error().into())
}

fn try_generate_main_wrapped(
    input: proc_macro2::TokenStream,
) -> Result<proc_macro2::TokenStream, Error> {
    let ast = syn::parse2::<ItemFn>(input)?;
    let block = ast.block;
    let output = &ast.sig.output;
    Ok(quote!(
        fn main() #output {
            static mut MAIN_INVOKED: bool = false;
            unsafe {
                if MAIN_INVOKED {
                    panic!("Main called recursively; this is unsafe with #[libtock::main]");
                }
                MAIN_INVOKED = true;
            }
            let _block = async #block;
            unsafe {::core::executor::block_on(_block) }
        }
    ))
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn wraps_main_into_blocking_executor() {
        let method_def: proc_macro2::TokenStream = quote! {
            async fn main() -> ::libtock::result::TockResult<()>{
                method_call().await;
            }
        }
        .into();
        let actual: ItemFn = syn::parse2::<ItemFn>(generate_main_wrapped(method_def.into()))
            .unwrap()
            .into();
        let expected: ItemFn = syn::parse2::<ItemFn>(quote!(
            fn main() -> ::libtock::result::TockResult<()> {
                static mut MAIN_INVOKED: bool = false;
                unsafe {
                    if MAIN_INVOKED {
                        panic!("Main called recursively; this is unsafe with #[libtock::main]");
                    }
                    MAIN_INVOKED = true;
                }
                let _block = async {
                    method_call().await;
                };
                unsafe { ::core::executor::block_on(_block) }
            }
        ))
        .unwrap()
        .into();
        assert_eq!(actual, expected);
    }
}
<commit_msg>Fix formatting of Rustdoc<commit_after>#![recursion_limit = "128"]
extern crate proc_macro;
extern crate proc_macro2;

use proc_macro::TokenStream;

use quote::quote;
use syn;
use syn::Error;
use syn::ItemFn;

/// Procedural attribute macro. This is meant to be applied to a binary's async
/// `main()`, transforming into a function that returns a type acceptable for
/// `main()`. In other words, this will not compile with libtock-rs:
/// ```ignore
/// async fn main() {
///     // async code
/// }
/// ```
/// and this will:
/// ```ignore
/// #[libtock::main]
/// async fn main() {
///     // async code
/// }
/// ```
#[proc_macro_attribute]
pub fn main(_: TokenStream, input: TokenStream) -> TokenStream {
    generate_main_wrapped(input.into()).into()
}

fn generate_main_wrapped(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
    try_generate_main_wrapped(input).unwrap_or_else(|err| err.to_compile_error().into())
}

fn try_generate_main_wrapped(
    input: proc_macro2::TokenStream,
) -> Result<proc_macro2::TokenStream, Error> {
    let ast = syn::parse2::<ItemFn>(input)?;
    let block = ast.block;
    let output = &ast.sig.output;
    Ok(quote!(
        fn main() #output {
            static mut MAIN_INVOKED: bool = false;
            unsafe {
                if MAIN_INVOKED {
                    panic!("Main called recursively; this is unsafe with #[libtock::main]");
                }
                MAIN_INVOKED = true;
            }
            let _block = async #block;
            unsafe {::core::executor::block_on(_block) }
        }
    ))
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn wraps_main_into_blocking_executor() {
        let method_def: proc_macro2::TokenStream = quote! {
            async fn main() -> ::libtock::result::TockResult<()>{
                method_call().await;
            }
        }
        .into();
        let actual: ItemFn = syn::parse2::<ItemFn>(generate_main_wrapped(method_def.into()))
            .unwrap()
            .into();
        let expected: ItemFn = syn::parse2::<ItemFn>(quote!(
            fn main() -> ::libtock::result::TockResult<()> {
                static mut MAIN_INVOKED: bool = false;
                unsafe {
                    if MAIN_INVOKED {
                        panic!("Main called recursively; this is unsafe with #[libtock::main]");
                    }
                    MAIN_INVOKED = true;
                }
                let _block = async {
                    method_call().await;
                };
                unsafe { ::core::executor::block_on(_block) }
            }
        ))
        .unwrap()
        .into();
        assert_eq!(actual, expected);
    }
}
<|endoftext|>