<commit_before>// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use std::collections::HashMap;
use std::result::Result;

use micro_http::{HttpHeaderError, RequestError};

/// Header rejected by MMDS.
pub const REJECTED_HEADER: &str = "X-Forwarded-For";

/// Wrapper over the list of token headers associated with a Request.
#[derive(Debug, PartialEq, Eq)]
pub struct TokenHeaders {
    /// The `X-metadata-token` header might be used by HTTP clients to specify a token in order
    /// to authenticate to the session. This is used for guest requests to MMDS only.
    x_metadata_token: Option<String>,
    /// The `X-metadata-token-ttl-seconds` header might be used by HTTP clients to specify
    /// the expiry time of a token. This is used for PUT requests issued by the guest to MMDS only.
    x_metadata_token_ttl_seconds: Option<u32>,
}

impl Default for TokenHeaders {
    /// Token headers are not present in the request by default.
    fn default() -> Self {
        Self {
            x_metadata_token: None,
            x_metadata_token_ttl_seconds: None,
        }
    }
}

impl TokenHeaders {
    /// `X-metadata-token` header.
    const X_METADATA_TOKEN: &'static str = "X-metadata-token";
    /// `X-metadata-token-ttl-seconds` header.
    const X_METADATA_TOKEN_TTL_SECONDS: &'static str = "X-metadata-token-ttl-seconds";

    /// Return `TokenHeaders` from headers map.
    pub fn try_from(map: &HashMap<String, String>) -> Result<TokenHeaders, RequestError> {
        let mut headers = Self::default();

        if let Some(token) = map.get(TokenHeaders::X_METADATA_TOKEN) {
            headers.x_metadata_token = Some(token.to_string());
        }

        if let Some(value) = map.get(TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS) {
            match value.parse::<u32>() {
                Ok(seconds) => {
                    headers.x_metadata_token_ttl_seconds = Some(seconds);
                }
                Err(_) => {
                    return Err(RequestError::HeaderError(HttpHeaderError::InvalidValue(
                        TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_string(),
                        value.to_string(),
                    )));
                }
            }
        }

        Ok(headers)
    }

    /// Returns the `XMetadataToken` token.
    pub fn x_metadata_token(&self) -> Option<&String> {
        self.x_metadata_token.as_ref()
    }

    /// Returns the `XMetadataTokenTtlSeconds` token.
    pub fn x_metadata_token_ttl_seconds(&self) -> Option<u32> {
        self.x_metadata_token_ttl_seconds
    }

    /// Sets the `XMetadataToken` token.
    pub fn set_x_metadata_token(&mut self, token: String) {
        self.x_metadata_token = Some(token)
    }

    /// Sets the `XMetadataTokenTtlSeconds` token.
    pub fn set_x_metadata_token_ttl_seconds(&mut self, ttl: u32) {
        self.x_metadata_token_ttl_seconds = Some(ttl);
    }
}

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

    #[test]
    fn test_default() {
        let headers = TokenHeaders::default();
        assert_eq!(headers.x_metadata_token(), None);
        assert_eq!(headers.x_metadata_token_ttl_seconds(), None);
    }

    #[test]
    fn test_try_from_headers() {
        // Empty token header map.
        let map: HashMap<String, String> = HashMap::default();
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(headers, TokenHeaders::default());

        // Unrecognised headers.
        let mut map: HashMap<String, String> = HashMap::default();
        map.insert("Some-Header".to_string(), "10".to_string());
        map.insert("Another-Header".to_string(), "value".to_string());
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(headers, TokenHeaders::default());

        // Valid headers.
        let mut map: HashMap<String, String> = HashMap::default();
        map.insert("Some-Header".to_string(), "10".to_string());
        map.insert(
            TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_string(),
            "60".to_string(),
        );
        map.insert(
            TokenHeaders::X_METADATA_TOKEN.to_string(),
            "foo".to_string(),
        );
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(headers.x_metadata_token_ttl_seconds().unwrap(), 60);
        assert_eq!(*headers.x_metadata_token().unwrap(), "foo".to_string());

        let mut map: HashMap<String, String> = HashMap::default();
        map.insert(TokenHeaders::X_METADATA_TOKEN.to_string(), "".to_string());
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(*headers.x_metadata_token().unwrap(), "".to_string());

        // Invalid value.
        let mut map: HashMap<String, String> = HashMap::default();
        map.insert(
            TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_string(),
            "-60".to_string(),
        );
        assert_eq!(
            TokenHeaders::try_from(&map).unwrap_err(),
            RequestError::HeaderError(HttpHeaderError::InvalidValue(
                TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_string(),
                "-60".to_string()
            ))
        );
    }
}
<commit_msg>MMDS: Add support for lowercased headers<commit_after>// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use std::collections::HashMap;
use std::result::Result;

use micro_http::{HttpHeaderError, RequestError};

/// Header rejected by MMDS.
pub const REJECTED_HEADER: &str = "X-Forwarded-For";

/// Wrapper over the list of token headers associated with a Request.
#[derive(Debug, PartialEq, Eq)]
pub struct TokenHeaders {
    /// The `X-metadata-token` header might be used by HTTP clients to specify a token in order
    /// to authenticate to the session. This is used for guest requests to MMDS only.
    x_metadata_token: Option<String>,
    /// The `X-metadata-token-ttl-seconds` header might be used by HTTP clients to specify
    /// the expiry time of a token. This is used for PUT requests issued by the guest to MMDS only.
    x_metadata_token_ttl_seconds: Option<u32>,
}

impl Default for TokenHeaders {
    /// Token headers are not present in the request by default.
    fn default() -> Self {
        Self {
            x_metadata_token: None,
            x_metadata_token_ttl_seconds: None,
        }
    }
}

impl TokenHeaders {
    /// `X-metadata-token` header.
    const X_METADATA_TOKEN: &'static str = "X-metadata-token";
    /// `X-metadata-token-ttl-seconds` header.
    const X_METADATA_TOKEN_TTL_SECONDS: &'static str = "X-metadata-token-ttl-seconds";

    /// Return `TokenHeaders` from headers map.
    pub fn try_from(map: &HashMap<String, String>) -> Result<TokenHeaders, RequestError> {
        let mut headers = Self::default();
        let lowercased_headers: HashMap<String, String> = map
            .iter()
            .map(|(k, v)| (k.to_lowercase(), v.clone()))
            .collect();

        if let Some(token) = lowercased_headers.get(&TokenHeaders::X_METADATA_TOKEN.to_lowercase())
        {
            headers.x_metadata_token = Some(token.to_string());
        }

        if let Some(value) =
            lowercased_headers.get(&TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_lowercase())
        {
            match value.parse::<u32>() {
                Ok(seconds) => {
                    headers.x_metadata_token_ttl_seconds = Some(seconds);
                }
                Err(_) => {
                    return Err(RequestError::HeaderError(HttpHeaderError::InvalidValue(
                        TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_string(),
                        value.to_string(),
                    )));
                }
            }
        }

        Ok(headers)
    }

    /// Returns the `XMetadataToken` token.
    pub fn x_metadata_token(&self) -> Option<&String> {
        self.x_metadata_token.as_ref()
    }

    /// Returns the `XMetadataTokenTtlSeconds` token.
    pub fn x_metadata_token_ttl_seconds(&self) -> Option<u32> {
        self.x_metadata_token_ttl_seconds
    }

    /// Sets the `XMetadataToken` token.
    pub fn set_x_metadata_token(&mut self, token: String) {
        self.x_metadata_token = Some(token)
    }

    /// Sets the `XMetadataTokenTtlSeconds` token.
    pub fn set_x_metadata_token_ttl_seconds(&mut self, ttl: u32) {
        self.x_metadata_token_ttl_seconds = Some(ttl);
    }
}

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

    #[test]
    fn test_default() {
        let headers = TokenHeaders::default();
        assert_eq!(headers.x_metadata_token(), None);
        assert_eq!(headers.x_metadata_token_ttl_seconds(), None);
    }

    #[test]
    fn test_try_from_headers() {
        // Empty token header map.
        let map: HashMap<String, String> = HashMap::default();
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(headers, TokenHeaders::default());

        // Unrecognised headers.
        let mut map: HashMap<String, String> = HashMap::default();
        map.insert("Some-Header".to_string(), "10".to_string());
        map.insert("Another-Header".to_string(), "value".to_string());
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(headers, TokenHeaders::default());

        // Valid headers.
        let mut map: HashMap<String, String> = HashMap::default();
        map.insert("Some-Header".to_string(), "10".to_string());
        map.insert(
            TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_string(),
            "60".to_string(),
        );
        map.insert(
            TokenHeaders::X_METADATA_TOKEN.to_string(),
            "foo".to_string(),
        );
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(headers.x_metadata_token_ttl_seconds().unwrap(), 60);
        assert_eq!(*headers.x_metadata_token().unwrap(), "foo".to_string());

        let mut map: HashMap<String, String> = HashMap::default();
        map.insert(TokenHeaders::X_METADATA_TOKEN.to_string(), "".to_string());
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(*headers.x_metadata_token().unwrap(), "".to_string());

        // Lowercased headers
        let mut map: HashMap<String, String> = HashMap::default();
        map.insert(
            TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS
                .to_string()
                .to_lowercase(),
            "60".to_string(),
        );
        let headers = TokenHeaders::try_from(&map).unwrap();
        assert_eq!(headers.x_metadata_token_ttl_seconds().unwrap(), 60);

        // Invalid value.
        let mut map: HashMap<String, String> = HashMap::default();
        map.insert(
            TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_string(),
            "-60".to_string(),
        );
        assert_eq!(
            TokenHeaders::try_from(&map).unwrap_err(),
            RequestError::HeaderError(HttpHeaderError::InvalidValue(
                TokenHeaders::X_METADATA_TOKEN_TTL_SECONDS.to_string(),
                "-60".to_string()
            ))
        );
    }
}
<|endoftext|>


<commit_before>enum SqlType {
	Char(uint),
	Varchar(uint),
	Integer,
}

