<commit_before>use yew::prelude::*;

use crate::{
    schema::{Field, Multiplicity, RUST_SCHEMA},
    types::*,
};

impl Model {
    pub fn view_actions(&self) -> Html {
        let actions = vec![
            Action {
                text: "store".to_string(),
                msg: Msg::Store,
            },
            Action {
                text: "load".to_string(),
                msg: Msg::Load,
            },
            Action {
                text: "prev".to_string(),
                msg: Msg::Prev,
            },
            Action {
                text: "next".to_string(),
                msg: Msg::Next,
            },
            Action {
                text: "parent".to_string(),
                msg: Msg::Parent,
            },
            Action {
                text: "+item".to_string(),
                msg: Msg::AddItem,
            },
            Action {
                text: "x".to_string(),
                msg: Msg::DeleteItem,
            },
        ];
        let actions = actions
            .iter()
            // .filter(|a| self.is_valid_action(a))
            .map(|a| self.view_action(a));

        html! {

                { for actions }

        }
    }

    pub fn current_field(&self) -> Option<&Field> {
        match self.cursor.back() {
            Some(selector) => {
                let parent = self.lookup(&self.parent_ref().unwrap()).unwrap();
                match &parent.value {
                    Value::Inner(v) => RUST_SCHEMA
                        .kinds
                        .iter()
                        .find(|k| k.name == v.kind)
                        .unwrap()
                        .fields
                        .iter()
                        .find(|f| f.name == selector.field),
                    _ => None,
                }
            }
            None => None,
        }
    }

    pub fn is_valid_value(&self, new_value: &Value) -> bool {
        self.current_field()
            .map(|field| field.type_.valid(new_value) && (field.validator)(new_value))
            .unwrap_or(false)
    }

    fn view_action(&self, action: &Action) -> Html {
        let msg = action.msg.clone();
        let callback = self.link.callback(move |_: MouseEvent| msg.clone());
        html! {
            <button
              class="action hover:bg-blue-200 hover:text-blue-800 group flex items-center rounded-md bg-blue-100 text-blue-600 text-sm font-medium px-4 py-2"
              onclick=callback>
                { &action.text }
            </button>
        }
    }

    pub fn view_file(&self, file: &File) -> Html {
        let node = self.view_node(&file.root, &Path::new());
        html! {

{ node }

        }
    }

    pub fn view_file_json(&self, file: &File) -> Html {
        let serialized = serde_json::to_string_pretty(file).expect("could not serialize to JSON");
        html! {

{ serialized }

        }
    }

    pub fn traverse_fields(kind: &str) -> &[Field] {
        match RUST_SCHEMA.kinds.iter().find(|k| k.name == kind) {
            Some(kind) => kind.fields,
            None => &[],
        }
    }

    pub fn flatten_paths(&self, reference: &Ref, base: Path) -> Vec<Path> {
        log::info!("flatten: {:?} {:?}", reference, base);
        match &self.lookup(reference) {
            Some(node) => match &node.value {
                Value::Inner(v) => {
                    let mut paths = vec![];
                    for field in Model::traverse_fields(v.kind.as_ref()) {
                        match field.multiplicity {
                            // If repeated field, stay on the parent.
                            Multiplicity::Repeated => {
                                let new_base = append(
                                    &base,
                                    Selector {
                                        field: field.name.to_string(),
                                        index: None,
                                    },
                                );
                                paths.push(new_base.clone());
                            }
                            // If single field, skip directly to the first (and only) child.
                            Multiplicity::Single => {}
                        }
                        let mut children = v.children.get(field.name).cloned().unwrap_or_default();
                        match field.multiplicity {
                            Multiplicity::Single => {
                                if children.is_empty() {
                                    children.push("dummy".to_string());
                                }
                            }
                            Multiplicity::Repeated => {}
                        };
                        for (n, child) in children.iter().enumerate() {
                            let new_base = append(
                                &base,
                                Selector {
                                    field: field.name.to_string(),
                                    index: Some(n),
                                },
                            );
                            paths.push(new_base.clone());
                            log::info!("child: {:?}[{:?}]->{:?}", reference, field.name, child);
                            paths.extend(self.flatten_paths(child, new_base));
                        }
                    }
                    paths
                }
                _ => vec![],
            },
            None => vec![],
        }
    }

    fn view_node_list(&self, references: &[Ref], path: &Path) -> Vec {
        let selected = path == &self.cursor;
        let mut classes = vec!["node".to_string()];
        if selected {
            classes.push("selected".to_string());
        }
        let mut nodes = references
            .iter()
            .enumerate()
            .map(|(i, n)| {
                let mut path = path.clone();
                let l = path.len();
                path[l - 1].index = Some(i);
                self.view_node(n, &path)
            })
            .collect::<Vec<_>>();
        let path = path.clone();
        let callback = self
            .link
            .callback(move |_: MouseEvent| Msg::Select(path.clone()));
        let head = html! {

{ "▷" }

        };
        nodes.insert(0, head);
        nodes
    }

    // fn view_node(&self, reference: &Ref, path: Path, cursor: Option<Path>) -> Html {
    fn view_node(&self, reference: &Ref, path: &Path) -> Html {
        let selected = path == &self.cursor;
        let mut classes = vec!["node".to_string()];
        if selected {
            classes.push("selected".to_string());
        }
        let path_clone = path.clone();
        let callback = self
            .link
            .callback(move |_: MouseEvent| Msg::Select(path_clone.clone()));
        let value = if reference == INVALID_REF {
            html! {
                { "◆" }
            }
        } else {
            match self.lookup(reference) {
                Some(node) => self.view_value(&node.reference, &node.value, &path),
                None => {
                    html! {
                        { format!("invalid: {}", reference) }
                    }
                }
            }
        };
        html! {

                { value }

        }
    }

    pub fn view_child(&self, value: &Inner, field_name: &str, path: &Path) -> Html {
        let path = append(
            &path,
            Selector {
                field: field_name.to_string(),
                index: Some(0),
            },
        );
        match value.children.get(field_name).and_then(|v| v.get(0)) {
            Some(n) => self.view_node(n, &path),
            // Empty list vs hole vs special value?
            // TODO: How to traverse nested lists in preorder?
            None => self.view_node(&"-".to_string(), &path),
            // None => self.view_node_list(&[], &path),
        }
    }

    pub fn view_children(&self, value: &Inner, field_name: &str, path: &Path) -> Vec {
        let path = append(&path, field(field_name));
        // let cursor = sub_cursor(&cursor, field(field_name));
        let empty = vec![];
        let children = value.children.get(field_name).unwrap_or(&empty);
        self.view_node_list(&children, &path)
    }

    fn view_value(&self, reference: &Ref, value: &Value, path: &Path) -> Html {
        match value {
            Value::Hole => {
                html! { { "◆" } }
            }
            Value::Bool(v) => {
                let v = if *v { "true" } else { "false" };
                html! { { v } }
            }
            Value::Int(v) => {
                let v = format!("{}", v);
                html! { { v } }
            }
            Value::Float(v) => {
                let v = format!("{}", v);
                html! { { v } }
            }
            Value::String(v) => {
                html! { { v } }
            }
            Value::Inner(v) => match RUST_SCHEMA.kinds.iter().find(|k| k.name == v.kind) {
                Some(kind) => (kind.renderer)(self, v, path),
                None => html! { { v.kind.clone() } },
            },
        }
    }
}
<commit_msg>remove unnecessary ref<commit_after>use yew::prelude::*;

use crate::{
    schema::{Field, Multiplicity, RUST_SCHEMA},
    types::*,
};

impl Model {
    pub fn view_actions(&self) -> Html {
        let actions = vec![
            Action {
                text: "store".to_string(),
                msg: Msg::Store,
            },
            Action {
                text: "load".to_string(),
                msg: Msg::Load,
            },
            Action {
                text: "prev".to_string(),
                msg: Msg::Prev,
            },
            Action {
                text: "next".to_string(),
                msg: Msg::Next,
            },
            Action {
                text: "parent".to_string(),
                msg: Msg::Parent,
            },
            Action {
                text: "+item".to_string(),
                msg: Msg::AddItem,
            },
            Action {
                text: "x".to_string(),
                msg: Msg::DeleteItem,
            },
        ];
        let actions = actions
            .iter()
            // .filter(|a| self.is_valid_action(a))
            .map(|a| self.view_action(a));

        html! {

                { for actions }

        }
    }

    pub fn current_field(&self) -> Option<&Field> {
        match self.cursor.back() {
            Some(selector) => {
                let parent = self.lookup(&self.parent_ref().unwrap()).unwrap();
                match &parent.value {
                    Value::Inner(v) => RUST_SCHEMA
                        .kinds
                        .iter()
                        .find(|k| k.name == v.kind)
                        .unwrap()
                        .fields
                        .iter()
                        .find(|f| f.name == selector.field),
                    _ => None,
                }
            }
            None => None,
        }
    }

    pub fn is_valid_value(&self, new_value: &Value) -> bool {
        self.current_field()
            .map(|field| field.type_.valid(new_value) && (field.validator)(new_value))
            .unwrap_or(false)
    }

    fn view_action(&self, action: &Action) -> Html {
        let msg = action.msg.clone();
        let callback = self.link.callback(move |_: MouseEvent| msg.clone());
        html! {
            <button
              class="action hover:bg-blue-200 hover:text-blue-800 group flex items-center rounded-md bg-blue-100 text-blue-600 text-sm font-medium px-4 py-2"
              onclick=callback>
                { &action.text }
            </button>
        }
    }

    pub fn view_file(&self, file: &File) -> Html {
        let node = self.view_node(&file.root, &Path::new());
        html! {

{ node }

        }
    }

    pub fn view_file_json(&self, file: &File) -> Html {
        let serialized = serde_json::to_string_pretty(file).expect("could not serialize to JSON");
        html! {

{ serialized }

        }
    }

    pub fn traverse_fields(kind: &str) -> &[Field] {
        match RUST_SCHEMA.kinds.iter().find(|k| k.name == kind) {
            Some(kind) => kind.fields,
            None => &[],
        }
    }

    pub fn flatten_paths(&self, reference: &Ref, base: Path) -> Vec<Path> {
        log::info!("flatten: {:?} {:?}", reference, base);
        match &self.lookup(reference) {
            Some(node) => match &node.value {
                Value::Inner(v) => {
                    let mut paths = vec![];
                    for field in Model::traverse_fields(v.kind.as_ref()) {
                        match field.multiplicity {
                            // If repeated field, stay on the parent.
                            Multiplicity::Repeated => {
                                let new_base = append(
                                    &base,
                                    Selector {
                                        field: field.name.to_string(),
                                        index: None,
                                    },
                                );
                                paths.push(new_base.clone());
                            }
                            // If single field, skip directly to the first (and only) child.
                            Multiplicity::Single => {}
                        }
                        let mut children = v.children.get(field.name).cloned().unwrap_or_default();
                        match field.multiplicity {
                            Multiplicity::Single => {
                                if children.is_empty() {
                                    children.push("dummy".to_string());
                                }
                            }
                            Multiplicity::Repeated => {}
                        };
                        for (n, child) in children.iter().enumerate() {
                            let new_base = append(
                                &base,
                                Selector {
                                    field: field.name.to_string(),
                                    index: Some(n),
                                },
                            );
                            paths.push(new_base.clone());
                            log::info!("child: {:?}[{:?}]->{:?}", reference, field.name, child);
                            paths.extend(self.flatten_paths(child, new_base));
                        }
                    }
                    paths
                }
                _ => vec![],
            },
            None => vec![],
        }
    }

