<commit_before>use ascii::{AsAsciiStrError, AsciiChar, AsciiStr, ToAsciiChar, ToAsciiCharError};
use std::ascii::AsciiExt;
use std::borrow::{Borrow, BorrowMut};
use std::cmp::{Eq, PartialEq};
use std::convert::{AsRef, AsMut, From, Into};
use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};
use std::{fmt, mem, ptr, slice, str};
use ::{PascalStr, PASCAL_STRING_BUF_SIZE};

/// An owned `PascalString`. This string type stores its data the stack. It is always 256 bytes long, with
/// the first byte storing the length.
///
/// This string type uses Ascii encoding.
pub struct PascalString {
    /// The length of this string.
    len: u8,
    /// The characters of this string, encoded as an ascii array.
    chars: [AsciiChar; PASCAL_STRING_BUF_SIZE]
}

impl PascalString {
    /// Creates a new, empty `PascalString`.
    #[inline]
    pub fn new() -> Self {
        Default::default()
    }

    /// Create a new `PascalString` using the contents of `bytes`.
    ///
    /// Returns an `Err` if `bytes` is longer than 255 characters, or it does not contain
    /// Ascii encoded characters.
    #[inline]
    pub fn from<B: AsRef<[u8]>>(bytes: B) -> Result<Self, PascalStringCreateError> {
        PascalString::_from(bytes.as_ref())
    }

    fn _from(bytes: &[u8]) -> Result<Self, PascalStringCreateError>  {
        let len = bytes.len();
        if len > PASCAL_STRING_BUF_SIZE {
            return Err(PascalStringCreateError::InputTooLong);
        }
        // Perform ascii check
        let ascii = try!(AsciiStr::from_ascii(bytes));

        let mut string = PascalString::new();
        string.len = len as u8;
        for i in 0..len {
            string[i] = ascii[i];
        }
        Ok(string)
    }

    /// Push an ascii convertible character onto this string.
    ///
    /// # Panics
    ///
    /// Panics if the string is full, of if the `character` is not a valid ascii character.
    #[inline]
    pub fn push<C: ToAsciiChar>(&mut self, character: C) {
        self.try_push(character).unwrap();
    }

    /// Attempt to push an ascii convertible character onto the end of this `PascalString`.
    ///
    /// Returns `Err(_)` if the character cannot be pushed because this `PascalString` is full, or if
    /// `character` is not a valid ascii character.
    #[inline]
    pub fn try_push<C: ToAsciiChar>(&mut self, character: C) -> Result<(), PascalStringAppendError> {
        self._try_push(try!(AsciiChar::from(character)))
    }

    fn _try_push(&mut self, ch: AsciiChar) -> Result<(), PascalStringAppendError> {
        if self.is_full() {
            return Err(PascalStringAppendError::AppendedStringTooLong)
        }
        self.len += 1;
        let idx = self.len - 1;
        self[idx] = ch;
        Ok(())
    }

    /// Append a given string slice onto the end of this `PascalString`.
    ///
    /// # Panics
    ///
    /// Panics if the string cannot be pushed to because this `PascalString` is full.
    #[inline]
    pub fn push_str<S: AsRef<str>>(&mut self, s: S) {
        self.try_push_str(s).unwrap();
    }

    /// Attempt to append a given string slice onto the end of this `PascalString`.
    ///
    /// Returns `Err(_)` if the string cannot be pushed because this `PascalString` is full.
    #[inline]
    pub fn try_push_str<S: AsRef<str>>(&mut self, s: S) -> Result<(), PascalStringAppendError> {
        self._try_push_str(s.as_ref())
    }

    fn _try_push_str(&mut self, s: &str) -> Result<(), PascalStringAppendError> {
        unimplemented!()
    }

    /// Removes the last character from the string buffer and returns it.
    ///
    /// Returns `None` if this `PascalString` is empty.
    pub fn pop(&mut self) -> Option<AsciiChar> {
        if self.is_empty() {
            return None;
        }
        let c = self.chars[self.len as usize];
        self.len -= 1;
        Some(c)
    }

    pub fn remove(&mut self, index: u8) -> AsciiChar {
        assert!(self.len < index);
        let len = self.len as usize;
        let index = index as isize;
        let c = self[len];
        // Shift everything to the right of the removed character to the left to cover up the hole
        // left.
        unsafe {
            let ptr = self.as_mut_ptr().offset(index);
            ptr::copy(ptr.offset(1), ptr, len - index.abs() as usize - 1);
        }
        self.len -= 1;
        c
    }

    #[inline]
    pub fn insert<C: ToAsciiChar>(&mut self, ch: C, index: u8) {
        self._insert(AsciiChar::from(ch).unwrap(), index)
    }

    fn _insert(&mut self, ch: AsciiChar, index: u8) {
        assert!(self.len < index);
        assert!(!self.is_full());
        let len = self.len as usize;
        let index = index as isize;
        // Shift everything to the right of `index` 1 place to the right to make room for the
        // new character.
        unsafe {
            let ptr = self.as_mut_ptr().offset(index);
            ptr::copy(ptr, ptr.offset(1), len - index.abs() as usize - 1);
        }
        self[len] = ch;
        self.len += 1;
    }

    /// Truncates this String, removing all contents.
    ///
    /// Does not zero the values of the string.
    #[inline]
    pub fn clear(&mut self) {
        self.len = 0;
    }

    /// Consumes this `PascalString`, and returns its inner state as a `[u8; 256]`, where the first byte
    /// is the length.
    ///
    /// Note that if the string has been truncated, bytes beyond the end of the string will not have been
    /// zeroed.
    #[inline]
    pub fn to_array(self) -> [u8; PASCAL_STRING_BUF_SIZE + 1] {
        self.into()
    }

    /// Get a character in the string, without checking if the index is within the bounds of `len()`.
    ///
    /// This method cannot cause memory unsafety because of the size of `index`. However, it can give access
    /// to stale characters if `index` is greater than `len()`, and `len() < 255`.
    #[inline]
    pub fn get_unchecked(&self, index: u8) -> AsciiChar {
        self.chars[index as usize]
    }
}

impl Default for PascalString {
    #[inline]
    fn default() -> Self {
        PascalString {
            len: 0,
            chars: [AsciiChar::Null; PASCAL_STRING_BUF_SIZE]
        }
    }
}

impl Clone for PascalString {
    fn clone(&self) -> Self {
        let mut clone = PascalString::default();
        clone.len = self.len;
        unsafe {
            ptr::copy_nonoverlapping(&self.chars, &mut clone.chars, PASCAL_STRING_BUF_SIZE);
        }
        clone
    }
}

impl Eq for PascalString { }

impl PartialEq for PascalString {
    fn eq(&self, other: &PascalString) -> bool {
        if self.len != other.len {
            return false;
        }
        self.chars.iter().zip(other.chars.iter()).all(|(c0, c1)| c0 == c1)
    }
}

impl Hash for PascalString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_u8(self.len);
        state.write(self.as_ref());
    }
}

impl AsciiExt for PascalString {
    type Owned = Self;

    fn is_ascii(&self) -> bool {
        true
    }

    fn to_ascii_uppercase(&self) -> Self::Owned {
        let mut upper = self.clone();
        upper.make_ascii_uppercase();
        upper
    }

    fn to_ascii_lowercase(&self) -> Self::Owned {
        let mut lower = self.clone();
        lower.make_ascii_lowercase();
        lower
    }

    fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
        self.chars.iter().zip(other.chars.iter()).all(|(c0, c1)| c0.eq_ignore_ascii_case(&c1))
    }

    fn make_ascii_uppercase(&mut self) {
        for c in self.chars.iter_mut() {
            c.make_ascii_uppercase();
        }
    }

    fn make_ascii_lowercase(&mut self) {
        for c in self.chars.iter_mut() {
            c.make_ascii_lowercase();
        }
    }
}

impl fmt::Debug for PascalString {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        write!(fmtr, "{}", self)
    }
}

impl fmt::Display for PascalString {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        fmtr.pad(self.as_ref())
    }
}

impl Deref for PascalString {
    type Target = PascalStr;
    fn deref(&self) -> &Self::Target {
        let ascii_str: &[AsciiChar] = self.as_ref();
        unsafe {
            mem::transmute(ascii_str)
        }
    }
}

impl DerefMut for PascalString {
    fn deref_mut(&mut self) -> &mut Self::Target {
        let ascii_str: &mut [AsciiChar] = self.as_mut();
        unsafe {
            mem::transmute(ascii_str)
        }
    }
}

impl AsRef<PascalStr> for PascalString {
    fn as_ref(&self) -> &PascalStr {
        self.deref()
    }
}

impl AsRef<str> for PascalString {
    fn as_ref(&self) -> &str {
        let bytes: &[u8] = self.as_ref();
        str::from_utf8(bytes).unwrap()
    }
}

impl AsRef<[u8]> for PascalString {
    fn as_ref(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self.chars.as_ptr() as *const u8, self.len as usize)
        }
    }
}

impl AsRef<AsciiStr> for PascalString {
    fn as_ref(&self) -> &AsciiStr {
        let bytes: &[u8] = self.as_ref();
        AsciiStr::from_ascii(bytes).unwrap()
    }
}

impl AsRef<[AsciiChar]> for PascalString {
    fn as_ref(&self) -> &[AsciiChar] {
        unsafe {
            slice::from_raw_parts(self.chars.as_ptr(), self.len as usize)
        }
    }
}

impl AsMut<[AsciiChar]> for PascalString {
    fn as_mut(&mut self) -> &mut [AsciiChar] {
        unsafe {
            slice::from_raw_parts_mut(self.chars.as_mut_ptr(), self.len as usize)
        }
    }
}

impl Borrow<PascalStr> for PascalString {
    fn borrow(&self) -> &PascalStr {
        self.deref()
    }
}

impl BorrowMut<PascalStr> for PascalString {
    fn borrow_mut(&mut self) -> &mut PascalStr {
        self.deref_mut()
    }
}

impl Borrow<str> for PascalString {
    fn borrow(&self) -> &str {
        self.as_ref()
    }
}

impl Borrow<[u8]> for PascalString {
    fn borrow(&self) -> &[u8] {
        self.as_ref()
    }
}

impl Borrow<AsciiStr> for PascalString {
    fn borrow(&self) -> &AsciiStr {
        self.as_ref()
    }
}

impl Borrow<[AsciiChar]> for PascalString {
    fn borrow(&self) -> &[AsciiChar] {
        self.as_ref()
    }
}

impl BorrowMut<[AsciiChar]> for PascalString {
    fn borrow_mut(&mut self) -> &mut [AsciiChar] {
        self.as_mut()
    }
}

impl Into<[u8; PASCAL_STRING_BUF_SIZE + 1]> for PascalString {
    fn into(self) -> [u8; PASCAL_STRING_BUF_SIZE + 1] {
        let mut array = [0u8; PASCAL_STRING_BUF_SIZE + 1];
        array[0] = self.len;
        unsafe {
            let chars_ptr = &self.chars as *const _ as *const [u8; PASCAL_STRING_BUF_SIZE];
            let array_ptr = (&mut array as *mut _).offset(1) as *mut [u8; PASCAL_STRING_BUF_SIZE];
            ptr::copy_nonoverlapping(chars_ptr, array_ptr, PASCAL_STRING_BUF_SIZE);
        }
        array
    }
}

impl Into<String> for PascalString {
    fn into(self) -> String {
        String::from_utf8_lossy(self.as_ref()).into_owned()
    }
}