enum SqlAttribute {
	Null,
	NotNull,
}

struct Column {
	name: ~str,
	datatype: SqlType,
	attributes: Vec<SqlAttribute>,
}

struct Relation {
	name: ~str,
	columns: Vec<Column>,
}

struct Schema {
	relations: Vec<Relation>,
}

struct Record {
	// TODO: do we even need this?
	len: uint,
	data: Vec<u8>,
}

impl Record {
	/* move semantics, no copy */
	pub fn new(len: uint, data: Vec<u8>) -> Record {
		Record {len: len, data: data}
	}

	pub fn get_data<'a>(&'a self) -> &'a [u8] {
		self.data.as_slice()
	}
}

struct SPSegment;

/* our newtype struct: create a TID type as an alias to u64 */
struct TID(u64);

impl SPSegment {
	pub fn insert(r: Record) -> TID {
		TID(0_u64)
	}

	pub fn remove(tid: TID) -> bool {
		false
	}

	pub fn lookup(tid: TID) -> Record {
		// TODO
		Record {len: 1, data: vec!(1)}
	}

	pub fn update(tid: TID, r: Record) -> bool {
		false
	}
}

#[test]
fn main() {
}
<commit_msg>Added code to build up schema data structure<commit_after>enum SqlType {
	Char(uint),
	Varchar(uint),
	Integer,
}

enum SqlAttribute {
	Null,
	NotNull,
}

struct Column {
	name: ~str,
	datatype: SqlType,
	attributes: Vec<SqlAttribute>,
}

struct Relation {
	name: ~str,
	columns: Vec<Column>,
}

impl Relation {
	pub fn new(name: ~str) -> Relation {
		Relation {name: name, columns: Vec::new()}
	}

	pub fn add_column(&mut self, column: Column) {
		self.columns.push(column);
	}
}

struct Schema {
	relations: Vec<Relation>,
}

impl Schema {
	pub fn new() -> Schema {
		Schema {relations: Vec::new()}
	}

	pub fn new_from_disk() {
	}

	pub fn add_relation(&mut self, relation: Relation) {
		self.relations.push(relation);
	}
}

struct Record {
	// TODO: do we even need this?
	len: uint,
	data: Vec<u8>,
}

impl Record {
	/* move semantics, no copy */
	pub fn new(len: uint, data: Vec<u8>) -> Record {
		Record {len: len, data: data}
	}

	pub fn get_data<'a>(&'a self) -> &'a [u8] {
		self.data.as_slice()
	}
}

struct SPSegment;

/* our newtype struct: create a TID type as an alias to u64 */
struct TID(u64);

impl SPSegment {
	pub fn insert(r: Record) -> TID {
		TID(0_u64)
	}

	pub fn remove(tid: TID) -> bool {
		false
	}

	pub fn lookup(tid: TID) -> Record {
		// TODO
		Record {len: 1, data: vec!(1)}
	}

	pub fn update(tid: TID, r: Record) -> bool {
		false
	}
}

#[test]
fn main() {
}

