<commit_before>use std::rc::{Rc};
use std::cell::{RefCell};
use std::collections::HashMap;

pub struct Broker<T: Subscriber> {
    subscriptions: Subscriptions<T>,
}

impl<T: Subscriber> Broker<T> {
    pub fn new() -> Self {
        Broker{ subscriptions: Subscriptions::<T>::new() }
    }

    pub fn publish(&mut self, topic: &str, payload: &[u8]) {
        self.subscriptions.publish(topic, payload);
    }

    pub fn subscribe(&mut self, subscriber: Rc<RefCell<T>>, topics: &[&str]) {
        self.subscriptions.subscribe(subscriber, &topics)
    }
}

pub struct Subscriptions<T: Subscriber> {
    subscribers: Vec<Rc<RefCell<T>>>,
}

impl<T: Subscriber> Subscriptions<T> {
    fn new() -> Self {
        return Subscriptions { subscribers: vec![], }
    }

    fn subscribe(&mut self, subscriber: Rc<RefCell<T>>, topics: &[&str]) {
        let subscriber = self.add_or_find(subscriber);
        subscriber.borrow_mut().append_topics(topics);
    }

    fn add_or_find(&mut self, subscriber: Rc<RefCell<T>>) -> Rc<RefCell<T>> {
        for sub in &self.subscribers {
            let sub1 = sub.clone();
            let sub2 = subscriber.clone();
            //this is horrible
            //borrow doesn't return T, it returns Ref<T>
            //since Ref<T> itself doesn't satisfy the template contraint, we need to deref
            //it to get the to the T inside. And since is_same takes borrows, we reapply
            //the ampersand
            if is_same(&*sub1.borrow(), &*sub2.borrow()) {
                return sub2;
            }
        }

        self.subscribers.push(subscriber);
        self.subscribers[self.subscribers.len() - 1].clone()
    }

    fn publish(&mut self, topic: &str, payload: &[u8]) {
        for subscriber in &mut self.subscribers {
            let subscriber = subscriber.clone();
            let mut subscriber = subscriber.borrow_mut();

            for _ in subscriber.topics().iter().filter(|&t| topic_matches(&topic, &t)) {
                subscriber.new_message(payload);
            }
        }
    }
}

//is same identity
fn is_same<T>(lhs: &T, rhs: &T) -> bool {
    return lhs as *const T as i64 == rhs as *const T as i64
}

fn topic_matches(pub_topic: &str, sub_topic: &str) -> bool {
    pub_topic == sub_topic
}

pub trait Subscriber {
    fn new_message(&mut self, bytes: &[u8]);
    fn append_topics(&mut self, topics: &[&str]);
    fn topics(&self) -> Vec<String>;
}

pub trait SubscriberT {
    fn new_message(&mut self, bytes: &[u8]);
}

struct Subscription<T: SubscriberT> {
    subscriber: Rc<RefCell<T>>,
    topics: Vec<String>,
}

impl<T: SubscriberT> Subscription<T> {
    fn append_topics(&mut self, topics: &[&str]) {
        let mut new_topics = topics.to_vec().into_iter().map(|t| t.to_string()).collect();
        self.topics.append(&mut new_topics);
    }

    fn topics(&self) -> Vec<String> {
        self.topics.clone()
    }
}

struct Node<T: SubscriberT> {
    children: HashMap<String, Box<Node<T>>>,
    leaves: Vec<Subscription<T>>,
}

pub struct SubscriptionsT<T: SubscriberT> {
    tree: Node<T>,
}

impl<T: SubscriberT> SubscriptionsT<T> {
    pub fn new() -> Self {
        SubscriptionsT { tree: Node { children: HashMap::new(), leaves: vec![] }}
    }

    pub fn subscribe(&mut self, subscriber: Rc<RefCell<T>>, topics: &[&str]) {
    }

    pub fn publish(&self, topic: &str, payload: &[u8]) {

    }

    // fn add_or_find(&mut self, subscriber: Rc<RefCell<T>>) -> Rc<RefCell<T>> {
    // }

}

#[cfg(test)]
struct TestSubscriberT {
    msgs: Vec<Vec<u8>>,
}

#[cfg(test)]
impl TestSubscriberT {
    fn new() -> Self {
        return TestSubscriberT{msgs: vec![]}
    }
}

#[cfg(test)]
impl SubscriberT for TestSubscriberT {
    fn new_message(&mut self, bytes: &[u8]) {
        self.msgs.push(bytes.to_vec());
    }
}

#[test]
fn test_subt() {
    let mut broker = SubscriptionsT::<TestSubscriberT>::new();
    let sub_ref = Rc::new(RefCell::new(TestSubscriberT::new()));
    let mut subscriber = sub_ref.clone();
    broker.publish("topics/foo", &[0, 1, 2]);
    assert_eq!(subscriber.borrow().msgs.len(), 0);

    broker.subscribe(subscriber.clone(), &["topics/foo"]);
    broker.publish("topics/foo", &[0, 1, 9]);
    broker.publish("topics/bar", &[2, 4, 6]);
    assert_eq!(subscriber.borrow().msgs.len(), 1);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);

    broker.subscribe(subscriber.clone(), &["topics/foo"]);
    broker.publish("topics/foo", &[0, 1, 9]);
    broker.publish("topics/bar", &[2, 4, 6]);
    assert_eq!(subscriber.borrow().msgs.len(), 1);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);

    broker.subscribe(subscriber.clone(), &["topics/bar"]);
    broker.publish("topics/foo", &[1, 3, 5, 7]);
    broker.publish("topics/bar", &[2, 4]);
    assert_eq!(subscriber.borrow().msgs.len(), 3);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);
    assert_eq!(subscriber.borrow().msgs[1], &[1, 3, 5, 7]);
    assert_eq!(subscriber.borrow().msgs[2], &[2, 4]);
}

#[cfg(test)]
struct TestSubscriber {
    msgs: Vec<Vec<u8>>,
    topics: Vec<String>,
}
#[cfg(test)]
impl TestSubscriber {
    fn new() -> Self {
        return TestSubscriber{msgs: vec![], topics: vec![]}
    }
}

#[cfg(test)]
impl Subscriber for TestSubscriber {

    fn new_message(&mut self, bytes: &[u8]) {
        self.msgs.push(bytes.to_vec());
    }

    fn append_topics(&mut self, topics: &[&str]) {
        let mut new_topics = topics.to_vec().into_iter().map(|t| t.to_string()).collect();
        self.topics.append(&mut new_topics);
    }

    fn topics(&self) -> Vec<String> {
        self.topics.clone()
    }
}

#[test]
fn test_subscribe() {
    let mut broker = Broker::<TestSubscriber>::new();
    let sub_ref = Rc::new(RefCell::new(TestSubscriber::new()));
    let subscriber = sub_ref.clone();
    broker.publish("topics/foo", &[0, 1, 2]);
    assert_eq!(subscriber.borrow().msgs.len(), 0);

    broker.subscribe(subscriber.clone(), &["topics/foo"]);
    broker.publish("topics/foo", &[0, 1, 9]);
    broker.publish("topics/bar", &[2, 4, 6]);
    assert_eq!(subscriber.borrow().msgs.len(), 1);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);

    broker.subscribe(subscriber.clone(), &["topics/bar"]);
    broker.publish("topics/foo", &[1, 3, 5, 7]);
    broker.publish("topics/bar", &[2, 4]);
    assert_eq!(subscriber.borrow().msgs.len(), 3);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);
    assert_eq!(subscriber.borrow().msgs[1], &[1, 3, 5, 7]);
    assert_eq!(subscriber.borrow().msgs[2], &[2, 4]);
}

#[test]
fn test_tree() {

}
<commit_msg>Compiles checkpoint<commit_after>use std::rc::{Rc};
use std::cell::{RefCell};
use std::collections::HashMap;

pub struct Broker<T: Subscriber> {
    subscriptions: Subscriptions<T>,
}

impl<T: Subscriber> Broker<T> {
    pub fn new() -> Self {
        Broker{ subscriptions: Subscriptions::<T>::new() }
    }

    pub fn publish(&mut self, topic: &str, payload: &[u8]) {
        self.subscriptions.publish(topic, payload);
    }

    pub fn subscribe(&mut self, subscriber: Rc<RefCell<T>>, topics: &[&str]) {
        self.subscriptions.subscribe(subscriber, &topics)
    }
}

pub struct Subscriptions<T: Subscriber> {
    subscribers: Vec<Rc<RefCell<T>>>,
}

impl<T: Subscriber> Subscriptions<T> {
    fn new() -> Self {
        return Subscriptions { subscribers: vec![], }
    }

    fn subscribe(&mut self, subscriber: Rc<RefCell<T>>, topics: &[&str]) {
        let subscriber = self.add_or_find(subscriber);
        subscriber.borrow_mut().append_topics(topics);
    }

    fn add_or_find(&mut self, subscriber: Rc<RefCell<T>>) -> Rc<RefCell<T>> {
        for sub in &self.subscribers {
            let sub1 = sub.clone();
            let sub2 = subscriber.clone();
            //this is horrible
            //borrow doesn't return T, it returns Ref<T>
            //since Ref<T> itself doesn't satisfy the template contraint, we need to deref
            //it to get the to the T inside. And since is_same takes borrows, we reapply
            //the ampersand
            if is_same(&*sub1.borrow(), &*sub2.borrow()) {
                return sub2;
            }
        }

        self.subscribers.push(subscriber);
        self.subscribers[self.subscribers.len() - 1].clone()
    }