    fn view_node_list(&self, references: &[Ref], path: &Path) -> Vec {
        let selected = path == &self.cursor;
        let mut classes = vec!["node".to_string()];
        if selected {
            classes.push("selected".to_string());
        }
        let mut nodes = references
            .iter()
            .enumerate()
            .map(|(i, n)| {
                let mut path = path.clone();
                let l = path.len();
                path[l - 1].index = Some(i);
                self.view_node(n, &path)
            })
            .collect::<Vec<_>>();
        let path = path.clone();
        let callback = self
            .link
            .callback(move |_: MouseEvent| Msg::Select(path.clone()));
        let head = html! {

{ "▷" }

        };
        nodes.insert(0, head);
        nodes
    }

    // fn view_node(&self, reference: &Ref, path: Path, cursor: Option<Path>) -> Html {
    fn view_node(&self, reference: &Ref, path: &Path) -> Html {
        let selected = path == &self.cursor;
        let mut classes = vec!["node".to_string()];
        if selected {
            classes.push("selected".to_string());
        }
        let path_clone = path.clone();
        let callback = self
            .link
            .callback(move |_: MouseEvent| Msg::Select(path_clone.clone()));
        let value = if reference == INVALID_REF {
            html! {
                { "◆" }
            }
        } else {
            match self.lookup(reference) {
                Some(node) => self.view_value(&node.value, &path),
                None => {
                    html! {
                        { format!("invalid: {}", reference) }
                    }
                }
            }
        };
        html! {

                { value }

        }
    }

    pub fn view_child(&self, value: &Inner, field_name: &str, path: &Path) -> Html {
        let path = append(
            &path,
            Selector {
                field: field_name.to_string(),
                index: Some(0),
            },
        );
        match value.children.get(field_name).and_then(|v| v.get(0)) {
            Some(n) => self.view_node(n, &path),
            // Empty list vs hole vs special value?
            // TODO: How to traverse nested lists in preorder?
            None => self.view_node(&"-".to_string(), &path),
            // None => self.view_node_list(&[], &path),
        }
    }

    pub fn view_children(&self, value: &Inner, field_name: &str, path: &Path) -> Vec {
        let path = append(&path, field(field_name));
        // let cursor = sub_cursor(&cursor, field(field_name));
        let empty = vec![];
        let children = value.children.get(field_name).unwrap_or(&empty);
        self.view_node_list(&children, &path)
    }