#[test]
fn create_schema() {
	let name = Column {name: ~"name", datatype: Varchar(128), attributes: vec!(NotNull)};
	let age = Column {name: ~"age", datatype: Integer, attributes: vec!(NotNull)};
	let mut relation = Relation::new(~"Person");
	relation.add_column(name);
	relation.add_column(age);
	let mut schema = Schema::new();
	schema.add_relation(relation);
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Ben Ashford
 *
 * 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.
 */

//! Implementation of ElasticSearch Mapping operation
//!
//! Please note: this will grow and become a full implementation of the ElasticSearch
//! [Indices API](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices.html)
//! so subtle (potentially breaking) changes will be made to the API when that happens

use std::collections::HashMap;

use ::Client;
use ::error::EsError;

pub type Properties<'a> = HashMap<&'a str, HashMap<&'a str, &'a str>>;

/// An indexing operation
pub struct MappingOperation<'a, 'b> {
    /// The HTTP client that this operation will use
    client:     &'a mut Client,

    /// The index that will be created and eventually mapped
    index:      &'b str,

    /// The actual mapping
    properties: &'b Properties<'b>
}

impl<'a, 'b> MappingOperation<'a, 'b> {
    pub fn new(client: &'a mut Client, index: &'b str, properties: &'b Properties) -> MappingOperation<'a, 'b> {
        MappingOperation {
            client:     client,
            index:      index,
            properties: properties
        }
    }

    pub fn send(&'b mut self) -> Result<MappingResult, EsError> {
        let body = hashmap! {
            "mappings" => hashmap! {
                "sample" => hashmap! {
                    "properties" => self.properties
                }
            }
        };

        let url = format!("{}", self.index);
        let (_, _) = try!(self.client.put_body_op(&url, &body));
        Ok(MappingResult)
    }
}

/// The result of a mapping operation
#[derive(Debug)]
pub struct MappingResult;

#[cfg(test)]
pub mod tests {
    extern crate env_logger;

    use std::collections::HashMap;

    use super::MappingOperation;

    #[test]
    fn test_mapping() {
        let index_name = "tests_test_mapping";
        let mut client = ::tests::make_client();

        client.delete_op(&format!("/{}", index_name)).unwrap();

        let mapping = hashmap! {
            "created_at" => hashmap! {
                "type" => "date",
                "format" => "strict_date_optional_time"
            },

            "title" => hashmap! {
                "type" => "string",
                "index" => "not_analyzed"
            }
        };

        let result = MappingOperation::new(&mut client, index_name, &mapping).send();
        assert!(result.is_ok());
    }
}
<commit_msg>Allow mapping for given type<commit_after>/*
 * Copyright 2016 Ben Ashford
 *
 * 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.
 */

//! Implementation of ElasticSearch Mapping operation
//!
//! Please note: this will grow and become a full implementation of the ElasticSearch
//! [Indices API](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices.html)
//! so subtle (potentially breaking) changes will be made to the API when that happens

use std::collections::HashMap;

use ::Client;
use ::error::EsError;

pub type Properties<'a> = HashMap<&'a str, HashMap<&'a str, &'a str>>;

/// An indexing operation
pub struct MappingOperation<'a, 'b> {
    /// The HTTP client that this operation will use
    client:     &'a mut Client,

    /// The index that will be created and eventually mapped
    index:      &'b str,

    /// The type that will be mapped
    doc_type:   &'b str,

    /// The actual mapping
    properties: &'b Properties<'b>
}

impl<'a, 'b> MappingOperation<'a, 'b> {
    pub fn new(client: &'a mut Client, index: &'b str, doc_type: &'b str, properties: &'b Properties) -> MappingOperation<'a, 'b> {
        MappingOperation {
            client:     client,
            index:      index,
            doc_type:   doc_type,
            properties: properties
        }
    }

    pub fn send(&'b mut self) -> Result<MappingResult, EsError> {
        let body = hashmap! {
            "mappings" => hashmap! {
                self.doc_type => hashmap! {
                    "properties" => self.properties
                }
            }
        };

        let url = format!("{}", self.index);
        let (_, _) = try!(self.client.put_body_op(&url, &body));
        Ok(MappingResult)
    }
}

/// The result of a mapping operation
#[derive(Debug)]
pub struct MappingResult;

#[cfg(test)]
pub mod tests {
    extern crate env_logger;

    use std::collections::HashMap;

    use super::MappingOperation;

    #[test]
    fn test_mapping() {
        let index_name = "tests_test_mapping";
        let mut client = ::tests::make_client();

        client.delete_op(&format!("/{}", index_name)).unwrap();

        let mapping = hashmap! {
            "created_at" => hashmap! {
                "type" => "date",
                "format" => "strict_date_optional_time"
            },

            "title" => hashmap! {
                "type" => "string",
                "index" => "not_analyzed"
            }
        };

        let result = MappingOperation::new(&mut client, index_name, "sample", &mapping).send();
        assert!(result.is_ok());
    }
}
<|endoftext|>


<commit_before>//! Aggregates the weights of equal records into at most one record.
//!
//! As differential dataflow streams are unordered and taken to be the accumulation of all records,
//! no semantic change happens via `consolidate`. However, there is a practical difference between
//! a collection that aggregates down to zero records, and one that actually has no records. The
//! underlying system can more clearly see that no work must be done in the later case, and we can
//! drop out of, e.g. iterative computations.

use timely::dataflow::Scope;

use ::{Collection, ExchangeData, Hashable};
use ::difference::Semigroup;
use operators::arrange::ArrangeBySelf;

/// An extension method for consolidating weighted streams.
pub trait Consolidate<D: ExchangeData+Hashable> {
    /// Aggregates the weights of equal records into at most one record.
    ///
    /// This method uses the type `D`'s `hashed()` method to partition the data. The data are
    /// accumulated in place, each held back until their timestamp has completed.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use differential_dataflow::input::Input;
    /// use differential_dataflow::operators::Consolidate;
    ///
    /// fn main() {
    ///     ::timely::example(|scope| {
    ///
    ///         let x = scope.new_collection_from(1 .. 10u32).1;
    ///
    ///         x.negate()
    ///          .concat(&x)
    ///          .consolidate() // <-- ensures cancellation occurs
    ///          .assert_empty();
    ///     });
    /// }
    /// ```
    fn consolidate(&self) -> Self;
}

impl<G: Scope, D, R> Consolidate<D> for Collection<G, D, R>
where
    D: ExchangeData+Hashable,
    R: ExchangeData+Semigroup,
    G::Timestamp: ::lattice::Lattice+Ord,
 {
    fn consolidate(&self) -> Self {
        self.arrange_by_self().as_collection(|d,_| d.clone())
    }
}

/// An extension method for consolidating weighted streams.
pub trait ConsolidateStream<D: ExchangeData+Hashable> {
    /// Aggregates the weights of equal records.
    ///
    /// Unlike `consolidate`, this method does not exchange data and does not
    /// ensure that at most one copy of each `(data, time)` pair exists in the
    /// results. Instead, it acts on each batch of data and collapses equivalent
    /// `(data, time)` pairs found therein, suppressing any that accumulate to
    /// zero.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use differential_dataflow::input::Input;
    /// use differential_dataflow::operators::consolidate::ConsolidateStream;
    ///
    /// fn main() {
    ///     ::timely::example(|scope| {
    ///
    ///         let x = scope.new_collection_from(1 .. 10u32).1;
    ///
    ///         // nothing to assert, as no particular guarantees.
    ///         x.negate()
    ///          .concat(&x)
    ///          .consolidate_stream();
    ///     });
    /// }
    /// ```
    fn consolidate_stream(&self) -> Self;
}

impl<G: Scope, D, R> ConsolidateStream<D> for Collection<G, D, R>
where
    D: ExchangeData+Hashable,
    R: ExchangeData+Semigroup,
    G::Timestamp: ::lattice::Lattice+Ord,
 {
    fn consolidate_stream(&self) -> Self {

        use timely::dataflow::channels::pact::Pipeline;
        use timely::dataflow::operators::Operator;
        use collection::AsCollection;

        self.inner
            .unary(Pipeline, "ConsolidateStream", |_cap, _info| {

                let mut vector = Vec::new();
                move |input, output| {
                    input.for_each(|time, data| {
                        data.swap(&mut vector);
                        crate::consolidation::consolidate_updates(&mut vector);
                        output.session(&time).give_vec(&mut vector);
                    })
                }
            })
            .as_collection()
    }
}
<commit_msg>named variant of consolidate<commit_after>//! Aggregates the weights of equal records into at most one record.
//!
//! As differential dataflow streams are unordered and taken to be the accumulation of all records,
//! no semantic change happens via `consolidate`. However, there is a practical difference between
//! a collection that aggregates down to zero records, and one that actually has no records. The
//! underlying system can more clearly see that no work must be done in the later case, and we can
//! drop out of, e.g. iterative computations.

use timely::dataflow::Scope;

use ::{Collection, ExchangeData, Hashable};
use ::difference::Semigroup;
use operators::arrange::arrangement::Arrange;

/// An extension method for consolidating weighted streams.
pub trait Consolidate<D: ExchangeData+Hashable> : Sized {
    /// Aggregates the weights of equal records into at most one record.
    ///
    /// This method uses the type `D`'s `hashed()` method to partition the data. The data are
    /// accumulated in place, each held back until their timestamp has completed.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use differential_dataflow::input::Input;
    /// use differential_dataflow::operators::Consolidate;
    ///
    /// fn main() {
    ///     ::timely::example(|scope| {
    ///
    ///         let x = scope.new_collection_from(1 .. 10u32).1;
    ///
    ///         x.negate()
    ///          .concat(&x)
    ///          .consolidate() // <-- ensures cancellation occurs
    ///          .assert_empty();
    ///     });
    /// }
    /// ```
    fn consolidate(&self) -> Self {
        self.consolidate_named("Consolidate")
    }

    /// As `consolidate` but with the ability to name the operator.
    fn consolidate_named(&self, name: &str) -> Self;
}

impl<G: Scope, D, R> Consolidate<D> for Collection<G, D, R>
where
    D: ExchangeData+Hashable,
    R: ExchangeData+Semigroup,
    G::Timestamp: ::lattice::Lattice+Ord,
 {
    fn consolidate_named(&self, name: &str) -> Self {
        use trace::implementations::ord::OrdKeySpine as DefaultKeyTrace;
        self.map(|k| (k, ()))
            .arrange_named::<DefaultKeyTrace<_,_,_>>(name)
            .as_collection(|d: &D, _| d.clone())
    }
}

/// An extension method for consolidating weighted streams.
pub trait ConsolidateStream<D: ExchangeData+Hashable> {
    /// Aggregates the weights of equal records.
    ///
    /// Unlike `consolidate`, this method does not exchange data and does not
    /// ensure that at most one copy of each `(data, time)` pair exists in the
    /// results. Instead, it acts on each batch of data and collapses equivalent
    /// `(data, time)` pairs found therein, suppressing any that accumulate to
    /// zero.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use differential_dataflow::input::Input;
    /// use differential_dataflow::operators::consolidate::ConsolidateStream;
    ///
    /// fn main() {
    ///     ::timely::example(|scope| {
    ///
    ///         let x = scope.new_collection_from(1 .. 10u32).1;
    ///
    ///         // nothing to assert, as no particular guarantees.
    ///         x.negate()
    ///          .concat(&x)
    ///          .consolidate_stream();
    ///     });
    /// }
    /// ```
    fn consolidate_stream(&self) -> Self;
}

impl<G: Scope, D, R> ConsolidateStream<D> for Collection<G, D, R>
where
    D: ExchangeData+Hashable,
    R: ExchangeData+Semigroup,
    G::Timestamp: ::lattice::Lattice+Ord,
 {
    fn consolidate_stream(&self) -> Self {

        use timely::dataflow::channels::pact::Pipeline;
        use timely::dataflow::operators::Operator;
        use collection::AsCollection;

        self.inner
            .unary(Pipeline, "ConsolidateStream", |_cap, _info| {

                let mut vector = Vec::new();
                move |input, output| {
                    input.for_each(|time, data| {
                        data.swap(&mut vector);
                        crate::consolidation::consolidate_updates(&mut vector);
                        output.session(&time).give_vec(&mut vector);
                    })
                }
            })
            .as_collection()
    }
}
<|endoftext|>


<commit_before>//! way-cooler registry.

use std::ops::Deref;
use std::cmp::Eq;
use std::fmt::Display;
use std::hash::Hash;
use std::borrow::Borrow;

use hlua::any::AnyLuaValue;
use convert::{ToTable, FromTable, LuaDecoder, ConverterError};

use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

mod types;
pub use self::types::*; // Export constants too

#[cfg(test)]
mod tests;

pub type RegMap = HashMap<String, RegistryValue>;

lazy_static! {
    /// Registry variable for the registry
    static ref REGISTRY: RwLock<RegMap> =
        RwLock::new(HashMap::new());
}

/// Error types that can happen
#[derive(Debug, PartialEq, Eq)]
pub enum RegistryError {
    /// The value in the registry could not be parsed
    InvalidLua,
    /// The registry key was not found
    KeyNotFound
}

/// Acquires a read lock on the registry.
pub fn read_lock<'a>() -> RwLockReadGuard<'a, RegMap> {
    REGISTRY.read().unwrap()
}

/// Acquires a write lock on the registry.
pub fn write_lock<'a>() -> RwLockWriteGuard<'a, RegMap> {
    REGISTRY.write().unwrap()
}

/// Gets a Lua object from a registry key
pub fn get_lua<K>(name: &K) -> Option<(AccessFlags, Arc<AnyLuaValue>)>
where String: Borrow<K>, K: Hash + Eq + Display {
    trace!("get_lua: {}", *name);
    let ref reg = *read_lock();
    reg.get(name).map(|val| (val.flags(), val.get_lua()))
}

/// Gets an object from the registry, decoding its internal Lua
/// representation.
pub fn get<K, T>(name: &K) -> Result<(AccessFlags, T), RegistryError>
where T: FromTable, String: Borrow<K>, K: Hash + Eq + Display {
    let maybe_lua = get_lua(name);
    if let Some(lua_pair) = maybe_lua {
        let (access, lua_arc) = lua_pair;
        // Ultimately, values must be cloned out of the registry as well
        match T::from_lua_table(lua_arc.deref().clone()) {
            Ok(val) => Ok((access, val)),
            Err(e) => Err(RegistryError::InvalidLua)
        }
    }
    else {
        Err(RegistryError::KeyNotFound)
    }
}

/// Set a key in the registry to a particular value
pub fn set<T: ToTable>(key: String, flags: AccessFlags, val: T) {
    trace!("set: {:?} {}", flags, key);
    let regvalue = RegistryValue::new(flags, val);
    let ref mut write_reg = *write_lock();
    write_reg.insert(key, regvalue);
}

/// Whether this map contains a key
pub fn contains_key<K>(key: &K) -> bool
where String: Borrow<K>, K: Hash + Eq + Display {
    trace!("contains_key: {}", *key);
    let ref read_reg = *read_lock();
    read_reg.contains_key(key)
}
<commit_msg>Add inner Lua conversion errror to RegistryError::InvalidLua<commit_after>//! way-cooler registry.

use std::ops::Deref;
use std::cmp::Eq;
use std::fmt::Display;
use std::hash::Hash;
use std::borrow::Borrow;

use hlua::any::AnyLuaValue;
use convert::{ToTable, FromTable, LuaDecoder, ConverterError};

use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

mod types;
pub use self::types::*; // Export constants too

#[cfg(test)]
mod tests;

pub type RegMap = HashMap<String, RegistryValue>;

lazy_static! {
    /// Registry variable for the registry
    static ref REGISTRY: RwLock<RegMap> =
        RwLock::new(HashMap::new());
}

/// Error types that can happen
#[derive(Debug, PartialEq, Eq)]
pub enum RegistryError {
    /// The value in the registry could not be parsed
    InvalidLua(ConverterError),
    /// The registry key was not found
    KeyNotFound
}

/// Acquires a read lock on the registry.
pub fn read_lock<'a>() -> RwLockReadGuard<'a, RegMap> {
    REGISTRY.read().unwrap()
}

/// Acquires a write lock on the registry.
pub fn write_lock<'a>() -> RwLockWriteGuard<'a, RegMap> {
    REGISTRY.write().unwrap()
}

/// Gets a Lua object from a registry key
pub fn get_lua<K>(name: &K) -> Option<(AccessFlags, Arc<AnyLuaValue>)>
where String: Borrow<K>, K: Hash + Eq + Display {
    trace!("get_lua: {}", *name);
    let reg = read_lock();
    reg.get(name).map(|val| (val.flags(), val.get_lua()))
}

/// Gets an object from the registry, decoding its internal Lua
/// representation.
pub fn get<K, T>(name: &K) -> Result<(AccessFlags, T), RegistryError>
    where T: FromTable, String: Borrow<K>, K: Hash + Eq + Display {
    if let Some(lua_pair) = get_lua(name) {
        let (access, lua_arc) = lua_pair;
        // Ultimately, values must be cloned out of the registry as well
        match T::from_lua_table(lua_arc.deref().clone()) {
            Ok(val) => Ok((access, val)),
            Err(e) => Err(RegistryError::InvalidLua(e))
        }
    }
    else {
        Err(RegistryError::KeyNotFound)
    }
}

/// Set a key in the registry to a particular value
pub fn set<T: ToTable>(key: String, flags: AccessFlags, val: T) {
    trace!("set: {:?} {}", flags, key);
    let regvalue = RegistryValue::new(flags, val);
    let mut write_reg = write_lock();
    write_reg.insert(key, regvalue);
}

/// Whether this map contains a key
pub fn contains_key<K>(key: &K) -> bool
where String: Borrow<K>, K: Hash + Eq + Display {
    trace!("contains_key: {}", *key);
    let read_reg = read_lock();
    read_reg.contains_key(key)
}
<|endoftext|>


<commit_before>use std::io::{self, Read, Cursor, Seek, SeekFrom};
use std::num::ParseIntError;
use std::result::Result as StdResult;
use {Run, TimeSpan, Time, RealTime, Segment};
use base64::{self, STANDARD};
use byteorder::{ReadBytesExt, BigEndian as BE};
use imagelib::{png, Rgba, ImageBuffer, ColorType};
use super::xml_util::{self, text};
use sxd_document::dom::Element;
use sxd_document::parser::{Error as XmlError, parse as parse_xml};

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        Xml(err: (usize, Vec<XmlError>)) {
            from()
        }
        Io(err: io::Error) {
            from()
        }
        Int(err: ParseIntError) {
            from()
        }
        ElementNotFound
        AttributeNotFound
    }
}