    fn publish(&mut self, topic: &str, payload: &[u8]) {
        for subscriber in &mut self.subscribers {
            let subscriber = subscriber.clone();
            let mut subscriber = subscriber.borrow_mut();

            for _ in subscriber.topics().iter().filter(|&t| topic_matches(&topic, &t)) {
                subscriber.new_message(payload);
            }
        }
    }
}

//is same identity
fn is_same<T>(lhs: &T, rhs: &T) -> bool {
    return lhs as *const T as i64 == rhs as *const T as i64
}

fn topic_matches(pub_topic: &str, sub_topic: &str) -> bool {
    pub_topic == sub_topic
}

pub trait Subscriber {
    fn new_message(&mut self, bytes: &[u8]);
    fn append_topics(&mut self, topics: &[&str]);
    fn topics(&self) -> Vec<String>;
}

pub trait SubscriberT {
    fn new_message(&mut self, bytes: &[u8]);
}

struct Subscription<T: SubscriberT> {
    subscriber: Rc<RefCell<T>>,
    topics: Vec<String>,
}

impl<T: SubscriberT> Subscription<T> {
    fn append_topics(&mut self, topics: &[&str]) {
        let mut new_topics = topics.to_vec().into_iter().map(|t| t.to_string()).collect();
        self.topics.append(&mut new_topics);
    }

    fn topics(&self) -> Vec<String> {
        self.topics.clone()
    }
}

struct Node<T: SubscriberT> {
    children: HashMap<String, Box<Node<T>>>,
    leaves: Vec<Subscription<T>>,
}

impl<T: SubscriberT> Node<T> {
    pub fn new() -> Self {
        Node { children: HashMap::new(), leaves: vec![] }
    }
}

pub struct SubscriptionsT<T: SubscriberT> {
    tree: Node<T>,
}

impl<T: SubscriberT> SubscriptionsT<T> {
    pub fn new() -> Self {
        SubscriptionsT { tree: Node::new() }
    }

    pub fn subscribe(&mut self, subscriber: Rc<RefCell<T>>, topics: &[&str]) {
        for topic in topics {
            let topParts : Vec<&str> = topic.split("/").collect();
            println!("topParts: ");
            for part in &topParts {
                print!("{}, ", part)
            }
            println!("");

            self.tree.children.insert("part".to_string(), Box::new(Node::new()));
        }
    }

    pub fn publish(&self, topic: &str, payload: &[u8]) {

    }

    // fn add_or_find(&mut self, subscriber: Rc<RefCell<T>>) -> Rc<RefCell<T>> {
    // }

}

#[cfg(test)]
struct TestSubscriberT {
    msgs: Vec<Vec<u8>>,
}

#[cfg(test)]
impl TestSubscriberT {
    fn new() -> Self {
        return TestSubscriberT{msgs: vec![]}
    }
}

#[cfg(test)]
impl SubscriberT for TestSubscriberT {
    fn new_message(&mut self, bytes: &[u8]) {
        self.msgs.push(bytes.to_vec());
    }
}

#[test]
fn test_subt() {
    let mut broker = SubscriptionsT::<TestSubscriberT>::new();
    let sub_ref = Rc::new(RefCell::new(TestSubscriberT::new()));
    let mut subscriber = sub_ref.clone();
    broker.publish("topics/foo", &[0, 1, 2]);
    assert_eq!(subscriber.borrow().msgs.len(), 0);

    broker.subscribe(subscriber.clone(), &["topics/foo"]);
    broker.publish("topics/foo", &[0, 1, 9]);
    broker.publish("topics/bar", &[2, 4, 6]);
    assert_eq!(subscriber.borrow().msgs.len(), 1);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);

    broker.subscribe(subscriber.clone(), &["topics/foo"]);
    broker.publish("topics/foo", &[0, 1, 9]);
    broker.publish("topics/bar", &[2, 4, 6]);
    assert_eq!(subscriber.borrow().msgs.len(), 1);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);

    broker.subscribe(subscriber.clone(), &["topics/bar"]);
    broker.publish("topics/foo", &[1, 3, 5, 7]);
    broker.publish("topics/bar", &[2, 4]);
    assert_eq!(subscriber.borrow().msgs.len(), 3);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);
    assert_eq!(subscriber.borrow().msgs[1], &[1, 3, 5, 7]);
    assert_eq!(subscriber.borrow().msgs[2], &[2, 4]);
}

#[cfg(test)]
struct TestSubscriber {
    msgs: Vec<Vec<u8>>,
    topics: Vec<String>,
}
#[cfg(test)]
impl TestSubscriber {
    fn new() -> Self {
        return TestSubscriber{msgs: vec![], topics: vec![]}
    }
}

#[cfg(test)]
impl Subscriber for TestSubscriber {

    fn new_message(&mut self, bytes: &[u8]) {
        self.msgs.push(bytes.to_vec());
    }

    fn append_topics(&mut self, topics: &[&str]) {
        let mut new_topics = topics.to_vec().into_iter().map(|t| t.to_string()).collect();
        self.topics.append(&mut new_topics);
    }

    fn topics(&self) -> Vec<String> {
        self.topics.clone()
    }
}

#[test]
fn test_subscribe() {
    let mut broker = Broker::<TestSubscriber>::new();
    let sub_ref = Rc::new(RefCell::new(TestSubscriber::new()));
    let subscriber = sub_ref.clone();
    broker.publish("topics/foo", &[0, 1, 2]);
    assert_eq!(subscriber.borrow().msgs.len(), 0);

    broker.subscribe(subscriber.clone(), &["topics/foo"]);
    broker.publish("topics/foo", &[0, 1, 9]);
    broker.publish("topics/bar", &[2, 4, 6]);
    assert_eq!(subscriber.borrow().msgs.len(), 1);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);

    broker.subscribe(subscriber.clone(), &["topics/bar"]);
    broker.publish("topics/foo", &[1, 3, 5, 7]);
    broker.publish("topics/bar", &[2, 4]);
    assert_eq!(subscriber.borrow().msgs.len(), 3);
    assert_eq!(subscriber.borrow().msgs[0], &[0, 1, 9]);
    assert_eq!(subscriber.borrow().msgs[1], &[1, 3, 5, 7]);
    assert_eq!(subscriber.borrow().msgs[2], &[2, 4]);
}
<|endoftext|>


<commit_before>//pub const FINGERPRINT_SIZE: usize = 1;
pub const BUCKET_SIZE: usize = 4;

// Fingerprint Size is 1 byte so lets remove the Vec
#[derive(PartialEq, Copy, Clone)]
pub struct Fingerprint (pub u8);

/// Manages BUCKET_SIZE fingerprints at most.
pub struct Bucket {
    pub buffer: Vec<Fingerprint>,
}

impl Bucket {
    /// Creates a new bucket with a pre-allocated buffer.
    pub fn new() -> Bucket {
        Bucket {
            buffer: Vec::with_capacity(BUCKET_SIZE)
        }
    }

    /// Inserts the fingerprint into the buffer if the buffer is not full. This
    /// Operation will be O(1), since the buffer was pre-allocated.
    pub fn insert(&mut self, fp: Fingerprint) -> bool {
        if self.buffer.len() < BUCKET_SIZE {
            self.buffer.push(fp);
            true
        } else {
            false
        }
    }

    /// Deletes the given fingerprint from the bucket. Since the order inside
    /// the bucket doesn't matter, we can use `swap_remove` to keep the runtime
    /// in O(1).
    pub fn delete(&mut self, fp: Fingerprint) -> bool {
        match self.get_fingerprint_index(fp) {
            Some(index) => { self.buffer.swap_remove(index); true }
            None => false
        }
    }

    /// Returns the index of the given fingerprint, if its found.
    pub fn get_fingerprint_index(&mut self, fp: Fingerprint) -> Option<usize> {
        self.buffer.iter().position(|e| *e == fp)
    }
}
<commit_msg>doc-fix: Of course, `delete` is still O(n) due to finding the element with linear search<commit_after>//pub const FINGERPRINT_SIZE: usize = 1;
pub const BUCKET_SIZE: usize = 4;

// Fingerprint Size is 1 byte so lets remove the Vec
#[derive(PartialEq, Copy, Clone)]
pub struct Fingerprint (pub u8);

/// Manages BUCKET_SIZE fingerprints at most.
pub struct Bucket {
    pub buffer: Vec<Fingerprint>,
}

impl Bucket {
    /// Creates a new bucket with a pre-allocated buffer.
    pub fn new() -> Bucket {
        Bucket {
            buffer: Vec::with_capacity(BUCKET_SIZE)
        }
    }

    /// Inserts the fingerprint into the buffer if the buffer is not full. This
    /// Operation will be O(1), since the buffer was pre-allocated.
    pub fn insert(&mut self, fp: Fingerprint) -> bool {
        if self.buffer.len() < BUCKET_SIZE {
            self.buffer.push(fp);
            true
        } else {
            false
        }
    }

    /// Deletes the given fingerprint from the bucket. Since the order inside
    /// the bucket doesn't matter, we can use `swap_remove` to make the
    /// deletion O(1). Finding element still needs O(n).
    pub fn delete(&mut self, fp: Fingerprint) -> bool {
        match self.get_fingerprint_index(fp) {
            Some(index) => { self.buffer.swap_remove(index); true }
            None => false
        }
    }

    /// Returns the index of the given fingerprint, if its found. O(n)
    pub fn get_fingerprint_index(&mut self, fp: Fingerprint) -> Option<usize> {
        self.buffer.iter().position(|e| *e == fp)
    }
}
<|endoftext|>