#[derive(Debug, PartialEq)]
pub enum PascalStringCreateError {
    InputTooLong,
    NotValidAscii(AsAsciiStrError)
}

impl From<AsAsciiStrError> for PascalStringCreateError {
    fn from(e: AsAsciiStrError) -> Self {
        PascalStringCreateError::NotValidAscii(e)
    }
}

#[derive(Debug, PartialEq)]
pub enum PascalStringAppendError {
    AppendedStringTooLong,
    InvalidCharAppended(ToAsciiCharError),
    InvalidStringAppended(AsAsciiStrError)
}

impl From<ToAsciiCharError> for PascalStringAppendError {
    fn from(e: ToAsciiCharError) -> Self {
        PascalStringAppendError::InvalidCharAppended(e)
    }
}

impl From<AsAsciiStrError> for PascalStringAppendError {
    fn from(e: AsAsciiStrError) -> Self {
        PascalStringAppendError::InvalidStringAppended(e)
    }
}<commit_msg>Add impl Into<Vec<u8>> for PascalString, and set the trailing byte to null after mutating string operations, to facilitate a new api on PascalStr<commit_after>use ascii::{AsAsciiStrError, AsciiChar, AsciiStr, ToAsciiChar, ToAsciiCharError};
use std::ascii::AsciiExt;
use std::borrow::{Borrow, BorrowMut};
use std::cmp::{Eq, PartialEq};
use std::convert::{AsRef, AsMut, From, Into};
use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};
use std::{fmt, mem, ptr, slice, str};
use ::{PascalStr, PASCAL_STRING_BUF_SIZE};

/// An owned `PascalString`. This string type stores its data the stack. It is always 256 bytes long, with
/// the first byte storing the length.
///
/// This string type uses Ascii encoding.
pub struct PascalString {
    /// The length of this string.
    len: u8,
    /// The characters of this string, encoded as an ascii array.
    chars: [AsciiChar; PASCAL_STRING_BUF_SIZE]
}

impl PascalString {
    /// Creates a new, empty `PascalString`.
    #[inline]
    pub fn new() -> Self {
        Default::default()
    }

    /// Create a new `PascalString` using the contents of `bytes`.
    ///
    /// Returns an `Err` if `bytes` is longer than 255 characters, or it does not contain
    /// Ascii encoded characters.
    #[inline]
    pub fn from<B: AsRef<[u8]>>(bytes: B) -> Result<Self, PascalStringCreateError> {
        PascalString::_from(bytes.as_ref())
    }

    fn _from(bytes: &[u8]) -> Result<Self, PascalStringCreateError>  {
        let len = bytes.len();
        if len > PASCAL_STRING_BUF_SIZE {
            return Err(PascalStringCreateError::InputTooLong);
        }
        // Perform ascii check
        let ascii = try!(AsciiStr::from_ascii(bytes));

        let mut string = PascalString::new();
        string.len = len as u8;
        for i in 0..len {
            string[i] = ascii[i];
        }
        Ok(string)
    }

    /// Push an ascii convertible character onto this string.
    ///
    /// # Panics
    ///
    /// Panics if the string is full, of if the `character` is not a valid ascii character.
    #[inline]
    pub fn push<C: ToAsciiChar>(&mut self, character: C) {
        self.try_push(character).unwrap();
    }

    /// Attempt to push an ascii convertible character onto the end of this `PascalString`.
    ///
    /// Returns `Err(_)` if the character cannot be pushed because this `PascalString` is full, or if
    /// `character` is not a valid ascii character.
    #[inline]
    pub fn try_push<C: ToAsciiChar>(&mut self, character: C) -> Result<(), PascalStringAppendError> {
        self._try_push(try!(AsciiChar::from(character)))
    }

    fn _try_push(&mut self, ch: AsciiChar) -> Result<(), PascalStringAppendError> {
        if self.is_full() {
            return Err(PascalStringAppendError::AppendedStringTooLong)
        }
        self.len += 1;
        let idx = self.len - 1;
        self[idx] = ch;
        self.set_trailing_byte_to_null();
        Ok(())
    }

    /// Append a given string slice onto the end of this `PascalString`.
    ///
    /// # Panics
    ///
    /// Panics if the string cannot be pushed to because this `PascalString` is full.
    #[inline]
    pub fn push_str<S: AsRef<str>>(&mut self, s: S) {
        self.try_push_str(s).unwrap();
    }

    /// Attempt to append a given string slice onto the end of this `PascalString`.
    ///
    /// Returns `Err(_)` if the string cannot be pushed because this `PascalString` is full.
    #[inline]
    pub fn try_push_str<S: AsRef<str>>(&mut self, s: S) -> Result<(), PascalStringAppendError> {
        self._try_push_str(s.as_ref())
    }

    fn _try_push_str(&mut self, s: &str) -> Result<(), PascalStringAppendError> {
        unimplemented!()
    }

    /// Removes the last character from the string buffer and returns it.
    ///
    /// Returns `None` if this `PascalString` is empty.
    pub fn pop(&mut self) -> Option<AsciiChar> {
        if self.is_empty() {
            return None;
        }
        let c = self.chars[self.len as usize];
        self.len -= 1;
        self.set_trailing_byte_to_null();
        Some(c)
    }

    pub fn remove(&mut self, index: u8) -> AsciiChar {
        assert!(self.len < index);
        let len = self.len as usize;
        let index = index as isize;
        let c = self[len];
        // Shift everything to the right of the removed character to the left to cover up the hole
        // left.
        unsafe {
            let ptr = self.as_mut_ptr().offset(index);
            ptr::copy(ptr.offset(1), ptr, len - index.abs() as usize - 1);
        }
        self.len -= 1;
        self.set_trailing_byte_to_null();
        c
    }

    #[inline]
    pub fn insert<C: ToAsciiChar>(&mut self, ch: C, index: u8) {
        self._insert(AsciiChar::from(ch).unwrap(), index)
    }

    fn _insert(&mut self, ch: AsciiChar, index: u8) {
        assert!(self.len < index);
        assert!(!self.is_full());
        let len = self.len as usize;
        let index = index as isize;
        // Shift everything to the right of `index` 1 place to the right to make room for the
        // new character.
        unsafe {
            let ptr = self.as_mut_ptr().offset(index);
            ptr::copy(ptr, ptr.offset(1), len - index.abs() as usize - 1);
        }
        self[len] = ch;
        self.len += 1;
        self.set_trailing_byte_to_null();
    }

    /// Truncates this String, removing all contents.
    ///
    /// Does not zero the values of the string.
    #[inline]
    pub fn clear(&mut self) {
        self.len = 0;
        self.set_trailing_byte_to_null();
    }

    /// Consumes this `PascalString`, and returns its inner state as a `[u8; 256]`, where the first byte
    /// is the length.
    ///
    /// Note that if the string has been truncated, bytes beyond the end of the string will not have been
    /// zeroed.
    #[inline]
    pub fn to_array(self) -> [u8; PASCAL_STRING_BUF_SIZE + 1] {
        self.into()
    }

    /// Get a character in the string, without checking if the index is within the bounds of `len()`.
    ///
    /// This method cannot cause memory unsafety because of the size of `index`. However, it can give access
    /// to stale characters if `index` is greater than `len()`, and `len() < 255`.
    #[inline]
    pub fn get_unchecked(&self, index: u8) -> AsciiChar {
        self.chars[index as usize]
    }

    #[inline]
    fn set_trailing_byte_to_null(&mut self) {
        if !self.is_full() {
            self.chars[self.len as usize] = AsciiChar::Null;
        }
    }
}

impl Default for PascalString {
    #[inline]
    fn default() -> Self {
        PascalString {
            len: 0,
            chars: [AsciiChar::Null; PASCAL_STRING_BUF_SIZE]
        }
    }
}

impl Clone for PascalString {
    fn clone(&self) -> Self {
        let mut clone = PascalString::default();
        clone.len = self.len;
        unsafe {
            ptr::copy_nonoverlapping(&self.chars, &mut clone.chars, PASCAL_STRING_BUF_SIZE);
        }
        clone
    }
}

impl Eq for PascalString { }

impl PartialEq for PascalString {
    fn eq(&self, other: &PascalString) -> bool {
        if self.len != other.len {
            return false;
        }
        self.chars.iter().zip(other.chars.iter()).all(|(c0, c1)| c0 == c1)
    }
}

impl Hash for PascalString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_u8(self.len);
        state.write(self.as_ref());
    }
}

impl AsciiExt for PascalString {
    type Owned = Self;

    fn is_ascii(&self) -> bool {
        true
    }

    fn to_ascii_uppercase(&self) -> Self::Owned {
        let mut upper = self.clone();
        upper.make_ascii_uppercase();
        upper
    }

    fn to_ascii_lowercase(&self) -> Self::Owned {
        let mut lower = self.clone();
        lower.make_ascii_lowercase();
        lower
    }

    fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
        self.chars.iter().zip(other.chars.iter()).all(|(c0, c1)| c0.eq_ignore_ascii_case(&c1))
    }

    fn make_ascii_uppercase(&mut self) {
        for c in self.chars.iter_mut() {
            c.make_ascii_uppercase();
        }
    }

    fn make_ascii_lowercase(&mut self) {
        for c in self.chars.iter_mut() {
            c.make_ascii_lowercase();
        }
    }
}

impl fmt::Debug for PascalString {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        write!(fmtr, "{}", self)
    }
}

impl fmt::Display for PascalString {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        fmtr.pad(self.as_ref())
    }
}

impl Deref for PascalString {
    type Target = PascalStr;
    fn deref(&self) -> &Self::Target {
        let ascii_str: &[AsciiChar] = self.as_ref();
        unsafe {
            mem::transmute(ascii_str)
        }
    }
}

impl DerefMut for PascalString {
    fn deref_mut(&mut self) -> &mut Self::Target {
        let ascii_str: &mut [AsciiChar] = self.as_mut();
        unsafe {
            mem::transmute(ascii_str)
        }
    }
}

impl AsRef<PascalStr> for PascalString {
    fn as_ref(&self) -> &PascalStr {
        self.deref()
    }
}

impl AsRef<str> for PascalString {
    fn as_ref(&self) -> &str {
        let bytes: &[u8] = self.as_ref();
        str::from_utf8(bytes).unwrap()
    }
}

impl AsRef<[u8]> for PascalString {
    fn as_ref(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self.chars.as_ptr() as *const u8, self.len as usize)
        }
    }
}

impl AsRef<AsciiStr> for PascalString {
    fn as_ref(&self) -> &AsciiStr {
        let bytes: &[u8] = self.as_ref();
        AsciiStr::from_ascii(bytes).unwrap()
    }
}

impl AsRef<[AsciiChar]> for PascalString {
    fn as_ref(&self) -> &[AsciiChar] {
        unsafe {
            slice::from_raw_parts(self.chars.as_ptr(), self.len as usize)
        }
    }
}

impl AsMut<[AsciiChar]> for PascalString {
    fn as_mut(&mut self) -> &mut [AsciiChar] {
        unsafe {
            slice::from_raw_parts_mut(self.chars.as_mut_ptr(), self.len as usize)
        }
    }
}

impl Borrow<PascalStr> for PascalString {
    fn borrow(&self) -> &PascalStr {
        self.deref()
    }
}

impl BorrowMut<PascalStr> for PascalString {
    fn borrow_mut(&mut self) -> &mut PascalStr {
        self.deref_mut()
    }
}