pub type Result<T> = StdResult<T, Error>;

fn child<'d>(element: &Element<'d>, name: &str) -> Result<Element<'d>> {
    xml_util::child(element, name).ok_or(Error::ElementNotFound)
}

fn attribute<'d>(element: &Element<'d>, attribute: &str) -> Result<&'d str> {
    xml_util::attribute(element, attribute).ok_or(Error::AttributeNotFound)
}

fn time_span(element: &Element, buf: &mut String) -> Result<TimeSpan> {
    let text = text(element, buf);
    let milliseconds = text.parse::<i64>()?;
    Ok(TimeSpan::from_milliseconds(milliseconds as f64))
}

fn time(element: &Element, buf: &mut String) -> Result<Time> {
    Ok(RealTime(Some(time_span(element, buf)?)).into())
}

fn image<'b>(
    node: &Element,
    buf: &mut Vec<u8>,
    buf2: &'b mut Vec<u8>,
    str_buf: &mut String,
) -> Result<&'b [u8]> {
    let node = child(&node, "icon")?;
    let node = child(&node, "ImageIcon")?;

    buf.clear();
    base64::decode_config_buf(text(&node, str_buf), STANDARD, buf)
        .map_err(|_| Error::ElementNotFound)?;

    let (width, height);
    {
        let mut cursor = Cursor::new(&buf);
        cursor.seek(SeekFrom::Current(0xD1))?;
        height = cursor.read_u32::<BE>()?;
        width = cursor.read_u32::<BE>()?;
    }

    let len = width as usize * height as usize * 4;

    if buf.len() < 0xFE + len {
        return Err(Error::ElementNotFound);
    }

    let buf = &buf[0xFE..][..len];
    let image = ImageBuffer::<Rgba<_>, _>::from_raw(width, height, buf)
        .ok_or(Error::ElementNotFound)?;

    buf2.clear();
    png::PNGEncoder::new(&mut *buf2)
        .encode(image.as_ref(), width, height, ColorType::RGBA(8))
        .map_err(|_| Error::ElementNotFound)?;

    Ok(buf2)
}

pub fn parse<R: Read>(mut source: R) -> Result<Run> {
    let buf = &mut String::new();
    let mut byte_buf = Vec::new();
    let mut byte_buf2 = Vec::new();
    source.read_to_string(buf)?;
    let package = parse_xml(buf)?;

    let node = package
        .as_document()
        .root()
        .children()
        .into_iter()
        .filter_map(|c| c.element())
        .next()
        .unwrap();

    let mut run = Run::new();

    let node = child(&node, "Run")?;
    let node = child(&node, "default")?;

    run.set_game_name(text(&child(&node, "name")?, buf));
    run.set_category_name(text(&child(&node, "subTitle")?, buf));
    run.set_offset(
        TimeSpan::zero() - time_span(&child(&node, "delayedStart")?, buf)?,
    );
    run.set_attempt_count(text(&child(&node, "numberOfAttempts")?, buf).parse()?);

    let segments = child(&node, "segments")?;

    let mut total_time = TimeSpan::zero();

    for node in segments.children().into_iter().filter_map(|c| c.element()) {
        let node = child(&node, "Segment")?;
        let node = child(&node, "default")?;

        let mut segment = Segment::new(text(&child(&node, "name")?, buf));

        if let Ok(node) = child(&node, "bestTime") {
            if let Ok(node) = child(&node, "milliseconds") {
                segment.set_best_segment_time(time(&node, buf)?);
            }
        }

        if let Ok(node) = child(&node, "runTime") {
            if let Ok(node) = child(&node, "milliseconds") {
                total_time += time_span(&node, buf)?;
            } else if let Ok("../bestTime") = attribute(&node, "reference") {
                total_time += segment.best_segment_time().real_time.ok_or(
                    Error::ElementNotFound,
                )?;
            }
            segment.set_personal_best_split_time(RealTime(Some(total_time)).into());
        }

        if let Ok(image) = image(&node, &mut byte_buf, &mut byte_buf2, buf) {
            segment.set_icon(image);
        }

        run.push_segment(segment);
    }

    Ok(run)
}
<commit_msg>Handle Arithmetic Overflow in Gered Llanfair Parser<commit_after>use std::io::{self, Read, Cursor, Seek, SeekFrom};
use std::num::ParseIntError;
use std::result::Result as StdResult;
use {Run, TimeSpan, Time, RealTime, Segment};
use base64::{self, STANDARD};
use byteorder::{ReadBytesExt, BigEndian as BE};
use imagelib::{png, Rgba, ImageBuffer, ColorType};
use super::xml_util::{self, text};
use sxd_document::dom::Element;
use sxd_document::parser::{Error as XmlError, parse as parse_xml};

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        Xml(err: (usize, Vec<XmlError>)) {
            from()
        }
        Io(err: io::Error) {
            from()
        }
        Int(err: ParseIntError) {
            from()
        }
        LengthOutOfBounds
        ElementNotFound
        AttributeNotFound
    }
}

pub type Result<T> = StdResult<T, Error>;

fn child<'d>(element: &Element<'d>, name: &str) -> Result<Element<'d>> {
    xml_util::child(element, name).ok_or(Error::ElementNotFound)
}

fn attribute<'d>(element: &Element<'d>, attribute: &str) -> Result<&'d str> {
    xml_util::attribute(element, attribute).ok_or(Error::AttributeNotFound)
}

fn time_span(element: &Element, buf: &mut String) -> Result<TimeSpan> {
    let text = text(element, buf);
    let milliseconds = text.parse::<i64>()?;
    Ok(TimeSpan::from_milliseconds(milliseconds as f64))
}

fn time(element: &Element, buf: &mut String) -> Result<Time> {
    Ok(RealTime(Some(time_span(element, buf)?)).into())
}

fn image<'b>(
    node: &Element,
    buf: &mut Vec<u8>,
    buf2: &'b mut Vec<u8>,
    str_buf: &mut String,
) -> Result<&'b [u8]> {
    let node = child(&node, "icon")?;
    let node = child(&node, "ImageIcon")?;

    buf.clear();
    base64::decode_config_buf(text(&node, str_buf), STANDARD, buf)
        .map_err(|_| Error::ElementNotFound)?;

    let (width, height);
    {
        let mut cursor = Cursor::new(&buf);
        cursor.seek(SeekFrom::Current(0xD1))?;
        height = cursor.read_u32::<BE>()?;
        width = cursor.read_u32::<BE>()?;
    }

    let len = (width as usize)
        .checked_mul(height as usize)
        .and_then(|b| b.checked_mul(4))
        .ok_or(Error::LengthOutOfBounds)?;

    if buf.len() < 0xFE + len {
        return Err(Error::ElementNotFound);
    }

    let buf = &buf[0xFE..][..len];
    let image = ImageBuffer::<Rgba<_>, _>::from_raw(width, height, buf)
        .ok_or(Error::ElementNotFound)?;

    buf2.clear();
    png::PNGEncoder::new(&mut *buf2)
        .encode(image.as_ref(), width, height, ColorType::RGBA(8))
        .map_err(|_| Error::ElementNotFound)?;

    Ok(buf2)
}

pub fn parse<R: Read>(mut source: R) -> Result<Run> {
    let buf = &mut String::new();
    let mut byte_buf = Vec::new();
    let mut byte_buf2 = Vec::new();
    source.read_to_string(buf)?;
    let package = parse_xml(buf)?;

    let node = package
        .as_document()
        .root()
        .children()
        .into_iter()
        .filter_map(|c| c.element())
        .next()
        .unwrap();

    let mut run = Run::new();

    let node = child(&node, "Run")?;
    let node = child(&node, "default")?;

    run.set_game_name(text(&child(&node, "name")?, buf));
    run.set_category_name(text(&child(&node, "subTitle")?, buf));
    run.set_offset(
        TimeSpan::zero() - time_span(&child(&node, "delayedStart")?, buf)?,
    );
    run.set_attempt_count(text(&child(&node, "numberOfAttempts")?, buf).parse()?);

    let segments = child(&node, "segments")?;

    let mut total_time = TimeSpan::zero();

    for node in segments.children().into_iter().filter_map(|c| c.element()) {
        let node = child(&node, "Segment")?;
        let node = child(&node, "default")?;

        let mut segment = Segment::new(text(&child(&node, "name")?, buf));

        if let Ok(node) = child(&node, "bestTime") {
            if let Ok(node) = child(&node, "milliseconds") {
                segment.set_best_segment_time(time(&node, buf)?);
            }
        }

        if let Ok(node) = child(&node, "runTime") {
            if let Ok(node) = child(&node, "milliseconds") {
                total_time += time_span(&node, buf)?;
            } else if let Ok("../bestTime") = attribute(&node, "reference") {
                total_time += segment.best_segment_time().real_time.ok_or(
                    Error::ElementNotFound,
                )?;
            }
            segment.set_personal_best_split_time(RealTime(Some(total_time)).into());
        }

        if let Ok(image) = image(&node, &mut byte_buf, &mut byte_buf2, buf) {
            segment.set_icon(image);
        }

        run.push_segment(segment);
    }

    Ok(run)
}
<|endoftext|>