<commit_before>use na::{Real, Orthographic3, Perspective3};
use aliases::TMat4;

//pub fn frustum<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}

//pub fn frustum_lh<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_lr_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_lh_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_rh<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_rh_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_rh_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}

//pub fn infinite_perspective<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn infinite_perspective_lh<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn infinite_perspective_rh<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn infinite_ortho<N: Real>(left: N, right: N, bottom: N, top: N) -> TMat4<N> {
//    unimplemented!()
//}

/// Creates a matrix for an orthographic parallel viewing volume, using the right handedness and OpenGL near and far clip planes definition.
pub fn ortho<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
    Orthographic3::new(left, right, bottom, top, znear, zfar).unwrap()
}

//pub fn ortho_lh<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_lh_no<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_lh_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_no<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_rh<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_rh_no<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_rh_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}

/// Creates a matrix for a symmetric perspective-view frustum based on the right handedness and OpenGL near and far clip planes definition.
pub fn perspective<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
    Perspective3::new(fovy, aspect, near, far).unwrap()
}

//pub fn perspective_fov<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_lh<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_lh_no<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_lh_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_no<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_rh<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_rh_no<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_rh_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_lh<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_lh_no<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_lh_zo<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_no<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_rh<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_rh_no<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_rh_zo<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_zo<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn tweaked_infinite_perspective<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn tweaked_infinite_perspective_ep<N: Real>(fovy: N, aspect: N, near: N, ep: N) -> TMat4<N> {
//    unimplemented!()
//}
<commit_msg>Fix glm::perspective.<commit_after>use na::{Real, Orthographic3, Perspective3};
use aliases::TMat4;

//pub fn frustum<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}

//pub fn frustum_lh<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_lr_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_lh_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_rh<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_rh_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_rh_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn frustum_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}

//pub fn infinite_perspective<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn infinite_perspective_lh<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn infinite_perspective_rh<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn infinite_ortho<N: Real>(left: N, right: N, bottom: N, top: N) -> TMat4<N> {
//    unimplemented!()
//}

/// Creates a matrix for an orthographic parallel viewing volume, using the right handedness and OpenGL near and far clip planes definition.
pub fn ortho<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
    Orthographic3::new(left, right, bottom, top, znear, zfar).unwrap()
}

//pub fn ortho_lh<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_lh_no<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_lh_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_no<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_rh<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_rh_no<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_rh_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn ortho_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
//    unimplemented!()
//}

/// Creates a matrix for a perspective-view frustum based on the right handedness and OpenGL near and far clip planes definition.
///
/// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
    Perspective3::new(aspect, fovy, near, far).unwrap()
}

//pub fn perspective_fov<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_lh<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_lh_no<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_lh_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_no<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_rh<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_rh_no<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_rh_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_fov_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_lh<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_lh_no<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_lh_zo<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_no<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_rh<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_rh_no<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_rh_zo<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn perspective_zo<N: Real>(fovy: N, aspect: N, near: N, far: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn tweaked_infinite_perspective<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
//    unimplemented!()
//}
//
//pub fn tweaked_infinite_perspective_ep<N: Real>(fovy: N, aspect: N, near: N, ep: N) -> TMat4<N> {
//    unimplemented!()
//}
<|endoftext|>


<commit_before>// TODO
// impl ToGeojson for ....
// generic number instead of f64 for position?
// rename Position to Pos

extern crate serialize;

use std::collections::TreeMap;
use serialize::json::ToJson;
use serialize::json;

/// Position
///
/// [GeoJSON Format Specification § 2.1.1](http://geojson.org/geojson-spec.html#positions)
pub struct Position(Vec<f64>);

impl ToJson for Position {
    fn to_json(&self) -> json::Json {
        let &Position(ref nums) = self;
        nums.to_json()
    }
}

impl Clone for Position {
    fn clone(&self) -> Position {
        let &Position(ref nums) = self;
        Position(nums.clone())
    }
}

/// Point
///
/// [GeoJSON Format Specification § 2.1.2](http://geojson.org/geojson-spec.html#point)
pub struct Point {
    coordinates: Position,
}

impl ToJson for Point {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "Point".to_string().to_json());
        d.insert("coordinates".to_string(), self.coordinates.to_json());
        d.to_json()
    }
}

/// MultiPoint
///
/// [GeoJSON Format Specification § 2.1.3](http://geojson.org/geojson-spec.html#multipoint)
pub struct MultiPoint {
    points: Vec<Point>,
}

impl ToJson for MultiPoint {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "MultiPoint".to_string().to_json());
        d.insert("coordinates".to_string(), self.points.to_json());
        d.to_json()
    }
}

/// LineString
///
/// [GeoJSON Format Specification § 2.1.4](http://geojson.org/geojson-spec.html#linestring)
pub struct LineString {
    coordinates: Vec<Position>,
}

impl ToJson for LineString {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "LineString".to_string().to_json());
        d.insert("coordinates".to_string(), self.coordinates.to_json());
        d.to_json()
    }
}

/// MultiLineString
///
/// [GeoJSON Format Specification § 2.1.5](http://geojson.org/geojson-spec.html#multilinestring)
pub struct MultiLineString {
    line_strings: Vec<LineString>,
}

impl ToJson for MultiLineString {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "MultiLineString".to_string().to_json());
        d.insert("coordinates".to_string(), self.line_strings.to_json());
        d.to_json()
    }
}

/// Polygon
///
/// [GeoJSON Format Specification § 2.1.6](http://geojson.org/geojson-spec.html#polygon)
pub struct Polygon {
    exterior: Vec<Position>,
    holes: Vec<Vec<Position>>,
}

impl ToJson for Polygon {
    fn to_json(&self) -> json::Json {
        let mut coordinates = self.holes.clone();
        coordinates.unshift(self.exterior.clone());

        let mut d = TreeMap::new();
        d.insert("type".to_string(), "Polygon".to_string().to_json());
        d.insert("coordinates".to_string(), coordinates.to_json());
        d.to_json()
    }
}

/// MultiPolygon
///
/// [GeoJSON Format Specification § 2.1.7](http://geojson.org/geojson-spec.html#multipolygon)
pub struct MultiPolygon {
    polygons: Vec<Polygon>,
}

impl ToJson for MultiPolygon {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "MultiPolygon".to_string().to_json());
        d.insert("coordinates".to_string(), self.polygons.to_json());
        d.to_json()
    }
}

fn main() {
    let point = Point {
        coordinates: Position(vec![1., 2., 3.]),
    };

    let j: json::Json = point.to_json();
    let s: String = j.to_pretty_str();

    println!("{}", s);
}
<commit_msg>Make struct values public<commit_after>// TODO
// impl ToGeojson for ....
// generic number instead of f64 for position?
// rename Position to Pos

extern crate serialize;

use std::collections::TreeMap;
use serialize::json::ToJson;
use serialize::json;

/// Position
///
/// [GeoJSON Format Specification § 2.1.1](http://geojson.org/geojson-spec.html#positions)
pub struct Position(pub Vec<f64>);

impl ToJson for Position {
    fn to_json(&self) -> json::Json {
        let &Position(ref nums) = self;
        nums.to_json()
    }
}

impl Clone for Position {
    fn clone(&self) -> Position {
        let &Position(ref nums) = self;
        Position(nums.clone())
    }
}

/// Point
///
/// [GeoJSON Format Specification § 2.1.2](http://geojson.org/geojson-spec.html#point)
pub struct Point {
    pub coordinates: Position,
}

impl ToJson for Point {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "Point".to_string().to_json());
        d.insert("coordinates".to_string(), self.coordinates.to_json());
        d.to_json()
    }
}

/// MultiPoint
///
/// [GeoJSON Format Specification § 2.1.3](http://geojson.org/geojson-spec.html#multipoint)
pub struct MultiPoint {
    pub points: Vec<Point>,
}

impl ToJson for MultiPoint {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "MultiPoint".to_string().to_json());
        d.insert("coordinates".to_string(), self.points.to_json());
        d.to_json()
    }
}

/// LineString
///
/// [GeoJSON Format Specification § 2.1.4](http://geojson.org/geojson-spec.html#linestring)
pub struct LineString {
    pub coordinates: Vec<Position>,
}

impl ToJson for LineString {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "LineString".to_string().to_json());
        d.insert("coordinates".to_string(), self.coordinates.to_json());
        d.to_json()
    }
}

/// MultiLineString
///
/// [GeoJSON Format Specification § 2.1.5](http://geojson.org/geojson-spec.html#multilinestring)
pub struct MultiLineString {
    pub line_strings: Vec<LineString>,
}

impl ToJson for MultiLineString {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "MultiLineString".to_string().to_json());
        d.insert("coordinates".to_string(), self.line_strings.to_json());
        d.to_json()
    }
}

/// Polygon
///
/// [GeoJSON Format Specification § 2.1.6](http://geojson.org/geojson-spec.html#polygon)
pub struct Polygon {
    pub exterior: Vec<Position>,
    pub holes: Vec<Vec<Position>>,
}

impl ToJson for Polygon {
    fn to_json(&self) -> json::Json {
        let mut coordinates = self.holes.clone();
        coordinates.unshift(self.exterior.clone());

        let mut d = TreeMap::new();
        d.insert("type".to_string(), "Polygon".to_string().to_json());
        d.insert("coordinates".to_string(), coordinates.to_json());
        d.to_json()
    }
}