impl Borrow<str> for PascalString {
    fn borrow(&self) -> &str {
        self.as_ref()
    }
}

impl Borrow<[u8]> for PascalString {
    fn borrow(&self) -> &[u8] {
        self.as_ref()
    }
}

impl Borrow<AsciiStr> for PascalString {
    fn borrow(&self) -> &AsciiStr {
        self.as_ref()
    }
}

impl Borrow<[AsciiChar]> for PascalString {
    fn borrow(&self) -> &[AsciiChar] {
        self.as_ref()
    }
}

impl BorrowMut<[AsciiChar]> for PascalString {
    fn borrow_mut(&mut self) -> &mut [AsciiChar] {
        self.as_mut()
    }
}

impl Into<[u8; PASCAL_STRING_BUF_SIZE + 1]> for PascalString {
    fn into(self) -> [u8; PASCAL_STRING_BUF_SIZE + 1] {
        let mut array = [0u8; PASCAL_STRING_BUF_SIZE + 1];
        array[0] = self.len;
        unsafe {
            let chars_ptr = &self.chars as *const _ as *const [u8; PASCAL_STRING_BUF_SIZE];
            let array_ptr = (&mut array as *mut _).offset(1) as *mut [u8; PASCAL_STRING_BUF_SIZE];
            ptr::copy_nonoverlapping(chars_ptr, array_ptr, PASCAL_STRING_BUF_SIZE);
        }
        array
    }
}

impl Into<String> for PascalString {
    fn into(self) -> String {
        String::from_utf8_lossy(self.as_ref()).into_owned()
    }
}

impl Into<Vec<u8>> for PascalString {
    fn into(self) -> Vec<u8> {
        let mut v = Vec::with_capacity(self.len());
        v.extend_from_slice(self.as_ref());
        v
    }
}

#[derive(Debug, PartialEq)]
pub enum PascalStringCreateError {
    InputTooLong,
    NotValidAscii(AsAsciiStrError)
}

impl From<AsAsciiStrError> for PascalStringCreateError {
    fn from(e: AsAsciiStrError) -> Self {
        PascalStringCreateError::NotValidAscii(e)
    }
}

#[derive(Debug, PartialEq)]
pub enum PascalStringAppendError {
    AppendedStringTooLong,
    InvalidCharAppended(ToAsciiCharError),
    InvalidStringAppended(AsAsciiStrError)
}

impl From<ToAsciiCharError> for PascalStringAppendError {
    fn from(e: ToAsciiCharError) -> Self {
        PascalStringAppendError::InvalidCharAppended(e)
    }
}

impl From<AsAsciiStrError> for PascalStringAppendError {
    fn from(e: AsAsciiStrError) -> Self {
        PascalStringAppendError::InvalidStringAppended(e)
    }
}<|endoftext|>


<commit_before>extern crate clap;
extern crate rusqlite;
#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;
extern crate rustc_serialize;
extern crate serde_yaml;
extern crate uuid;
#[cfg(test)]
#[macro_use]
extern crate proptest;

mod actions_process;
mod actions_process_list_provides;
mod autoconf;
mod clap_actions;
mod clap_fern;
mod cli_clap;
mod db;
mod db_enviroment;
mod db_fs_dir;
mod db_fs_dir_type;
mod db_fs_file;
mod db_job;
mod db_job_depend;
mod db_job_provide;
mod db_job_require_variable;
mod db_job_require_variable_pair;
mod db_provider;
use db::db_session;
mod db_variable_name;
mod db_variable_pair;
mod elephant;
mod jobs_load;
mod json_loader_elephant;
mod loader;
use uuid::Uuid;

fn main() {
    let some_value = 10;
    let clap_matches = cli_clap::cli_clap(&some_value);
    let actions = clap_actions::actions_get(&clap_matches);
    clap_fern::log_setup(&clap_matches);
    let session_uuid = Uuid::new_v4();
    let session_uuid_string = session_uuid.hyphenated().to_string();
    trace!("session_uuid_string:{}", session_uuid_string);
    let conn = db::connect_deligate(&clap_matches);
    db::create_tables(&conn);
    loader::deligate(&conn, &actions, &clap_matches);
    let pk_session = elephant::elephant_session(&conn, &session_uuid_string);
    loader::enviroment(&conn, pk_session, &clap_matches);
    jobs_load::load(&conn);
    actions_process::process(&conn, &actions)
}
<commit_msg>Move db_provider into db module<commit_after>extern crate clap;
extern crate rusqlite;
#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;
extern crate rustc_serialize;
extern crate serde_yaml;
extern crate uuid;
#[cfg(test)]
#[macro_use]
extern crate proptest;

mod actions_process;
mod actions_process_list_provides;
mod autoconf;
mod clap_actions;
mod clap_fern;
mod cli_clap;
mod db;
mod db_enviroment;
mod db_fs_dir;
mod db_fs_dir_type;
mod db_fs_file;
use db::db_job;
mod db_job_depend;
mod db_job_provide;
mod db_job_require_variable;
mod db_job_require_variable_pair;
use db::db_provider;
use db::db_session;
mod db_variable_name;
mod db_variable_pair;
mod elephant;
mod jobs_load;
mod json_loader_elephant;
mod loader;
use uuid::Uuid;

fn main() {
    let some_value = 10;
    let clap_matches = cli_clap::cli_clap(&some_value);
    let actions = clap_actions::actions_get(&clap_matches);
    clap_fern::log_setup(&clap_matches);
    let session_uuid = Uuid::new_v4();
    let session_uuid_string = session_uuid.hyphenated().to_string();
    trace!("session_uuid_string:{}", session_uuid_string);
    let conn = db::connect_deligate(&clap_matches);
    db::create_tables(&conn);
    loader::deligate(&conn, &actions, &clap_matches);
    let pk_session = elephant::elephant_session(&conn, &session_uuid_string);
    loader::enviroment(&conn, pk_session, &clap_matches);
    jobs_load::load(&conn);
    actions_process::process(&conn, &actions)
}
<|endoftext|>


<commit_before>//   Copyright 2014 Colin Sherratt
//
//   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.

#![crate_name = "snowmew-position"]

#![crate_type = "lib"]
#![feature(macro_rules)]
#![feature(old_orphan_check)]
#![feature(associated_types)]

extern crate "snowmew-core" as snowmew;
extern crate cgmath;
extern crate opencl;
extern crate cow;
extern crate time;
extern crate "rustc-serialize" as rustc_serialize;

use std::default::Default;

use cgmath::{Transform, Decomposed, Vector3, Matrix4, ToMatrix4, Matrix, Quaternion};

use snowmew::common::{Entity, Duplicate, Delete};
use snowmew::input_integrator::InputIntegratorGameData;
use snowmew::table::{Dynamic, DynamicIterator};

pub trait MatrixManager {
    fn size(&mut self, size: uint);
    fn set(&mut self, idx: uint, mat: Matrix4<f32>);
    fn get(&self, idx: uint) -> Matrix4<f32>;
}

impl<'r> MatrixManager for Vec<Matrix4<f32>> {
    fn size(&mut self, size: uint) {
        if self.len() < size {
            let amount = self.len() - size;
            self.grow(amount, Matrix4::identity())
        }
    }
    fn set(&mut self, idx: uint, m: Matrix4<f32>) { self[idx] = m; }
    fn get(&self, idx: uint) -> Matrix4<f32> { self[idx] }
}

#[derive(RustcEncodable, RustcDecodable, Copy)]
pub struct Delta {
    pub parent: Option<Entity>,
    pub delta: Decomposed<f32, Vector3<f32>, Quaternion<f32>>
}

impl Clone for Delta {
    fn clone(&self) -> Delta {
        Delta {
            parent: self.parent,
            delta: self.delta
        }
    }
}

impl Default for Delta {
    fn default() -> Delta {
        Delta {
            parent: None,
            delta: Transform::identity()
        }
    }
}

#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct PositionData {
    delta: Dynamic<Delta>,
}

impl PositionData {
    pub fn new() -> PositionData {
        PositionData {
            delta: Dynamic::new()
        }
    }
}

pub trait Positions {
    fn get_position<'a>(&'a self) -> &'a PositionData;
    fn get_position_mut<'a>(&'a mut self) -> &'a mut PositionData;

    fn set_delta(&mut self,
                 key: Entity,
                 parent: Option<Entity>,
                 transform: Decomposed<f32, Vector3<f32>, Quaternion<f32>>) {
        self.get_position_mut().delta.insert(key,
            Delta {
                parent: parent,
                delta: transform
            }
        );
    }

    fn set_to_identity(&mut self, key: Entity) {
        self.set_delta(key, None, Transform::identity())
    }

    fn init_position(&mut self, key: Entity) {
        if self.get_position().delta.get(key).is_none() {
            self.set_to_identity(key);
        }
    }

    fn set_scale(&mut self, key: Entity, scale: f32) {
        self.init_position(key);
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| d.delta.scale = scale);
    }

    fn set_displacement(&mut self, key: Entity, disp: Vector3<f32>) {
        self.init_position(key);
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| d.delta.disp = disp);
    }

    fn set_rotation(&mut self, key: Entity, rot: Quaternion<f32>) {
        self.init_position(key);
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| d.delta.rot = rot);
    }

    fn get_scale(&mut self, key: Entity) -> Option<&f32> {
        self.get_position()
            .delta.get(key)
            .map(|d| &d.delta.scale)
    }

    fn get_displacement(&mut self, key: Entity) -> Option<&Vector3<f32>> {
        self.get_position()
            .delta.get(key)
            .map(|d| &d.delta.disp)
    }

    fn get_rotation(&mut self, key: Entity) -> Option<&Quaternion<f32>> {
        self.get_position()
            .delta.get(key)
            .map(|d| &d.delta.rot)
    }

    fn get_mut_scale(&mut self, key: Entity) -> Option<&mut f32> {
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| &mut d.delta.scale)
    }

    fn get_mut_displacement(&mut self, key: Entity) -> Option<&mut Vector3<f32>> {
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| &mut d.delta.disp)
    }

    fn get_mut_rotation(&mut self, key: Entity) -> Option<&mut Quaternion<f32>> {
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| &mut d.delta.rot)
    }

    fn get_transform(&self, key: Entity) -> Option<Decomposed<f32, Vector3<f32>, Quaternion<f32>>> {
        self.get_position()
            .delta.get(key)
            .map(|d| d.delta)
    }

    fn get_parent(&self, key: Entity) -> Option<&Option<Entity>> {
        self.get_position()
            .delta.get(key)
            .map(|d| &d.parent)
    }

    fn position(&self, key: Entity) -> Matrix4<f32> {
        self.get_position()
            .delta.get(key)
            .map(|d| {
                let matrix = d.delta.to_matrix4();
                match d.parent {
                    Some(p) => {
                        let parent = self.position(p);
                        parent.mul_m(&matrix)
                    }
                    None => {
                        matrix
                    }
                }
            })
            .unwrap_or_else(|| Matrix4::identity())
    }

    fn write_positions(&self, mm: &mut MatrixManager) {
        mm.size(self.get_position().delta.highest_entity() as uint);
        for (key, _) in self.get_position().delta.iter() {
            mm.set(key as uint, self.position(key));
        }
    }

    fn delta_iter(&self) -> DynamicIterator<Delta> {
        self.get_position().delta.iter()
    }

    fn position_iter(&self) -> PositionIter {
        let pos = self.get_position();
        PositionIter {
            pos: pos,
            iter: pos.delta.iter()
        }
    }

    fn position_max(&self) -> uint {
        self.get_position().delta.highest_entity() as uint + 1
    }
}