<commit_before>use std::sync::{Arc};
use std::f32::consts::{PI};

use cgmath::{Point3, Vector3, InnerSpace};
use rand;
use rand::distributions::{IndependentSample, Range};

use camera::{Camera, to_view_direction};
use context::{Context};
use input::{InputFrame};
use inverse_kinematics::{Axis, Chain, Joint, State, Transition, updater};
use inverse_kinematics::cyclic_coordinate_descent::{cyclic_coordinate_descent};
use inverse_kinematics::jacobian_transpose::{jacobian_transpose};

// TODO: put in a soft cap on elevation with a slow drift
//
pub struct PhysicsFrame {
	pub frame_counter:   u64,
	pub camera:          Camera,
	pub player_position: Point3<f32>,
	pub ik_chains:       Vec<Chain>,

	pub light_direction: Vector3<f32>,
	pub aspect_ratio:    f32,
}

impl PhysicsFrame {
	pub fn frame_zero(aspect_ratio: f32) -> PhysicsFrame {
		let light_direction = Vector3::new(0.4, -1.0, -0.6).normalize();
		let player_position = Point3::new(0f32, 1f32, 0f32);
		let camera = Camera::new(player_position, 0.0, 0.0, aspect_ratio);
		let ik_chains = vec![
			Chain {
				joints: vec![
					Joint { length: 0.0, axis: Axis::Y },
					Joint { length: 3.0, axis: Axis::X },
					Joint { length: 3.0, axis: Axis::X },
					Joint { length: 3.0, axis: Axis::X }
				],
				angles: vec![0.0, 0.0, 0.0, 0.1],
				state: State::Done,
				position: Vector3::new(59.0, -9.0, -9.0),
				ik_fun: cyclic_coordinate_descent,
			},
			Chain {
				joints: vec![
					Joint { length: 0.0, axis: Axis::Y },
					Joint { length: 3.0, axis: Axis::X },
					Joint { length: 3.0, axis: Axis::X },
					Joint { length: 3.0, axis: Axis::X }
				],
				angles: vec![0.0, 0.0, 0.0, 0.1],
				state: State::Done,
				position: Vector3::new(59.0, -9.0, 9.0),
				ik_fun: jacobian_transpose,
			}
		];

		PhysicsFrame {
			frame_counter:   0,
			camera:          camera,
			player_position: player_position,
			ik_chains:       ik_chains,
			light_direction: light_direction,
			aspect_ratio:    aspect_ratio,
		}
	}

	pub fn new(context: Arc<Context>, frame: Arc<PhysicsFrame>, input_frame: Arc<InputFrame>) -> PhysicsFrame {
		let angles_delta = -input_frame.view_angles_delta; // TODO: scale
		let camera = frame.camera.update(frame.player_position, angles_delta.x, angles_delta.y, context.render.aspect_ratio());

		let player_position = {
			let view_direction = camera.view_direction();
			let right = view_direction.cross(Vector3::new(0f32, 1f32, 0f32)).normalize();

			let input_direction = input_frame.movement_delta; // TODO: scale

			let flat_view_direction = (Vector3 { y: 0f32, .. view_direction }).normalize();
			let flat_right          = (Vector3 { y: 0f32, ..          right }).normalize();

			// TODO: generalize and factor out all integration
			//
			const FUDGE: f32 = 0.1f32;
			let acceleration
				= flat_view_direction * input_direction.x * FUDGE
				+ flat_right          * input_direction.y * FUDGE;

			frame.player_position + acceleration
		};
		let ik_chains = frame.ik_chains.iter().map(|chain| {
			if chain.state == State::Done {
				let target = sphere_point(9.0);

				updater::update(chain, Transition::NewTarget{
					target: target,
					num_transition_frames: 180
				})
			} else {
				updater::update(chain, Transition::Update)
			}
		}).collect();

		PhysicsFrame {
			frame_counter: frame.frame_counter + 1,
			camera: camera,
			player_position: player_position,
			ik_chains: ik_chains,

			light_direction: frame.light_direction,
			aspect_ratio: frame.aspect_ratio,
		}
	}
}

fn sphere_point(radius: f32) -> Vector3<f32> {
	let mut rng = rand::thread_rng();

	let azimuth_range = Range::new(0.0, PI);
	let elevation_range = Range::new(PI * 0.5, PI * 0.75);
	let radius_range = Range::new(radius * 0.2, radius);

	let unit = to_view_direction(
		azimuth_range.ind_sample(&mut rng),
		elevation_range.ind_sample(&mut rng)
	);

	unit * radius_range.ind_sample(&mut rng)
}
<commit_msg>Use the same target for all IK chains<commit_after>use std::sync::{Arc};
use std::f32::consts::{PI};

use cgmath::{Point3, Vector3, InnerSpace};
use rand;
use rand::distributions::{IndependentSample, Range};

use camera::{Camera, to_view_direction};
use context::{Context};
use input::{InputFrame};
use inverse_kinematics::{Axis, Chain, Joint, State, Transition, updater};
use inverse_kinematics::cyclic_coordinate_descent::{cyclic_coordinate_descent};
use inverse_kinematics::jacobian_transpose::{jacobian_transpose};

// TODO: put in a soft cap on elevation with a slow drift
//
pub struct PhysicsFrame {
	pub frame_counter:   u64,
	pub camera:          Camera,
	pub player_position: Point3<f32>,
	pub ik_chains:       Vec<Chain>,

	pub light_direction: Vector3<f32>,
	pub aspect_ratio:    f32,
}

impl PhysicsFrame {
	pub fn frame_zero(aspect_ratio: f32) -> PhysicsFrame {
		let light_direction = Vector3::new(0.4, -1.0, -0.6).normalize();
		let player_position = Point3::new(0f32, 1f32, 0f32);
		let camera = Camera::new(player_position, 0.0, 0.0, aspect_ratio);
		let ik_chains = vec![
			Chain {
				joints: vec![
					Joint { length: 0.0, axis: Axis::Y },
					Joint { length: 3.0, axis: Axis::X },
					Joint { length: 3.0, axis: Axis::X },
					Joint { length: 3.0, axis: Axis::X }
				],
				angles: vec![0.0, 0.0, 0.0, 0.1],
				state: State::Done,
				position: Vector3::new(59.0, -9.0, -9.0),
				ik_fun: cyclic_coordinate_descent,
			},
			Chain {
				joints: vec![
					Joint { length: 0.0, axis: Axis::Y },
					Joint { length: 3.0, axis: Axis::X },
					Joint { length: 3.0, axis: Axis::X },
					Joint { length: 3.0, axis: Axis::X }
				],
				angles: vec![0.0, 0.0, 0.0, 0.1],
				state: State::Done,
				position: Vector3::new(59.0, -9.0, 9.0),
				ik_fun: jacobian_transpose,
			}
		];

		PhysicsFrame {
			frame_counter:   0,
			camera:          camera,
			player_position: player_position,
			ik_chains:       ik_chains,
			light_direction: light_direction,
			aspect_ratio:    aspect_ratio,
		}
	}

	pub fn new(context: Arc<Context>, frame: Arc<PhysicsFrame>, input_frame: Arc<InputFrame>) -> PhysicsFrame {
		let angles_delta = -input_frame.view_angles_delta; // TODO: scale
		let camera = frame.camera.update(frame.player_position, angles_delta.x, angles_delta.y, context.render.aspect_ratio());

		let player_position = {
			let view_direction = camera.view_direction();
			let right = view_direction.cross(Vector3::new(0f32, 1f32, 0f32)).normalize();

			let input_direction = input_frame.movement_delta; // TODO: scale

			let flat_view_direction = (Vector3 { y: 0f32, .. view_direction }).normalize();
			let flat_right          = (Vector3 { y: 0f32, ..          right }).normalize();

			// TODO: generalize and factor out all integration
			//
			const FUDGE: f32 = 0.1f32;
			let acceleration
				= flat_view_direction * input_direction.x * FUDGE
				+ flat_right          * input_direction.y * FUDGE;

			frame.player_position + acceleration
		};
		let target = sphere_point(9.0);
		let ik_chains = frame.ik_chains.iter().map(|chain| {
			if chain.state == State::Done {
				updater::update(chain, Transition::NewTarget{
					target: target,
					num_transition_frames: 180
				})
			} else {
				updater::update(chain, Transition::Update)
			}
		}).collect();

		PhysicsFrame {
			frame_counter: frame.frame_counter + 1,
			camera: camera,
			player_position: player_position,
			ik_chains: ik_chains,

			light_direction: frame.light_direction,
			aspect_ratio: frame.aspect_ratio,
		}
	}
}