/// MultiPolygon
///
/// [GeoJSON Format Specification § 2.1.7](http://geojson.org/geojson-spec.html#multipolygon)
pub struct MultiPolygon {
    pub polygons: Vec<Polygon>,
}

impl ToJson for MultiPolygon {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), "MultiPolygon".to_string().to_json());
        d.insert("coordinates".to_string(), self.polygons.to_json());
        d.to_json()
    }
}

fn main() {
    let point = Point {
        coordinates: Position(vec![1., 2., 3.]),
    };

    let j: json::Json = point.to_json();
    let s: String = j.to_pretty_str();

    println!("{}", s);
}
<|endoftext|>


<commit_before>use core::rand::*;
use core::f64::sqrt;
use core::f64::pow;

#[deriving(Eq)]
pub struct Point {
    x : f64,
    y : f64
}

pub impl Point {
    fn new() -> Point {
        Point{x:0.0, y:0.0}
    }

    fn new_dir() -> Point {
        let mut pt : Point =rand::random();
        pt-=0.5f64;
        pt/pt.norm2()
    }

    fn norm2(&self) -> f64 {
        sqrt(pow(self.x,2.0)+pow(self.y,2.0))
    }

    fn dist(&self, other : &Point) -> f64 {
        (*self-*other).norm2()
    }

}

impl ToStr for Point {
    fn to_str(&self) -> ~str {
        fmt!("(%f, %f)", self.x as float, self.y as float)
    }
}

//
// * Génération aléatoire
//
impl Rand for Point {
    fn rand<R: Rng>(rng: &mut R) -> Point {
        Point { x: rng.gen::<f64>(), y: rng.gen::<f64>()}
    }
}

//
// * Opérateurs arithmétiques
//
// Addition
trait RhsOfAdd<Result> {
  fn add_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfAdd<Point> for Point {
  fn add_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self.x+lhs.x), y:(self.y+lhs.y)}
   }
}
impl RhsOfAdd<Point> for f64 {
  fn add_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (*self+lhs.x), y:(*self+lhs.y)}
   }
}
impl<Result, Rhs: RhsOfAdd<Result> > ops::Add<Rhs, Result> for Point {
  fn add(&self, rhs: &Rhs) -> Result {
    rhs.add_lhs_to(self)
  }
}
// Soustraction
trait RhsOfSub<Result> {
  fn sub_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfSub<Point> for Point {
  fn sub_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (-self.x+lhs.x), y:(-self.y+lhs.y)}
   }
}
impl RhsOfSub<Point> for f64 {
    fn sub_lhs_to(&self, lhs:&Point) -> Point {
        Point{x: lhs.x - *self, y: lhs.y-*self}
    }
}
impl<Result, Rhs: RhsOfSub<Result> > ops::Sub<Rhs, Result> for Point {
  fn sub(&self, rhs: &Rhs) -> Result {
    rhs.sub_lhs_to(self)
  }
}
// Multiplication
trait RhsOfMul<Result> {
  fn mul_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfMul<Point> for Point {
  fn mul_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self.x*lhs.x), y:(self.y*lhs.y)}
   }
}
impl RhsOfMul<Point> for f64 {
  fn mul_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self*lhs.x), y:(self*lhs.y)}
   }
}

impl<Result, Rhs: RhsOfMul<Result> > ops::Mul<Rhs, Result> for Point {
  fn mul(&self, rhs: &Rhs) -> Result {
    rhs.mul_lhs_to(self)
  }
}
// Division
trait RhsOfDiv<Result> {
  fn div_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfDiv<Point> for Point {
  fn div_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (lhs.x/self.x), y:(lhs.y/self.y)}
   }
}
impl RhsOfDiv<Point> for f64 {
  fn div_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (lhs.x/ *self), y:(lhs.y/ *self)}
   }
}
impl<Result, Rhs: RhsOfDiv<Result> > ops::Div<Rhs, Result> for Point {
  fn div(&self, rhs: &Rhs) -> Result {
    rhs.div_lhs_to(self)
  }
}

//
// * Test
//
#[test]
fn test_norm2() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let norm=pt1.norm2();

    assert!(norm==sqrt(5.0));
}

#[test]
fn test_dist() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: 2.0, y: 3.0};
    let distance=pt1.dist(pt2);

    assert!(distance==f64::sqrt(2.0));
}

#[test]
fn test_add() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=*pt1+*pt2;

    assert!((pt3.x==0.0)&&(pt3.y==5.0));
}

#[test]
fn test_add_float() {
    let pt1=Point{ x: 1.0, y: 2.0};
    let pt3=pt1+1.0f64;

    assert!((pt3.x==2.0)&&(pt3.y==3.0));
}

#[test]
fn test_sub() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=*pt1-*pt2;
    assert!((pt3.x==2.0)&&(pt3.y==-1.0));
}
fn test_sub_float() {
    let pt1=Point{ x: 1.0, y: 2.0};
    let pt3=pt1-0.5 as f64;
    assert!((pt3.x==0.5)&&(pt3.y==1.5));
}

#[test]
fn test_mult() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=(*pt1)*(*pt2);
    assert!((pt3.x==-1.0)&&(pt3.y==6.0));
    let pt4=(*pt1)*(2.0 as f64);
    assert!((pt4.x==2.0)&&(pt4.y==4.0));
}

#[test]
fn test_div() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=(*pt1)/(*pt2);
    assert!(pt3.dist(&Point{x:-1.0, y:2.0/3.0})==0.0);
    let pt4=(*pt1)/(2.0 as f64);
    assert!((pt4.x==0.5)&&(pt4.y==1.0));
}

#[test]
fn test_new_dir() {
    let pt = Point::new_dir();
    assert!(pt.norm2()==1.0);
}

#[test]
fn test_rand() {
    let pt1 : Point = rand::random();
    let pt2 : Point = rand::random();
    let pt3 : Point = rand::random();

    assert!(pt1 != pt2); assert!(pt1 != pt3); assert!(pt2 != pt3);
    assert!((pt1.x>=0.0)&&(pt1.y<=1.0));
}
<commit_msg>Un test plus résistant pour la normalisation<commit_after>use core::rand::*;
use core::f64::sqrt;
use core::f64::pow;

#[deriving(Eq)]
pub struct Point {
    x : f64,
    y : f64
}

pub impl Point {
    fn new() -> Point {
        Point{x:0.0, y:0.0}
    }

    fn new_dir() -> Point {
        let mut pt : Point =rand::random();
        pt-=0.5f64;
        pt/pt.norm2()
    }

    fn norm2(&self) -> f64 {
        sqrt(pow(self.x,2.0)+pow(self.y,2.0))
    }

    fn dist(&self, other : &Point) -> f64 {
        (*self-*other).norm2()
    }

}

impl ToStr for Point {
    fn to_str(&self) -> ~str {
        fmt!("(%f, %f)", self.x as float, self.y as float)
    }
}

//
// * Génération aléatoire
//
impl Rand for Point {
    fn rand<R: Rng>(rng: &mut R) -> Point {
        Point { x: rng.gen::<f64>(), y: rng.gen::<f64>()}
    }
}

//
// * Opérateurs arithmétiques
//
// Addition
trait RhsOfAdd<Result> {
  fn add_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfAdd<Point> for Point {
  fn add_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self.x+lhs.x), y:(self.y+lhs.y)}
   }
}
impl RhsOfAdd<Point> for f64 {
  fn add_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (*self+lhs.x), y:(*self+lhs.y)}
   }
}
impl<Result, Rhs: RhsOfAdd<Result> > ops::Add<Rhs, Result> for Point {
  fn add(&self, rhs: &Rhs) -> Result {
    rhs.add_lhs_to(self)
  }
}
// Soustraction
trait RhsOfSub<Result> {
  fn sub_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfSub<Point> for Point {
  fn sub_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (-self.x+lhs.x), y:(-self.y+lhs.y)}
   }
}
impl RhsOfSub<Point> for f64 {
    fn sub_lhs_to(&self, lhs:&Point) -> Point {
        Point{x: lhs.x - *self, y: lhs.y-*self}
    }
}
impl<Result, Rhs: RhsOfSub<Result> > ops::Sub<Rhs, Result> for Point {
  fn sub(&self, rhs: &Rhs) -> Result {
    rhs.sub_lhs_to(self)
  }
}
// Multiplication
trait RhsOfMul<Result> {
  fn mul_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfMul<Point> for Point {
  fn mul_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self.x*lhs.x), y:(self.y*lhs.y)}
   }
}
impl RhsOfMul<Point> for f64 {
  fn mul_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self*lhs.x), y:(self*lhs.y)}
   }
}

impl<Result, Rhs: RhsOfMul<Result> > ops::Mul<Rhs, Result> for Point {
  fn mul(&self, rhs: &Rhs) -> Result {
    rhs.mul_lhs_to(self)
  }
}
// Division
trait RhsOfDiv<Result> {
  fn div_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfDiv<Point> for Point {
  fn div_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (lhs.x/self.x), y:(lhs.y/self.y)}
   }
}
impl RhsOfDiv<Point> for f64 {
  fn div_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (lhs.x/ *self), y:(lhs.y/ *self)}
   }
}
impl<Result, Rhs: RhsOfDiv<Result> > ops::Div<Rhs, Result> for Point {
  fn div(&self, rhs: &Rhs) -> Result {
    rhs.div_lhs_to(self)
  }
}

//
// * Test
//
#[test]
fn test_norm2() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let norm=pt1.norm2();

    assert!(norm==sqrt(5.0));
}