pub struct PositionIter<'a> {
    pos: &'a PositionData,
    iter: DynamicIterator<'a, Delta>
}

impl<'a> Iterator for PositionIter<'a> {
    type Item = (Entity, Matrix4<f32>);

    fn next(&mut self) -> Option<(Entity, Matrix4<f32>)> {
        self.iter.next().map(|(id, _)| (id, self.pos.position(id)) )
    }
}

impl Duplicate for PositionData {
    fn duplicate(&mut self, src: Entity, dst: Entity) {
        let delta = self.delta.get(src).map(|&x| x);
        delta.map(|delta| self.delta.insert(dst, delta));
    }
}

impl Delete for PositionData {
    fn delete(&mut self, key: Entity) -> bool {
        self.delta.remove(key)
    }
}

impl Positions for PositionData {
    fn get_position<'a>(&'a self) -> &'a PositionData { self }
    fn get_position_mut<'a>(&'a mut self) -> &'a mut PositionData { self }
}

impl<T: Positions> Positions for InputIntegratorGameData<T> {
    fn get_position<'a>(&'a self) -> &'a PositionData { self.inner.get_position() }
    fn get_position_mut<'a>(&'a mut self) -> &'a mut PositionData { self.inner.get_position_mut() }
}

pub mod cl {
    use cgmath::{Transform, Decomposed, Vector3, Vector4, Matrix4, Quaternion};

    use opencl::hl::{Device, Context, CommandQueue, Kernel, Event};
    use opencl::mem::CLBuffer;
    use opencl::cl::{CL_MEM_READ_ONLY};

    use super::Positions;

    const OPENCL_PROGRAM: &'static str = include_str!("position.c");

    #[derive(Copy)]
    pub struct Delta {
        delta: Decomposed<f32, Vector3<f32>, Quaternion<f32>>
    }

    impl Clone for Delta {
        fn clone(&self) -> Delta {
            Delta {
                delta: self.delta
            }
        }
    }

    pub struct Accelerator {
        kernel_vec4: Kernel,
        kernel_mat: Kernel,
        input: CLBuffer<Delta>,
        input_buf: Vec<Delta>,
        parent: CLBuffer<u32>,
        parent_buf: Vec<u32>
    }

    impl Accelerator {
        pub fn new(ctx: &Context, device: &Device) -> Accelerator {
            let program = ctx.create_program_from_source(OPENCL_PROGRAM);
            match program.build(device) {
                Ok(_) => (),
                Err(build_log) => {
                    println!("Error building program:");
                    println!("{}", build_log);
                    panic!("");
                }
            }

            let kernel_mat = program.create_kernel("calc_mat");
            let kernel_vec4 = program.create_kernel("calc_vec4");
            let delta_mem = ctx.create_buffer(1024*1024, CL_MEM_READ_ONLY);
            let delta_buf = Vec::from_elem(1024*1024, Delta {
                delta: Transform::identity()
            });
            let parent_mem = ctx.create_buffer(1024*1024, CL_MEM_READ_ONLY);
            let parent_buf = Vec::from_elem(1024*1024, 0u32);

            Accelerator {
                kernel_vec4: kernel_vec4,
                kernel_mat: kernel_mat,
                input: delta_mem,
                input_buf: delta_buf,
                parent: parent_mem,
                parent_buf: parent_buf
            }
        }

        fn write<P: Positions>(&mut self, pos: &P) -> uint {
            let mut top = 0;
            for i in range(0, pos.position_max()) {
                self.parent_buf[i] = !0;
            }
            for (idx, &p) in pos.delta_iter() {
                top = idx;
                self.parent_buf[idx as uint] = p.parent.unwrap_or(!0);
                self.input_buf[idx as uint] = Delta {
                    delta: p.delta
                };
            }
            top as uint
        }

        pub fn compute_mat<P: Positions>(&mut self,
                                      pos: &P,
                                      queue: &CommandQueue,
                                      buf: &CLBuffer<Matrix4<f32>>) -> Event {
            self.write(pos);
            let max = pos.position_max();
            let event = [queue.write_async(&self.input, &self.input_buf.slice(0, max), ()),
                         queue.write_async(&self.parent, &self.parent_buf.slice(0, max), ())];
            self.kernel_mat.set_arg(0, &self.input);
            self.kernel_mat.set_arg(1, &self.parent);
            self.kernel_mat.set_arg(2, buf);
            self.kernel_mat.set_arg(3, &(pos.position_max() as u32));
            queue.enqueue_async_kernel(&self.kernel_mat, pos.position_max(), None, event.as_slice())
        }

        pub fn compute_vec4x4<P: Positions>(&mut self,
                                        pos: &P,
                                        queue: &CommandQueue,
                                        buf: &[CLBuffer<Vector4<f32>>; 4]) -> Event {
            self.write(pos);
            let max = pos.position_max();
            let event = [queue.write_async(&self.input, &self.input_buf.slice(0, max), ()),
                         queue.write_async(&self.parent, &self.parent_buf.slice(0, max), ())];
            self.kernel_vec4.set_arg(0, &self.input);
            self.kernel_vec4.set_arg(1, &self.parent);
            self.kernel_vec4.set_arg(2, &buf[0]);
            self.kernel_vec4.set_arg(3, &buf[1]);
            self.kernel_vec4.set_arg(4, &buf[2]);
            self.kernel_vec4.set_arg(5, &buf[3]);
            self.kernel_vec4.set_arg(6, &(max as u32));
            queue.enqueue_async_kernel(&self.kernel_vec4, pos.position_max(), None, event.as_slice())
        }
    }
}

<commit_msg>Added OrderedMapIterator to position iter<commit_after>//   Copyright 2014 Colin Sherratt
//
//   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.

#![crate_name = "snowmew-position"]

#![crate_type = "lib"]
#![feature(macro_rules)]
#![feature(old_orphan_check)]
#![feature(associated_types)]

extern crate "snowmew-core" as snowmew;
extern crate cgmath;
extern crate opencl;
extern crate cow;
extern crate time;
extern crate collect;
extern crate "rustc-serialize" as rustc_serialize;

use std::default::Default;

use cgmath::{Transform, Decomposed, Vector3, Matrix4, ToMatrix4, Matrix, Quaternion};
use collect::iter::OrderedMapIterator;

use snowmew::common::{Entity, Duplicate, Delete};
use snowmew::input_integrator::InputIntegratorGameData;
use snowmew::table::{Dynamic, DynamicIterator};

pub trait MatrixManager {
    fn size(&mut self, size: uint);
    fn set(&mut self, idx: uint, mat: Matrix4<f32>);
    fn get(&self, idx: uint) -> Matrix4<f32>;
}

impl<'r> MatrixManager for Vec<Matrix4<f32>> {
    fn size(&mut self, size: uint) {
        if self.len() < size {
            let amount = self.len() - size;
            self.grow(amount, Matrix4::identity())
        }
    }
    fn set(&mut self, idx: uint, m: Matrix4<f32>) { self[idx] = m; }
    fn get(&self, idx: uint) -> Matrix4<f32> { self[idx] }
}

#[derive(RustcEncodable, RustcDecodable, Copy)]
pub struct Delta {
    pub parent: Option<Entity>,
    pub delta: Decomposed<f32, Vector3<f32>, Quaternion<f32>>
}

impl Clone for Delta {
    fn clone(&self) -> Delta {
        Delta {
            parent: self.parent,
            delta: self.delta
        }
    }
}

impl Default for Delta {
    fn default() -> Delta {
        Delta {
            parent: None,
            delta: Transform::identity()
        }
    }
}

#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct PositionData {
    delta: Dynamic<Delta>,
}

impl PositionData {
    pub fn new() -> PositionData {
        PositionData {
            delta: Dynamic::new()
        }
    }
}

pub trait Positions {
    fn get_position<'a>(&'a self) -> &'a PositionData;
    fn get_position_mut<'a>(&'a mut self) -> &'a mut PositionData;

    fn set_delta(&mut self,
                 key: Entity,
                 parent: Option<Entity>,
                 transform: Decomposed<f32, Vector3<f32>, Quaternion<f32>>) {
        self.get_position_mut().delta.insert(key,
            Delta {
                parent: parent,
                delta: transform
            }
        );
    }

    fn set_to_identity(&mut self, key: Entity) {
        self.set_delta(key, None, Transform::identity())
    }

    fn init_position(&mut self, key: Entity) {
        if self.get_position().delta.get(key).is_none() {
            self.set_to_identity(key);
        }
    }

    fn set_scale(&mut self, key: Entity, scale: f32) {
        self.init_position(key);
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| d.delta.scale = scale);
    }

    fn set_displacement(&mut self, key: Entity, disp: Vector3<f32>) {
        self.init_position(key);
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| d.delta.disp = disp);
    }

    fn set_rotation(&mut self, key: Entity, rot: Quaternion<f32>) {
        self.init_position(key);
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| d.delta.rot = rot);
    }

    fn get_scale(&mut self, key: Entity) -> Option<&f32> {
        self.get_position()
            .delta.get(key)
            .map(|d| &d.delta.scale)
    }

    fn get_displacement(&mut self, key: Entity) -> Option<&Vector3<f32>> {
        self.get_position()
            .delta.get(key)
            .map(|d| &d.delta.disp)
    }

    fn get_rotation(&mut self, key: Entity) -> Option<&Quaternion<f32>> {
        self.get_position()
            .delta.get(key)
            .map(|d| &d.delta.rot)
    }

    fn get_mut_scale(&mut self, key: Entity) -> Option<&mut f32> {
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| &mut d.delta.scale)
    }

    fn get_mut_displacement(&mut self, key: Entity) -> Option<&mut Vector3<f32>> {
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| &mut d.delta.disp)
    }

    fn get_mut_rotation(&mut self, key: Entity) -> Option<&mut Quaternion<f32>> {
        self.get_position_mut()
            .delta.get_mut(key)
            .map(|d| &mut d.delta.rot)
    }

    fn get_transform(&self, key: Entity) -> Option<Decomposed<f32, Vector3<f32>, Quaternion<f32>>> {
        self.get_position()
            .delta.get(key)
            .map(|d| d.delta)
    }

    fn get_parent(&self, key: Entity) -> Option<&Option<Entity>> {
        self.get_position()
            .delta.get(key)
            .map(|d| &d.parent)
    }

    fn position(&self, key: Entity) -> Matrix4<f32> {
        self.get_position()
            .delta.get(key)
            .map(|d| {
                let matrix = d.delta.to_matrix4();
                match d.parent {
                    Some(p) => {
                        let parent = self.position(p);
                        parent.mul_m(&matrix)
                    }
                    None => {
                        matrix
                    }
                }
            })
            .unwrap_or_else(|| Matrix4::identity())
    }

    fn write_positions(&self, mm: &mut MatrixManager) {
        mm.size(self.get_position().delta.highest_entity() as uint);
        for (key, _) in self.get_position().delta.iter() {
            mm.set(key as uint, self.position(key));
        }
    }

    fn delta_iter(&self) -> DynamicIterator<Delta> {
        self.get_position().delta.iter()
    }

    fn position_iter(&self) -> PositionIter {
        let pos = self.get_position();
        PositionIter {
            pos: pos,
            iter: pos.delta.iter()
        }
    }

    fn position_max(&self) -> uint {
        self.get_position().delta.highest_entity() as uint + 1
    }
}