fn sphere_point(radius: f32) -> Vector3<f32> {
	let mut rng = rand::thread_rng();

	let azimuth_range = Range::new(0.0, PI);
	let elevation_range = Range::new(PI * 0.5, PI * 0.75);
	let radius_range = Range::new(radius * 0.2, radius);

	let unit = to_view_direction(
		azimuth_range.ind_sample(&mut rng),
		elevation_range.ind_sample(&mut rng)
	);

	unit * radius_range.ind_sample(&mut rng)
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use any_pointer;
use MessageSize;
use capability::{Params, Promise, Request, RemotePromise, Results};

pub trait ResponseHook {
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

pub trait RequestHook {
    fn get<'a>(&'a mut self) -> any_pointer::Builder<'a>;
    fn send<'a>(self : Box<Self>) -> RemotePromise<any_pointer::Owned>;
}

pub trait ClientHook {
    fn add_ref(&self) -> Box<ClientHook>;
    fn new_call(&self,
                interface_id: u64,
                method_id: u16,
                size_hint: Option<MessageSize>)
                -> Request<any_pointer::Owned, any_pointer::Owned>;

    fn call(&self, interface_id: u64, method_id: u16,
            params: Box<ParamsHook>, results: Box<ResultsHook>)
            -> (::capability::Promise<Box<ResultsDoneHook>, ::Error>, Box<PipelineHook>);

    fn get_brand(&self) -> usize;
    fn get_ptr(&self) -> usize;

    fn write_target(&self, target: any_pointer::Builder) -> Option<Box<ClientHook>>;

    fn write_descriptor(&self, descriptor: any_pointer::Builder) -> Option<u32>;

    /// If this ClientHook is a promise that has already resolved, returns the inner, resolved version
    /// of the capability.  The caller may permanently replace this client with the resolved one if
    /// desired.  Returns null if the client isn't a promise or hasn't resolved yet -- use
    /// `whenMoreResolved()` to distinguish between them.
    fn get_resolved(&self) -> Option<Box<ClientHook>>;

    /// If this client is a settled reference (not a promise), return nullptr.  Otherwise, return a
    /// promise that eventually resolves to a new client that is closer to being the final, settled
    /// client (i.e. the value eventually returned by `getResolved()`).  Calling this repeatedly
    /// should eventually produce a settled client.
    fn when_more_resolved(&self) -> Option<::capability::Promise<Box<ClientHook>, ::Error>>;
}

impl Clone for Box<ClientHook> {
    fn clone(&self) -> Box<ClientHook> {
        self.add_ref()
    }
}

pub trait ServerHook: 'static {
    fn new_client(server: Box<::capability::Server>) -> ::capability::Client;
}

pub trait ResultsHook {
    fn get<'a>(&'a mut self) -> ::Result<any_pointer::Builder<'a>>;
    fn get_as_reader<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
    fn allow_cancellation(&self);
    fn tail_call(self: Box<Self>, request: Box<RequestHook>) -> Promise<(), ::Error>;

    fn send_return(self: Box<Self>) -> Promise<Box<ResultsDoneHook>, ::Error>;
}

pub trait ResultsDoneHook {
    fn add_ref(&self) -> Box<ResultsDoneHook>;
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

impl Clone for Box<ResultsDoneHook> {
    fn clone(&self) -> Box<ResultsDoneHook> {
        self.add_ref()
    }
}

pub trait ParamsHook {
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

// Where should this live?
pub fn internal_get_typed_params<T>(typeless: Params<any_pointer::Owned>) -> Params<T> {
    Params { hook: typeless.hook, marker: ::std::marker::PhantomData }
}

pub fn internal_get_typed_results<T>(typeless: Results<any_pointer::Owned>) -> Results<T> {
    Results { hook: typeless.hook, marker: ::std::marker::PhantomData }
}

pub fn internal_get_untyped_results<T>(typeful: Results<T>) -> Results<any_pointer::Owned> {
    Results { hook: typeful.hook, marker: ::std::marker::PhantomData }
}

pub trait PipelineHook {
    fn add_ref(&self) -> Box<PipelineHook>;
    fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box<ClientHook>;

    /// Version of get_pipelined_cap() passing the array by move. May avoid a copy in some cases.
    /// Default implementation just calls the other version.
    fn get_pipelined_cap_move(&self, ops: Vec<PipelineOp>) -> Box<ClientHook> {
        self.get_pipelined_cap(&ops)
    }
}

impl Clone for Box<PipelineHook> {
    fn clone(&self) -> Box<PipelineHook> {
        self.add_ref()
    }
}

#[derive(Clone, Copy)]
pub enum PipelineOp {
    Noop,
    GetPointerField(u16),
}

<commit_msg>Get rid of ResultsHook::get_as_reader().<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use any_pointer;
use MessageSize;
use capability::{Params, Promise, Request, RemotePromise, Results};

pub trait ResponseHook {
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

pub trait RequestHook {
    fn get<'a>(&'a mut self) -> any_pointer::Builder<'a>;
    fn send<'a>(self : Box<Self>) -> RemotePromise<any_pointer::Owned>;
}

pub trait ClientHook {
    fn add_ref(&self) -> Box<ClientHook>;
    fn new_call(&self,
                interface_id: u64,
                method_id: u16,
                size_hint: Option<MessageSize>)
                -> Request<any_pointer::Owned, any_pointer::Owned>;

    fn call(&self, interface_id: u64, method_id: u16,
            params: Box<ParamsHook>, results: Box<ResultsHook>)
            -> (::capability::Promise<Box<ResultsDoneHook>, ::Error>, Box<PipelineHook>);

    fn get_brand(&self) -> usize;
    fn get_ptr(&self) -> usize;

    fn write_target(&self, target: any_pointer::Builder) -> Option<Box<ClientHook>>;

    fn write_descriptor(&self, descriptor: any_pointer::Builder) -> Option<u32>;

    /// If this ClientHook is a promise that has already resolved, returns the inner, resolved version
    /// of the capability.  The caller may permanently replace this client with the resolved one if
    /// desired.  Returns null if the client isn't a promise or hasn't resolved yet -- use
    /// `whenMoreResolved()` to distinguish between them.
    fn get_resolved(&self) -> Option<Box<ClientHook>>;

    /// If this client is a settled reference (not a promise), return nullptr.  Otherwise, return a
    /// promise that eventually resolves to a new client that is closer to being the final, settled
    /// client (i.e. the value eventually returned by `getResolved()`).  Calling this repeatedly
    /// should eventually produce a settled client.
    fn when_more_resolved(&self) -> Option<::capability::Promise<Box<ClientHook>, ::Error>>;
}

impl Clone for Box<ClientHook> {
    fn clone(&self) -> Box<ClientHook> {
        self.add_ref()
    }
}

pub trait ServerHook: 'static {
    fn new_client(server: Box<::capability::Server>) -> ::capability::Client;
}

pub trait ResultsHook {
    fn get<'a>(&'a mut self) -> ::Result<any_pointer::Builder<'a>>;
    fn allow_cancellation(&self);
    fn tail_call(self: Box<Self>, request: Box<RequestHook>) -> Promise<(), ::Error>;

    fn send_return(self: Box<Self>) -> Promise<Box<ResultsDoneHook>, ::Error>;
}

pub trait ResultsDoneHook {
    fn add_ref(&self) -> Box<ResultsDoneHook>;
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

impl Clone for Box<ResultsDoneHook> {
    fn clone(&self) -> Box<ResultsDoneHook> {
        self.add_ref()
    }
}

pub trait ParamsHook {
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

// Where should this live?
pub fn internal_get_typed_params<T>(typeless: Params<any_pointer::Owned>) -> Params<T> {
    Params { hook: typeless.hook, marker: ::std::marker::PhantomData }
}

pub fn internal_get_typed_results<T>(typeless: Results<any_pointer::Owned>) -> Results<T> {
    Results { hook: typeless.hook, marker: ::std::marker::PhantomData }
}

pub fn internal_get_untyped_results<T>(typeful: Results<T>) -> Results<any_pointer::Owned> {
    Results { hook: typeful.hook, marker: ::std::marker::PhantomData }
}

pub trait PipelineHook {
    fn add_ref(&self) -> Box<PipelineHook>;
    fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box<ClientHook>;

    /// Version of get_pipelined_cap() passing the array by move. May avoid a copy in some cases.
    /// Default implementation just calls the other version.
    fn get_pipelined_cap_move(&self, ops: Vec<PipelineOp>) -> Box<ClientHook> {
        self.get_pipelined_cap(&ops)
    }
}

impl Clone for Box<PipelineHook> {
    fn clone(&self) -> Box<PipelineHook> {
        self.add_ref()
    }
}

#[derive(Clone, Copy)]
pub enum PipelineOp {
    Noop,
    GetPointerField(u16),
}

<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use any_pointer;
use MessageSize;
use capability::{Params, Promise, Request, RemotePromise, Results};

pub trait ResponseHook {
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

pub trait RequestHook {
    fn get<'a>(&'a mut self) -> any_pointer::Builder<'a>;
    fn send<'a>(self : Box<Self>) -> RemotePromise<any_pointer::Owned>;
}

pub trait ClientHook {
    fn add_ref(&self) -> Box<ClientHook>;
    fn new_call(&self,
                interface_id: u64,
                method_id: u16,
                size_hint: Option<MessageSize>)
                -> Request<any_pointer::Owned, any_pointer::Owned>;

    fn call(&self, interface_id: u64, method_id: u16,
            params: Box<ParamsHook>, results: Box<ResultsHook>)
            -> (::capability::Promise<Box<ResultsDoneHook>, ::Error>, Box<PipelineHook>);

    fn get_brand(&self) -> usize;
    fn get_ptr(&self) -> usize;

    fn write_target(&self, target: any_pointer::Builder) -> Option<Box<ClientHook>>;

    fn write_descriptor(&self, descriptor: any_pointer::Builder) -> Option<u32>;

    /// If this ClientHook is a promise that has already resolved, returns the inner, resolved version
    /// of the capability.  The caller may permanently replace this client with the resolved one if
    /// desired.  Returns null if the client isn't a promise or hasn't resolved yet -- use
    /// `whenMoreResolved()` to distinguish between them.
    fn get_resolved(&self) -> Option<Box<ClientHook>>;