#[test]
fn test_dist() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: 2.0, y: 3.0};
    let distance=pt1.dist(pt2);

    assert!(distance==f64::sqrt(2.0));
}

#[test]
fn test_add() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=*pt1+*pt2;

    assert!((pt3.x==0.0)&&(pt3.y==5.0));
}

#[test]
fn test_add_float() {
    let pt1=Point{ x: 1.0, y: 2.0};
    let pt3=pt1+1.0f64;

    assert!((pt3.x==2.0)&&(pt3.y==3.0));
}

#[test]
fn test_sub() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=*pt1-*pt2;
    assert!((pt3.x==2.0)&&(pt3.y==-1.0));
}
fn test_sub_float() {
    let pt1=Point{ x: 1.0, y: 2.0};
    let pt3=pt1-0.5 as f64;
    assert!((pt3.x==0.5)&&(pt3.y==1.5));
}

#[test]
fn test_mult() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=(*pt1)*(*pt2);
    assert!((pt3.x==-1.0)&&(pt3.y==6.0));
    let pt4=(*pt1)*(2.0 as f64);
    assert!((pt4.x==2.0)&&(pt4.y==4.0));
}

#[test]
fn test_div() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=(*pt1)/(*pt2);
    assert!(pt3.dist(&Point{x:-1.0, y:2.0/3.0})==0.0);
    let pt4=(*pt1)/(2.0 as f64);
    assert!((pt4.x==0.5)&&(pt4.y==1.0));
}

#[test]
fn test_new_dir() {
    let pt = Point::new_dir();
    assert!((pt.norm2()-1.0).abs()<=1e-15f64);
}

#[test]
fn test_rand() {
    let pt1 : Point = rand::random();
    let pt2 : Point = rand::random();
    let pt3 : Point = rand::random();

    assert!(pt1 != pt2); assert!(pt1 != pt3); assert!(pt2 != pt3);
    assert!((pt1.x>=0.0)&&(pt1.y<=1.0));
}
<|endoftext|>


<commit_before>use std::{cell::RefCell, collections::BTreeMap, rc::Rc};

use dces::prelude::{Entity, EntityComponentManager};

use crate::{css_engine::*, prelude::*, render::*, shell::WindowShell, tree::Tree};

use super::{MessageBox, WidgetContainer};

/// The `Context` is provides access for the states to objects they could work with.
pub struct Context<'a> {
    ecm: &'a mut EntityComponentManager<Tree, StringComponentStore>,
    window_shell: &'a mut WindowShell<WindowAdapter>,
    pub entity: Entity,
    pub theme: &'a ThemeValue,
    render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
    layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
    handlers: EventHandlerMap,
    states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
    new_states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
}

impl<'a> Drop for Context<'a> {
    fn drop(&mut self) {
        self.states
            .borrow_mut()
            .append(&mut self.new_states.borrow_mut());
    }
}

impl<'a> Context<'a> {
    /// Creates a new container.
    pub fn new(
        ecs: (
            Entity,
            &'a mut EntityComponentManager<Tree, StringComponentStore>,
        ),
        window_shell: &'a mut WindowShell<WindowAdapter>,
        theme: &'a ThemeValue,
        render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
        layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
        handlers: EventHandlerMap,
        states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
    ) -> Self {
        Context {
            entity: ecs.0,
            ecm: ecs.1,
            window_shell,
            theme,
            render_objects,
            layouts,
            handlers,
            states,
            new_states: Rc::new(RefCell::new(BTreeMap::new())),
        }
    }

    // -- Widgets --

    /// Returns a specific widget.
    pub fn get_widget(&mut self, entity: Entity) -> WidgetContainer<'_> {
        WidgetContainer::new(entity, self.ecm, self.theme)
    }

    /// Returns the widget of the current state ctx.
    pub fn widget(&mut self) -> WidgetContainer<'_> {
        self.get_widget(self.entity)
    }

    /// Returns the window widget.
    pub fn window(&mut self) -> WidgetContainer<'_> {
        let root = self.ecm.entity_store().root;
        self.get_widget(root)
    }

    /// Returns a child of the widget of the current state referenced by css `id`.
    /// If the no id is defined its panics.
    pub fn child<'b>(&mut self, id: impl Into<&'b str>) -> WidgetContainer<'_> {
        self.entity_of_child(id)
            .map(move |child| self.get_widget(child))
            .unwrap()
    }

    /// Returns a child of the widget of the current state referenced by css `id`.
    /// If the no id is defined None will returned.
    pub fn try_child<'b>(&mut self, id: impl Into<&'b str>) -> Option<WidgetContainer<'_>> {
        self.entity_of_child(id)
            .map(move |child| self.get_widget(child))
    }

    /// Returns the parent of the current widget.
    /// Panics if the parent does not exists.
    pub fn parent(&mut self) -> WidgetContainer<'_> {
        let entity = self.ecm.entity_store().parent[&self.entity].unwrap();
        self.get_widget(entity)
    }

    // Returns the parent of the current widget.
    /// If the current widget is the root None will be returned.
    pub fn try_parent(&mut self) -> Option<WidgetContainer<'_>> {
        if self.ecm.entity_store().parent[&self.entity] == None {
            return None;
        }

        let entity = self.ecm.entity_store().parent[&self.entity].unwrap();

        Some(self.get_widget(entity))
    }

    /// Returns a parent of the widget of the current state referenced by css `id`.
    /// Panics if a parent with the given id could not be found
    pub fn parent_from_id<'b>(&mut self, id: impl Into<&'b str>) -> WidgetContainer<'_> {
        let mut current = self.entity;
        let id = id.into();

        while let Some(parent) = self.ecm.entity_store().parent[&current] {
            if let Ok(selector) = self
                .ecm
                .component_store()
                .get::<Selector>("selector", parent)
            {
                if let Some(parent_id) = &selector.id {
                    if parent_id == id {
                        return self.get_widget(parent);
                    }
                }
            }

            current = parent;
        }

        panic!(
            "Parent with id: {}, of child with entity: {} could not be found",
            id, self.entity.0
        );
    }

    /// Returns a parent of the widget of the current state referenced by css `id`.
    /// If the no id is defined None will returned.
    pub fn try_parent_from_id<'b>(
        &mut self,
        id: impl Into<&'b str>,
    ) -> Option<WidgetContainer<'_>> {
        let mut current = self.entity;
        let id = id.into();

        while let Some(parent) = self.ecm.entity_store().parent[&current] {
            if let Ok(selector) = self
                .ecm
                .component_store()
                .get::<Selector>("selector", parent)
            {
                if let Some(parent_id) = &selector.id {
                    if parent_id == id {
                        return Some(self.get_widget(parent));
                    }
                }
            }

            current = parent;
        }

        None
    }

    /// Returns the child of the current widget.
    /// Panics if a child on the given index could not be found.
    pub fn child_from_index(&mut self, index: usize) -> WidgetContainer<'_> {
        let entity = self.ecm.entity_store().children[&self.entity][index];
        self.get_widget(entity)
    }

    /// Returns the child of the current widget.
    /// If the index is out of the children index bounds or the widget has no children None will be returned.
    pub fn try_child_from_index(&mut self, index: usize) -> Option<WidgetContainer<'_>> {
        if index >= self.ecm.entity_store().children[&self.entity].len() {
            return None;
        }

        let entity = self.ecm.entity_store().children[&self.entity][index];

        Some(self.get_widget(entity))
    }

    // -- Widgets --

    // -- Manipulation --

    /// Returns the current build ctx.
    pub fn build_context(&mut self) -> BuildContext {
        BuildContext::new(
            self.ecm,
            self.render_objects.clone(),
            self.layouts.clone(),
            self.handlers.clone(),
            self.new_states.clone(),
        )
    }

    /// Appends a child widget to the given parent.
    pub fn append_child_to<W: Widget>(&mut self, child: W, parent: Entity) {
        let mut build_context = self.build_context();
        let child = child.build(&mut build_context);
        build_context.append_child(parent, child);
    }

    /// Appends a child widget by entity to the given parent.
    pub fn append_child_entity_to(&mut self, child: Entity, parent: Entity) {
        self.build_context().append_child(parent, child);
    }

    /// Appends a child to the current widget.
    pub fn append_child<W: Widget>(&mut self, child: W) {
        self.append_child_to(child, self.entity);
    }

    /// Appends a child widget by entity to the current widget.
    pub fn append_child_entity(&mut self, child: Entity) {
        self.append_child_entity_to(self.entity, child);
    }

    /// Clears all children of the current widget.
    pub fn clear_children(&mut self) {
        self.clear_children_of(self.entity);
    }

    /// Clears all children of the given widget.
    pub fn clear_children_of(&mut self, parent: Entity) {
        while !self.ecm.entity_store().children[&parent].is_empty() {
            let child = self.ecm.entity_store().children[&parent][0];

            self.ecm.remove_entity(child);
        }
    }

    // -- Manipulation --

    /// Returns the entity id of an child by the given name.
    pub fn entity_of_child<'b>(&mut self, id: impl Into<&'b str>) -> Option<Entity> {
        let id = id.into();

        let mut current_node = self.entity;

        loop {
            if let Ok(selector) = self
                .ecm
                .component_store()
                .get::<Selector>("selector", current_node)
            {
                if let Some(child_id) = &selector.id {
                    if child_id == id {
                        return Some(current_node);
                    }
                }
            }

            let mut it = self.ecm.entity_store().start_node(current_node).into_iter();
            it.next();

            if let Some(node) = it.next() {
                current_node = node;
            } else {
                break;
            }
        }

        None
    }

    /// Returns the entity of the parent referenced by css `element`.
    /// If the no id is defined None will returned.
    pub fn parent_entity_by_element<'b>(&mut self, element: impl Into<&'b str>) -> Option<Entity> {
        let mut current = self.entity;
        let element = element.into();

        while let Some(parent) = self.ecm.entity_store().parent[&current] {
            if let Ok(selector) = self
                .ecm
                .component_store()
                .get::<Selector>("selector", parent)
            {
                if let Some(parent_element) = &selector.element {
                    if parent_element == element
                        && self
                            .ecm
                            .component_store()
                            .is_origin::<Selector>("selector", parent)
                    {
                        return Some(parent);
                    }
                }
            }

            current = parent;
        }

        None
    }

    /// Returns the entity of the parent.
    pub fn entity_of_parent(&mut self) -> Option<Entity> {
        self.ecm.entity_store().parent[&self.entity]
    }

    /// Returns the child index of the current entity.
    pub fn index_as_child(&mut self, entity: Entity) -> Option<usize> {
        if let Some(parent) = self.ecm.entity_store().parent[&entity] {
            return self.ecm.entity_store().children[&parent]
                .iter()
                .position(|e| *e == entity);
        }

        None
    }

    /// Sends a message to the widget with the given id over the message channel.
    pub fn send_message(&mut self, target_widget: &str, message: impl Into<MessageBox>) {
        let mut entity = None;
        if let Ok(global) = self.ecm.component_store().get::<Global>("global", 0.into()) {
            if let Some(en) = global.id_map.get(target_widget) {
                entity = Some(*en);
            }
        }

        if let Some(entity) = entity {
            self.window_shell
                .adapter()
                .messages
                .entry(entity)
                .or_insert_with(Vec::new)
                .push(message.into());
        } else {
            println!(
                "Context send_message: widget id {} not found.",
                target_widget
            );
        }
    }

    /// Pushes an event to the event queue with the given `strategy`.
    pub fn push_event_strategy<E: Event>(&mut self, event: E, strategy: EventStrategy) {
        self.window_shell
            .adapter()
            .event_queue
            .register_event_with_strategy(event, strategy, self.entity);
    }

    /// Pushes an event to the event queue.
    pub fn push_event<E: Event>(&mut self, event: E) {
        self.window_shell
            .adapter()
            .event_queue
            .register_event(event, self.entity);
    }

    /// Pushes an event to the event queue.
    pub fn push_event_by_entity<E: Event>(&mut self, event: E, entity: Entity) {
        self.window_shell
            .adapter()
            .event_queue
            .register_event(event, entity);
    }

    /// Returns a mutable reference of the 2d render ctx.
    pub fn render_context_2_d(&mut self) -> &mut RenderContext2D {
        self.window_shell.render_context_2_d()
    }
}
<commit_msg>Add remove_child and remove_child_from to Context.<commit_after>use std::{cell::RefCell, collections::BTreeMap, rc::Rc};