pub struct PositionIter<'a> {
    pos: &'a PositionData,
    iter: DynamicIterator<'a, Delta>
}

impl<'a> Iterator for PositionIter<'a> {
    type Item = (Entity, Matrix4<f32>);

    fn next(&mut self) -> Option<(Entity, Matrix4<f32>)> {
        self.iter.next().map(|(id, _)| (id, self.pos.position(id)) )
    }
}

impl<'a> OrderedMapIterator<Entity, Matrix4<f32>> for PositionIter<'a> {}

impl Duplicate for PositionData {
    fn duplicate(&mut self, src: Entity, dst: Entity) {
        let delta = self.delta.get(src).map(|&x| x);
        delta.map(|delta| self.delta.insert(dst, delta));
    }
}

impl Delete for PositionData {
    fn delete(&mut self, key: Entity) -> bool {
        self.delta.remove(key)
    }
}

impl Positions for PositionData {
    fn get_position<'a>(&'a self) -> &'a PositionData { self }
    fn get_position_mut<'a>(&'a mut self) -> &'a mut PositionData { self }
}

impl<T: Positions> Positions for InputIntegratorGameData<T> {
    fn get_position<'a>(&'a self) -> &'a PositionData { self.inner.get_position() }
    fn get_position_mut<'a>(&'a mut self) -> &'a mut PositionData { self.inner.get_position_mut() }
}

pub mod cl {
    use cgmath::{Transform, Decomposed, Vector3, Vector4, Matrix4, Quaternion};

    use opencl::hl::{Device, Context, CommandQueue, Kernel, Event};
    use opencl::mem::CLBuffer;
    use opencl::cl::{CL_MEM_READ_ONLY};

    use super::Positions;

    const OPENCL_PROGRAM: &'static str = include_str!("position.c");

    #[derive(Copy)]
    pub struct Delta {
        delta: Decomposed<f32, Vector3<f32>, Quaternion<f32>>
    }

    impl Clone for Delta {
        fn clone(&self) -> Delta {
            Delta {
                delta: self.delta
            }
        }
    }

    pub struct Accelerator {
        kernel_vec4: Kernel,
        kernel_mat: Kernel,
        input: CLBuffer<Delta>,
        input_buf: Vec<Delta>,
        parent: CLBuffer<u32>,
        parent_buf: Vec<u32>
    }

    impl Accelerator {
        pub fn new(ctx: &Context, device: &Device) -> Accelerator {
            let program = ctx.create_program_from_source(OPENCL_PROGRAM);
            match program.build(device) {
                Ok(_) => (),
                Err(build_log) => {
                    println!("Error building program:");
                    println!("{}", build_log);
                    panic!("");
                }
            }

            let kernel_mat = program.create_kernel("calc_mat");
            let kernel_vec4 = program.create_kernel("calc_vec4");
            let delta_mem = ctx.create_buffer(1024*1024, CL_MEM_READ_ONLY);
            let delta_buf = Vec::from_elem(1024*1024, Delta {
                delta: Transform::identity()
            });
            let parent_mem = ctx.create_buffer(1024*1024, CL_MEM_READ_ONLY);
            let parent_buf = Vec::from_elem(1024*1024, 0u32);

            Accelerator {
                kernel_vec4: kernel_vec4,
                kernel_mat: kernel_mat,
                input: delta_mem,
                input_buf: delta_buf,
                parent: parent_mem,
                parent_buf: parent_buf
            }
        }

        fn write<P: Positions>(&mut self, pos: &P) -> uint {
            let mut top = 0;
            for i in range(0, pos.position_max()) {
                self.parent_buf[i] = !0;
            }
            for (idx, &p) in pos.delta_iter() {
                top = idx;
                self.parent_buf[idx as uint] = p.parent.unwrap_or(!0);
                self.input_buf[idx as uint] = Delta {
                    delta: p.delta
                };
            }
            top as uint
        }

        pub fn compute_mat<P: Positions>(&mut self,
                                      pos: &P,
                                      queue: &CommandQueue,
                                      buf: &CLBuffer<Matrix4<f32>>) -> Event {
            self.write(pos);
            let max = pos.position_max();
            let event = [queue.write_async(&self.input, &self.input_buf.slice(0, max), ()),
                         queue.write_async(&self.parent, &self.parent_buf.slice(0, max), ())];
            self.kernel_mat.set_arg(0, &self.input);
            self.kernel_mat.set_arg(1, &self.parent);
            self.kernel_mat.set_arg(2, buf);
            self.kernel_mat.set_arg(3, &(pos.position_max() as u32));
            queue.enqueue_async_kernel(&self.kernel_mat, pos.position_max(), None, event.as_slice())
        }

        pub fn compute_vec4x4<P: Positions>(&mut self,
                                        pos: &P,
                                        queue: &CommandQueue,
                                        buf: &[CLBuffer<Vector4<f32>>; 4]) -> Event {
            self.write(pos);
            let max = pos.position_max();
            let event = [queue.write_async(&self.input, &self.input_buf.slice(0, max), ()),
                         queue.write_async(&self.parent, &self.parent_buf.slice(0, max), ())];
            self.kernel_vec4.set_arg(0, &self.input);
            self.kernel_vec4.set_arg(1, &self.parent);
            self.kernel_vec4.set_arg(2, &buf[0]);
            self.kernel_vec4.set_arg(3, &buf[1]);
            self.kernel_vec4.set_arg(4, &buf[2]);
            self.kernel_vec4.set_arg(5, &buf[3]);
            self.kernel_vec4.set_arg(6, &(max as u32));
            queue.enqueue_async_kernel(&self.kernel_vec4, pos.position_max(), None, event.as_slice())
        }
    }
}

<|endoftext|>


<commit_before>//! Implements static board evaluation.

use std::hash::{Hasher, SipHasher};
use basetypes::*;
use position::bitsets::*;
use position::move_generation::Board;

/// Statically evaluates the board.
///
/// This method considers only static material and positional
/// properties of the position. If the position is dynamic, with
/// pending tactical threats, this function will return a grossly
/// incorrect evaluation. Therefore, it should be relied upon only
/// for reasonably "quiet" positions.
///
/// The returned value will always be between `STATIC_EVAL_MIN` and
/// `STATIC_EVAL_MAX`.
#[inline]
pub fn evaluate_board(board: &Board) -> Value {
    // TODO: Implement a real evaluation.

    const PIECE_VALUES: [Value; 8] = [10000, 975, 500, 325, 325, 100, 0, 0];

    if board.checkers() != 0 {
        // In positions under check we can be vastly incorrect with no
        // negative consequences.
        return 0;
    }

    let piece_type = board.pieces().piece_type;
    let color = board.pieces().color;
    let us = board.to_move();
    let them = 1 ^ us;
    let mut result = 0;
    for piece in QUEEN..NO_PIECE {
        result += PIECE_VALUES[piece] *
                  (pop_count(piece_type[piece] & color[us]) as i16 -
                   pop_count(piece_type[piece] & color[them]) as i16);
    }
    let mut hasher = SipHasher::new();
    hasher.write_u64(board.occupied());
    result + (hasher.finish() >> 61) as i16
}

// use rand;
// use rand::distributions::{Sample, Range};
// let mut rng = rand::thread_rng();
// let mut between = Range::new(0, 10);
// let x = between.sample(&mut rng);
<commit_msg>more randomness in eval again<commit_after>//! Implements static board evaluation.

use std::hash::{Hasher, SipHasher};
use basetypes::*;
use position::bitsets::*;
use position::move_generation::Board;

/// Statically evaluates the board.
///
/// This method considers only static material and positional
/// properties of the position. If the position is dynamic, with
/// pending tactical threats, this function will return a grossly
/// incorrect evaluation. Therefore, it should be relied upon only
/// for reasonably "quiet" positions.
///
/// The returned value will always be between `STATIC_EVAL_MIN` and
/// `STATIC_EVAL_MAX`.
#[inline]
pub fn evaluate_board(board: &Board) -> Value {
    // TODO: Implement a real evaluation.

    const PIECE_VALUES: [Value; 8] = [10000, 975, 500, 325, 325, 100, 0, 0];

    if board.checkers() != 0 {
        // In positions under check we can be vastly incorrect with no
        // negative consequences.
        return 0;
    }

    let piece_type = board.pieces().piece_type;
    let color = board.pieces().color;
    let us = board.to_move();
    let them = 1 ^ us;
    let mut result = 0;
    for piece in QUEEN..NO_PIECE {
        result += PIECE_VALUES[piece] *
                  (pop_count(piece_type[piece] & color[us]) as i16 -
                   pop_count(piece_type[piece] & color[them]) as i16);
    }
    let mut hasher = SipHasher::new();
    hasher.write_u64(board.occupied());
    result + (hasher.finish() >> 59) as i16
}

// use rand;
// use rand::distributions::{Sample, Range};
// let mut rng = rand::thread_rng();
// let mut between = Range::new(0, 10);
// let x = between.sample(&mut rng);
<|endoftext|>


<commit_before>use super::utils::types::Sha256Digest;
use super::rlp::{ RlpStream, Encodable };

pub struct CrosslinkRecord {
    pub epoch: u64,
    pub hash: Sha256Digest
}

impl CrosslinkRecord {
    pub fn new(epoch: u64, hash: Sha256Digest) -> CrosslinkRecord {
        CrosslinkRecord {
            epoch: epoch,
            hash: hash
        }
    }
}

/*
 * RLP Encoding
 */
impl Encodable for CrosslinkRecord {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.append(&self.epoch);
        s.append(&self.hash);
    }
}

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

    #[test]
    fn test_new() {
        let epoch = 1;
        let hash = Sha256Digest::random();
        let c = CrosslinkRecord::new(epoch, hash);
        assert_eq!(c.epoch, epoch);
        assert_eq!(c.hash, hash);
    }

    #[test]
    fn test_rlp_serialization() {
        let c = CrosslinkRecord {
            epoch: 100,
            hash: Sha256Digest::zero()
        };
        let e = rlp::encode(&c);
        assert_eq!(e.len(), 34);
        assert_eq!(e[0], 100);
        assert_eq!(e[1], 160);
        assert_eq!(e[2..34], [0; 32]);
    }
}
<commit_msg>Implement Clone for CrosslinkRecord<commit_after>use super::utils::types::Sha256Digest;
use super::rlp::{ RlpStream, Encodable };

#[derive(Copy)]
pub struct CrosslinkRecord {
    pub epoch: u64,
    pub hash: Sha256Digest
}

impl CrosslinkRecord {
    pub fn new(epoch: u64, hash: Sha256Digest) -> CrosslinkRecord {
        CrosslinkRecord {
            epoch: epoch,
            hash: hash
        }
    }
}

impl Clone for CrosslinkRecord {
    fn clone(&self) -> CrosslinkRecord { *self }
}

/*
 * RLP Encoding
 */
impl Encodable for CrosslinkRecord {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.append(&self.epoch);
        s.append(&self.hash);
    }
}

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

    #[test]
    fn test_new() {
        let epoch = 1;
        let hash = Sha256Digest::random();
        let c = CrosslinkRecord::new(epoch, hash);
        assert_eq!(c.epoch, epoch);
        assert_eq!(c.hash, hash);
    }

    #[test]
    fn test_rlp_serialization() {
        let c = CrosslinkRecord {
            epoch: 100,
            hash: Sha256Digest::zero()
        };
        let e = rlp::encode(&c);
        assert_eq!(e.len(), 34);
        assert_eq!(e[0], 100);
        assert_eq!(e[1], 160);
        assert_eq!(e[2..34], [0; 32]);
    }
}
<|endoftext|>