    /// If this client is a settled reference (not a promise), return nullptr.  Otherwise, return a
    /// promise that eventually resolves to a new client that is closer to being the final, settled
    /// client (i.e. the value eventually returned by `getResolved()`).  Calling this repeatedly
    /// should eventually produce a settled client.
    fn when_more_resolved(&self) -> Option<::capability::Promise<Box<ClientHook>, ::Error>>;
}

impl Clone for Box<ClientHook> {
    fn clone(&self) -> Box<ClientHook> {
        self.add_ref()
    }
}

pub trait ServerHook: 'static {
    fn new_client(server: Box<::capability::Server>) -> ::capability::Client;
}

pub trait ResultsHook {
    fn get<'a>(&'a mut self) -> ::Result<any_pointer::Builder<'a>>;
    fn get_as_reader<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
    fn allow_cancellation(&self);
    fn tail_call(self: Box<Self>, request: Box<RequestHook>) -> Promise<(), ::Error>;

}

pub trait ResultsDoneHook {
    fn add_ref(&self) -> Box<ResultsDoneHook>;
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

impl Clone for Box<ResultsDoneHook> {
    fn clone(&self) -> Box<ResultsDoneHook> {
        self.add_ref()
    }
}

pub trait ParamsHook {
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

// Where should this live?
pub fn internal_get_typed_params<T>(typeless: Params<any_pointer::Owned>) -> Params<T> {
    Params { hook: typeless.hook, marker: ::std::marker::PhantomData }
}

pub fn internal_get_typed_results<T>(typeless: Results<any_pointer::Owned>) -> Results<T> {
    Results { hook: typeless.hook, marker: ::std::marker::PhantomData }
}

pub fn internal_get_untyped_results<T>(typeful: Results<T>) -> Results<any_pointer::Owned> {
    Results { hook: typeful.hook, marker: ::std::marker::PhantomData }
}

pub trait PipelineHook {
    fn add_ref(&self) -> Box<PipelineHook>;
    fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box<ClientHook>;

    /// Version of get_pipelined_cap() passing the array by move. May avoid a copy in some cases.
    /// Default implementation just calls the other version.
    fn get_pipelined_cap_move(&self, ops: Vec<PipelineOp>) -> Box<ClientHook> {
        self.get_pipelined_cap(&ops)
    }
}

impl Clone for Box<PipelineHook> {
    fn clone(&self) -> Box<PipelineHook> {
        self.add_ref()
    }
}

#[derive(Clone, Copy)]
pub enum PipelineOp {
    Noop,
    GetPointerField(u16),
}

<commit_msg>send_return()<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use any_pointer;
use MessageSize;
use capability::{Params, Promise, Request, RemotePromise, Results};

pub trait ResponseHook {
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

pub trait RequestHook {
    fn get<'a>(&'a mut self) -> any_pointer::Builder<'a>;
    fn send<'a>(self : Box<Self>) -> RemotePromise<any_pointer::Owned>;
}

pub trait ClientHook {
    fn add_ref(&self) -> Box<ClientHook>;
    fn new_call(&self,
                interface_id: u64,
                method_id: u16,
                size_hint: Option<MessageSize>)
                -> Request<any_pointer::Owned, any_pointer::Owned>;

    fn call(&self, interface_id: u64, method_id: u16,
            params: Box<ParamsHook>, results: Box<ResultsHook>)
            -> (::capability::Promise<Box<ResultsDoneHook>, ::Error>, Box<PipelineHook>);

    fn get_brand(&self) -> usize;
    fn get_ptr(&self) -> usize;

    fn write_target(&self, target: any_pointer::Builder) -> Option<Box<ClientHook>>;

    fn write_descriptor(&self, descriptor: any_pointer::Builder) -> Option<u32>;

    /// If this ClientHook is a promise that has already resolved, returns the inner, resolved version
    /// of the capability.  The caller may permanently replace this client with the resolved one if
    /// desired.  Returns null if the client isn't a promise or hasn't resolved yet -- use
    /// `whenMoreResolved()` to distinguish between them.
    fn get_resolved(&self) -> Option<Box<ClientHook>>;

    /// If this client is a settled reference (not a promise), return nullptr.  Otherwise, return a
    /// promise that eventually resolves to a new client that is closer to being the final, settled
    /// client (i.e. the value eventually returned by `getResolved()`).  Calling this repeatedly
    /// should eventually produce a settled client.
    fn when_more_resolved(&self) -> Option<::capability::Promise<Box<ClientHook>, ::Error>>;
}

impl Clone for Box<ClientHook> {
    fn clone(&self) -> Box<ClientHook> {
        self.add_ref()
    }
}

pub trait ServerHook: 'static {
    fn new_client(server: Box<::capability::Server>) -> ::capability::Client;
}

pub trait ResultsHook {
    fn get<'a>(&'a mut self) -> ::Result<any_pointer::Builder<'a>>;
    fn get_as_reader<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
    fn allow_cancellation(&self);
    fn tail_call(self: Box<Self>, request: Box<RequestHook>) -> Promise<(), ::Error>;

    fn send_return(self: Box<Self>) -> Promise<Box<ResultsDoneHook>, ::Error>;
}

pub trait ResultsDoneHook {
    fn add_ref(&self) -> Box<ResultsDoneHook>;
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

impl Clone for Box<ResultsDoneHook> {
    fn clone(&self) -> Box<ResultsDoneHook> {
        self.add_ref()
    }
}

pub trait ParamsHook {
    fn get<'a>(&'a self) -> ::Result<any_pointer::Reader<'a>>;
}

// Where should this live?
pub fn internal_get_typed_params<T>(typeless: Params<any_pointer::Owned>) -> Params<T> {
    Params { hook: typeless.hook, marker: ::std::marker::PhantomData }
}

pub fn internal_get_typed_results<T>(typeless: Results<any_pointer::Owned>) -> Results<T> {
    Results { hook: typeless.hook, marker: ::std::marker::PhantomData }
}

pub fn internal_get_untyped_results<T>(typeful: Results<T>) -> Results<any_pointer::Owned> {
    Results { hook: typeful.hook, marker: ::std::marker::PhantomData }
}

pub trait PipelineHook {
    fn add_ref(&self) -> Box<PipelineHook>;
    fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box<ClientHook>;

    /// Version of get_pipelined_cap() passing the array by move. May avoid a copy in some cases.
    /// Default implementation just calls the other version.
    fn get_pipelined_cap_move(&self, ops: Vec<PipelineOp>) -> Box<ClientHook> {
        self.get_pipelined_cap(&ops)
    }
}

impl Clone for Box<PipelineHook> {
    fn clone(&self) -> Box<PipelineHook> {
        self.add_ref()
    }
}

#[derive(Clone, Copy)]
pub enum PipelineOp {
    Noop,
    GetPointerField(u16),
}

<|endoftext|>


<commit_before><commit_msg>Unconditionally update texture from pixels<commit_after><|endoftext|>


<commit_before>pub const RUNTIME: &'static str = r#"
#include "ruby.h"
#include <stdbool.h>

static VALUE escape_html(VALUE value) {
    VALUE cgi = rb_const_get(rb_cObject, rb_intern("CGI"));
    return rb_funcall(cgi, rb_intern("escapeHTML"), 1, value);
}

static VALUE fetch(VALUE context, VALUE key) {
    switch (rb_type(context)) {
        case T_HASH:
            return rb_hash_aref(context, key);
        case T_STRUCT:
            // TODO Check rb_struct_members to avoid name error.
            return rb_struct_aref(context, key);
        case T_OBJECT:
            // TODO Prevent undefined method error and check arity.
            return rb_funcall(context, rb_to_id(key), 0);
        default:
            return Qundef;
    }
}

static VALUE context_fetch(VALUE stack, VALUE key) {
    for (long i = RARRAY_LEN(stack) - 1; i >= 0; i--) {
        VALUE context = rb_ary_entry(stack, i);
        VALUE value = fetch(context, key);
        if (value != Qundef) {
            return value;
        }
    }
    return Qnil;
}

static VALUE fetch_path(VALUE stack, VALUE path) {
    VALUE value = context_fetch(stack, rb_ary_entry(path, 0));
    if (value == Qnil) {
        return Qnil;
    }
    for (long i = 1; i < RARRAY_LEN(path); i++) {
        value = fetch(value, rb_ary_entry(path, i));
        if (value == Qundef) {
            return Qnil;
        }
    }
    return value;
}

static void append_value(VALUE buf, VALUE stack, VALUE path, bool escape) {
    VALUE value = fetch_path(stack, path);
    switch (rb_type(value)) {
        case T_NIL:
        case T_UNDEF:
            return;
        case T_STRING:
            break;
        default:
            value = rb_funcall(value, rb_intern("to_s"), 0);
            break;
    }
    rb_str_buf_append(buf, escape ? escape_html(value) : value);
}

static void section(VALUE buf, VALUE stack, VALUE path, void (*block)(VALUE, VALUE)) {
    VALUE value = fetch_path(stack, path);
    switch (rb_type(value)) {
        case T_ARRAY:
            for (long i = 0; i < RARRAY_LEN(value); i++) {
                rb_ary_push(stack, rb_ary_entry(value, i));
                block(buf, stack);
                rb_ary_pop(stack);
            }
            break;
        case T_OBJECT:
        case T_STRUCT:
            rb_ary_push(stack, value);
            block(buf, stack);
            rb_ary_pop(stack);
            break;
        case T_NIL:
        case T_UNDEF:
        case T_FALSE:
            break;
        default:
            block(buf, stack);
            break;
    }
}

static void inverted(VALUE buf, VALUE stack, VALUE path, void (*block)(VALUE, VALUE)) {
    VALUE value = fetch_path(stack, path);
    switch (rb_type(value)) {
        case T_ARRAY:
            if (RARRAY_LEN(value) == 0) {
                block(buf, stack);
            }
            break;
        case T_NIL:
        case T_UNDEF:
        case T_FALSE:
            block(buf, stack);
            break;
    }
}
"#;
<commit_msg>Push Hash objects onto context stack<commit_after>pub const RUNTIME: &'static str = r#"
#include "ruby.h"
#include <stdbool.h>

static VALUE escape_html(VALUE value) {
    VALUE cgi = rb_const_get(rb_cObject, rb_intern("CGI"));
    return rb_funcall(cgi, rb_intern("escapeHTML"), 1, value);
}