use dces::prelude::{Entity, EntityComponentManager};

use crate::{css_engine::*, prelude::*, render::*, shell::WindowShell, tree::Tree};

use super::{MessageBox, WidgetContainer};

/// The `Context` is provides access for the states to objects they could work with.
pub struct Context<'a> {
    ecm: &'a mut EntityComponentManager<Tree, StringComponentStore>,
    window_shell: &'a mut WindowShell<WindowAdapter>,
    pub entity: Entity,
    pub theme: &'a ThemeValue,
    render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
    layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
    handlers: EventHandlerMap,
    states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
    new_states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
}

impl<'a> Drop for Context<'a> {
    fn drop(&mut self) {
        self.states
            .borrow_mut()
            .append(&mut self.new_states.borrow_mut());
    }
}

impl<'a> Context<'a> {
    /// Creates a new container.
    pub fn new(
        ecs: (
            Entity,
            &'a mut EntityComponentManager<Tree, StringComponentStore>,
        ),
        window_shell: &'a mut WindowShell<WindowAdapter>,
        theme: &'a ThemeValue,
        render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
        layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
        handlers: EventHandlerMap,
        states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
    ) -> Self {
        Context {
            entity: ecs.0,
            ecm: ecs.1,
            window_shell,
            theme,
            render_objects,
            layouts,
            handlers,
            states,
            new_states: Rc::new(RefCell::new(BTreeMap::new())),
        }
    }

    // -- Widgets --

    /// Returns a specific widget.
    pub fn get_widget(&mut self, entity: Entity) -> WidgetContainer<'_> {
        WidgetContainer::new(entity, self.ecm, self.theme)
    }

    /// Returns the widget of the current state ctx.
    pub fn widget(&mut self) -> WidgetContainer<'_> {
        self.get_widget(self.entity)
    }

    /// Returns the window widget.
    pub fn window(&mut self) -> WidgetContainer<'_> {
        let root = self.ecm.entity_store().root;
        self.get_widget(root)
    }

    /// Returns a child of the widget of the current state referenced by css `id`.
    /// If the no id is defined its panics.
    pub fn child<'b>(&mut self, id: impl Into<&'b str>) -> WidgetContainer<'_> {
        self.entity_of_child(id)
            .map(move |child| self.get_widget(child))
            .unwrap()
    }

    /// Returns a child of the widget of the current state referenced by css `id`.
    /// If the no id is defined None will returned.
    pub fn try_child<'b>(&mut self, id: impl Into<&'b str>) -> Option<WidgetContainer<'_>> {
        self.entity_of_child(id)
            .map(move |child| self.get_widget(child))
    }

    /// Returns the parent of the current widget.
    /// Panics if the parent does not exists.
    pub fn parent(&mut self) -> WidgetContainer<'_> {
        let entity = self.ecm.entity_store().parent[&self.entity].unwrap();
        self.get_widget(entity)
    }

    // Returns the parent of the current widget.
    /// If the current widget is the root None will be returned.
    pub fn try_parent(&mut self) -> Option<WidgetContainer<'_>> {
        if self.ecm.entity_store().parent[&self.entity] == None {
            return None;
        }

        let entity = self.ecm.entity_store().parent[&self.entity].unwrap();

        Some(self.get_widget(entity))
    }

    /// Returns a parent of the widget of the current state referenced by css `id`.
    /// Panics if a parent with the given id could not be found
    pub fn parent_from_id<'b>(&mut self, id: impl Into<&'b str>) -> WidgetContainer<'_> {
        let mut current = self.entity;
        let id = id.into();

        while let Some(parent) = self.ecm.entity_store().parent[&current] {
            if let Ok(selector) = self
                .ecm
                .component_store()
                .get::<Selector>("selector", parent)
            {
                if let Some(parent_id) = &selector.id {
                    if parent_id == id {
                        return self.get_widget(parent);
                    }
                }
            }

            current = parent;
        }

        panic!(
            "Parent with id: {}, of child with entity: {} could not be found",
            id, self.entity.0
        );
    }

    /// Returns a parent of the widget of the current state referenced by css `id`.
    /// If the no id is defined None will returned.
    pub fn try_parent_from_id<'b>(
        &mut self,
        id: impl Into<&'b str>,
    ) -> Option<WidgetContainer<'_>> {
        let mut current = self.entity;
        let id = id.into();

        while let Some(parent) = self.ecm.entity_store().parent[&current] {
            if let Ok(selector) = self
                .ecm
                .component_store()
                .get::<Selector>("selector", parent)
            {
                if let Some(parent_id) = &selector.id {
                    if parent_id == id {
                        return Some(self.get_widget(parent));
                    }
                }
            }

            current = parent;
        }

        None
    }

    /// Returns the child of the current widget.
    /// Panics if a child on the given index could not be found.
    pub fn child_from_index(&mut self, index: usize) -> WidgetContainer<'_> {
        let entity = self.ecm.entity_store().children[&self.entity][index];
        self.get_widget(entity)
    }

    /// Returns the child of the current widget.
    /// If the index is out of the children index bounds or the widget has no children None will be returned.
    pub fn try_child_from_index(&mut self, index: usize) -> Option<WidgetContainer<'_>> {
        if index >= self.ecm.entity_store().children[&self.entity].len() {
            return None;
        }

        let entity = self.ecm.entity_store().children[&self.entity][index];

        Some(self.get_widget(entity))
    }

    // -- Widgets --

    // -- Manipulation --

    /// Returns the current build ctx.
    pub fn build_context(&mut self) -> BuildContext {
        BuildContext::new(
            self.ecm,
            self.render_objects.clone(),
            self.layouts.clone(),
            self.handlers.clone(),
            self.new_states.clone(),
        )
    }

    /// Appends a child widget to the given parent.
    pub fn append_child_to<W: Widget>(&mut self, child: W, parent: Entity) {
        let mut build_context = self.build_context();
        let child = child.build(&mut build_context);
        build_context.append_child(parent, child);
    }

    /// Appends a child widget by entity to the given parent.
    pub fn append_child_entity_to(&mut self, child: Entity, parent: Entity) {
        self.build_context().append_child(parent, child);
    }

    /// Appends a child to the current widget.
    pub fn append_child<W: Widget>(&mut self, child: W) {
        self.append_child_to(child, self.entity);
    }

    /// Appends a child widget by entity to the current widget.
    pub fn append_child_entity(&mut self, child: Entity) {
        self.append_child_entity_to(self.entity, child);
    }

    /// Removes a child from the current widget. If the given entity is not a child
    /// of the given parent nothing will happen.
    pub fn remove_child(&mut self, child: Entity) {
        self.remove_child_from(child, self.entity);
    }

    /// Removes a child from the given parent. If the given entity is not a child
    /// of the given parent nothing will happen.
    pub fn remove_child_from(&mut self, child: Entity, parent: Entity) {
        if self.ecm.entity_store().children[&parent].contains(&child) {
            self.ecm.remove_entity(child);
        }
    }

    /// Clears all children of the current widget.
    pub fn clear_children(&mut self) {
        self.clear_children_of(self.entity);
    }

    /// Clears all children of the given widget.
    pub fn clear_children_of(&mut self, parent: Entity) {
        while !self.ecm.entity_store().children[&parent].is_empty() {
            let child = self.ecm.entity_store().children[&parent][0];

            self.ecm.remove_entity(child);
        }
    }

    // -- Manipulation --

    /// Returns the entity id of an child by the given name.
    pub fn entity_of_child<'b>(&mut self, id: impl Into<&'b str>) -> Option<Entity> {
        let id = id.into();

        let mut current_node = self.entity;

        loop {
            if let Ok(selector) = self
                .ecm
                .component_store()
                .get::<Selector>("selector", current_node)
            {
                if let Some(child_id) = &selector.id {
                    if child_id == id {
                        return Some(current_node);
                    }
                }
            }

            let mut it = self.ecm.entity_store().start_node(current_node).into_iter();
            it.next();

            if let Some(node) = it.next() {
                current_node = node;
            } else {
                break;
            }
        }

        None
    }

    /// Returns the entity of the parent referenced by css `element`.
    /// If the no id is defined None will returned.
    pub fn parent_entity_by_element<'b>(&mut self, element: impl Into<&'b str>) -> Option<Entity> {
        let mut current = self.entity;
        let element = element.into();

        while let Some(parent) = self.ecm.entity_store().parent[&current] {
            if let Ok(selector) = self
                .ecm
                .component_store()
                .get::<Selector>("selector", parent)
            {
                if let Some(parent_element) = &selector.element {
                    if parent_element == element
                        && self
                            .ecm
                            .component_store()
                            .is_origin::<Selector>("selector", parent)
                    {
                        return Some(parent);
                    }
                }
            }

            current = parent;
        }

        None
    }

    /// Returns the entity of the parent.
    pub fn entity_of_parent(&mut self) -> Option<Entity> {
        self.ecm.entity_store().parent[&self.entity]
    }

    /// Returns the child index of the current entity.
    pub fn index_as_child(&mut self, entity: Entity) -> Option<usize> {
        if let Some(parent) = self.ecm.entity_store().parent[&entity] {
            return self.ecm.entity_store().children[&parent]
                .iter()
                .position(|e| *e == entity);
        }

        None
    }

    /// Sends a message to the widget with the given id over the message channel.
    pub fn send_message(&mut self, target_widget: &str, message: impl Into<MessageBox>) {
        let mut entity = None;
        if let Ok(global) = self.ecm.component_store().get::<Global>("global", 0.into()) {
            if let Some(en) = global.id_map.get(target_widget) {
                entity = Some(*en);
            }
        }

        if let Some(entity) = entity {
            self.window_shell
                .adapter()
                .messages
                .entry(entity)
                .or_insert_with(Vec::new)
                .push(message.into());
        } else {
            println!(
                "Context send_message: widget id {} not found.",
                target_widget
            );
        }
    }

    /// Pushes an event to the event queue with the given `strategy`.
    pub fn push_event_strategy<E: Event>(&mut self, event: E, strategy: EventStrategy) {
        self.window_shell
            .adapter()
            .event_queue
            .register_event_with_strategy(event, strategy, self.entity);
    }

    /// Pushes an event to the event queue.
    pub fn push_event<E: Event>(&mut self, event: E) {
        self.window_shell
            .adapter()
            .event_queue
            .register_event(event, self.entity);
    }

    /// Pushes an event to the event queue.
    pub fn push_event_by_entity<E: Event>(&mut self, event: E, entity: Entity) {
        self.window_shell
            .adapter()
            .event_queue
            .register_event(event, entity);
    }

    /// Returns a mutable reference of the 2d render ctx.
    pub fn render_context_2_d(&mut self) -> &mut RenderContext2D {
        self.window_shell.render_context_2_d()
    }
}
<|endoftext|>