    fn view_value(&self, value: &Value, path: &Path) -> Html {
        match value {
            Value::Hole => {
                html! { { "◆" } }
            }
            Value::Bool(v) => {
                let v = if *v { "true" } else { "false" };
                html! { { v } }
            }
            Value::Int(v) => {
                let v = format!("{}", v);
                html! { { v } }
            }
            Value::Float(v) => {
                let v = format!("{}", v);
                html! { { v } }
            }
            Value::String(v) => {
                html! { { v } }
            }
            Value::Inner(v) => match RUST_SCHEMA.kinds.iter().find(|k| k.name == v.kind) {
                Some(kind) => (kind.renderer)(self, v, path),
                None => html! { { v.kind.clone() } },
            },
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::io::{Cursor, Read};
use super::{Dictionary, Stream};

#[derive(Debug, Clone)]
pub struct Xref {
	/// Entries for indirect object.
	pub entries: BTreeMap<u32, XrefEntry>,

	/// Total number of entries (including free entries), equal to the highest object number plus 1.
	pub size: u32,
}

#[derive(Debug, Clone)]
pub enum XrefEntry {
	Free,
	Normal { offset: u32, generation: u16 },
	Compressed { container: u32, index: u16 },
}

impl Xref {
	pub fn new(size: u32) -> Xref {
		Xref { entries: BTreeMap::new(), size }
	}

	pub fn get(&self, id: u32) -> Option<&XrefEntry> {
		self.entries.get(&id)
	}

	pub fn insert(&mut self, id: u32, entry: XrefEntry) {
		self.entries.insert(id, entry);
	}

	pub fn extend(&mut self, xref: Xref) {
		self.entries.extend(xref.entries);
	}

	pub fn clear(&mut self) {
		self.entries.clear()
	}
}

use self::XrefEntry::*;
impl XrefEntry {
	pub fn is_normal(&self) -> bool {
		match *self {
			Normal{..} => true,
			_ => false
		}
	}

	pub fn is_compressed(&self) -> bool {
		match *self {
			Compressed{..} => true,
			_ => false
		}
	}
}

pub fn decode_xref_stream(mut stream: Stream) -> (Xref, Dictionary) {
	stream.decompress();
	let mut dict = stream.dict;
	let mut reader = Cursor::new(stream.content);
	let size = dict.get("Size").and_then(|size| size.as_i64()).expect("Size is absent in trailer.");
	let mut xref = Xref::new(size as u32);
	{
		let section_indice = dict.get("Index")
			.and_then(|obj| obj.as_array())
			.map(|array| array.iter().map(|n| n.as_i64().unwrap()).collect())
			.unwrap_or(vec![0, size]);
		let field_widths: Vec<usize> = dict.get("W")
			.and_then(|obj| obj.as_array())
			.map(|array| array.iter().map(|n| n.as_i64().unwrap() as usize).collect())
			.expect("W is absent in trailer.");
		let mut bytes1 = vec![0_u8; field_widths[0]];
		let mut bytes2 = vec![0_u8; field_widths[1]];
		let mut bytes3 = vec![0_u8; field_widths[2]];

		for i in 0..section_indice.len() / 2 {
			let start = section_indice[2 * i];
			let count = section_indice[2 * i + 1];

			for j in 0..count {
				let entry_type = if bytes1.len() > 0 {
					read_big_endian_interger(&mut reader, bytes1.as_mut_slice())
				} else {
					1
				};
				match entry_type {
					0 => { //free object
						read_big_endian_interger(&mut reader, bytes2.as_mut_slice());
						read_big_endian_interger(&mut reader, bytes3.as_mut_slice());
					},
					1 => { //normal object
						let offset = read_big_endian_interger(&mut reader, bytes2.as_mut_slice());
						let generation = if bytes3.len() > 0 {
							read_big_endian_interger(&mut reader, bytes3.as_mut_slice())
						} else {
							0
						} as u16;
						xref.insert((start + j) as u32, XrefEntry::Normal { offset: offset, generation: generation });
					},
					2 => { //compressed object
						let container = read_big_endian_interger(&mut reader, bytes2.as_mut_slice());
						let index = read_big_endian_interger(&mut reader, bytes3.as_mut_slice()) as u16;
						xref.insert((start + j) as u32, XrefEntry::Compressed { container: container, index: index });
					},
					_ => {}
				}
			}
		}
	}
	dict.remove("Length");
	dict.remove("W");
	dict.remove("Index");
	(xref, dict)
}

fn read_big_endian_interger(reader: &mut Cursor<Vec<u8>>, buffer: &mut [u8]) -> u32 {
	reader.read_exact(buffer).unwrap();
	let mut value = 0;
	for &mut byte in buffer {
		value = (value << 8) + byte as u32;
	}
	value
}

<commit_msg>Fix bug in reading incremental updated document<commit_after>use std::collections::BTreeMap;
use std::io::{Cursor, Read};
use super::{Dictionary, Stream};

#[derive(Debug, Clone)]
pub struct Xref {
	/// Entries for indirect object.
	pub entries: BTreeMap<u32, XrefEntry>,

	/// Total number of entries (including free entries), equal to the highest object number plus 1.
	pub size: u32,
}

#[derive(Debug, Clone)]
pub enum XrefEntry {
	Free,
	Normal { offset: u32, generation: u16 },
	Compressed { container: u32, index: u16 },
}

impl Xref {
	pub fn new(size: u32) -> Xref {
		Xref { entries: BTreeMap::new(), size }
	}

	pub fn get(&self, id: u32) -> Option<&XrefEntry> {
		self.entries.get(&id)
	}

	pub fn insert(&mut self, id: u32, entry: XrefEntry) {
		self.entries.insert(id, entry);
	}

	pub fn extend(&mut self, xref: Xref) {
		for (id, entry) in xref.entries {
			if !self.entries.contains_key(&id) {
				self.entries.insert(id, entry);
			}
		}
	}

	pub fn clear(&mut self) {
		self.entries.clear()
	}
}

use self::XrefEntry::*;
impl XrefEntry {
	pub fn is_normal(&self) -> bool {
		match *self {
			Normal{..} => true,
			_ => false
		}
	}

	pub fn is_compressed(&self) -> bool {
		match *self {
			Compressed{..} => true,
			_ => false
		}
	}
}

pub fn decode_xref_stream(mut stream: Stream) -> (Xref, Dictionary) {
	stream.decompress();
	let mut dict = stream.dict;
	let mut reader = Cursor::new(stream.content);
	let size = dict.get("Size").and_then(|size| size.as_i64()).expect("Size is absent in trailer.");
	let mut xref = Xref::new(size as u32);
	{
		let section_indice = dict.get("Index")
			.and_then(|obj| obj.as_array())
			.map(|array| array.iter().map(|n| n.as_i64().unwrap()).collect())
			.unwrap_or(vec![0, size]);
		let field_widths: Vec<usize> = dict.get("W")
			.and_then(|obj| obj.as_array())
			.map(|array| array.iter().map(|n| n.as_i64().unwrap() as usize).collect())
			.expect("W is absent in trailer.");
		let mut bytes1 = vec![0_u8; field_widths[0]];
		let mut bytes2 = vec![0_u8; field_widths[1]];
		let mut bytes3 = vec![0_u8; field_widths[2]];

		for i in 0..section_indice.len() / 2 {
			let start = section_indice[2 * i];
			let count = section_indice[2 * i + 1];

			for j in 0..count {
				let entry_type = if bytes1.len() > 0 {
					read_big_endian_interger(&mut reader, bytes1.as_mut_slice())
				} else {
					1
				};
				match entry_type {
					0 => { //free object
						read_big_endian_interger(&mut reader, bytes2.as_mut_slice());
						read_big_endian_interger(&mut reader, bytes3.as_mut_slice());
					},
					1 => { //normal object
						let offset = read_big_endian_interger(&mut reader, bytes2.as_mut_slice());
						let generation = if bytes3.len() > 0 {
							read_big_endian_interger(&mut reader, bytes3.as_mut_slice())
						} else {
							0
						} as u16;
						xref.insert((start + j) as u32, XrefEntry::Normal { offset: offset, generation: generation });
					},
					2 => { //compressed object
						let container = read_big_endian_interger(&mut reader, bytes2.as_mut_slice());
						let index = read_big_endian_interger(&mut reader, bytes3.as_mut_slice()) as u16;
						xref.insert((start + j) as u32, XrefEntry::Compressed { container: container, index: index });
					},
					_ => {}
				}
			}
		}
	}
	dict.remove("Length");
	dict.remove("W");
	dict.remove("Index");
	(xref, dict)
}

fn read_big_endian_interger(reader: &mut Cursor<Vec<u8>>, buffer: &mut [u8]) -> u32 {
	reader.read_exact(buffer).unwrap();
	let mut value = 0;
	for &mut byte in buffer {
		value = (value << 8) + byte as u32;
	}
	value
}

<|endoftext|>


<commit_before>//! A collection of methods that modify the background of the outputs.
use super::super::{Container, ContainerType, LayoutTree, TreeError,
                   MaybeBackground, IncompleteBackground};
use super::super::commands::CommandResult;

use uuid::Uuid;
use wayland_sys::server::wl_client;
use rustwlc::WlcView;
use rustwlc::wayland::wlc_view_get_wl_client;

impl LayoutTree {
    /// Attempts to attach the `bg` to the `outputs`.
    ///
    /// If any of them already have a background attached,
    pub fn attach_background(&mut self, bg: WlcView, output_id: Uuid)
                             -> Result<bool, TreeError> {
        match *self.lookup_mut(output_id)? {
            Container::Output { ref mut background, .. } => {
                match *background {
                    None => {
                        // The background wasn't expecting it
                        Ok(false)
                    }
                    Some(MaybeBackground::Incomplete(incomplete)) => {
                        let client: *mut wl_client;
                        unsafe {
                            client = wlc_view_get_wl_client(bg.0 as _) as _;
                        }
                        *background = Some(incomplete.build(client, bg));
                        Ok(match background.unwrap() {
                            MaybeBackground::Incomplete(_) => false,
                            MaybeBackground::Complete(_) => true,
                        })
                    },
                    // TODO Allow hot-reloading like before? Should probably implement that...
                    _ => {Ok(false)}
                }
            },
            _ => Err(TreeError::UuidWrongType(output_id,
                                              vec![ContainerType::Output]))
        }
    }

    pub fn attach_incomplete_background(&mut self,
                                        bg: IncompleteBackground,
                                        output_id: Uuid) -> CommandResult {
        match *self.lookup_mut(output_id)? {
            Container::Output { ref mut background, .. } => {
                match *background {
                    None => {
                        *background = Some(bg.into());
                        Ok(())
                    },
                    _ => unimplemented!()
                }
            },
            _ => Err(TreeError::UuidWrongType(output_id,
                                              vec![ContainerType::Output]))
        }
    }
}
<commit_msg>Handle hotloading<commit_after>//! A collection of methods that modify the background of the outputs.
use super::super::{Container, ContainerType, LayoutTree, TreeError,
                   MaybeBackground, IncompleteBackground};
use super::super::commands::CommandResult;

use uuid::Uuid;
use wayland_sys::server::wl_client;
use rustwlc::WlcView;
use rustwlc::wayland::wlc_view_get_wl_client;

impl LayoutTree {
    /// Attempts to attach the `bg` to the `outputs`.
    ///
    /// If any of them already have a background attached,
    pub fn attach_background(&mut self, bg: WlcView, output_id: Uuid)
                             -> Result<bool, TreeError> {
        match *self.lookup_mut(output_id)? {
            Container::Output { ref mut background, .. } => {
                match *background {
                    None => {
                        // The background wasn't expecting it
                        Ok(false)
                    }
                    Some(MaybeBackground::Incomplete(incomplete)) => {
                        let client: *mut wl_client;
                        unsafe {
                            client = wlc_view_get_wl_client(bg.0 as _) as _;
                        }
                        *background = Some(incomplete.build(client, bg));
                        Ok(match background.unwrap() {
                            MaybeBackground::Incomplete(_) => false,
                            MaybeBackground::Complete(_) => true,
                        })
                    },
                    _ => Ok(false)
                }
            },
            _ => Err(TreeError::UuidWrongType(output_id,
                                              vec![ContainerType::Output]))
        }
    }

    pub fn attach_incomplete_background(&mut self,
                                        bg: IncompleteBackground,
                                        output_id: Uuid) -> CommandResult {
        match *self.lookup_mut(output_id)? {
            Container::Output { ref mut background, .. } => {
                match *background {
                    None => {
                        *background = Some(bg.into());
                        Ok(())
                    },
                    Some(MaybeBackground::Complete(complete)) => {
                        complete.handle.close();
                        *background = Some(bg.into());
                        Ok(())
                    }
                    _ => {
                        warn!("Tried to set background while the other was still loading!");
                        Ok(())
                    }
                }
            },
            _ => Err(TreeError::UuidWrongType(output_id,
                                              vec![ContainerType::Output]))
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(clippy)]
#![allow(no_effect, unnecessary_operation)]
#![feature(proc_macro)]
extern crate descartes;
#[macro_use]
pub extern crate glium;
extern crate kay;
#[macro_use]
extern crate kay_macros;
extern crate glium_text;

pub use ::descartes::{N, P3, P2, V3, V4, M4, Iso3, Persp3, ToHomogeneous, Norm, Into2d, Into3d, WithUniqueOrthogonal, Inverse, Rotate};
use ::kay::{ID, Recipient, CVec, ActorSystem, Individual, Fate};
use std::collections::HashMap;

use glium::{index, Surface};
pub use glium::backend::glutin_backend::GlutinFacade;

pub struct Renderer {
    pub scenes: HashMap<usize, Scene>,
    pub render_context: RenderContext
}

impl Renderer {
    pub fn new (window: GlutinFacade) -> Renderer {
        Renderer {
            scenes: HashMap::new(),
            render_context: RenderContext::new(window)
        }
    }
}

impl Individual for Renderer {}

#[derive(Copy, Clone)]
pub enum Control {Setup, Render, Submit}

#[derive(Copy, Clone)]
pub struct SetupInScene {pub renderer_id: ID, pub scene_id: usize}

#[derive(Copy, Clone)]
pub struct RenderToScene {pub renderer_id: ID, pub scene_id: usize}

impl Recipient<Control> for Renderer {
    fn receive(&mut self, msg: &Control) -> Fate {match *msg {
        Control::Setup => {
            for (scene_id, scene) in &self.scenes {
                for renderable in &scene.renderables {
                    *renderable << SetupInScene{renderer_id: Self::id(), scene_id: *scene_id};
                }
            }
            Fate::Live
        },

        Control::Render => {
            for (scene_id, mut scene) in &mut self.scenes {
                for batch in (&mut scene).batches.values_mut() {
                    batch.instances.clear();
                }
                for renderable in &scene.renderables {
                    *renderable << RenderToScene{renderer_id: Self::id(), scene_id: *scene_id};
                }
            }
            Fate::Live
        }

        Control::Submit => {
            for scene in self.scenes.values() {
                self.render_context.submit(scene);
            }
            Fate::Live
        }
    }}
}

#[derive(Copy, Clone)]
pub struct MoveEye {pub scene_id: usize, pub delta: V3}

impl Recipient<MoveEye> for Renderer {
    fn receive(&mut self, msg: &MoveEye) -> Fate {match *msg{
        MoveEye{scene_id, delta} => {
            let eye = &mut self.scenes.get_mut(&scene_id).unwrap().eye;
            let eye_direction_2d = (eye.target - eye.position).into_2d().normalize();
            let absolute_delta = delta.x * eye_direction_2d.into_3d()
                + delta.y * eye_direction_2d.orthogonal().into_3d()
                + V3::new(0.0, 0.0, delta.z);
            eye.position += absolute_delta;
            eye.target += absolute_delta;
            Fate::Live
        }
    }}
}

#[derive(Compact, Clone)]
pub struct AddBatch {pub scene_id: usize, pub batch_id: usize, pub thing: Thing}

impl Recipient<AddBatch> for Renderer {
    fn receive(&mut self, msg: &AddBatch) -> Fate {match *msg {
        AddBatch{scene_id, batch_id, ref thing} => {
            self.scenes.get_mut(&scene_id).unwrap().batches.insert(batch_id, Batch::new(thing.clone(), Vec::new()));
            Fate::Live
        }
    }}
}

#[derive(Compact, Clone)]
pub struct UpdateThing {pub scene_id: usize, pub thing_id: usize, pub thing: Thing, pub instance: Instance}

impl Recipient<UpdateThing> for Renderer {
    fn receive(&mut self, msg: &UpdateThing) -> Fate {match *msg {
        UpdateThing{scene_id, thing_id, ref thing, instance} => {
            self.scenes.get_mut(&scene_id).unwrap().things.insert(thing_id, (thing.clone(), instance));
            Fate::Live
        }
    }}
}

#[derive(Copy, Clone)]
pub struct AddInstance {pub scene_id: usize, pub batch_id: usize, pub position: Instance}

impl Recipient<AddInstance> for Renderer {
    fn receive(&mut self, msg: &AddInstance) -> Fate {match *msg {
        AddInstance{scene_id, batch_id, position} => {
            self.scenes.get_mut(&scene_id).unwrap().batches.get_mut(&batch_id).unwrap().instances.push(position);
            Fate::Live
        }
    }}
}

#[derive(Copy, Clone)]
pub struct Project2dTo3d {pub scene_id: usize, pub position_2d: P2, pub requester: ID}

#[derive(Copy, Clone)]
pub struct Projected3d{pub position_3d: P3}

impl Recipient<Project2dTo3d> for Renderer {
    fn receive(&mut self, msg: &Project2dTo3d) -> Fate {match *msg{
        Project2dTo3d{scene_id, position_2d, requester} => {
            let eye = &self.scenes.get_mut(&scene_id).unwrap().eye;
            let frame_size = self.render_context.window.get_framebuffer_dimensions();

            // mouse is on the close plane of the frustum
            let normalized_2d_position = V4::new(
                (position_2d.x / (frame_size.0 as N)) * 2.0 - 1.0,
                (-position_2d.y / (frame_size.1 as N)) * 2.0 + 1.0,
                -1.0,
                1.0
            );

            let inverse_view = Iso3::look_at_rh(
                &eye.position,
                &eye.target,
                &eye.up
            ).to_homogeneous().inverse().unwrap();
            let inverse_perspective = Persp3::new(
                frame_size.0 as f32 / frame_size.1 as f32,
                eye.field_of_view,
                0.1,
                1000.0
            ).to_matrix().inverse().unwrap();

            // converts from frustum to position relative to camera
            let mut position_from_camera = inverse_perspective * normalized_2d_position;
            // reinterpret that as a vector (direction)
            position_from_camera.w = 0.0;
            // convert into world coordinates
            let direction_into_world = inverse_view * position_from_camera;

            let direction_into_world_3d = V3::new(direction_into_world.x, direction_into_world.y, direction_into_world.z);// / direction_into_world.w;

            let distance =  -eye.position.z / direction_into_world_3d.z;
            let position_in_world = eye.position + distance * direction_into_world_3d;

            requester << Projected3d{position_3d: position_in_world};
            Fate::Live
        }
    }}
}

pub fn setup(system: &mut ActorSystem, renderer: Renderer) {
    system.add_individual(renderer);
    system.add_inbox::<Control, Renderer>();
    system.add_inbox::<AddBatch, Renderer>();
    system.add_inbox::<AddInstance, Renderer>();
    system.add_inbox::<UpdateThing, Renderer>();
    system.add_inbox::<MoveEye, Renderer>();
    system.add_inbox::<Project2dTo3d, Renderer>();

    Renderer::id() << Control::Setup;
}

pub struct Scene {
    pub eye: Eye,
    pub batches: HashMap<usize, Batch>,
    pub things: HashMap<usize, (Thing, Instance)>,
    pub renderables: Vec<ID>,
    pub debug_text: String
}

impl Scene {
    pub fn new() -> Scene {
        Scene{
            eye: Eye{
                position: P3::new(-5.0, -5.0, 5.0),
                target: P3::new(0.0, 0.0, 0.0),
                up: V3::new(0.0, 0.0, 1.0),
                field_of_view: 0.3 * ::std::f32::consts::PI
            },
            batches: HashMap::new(),
            things: HashMap::new(),
            renderables: Vec::new(),
            debug_text: String::new()
        }
    }
}

impl Default for Scene {
    fn default() -> Self {Self::new()}
}

pub struct Eye {
    pub position: P3,
    pub target: P3,
    pub up: V3,
    pub field_of_view: f32
}

#[derive(Compact)]
pub struct Thing {
    pub vertices: CVec<Vertex>,
    pub indices: CVec<u16>
}

impl Thing {
    pub fn new(vertices: Vec<Vertex>, indices: Vec<u16>) -> Thing {
        Thing{vertices: vertices.into(), indices: indices.into()}
    }
}

impl Clone for Thing {
    fn clone(&self) -> Thing {
        Thing {
            vertices: self.vertices.to_vec().into(),
            indices: self.indices.to_vec().into()
        }
    }
}

impl ::std::ops::Add for Thing {
    type Output = Thing;

    fn add(self, rhs: Thing) -> Thing {
        let self_n_vertices = self.vertices.len();
        Thing::new(
            self.vertices.iter().chain(rhs.vertices.iter()).cloned().collect(),
            self.indices.iter().cloned().chain(rhs.indices.iter().map(|i| *i + self_n_vertices as u16)).collect()
        )
    }
}

impl ::std::ops::AddAssign for Thing {
    fn add_assign(&mut self, rhs: Thing) {
        let self_n_vertices = self.vertices.len();
        for vertex in rhs.vertices.iter().cloned() {
            self.vertices.push(vertex);
        }
        for index in rhs.indices.iter() {
            self.indices.push(index + self_n_vertices as u16)
        }
    }
}

impl ::std::iter::Sum for Thing {
    fn sum<I: Iterator<Item=Self>>(iter: I) -> Thing {
        let mut summed_thing = Thing{vertices: CVec::new(), indices: CVec::new()};
        for thing in iter {
            {
                let vertices : &[Vertex] = &*thing.vertices;
                let indices : &[u16] = &*thing.indices;
                let bla = 5;
            }
            summed_thing += thing;
        }
        summed_thing
    }
}

pub struct Batch {
    prototype: Thing,
    pub instances: Vec<Instance>
}

impl Batch {
    pub fn new(prototype: Thing, instances: Vec<Instance>) -> Batch {
        Batch{prototype: prototype, instances: instances}
    }
}

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

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

pub struct RenderContext {
    pub window: GlutinFacade,
    batch_program: glium::Program,
    text_system: glium_text::TextSystem,
    font: glium_text::FontTexture
}

impl RenderContext {
    #[allow(redundant_closure)]
    pub fn new (window: GlutinFacade) -> RenderContext {
        RenderContext{
            batch_program: program!(&window,
                140 => {
                    vertex: include_str!("shader/solid_140.glslv"),
                    fragment: include_str!("shader/solid_140.glslf")
                }
            ).unwrap(),
            text_system: glium_text::TextSystem::new(&window),
            font: glium_text::FontTexture::new(
                &window,
                ::std::fs::File::open(&::std::path::Path::new("fonts/ClearSans-Regular.ttf")).unwrap(),
                64
            ).unwrap(),
            window: window,
        }
    }

    pub fn submit (&self, scene: &Scene) {
        let mut target = self.window.draw();

        let view : [[f32; 4]; 4] = *Iso3::look_at_rh(
            &scene.eye.position,
            &scene.eye.target,
            &scene.eye.up
        ).to_homogeneous().as_ref();
        let perspective : [[f32; 4]; 4] = *Persp3::new(
            target.get_dimensions().0 as f32 / target.get_dimensions().1 as f32,
            scene.eye.field_of_view,
            0.1,
            1000.0
        ).to_matrix().as_ref();

        let uniforms = uniform! {
            view: view,
            perspective: perspective
        };

        let params = glium::DrawParameters {
            depth: glium::Depth {
                test: glium::draw_parameters::DepthTest::IfLess,
                write: true,
                .. Default::default()
            },
            .. Default::default()
        };

        // draw a frame
        target.clear_color_and_depth((1.0, 1.0, 1.0, 1.0), 1.0);

        for batch in scene.batches.values() {
            let vertices = glium::VertexBuffer::new(&self.window, &batch.prototype.vertices).unwrap();
            let indices = glium::IndexBuffer::new(&self.window, index::PrimitiveType::TrianglesList, &batch.prototype.indices).unwrap();
            let instances = glium::VertexBuffer::dynamic(&self.window, batch.instances.as_slice()).unwrap();
            target.draw((&vertices, instances.per_instance().unwrap()), &indices, &self.batch_program, &uniforms, &params).unwrap();
        }

        for &(ref thing, instance) in scene.things.values() {
            let vertices = glium::VertexBuffer::new(&self.window, &thing.vertices).unwrap();
            let indices = glium::IndexBuffer::new(&self.window, index::PrimitiveType::TrianglesList, &thing.indices).unwrap();
            let instances = glium::VertexBuffer::new(&self.window, &[instance]).unwrap();
            target.draw((&vertices, instances.per_instance().unwrap()), &indices, &self.batch_program, &uniforms, &params).unwrap();
        }

        let text = glium_text::TextDisplay::new(&self.text_system, &self.font, scene.debug_text.as_str());
        let text_matrix = [
            [0.05, 0.0, 0.0, 0.0],
            [0.0, 0.05, 0.0, 0.0],
            [0.0, 0.0, 0.05, 0.0],
            [-0.9, 0.8, 0.0, 1.0f32]
        ];

        glium_text::draw(&text, &self.text_system, &mut target, text_matrix, (0.0, 0.0, 0.0, 1.0));

        target.finish().unwrap();
    }
}<commit_msg>cleanup<commit_after>#![feature(plugin)]
#![plugin(clippy)]
#![allow(no_effect, unnecessary_operation)]
#![feature(proc_macro)]
extern crate descartes;
#[macro_use]
pub extern crate glium;
extern crate kay;
#[macro_use]
extern crate kay_macros;
extern crate glium_text;

pub use ::descartes::{N, P3, P2, V3, V4, M4, Iso3, Persp3, ToHomogeneous, Norm, Into2d, Into3d, WithUniqueOrthogonal, Inverse, Rotate};
use ::kay::{ID, Recipient, CVec, ActorSystem, Individual, Fate};
use std::collections::HashMap;

use glium::{index, Surface};
pub use glium::backend::glutin_backend::GlutinFacade;

pub struct Renderer {
    pub scenes: HashMap<usize, Scene>,
    pub render_context: RenderContext
}

impl Renderer {
    pub fn new (window: GlutinFacade) -> Renderer {
        Renderer {
            scenes: HashMap::new(),
            render_context: RenderContext::new(window)
        }
    }
}

impl Individual for Renderer {}

#[derive(Copy, Clone)]
pub enum Control {Setup, Render, Submit}

#[derive(Copy, Clone)]
pub struct SetupInScene {pub renderer_id: ID, pub scene_id: usize}

#[derive(Copy, Clone)]
pub struct RenderToScene {pub renderer_id: ID, pub scene_id: usize}

impl Recipient<Control> for Renderer {
    fn receive(&mut self, msg: &Control) -> Fate {match *msg {
        Control::Setup => {
            for (scene_id, scene) in &self.scenes {
                for renderable in &scene.renderables {
                    *renderable << SetupInScene{renderer_id: Self::id(), scene_id: *scene_id};
                }
            }
            Fate::Live
        },

        Control::Render => {
            for (scene_id, mut scene) in &mut self.scenes {
                for batch in (&mut scene).batches.values_mut() {
                    batch.instances.clear();
                }
                for renderable in &scene.renderables {
                    *renderable << RenderToScene{renderer_id: Self::id(), scene_id: *scene_id};
                }
            }
            Fate::Live
        }

        Control::Submit => {
            for scene in self.scenes.values() {
                self.render_context.submit(scene);
            }
            Fate::Live
        }
    }}
}

#[derive(Copy, Clone)]
pub struct MoveEye {pub scene_id: usize, pub delta: V3}

impl Recipient<MoveEye> for Renderer {
    fn receive(&mut self, msg: &MoveEye) -> Fate {match *msg{
        MoveEye{scene_id, delta} => {
            let eye = &mut self.scenes.get_mut(&scene_id).unwrap().eye;
            let eye_direction_2d = (eye.target - eye.position).into_2d().normalize();
            let absolute_delta = delta.x * eye_direction_2d.into_3d()
                + delta.y * eye_direction_2d.orthogonal().into_3d()
                + V3::new(0.0, 0.0, delta.z);
            eye.position += absolute_delta;
            eye.target += absolute_delta;
            Fate::Live
        }
    }}
}

#[derive(Compact, Clone)]
pub struct AddBatch {pub scene_id: usize, pub batch_id: usize, pub thing: Thing}

impl Recipient<AddBatch> for Renderer {
    fn receive(&mut self, msg: &AddBatch) -> Fate {match *msg {
        AddBatch{scene_id, batch_id, ref thing} => {
            self.scenes.get_mut(&scene_id).unwrap().batches.insert(batch_id, Batch::new(thing.clone(), Vec::new()));
            Fate::Live
        }
    }}
}

#[derive(Compact, Clone)]
pub struct UpdateThing {pub scene_id: usize, pub thing_id: usize, pub thing: Thing, pub instance: Instance}

impl Recipient<UpdateThing> for Renderer {
    fn receive(&mut self, msg: &UpdateThing) -> Fate {match *msg {
        UpdateThing{scene_id, thing_id, ref thing, instance} => {
            self.scenes.get_mut(&scene_id).unwrap().things.insert(thing_id, (thing.clone(), instance));
            Fate::Live
        }
    }}
}

#[derive(Copy, Clone)]
pub struct AddInstance {pub scene_id: usize, pub batch_id: usize, pub position: Instance}

impl Recipient<AddInstance> for Renderer {
    fn receive(&mut self, msg: &AddInstance) -> Fate {match *msg {
        AddInstance{scene_id, batch_id, position} => {
            self.scenes.get_mut(&scene_id).unwrap().batches.get_mut(&batch_id).unwrap().instances.push(position);
            Fate::Live
        }
    }}
}

#[derive(Copy, Clone)]
pub struct Project2dTo3d {pub scene_id: usize, pub position_2d: P2, pub requester: ID}

#[derive(Copy, Clone)]
pub struct Projected3d{pub position_3d: P3}

impl Recipient<Project2dTo3d> for Renderer {
    fn receive(&mut self, msg: &Project2dTo3d) -> Fate {match *msg{
        Project2dTo3d{scene_id, position_2d, requester} => {
            let eye = &self.scenes.get_mut(&scene_id).unwrap().eye;
            let frame_size = self.render_context.window.get_framebuffer_dimensions();

            // mouse is on the close plane of the frustum
            let normalized_2d_position = V4::new(
                (position_2d.x / (frame_size.0 as N)) * 2.0 - 1.0,
                (-position_2d.y / (frame_size.1 as N)) * 2.0 + 1.0,
                -1.0,
                1.0
            );

            let inverse_view = Iso3::look_at_rh(
                &eye.position,
                &eye.target,
                &eye.up
            ).to_homogeneous().inverse().unwrap();
            let inverse_perspective = Persp3::new(
                frame_size.0 as f32 / frame_size.1 as f32,
                eye.field_of_view,
                0.1,
                1000.0
            ).to_matrix().inverse().unwrap();

            // converts from frustum to position relative to camera
            let mut position_from_camera = inverse_perspective * normalized_2d_position;
            // reinterpret that as a vector (direction)
            position_from_camera.w = 0.0;
            // convert into world coordinates
            let direction_into_world = inverse_view * position_from_camera;

            let direction_into_world_3d = V3::new(direction_into_world.x, direction_into_world.y, direction_into_world.z);// / direction_into_world.w;

            let distance =  -eye.position.z / direction_into_world_3d.z;
            let position_in_world = eye.position + distance * direction_into_world_3d;

            requester << Projected3d{position_3d: position_in_world};
            Fate::Live
        }
    }}
}

pub fn setup(system: &mut ActorSystem, renderer: Renderer) {
    system.add_individual(renderer);
    system.add_inbox::<Control, Renderer>();
    system.add_inbox::<AddBatch, Renderer>();
    system.add_inbox::<AddInstance, Renderer>();
    system.add_inbox::<UpdateThing, Renderer>();
    system.add_inbox::<MoveEye, Renderer>();
    system.add_inbox::<Project2dTo3d, Renderer>();

    Renderer::id() << Control::Setup;
}

pub struct Scene {
    pub eye: Eye,
    pub batches: HashMap<usize, Batch>,
    pub things: HashMap<usize, (Thing, Instance)>,
    pub renderables: Vec<ID>,
    pub debug_text: String
}

impl Scene {
    pub fn new() -> Scene {
        Scene{
            eye: Eye{
                position: P3::new(-5.0, -5.0, 5.0),
                target: P3::new(0.0, 0.0, 0.0),
                up: V3::new(0.0, 0.0, 1.0),
                field_of_view: 0.3 * ::std::f32::consts::PI
            },
            batches: HashMap::new(),
            things: HashMap::new(),
            renderables: Vec::new(),
            debug_text: String::new()
        }
    }
}

impl Default for Scene {
    fn default() -> Self {Self::new()}
}

pub struct Eye {
    pub position: P3,
    pub target: P3,
    pub up: V3,
    pub field_of_view: f32
}

#[derive(Compact)]
pub struct Thing {
    pub vertices: CVec<Vertex>,
    pub indices: CVec<u16>
}

impl Thing {
    pub fn new(vertices: Vec<Vertex>, indices: Vec<u16>) -> Thing {
        Thing{vertices: vertices.into(), indices: indices.into()}
    }
}

impl Clone for Thing {
    fn clone(&self) -> Thing {
        Thing {
            vertices: self.vertices.to_vec().into(),
            indices: self.indices.to_vec().into()
        }
    }
}

impl ::std::ops::Add for Thing {
    type Output = Thing;

    fn add(self, rhs: Thing) -> Thing {
        let self_n_vertices = self.vertices.len();
        Thing::new(
            self.vertices.iter().chain(rhs.vertices.iter()).cloned().collect(),
            self.indices.iter().cloned().chain(rhs.indices.iter().map(|i| *i + self_n_vertices as u16)).collect()
        )
    }
}

impl ::std::ops::AddAssign for Thing {
    fn add_assign(&mut self, rhs: Thing) {
        let self_n_vertices = self.vertices.len();
        for vertex in rhs.vertices.iter().cloned() {
            self.vertices.push(vertex);
        }
        for index in rhs.indices.iter() {
            self.indices.push(index + self_n_vertices as u16)
        }
    }
}

impl ::std::iter::Sum for Thing {
    fn sum<I: Iterator<Item=Self>>(iter: I) -> Thing {
        let mut summed_thing = Thing{vertices: CVec::new(), indices: CVec::new()};
        for thing in iter {
            summed_thing += thing;
        }
        summed_thing
    }
}

pub struct Batch {
    prototype: Thing,
    pub instances: Vec<Instance>
}

impl Batch {
    pub fn new(prototype: Thing, instances: Vec<Instance>) -> Batch {
        Batch{prototype: prototype, instances: instances}
    }
}

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

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

pub struct RenderContext {
    pub window: GlutinFacade,
    batch_program: glium::Program,
    text_system: glium_text::TextSystem,
    font: glium_text::FontTexture
}

impl RenderContext {
    #[allow(redundant_closure)]
    pub fn new (window: GlutinFacade) -> RenderContext {
        RenderContext{
            batch_program: program!(&window,
                140 => {
                    vertex: include_str!("shader/solid_140.glslv"),
                    fragment: include_str!("shader/solid_140.glslf")
                }
            ).unwrap(),
            text_system: glium_text::TextSystem::new(&window),
            font: glium_text::FontTexture::new(
                &window,
                ::std::fs::File::open(&::std::path::Path::new("fonts/ClearSans-Regular.ttf")).unwrap(),
                64
            ).unwrap(),
            window: window,
        }
    }

    pub fn submit (&self, scene: &Scene) {
        let mut target = self.window.draw();

        let view : [[f32; 4]; 4] = *Iso3::look_at_rh(
            &scene.eye.position,
            &scene.eye.target,
            &scene.eye.up
        ).to_homogeneous().as_ref();
        let perspective : [[f32; 4]; 4] = *Persp3::new(
            target.get_dimensions().0 as f32 / target.get_dimensions().1 as f32,
            scene.eye.field_of_view,
            0.1,
            1000.0
        ).to_matrix().as_ref();

        let uniforms = uniform! {
            view: view,
            perspective: perspective
        };

        let params = glium::DrawParameters {
            depth: glium::Depth {
                test: glium::draw_parameters::DepthTest::IfLess,
                write: true,
                .. Default::default()
            },
            .. Default::default()
        };

        // draw a frame
        target.clear_color_and_depth((1.0, 1.0, 1.0, 1.0), 1.0);

        for batch in scene.batches.values() {
            let vertices = glium::VertexBuffer::new(&self.window, &batch.prototype.vertices).unwrap();
            let indices = glium::IndexBuffer::new(&self.window, index::PrimitiveType::TrianglesList, &batch.prototype.indices).unwrap();
            let instances = glium::VertexBuffer::dynamic(&self.window, batch.instances.as_slice()).unwrap();
            target.draw((&vertices, instances.per_instance().unwrap()), &indices, &self.batch_program, &uniforms, &params).unwrap();
        }

        for &(ref thing, instance) in scene.things.values() {
            let vertices = glium::VertexBuffer::new(&self.window, &thing.vertices).unwrap();
            let indices = glium::IndexBuffer::new(&self.window, index::PrimitiveType::TrianglesList, &thing.indices).unwrap();
            let instances = glium::VertexBuffer::new(&self.window, &[instance]).unwrap();
            target.draw((&vertices, instances.per_instance().unwrap()), &indices, &self.batch_program, &uniforms, &params).unwrap();
        }

        let text = glium_text::TextDisplay::new(&self.text_system, &self.font, scene.debug_text.as_str());
        let text_matrix = [
            [0.05, 0.0, 0.0, 0.0],
            [0.0, 0.05, 0.0, 0.0],
            [0.0, 0.0, 0.05, 0.0],
            [-0.9, 0.8, 0.0, 1.0f32]
        ];

        glium_text::draw(&text, &self.text_system, &mut target, text_matrix, (0.0, 0.0, 0.0, 1.0));

        target.finish().unwrap();
    }
}<|endoftext|>


<commit_before>#[cfg(test)]
mod lucetc_tests {
    use failure::Error;
    use lucet_module::bindings::Bindings;
    use lucet_validate::Validator;
    use lucet_wasi_sdk::*;
    use lucetc::{Compiler, HeapSettings, OptLevel};
    use std::collections::HashMap;
    use std::fs::File;
    use std::io::Read;
    use std::path::PathBuf;

    /// Compile C -> WebAssembly using wasi-sdk's clang. Does not use the wasi-sdk
    /// libc, and does not produce a wasi executable, just a wasm module with the given set of
    /// export functions.
    fn module_from_c(cfiles: &[&str], exports: &[&str]) -> Result<Vec<u8>, Error> {
        let cfiles: Vec<PathBuf> = cfiles
            .iter()
            .map(|ref name| PathBuf::from(format!("tests/{}.c", name)))
            .collect();
        let tempdir = tempfile::Builder::new().prefix("wasi-sdk-test").tempdir()?;

        let mut wasm = PathBuf::from(tempdir.path());
        wasm.push("out.wasm");

        let mut linker = Link::new(&cfiles)
            .with_cflag("-nostartfiles")
            .with_link_opt(LinkOpt::NoDefaultEntryPoint)
            .with_link_opt(LinkOpt::AllowUndefinedAll);
        for export in exports {
            linker.export(export);
        }
        linker.link(wasm.clone())?;

        let mut wasm_file = File::open(wasm)?;
        let mut wasm_contents = Vec::new();
        wasm_file.read_to_end(&mut wasm_contents)?;
        Ok(wasm_contents)
    }

    #[test]
    fn empty() {
        let m = module_from_c(&["empty"], &[]).expect("build module for empty");
        let b = Bindings::empty();
        let h = HeapSettings::default();
        let v = Validator::parse("").expect("empty validation environment");
        let c =
            Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile empty");
        let mdata = c.module_data().unwrap();
        assert!(mdata.heap_spec().is_some());
        // clang creates 1 global, which is not exported.:
        assert_eq!(mdata.globals_spec().len(), 1);
        assert!(mdata.globals_spec()[0].is_internal());

        assert_eq!(mdata.import_functions().len(), 0, "import functions");
        assert_eq!(mdata.export_functions().len(), 0, "export functions");

        /* FIXME: module data doesn't contain the information to check these properties:
        assert_eq!(num_import_globals(&p), 0, "import globals");
        */

        let _obj = c.object_file().expect("generate code from empty");
    }

    fn d_only_test_bindings() -> Bindings {
        let imports: HashMap<String, String> = [
            ("c".into(), "c".into()), // d_only
        ]
        .iter()
        .cloned()
        .collect();

        Bindings::env(imports)
    }

    #[test]
    fn just_c() {
        let m = module_from_c(&["c"], &["c"]).expect("build module for c");
        let b = Bindings::empty();
        let h = HeapSettings::default();
        let v = Validator::parse("").expect("empty validation environment");

        let c = Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile c");
        let mdata = c.module_data().unwrap();
        assert_eq!(mdata.import_functions().len(), 0, "import functions");
        assert_eq!(mdata.export_functions().len(), 1, "export functions");

        /* FIXME: module data doesn't contain the information to check these properties:
        assert_eq!(num_import_globals(&p), 0, "import globals");
        */

        let _obj = c.object_file().expect("generate code from c");
    }

    #[test]
    fn just_d() {
        let m = module_from_c(&["d"], &["d"]).expect("build module for d");
        let b = d_only_test_bindings();
        let h = HeapSettings::default();
        let v = Validator::parse(
            "(module $env (@interface func (export \"c\") (param $a1 s32) (result $r1 s32)))",
        )
        .expect("empty validation environment");
        let c = Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile d");
        let mdata = c.module_data().unwrap();
        assert_eq!(mdata.import_functions().len(), 1, "import functions");
        assert_eq!(mdata.export_functions().len(), 1, "export functions");

        /* FIXME: module data doesn't contain the information to check these properties:
        assert_eq!(num_import_globals(&p), 0, "import globals");
        */
        let _obj = c.object_file().expect("generate code from d");
    }

    #[test]
    fn c_and_d() {
        let m = module_from_c(&["c", "d"], &["c", "d"]).expect("build module for c & d");
        let b = Bindings::empty();
        let h = HeapSettings::default();
        let v = Validator::parse("").expect("empty validation environment");
        let c =
            Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile c & d");
        let mdata = c.module_data().unwrap();
        assert_eq!(mdata.import_functions().len(), 0, "import functions");
        assert_eq!(mdata.export_functions().len(), 2, "export functions");

        /* FIXME: module data doesn't contain the information to check these properties:
        assert_eq!(num_import_globals(&p), 0, "import globals");
        */
        let _obj = c.object_file().expect("generate code from c & d");
    }

    #[test]
    fn hello() {
        let m = {
            // Unlike in module_from_c, use wasi-sdk to compile a C file to a wasi executable,
            // linking in wasi-libc and exposing the wasi _start entry point only:
            let tempdir = tempfile::Builder::new()
                .prefix("wasi-sdk-test")
                .tempdir()
                .expect("create tempdir");
            let mut wasm = PathBuf::from(tempdir.path());
            wasm.push("out.wasm");

            let linker = Link::new(&[PathBuf::from("tests/hello.c")]);
            linker.link(wasm.clone()).expect("link");

            let mut wasm_file = File::open(wasm).expect("open wasm");
            let mut wasm_contents = Vec::new();
            wasm_file
                .read_to_end(&mut wasm_contents)
                .expect("read wasm");
            wasm_contents
        };

        let b =
            Bindings::from_file("../lucet-wasi/bindings.json").expect("load lucet-wasi bindings");
        let h = HeapSettings::default();
        let v = Validator::load("../wasi/phases/unstable/witx/wasi_unstable_preview0.witx")
            .expect("wasi spec validation")
            .with_wasi_exe(true);
        // Compiler will only unwrap if the Validator defined above accepts the module
        let c =
            Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile empty");
        let mdata = c.module_data().unwrap();
        assert!(mdata.heap_spec().is_some());
    }
}
<commit_msg>fix the number of magic globals that wasi-sdk clang creates<commit_after>#[cfg(test)]
mod lucetc_tests {
    use failure::Error;
    use lucet_module::bindings::Bindings;
    use lucet_validate::Validator;
    use lucet_wasi_sdk::*;
    use lucetc::{Compiler, HeapSettings, OptLevel};
    use std::collections::HashMap;
    use std::fs::File;
    use std::io::Read;
    use std::path::PathBuf;

    /// Compile C -> WebAssembly using wasi-sdk's clang. Does not use the wasi-sdk
    /// libc, and does not produce a wasi executable, just a wasm module with the given set of
    /// export functions.
    fn module_from_c(cfiles: &[&str], exports: &[&str]) -> Result<Vec<u8>, Error> {
        let cfiles: Vec<PathBuf> = cfiles
            .iter()
            .map(|ref name| PathBuf::from(format!("tests/{}.c", name)))
            .collect();
        let tempdir = tempfile::Builder::new().prefix("wasi-sdk-test").tempdir()?;

        let mut wasm = PathBuf::from(tempdir.path());
        wasm.push("out.wasm");

        let mut linker = Link::new(&cfiles)
            .with_cflag("-nostartfiles")
            .with_link_opt(LinkOpt::NoDefaultEntryPoint)
            .with_link_opt(LinkOpt::AllowUndefinedAll);
        for export in exports {
            linker.export(export);
        }
        linker.link(wasm.clone())?;

        let mut wasm_file = File::open(wasm)?;
        let mut wasm_contents = Vec::new();
        wasm_file.read_to_end(&mut wasm_contents)?;
        Ok(wasm_contents)
    }

    #[test]
    fn empty() {
        let m = module_from_c(&["empty"], &[]).expect("build module for empty");
        let b = Bindings::empty();
        let h = HeapSettings::default();
        let v = Validator::parse("").expect("empty validation environment");
        let c =
            Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile empty");
        let mdata = c.module_data().unwrap();
        assert!(mdata.heap_spec().is_some());
        // clang creates 3 globals, which are not exported.:
        assert_eq!(mdata.globals_spec().len(), 3);
        assert!(mdata.globals_spec()[0].is_internal());

        assert_eq!(mdata.import_functions().len(), 0, "import functions");
        assert_eq!(mdata.export_functions().len(), 0, "export functions");

        /* FIXME: module data doesn't contain the information to check these properties:
        assert_eq!(num_import_globals(&p), 0, "import globals");
        */

        let _obj = c.object_file().expect("generate code from empty");
    }

    fn d_only_test_bindings() -> Bindings {
        let imports: HashMap<String, String> = [
            ("c".into(), "c".into()), // d_only
        ]
        .iter()
        .cloned()
        .collect();

        Bindings::env(imports)
    }

    #[test]
    fn just_c() {
        let m = module_from_c(&["c"], &["c"]).expect("build module for c");
        let b = Bindings::empty();
        let h = HeapSettings::default();
        let v = Validator::parse("").expect("empty validation environment");

        let c = Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile c");
        let mdata = c.module_data().unwrap();
        assert_eq!(mdata.import_functions().len(), 0, "import functions");
        assert_eq!(mdata.export_functions().len(), 1, "export functions");

        /* FIXME: module data doesn't contain the information to check these properties:
        assert_eq!(num_import_globals(&p), 0, "import globals");
        */

        let _obj = c.object_file().expect("generate code from c");
    }

    #[test]
    fn just_d() {
        let m = module_from_c(&["d"], &["d"]).expect("build module for d");
        let b = d_only_test_bindings();
        let h = HeapSettings::default();
        let v = Validator::parse(
            "(module $env (@interface func (export \"c\") (param $a1 s32) (result $r1 s32)))",
        )
        .expect("empty validation environment");
        let c = Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile d");
        let mdata = c.module_data().unwrap();
        assert_eq!(mdata.import_functions().len(), 1, "import functions");
        assert_eq!(mdata.export_functions().len(), 1, "export functions");

        /* FIXME: module data doesn't contain the information to check these properties:
        assert_eq!(num_import_globals(&p), 0, "import globals");
        */
        let _obj = c.object_file().expect("generate code from d");
    }

    #[test]
    fn c_and_d() {
        let m = module_from_c(&["c", "d"], &["c", "d"]).expect("build module for c & d");
        let b = Bindings::empty();
        let h = HeapSettings::default();
        let v = Validator::parse("").expect("empty validation environment");
        let c =
            Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile c & d");
        let mdata = c.module_data().unwrap();
        assert_eq!(mdata.import_functions().len(), 0, "import functions");
        assert_eq!(mdata.export_functions().len(), 2, "export functions");

        /* FIXME: module data doesn't contain the information to check these properties:
        assert_eq!(num_import_globals(&p), 0, "import globals");
        */
        let _obj = c.object_file().expect("generate code from c & d");
    }

    #[test]
    fn hello() {
        let m = {
            // Unlike in module_from_c, use wasi-sdk to compile a C file to a wasi executable,
            // linking in wasi-libc and exposing the wasi _start entry point only:
            let tempdir = tempfile::Builder::new()
                .prefix("wasi-sdk-test")
                .tempdir()
                .expect("create tempdir");
            let mut wasm = PathBuf::from(tempdir.path());
            wasm.push("out.wasm");

            let linker = Link::new(&[PathBuf::from("tests/hello.c")]);
            linker.link(wasm.clone()).expect("link");

            let mut wasm_file = File::open(wasm).expect("open wasm");
            let mut wasm_contents = Vec::new();
            wasm_file
                .read_to_end(&mut wasm_contents)
                .expect("read wasm");
            wasm_contents
        };

        let b =
            Bindings::from_file("../lucet-wasi/bindings.json").expect("load lucet-wasi bindings");
        let h = HeapSettings::default();
        let v = Validator::load("../wasi/phases/unstable/witx/wasi_unstable_preview0.witx")
            .expect("wasi spec validation")
            .with_wasi_exe(true);
        // Compiler will only unwrap if the Validator defined above accepts the module
        let c =
            Compiler::new(&m, OptLevel::default(), &b, h, false, &Some(v)).expect("compile empty");
        let mdata = c.module_data().unwrap();
        assert!(mdata.heap_spec().is_some());
    }
}
<|endoftext|>


<commit_before>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

//! Metropolis Monte-Carlo propagator implementation
use rand::{self, SeedableRng};

use constants::K_BOLTZMANN;
use system::{System, EnergyCache};
use simulation::Propagator;

use super::MCMove;

/// Metropolis Monte-Carlo propagator
pub struct MonteCarlo {
    /// Boltzmann factor: beta = 1/(kB * T)
    beta: f64,
    /// List of possible Monte-Carlo moves
    moves: Vec<Box<MCMove>>,
    /// Cummulative frequencies of the Monte-Carlo moves
    frequencies: Vec<f64>,
    /// Random number generator for the simulation. All random state will be
    /// taken from this.
    rng: Box<rand::Rng>,
    /// Cache for faster energy computation
    cache: EnergyCache,
}

impl MonteCarlo {
    /// Create a new Monte-Carlo propagator at temperature `T`.
    pub fn new(temperature: f64) -> MonteCarlo {
        let mut rng = Box::new(rand::XorShiftRng::new_unseeded());
        rng.reseed([2015u32, 42u32, 3u32, 12u32]);
        return MonteCarlo::from_rng(temperature, rng);
    }

    /// Create a Monte-Carlo propagator at temperature `T`, using the `rng`
    /// random number generator.
    pub fn from_rng(temperature: f64, rng: Box<rand::Rng>) -> MonteCarlo {
        assert!(temperature >= 0.0, "Monte-Carlo temperature must be positive");
        MonteCarlo {
            beta: 1.0 / (K_BOLTZMANN * temperature),
            moves: Vec::new(),
            frequencies: Vec::new(),
            rng: rng,
            cache: EnergyCache::new(),
        }
    }

    /// Add a the `mcmove` Monte-Carlo move to this propagator, with frequency
    /// `frequency`.
    pub fn add(&mut self, mcmove: Box<MCMove>, frequency: f64) {
        self.moves.push(mcmove);
        self.frequencies.push(frequency);
    }

    /// Get the temperature of the simulation
    pub fn temperature(&self) -> f64 {
        1.0 / (self.beta * K_BOLTZMANN)
    }

    /// Set the temperature of the simulation
    pub fn set_temperature(&mut self, temperature: f64) {
        self.beta = 1.0 / (temperature * K_BOLTZMANN);
    }

    fn normalize_frequencies(&mut self) {
        assert!(self.frequencies.len() == self.moves.len());
        if self.frequencies.is_empty() {
            warn!(
                "No move in the Monte-Carlo simulation, \
                did you forget to specify them?"
            );
            return;
        }

        // Normalize the frequencies
        let sum = self.frequencies.iter().fold(0.0, |sum, &f| sum + f);
        for frequency in &mut self.frequencies {
            *frequency /= sum;
        }
        // Make the frequencies vector contain cummulative frequencies
        for i in 1..self.frequencies.len() {
            self.frequencies[i] += self.frequencies[i - 1];
        }
        let last = self.frequencies.len() - 1;
        self.frequencies[last] = 1.0;
    }
}

impl Propagator for MonteCarlo {
    fn setup(&mut self, system: &System) {
        self.normalize_frequencies();
        self.cache.init(system);
    }

    fn propagate(&mut self, system: &mut System) {
        let mcmove = {
            let probability = self.rng.next_f64();
            // Get the index of the first move with frequency >= probability.
            let (i, _) = self.frequencies.iter()
                                         .enumerate()
                                         .find(|&(_, f)| probability <= *f)
                                         .expect("Could not find a move in MonteCarlo moves list");
            &mut self.moves[i]
        };
        trace!("Selected move is '{}'", mcmove.describe());

        if !mcmove.prepare(system, &mut self.rng) {
            trace!("    --> Can not perform the move");
            return;
        }

        let cost = mcmove.cost(system, self.beta, &mut self.cache);
        trace!("    --> Move cost is {}", cost);

        let accepted = cost <= 0.0 || self.rng.next_f64() < f64::exp(-cost);

        if accepted {
            trace!("    --> Move was accepted");
            mcmove.apply(system);
            self.cache.update(system);
        } else {
            trace!("    --> Move was rejected");
            mcmove.restore(system);
        }
    }
}

#[cfg(test)]
mod tests {
    use simulation::{MonteCarlo, MCMove, Propagator};
    use system::{System, EnergyCache};
    use rand::Rng;

    struct DummyMove;
    impl MCMove for DummyMove {
        fn describe(&self) -> &str {"dummy"}
        fn prepare(&mut self, _: &mut System, _: &mut Box<Rng>) -> bool {true}
        fn cost(&self, _: &System, _: f64, _: &mut EnergyCache) -> f64 {0.0}
        fn apply(&mut self, _: &mut System) {}
        fn restore(&mut self, _: &mut System) {}
    }

    #[test]
    fn frequencies() {
        let mut mc = MonteCarlo::new(100.0);
        mc.add(Box::new(DummyMove), 13.0);
        mc.add(Box::new(DummyMove), 2.0);
        mc.add(Box::new(DummyMove), 5.0);

        mc.setup(&System::new());
        let mut last_frequency = 0.0;
        for &f in &mc.frequencies {
            assert!(f > last_frequency);
            last_frequency = f;
        }
        assert_eq!(mc.frequencies.last(), Some(&1.0));

        assert_eq!(mc.frequencies.len(), 3);
        assert_eq!(mc.frequencies[0], 0.65);
        assert_eq!(mc.frequencies[1], 0.75);
        assert_eq!(mc.frequencies[2], 1.0);
    }
}
<commit_msg>We can not add new moves after the simulation has been initialized<commit_after>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

//! Metropolis Monte-Carlo propagator implementation
use rand::{self, SeedableRng};

use constants::K_BOLTZMANN;
use system::{System, EnergyCache};
use simulation::Propagator;

use super::MCMove;

/// Metropolis Monte-Carlo propagator
pub struct MonteCarlo {
    /// Boltzmann factor: beta = 1/(kB * T)
    beta: f64,
    /// List of possible Monte-Carlo moves
    moves: Vec<Box<MCMove>>,
    /// Cummulative frequencies of the Monte-Carlo moves
    frequencies: Vec<f64>,
    /// Random number generator for the simulation. All random state will be
    /// taken from this.
    rng: Box<rand::Rng>,
    /// Cache for faster energy computation
    cache: EnergyCache,
    /// Flag checking if the moves frequencies has been converted to
    /// cummulative frequencies or not yet.
    initialized: bool,
}

impl MonteCarlo {
    /// Create a new Monte-Carlo propagator at temperature `T`.
    pub fn new(temperature: f64) -> MonteCarlo {
        let mut rng = Box::new(rand::XorShiftRng::new_unseeded());
        rng.reseed([2015u32, 42u32, 3u32, 12u32]);
        return MonteCarlo::from_rng(temperature, rng);
    }

    /// Create a Monte-Carlo propagator at temperature `T`, using the `rng`
    /// random number generator.
    pub fn from_rng(temperature: f64, rng: Box<rand::Rng>) -> MonteCarlo {
        assert!(temperature >= 0.0, "Monte-Carlo temperature must be positive");
        MonteCarlo {
            beta: 1.0 / (K_BOLTZMANN * temperature),
            moves: Vec::new(),
            frequencies: Vec::new(),
            rng: rng,
            cache: EnergyCache::new(),
            initialized: false,
        }
    }

    /// Add a the `mcmove` Monte-Carlo move to this propagator, with frequency
    /// `frequency`. All calls to this function should happen before any
    /// simulation run.
    ///
    /// # Panics
    ///
    /// If called after a simulation run.
    pub fn add(&mut self, mcmove: Box<MCMove>, frequency: f64) {
        if self.initialized {
            fatal_error!(
                "Monte-Carlo simulation has already been initialized, \
                we can not add new moves."
            );
        }
        self.moves.push(mcmove);
        self.frequencies.push(frequency);
    }

    /// Get the temperature of the simulation
    pub fn temperature(&self) -> f64 {
        1.0 / (self.beta * K_BOLTZMANN)
    }

    /// Set the temperature of the simulation
    pub fn set_temperature(&mut self, temperature: f64) {
        self.beta = 1.0 / (temperature * K_BOLTZMANN);
    }

    fn normalize_frequencies(&mut self) {
        assert!(self.frequencies.len() == self.moves.len());
        if self.frequencies.is_empty() {
            warn!(
                "No move in the Monte-Carlo simulation, \
                did you forget to specify them?"
            );
            return;
        }

        if self.initialized {
            error!("This Monte-Carlo simulation has already been initialized.");
            return;
        }

        self.initialized = true;
        // Normalize the frequencies
        let sum = self.frequencies.iter().fold(0.0, |sum, &f| sum + f);
        for frequency in &mut self.frequencies {
            *frequency /= sum;
        }
        // Make the frequencies vector contain cummulative frequencies
        for i in 1..self.frequencies.len() {
            self.frequencies[i] += self.frequencies[i - 1];
        }
        let last = self.frequencies.len() - 1;
        self.frequencies[last] = 1.0;
    }
}

impl Propagator for MonteCarlo {
    fn setup(&mut self, system: &System) {
        self.normalize_frequencies();
        self.cache.init(system);
    }

    fn propagate(&mut self, system: &mut System) {
        let mcmove = {
            let probability = self.rng.next_f64();
            // Get the index of the first move with frequency >= probability.
            let (i, _) = self.frequencies.iter()
                                         .enumerate()
                                         .find(|&(_, f)| probability <= *f)
                                         .expect("Could not find a move in MonteCarlo moves list");
            &mut self.moves[i]
        };
        trace!("Selected move is '{}'", mcmove.describe());

        if !mcmove.prepare(system, &mut self.rng) {
            trace!("    --> Can not perform the move");
            return;
        }

        let cost = mcmove.cost(system, self.beta, &mut self.cache);
        trace!("    --> Move cost is {}", cost);

        let accepted = cost <= 0.0 || self.rng.next_f64() < f64::exp(-cost);

        if accepted {
            trace!("    --> Move was accepted");
            mcmove.apply(system);
            self.cache.update(system);
        } else {
            trace!("    --> Move was rejected");
            mcmove.restore(system);
        }
    }
}

#[cfg(test)]
mod tests {
    use simulation::{MonteCarlo, MCMove, Propagator};
    use system::{System, EnergyCache};
    use rand::Rng;

    struct DummyMove;
    impl MCMove for DummyMove {
        fn describe(&self) -> &str {"dummy"}
        fn prepare(&mut self, _: &mut System, _: &mut Box<Rng>) -> bool {true}
        fn cost(&self, _: &System, _: f64, _: &mut EnergyCache) -> f64 {0.0}
        fn apply(&mut self, _: &mut System) {}
        fn restore(&mut self, _: &mut System) {}
    }

    #[test]
    fn frequencies() {
        let mut mc = MonteCarlo::new(100.0);
        mc.add(Box::new(DummyMove), 13.0);
        mc.add(Box::new(DummyMove), 2.0);
        mc.add(Box::new(DummyMove), 5.0);

        mc.setup(&System::new());
        let mut last_frequency = 0.0;
        for &f in &mc.frequencies {
            assert!(f > last_frequency);
            last_frequency = f;
        }
        assert_eq!(mc.frequencies.last(), Some(&1.0));

        assert_eq!(mc.frequencies.len(), 3);
        assert_eq!(mc.frequencies[0], 0.65);
        assert_eq!(mc.frequencies[1], 0.75);
        assert_eq!(mc.frequencies[2], 1.0);
    }

    #[test]
    #[should_panic]
    fn add_after_init() {
        let mut mc = MonteCarlo::new(100.0);
        mc.add(Box::new(DummyMove), 1.0);
        mc.setup(&System::new());
        mc.add(Box::new(DummyMove), 1.0);
    }
}
<|endoftext|>


<commit_before>extern crate gcc;

fn main() {
    let root = Path::new(std::os::getenv("CARGO_MANIFEST_DIR").unwrap())
        .join("libogg");

    let config = gcc::Config {
        include_directories: vec![
            root.join("include"),
        ],
        definitions: vec![
            ("_USRDLL".to_string(), None),
            ("LIBOGG_EXPORTS".to_string(), None)
        ],
        .. std::default::Default::default()
    };

    println!("cargo:include={}", root.join("include").display());

    let libfiles_root = root.join("src");

    gcc::compile_library("libogg.a", &config, &[
        libfiles_root.join("bitwise.c").as_str().unwrap(),
        libfiles_root.join("framing.c").as_str().unwrap(),
    ]);
}
<commit_msg>Fix paths to pass to gcc-rs<commit_after>extern crate gcc;

fn main() {
    let root = Path::new(std::os::getenv("CARGO_MANIFEST_DIR").unwrap())
        .join("libogg");

    let config = gcc::Config {
        include_directories: vec![
            root.join("include"),
        ],
        definitions: vec![
            ("_USRDLL".to_string(), None),
            ("LIBOGG_EXPORTS".to_string(), None)
        ],
        .. std::default::Default::default()
    };

    println!("cargo:include={}", root.join("include").display());

    gcc::compile_library("libogg.a", &config, &[
        "libogg/src/bitwise.c",
        "libogg/src/framing.c",
    ]);
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use PanicStrategy;
use target::TargetOptions;
use std::default::Default;

pub fn opts() -> TargetOptions {
    TargetOptions {
        pre_link_args: vec![
            // We want to be able to strip as much executable code as possible
            // from the linker command line, and this flag indicates to the
            // linker that it can avoid linking in dynamic libraries that don't
            // actually satisfy any symbols up to that point (as with many other
            // resolutions the linker does). This option only applies to all
            // following libraries so we're sure to pass it as one of the first
            // arguments.
            "-Wl,--as-needed".to_string(),

            // Always enable NX protection when it is available
            "-Wl,-z,noexecstack".to_string(),

            // Do not link libc
            "-nostdlib".to_string(),

            // Static link
            "-static".to_string()
        ],
        executables: true,
        relocation_model: "static".to_string(),
        disable_redzone: true,
        eliminate_frame_pointer: false,
        target_family: Some("redox".to_string()),
        linker_is_gnu: true,
        no_default_libraries: true,
        has_elf_tls: true,
        panic_strategy: PanicStrategy::Abort,
        .. Default::default()
    }
}
<commit_msg>Use alloc_system as default allocation crate<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use PanicStrategy;
use target::TargetOptions;
use std::default::Default;

pub fn opts() -> TargetOptions {
    TargetOptions {
        pre_link_args: vec![
            // We want to be able to strip as much executable code as possible
            // from the linker command line, and this flag indicates to the
            // linker that it can avoid linking in dynamic libraries that don't
            // actually satisfy any symbols up to that point (as with many other
            // resolutions the linker does). This option only applies to all
            // following libraries so we're sure to pass it as one of the first
            // arguments.
            "-Wl,--as-needed".to_string(),

            // Always enable NX protection when it is available
            "-Wl,-z,noexecstack".to_string(),

            // Do not link libc
            "-nostdlib".to_string(),

            // Static link
            "-static".to_string()
        ],
        executables: true,
        relocation_model: "static".to_string(),
        disable_redzone: true,
        eliminate_frame_pointer: false,
        target_family: Some("redox".to_string()),
        linker_is_gnu: true,
        no_default_libraries: true,
        lib_allocation_crate: "alloc_system".to_string(),
        exe_allocation_crate: "alloc_system".to_string(),
        has_elf_tls: true,
        panic_strategy: PanicStrategy::Abort,
        .. Default::default()
    }
}
<|endoftext|>


<commit_before>/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Copy)]
pub struct Struct_zmq_msg_t {
    pub unnamed_field1: [::libc::c_uchar; 32u],
}
pub type zmq_msg_t = Struct_zmq_msg_t;
pub type zmq_free_fn = ::libc::c_void;
#[repr(C)]
#[derive(Copy)]
pub struct Struct_Unnamed1 {
    pub event: uint16_t,
    pub value: int32_t,
}
pub type zmq_event_t = Struct_Unnamed1;
pub enum Struct_iovec { }
#[repr(C)]
#[derive(Copy)]
pub struct Struct_Unnamed2 {
    pub socket: *mut ::libc::c_void,
    pub fd: ::libc::c_int,
    pub events: ::libc::c_short,
    pub revents: ::libc::c_short,
}
pub type zmq_pollitem_t = Struct_Unnamed2;
#[link(name = "zmq")]
extern "C" { }
#[link(name = "zmq")]
extern "C" {
    pub fn zmq_version(major: *mut ::libc::c_int, minor: *mut ::libc::c_int,
                       patch: *mut ::libc::c_int);
    pub fn zmq_errno() -> ::libc::c_int;
    pub fn zmq_strerror(errnum: ::libc::c_int) -> *const ::libc::c_char;
    pub fn zmq_ctx_new() -> *mut ::libc::c_void;
    pub fn zmq_ctx_term(context: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_ctx_shutdown(ctx_: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_ctx_set(context: *mut ::libc::c_void, option: ::libc::c_int,
                       optval: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_ctx_get(context: *mut ::libc::c_void, option: ::libc::c_int)
     -> ::libc::c_int;
    pub fn zmq_init(io_threads: ::libc::c_int) -> *mut ::libc::c_void;
    pub fn zmq_term(context: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_ctx_destroy(context: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_msg_init(msg: *mut zmq_msg_t) -> ::libc::c_int;
    pub fn zmq_msg_init_size(msg: *mut zmq_msg_t, size: size_t)
     -> ::libc::c_int;
    pub fn zmq_msg_init_data(msg: *mut zmq_msg_t, data: *mut ::libc::c_void,
                             size: size_t, ffn: *mut zmq_free_fn,
                             hint: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_msg_send(msg: *mut zmq_msg_t, s: *mut ::libc::c_void,
                        flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_msg_recv(msg: *mut zmq_msg_t, s: *mut ::libc::c_void,
                        flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_msg_close(msg: *mut zmq_msg_t) -> ::libc::c_int;
    pub fn zmq_msg_move(dest: *mut zmq_msg_t, src: *mut zmq_msg_t)
     -> ::libc::c_int;
    pub fn zmq_msg_copy(dest: *mut zmq_msg_t, src: *mut zmq_msg_t)
     -> ::libc::c_int;
    pub fn zmq_msg_data(msg: *mut zmq_msg_t) -> *mut ::libc::c_void;
    pub fn zmq_msg_size(msg: *mut zmq_msg_t) -> size_t;
    pub fn zmq_msg_more(msg: *mut zmq_msg_t) -> ::libc::c_int;
    pub fn zmq_msg_get(msg: *mut zmq_msg_t, option: ::libc::c_int)
     -> ::libc::c_int;
    pub fn zmq_msg_set(msg: *mut zmq_msg_t, option: ::libc::c_int,
                       optval: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_socket(arg1: *mut ::libc::c_void, _type: ::libc::c_int)
     -> *mut ::libc::c_void;
    pub fn zmq_close(s: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_setsockopt(s: *mut ::libc::c_void, option: ::libc::c_int,
                          optval: *const ::libc::c_void, optvallen: size_t)
     -> ::libc::c_int;
    pub fn zmq_getsockopt(s: *mut ::libc::c_void, option: ::libc::c_int,
                          optval: *mut ::libc::c_void, optvallen: *mut size_t)
     -> ::libc::c_int;
    pub fn zmq_bind(s: *mut ::libc::c_void, addr: *const ::libc::c_char)
     -> ::libc::c_int;
    pub fn zmq_connect(s: *mut ::libc::c_void, addr: *const ::libc::c_char)
     -> ::libc::c_int;
    pub fn zmq_unbind(s: *mut ::libc::c_void, addr: *const ::libc::c_char)
     -> ::libc::c_int;
    pub fn zmq_disconnect(s: *mut ::libc::c_void, addr: *const ::libc::c_char)
     -> ::libc::c_int;
    pub fn zmq_send(s: *mut ::libc::c_void, buf: *const ::libc::c_void,
                    len: size_t, flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_send_const(s: *mut ::libc::c_void, buf: *const ::libc::c_void,
                          len: size_t, flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_recv(s: *mut ::libc::c_void, buf: *mut ::libc::c_void,
                    len: size_t, flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_socket_monitor(s: *mut ::libc::c_void,
                              addr: *const ::libc::c_char,
                              events: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_sendmsg(s: *mut ::libc::c_void, msg: *mut zmq_msg_t,
                       flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_recvmsg(s: *mut ::libc::c_void, msg: *mut zmq_msg_t,
                       flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_sendiov(s: *mut ::libc::c_void, iov: *mut Struct_iovec,
                       count: size_t, flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_recviov(s: *mut ::libc::c_void, iov: *mut Struct_iovec,
                       count: *mut size_t, flags: ::libc::c_int)
     -> ::libc::c_int;
    pub fn zmq_poll(items: *mut zmq_pollitem_t, nitems: ::libc::c_int,
                    timeout: ::libc::c_long) -> ::libc::c_int;
    pub fn zmq_proxy(frontend: *mut ::libc::c_void,
                     backend: *mut ::libc::c_void,
                     capture: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_proxy_steerable(frontend: *mut ::libc::c_void,
                               backend: *mut ::libc::c_void,
                               capture: *mut ::libc::c_void,
                               control: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_z85_encode(dest: *mut ::libc::c_char, data: *mut uint8_t,
                          size: size_t) -> *mut ::libc::c_char;
    pub fn zmq_z85_decode(dest: *mut uint8_t, string: *mut ::libc::c_char)
     -> *mut uint8_t;
    pub fn zmq_device(_type: ::libc::c_int, frontend: *mut ::libc::c_void,
                      backend: *mut ::libc::c_void) -> ::libc::c_int;
}
<commit_msg>32u -> 32us<commit_after>/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Copy)]
pub struct Struct_zmq_msg_t {
    pub unnamed_field1: [::libc::c_uchar; 32us],
}
pub type zmq_msg_t = Struct_zmq_msg_t;
pub type zmq_free_fn = ::libc::c_void;
#[repr(C)]
#[derive(Copy)]
pub struct Struct_Unnamed1 {
    pub event: uint16_t,
    pub value: int32_t,
}
pub type zmq_event_t = Struct_Unnamed1;
pub enum Struct_iovec { }
#[repr(C)]
#[derive(Copy)]
pub struct Struct_Unnamed2 {
    pub socket: *mut ::libc::c_void,
    pub fd: ::libc::c_int,
    pub events: ::libc::c_short,
    pub revents: ::libc::c_short,
}
pub type zmq_pollitem_t = Struct_Unnamed2;
#[link(name = "zmq")]
extern "C" { }
#[link(name = "zmq")]
extern "C" {
    pub fn zmq_version(major: *mut ::libc::c_int, minor: *mut ::libc::c_int,
                       patch: *mut ::libc::c_int);
    pub fn zmq_errno() -> ::libc::c_int;
    pub fn zmq_strerror(errnum: ::libc::c_int) -> *const ::libc::c_char;
    pub fn zmq_ctx_new() -> *mut ::libc::c_void;
    pub fn zmq_ctx_term(context: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_ctx_shutdown(ctx_: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_ctx_set(context: *mut ::libc::c_void, option: ::libc::c_int,
                       optval: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_ctx_get(context: *mut ::libc::c_void, option: ::libc::c_int)
     -> ::libc::c_int;
    pub fn zmq_init(io_threads: ::libc::c_int) -> *mut ::libc::c_void;
    pub fn zmq_term(context: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_ctx_destroy(context: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_msg_init(msg: *mut zmq_msg_t) -> ::libc::c_int;
    pub fn zmq_msg_init_size(msg: *mut zmq_msg_t, size: size_t)
     -> ::libc::c_int;
    pub fn zmq_msg_init_data(msg: *mut zmq_msg_t, data: *mut ::libc::c_void,
                             size: size_t, ffn: *mut zmq_free_fn,
                             hint: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_msg_send(msg: *mut zmq_msg_t, s: *mut ::libc::c_void,
                        flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_msg_recv(msg: *mut zmq_msg_t, s: *mut ::libc::c_void,
                        flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_msg_close(msg: *mut zmq_msg_t) -> ::libc::c_int;
    pub fn zmq_msg_move(dest: *mut zmq_msg_t, src: *mut zmq_msg_t)
     -> ::libc::c_int;
    pub fn zmq_msg_copy(dest: *mut zmq_msg_t, src: *mut zmq_msg_t)
     -> ::libc::c_int;
    pub fn zmq_msg_data(msg: *mut zmq_msg_t) -> *mut ::libc::c_void;
    pub fn zmq_msg_size(msg: *mut zmq_msg_t) -> size_t;
    pub fn zmq_msg_more(msg: *mut zmq_msg_t) -> ::libc::c_int;
    pub fn zmq_msg_get(msg: *mut zmq_msg_t, option: ::libc::c_int)
     -> ::libc::c_int;
    pub fn zmq_msg_set(msg: *mut zmq_msg_t, option: ::libc::c_int,
                       optval: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_socket(arg1: *mut ::libc::c_void, _type: ::libc::c_int)
     -> *mut ::libc::c_void;
    pub fn zmq_close(s: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_setsockopt(s: *mut ::libc::c_void, option: ::libc::c_int,
                          optval: *const ::libc::c_void, optvallen: size_t)
     -> ::libc::c_int;
    pub fn zmq_getsockopt(s: *mut ::libc::c_void, option: ::libc::c_int,
                          optval: *mut ::libc::c_void, optvallen: *mut size_t)
     -> ::libc::c_int;
    pub fn zmq_bind(s: *mut ::libc::c_void, addr: *const ::libc::c_char)
     -> ::libc::c_int;
    pub fn zmq_connect(s: *mut ::libc::c_void, addr: *const ::libc::c_char)
     -> ::libc::c_int;
    pub fn zmq_unbind(s: *mut ::libc::c_void, addr: *const ::libc::c_char)
     -> ::libc::c_int;
    pub fn zmq_disconnect(s: *mut ::libc::c_void, addr: *const ::libc::c_char)
     -> ::libc::c_int;
    pub fn zmq_send(s: *mut ::libc::c_void, buf: *const ::libc::c_void,
                    len: size_t, flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_send_const(s: *mut ::libc::c_void, buf: *const ::libc::c_void,
                          len: size_t, flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_recv(s: *mut ::libc::c_void, buf: *mut ::libc::c_void,
                    len: size_t, flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_socket_monitor(s: *mut ::libc::c_void,
                              addr: *const ::libc::c_char,
                              events: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_sendmsg(s: *mut ::libc::c_void, msg: *mut zmq_msg_t,
                       flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_recvmsg(s: *mut ::libc::c_void, msg: *mut zmq_msg_t,
                       flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_sendiov(s: *mut ::libc::c_void, iov: *mut Struct_iovec,
                       count: size_t, flags: ::libc::c_int) -> ::libc::c_int;
    pub fn zmq_recviov(s: *mut ::libc::c_void, iov: *mut Struct_iovec,
                       count: *mut size_t, flags: ::libc::c_int)
     -> ::libc::c_int;
    pub fn zmq_poll(items: *mut zmq_pollitem_t, nitems: ::libc::c_int,
                    timeout: ::libc::c_long) -> ::libc::c_int;
    pub fn zmq_proxy(frontend: *mut ::libc::c_void,
                     backend: *mut ::libc::c_void,
                     capture: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_proxy_steerable(frontend: *mut ::libc::c_void,
                               backend: *mut ::libc::c_void,
                               capture: *mut ::libc::c_void,
                               control: *mut ::libc::c_void) -> ::libc::c_int;
    pub fn zmq_z85_encode(dest: *mut ::libc::c_char, data: *mut uint8_t,
                          size: size_t) -> *mut ::libc::c_char;
    pub fn zmq_z85_decode(dest: *mut uint8_t, string: *mut ::libc::c_char)
     -> *mut uint8_t;
    pub fn zmq_device(_type: ::libc::c_int, frontend: *mut ::libc::c_void,
                      backend: *mut ::libc::c_void) -> ::libc::c_int;
}
<|endoftext|>