static VALUE fetch(VALUE context, VALUE key) {
    switch (rb_type(context)) {
        case T_HASH:
            return rb_hash_aref(context, key);
        case T_STRUCT:
            // TODO Check rb_struct_members to avoid name error.
            return rb_struct_aref(context, key);
        case T_OBJECT:
            // TODO Prevent undefined method error and check arity.
            return rb_funcall(context, rb_to_id(key), 0);
        default:
            return Qundef;
    }
}

static VALUE context_fetch(VALUE stack, VALUE key) {
    for (long i = RARRAY_LEN(stack) - 1; i >= 0; i--) {
        VALUE context = rb_ary_entry(stack, i);
        VALUE value = fetch(context, key);
        if (value != Qundef) {
            return value;
        }
    }
    return Qnil;
}

static VALUE fetch_path(VALUE stack, VALUE path) {
    VALUE value = context_fetch(stack, rb_ary_entry(path, 0));
    if (value == Qnil) {
        return Qnil;
    }
    for (long i = 1; i < RARRAY_LEN(path); i++) {
        value = fetch(value, rb_ary_entry(path, i));
        if (value == Qundef) {
            return Qnil;
        }
    }
    return value;
}

static void append_value(VALUE buf, VALUE stack, VALUE path, bool escape) {
    VALUE value = fetch_path(stack, path);
    switch (rb_type(value)) {
        case T_NIL:
        case T_UNDEF:
            return;
        case T_STRING:
            break;
        default:
            value = rb_funcall(value, rb_intern("to_s"), 0);
            break;
    }
    rb_str_buf_append(buf, escape ? escape_html(value) : value);
}

static void section(VALUE buf, VALUE stack, VALUE path, void (*block)(VALUE, VALUE)) {
    VALUE value = fetch_path(stack, path);
    switch (rb_type(value)) {
        case T_ARRAY:
            for (long i = 0; i < RARRAY_LEN(value); i++) {
                rb_ary_push(stack, rb_ary_entry(value, i));
                block(buf, stack);
                rb_ary_pop(stack);
            }
            break;
        case T_HASH:
        case T_OBJECT:
        case T_STRUCT:
            rb_ary_push(stack, value);
            block(buf, stack);
            rb_ary_pop(stack);
            break;
        case T_NIL:
        case T_UNDEF:
        case T_FALSE:
            break;
        default:
            block(buf, stack);
            break;
    }
}

static void inverted(VALUE buf, VALUE stack, VALUE path, void (*block)(VALUE, VALUE)) {
    VALUE value = fetch_path(stack, path);
    switch (rb_type(value)) {
        case T_ARRAY:
            if (RARRAY_LEN(value) == 0) {
                block(buf, stack);
            }
            break;
        case T_NIL:
        case T_UNDEF:
        case T_FALSE:
            block(buf, stack);
            break;
    }
}
"#;
<|endoftext|>


<commit_before>// Copyright 2016 `multipart` Crate Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//! Server-side integration with [Hyper](https://github.com/hyperium/hyper).
//! Enabled with the `hyper` feature (on by default).
use hyper::net::Fresh;
use hyper::header::ContentType;
use hyper::method::Method;
use hyper::server::{Handler, Request, Response};

use mime::{Mime, TopLevel, SubLevel, Attr, Value};

use super::{Multipart, HttpRequest};

/// A container that implements `hyper::server::Handler` which will switch
/// the handler implementation depending on if the incoming request is multipart or not.
///
/// Create an instance with `new()` and pass it to `hyper::server::Server::listen()` where
/// you would normally pass a `Handler` instance.
///
/// A convenient wrapper for `Multipart::from_request()`.
pub struct Switch<H, M> {
    normal: H,
    multipart: M,
}

impl<H, M> Switch<H, M> where H: Handler, M: MultipartHandler {
    /// Create a new `Switch` instance where
    /// `normal` handles normal Hyper requests and `multipart` handles Multipart requests
    pub fn new(normal: H, multipart: M) -> Switch<H, M> {
        Switch {
            normal: normal,
            multipart: multipart,
        }
    }
}

impl<H, M> Handler for Switch<H, M> where H: Handler, M: MultipartHandler {
    fn handle<'a, 'k>(&'a self, req: Request<'a, 'k>, res: Response<'a, Fresh>) {
        match Multipart::from_request(req) {
            Ok(multi) => self.multipart.handle_multipart(multi, res),
            Err(req) => self.normal.handle(req, res),
        }
    }
}

/// A trait defining a type that can handle an incoming multipart request.
///
/// Extends to closures of the type `Fn(Multipart<Request>, Response<Fresh>)`,
/// and subsequently static functions.
pub trait MultipartHandler: Send + Sync {
    /// Generate a response from this multipart request.
    fn handle_multipart<'a, 'k>(&self,
                                multipart: Multipart<Request<'a, 'k>>,
                                response: Response<'a, Fresh>);
}

impl<F> MultipartHandler for F
where F: Fn(Multipart<Request>, Response<Fresh>), F: Send + Sync {
    fn handle_multipart<'a, 'k>(&self,
                                multipart: Multipart<Request<'a, 'k>>,
                                response: Response<'a, Fresh>) {
        (*self)(multipart, response);
    }
}

impl<'a, 'b> HttpRequest for Request<'a, 'b> {
    type Body = Self;

    fn multipart_boundary(&self) -> Option<&str> {
        if self.method != Method::Post {
            return None;
        }

        self.headers.get::<ContentType>().and_then(|ct| {
            let ContentType(ref mime) = *ct;
            let params = match *mime {
                Mime(TopLevel::Multipart, SubLevel::FormData, ref params) => params,
                _ => return None,
            };

            params.iter().find(|&&(ref name, _)|
                match *name {
                    Attr::Boundary => true,
                    _ => false,
                }
            ).and_then(|&(_, ref val)|
                match *val {
                    Value::Ext(ref val) => Some(&**val),
                    _ => None,
                }
            )
        })
    }

    fn body(&mut self) -> &mut Self {
        self
    }
}

<commit_msg>Add impl for &mut hyper::server::Request<commit_after>// Copyright 2016 `multipart` Crate Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//! Server-side integration with [Hyper](https://github.com/hyperium/hyper).
//! Enabled with the `hyper` feature (on by default).
use hyper::net::Fresh;
use hyper::header::ContentType;
use hyper::method::Method;
use hyper::server::{Handler, Request, Response};

use mime::{Mime, TopLevel, SubLevel, Attr, Value};

use super::{Multipart, HttpRequest};

/// A container that implements `hyper::server::Handler` which will switch
/// the handler implementation depending on if the incoming request is multipart or not.
///
/// Create an instance with `new()` and pass it to `hyper::server::Server::listen()` where
/// you would normally pass a `Handler` instance.
///
/// A convenient wrapper for `Multipart::from_request()`.
pub struct Switch<H, M> {
    normal: H,
    multipart: M,
}

impl<H, M> Switch<H, M> where H: Handler, M: MultipartHandler {
    /// Create a new `Switch` instance where
    /// `normal` handles normal Hyper requests and `multipart` handles Multipart requests
    pub fn new(normal: H, multipart: M) -> Switch<H, M> {
        Switch {
            normal: normal,
            multipart: multipart,
        }
    }
}

impl<H, M> Handler for Switch<H, M> where H: Handler, M: MultipartHandler {
    fn handle<'a, 'k>(&'a self, req: Request<'a, 'k>, res: Response<'a, Fresh>) {
        match Multipart::from_request(req) {
            Ok(multi) => self.multipart.handle_multipart(multi, res),
            Err(req) => self.normal.handle(req, res),
        }
    }
}

/// A trait defining a type that can handle an incoming multipart request.
///
/// Extends to closures of the type `Fn(Multipart<Request>, Response<Fresh>)`,
/// and subsequently static functions.
pub trait MultipartHandler: Send + Sync {
    /// Generate a response from this multipart request.
    fn handle_multipart<'a, 'k>(&self,
                                multipart: Multipart<Request<'a, 'k>>,
                                response: Response<'a, Fresh>);
}

impl<F> MultipartHandler for F
where F: Fn(Multipart<Request>, Response<Fresh>), F: Send + Sync {
    fn handle_multipart<'a, 'k>(&self,
                                multipart: Multipart<Request<'a, 'k>>,
                                response: Response<'a, Fresh>) {
        (*self)(multipart, response);
    }
}

impl<'a, 'b> HttpRequest for Request<'a, 'b> {
    type Body = Self;

    fn multipart_boundary(&self) -> Option<&str> {
        if self.method != Method::Post {
            return None;
        }

        self.headers.get::<ContentType>().and_then(|ct| {
            let ContentType(ref mime) = *ct;
            let params = match *mime {
                Mime(TopLevel::Multipart, SubLevel::FormData, ref params) => params,
                _ => return None,
            };

            params.iter().find(|&&(ref name, _)|
                match *name {
                    Attr::Boundary => true,
                    _ => false,
                }
            ).and_then(|&(_, ref val)|
                match *val {
                    Value::Ext(ref val) => Some(&**val),
                    _ => None,
                }
            )
        })
    }

    fn body(self) -> Self {
        self
    }
}

impl<'r, 'a, 'b> HttpRequest for &'r mut Request<'a, 'b> {
    type Body = &'r mut Request<'a, 'b>;

    fn multipart_boundary(&self) -> Option<&str> {
        if self.method != Method::Post {
            return None;
        }

        self.headers.get::<ContentType>().and_then(|ct| {
            let ContentType(ref mime) = *ct;
            let params = match *mime {
                Mime(TopLevel::Multipart, SubLevel::FormData, ref params) => params,
                _ => return None,
            };

            params.iter().find(|&&(ref name, _)|
                match *name {
                    Attr::Boundary => true,
                    _ => false,
                }
            ).and_then(|&(_, ref val)|
                match *val {
                    Value::Ext(ref val) => Some(&**val),
                    _ => None,
                }
            )
        })
    }

    fn body(self) -> Self::Body {
        self
    }
}

<|endoftext|>