<commit_before>// -*- rust -*-
// xfail-test
// error-pattern:Unsatisfied precondition

pure fn less_than(x: int, y: int) -> bool { return x < y; }

type ordered_range = {low: int, high: int} : less_than(*.low, *.high);

fn main() {
    // Should fail to compile, b/c we're not doing the check
    // explicitly that a < b
    let a: int = 1;
    let b: int = 2;
    let c: ordered_range = {low: a, high: b};
    log(debug, c.low);
}
<commit_msg>Remove typestate test<commit_after><|endoftext|>


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

use super::Test;
use crate::{CoreContext, Result};
use diem_sdk::{
    client::{BlockingClient, FaucetClient},
    move_types::account_address::AccountAddress,
    transaction_builder::{Currency, TransactionFactory},
    types::{chain_id::ChainId, transaction::authenticator::AuthenticationKey, LocalAccount},
};

/// The testing interface which defines a test written from the perspective of the a public user of
/// the network in a "testnet" like environment where there exists a funding source and a means of
/// creating new accounts.
pub trait PublicUsageTest: Test {
    /// Executes the test against the given context.
    fn run<'t>(&self, ctx: &mut PublicUsageContext<'t>) -> Result<()>;
}

pub struct PublicUsageContext<'t> {
    core: CoreContext,

    public_info: PublicInfo<'t>,
}

impl<'t> PublicUsageContext<'t> {
    pub fn new(core: CoreContext, public_info: PublicInfo<'t>) -> Self {
        Self { core, public_info }
    }

    pub fn client(&self) -> BlockingClient {
        BlockingClient::new(&self.public_info.json_rpc_url)
    }

    pub fn core(&self) -> &CoreContext {
        &self.core
    }

    pub fn random_account(&mut self) -> LocalAccount {
        LocalAccount::generate(self.core.rng())
    }

    pub fn chain_id(&self) -> ChainId {
        self.public_info.chain_id
    }

    pub fn transaction_factory(&self) -> TransactionFactory {
        TransactionFactory::new(self.chain_id())
    }

    pub fn fund(&mut self, address: AccountAddress, amount: u64) -> Result<()> {
        self.public_info.coffer.fund(Currency::XUS, address, amount)
    }

    pub fn create_parent_vasp_account(&mut self, auth_key: AuthenticationKey) -> Result<()> {
        self.public_info
            .coffer
            .create_parent_vasp_account(Currency::XUS, auth_key)
    }

    pub fn create_designated_dealer_account(&mut self, auth_key: AuthenticationKey) -> Result<()> {
        self.public_info
            .coffer
            .create_designated_dealer_account(Currency::XUS, auth_key)
    }

    pub fn transfer_coins(
        &mut self,
        currency: Currency,
        sender: &mut LocalAccount,
        payee: AccountAddress,
        amount: u64,
    ) -> Result<()> {
        let client = self.client();
        let tx = sender.sign_with_transaction_builder(
            self.transaction_factory()
                .peer_to_peer(currency, payee, amount),
        );
        client.submit(&tx)?;
        client.wait_for_signed_transaction(&tx, None, None)?;

        Ok(())
    }
}

pub enum Coffer<'t> {
    TreasuryCompliance {
        transaction_factory: TransactionFactory,
        json_rpc_client: BlockingClient,
        treasury_compliance_account: &'t mut LocalAccount,
        designated_dealer_account: &'t mut LocalAccount,
    },
    Faucet(FaucetClient),
}

pub trait Fund {
    fn fund(&mut self, currency: Currency, address: AccountAddress, amount: u64) -> Result<()>;
    fn create_parent_vasp_account(
        &mut self,
        currency: Currency,
        auth_key: AuthenticationKey,
    ) -> Result<()>;
    fn create_designated_dealer_account(
        &mut self,
        currency: Currency,
        auth_key: AuthenticationKey,
    ) -> Result<()>;
}

impl Fund for Coffer<'_> {
    fn fund(&mut self, currency: Currency, address: AccountAddress, amount: u64) -> Result<()> {
        match self {
            Coffer::Faucet(_) => todo!(),
            Coffer::TreasuryCompliance {
                transaction_factory,
                json_rpc_client,
                treasury_compliance_account: _,
                designated_dealer_account,
            } => {
                let fund_account_txn = designated_dealer_account.sign_with_transaction_builder(
                    transaction_factory.peer_to_peer(currency, address, amount),
                );
                json_rpc_client.submit(&fund_account_txn)?;
                json_rpc_client.wait_for_signed_transaction(&fund_account_txn, None, None)?;
                Ok(())
            }
        }
    }

    fn create_parent_vasp_account(
        &mut self,
        currency: Currency,
        auth_key: AuthenticationKey,
    ) -> Result<()> {
        match self {
            Coffer::Faucet(_) => todo!(),
            Coffer::TreasuryCompliance {
                transaction_factory,
                json_rpc_client,
                treasury_compliance_account,
                ..
            } => {
                let create_account_txn = treasury_compliance_account.sign_with_transaction_builder(
                    transaction_factory.create_parent_vasp_account(
                        currency,
                        0,
                        auth_key,
                        &format!("No. {} VASP", treasury_compliance_account.sequence_number()),
                        false,
                    ),
                );
                json_rpc_client.submit(&create_account_txn)?;
                json_rpc_client.wait_for_signed_transaction(&create_account_txn, None, None)?;
                Ok(())
            }
        }
    }

    fn create_designated_dealer_account(
        &mut self,
        currency: Currency,
        auth_key: AuthenticationKey,
    ) -> Result<()> {
        match self {
            Coffer::Faucet(_) => todo!(),
            Coffer::TreasuryCompliance {
                transaction_factory,
                json_rpc_client,
                treasury_compliance_account,
                ..
            } => {
                let create_account_txn = treasury_compliance_account.sign_with_transaction_builder(
                    transaction_factory.create_designated_dealer(
                        currency,
                        0, // sliding_nonce
                        auth_key,
                        &format!("No. {} DD", treasury_compliance_account.sequence_number()),
                        false, // add all currencies
                    ),
                );
                json_rpc_client.submit(&create_account_txn)?;
                json_rpc_client.wait_for_signed_transaction(&create_account_txn, None, None)?;
                Ok(())
            }
        }
    }
}

pub struct PublicInfo<'t> {
    json_rpc_url: String,
    chain_id: ChainId,
    coffer: Coffer<'t>,
}

impl<'t> PublicInfo<'t> {
    pub fn new(json_rpc_url: String, chain_id: ChainId, coffer: Coffer<'t>) -> Self {
        Self {
            json_rpc_url,
            chain_id,
            coffer,
        }
    }
}
<commit_msg>forge: add more helper methods to PublicUsageContext<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use super::Test;
use crate::{CoreContext, Result};
use diem_sdk::{
    client::{BlockingClient, FaucetClient},
    move_types::account_address::AccountAddress,
    transaction_builder::{Currency, TransactionFactory},
    types::{chain_id::ChainId, transaction::authenticator::AuthenticationKey, LocalAccount},
};

/// The testing interface which defines a test written from the perspective of the a public user of
/// the network in a "testnet" like environment where there exists a funding source and a means of
/// creating new accounts.
pub trait PublicUsageTest: Test {
    /// Executes the test against the given context.
    fn run<'t>(&self, ctx: &mut PublicUsageContext<'t>) -> Result<()>;
}

pub struct PublicUsageContext<'t> {
    core: CoreContext,

    public_info: PublicInfo<'t>,
}

impl<'t> PublicUsageContext<'t> {
    pub fn new(core: CoreContext, public_info: PublicInfo<'t>) -> Self {
        Self { core, public_info }
    }

    pub fn client(&self) -> BlockingClient {
        BlockingClient::new(&self.public_info.json_rpc_url)
    }

    pub fn url(&self) -> &str {
        &self.public_info.json_rpc_url
    }

    pub fn core(&self) -> &CoreContext {
        &self.core
    }

    pub fn rng(&mut self) -> &mut ::rand::rngs::StdRng {
        self.core.rng()
    }

    pub fn random_account(&mut self) -> LocalAccount {
        LocalAccount::generate(self.core.rng())
    }

    pub fn chain_id(&self) -> ChainId {
        self.public_info.chain_id
    }

    pub fn transaction_factory(&self) -> TransactionFactory {
        TransactionFactory::new(self.chain_id())
    }

    pub fn fund(&mut self, address: AccountAddress, amount: u64) -> Result<()> {
        self.public_info.coffer.fund(Currency::XUS, address, amount)
    }

    pub fn create_parent_vasp_account(&mut self, auth_key: AuthenticationKey) -> Result<()> {
        self.public_info
            .coffer
            .create_parent_vasp_account(Currency::XUS, auth_key)
    }

    pub fn create_designated_dealer_account(&mut self, auth_key: AuthenticationKey) -> Result<()> {
        self.public_info
            .coffer
            .create_designated_dealer_account(Currency::XUS, auth_key)
    }

    pub fn transfer_coins(
        &mut self,
        currency: Currency,
        sender: &mut LocalAccount,
        payee: AccountAddress,
        amount: u64,
    ) -> Result<()> {
        let client = self.client();
        let tx = sender.sign_with_transaction_builder(
            self.transaction_factory()
                .peer_to_peer(currency, payee, amount),
        );
        client.submit(&tx)?;
        client.wait_for_signed_transaction(&tx, None, None)?;

        Ok(())
    }
}

pub enum Coffer<'t> {
    TreasuryCompliance {
        transaction_factory: TransactionFactory,
        json_rpc_client: BlockingClient,
        treasury_compliance_account: &'t mut LocalAccount,
        designated_dealer_account: &'t mut LocalAccount,
    },
    Faucet(FaucetClient),
}

pub trait Fund {
    fn fund(&mut self, currency: Currency, address: AccountAddress, amount: u64) -> Result<()>;
    fn create_parent_vasp_account(
        &mut self,
        currency: Currency,
        auth_key: AuthenticationKey,
    ) -> Result<()>;
    fn create_designated_dealer_account(
        &mut self,
        currency: Currency,
        auth_key: AuthenticationKey,
    ) -> Result<()>;
}

impl Fund for Coffer<'_> {
    fn fund(&mut self, currency: Currency, address: AccountAddress, amount: u64) -> Result<()> {
        match self {
            Coffer::Faucet(_) => todo!(),
            Coffer::TreasuryCompliance {
                transaction_factory,
                json_rpc_client,
                treasury_compliance_account: _,
                designated_dealer_account,
            } => {
                let fund_account_txn = designated_dealer_account.sign_with_transaction_builder(
                    transaction_factory.peer_to_peer(currency, address, amount),
                );
                json_rpc_client.submit(&fund_account_txn)?;
                json_rpc_client.wait_for_signed_transaction(&fund_account_txn, None, None)?;
                Ok(())
            }
        }
    }

    fn create_parent_vasp_account(
        &mut self,
        currency: Currency,
        auth_key: AuthenticationKey,
    ) -> Result<()> {
        match self {
            Coffer::Faucet(_) => todo!(),
            Coffer::TreasuryCompliance {
                transaction_factory,
                json_rpc_client,
                treasury_compliance_account,
                ..
            } => {
                let create_account_txn = treasury_compliance_account.sign_with_transaction_builder(
                    transaction_factory.create_parent_vasp_account(
                        currency,
                        0,
                        auth_key,
                        &format!("No. {} VASP", treasury_compliance_account.sequence_number()),
                        false,
                    ),
                );
                json_rpc_client.submit(&create_account_txn)?;
                json_rpc_client.wait_for_signed_transaction(&create_account_txn, None, None)?;
                Ok(())
            }
        }
    }

    fn create_designated_dealer_account(
        &mut self,
        currency: Currency,
        auth_key: AuthenticationKey,
    ) -> Result<()> {
        match self {
            Coffer::Faucet(_) => todo!(),
            Coffer::TreasuryCompliance {
                transaction_factory,
                json_rpc_client,
                treasury_compliance_account,
                ..
            } => {
                let create_account_txn = treasury_compliance_account.sign_with_transaction_builder(
                    transaction_factory.create_designated_dealer(
                        currency,
                        0, // sliding_nonce
                        auth_key,
                        &format!("No. {} DD", treasury_compliance_account.sequence_number()),
                        false, // add all currencies
                    ),
                );
                json_rpc_client.submit(&create_account_txn)?;
                json_rpc_client.wait_for_signed_transaction(&create_account_txn, None, None)?;
                Ok(())
            }
        }
    }
}