<commit_before><commit_msg>More compact debug format for Word<commit_after><|endoftext|>


<commit_before>extern crate "parser-combinators" as parser_combinators;

use self::parser_combinators::{try, between, spaces, parser, many, many1, digit, optional, hex_digit, not_followed_by, satisfy, Parser, ParserExt, ParseResult};
use self::parser_combinators::primitives::{State, Stream};
use super::ast::*;
use super::ast::ExprNode::*;
use std::str::FromStr;
use std::num::FromStrRadix;

fn sint_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        optional(satisfy(|c| c == '-'))
            .and(
                (satisfy(|c| c == '0')
                    .and(satisfy(|c| c == 'x' || c == 'X')))
                    .with(many1::<Vec<_>, _>(hex_digit()))
                    .map(|x| {
                        isize::from_str_radix(
                            x.iter()
                             .fold(
                                String::new(),
                                |mut s: String, i| { s.push(*i); s })
                             .as_slice(),
                        16).unwrap()
                    })
                .or( many1::<Vec<_>, _>(digit()).map(|x|
                    isize::from_str(x.iter().fold(
                        String::new(), |mut s: String, i| { s.push(*i); s })
                        .as_slice()
                    ).unwrap()
                    )
                )
                )
            .map(|x| {
                if let Some(sign) = x.0 {
                    let mut s = String::new();
                    s.push(sign);
                    s.push('1');
                    x.1 * isize::from_str(s.as_slice()).unwrap()
                } else {
                    x.1
                }
                })
            .skip(not_followed_by(satisfy(|c| c == 'u' || c == 'U' || c == '.')))
            .map(|x: isize| NumNode::IntConst(IntNode{value: x}))
            .parse_state(input)
}

fn uint_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        (satisfy(|c| c == '0')
            .and(satisfy(|c| c == 'x' || c == 'X')))
            .with(many1::<Vec<_>, _>(hex_digit()))
            .map(|x| usize::from_str_radix(
                    x.iter()
                     .fold(
                        String::new(),
                        |mut s: String, i| { s.push(*i); s })
                     .as_slice(),
                16).unwrap()
            )
        .or( many1::<Vec<_>, _>(digit())
            .map(|x|usize::from_str(x.iter().fold(
                String::new(), |mut s: String, i| { s.push(*i); s })
                .as_slice()
            ).unwrap())
        )
        .skip(satisfy(|c| c == 'u' || c == 'U'))
        .map(|x: usize| NumNode::UIntConst(UIntNode{value: x}))
        .parse_state(input)
}

fn float_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        unimplemented!()
}

pub fn number<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        try(parser(sint_const))
            .or(try(parser(uint_const)))
            .or(try(parser(float_const)))
            .parse_state(input)
}