pub struct PublicInfo<'t> {
    json_rpc_url: String,
    chain_id: ChainId,
    coffer: Coffer<'t>,
}

impl<'t> PublicInfo<'t> {
    pub fn new(json_rpc_url: String, chain_id: ChainId, coffer: Coffer<'t>) -> Self {
        Self {
            json_rpc_url,
            chain_id,
            coffer,
        }
    }
}
<|endoftext|>


<commit_before>#[doc = "

Builds display lists on request and passes them to the renderer

"];

import task::*;
import comm::*;
import display_list::*;
import gfx::geom;
import gfx::geom::*;
import gfx::renderer;

enum msg {
    build,
    exit
}

fn layout(renderer: chan<renderer::msg>) -> chan<msg> {

    spawn_listener::<msg> {|po|
        let mut x1 = 100;
        let mut y1 = 100;
        let mut w1 = 200;
        let mut h1 = 200;
        let mut x2 = 200;
        let mut y2 = 200;
        let mut w2 = 300;
        let mut h2 = 300;

        loop {
            alt recv(po) {
              build {
                let dlist = [
                    display_item({
                        item_type: solid_color,
                        bounds: geom::box(
                            int_to_au(x1),
                            int_to_au(y1),
                            int_to_au(w1),
                            int_to_au(h1))
                    }),
                    display_item({
                        item_type: solid_color,
                        bounds: geom::box(
                            int_to_au(x2),
                            int_to_au(y2),
                            int_to_au(w2),
                            int_to_au(h2))
                    })
                ];

                send(renderer, gfx::renderer::draw(dlist));

                x1 += 1;
                y1 += 1;
                x2 -= 1;
                y2 -= 1;
                if x1 > 800 { x1 = 0 }
                if y1 > 600 { y1 = 0 }
                if x2 < 0 { x2 = 800 }
                if y2 < 0 { y2 = 600 }
              }
              exit {
                break;
              }
            }
        }
    }

}
<commit_msg>Structure layout task a little more<commit_after>#[doc = "

Builds display lists on request and passes them to the renderer

"];

import task::*;
import comm::*;
import gfx::geom;
import gfx::geom::*;
import gfx::renderer;
import dom::base::*;
import display_list::*;

enum msg {
    build,
    exit
}

fn layout(renderer: chan<renderer::msg>) -> chan<msg> {

    spawn_listener::<msg> {|po|

        let dom = new_node(nk_div);

        loop {
            alt recv(po) {
              build {

                let box = layout_dom(dom);
                let dlist = build_display_list(box);

                send(renderer, gfx::renderer::draw(dlist));
              }
              exit {
                break;
              }
            }
        }
    }

}

fn layout_dom(dom: node) -> base::box {
    base::new_box(dom)
}

fn build_display_list(_box: base::box) -> display_list::display_list {
    [
        display_item({
            item_type: solid_color,
            bounds: geom::box(
                int_to_au(0),
                int_to_au(0),
                int_to_au(100),
                int_to_au(100))
        }),
        display_item({
            item_type: solid_color,
            bounds: geom::box(
                int_to_au(100),
                int_to_au(100),
                int_to_au(100),
                int_to_au(100))
        })
    ]
}<|endoftext|>


<commit_before>use geom::point::Point2D;
use geom::size::Size2D;
use gfx::geometry::{au, px_to_au};
use libc::{c_void};
use font_library::FontLibrary;
use font::Font;
use glyph::Glyph;
use shaper::shape_text;

#[doc="A single, unbroken line of text."]
struct TextRun {
    priv glyphs: ~[Glyph],
    priv size_: Size2D<au>,
}

impl TextRun {
    fn size() -> Size2D<au> { self.size_ }
}

fn TextRun(font: Font, text: ~str) -> TextRun {
    let glyphs = shape_text(&font, text);
    let size = glyph_run_size(glyphs);

    TextRun {
        size_: size,
        glyphs: shape_text(&font, text)
    }
}

fn glyph_run_size(glyphs: &[Glyph]) -> Size2D<au> {
    let height = px_to_au(20);
    let pen_start_x = px_to_au(0);
    let pen_start_y = height;
    let pen_start = Point2D(pen_start_x, pen_start_y);
    let pen_end = glyphs.foldl(pen_start, |cur, glyph| {
        Point2D(cur.x.add(glyph.pos.offset.x).add(glyph.pos.advance.x),
                cur.y.add(glyph.pos.offset.y).add(glyph.pos.advance.y))
    });
    return Size2D(pen_end.x, pen_end.y);
}

fn should_calculate_the_total_size() {
    #[test];
    #[ignore(cfg(target_os = "macos"))];

    let flib = FontLibrary();
    let font = flib.get_test_font();
    let run = TextRun(*font, ~"firecracker");
    let expected = Size2D(px_to_au(84), px_to_au(20));
    assert run.size() == expected;
}
<commit_msg>Add TextRun.preferred_width<commit_after>use geom::point::Point2D;
use geom::size::Size2D;
use gfx::geometry::{au, px_to_au};
use libc::{c_void};
use font_library::FontLibrary;
use font::Font;
use glyph::Glyph;
use shaper::shape_text;

#[doc="A single, unbroken line of text."]
struct TextRun {
    priv glyphs: ~[Glyph],
    priv size_: Size2D<au>,
}

impl TextRun {
    fn size() -> Size2D<au> { self.size_ }
    fn preferred_width() -> au { self.size_.width }
}

fn TextRun(font: Font, text: ~str) -> TextRun {
    let glyphs = shape_text(&font, text);
    let size = glyph_run_size(glyphs);

    TextRun {
        size_: size,
        glyphs: shape_text(&font, text)
    }
}

fn glyph_run_size(glyphs: &[Glyph]) -> Size2D<au> {
    let height = px_to_au(20);
    let pen_start_x = px_to_au(0);
    let pen_start_y = height;
    let pen_start = Point2D(pen_start_x, pen_start_y);
    let pen_end = glyphs.foldl(pen_start, |cur, glyph| {
        Point2D(cur.x.add(glyph.pos.offset.x).add(glyph.pos.advance.x),
                cur.y.add(glyph.pos.offset.y).add(glyph.pos.advance.y))
    });
    return Size2D(pen_end.x, pen_end.y);
}

fn should_calculate_the_total_size() {
    #[test];
    #[ignore(cfg(target_os = "macos"))];

    let flib = FontLibrary();
    let font = flib.get_test_font();
    let run = TextRun(*font, ~"firecracker");
    let expected = Size2D(px_to_au(84), px_to_au(20));
    assert run.size() == expected;
}
<|endoftext|>


<commit_before>

extern crate "snowmew-core" as core;
extern crate "snowmew-position" as position;
extern crate "snowmew-graphics" as graphics;
extern crate "snowmew-render" as render;
extern crate wire;
extern crate bchannel;
extern crate bincode;
extern crate "rustc-serialize" as rustc_serialize;

use core::common::{Common, CommonData};
use position::{Positions, PositionData};
use graphics::{Graphics, GraphicsData};
use render::{Renderable, RenderData};

use std::sync::mpsc;
use std::thread::Thread;
use std::ops::{Deref, DerefMut};
use std::io::net::tcp::{
    TcpStream,
    TcpListener,
    TcpAcceptor
};
use std::io::{
    IoError,
};
use wire::SizeLimit;
use wire::tcp::OutTcpStream;
use rustc_serialize::{Decodable, Encodable};

use core::game::Game;

#[derive(RustcEncodable, RustcDecodable)]
pub enum ServerMessage<T, E> {
    Image(T),
    Event(E),
    Sync
}

#[derive(RustcEncodable, RustcDecodable)]
pub enum ClientMessage<E> {
    Event(E)
}

pub struct Server<Game, GameData> {
    game: Game,
    data: GameData
}

unsafe impl<T:Send, E:Send> Send for ServerClient<T, E> {}

struct ServerClient<T, E> {
    to_client: OutTcpStream<ServerMessage<T, E>>,
    from_client: bchannel::Receiver<ClientMessage<E>, bincode::DecodingError>
}

impl<G, GD:Clone+Send+Decodable+Encodable> Server<G, GD> {
    pub fn new(game: G, data: GD) -> Server<G, GD> {
        Server {
            game: game,
            data: data
        }
    }

    pub fn serve<E:Send+Encodable+Clone+Decodable>(mut self, iface: &str, port: u16)
        where G: Game<GD, E> {

        let (listener, _) = wire::listen_tcp(iface, port).unwrap();

        let (tx, rx): (mpsc::Sender<ServerClient<GD, E>>,
                       mpsc::Receiver<ServerClient<GD, E>>) = mpsc::channel();
        Thread::spawn(move || {
            let (read_limit, write_limit) = (SizeLimit::Infinite, SizeLimit::Infinite);

            for connection in listener.into_blocking_iter() {
                let (i, mut o) = wire::upgrade_tcp(connection, read_limit, write_limit);

                let client = ServerClient {
                    to_client: o,
                    from_client: i
                };

                tx.send(client);
            }
        });

        let mut clients = Vec::new();

        loop {
            // add clients to game
            while clients.len() == 0 {
                let mut res = rx.recv().ok().expect("failed to get message");
                res.to_client.send(&ServerMessage::Image(self.data.clone()));
                clients.push(res);
            }

            while let Ok(mut res) = rx.try_recv() {
                res.to_client.send(&ServerMessage::Image(self.data.clone()));
                clients.push(res)
            }

            let mut events = Vec::new();

            for c in clients.iter() {
                events.push(c.from_client.recv_block().expect("client sucks man"));
            }

            for ClientMessage::Event(e) in events.drain() {
                for c in clients.iter_mut() {
                    c.to_client.send(&ServerMessage::Event(e.clone()));
                }
                self.data = self.game.step(e, self.data)
            }
            for c in clients.iter_mut() {
                c.to_client.send(&ServerMessage::Sync);
            }

        }
    }
}

#[derive(Clone)]
pub struct ClientState<T, E> {
    sync: bool,
    predict_frame: u32,
    predict: T,
    predict_delta: Vec<(u32, E)>,
    server_frame: u32,
    server: T
}

impl<T, E> Deref for ClientState<T, E> {
    type Target = T;

    fn deref<'a>(&'a self) -> &'a T {
        &self.predict
    }
}

impl<T, E> DerefMut for ClientState<T, E> {
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        &mut self.predict
    }
}

impl<E, T: Common> Common for ClientState<T, E> {
    fn get_common<'a>(&'a self) -> &'a CommonData { self.predict.get_common() }
    fn get_common_mut<'a>(&'a mut self) -> &'a mut CommonData { self.predict.get_common_mut() }
}

impl<E, T: Positions> Positions for ClientState<T, E> {
    fn get_position<'a>(&'a self) -> &'a PositionData { self.predict.get_position() }
    fn get_position_mut<'a>(&'a mut self) -> &'a mut PositionData { self.predict.get_position_mut() }
}

impl<E, T: Graphics> Graphics for ClientState<T, E> {
    fn get_graphics<'a>(&'a self) -> &'a GraphicsData { self.predict.get_graphics() }
    fn get_graphics_mut<'a>(&'a mut self) -> &'a mut GraphicsData { self.predict.get_graphics_mut() }
}

impl<E, T: Renderable+Common+Positions+Graphics> Renderable for ClientState<T, E> {
    fn get_render_data<'a>(&'a self) -> &'a RenderData { self.predict.get_render_data() }
    fn get_render_data_mut<'a>(&'a mut self) -> &'a mut RenderData { self.predict.get_render_data_mut() }
}

pub struct Client<G, T, E> {
    game: G,
    to_server: OutTcpStream<ClientMessage<E>>,
    from_server: bchannel::Receiver<ServerMessage<T, E>, bincode::DecodingError>
}

impl<G, T:Send+Encodable+Decodable+Clone, E:Send+Encodable+Decodable> Client<G, T, E> {
    pub fn new(game: G, server: &str, port: u16) -> Client<G, T, E> {
        let (o, i) = wire::connect_tcp(server, port, SizeLimit::Infinite, SizeLimit::Infinite).unwrap();

        Client {
            game: game,
            to_server: i,
            from_server: o
        }
    }

    pub fn gamedata(&mut self) -> ClientState<T, E> {
        match self.from_server.recv_block().expect("failed to get state") {
            ServerMessage::Image(state) => {
                println!("download done");
                ClientState {
                    sync: false,
                    predict_frame: 0,
                    predict: state.clone(),
                    predict_delta: Vec::new(),
                    server_frame: 0,
                    server: state.clone()
                }
            },
            _ => panic!("expected game data")
        }
    }
}

impl<G: Game<T, E>, T:Send+Encodable+Decodable+Clone, E:Send+Encodable+Decodable+Clone>
    Game<ClientState<T, E>, E> for Client<G, T, E> {

    fn step(&mut self, event: E, mut gd: ClientState<T, E>) -> ClientState<T, E> {
        let mut frame = gd.predict.clone();
        let mut index = gd.predict_frame;

        loop {
            match self.from_server.recv() {
                Some(ServerMessage::Image(_)) => panic!("unexpected game data"),
                Some(ServerMessage::Event(e)) => {
                    gd.server = self.game.step(e, gd.server);
                }
                Some(ServerMessage::Sync) => {
                    gd.server_frame += 1;
                    frame = gd.server.clone();
                    index = gd.server_frame;
                },
                None => break
            }
        }

        if gd.sync {
            gd.sync = gd.predict_frame > gd.server_frame + 1;
            if gd.sync {
                return gd
            }
        } else if gd.predict_frame > gd.server_frame + 5 {
            gd.sync = true;
            return gd;
        }

        self.to_server.send(&ClientMessage::Event(event.clone()));
        gd.predict_delta.push((gd.predict_frame, event));
        gd.predict_frame += 1;

        let mut predict = Vec::new();
        for (idx, e) in gd.predict_delta.drain() {
            if idx > index {
                println!("{} > {}", idx, index);
                frame = self.game.step(e.clone(), frame);
            }

            if idx > gd.server_frame {
                predict.push((idx, e));
            }
        }

        gd.predict = frame;
        gd.predict_delta = predict;
        gd
    }
}

<commit_msg>cleanup of network<commit_after>//   Copyright 2015 Colin Sherratt
//
//   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.

extern crate "snowmew-core" as core;
extern crate "snowmew-position" as position;
extern crate "snowmew-graphics" as graphics;
extern crate "snowmew-render" as render;
extern crate wire;
extern crate bchannel;
extern crate bincode;
extern crate "rustc-serialize" as rustc_serialize;

use core::common::{Common, CommonData};
use position::{Positions, PositionData};
use graphics::{Graphics, GraphicsData};
use render::{Renderable, RenderData};

use std::sync::mpsc;
use std::thread::Thread;
use std::ops::{Deref, DerefMut};
use wire::SizeLimit;
use wire::tcp::OutTcpStream;
use rustc_serialize::{Decodable, Encodable};

use core::game::Game;

#[derive(RustcEncodable, RustcDecodable)]
pub enum ServerMessage<T, E> {
    Image(T),
    Event(E),
    Sync
}

#[derive(RustcEncodable, RustcDecodable)]
pub enum ClientMessage<E> {
    Event(E)
}

pub struct Server<Game, GameData> {
    game: Game,
    data: GameData
}

unsafe impl<T:Send, E:Send> Send for ServerClient<T, E> {}

struct ServerClient<T, E> {
    to_client: OutTcpStream<ServerMessage<T, E>>,
    from_client: bchannel::Receiver<ClientMessage<E>, bincode::DecodingError>
}

impl<G, GD:Clone+Send+Decodable+Encodable> Server<G, GD> {
    pub fn new(game: G, data: GD) -> Server<G, GD> {
        Server {
            game: game,
            data: data
        }
    }

    pub fn serve<E:Send+Encodable+Clone+Decodable>(mut self, iface: &str, port: u16)
        where G: Game<GD, E> {

        let (listener, _) = wire::listen_tcp(iface, port).unwrap();

        let (tx, rx): (mpsc::Sender<ServerClient<GD, E>>,
                       mpsc::Receiver<ServerClient<GD, E>>) = mpsc::channel();
        Thread::spawn(move || {
            let (read_limit, write_limit) = (SizeLimit::Infinite, SizeLimit::Infinite);

            for connection in listener.into_blocking_iter() {
                let (i, o) = wire::upgrade_tcp(connection, read_limit, write_limit);

                let client = ServerClient {
                    to_client: o,
                    from_client: i
                };

                tx.send(client);
            }
        });

        let mut clients = Vec::new();

        loop {
            // add clients to game
            while clients.len() == 0 {
                let mut res = rx.recv().ok().expect("failed to get message");
                res.to_client.send(&ServerMessage::Image(self.data.clone()));
                clients.push(res);
            }

            while let Ok(mut res) = rx.try_recv() {
                res.to_client.send(&ServerMessage::Image(self.data.clone()));
                clients.push(res)
            }

            let mut events = Vec::new();

            for c in clients.iter() {
                events.push(c.from_client.recv_block().expect("client sucks man"));
            }

            for ClientMessage::Event(e) in events.drain() {
                for c in clients.iter_mut() {
                    c.to_client.send(&ServerMessage::Event(e.clone()));
                }
                self.data = self.game.step(e, self.data)
            }
            for c in clients.iter_mut() {
                c.to_client.send(&ServerMessage::Sync);
            }

        }
    }
}

#[derive(Clone)]
pub struct ClientState<T, E> {
    sync: bool,
    predict_frame: u32,
    predict: T,
    predict_delta: Vec<(u32, E)>,
    server_frame: u32,
    server: T
}

impl<T, E> Deref for ClientState<T, E> {
    type Target = T;

    fn deref<'a>(&'a self) -> &'a T {
        &self.predict
    }
}

impl<T, E> DerefMut for ClientState<T, E> {
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        &mut self.predict
    }
}

impl<E, T: Common> Common for ClientState<T, E> {
    fn get_common<'a>(&'a self) -> &'a CommonData { self.predict.get_common() }
    fn get_common_mut<'a>(&'a mut self) -> &'a mut CommonData { self.predict.get_common_mut() }
}

impl<E, T: Positions> Positions for ClientState<T, E> {
    fn get_position<'a>(&'a self) -> &'a PositionData { self.predict.get_position() }
    fn get_position_mut<'a>(&'a mut self) -> &'a mut PositionData { self.predict.get_position_mut() }
}

impl<E, T: Graphics> Graphics for ClientState<T, E> {
    fn get_graphics<'a>(&'a self) -> &'a GraphicsData { self.predict.get_graphics() }
    fn get_graphics_mut<'a>(&'a mut self) -> &'a mut GraphicsData { self.predict.get_graphics_mut() }
}

impl<E, T: Renderable+Common+Positions+Graphics> Renderable for ClientState<T, E> {
    fn get_render_data<'a>(&'a self) -> &'a RenderData { self.predict.get_render_data() }
    fn get_render_data_mut<'a>(&'a mut self) -> &'a mut RenderData { self.predict.get_render_data_mut() }
}

pub struct Client<G, T, E> {
    game: G,
    to_server: OutTcpStream<ClientMessage<E>>,
    from_server: bchannel::Receiver<ServerMessage<T, E>, bincode::DecodingError>
}

impl<G, T:Send+Encodable+Decodable+Clone, E:Send+Encodable+Decodable> Client<G, T, E> {
    pub fn new(game: G, server: &str, port: u16) -> Client<G, T, E> {
        let (o, i) = wire::connect_tcp(server, port, SizeLimit::Infinite, SizeLimit::Infinite).unwrap();

        Client {
            game: game,
            to_server: i,
            from_server: o
        }
    }

    pub fn gamedata(&mut self) -> ClientState<T, E> {
        match self.from_server.recv_block().expect("failed to get state") {
            ServerMessage::Image(state) => {
                println!("download done");
                ClientState {
                    sync: false,
                    predict_frame: 0,
                    predict: state.clone(),
                    predict_delta: Vec::new(),
                    server_frame: 0,
                    server: state.clone()
                }
            },
            _ => panic!("expected game data")
        }
    }
}

impl<G: Game<T, E>, T:Send+Encodable+Decodable+Clone, E:Send+Encodable+Decodable+Clone>
    Game<ClientState<T, E>, E> for Client<G, T, E> {

    fn step(&mut self, event: E, mut gd: ClientState<T, E>) -> ClientState<T, E> {
        let mut frame = gd.predict.clone();
        let mut index = gd.predict_frame;

        loop {
            match self.from_server.recv() {
                Some(ServerMessage::Image(_)) => panic!("unexpected game data"),
                Some(ServerMessage::Event(e)) => {
                    gd.server = self.game.step(e, gd.server);
                }
                Some(ServerMessage::Sync) => {
                    gd.server_frame += 1;
                    frame = gd.server.clone();
                    index = gd.server_frame;
                },
                None => break
            }
        }

        if gd.sync {
            gd.sync = gd.predict_frame > gd.server_frame + 1;
            if gd.sync {
                return gd
            }
        } else if gd.predict_frame > gd.server_frame + 5 {
            gd.sync = true;
            return gd;
        }

        self.to_server.send(&ClientMessage::Event(event.clone()));
        gd.predict_delta.push((gd.predict_frame, event));
        gd.predict_frame += 1;

        let mut predict = Vec::new();
        for (idx, e) in gd.predict_delta.drain() {
            if idx > index {
                println!("{} > {}", idx, index);
                frame = self.game.step(e.clone(), frame);
            }

            if idx > gd.server_frame {
                predict.push((idx, e));
            }
        }

        gd.predict = frame;
        gd.predict_delta = predict;
        gd
    }
}

<|endoftext|>