pub fn name<I>(input: State<I>) -> ParseResult<NameNode, I>
    where I: Stream<Item=char> {
         let initial = satisfy(|c|
            c.is_alphabetic()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?');
        let subsequent = satisfy(|c|
            c.is_alphanumeric()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?'
                // R6RS 'special subsequent' characters
                || c == '+' || c == '-' || c == '.' || c == '@');
        initial
            .and(many::<Vec<_>, _>(subsequent).map(|it|
                it.iter().fold(
                    String::new(),
                    |mut s: String, i| {
                        s.push(*i);
                        s
                    }
                    )
                ))
            .parse_state(input)
            .map(|x| {
                let mut s = String::new();
                s.push((x.0).0);
                s.push_str(&(x.0).1);
                (NameNode{ name: s}, x.1)
            })
}

pub fn expr<I>(input: State<I>) -> ParseResult<ExprNode, I>
    where I: Stream<Item=char> {
        let spaces = spaces();
        let sexpr = between(
            satisfy(|c| c == '('),
            satisfy(|c| c == ')'),
            parser(name)
                .and(many(parser(expr)))
                .map(|x| {
                    SExpr(SExprNode {
                        operator: x.0,
                        operands: x.1
                    })
                })
            );
        spaces.clone().with(
            sexpr
                .or(parser(name).map(Name))
            ).parse_state(input)
}

#[cfg(test)]
mod tests {
    use ::ast::*;
    use ::ast::ExprNode::*;
    use super::*;
    use super::parser_combinators::{Parser,parser};

    #[test]
    fn test_basic_ident() {
        assert_eq!(
            parser(expr).parse("ident").unwrap(),
            (Name(NameNode { name: "ident".to_string() }), "")
            );
    }

    #[test]
    fn test_basic_sexpr() {
        assert_eq!(
            parser(expr).parse("(ident arg1 arg2)").unwrap(),
            (SExpr(SExprNode {
                operator: NameNode { name: "ident".to_string() },
                operands: vec![
                    Name(NameNode { name: "arg1".to_string() }),
                    Name(NameNode { name: "arg2".to_string() })
                ]
            }), "")
            );
    }

    #[test]
    fn test_parse_sint_pos() {
        assert_eq!(
            parser(number).parse("1234"),
            Ok((NumNode::IntConst(IntNode { value: 1234isize }), ""))
            );
    }

    #[test]
    fn test_parse_sint_neg() {
        assert_eq!(
            parser(number).parse("-1234"),
            Ok((NumNode::IntConst(IntNode { value: -1234isize }), ""))
            );
    }

    #[test]
    fn test_parse_sint_hex() {
        assert_eq!(
            parser(number).parse("0x0ff"),
            Ok((NumNode::IntConst(IntNode { value: 0x0ffisize }), ""))
            );
        assert_eq!(
            parser(number).parse("0X0FF"),
            Ok((NumNode::IntConst(IntNode { value: 0x0ffisize }), ""))
            );
    }
    /*
    #[test]
    fn test_parse_sint_bin_upper() {
        assert_eq!(
            parser(number).parse("0B01"),
            Ok((NumNode::IntConst(IntNode { value: 0b01isize }), ""))
            );
        assert_eq!(
            parser(number).parse("0b01"),
            Ok((NumNode::IntConst(IntNode { value: 0b01isize }), ""))
            );
    }*/

    #[test]
    fn test_parse_uint() {
        assert_eq!(
            parser(number).parse("1234u"),
            Ok((NumNode::UIntConst(UIntNode { value: 1234usize }), ""))
            );
        assert_eq!(
            parser(number).parse("4321U"),
            Ok((NumNode::UIntConst(UIntNode { value: 4321usize }), ""))
            );
    }

    #[test]
    fn test_parse_uint_hex() {
        assert_eq!(
            parser(number).parse("0x0ffu"),
            Ok((NumNode::UIntConst(UIntNode { value: 0x0ffusize }), ""))
            );
        assert_eq!(
            parser(number).parse("0X0FFu"),
            Ok((NumNode::UIntConst(UIntNode { value: 0x0ffusize }), ""))
            );
    }

    #[test]
    fn test_parse_float() {
        assert_eq!(
            parser(number).parse("1.0").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
            );
        assert_eq!(
            parser(number).parse("1f").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
            );
        assert_eq!(
            parser(number).parse("22.2222").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
            );
        assert_eq!(
            parser(number).parse("22.2222f").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
            );
    }

}
<commit_msg>Implement lexer for float constants<commit_after>extern crate "parser-combinators" as parser_combinators;

use self::parser_combinators::{try, between, spaces, parser, many, many1, digit, optional, hex_digit, not_followed_by, satisfy, Parser, ParserExt, ParseResult};
use self::parser_combinators::primitives::{State, Stream};
use super::ast::*;
use super::ast::ExprNode::*;
use std::str::FromStr;
use std::num::FromStrRadix;

fn sint_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        optional(satisfy(|c| c == '-'))
            .and(
                (satisfy(|c| c == '0')
                    .and(satisfy(|c| c == 'x' || c == 'X')))
                    .with(many1::<Vec<_>, _>(hex_digit()))
                    .map(|x| {
                        isize::from_str_radix(
                            x.iter()
                             .fold(
                                String::new(),
                                |mut s: String, i| { s.push(*i); s })
                             .as_slice(),
                        16).unwrap()
                    })
                .or( many1::<Vec<_>, _>(digit()).map(|x|
                    isize::from_str(x.iter().fold(
                        String::new(), |mut s: String, i| { s.push(*i); s })
                        .as_slice()
                    ).unwrap()
                    )
                )
                )
            .map(|x| {
                if let Some(sign) = x.0 {
                    let mut s = String::new();
                    s.push(sign);
                    s.push('1');
                    x.1 * isize::from_str(s.as_slice()).unwrap()
                } else {
                    x.1
                }
                })
            .skip(not_followed_by(satisfy(|c|
                c == 'u' || c == 'U' || c == '.' || c == 'f' || c == 'F')
            ))
            .map(|x: isize| NumNode::IntConst(IntNode{value: x}))
            .parse_state(input)
}

fn uint_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        (satisfy(|c| c == '0')
            .and(satisfy(|c| c == 'x' || c == 'X')))
            .with(many1::<Vec<_>, _>(hex_digit()))
            .map(|x| usize::from_str_radix(
                    x.iter()
                     .fold(
                        String::new(),
                        |mut s: String, i| { s.push(*i); s })
                     .as_slice(),
                16).unwrap()
            )
        .or( many1::<Vec<_>, _>(digit())
            .map(|x|usize::from_str(x.iter().fold(
                String::new(), |mut s: String, i| { s.push(*i); s })
                .as_slice()
            ).unwrap())
        )
        .skip(satisfy(|c| c == 'u' || c == 'U'))
        .map(|x: usize| NumNode::UIntConst(UIntNode{value: x}))
        .parse_state(input)
}

fn float_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        many1::<Vec<_>, _>(digit())
            .and(satisfy(|c| c == '.'))
            .and(many1::<Vec<_>, _>(digit()))
            .map(|x| {
                let mut s = String::new();
                for i in (x.0).0.iter() { s.push(*i); } ;
                s.push((x.0).1);

                for i in x.1.iter() { s.push(*i); };
                NumNode::FloatConst(FloatNode{
                    value: f64::from_str(s.as_slice()).unwrap()
                })
            })
            .skip(optional(satisfy(|c| c == 'f' || c == 'F')))
            .parse_state(input)
}

pub fn number<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        try(parser(sint_const))
            .or(try(parser(uint_const)))
            .or(try(parser(float_const)))
            .parse_state(input)
}

pub fn name<I>(input: State<I>) -> ParseResult<NameNode, I>
    where I: Stream<Item=char> {
         let initial = satisfy(|c|
            c.is_alphabetic()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?');
        let subsequent = satisfy(|c|
            c.is_alphanumeric()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?'
                // R6RS 'special subsequent' characters
                || c == '+' || c == '-' || c == '.' || c == '@');
        initial
            .and(many::<Vec<_>, _>(subsequent).map(|it|
                it.iter().fold(
                    String::new(),
                    |mut s: String, i| {
                        s.push(*i);
                        s
                    }
                    )
                ))
            .parse_state(input)
            .map(|x| {
                let mut s = String::new();
                s.push((x.0).0);
                s.push_str(&(x.0).1);
                (NameNode{ name: s}, x.1)
            })
}

pub fn expr<I>(input: State<I>) -> ParseResult<ExprNode, I>
    where I: Stream<Item=char> {
        let spaces = spaces();
        let sexpr = between(
            satisfy(|c| c == '('),
            satisfy(|c| c == ')'),
            parser(name)
                .and(many(parser(expr)))
                .map(|x| {
                    SExpr(SExprNode {
                        operator: x.0,
                        operands: x.1
                    })
                })
            );
        spaces.clone().with(
            sexpr
                .or(parser(name).map(Name))
            ).parse_state(input)
}

#[cfg(test)]
mod tests {
    use ::ast::*;
    use ::ast::ExprNode::*;
    use super::*;
    use super::parser_combinators::{Parser,parser};

    #[test]
    fn test_basic_ident() {
        assert_eq!(
            parser(expr).parse("ident").unwrap(),
            (Name(NameNode { name: "ident".to_string() }), "")
            );
    }

    #[test]
    fn test_basic_sexpr() {
        assert_eq!(
            parser(expr).parse("(ident arg1 arg2)").unwrap(),
            (SExpr(SExprNode {
                operator: NameNode { name: "ident".to_string() },
                operands: vec![
                    Name(NameNode { name: "arg1".to_string() }),
                    Name(NameNode { name: "arg2".to_string() })
                ]
            }), "")
            );
    }

    #[test]
    fn test_parse_sint_pos() {
        assert_eq!(
            parser(number).parse("1234"),
            Ok((NumNode::IntConst(IntNode { value: 1234isize }), ""))
            );
    }

    #[test]
    fn test_parse_sint_neg() {
        assert_eq!(
            parser(number).parse("-1234"),
            Ok((NumNode::IntConst(IntNode { value: -1234isize }), ""))
            );
    }

    #[test]
    fn test_parse_sint_hex() {
        assert_eq!(
            parser(number).parse("0x0ff"),
            Ok((NumNode::IntConst(IntNode { value: 0x0ffisize }), ""))
            );
        assert_eq!(
            parser(number).parse("0X0FF"),
            Ok((NumNode::IntConst(IntNode { value: 0x0ffisize }), ""))
            );
    }
    /* // Currently unsupported
    #[test]
    fn test_parse_sint_bin_upper() {
        assert_eq!(
            parser(number).parse("0B01"),
            Ok((NumNode::IntConst(IntNode { value: 0b01isize }), ""))
            );
        assert_eq!(
            parser(number).parse("0b01"),
            Ok((NumNode::IntConst(IntNode { value: 0b01isize }), ""))
            );
    }*/

    #[test]
    fn test_parse_uint() {
        assert_eq!(
            parser(number).parse("1234u"),
            Ok((NumNode::UIntConst(UIntNode { value: 1234usize }), ""))
            );
        assert_eq!(
            parser(number).parse("4321U"),
            Ok((NumNode::UIntConst(UIntNode { value: 4321usize }), ""))
            );
    }

    #[test]
    fn test_parse_uint_hex() {
        assert_eq!(
            parser(number).parse("0x0ffu"),
            Ok((NumNode::UIntConst(UIntNode { value: 0x0ffusize }), ""))
            );
        assert_eq!(
            parser(number).parse("0X0FFu"),
            Ok((NumNode::UIntConst(UIntNode { value: 0x0ffusize }), ""))
            );
    }

    #[test]
    fn test_parse_float() {
        assert_eq!(
            parser(number).parse("1.0").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
            );/* // Unsupported
        assert_eq!(
            parser(number).parse("1f").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
            );*/
        assert_eq!(
            parser(number).parse("22.2222").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
            );
        assert_eq!(
            parser(number).parse("22.2222f").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
            );
    }

}
<|endoftext|>