<commit_before>use std::rc::Rc;
use std::cell::RefCell;
use std::thread;
use std::ops::Deref;
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::intrinsics;
use std::raw::TraitObject;
use std::mem;

use bootstrap;
use bootstrap::window::Window;
use bootstrap::window::Message::*;
use bootstrap::time::Timer;
use bootstrap::gl_utils;

use bs_audio;

use polygon::gl_render::{self, GLRender};

use scene::Scene;
use resource::ResourceManager;
use ecs::System;
use component::*;

pub const TARGET_FRAME_TIME_SECONDS: f32 = 1.0 / 60.0;
pub const TARGET_FRAME_TIME_MS: f32 = TARGET_FRAME_TIME_SECONDS * 1000.0;

pub struct Engine {
    window: Rc<RefCell<Window>>, // TODO: This doesn't need to be an Rc<RefCell<>> when we're not doing hotloading.
    renderer: GLRender,
    resource_manager: Rc<RefCell<ResourceManager>>,

    systems: HashMap<TypeId, Box<System>>,
    system_names: HashMap<String, TypeId>,

    transform_update: Box<System>,
    light_update: Box<System>,
    audio_update: Box<System>,
    scene: Scene,

    close: bool,
}

impl Engine {
    pub fn new() -> Engine {
        let instance = bootstrap::init();
        let window = Window::new("Rust Window", instance);
        let renderer = gl_render::init(window.borrow().deref());
        let resource_manager = Rc::new(RefCell::new(ResourceManager::new(renderer)));

        let audio_source = match bs_audio::init() {
            Ok(audio_source) => {
                println!("Audio subsystem successfully initialized");
                audio_source
            },
            Err(error) => {
                panic!("Error while initialzing audio subsystem: {}", error)
            },
        };

        Engine {
            window: window.clone(),
            renderer: renderer,
            resource_manager: resource_manager.clone(),

            systems: HashMap::new(),
            system_names: HashMap::new(),

            transform_update: Box::new(TransformUpdateSystem),
            light_update: Box::new(LightUpdateSystem),
            audio_update: Box::new(AudioSystem),
            scene: Scene::new(&resource_manager, audio_source),

            close: false,
        }
    }

    pub fn update(&mut self) {
        let scene = &mut self.scene;

        scene.input.clear();
        let mut window = self.window.borrow_mut();
        window.handle_messages();
        loop {
            let message = window.next_message(); // TODO: Make this an iterator to simplify this loop.
            match message {
                Some(message) => {
                    match message {
                        Activate => (),
                        Close => self.close = true,
                        Destroy => (),
                        Paint => (),

                        // Handle inputs.
                        KeyDown(_)
                      | KeyUp(_)
                      | MouseMove(_, _)
                      | MousePos(_, _)
                      | MouseButtonPressed(_)
                      | MouseButtonReleased(_)
                      | MouseWheel(_) => scene.input.push_input(message),
                    }
                },
                None => break
            }
        }

        // Update systems.
        for (_, system) in self.systems.iter_mut() {
            system.update(scene, TARGET_FRAME_TIME_SECONDS);
        }

        self.transform_update.update(scene, TARGET_FRAME_TIME_SECONDS);
        self.light_update.update(scene, TARGET_FRAME_TIME_SECONDS);
        self.audio_update.update(scene, TARGET_FRAME_TIME_SECONDS);
    }

    pub fn draw(&mut self) {
        self.renderer.clear();

        let scene = &mut self.scene;
        let camera_manager = scene.get_manager::<CameraManager>();
        let transform_manager = scene.get_manager::<TransformManager>();
        let mesh_manager = scene.get_manager::<MeshManager>();
        let light_manager = scene.get_manager::<LightManager>();

        // Handle rendering for each camera.
        for (mut camera, entity) in camera_manager.iter_mut() {

            // TODO: Update the camera's bounds in a separate system.
            {
                let transform = transform_manager.get(entity);

                camera.position = transform.position_derived();
                camera.rotation = transform.rotation_derived();
            }

            // Draw all of the meshes.
            for (mesh, entity) in mesh_manager.iter() {
                let transform = transform_manager.get(entity);

                self.renderer.draw_mesh(
                    &mesh,
                    transform.derived_matrix(),
                    transform.derived_normal_matrix(),
                    &camera,
                    &mut light_manager.components().iter().map(|ref_cell| *ref_cell.borrow()));
            }
        }

        self.renderer.swap_buffers();
    }

    pub fn main_loop(&mut self) {
        let timer = Timer::new();

        loop {
            let start_time = timer.now();

            self.update();
            self.draw();

            if self.close {
                break;
            }

            // Wait for target frame time.
            let mut remaining_time_ms = TARGET_FRAME_TIME_MS - timer.elapsed_ms(start_time);
            while remaining_time_ms > 1.0 {
                thread::sleep_ms(remaining_time_ms as u32);
                remaining_time_ms = TARGET_FRAME_TIME_MS - timer.elapsed_ms(start_time);
            }

            while remaining_time_ms > 0.0 {
                remaining_time_ms = TARGET_FRAME_TIME_MS - timer.elapsed_ms(start_time);
            }

            // TODO: Don't flip buffers until end of frame time?
        };
    }

    pub fn register_system<T: Any + System>(&mut self, system: T) {
        let system_id = TypeId::of::<T>();
        assert!(!self.systems.contains_key(&system_id),
                "System {} with ID {:?} already registered", type_name::<T>(), system_id);

        self.systems.insert(system_id, Box::new(system));
        self.system_names.insert(type_name::<T>().into(), system_id);
    }

    pub fn get_system<T: Any + System>(&self) -> &T {
        let system_id = TypeId::of::<T>();
        let system = self.systems.get(&system_id).unwrap().deref();

        unsafe {
            // Get the raw representation of the trait object.
            let to: TraitObject = mem::transmute(system);

            // Extract the data pointer.
            mem::transmute(to.data)
        }
    }

    pub fn get_system_by_name<T: Any + System>(&self) -> &T {
        let system_id = self.system_names.get(type_name::<T>()).unwrap();
        let system = self.systems.get(&system_id).unwrap().deref();

        unsafe {
            // Get the raw representation of the trait object.
            let to: TraitObject = mem::transmute(system);

            // Extract the data pointer.
            mem::transmute(to.data)
        }
    }

    pub fn scene(&self) -> &Scene {
        &self.scene
    }

    pub fn scene_mut(&mut self) -> &mut Scene {
        &mut self.scene
    }

    pub fn close(&self) -> bool {
        self.close
    }
}

impl Clone for Engine {
    fn clone(&self) -> Engine {
        let resource_manager = Rc::new(RefCell::new(self.resource_manager.borrow().deref().clone()));

        let engine = Engine {
            window: self.window.clone(),
            renderer: self.renderer.clone(),
            resource_manager: resource_manager.clone(),

            systems: HashMap::new(),
            system_names: HashMap::new(),

            transform_update: Box::new(TransformUpdateSystem),
            light_update: Box::new(LightUpdateSystem),
            audio_update: Box::new(AudioSystem),
            scene: self.scene.clone(&resource_manager),

            close: false,
        };

        engine
    }
}

fn type_name<T>() -> &'static str {
    unsafe {
        intrinsics::type_name::<T>()
    }
}

#[no_mangle]
pub fn engine_init(window: Rc<RefCell<Window>>) -> Box<Engine> {
    let renderer = gl_render::init(window.borrow().deref());
    let resource_manager = Rc::new(RefCell::new(ResourceManager::new(renderer)));

    let audio_source = match bs_audio::init() {
        Ok(audio_source) => {
            println!("Audio subsystem successfully initialized");
            audio_source
        },
        Err(error) => {
            panic!("Error while initialzing audio subsystem: {}", error)
        },
    };

    Box::new(Engine {
        window: window,
        renderer: renderer,
        resource_manager: resource_manager.clone(),

        systems: HashMap::new(),
        system_names: HashMap::new(),

        transform_update: Box::new(TransformUpdateSystem),
        light_update: Box::new(LightUpdateSystem),
        audio_update: Box::new(AudioSystem),
        scene: Scene::new(&resource_manager, audio_source),

        close: false,
    })
}

#[no_mangle]
pub fn engine_reload(engine: &Engine) -> Box<Engine> {
    let new_engine = engine.clone();

    // The proc loader needs to be set from within the DLL otherwise we don't
    // correctly bind to OpenGL on Windows.
    gl_utils::set_proc_loader();

    Box::new(new_engine)
}

#[no_mangle]
pub fn engine_update_and_render(engine: &mut Engine) {
    engine.update();
    engine.draw();
}

#[no_mangle]
pub fn engine_close(engine: &Engine) -> bool {
    engine.close()
}

#[no_mangle]
pub fn engine_drop(engine: Box<Engine>) {
    drop(engine);
}
<commit_msg>Ordered System Update<commit_after>use std::rc::Rc;
use std::cell::RefCell;
use std::thread;
use std::ops::Deref;
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::intrinsics;
use std::raw::TraitObject;
use std::mem;

use bootstrap;
use bootstrap::window::Window;
use bootstrap::window::Message::*;
use bootstrap::time::Timer;
use bootstrap::gl_utils;

use bs_audio;

use polygon::gl_render::{self, GLRender};

use scene::Scene;
use resource::ResourceManager;
use ecs::System;
use component::*;

pub const TARGET_FRAME_TIME_SECONDS: f32 = 1.0 / 60.0;
pub const TARGET_FRAME_TIME_MS: f32 = TARGET_FRAME_TIME_SECONDS * 1000.0;

pub struct Engine {
    window: Rc<RefCell<Window>>, // TODO: This doesn't need to be an Rc<RefCell<>> when we're not doing hotloading.
    renderer: GLRender,
    resource_manager: Rc<RefCell<ResourceManager>>,

    systems: Vec<Box<System>>,
    system_indices: HashMap<TypeId, usize>,
    system_names: HashMap<String, TypeId>,

    transform_update: Box<System>,
    light_update: Box<System>,
    audio_update: Box<System>,
    scene: Scene,

    close: bool,
}

impl Engine {
    pub fn new() -> Engine {
        let instance = bootstrap::init();
        let window = Window::new("Rust Window", instance);
        let renderer = gl_render::init(window.borrow().deref());
        let resource_manager = Rc::new(RefCell::new(ResourceManager::new(renderer)));

        let audio_source = match bs_audio::init() {
            Ok(audio_source) => {
                println!("Audio subsystem successfully initialized");
                audio_source
            },
            Err(error) => {
                panic!("Error while initialzing audio subsystem: {}", error)
            },
        };

        Engine {
            window: window.clone(),
            renderer: renderer,
            resource_manager: resource_manager.clone(),

            systems: Vec::new(),
            system_indices: HashMap::new(),
            system_names: HashMap::new(),

            transform_update: Box::new(TransformUpdateSystem),
            light_update: Box::new(LightUpdateSystem),
            audio_update: Box::new(AudioSystem),
            scene: Scene::new(&resource_manager, audio_source),

            close: false,
        }
    }

    pub fn update(&mut self) {
        let scene = &mut self.scene;

        scene.input.clear();
        let mut window = self.window.borrow_mut();
        window.handle_messages();
        loop {
            let message = window.next_message(); // TODO: Make this an iterator to simplify this loop.
            match message {
                Some(message) => {
                    match message {
                        Activate => (),
                        Close => self.close = true,
                        Destroy => (),
                        Paint => (),

                        // Handle inputs.
                        KeyDown(_)
                      | KeyUp(_)
                      | MouseMove(_, _)
                      | MousePos(_, _)
                      | MouseButtonPressed(_)
                      | MouseButtonReleased(_)
                      | MouseWheel(_) => scene.input.push_input(message),
                    }
                },
                None => break
            }
        }

        // Update systems.
        for system in self.systems.iter_mut() {
            system.update(scene, TARGET_FRAME_TIME_SECONDS);
        }

        self.transform_update.update(scene, TARGET_FRAME_TIME_SECONDS);
        self.light_update.update(scene, TARGET_FRAME_TIME_SECONDS);
        self.audio_update.update(scene, TARGET_FRAME_TIME_SECONDS);
    }

    pub fn draw(&mut self) {
        self.renderer.clear();

        let scene = &mut self.scene;
        let camera_manager = scene.get_manager::<CameraManager>();
        let transform_manager = scene.get_manager::<TransformManager>();
        let mesh_manager = scene.get_manager::<MeshManager>();
        let light_manager = scene.get_manager::<LightManager>();

        // Handle rendering for each camera.
        for (mut camera, entity) in camera_manager.iter_mut() {

            // TODO: Update the camera's bounds in a separate system.
            {
                let transform = transform_manager.get(entity);

                camera.position = transform.position_derived();
                camera.rotation = transform.rotation_derived();
            }

            // Draw all of the meshes.
            for (mesh, entity) in mesh_manager.iter() {
                let transform = transform_manager.get(entity);

                self.renderer.draw_mesh(
                    &mesh,
                    transform.derived_matrix(),
                    transform.derived_normal_matrix(),
                    &camera,
                    &mut light_manager.components().iter().map(|ref_cell| *ref_cell.borrow()));
            }
        }

        self.renderer.swap_buffers();
    }

    pub fn main_loop(&mut self) {
        let timer = Timer::new();

        loop {
            let start_time = timer.now();

            self.update();
            self.draw();

            if self.close {
                break;
            }

            // Wait for target frame time.
            let mut remaining_time_ms = TARGET_FRAME_TIME_MS - timer.elapsed_ms(start_time);
            while remaining_time_ms > 1.0 {
                thread::sleep_ms(remaining_time_ms as u32);
                remaining_time_ms = TARGET_FRAME_TIME_MS - timer.elapsed_ms(start_time);
            }

            while remaining_time_ms > 0.0 {
                remaining_time_ms = TARGET_FRAME_TIME_MS - timer.elapsed_ms(start_time);
            }

            // TODO: Don't flip buffers until end of frame time?
        };
    }

    pub fn register_system<T: Any + System>(&mut self, system: T) {
        let system_id = TypeId::of::<T>();
        assert!(!self.system_indices.contains_key(&system_id),
                "System {} with ID {:?} already registered", type_name::<T>(), system_id);

        let index = self.systems.len();
        self.systems.push(Box::new(system));
        self.system_indices.insert(system_id, index);
        self.system_names.insert(type_name::<T>().into(), system_id);
    }

    pub fn get_system<T: Any + System>(&self) -> &T {
        let system_id = TypeId::of::<T>();
        let index =
            *self.system_indices.get(&system_id)
            .expect(&format!("Trying to retrive system {} but no index found", type_name::<T>()));
        let system = &*self.systems[index];

        unsafe {
            // Get the raw representation of the trait object.
            let to: TraitObject = mem::transmute(system);

            // Extract the data pointer.
            mem::transmute(to.data)
        }
    }

    pub fn get_system_by_name<T: Any + System>(&self) -> &T {
        let system_id = self.system_names.get(type_name::<T>()).unwrap();
        let index =
            *self.system_indices.get(system_id)
            .expect(&format!("Trying to retrive system {} but no index found", type_name::<T>()));
        let system = &*self.systems[index];

        unsafe {
            // Get the raw representation of the trait object.
            let to: TraitObject = mem::transmute(system);

            // Extract the data pointer.
            mem::transmute(to.data)
        }
    }

    pub fn scene(&self) -> &Scene {
        &self.scene
    }

    pub fn scene_mut(&mut self) -> &mut Scene {
        &mut self.scene
    }

    pub fn close(&self) -> bool {
        self.close
    }
}

impl Clone for Engine {
    fn clone(&self) -> Engine {
        let resource_manager = Rc::new(RefCell::new(self.resource_manager.borrow().deref().clone()));

        let engine = Engine {
            window: self.window.clone(),
            renderer: self.renderer.clone(),
            resource_manager: resource_manager.clone(),

            systems: Vec::new(),
            system_indices: HashMap::new(),
            system_names: HashMap::new(),

            transform_update: Box::new(TransformUpdateSystem),
            light_update: Box::new(LightUpdateSystem),
            audio_update: Box::new(AudioSystem),
            scene: self.scene.clone(&resource_manager),

            close: false,
        };

        engine
    }
}

fn type_name<T>() -> &'static str {
    unsafe {
        intrinsics::type_name::<T>()
    }
}

#[no_mangle]
pub fn engine_init(window: Rc<RefCell<Window>>) -> Box<Engine> {
    let renderer = gl_render::init(window.borrow().deref());
    let resource_manager = Rc::new(RefCell::new(ResourceManager::new(renderer)));

    let audio_source = match bs_audio::init() {
        Ok(audio_source) => {
            println!("Audio subsystem successfully initialized");
            audio_source
        },
        Err(error) => {
            panic!("Error while initialzing audio subsystem: {}", error)
        },
    };

    Box::new(Engine {
        window: window,
        renderer: renderer,
        resource_manager: resource_manager.clone(),

        systems: Vec::new(),
        system_indices: HashMap::new(),
        system_names: HashMap::new(),

        transform_update: Box::new(TransformUpdateSystem),
        light_update: Box::new(LightUpdateSystem),
        audio_update: Box::new(AudioSystem),
        scene: Scene::new(&resource_manager, audio_source),

        close: false,
    })
}

#[no_mangle]
pub fn engine_reload(engine: &Engine) -> Box<Engine> {
    let new_engine = engine.clone();

    // The proc loader needs to be set from within the DLL otherwise we don't
    // correctly bind to OpenGL on Windows.
    gl_utils::set_proc_loader();

    Box::new(new_engine)
}

#[no_mangle]
pub fn engine_update_and_render(engine: &mut Engine) {
    engine.update();
    engine.draw();
}

#[no_mangle]
pub fn engine_close(engine: &Engine) -> bool {
    engine.close()
}

#[no_mangle]
pub fn engine_drop(engine: Box<Engine>) {
    drop(engine);
}
<|endoftext|>


<commit_before>use id::Id;
use timestamp::Timestamp;

/// Describes an entity that exists anywhere in the game.
///
/// The game dictates that when entities move to different zones, they actually
/// become new entities (with new IDs!). That motivates the idea that the entity
/// itself should be lightweight and replacable, with most of the interesting
/// data living inside another, persistent object.
#[derive(Debug, Clone)]
pub struct Entity {
    pub id: Id,
    pub zone: Id,
    pub timestamp: Timestamp,
}
<commit_msg>Splat down thoughts about entity representation<commit_after>use id::Id;
use timestamp::Timestamp;

/// Represents the various kinds of entity that exist in the game rules.
///
/// I'm not sure if this is sufficient! I think all of the variants of this enum
/// will probably need associated data, like a card/ability descriptor ID.
#[derive(Debug, Clone)]
pub enum EntityKind {
    /// Any entity backed by a unique card
    Card,
    Token,
    Emblem,
    Ability,

    // TODO: Represent copy of another entity without Box or recursive types?
}

/// Describes an entity that exists anywhere in the game.
///
/// The game dictates that when entities move to different zones, they actually
/// become new entities (with new IDs!). That motivates the idea that the entity
/// itself should be lightweight and replacable, with most of the interesting
/// data living inside another, persistent object.
///
/// We'll need to represent several kinds of entity:
/// * Cards
///     * Permanents and non-permanents on the battlefield
///     * Cards in a graveyard, library, or hand
///     * Spells on the stack
/// * Tokens
///     * Unique tokens, like 2/2 zombies
///     * Copies of cards
/// * Emblems
/// * Abilities on the stack, never represented by a card
/// * Copies of spells on the stack
#[derive(Debug, Clone)]
pub struct Entity {
    pub id: Id,
    pub zone: Id,
    pub timestamp: Timestamp,
    pub kind: EntityKind,
}
<|endoftext|>


<commit_before>use std::ops::Deref;
pub use transform::*;

/// An entity is anything that has spatial property.
#[derive(Debug)]
pub struct Entity<T> {
  pub object: T,
  pub transform: Transform
}

impl<T> Entity<T> {
  pub fn new(object: T, transform: Transform) -> Self {
    Entity {
      object: object,
      transform: transform
    }
  }
}

impl<T> Deref for Entity<T> {
  type Target = Transform;

  fn deref(&self) -> &Self::Target {
    &self.transform
  }
}
<commit_msg>Removed Deref<Target=Transform> impl for Entity as it’s error-prone.<commit_after>pub use transform::Transform;

/// An entity is anything that has spatial properties (i.e. a `Transform`).
#[derive(Debug)]
pub struct Entity<T> {
  pub object: T,
  pub transform: Transform
}

impl<T> Entity<T> {
  pub fn new(object: T, transform: Transform) -> Self {
    Entity {
      object: object,
      transform: transform
    }
  }
}
<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::collections::HashMap;
use std::path::*;
use std::string::String;

use case::*;
use env::Env;
use analysis::namespaces;

pub fn split_namespace_name(name: &str) -> (Option<&str>, &str) {
    let mut parts = name.split('.');
    let name = parts.next_back().unwrap();
    let ns = parts.next_back();
    assert!(ns.is_none() || parts.next().is_none());
    (ns, name)
}

/* unused :(
pub fn strip_suffix<'a>(name: &'a str, suffix: &str) -> Option<&'a str> {
    if name.ends_with(suffix) {
        Some(&name[..name.len() - suffix.len()])
    }
    else {
        None
    }
}
*/

pub fn file_name_sys(name: &str) -> String {
    let mut path = PathBuf::from(name);
    let added = path.set_extension("rs");
    assert!(added);
    path.to_str().unwrap().into()
}

pub fn crate_name(name: &str) -> String {
    let name = name.to_snake();
    if name.starts_with("g_") {
        format!("g{}", &name[2..])
    } else {
        name
    }
}

pub fn exported_crate_name(crate_name: &str) -> String {
    crate_name.replace("_", "-")
}

pub fn ffi_crate_name(name: &str, env: &Env) -> String {
    let id = env.library.find_namespace(name).expect("namespace from crate name");
    if id == namespaces::MAIN {
        return "ffi".to_string();
    }
    let namespace = env.library.namespace(id);
    let name = crate_name(&namespace.name);
    format!("{}_ffi", name)
}

pub fn module_name(name: &str) -> String {
    mangle_keywords(name.to_snake()).into_owned()
}

pub fn enum_member_name(name: &str) -> String {
    if name.starts_with(char::is_alphabetic) {
        name.to_camel()
    } else {
        format!("_{}", name.to_camel())
    }
}

pub fn bitfield_member_name(name: &str) -> String {
    if name.starts_with(char::is_alphabetic) {
        name.to_uppercase()
    } else {
        format!("_{}", name.to_uppercase())
    }
}

pub fn needs_mangling(name: &str) -> bool {
    KEYWORDS.contains_key(name)
}

// If the mangling happened, guaranteed to return Owned.
pub fn mangle_keywords<'a, S: Into<Cow<'a, str>>>(name: S) -> Cow<'a, str> {
    let name = name.into();
    if let Some(s) = KEYWORDS.get(&*name) {
        s.clone().into()
    } else {
        name
    }
}

lazy_static! {
    static ref KEYWORDS: HashMap<&'static str, String> = {
        let mut map = HashMap::new();
        [
            "abstract", "alignof", "as", "become", "box", "break", "const",
            "continue", "crate", "do", "else", "enum", "extern", "false", "final",
            "fn", "for", "if", "impl", "in", "let", "loop", "macro", "match", "mod",
            "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
            "ref", "return", "Self", "self", "sizeof", "static", "struct", "super",
            "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual",
            "where", "while", "yield",
        ].iter().map(|k| map.insert(*k, format!("{}_", k))).count();
        map
    };
}

pub fn signal_to_snake(signal: &str) -> String {
    signal.replace("::", "_").replace('-', "_")
}

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

    #[test]
    fn split_no_namespace() {
        let (ns, name) = split_namespace_name("GObject");
        assert_eq!(ns, None);
        assert_eq!(name, "GObject");
    }

    #[test]
    fn split_full_name() {
        let (ns, name) = split_namespace_name("Gtk.StatusIcon");
        assert_eq!(ns, Some("Gtk"));
        assert_eq!(name, "StatusIcon");
    }

    /*
    #[test]
    fn strip_prefix_g() {
        assert_eq!(strip_prefix("G", "GBusType"), "BusType");
        assert_eq!(strip_prefix("G", "G_BUS_TYPE_NONE"), "BUS_TYPE_NONE");
    }

    #[test]
    fn strip_prefix_gtk() {
        assert_eq!(strip_prefix("Gtk", "GtkAlign"), "Align");
        assert_eq!(strip_prefix("Gtk", "GTK_ALIGN_FILL"), "ALIGN_FILL");
    }
    */

    #[test]
    fn crate_name_works() {
        assert_eq!(crate_name("GdkPixbuf"), "gdk_pixbuf");
        assert_eq!(crate_name("GLib"), "glib");
        assert_eq!(crate_name("Gtk"), "gtk");
    }

    #[test]
    fn file_name_sys_works() {
        assert_eq!(file_name_sys("funcs"), "funcs.rs");
    }

    #[test]
    fn signal_to_snake_works() {
        assert_eq!(signal_to_snake("changed"), "changed");
        assert_eq!(signal_to_snake("move-active"), "move_active");
    }
}
<commit_msg>Add comments for crate-names functions<commit_after>use std::borrow::Cow;
use std::collections::HashMap;
use std::path::*;
use std::string::String;

use case::*;
use env::Env;
use analysis::namespaces;

pub fn split_namespace_name(name: &str) -> (Option<&str>, &str) {
    let mut parts = name.split('.');
    let name = parts.next_back().unwrap();
    let ns = parts.next_back();
    assert!(ns.is_none() || parts.next().is_none());
    (ns, name)
}

/* unused :(
pub fn strip_suffix<'a>(name: &'a str, suffix: &str) -> Option<&'a str> {
    if name.ends_with(suffix) {
        Some(&name[..name.len() - suffix.len()])
    }
    else {
        None
    }
}
*/

pub fn file_name_sys(name: &str) -> String {
    let mut path = PathBuf::from(name);
    let added = path.set_extension("rs");
    assert!(added);
    path.to_str().unwrap().into()
}

/// Crate name with undescores for `use` statement
pub fn crate_name(name: &str) -> String {
    let name = name.to_snake();
    if name.starts_with("g_") {
        format!("g{}", &name[2..])
    } else {
        name
    }
}

/// Crate name with '-' for Cargo.toml etc.
pub fn exported_crate_name(crate_name: &str) -> String {
    crate_name.replace("_", "-")
}

/// Crate name for FFI part, like "gtk-sys"
/// with underscors for `use` statement
pub fn ffi_crate_name(name: &str, env: &Env) -> String {
    let id = env.library.find_namespace(name).expect("namespace from crate name");
    if id == namespaces::MAIN {
        return "ffi".to_string();
    }
    let namespace = env.library.namespace(id);
    let name = crate_name(&namespace.name);
    format!("{}_ffi", name)
}

pub fn module_name(name: &str) -> String {
    mangle_keywords(name.to_snake()).into_owned()
}

pub fn enum_member_name(name: &str) -> String {
    if name.starts_with(char::is_alphabetic) {
        name.to_camel()
    } else {
        format!("_{}", name.to_camel())
    }
}

pub fn bitfield_member_name(name: &str) -> String {
    if name.starts_with(char::is_alphabetic) {
        name.to_uppercase()
    } else {
        format!("_{}", name.to_uppercase())
    }
}

pub fn needs_mangling(name: &str) -> bool {
    KEYWORDS.contains_key(name)
}

// If the mangling happened, guaranteed to return Owned.
pub fn mangle_keywords<'a, S: Into<Cow<'a, str>>>(name: S) -> Cow<'a, str> {
    let name = name.into();
    if let Some(s) = KEYWORDS.get(&*name) {
        s.clone().into()
    } else {
        name
    }
}

lazy_static! {
    static ref KEYWORDS: HashMap<&'static str, String> = {
        let mut map = HashMap::new();
        [
            "abstract", "alignof", "as", "become", "box", "break", "const",
            "continue", "crate", "do", "else", "enum", "extern", "false", "final",
            "fn", "for", "if", "impl", "in", "let", "loop", "macro", "match", "mod",
            "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
            "ref", "return", "Self", "self", "sizeof", "static", "struct", "super",
            "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual",
            "where", "while", "yield",
        ].iter().map(|k| map.insert(*k, format!("{}_", k))).count();
        map
    };
}

pub fn signal_to_snake(signal: &str) -> String {
    signal.replace("::", "_").replace('-', "_")
}

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

    #[test]
    fn split_no_namespace() {
        let (ns, name) = split_namespace_name("GObject");
        assert_eq!(ns, None);
        assert_eq!(name, "GObject");
    }

    #[test]
    fn split_full_name() {
        let (ns, name) = split_namespace_name("Gtk.StatusIcon");
        assert_eq!(ns, Some("Gtk"));
        assert_eq!(name, "StatusIcon");
    }

    /*
    #[test]
    fn strip_prefix_g() {
        assert_eq!(strip_prefix("G", "GBusType"), "BusType");
        assert_eq!(strip_prefix("G", "G_BUS_TYPE_NONE"), "BUS_TYPE_NONE");
    }

    #[test]
    fn strip_prefix_gtk() {
        assert_eq!(strip_prefix("Gtk", "GtkAlign"), "Align");
        assert_eq!(strip_prefix("Gtk", "GTK_ALIGN_FILL"), "ALIGN_FILL");
    }
    */

    #[test]
    fn crate_name_works() {
        assert_eq!(crate_name("GdkPixbuf"), "gdk_pixbuf");
        assert_eq!(crate_name("GLib"), "glib");
        assert_eq!(crate_name("Gtk"), "gtk");
    }

    #[test]
    fn file_name_sys_works() {
        assert_eq!(file_name_sys("funcs"), "funcs.rs");
    }

    #[test]
    fn signal_to_snake_works() {
        assert_eq!(signal_to_snake("changed"), "changed");
        assert_eq!(signal_to_snake("move-active"), "move_active");
    }
}
<|endoftext|>


<commit_before>use crate::{channel::Reply, Error, Promise, PromiseResolver};
use amq_protocol::frame::AMQPFrame;
use log::{log_enabled, trace, Level::Trace};
use parking_lot::Mutex;
use pinky_swear::Cancellable;
use std::{
    collections::{HashMap, VecDeque},
    fmt,
    sync::Arc,
};

pub(crate) struct ExpectedReply(
    pub(crate) Reply,
    pub(crate) Box<dyn Cancellable<Error> + Send>,
);

impl fmt::Debug for ExpectedReply {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("ExpectedReply").field(&self.0).finish()
    }
}

#[derive(Clone, Default)]
pub(crate) struct Frames {
    inner: Arc<Mutex<Inner>>,
}

impl Frames {
    pub(crate) fn push(
        &self,
        channel_id: u16,
        frame: AMQPFrame,
        resolver: PromiseResolver<()>,
        expected_reply: Option<ExpectedReply>,
    ) {
        self.inner
            .lock()
            .push(channel_id, frame, resolver, expected_reply);
    }

    pub(crate) fn push_frames(&self, frames: Vec<AMQPFrame>) -> Promise<()> {
        self.inner.lock().push_frames(frames)
    }

    pub(crate) fn retry(&self, frame: (AMQPFrame, Option<PromiseResolver<()>>)) {
        self.inner.lock().retry_frames.push_back(frame);
    }

    pub(crate) fn pop(&self, flow: bool) -> Option<(AMQPFrame, Option<PromiseResolver<()>>)> {
        self.inner.lock().pop(flow)
    }

    pub(crate) fn next_expected_reply(&self, channel_id: u16) -> Option<Reply> {
        self.inner
            .lock()
            .expected_replies
            .get_mut(&channel_id)
            .and_then(|replies| replies.pop_front())
            .map(|t| t.0)
    }

    pub(crate) fn next_expected_close_ok_reply(&self, channel_id: u16, error: Error) -> Option<Reply> {
        self.inner.lock().next_expected_close_ok_reply(channel_id, error)
    }

    pub(crate) fn has_pending(&self) -> bool {
        self.inner.lock().has_pending()
    }

    pub(crate) fn drop_pending(&self, error: Error) {
        self.inner.lock().drop_pending(error);
    }

    pub(crate) fn clear_expected_replies(&self, channel_id: u16, error: Error) {
        self.inner.lock().clear_expected_replies(channel_id, error);
    }
}

struct Inner {
    /* Header frames must follow basic.publish frames directly, otherwise RabbitMQ-server send us an UNEXPECTED_FRAME */
    /* After sending the Header frame, we need to send the associated Body frames before anything else for the same reason */
    publish_frames: VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
    retry_frames: VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
    frames: VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
    low_prio_frames: VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
    expected_replies: HashMap<u16, VecDeque<ExpectedReply>>,
}

impl Default for Inner {
    fn default() -> Self {
        Self {
            publish_frames: VecDeque::default(),
            retry_frames: VecDeque::default(),
            frames: VecDeque::default(),
            low_prio_frames: VecDeque::default(),
            expected_replies: HashMap::default(),
        }
    }
}

impl fmt::Debug for Frames {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut debug = f.debug_struct("Frames");
        if let Some(inner) = self.inner.try_lock() {
            debug.field("expected_replies", &inner.expected_replies);
        }
        debug.finish()
    }
}

impl Inner {
    fn push(
        &mut self,
        channel_id: u16,
        frame: AMQPFrame,
        resolver: PromiseResolver<()>,
        expected_reply: Option<ExpectedReply>,
    ) {
        self.frames.push_back((frame, Some(resolver)));
        if let Some(reply) = expected_reply {
            trace!(
                "channel {} state is now waiting for {:?}",
                channel_id,
                reply
            );
            self.expected_replies
                .entry(channel_id)
                .or_default()
                .push_back(reply);
        }
    }

    fn push_frames(&mut self, mut frames: Vec<AMQPFrame>) -> Promise<()> {
        let (promise, resolver) = Promise::new();
        let last_frame = frames.pop();

        if log_enabled!(Trace) {
            promise.set_marker("Frames".into());
        }

        for frame in frames {
            self.low_prio_frames.push_back((frame, None));
        }
        if let Some(last_frame) = last_frame {
            self.low_prio_frames.push_back((last_frame, Some(resolver)));
        } else {
            resolver.swear(Ok(()));
        }

        promise
    }

    fn pop(&mut self, flow: bool) -> Option<(AMQPFrame, Option<PromiseResolver<()>>)> {
        if let Some(frame) = self
            .retry_frames
            .pop_front()
            .or_else(|| self.publish_frames.pop_front())
            .or_else(|| self.frames.pop_front())
        {
            return Some(frame);
        }
        if flow {
            if let Some(frame) = self.low_prio_frames.pop_front() {
                // If the next frame is a header, that means we're a basic.publish
                // Header frame needs to follow directly the basic.publish frame, and Body frames
                // need to be sent just after those or the AMQP server will close the connection.
                // Push the header into publish_frames which is there to handle just that.
                if self
                    .low_prio_frames
                    .front()
                    .map(|(frame, _)| frame.is_header())
                    .unwrap_or(false)
                {
                    // Yes, this will always be Some() with a Header frame, but let's keep our unwrap() count low
                    if let Some(next_frame) = self.low_prio_frames.pop_front() {
                        self.publish_frames.push_back(next_frame);
                    }
                    while let Some(next_frame) = self.low_prio_frames.pop_front() {
                        match next_frame.0 {
                            AMQPFrame::Body(..) => {
                                self.publish_frames.push_back(next_frame);
                            }
                            _ => {
                                // We've exhausted Body frames for this publish, push back the next one and exit
                                self.low_prio_frames.push_front(next_frame);
                                break;
                            }
                        }
                    }
                }
                return Some(frame);
            }
        }
        None
    }

    fn has_pending(&self) -> bool {
        !(self.retry_frames.is_empty()
            && self.publish_frames.is_empty()
            && self.frames.is_empty()
            && self.low_prio_frames.is_empty())
    }

    fn drop_pending(&mut self, error: Error) {
        Self::drop_pending_frames(&mut self.retry_frames, error.clone());
        Self::drop_pending_frames(&mut self.publish_frames, error.clone());
        Self::drop_pending_frames(&mut self.frames, error.clone());
        Self::drop_pending_frames(&mut self.low_prio_frames, error.clone());
        for (_, replies) in self.expected_replies.drain() {
            Self::cancel_expected_replies(replies, error.clone());
        }
    }

    fn drop_pending_frames(
        frames: &mut VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
        error: Error,
    ) {
        for (_, resolver) in std::mem::take(frames) {
            if let Some(resolver) = resolver {
                resolver.swear(Err(error.clone()));
            }
        }
    }

    fn next_expected_close_ok_reply(&mut self, channel_id: u16, error: Error) -> Option<Reply> {
        let expected_replies = self.expected_replies.get_mut(&channel_id)?;
        while let Some(reply) = expected_replies.pop_front() {
            match &reply.0 {
                Reply::ChannelCloseOk(_) => return Some(reply.0),
                Reply::BasicCancelOk(pinky) => pinky.swear(Ok(())), // Channel close means consumer is canceled automatically
                _ => reply.1.cancel(error.clone()),
            }
        }
        None
    }

    fn clear_expected_replies(&mut self, channel_id: u16, error: Error) {
        if let Some(replies) = self.expected_replies.remove(&channel_id) {
            Self::cancel_expected_replies(replies, error);
        }
    }

    fn cancel_expected_replies(replies: VecDeque<ExpectedReply>, error: Error) {
        for ExpectedReply(_, cancel) in replies {
            cancel.cancel(error.clone());
        }
    }
}
<commit_msg>frames: consider a channel close/error as a success for basic cancel<commit_after>use crate::{channel::Reply, Error, Promise, PromiseResolver};
use amq_protocol::frame::AMQPFrame;
use log::{log_enabled, trace, Level::Trace};
use parking_lot::Mutex;
use pinky_swear::Cancellable;
use std::{
    collections::{HashMap, VecDeque},
    fmt,
    sync::Arc,
};

pub(crate) struct ExpectedReply(
    pub(crate) Reply,
    pub(crate) Box<dyn Cancellable<Error> + Send>,
);

impl fmt::Debug for ExpectedReply {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("ExpectedReply").field(&self.0).finish()
    }
}

#[derive(Clone, Default)]
pub(crate) struct Frames {
    inner: Arc<Mutex<Inner>>,
}

impl Frames {
    pub(crate) fn push(
        &self,
        channel_id: u16,
        frame: AMQPFrame,
        resolver: PromiseResolver<()>,
        expected_reply: Option<ExpectedReply>,
    ) {
        self.inner
            .lock()
            .push(channel_id, frame, resolver, expected_reply);
    }

    pub(crate) fn push_frames(&self, frames: Vec<AMQPFrame>) -> Promise<()> {
        self.inner.lock().push_frames(frames)
    }

    pub(crate) fn retry(&self, frame: (AMQPFrame, Option<PromiseResolver<()>>)) {
        self.inner.lock().retry_frames.push_back(frame);
    }

    pub(crate) fn pop(&self, flow: bool) -> Option<(AMQPFrame, Option<PromiseResolver<()>>)> {
        self.inner.lock().pop(flow)
    }

    pub(crate) fn next_expected_reply(&self, channel_id: u16) -> Option<Reply> {
        self.inner
            .lock()
            .expected_replies
            .get_mut(&channel_id)
            .and_then(|replies| replies.pop_front())
            .map(|t| t.0)
    }

    pub(crate) fn next_expected_close_ok_reply(&self, channel_id: u16, error: Error) -> Option<Reply> {
        self.inner.lock().next_expected_close_ok_reply(channel_id, error)
    }

    pub(crate) fn has_pending(&self) -> bool {
        self.inner.lock().has_pending()
    }

    pub(crate) fn drop_pending(&self, error: Error) {
        self.inner.lock().drop_pending(error);
    }

    pub(crate) fn clear_expected_replies(&self, channel_id: u16, error: Error) {
        self.inner.lock().clear_expected_replies(channel_id, error);
    }
}

struct Inner {
    /* Header frames must follow basic.publish frames directly, otherwise RabbitMQ-server send us an UNEXPECTED_FRAME */
    /* After sending the Header frame, we need to send the associated Body frames before anything else for the same reason */
    publish_frames: VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
    retry_frames: VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
    frames: VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
    low_prio_frames: VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
    expected_replies: HashMap<u16, VecDeque<ExpectedReply>>,
}

impl Default for Inner {
    fn default() -> Self {
        Self {
            publish_frames: VecDeque::default(),
            retry_frames: VecDeque::default(),
            frames: VecDeque::default(),
            low_prio_frames: VecDeque::default(),
            expected_replies: HashMap::default(),
        }
    }
}

impl fmt::Debug for Frames {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut debug = f.debug_struct("Frames");
        if let Some(inner) = self.inner.try_lock() {
            debug.field("expected_replies", &inner.expected_replies);
        }
        debug.finish()
    }
}

impl Inner {
    fn push(
        &mut self,
        channel_id: u16,
        frame: AMQPFrame,
        resolver: PromiseResolver<()>,
        expected_reply: Option<ExpectedReply>,
    ) {
        self.frames.push_back((frame, Some(resolver)));
        if let Some(reply) = expected_reply {
            trace!(
                "channel {} state is now waiting for {:?}",
                channel_id,
                reply
            );
            self.expected_replies
                .entry(channel_id)
                .or_default()
                .push_back(reply);
        }
    }

    fn push_frames(&mut self, mut frames: Vec<AMQPFrame>) -> Promise<()> {
        let (promise, resolver) = Promise::new();
        let last_frame = frames.pop();

        if log_enabled!(Trace) {
            promise.set_marker("Frames".into());
        }

        for frame in frames {
            self.low_prio_frames.push_back((frame, None));
        }
        if let Some(last_frame) = last_frame {
            self.low_prio_frames.push_back((last_frame, Some(resolver)));
        } else {
            resolver.swear(Ok(()));
        }

        promise
    }

    fn pop(&mut self, flow: bool) -> Option<(AMQPFrame, Option<PromiseResolver<()>>)> {
        if let Some(frame) = self
            .retry_frames
            .pop_front()
            .or_else(|| self.publish_frames.pop_front())
            .or_else(|| self.frames.pop_front())
        {
            return Some(frame);
        }
        if flow {
            if let Some(frame) = self.low_prio_frames.pop_front() {
                // If the next frame is a header, that means we're a basic.publish
                // Header frame needs to follow directly the basic.publish frame, and Body frames
                // need to be sent just after those or the AMQP server will close the connection.
                // Push the header into publish_frames which is there to handle just that.
                if self
                    .low_prio_frames
                    .front()
                    .map(|(frame, _)| frame.is_header())
                    .unwrap_or(false)
                {
                    // Yes, this will always be Some() with a Header frame, but let's keep our unwrap() count low
                    if let Some(next_frame) = self.low_prio_frames.pop_front() {
                        self.publish_frames.push_back(next_frame);
                    }
                    while let Some(next_frame) = self.low_prio_frames.pop_front() {
                        match next_frame.0 {
                            AMQPFrame::Body(..) => {
                                self.publish_frames.push_back(next_frame);
                            }
                            _ => {
                                // We've exhausted Body frames for this publish, push back the next one and exit
                                self.low_prio_frames.push_front(next_frame);
                                break;
                            }
                        }
                    }
                }
                return Some(frame);
            }
        }
        None
    }

    fn has_pending(&self) -> bool {
        !(self.retry_frames.is_empty()
            && self.publish_frames.is_empty()
            && self.frames.is_empty()
            && self.low_prio_frames.is_empty())
    }

    fn drop_pending(&mut self, error: Error) {
        Self::drop_pending_frames(&mut self.retry_frames, error.clone());
        Self::drop_pending_frames(&mut self.publish_frames, error.clone());
        Self::drop_pending_frames(&mut self.frames, error.clone());
        Self::drop_pending_frames(&mut self.low_prio_frames, error.clone());
        for (_, replies) in self.expected_replies.drain() {
            Self::cancel_expected_replies(replies, error.clone());
        }
    }

    fn drop_pending_frames(
        frames: &mut VecDeque<(AMQPFrame, Option<PromiseResolver<()>>)>,
        error: Error,
    ) {
        for (_, resolver) in std::mem::take(frames) {
            if let Some(resolver) = resolver {
                resolver.swear(Err(error.clone()));
            }
        }
    }

    fn next_expected_close_ok_reply(&mut self, channel_id: u16, error: Error) -> Option<Reply> {
        let expected_replies = self.expected_replies.get_mut(&channel_id)?;
        while let Some(reply) = expected_replies.pop_front() {
            match &reply.0 {
                Reply::ChannelCloseOk(_) => return Some(reply.0),
                Reply::BasicCancelOk(pinky) => pinky.swear(Ok(())), // Channel close means consumer is canceled automatically
                _ => reply.1.cancel(error.clone()),
            }
        }
        None
    }

    fn clear_expected_replies(&mut self, channel_id: u16, error: Error) {
        if let Some(replies) = self.expected_replies.remove(&channel_id) {
            Self::cancel_expected_replies(replies, error);
        }
    }

    fn cancel_expected_replies(replies: VecDeque<ExpectedReply>, error: Error) {
        for ExpectedReply(reply, cancel) in replies {
            match reply {
                Reply::BasicCancelOk(pinky) => pinky.swear(Ok(())),
                _ => cancel.cancel(error.clone()),
            }
        }
    }
}
<|endoftext|>


<commit_before>
#[deriving(Copy)]
pub struct BloodDrop {
    pub pos: [f64, ..2],
    pub time: f64,
    pub dead: bool,
}

pub struct Blood {
    pub blood_drops: Vec<BloodDrop>,
    pub time_since_last_drop: f64,
}

pub fn update_blood(dt: f64) {
    use current_blood;
    use current_player;
    use current_stream;
    use piston::vecmath::vec2_add as add;
    use piston::vecmath::vec2_scale as scale;
    use settings::blood::{ DROP_INTERVAL, SPAN };

    let blood = unsafe { &mut *current_blood() };
    let player = unsafe { &mut *current_player() };
    let stream = unsafe { &mut *current_stream() };

    let interval = DROP_INTERVAL;
    blood.time_since_last_drop += dt;
    if blood.time_since_last_drop > interval {
        blood.time_since_last_drop -= interval;
        let new_drop = BloodDrop {
            pos: player.pos,
            time: 0.0,
            dead: false,
        };
        // Look for dead blood drops before inserting new.
        let mut found_dead = false;
        for blood_drop in blood.blood_drops.iter_mut() {
            if blood_drop.dead {
                *blood_drop = new_drop;
                found_dead = true;
                break;
            }
        }
        if !found_dead { blood.blood_drops.push(new_drop) };
    }

    // Make blood drops follow stream
    for blood_drop in blood.blood_drops.iter_mut() {
        blood_drop.pos = add(blood_drop.pos, scale(stream.at(blood_drop.pos), dt));
        blood_drop.time += dt;
        if blood_drop.time > SPAN {
            blood_drop.dead = true;
        }
    }
}

<commit_msg>Refactor<commit_after>
#[deriving(Copy)]
pub struct BloodDrop {
    pub pos: [f64, ..2],
    pub time: f64,
    pub dead: bool,
}

pub struct Blood {
    pub blood_drops: Vec<BloodDrop>,
    pub time_since_last_drop: f64,
}

impl Blood {
    pub fn insert(&mut self, new_drop: BloodDrop) {
        // Look for dead blood drops before inserting new.
        let mut found_dead = false;
        for blood_drop in self.blood_drops.iter_mut() {
            if blood_drop.dead {
                *blood_drop = new_drop;
                found_dead = true;
                break;
            }
        }
        if !found_dead { self.blood_drops.push(new_drop) };
    }
}

pub fn update_blood(dt: f64) {
    use current_blood;
    use current_player;
    use current_stream;
    use piston::vecmath::vec2_add as add;
    use piston::vecmath::vec2_scale as scale;
    use settings::blood::{ DROP_INTERVAL, SPAN };

    let blood = unsafe { &mut *current_blood() };
    let player = unsafe { &mut *current_player() };
    let stream = unsafe { &mut *current_stream() };

    let interval = DROP_INTERVAL;
    blood.time_since_last_drop += dt;
    if blood.time_since_last_drop > interval {
        blood.time_since_last_drop -= interval;
        blood.insert(BloodDrop {
            pos: player.pos,
            time: 0.0,
            dead: false,
        });
    }

    // Make blood drops follow stream
    for blood_drop in blood.blood_drops.iter_mut() {
        blood_drop.pos = add(blood_drop.pos, scale(stream.at(blood_drop.pos), dt));
        blood_drop.time += dt;
        if blood_drop.time > SPAN {
            blood_drop.dead = true;
        }
    }
}

<|endoftext|>


<commit_before>use bit_vec::BitVec;
use num::pow;
use std::slice::Iter;
use lfsr;

#[derive(PartialEq, Debug)]
pub struct GaloisLFSR {
    state: BitVec,
    mask: BitVec,
}

impl GaloisLFSR {
    pub fn from_iter(iter: Iter<usize>) -> Self {
        let &len = iter.clone().max().unwrap();

        let state = BitVec::from_elem(len, true);
        let mut mask = BitVec::from_elem(len, false);

        for &t in iter {
            if t < len {
                // Set the _counterpart_ mask index
                mask.set(len - t, true);
            }
        }
        mask.set(0, true);

        GaloisLFSR { state: state, mask: mask, }
    }

    pub fn output(&self) -> bool {
        let len = self.state.len();
        self.state[len - 1]
    }

    pub fn step(&mut self) {
        let output = self.output();

        self.shift();

        if output {
            self.feedback();
        }
    }

    fn shift(&mut self) {
        lfsr::shift(&mut self.state);
    }

    fn feedback(&mut self) {
        for (i, mb) in self.mask.iter().enumerate() {
            let sb = self.state[i];
            self.state.set(i, mb ^ sb);
        }
    }

    pub fn iter(&mut self) -> LFSRIter {
        LFSRIter { lfsr: self }
    }

    fn lsbyte(&self) -> u8 {
        self.state
            .iter()
            .take(8)
            .enumerate()
            .fold(0, |acc, (i, b)| acc + (b as u8) * pow(2, i))
    }

    pub fn bytes(&mut self) -> LFSRByteIter {
        if self.state.len() < 8 {
            panic!("LFSR must have length at least 8 to iterate bytes");
        }

        LFSRByteIter { lfsr: self }
    }
}

pub struct LFSRIter<'a> {
    lfsr: &'a mut GaloisLFSR,
}

impl<'a> Iterator for LFSRIter<'a> {
    type Item = bool;

    fn next(&mut self) -> Option<bool> {
        let o = self.lfsr.output();
        self.lfsr.step();
        Some(o)
    }
}

pub struct LFSRByteIter<'a> {
    lfsr: &'a mut GaloisLFSR,
}

impl<'a> Iterator for LFSRByteIter<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        let byte = self.lfsr.lsbyte();
        self.lfsr.step();
        Some(byte)
    }
}
<commit_msg>Add LFSR impl for GaloisLFSR<commit_after>use bit_vec::BitVec;
use num::pow;
use std::slice::Iter;
use lfsr;

#[derive(PartialEq, Debug)]
pub struct GaloisLFSR {
    state: BitVec,
    mask: BitVec,
}

impl GaloisLFSR {
    pub fn from_iter(iter: Iter<usize>) -> Self {
        let &len = iter.clone().max().unwrap();

        let state = BitVec::from_elem(len, true);
        let mut mask = BitVec::from_elem(len, false);

        for &t in iter {
            if t < len {
                // Set the _counterpart_ mask index
                mask.set(len - t, true);
            }
        }
        mask.set(0, true);

        GaloisLFSR { state: state, mask: mask, }
    }

    fn shift(&mut self) {
        lfsr::shift(&mut self.state);
    }

    fn feedback(&mut self) {
        for (i, mb) in self.mask.iter().enumerate() {
            let sb = self.state[i];
            self.state.set(i, mb ^ sb);
        }
    }

    pub fn iter(&mut self) -> LFSRIter {
        LFSRIter { lfsr: self }
    }

    fn lsbyte(&self) -> u8 {
        self.state
            .iter()
            .take(8)
            .enumerate()
            .fold(0, |acc, (i, b)| acc + (b as u8) * pow(2, i))
    }

    pub fn bytes(&mut self) -> LFSRByteIter {
        if self.state.len() < 8 {
            panic!("LFSR must have length at least 8 to iterate bytes");
        }

        LFSRByteIter { lfsr: self }
    }
}

impl lfsr::LFSR for GaloisLFSR {
    fn output(&self) -> bool {
        let len = self.state.len();
        self.state[len - 1]
    }

    fn step(&mut self) {
        let output = self.output();

        self.shift();

        if output {
            self.feedback();
        }
    }
}

pub struct LFSRIter<'a> {
    lfsr: &'a mut GaloisLFSR,
}

impl<'a> Iterator for LFSRIter<'a> {
    type Item = bool;

    fn next(&mut self) -> Option<bool> {
        use lfsr::LFSR;

        let o = self.lfsr.output();
        self.lfsr.step();
        Some(o)
    }
}

pub struct LFSRByteIter<'a> {
    lfsr: &'a mut GaloisLFSR,
}

impl<'a> Iterator for LFSRByteIter<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        use lfsr::LFSR;

        let byte = self.lfsr.lsbyte();
        self.lfsr.step();
        Some(byte)
    }
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::io::{self, Write, Seek, SeekFrom};
use std::fs::{File, OpenOptions};

#[derive(Debug)]
pub struct OutFile {
    file: File,
}

impl OutFile {
    pub fn open(path: &Path, size_bytes: u64) -> io::Result<OutFile> {
        let file = if !path.exists() {
            let file = OpenOptions::new()
                .create_new(true)
                .write(true)
                .open(path)?;
            file.set_len(size_bytes)?;
            file
        } else {
            OpenOptions::new()
                .write(true)
                .create(false)
                .truncate(false)
                .open(path)?
        };

        let meta = file.metadata()?;
        if meta.len() != size_bytes {
            panic!("Output file size does not match required length");
        }

        let res = OutFile {
            file: file,
        };
        Ok(res)
    }

    pub fn sync(&mut self) -> io::Result<()> {
        self.file.flush()?;
        self.file.sync_all()
    }
}

impl Write for OutFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.file.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.file.flush()
    }
}

impl Seek for OutFile {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        self.file.seek(pos)
    }
}

impl Drop for OutFile {
    fn drop(&mut self) {
        self.sync().unwrap()
    }
}
<commit_msg>Make OutFile readable.<commit_after>use std::path::Path;
use std::io::{self, Read, Seek, SeekFrom, Write};
use std::fs::{File, OpenOptions};

#[derive(Debug)]
pub struct OutFile {
    file: File,
}

impl OutFile {
    pub fn open(path: &Path, size_bytes: u64) -> io::Result<OutFile> {
        let file = if !path.exists() {
            let file = OpenOptions::new()
                .create_new(true)
                .read(true)
                .write(true)
                .open(path)?;
            file.set_len(size_bytes)?;
            file
        } else {
            OpenOptions::new()
                .read(true)
                .write(true)
                .create(false)
                .truncate(false)
                .open(path)?
        };

        let meta = file.metadata()?;
        if meta.len() != size_bytes {
            panic!("Output file size does not match required length");
        }

        let res = OutFile {
            file: file,
        };
        Ok(res)
    }

    pub fn sync(&mut self) -> io::Result<()> {
        self.file.flush()?;
        self.file.sync_all()
    }
}

impl Read for OutFile {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.file.read(buf)
    }
}

impl Write for OutFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.file.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.file.flush()
    }
}

impl Seek for OutFile {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        self.file.seek(pos)
    }
}

impl Drop for OutFile {
    fn drop(&mut self) {
        self.sync().unwrap()
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::slice::Iter;

use layout::Layout;
use stack::Stack;
use window::Window;
use x::{Connection, WindowId};
use super::Viewport;

#[derive(Clone)]
pub struct GroupBuilder {
    name: String,
    default_layout: String,
}

impl GroupBuilder {
    pub fn new(name: String, default_layout: String) -> GroupBuilder {
        GroupBuilder {
            name,
            default_layout,
        }
    }

    pub fn build(self, connection: Rc<Connection>, layouts: Vec<Box<Layout>>) -> Group {
        let mut layouts_stack = Stack::from(layouts);
        layouts_stack.focus(|layout| layout.name() == &self.default_layout);

        Group {
            name: self.name.clone(),
            connection: connection,
            active: false,
            stack: Stack::new(),
            layouts: layouts_stack,
            viewport: Viewport::default(),
        }
    }
}

pub struct Group {
    name: String,
    connection: Rc<Connection>,
    active: bool,
    stack: Stack<WindowId>,
    layouts: Stack<Box<Layout>>,
    viewport: Viewport,
}

impl Group {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn activate(&mut self, viewport: Viewport) {
        info!("Activating group: {}", self.name());
        self.active = true;
        self.viewport = viewport;
        self.perform_layout();
    }

    pub fn update_viewport(&mut self, viewport: Viewport) {
        self.viewport = viewport;
        self.perform_layout();
    }

    pub fn deactivate(&mut self) {
        info!("Deactivating group: {}", self.name());
        for window in self.iter() {
            window.without_tracking(|w| w.unmap());
        }
        self.active = false;
    }

    fn perform_layout(&mut self) {
        if !self.active {
            return;
        }

        // Allow the layout to map and position windows it cares about.
        let focused = self.stack.focused().map(|window_id| {
            GroupWindow {
                connection: &self.connection,
                window_id: &window_id,
            }
        });
        self.layouts
            .focused()
            .map(|l| l.layout(&self.viewport, focused, self.iter()));

        // Tell X to focus the focused window for this group.
        self.stack
            .focused()
            .map(|window_id| self.connection.focus_window(&window_id));
    }

    pub fn add_window(&mut self, window_id: WindowId) {
        info!("Adding window to group {}: {}", self.name(), window_id);
        self.stack.push(window_id);
        self.perform_layout();
    }

    pub fn remove_window(&mut self, window_id: &WindowId) -> WindowId {
        info!("Removing window from group {}: {}", self.name(), window_id);
        let removed = self.stack.remove(|w| w == window_id);
        self.perform_layout();
        removed
    }

    pub fn remove_focused(&mut self) -> Option<WindowId> {
        info!(
            "Removing focused window from group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        let removed = self.stack.remove_focused();
        self.perform_layout();
        removed.map(|window| {
            self.connection.unmap_window(&window);
            window
        })
    }

    pub fn contains(&self, window_id: &WindowId) -> bool {
        self.stack.iter().any(|w| w == window_id)
    }

    pub fn focus(&mut self, window_id: &WindowId) {
        info!("Focusing window in group {}: {}", self.name(), window_id);
        self.stack.focus(|id| id == window_id);
        self.perform_layout();
    }

    fn iter<'a>(&'a self) -> GroupIter<'a> {
        GroupIter {
            connection: &self.connection,
            inner: self.stack.iter(),
        }
    }

    pub fn get_focused<'a>(&'a self) -> Option<GroupWindow<'a>> {
        self.stack.focused().map(move |ref id| {
            GroupWindow {
                connection: &self.connection,
                window_id: &id,
            }
        })
    }

    pub fn focus_next(&mut self) {
        self.stack.focus_next();
        info!(
            "Focusing next window in group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        self.perform_layout();
    }

    pub fn focus_previous(&mut self) {
        self.stack.focus_previous();
        info!(
            "Focusing previous window in group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        self.perform_layout();
    }

    pub fn shuffle_next(&mut self) {
        info!(
            "Shuffling focused window to next position in group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        self.stack.shuffle_next();
        self.perform_layout();
    }

    pub fn shuffle_previous(&mut self) {
        info!(
            "Shuffling focused window to previous position in group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        self.stack.shuffle_previous();
        self.perform_layout();
    }

    pub fn layout_next(&mut self) {
        self.layouts.focus_next();
        info!(
            "Switching to next layout in group {}: {:?}",
            self.name(),
            self.layouts.focused()
        );
        self.perform_layout();
    }

    pub fn layout_previous(&mut self) {
        self.layouts.focus_next();
        info!(
            "Switching to previous layout in group {}: {:?}",
            self.name(),
            self.layouts.focused()
        );
        self.layouts.focus_previous();
        self.perform_layout();
    }
}

pub struct GroupIter<'a> {
    connection: &'a Connection,
    inner: Iter<'a, WindowId>,
}

impl<'a> Iterator for GroupIter<'a> {
    type Item = GroupWindow<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next().map(|window_id| {
            GroupWindow {
                connection: self.connection,
                window_id: window_id,
            }
        })
    }
}

impl<'a> ExactSizeIterator for GroupIter<'a> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}

pub struct GroupWindow<'a> {
    connection: &'a Connection,
    window_id: &'a WindowId,
}

impl<'a> Window for GroupWindow<'a> {
    fn connection(&self) -> &Connection {
        self.connection
    }

    fn id(&self) -> &WindowId {
        self.window_id
    }
}
<commit_msg>Don't track window when unmapping it.<commit_after>use std::rc::Rc;
use std::slice::Iter;

use layout::Layout;
use stack::Stack;
use window::Window;
use x::{Connection, WindowId};
use super::Viewport;

#[derive(Clone)]
pub struct GroupBuilder {
    name: String,
    default_layout: String,
}

impl GroupBuilder {
    pub fn new(name: String, default_layout: String) -> GroupBuilder {
        GroupBuilder {
            name,
            default_layout,
        }
    }

    pub fn build(self, connection: Rc<Connection>, layouts: Vec<Box<Layout>>) -> Group {
        let mut layouts_stack = Stack::from(layouts);
        layouts_stack.focus(|layout| layout.name() == &self.default_layout);

        Group {
            name: self.name.clone(),
            connection: connection,
            active: false,
            stack: Stack::new(),
            layouts: layouts_stack,
            viewport: Viewport::default(),
        }
    }
}

pub struct Group {
    name: String,
    connection: Rc<Connection>,
    active: bool,
    stack: Stack<WindowId>,
    layouts: Stack<Box<Layout>>,
    viewport: Viewport,
}

impl Group {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn activate(&mut self, viewport: Viewport) {
        info!("Activating group: {}", self.name());
        self.active = true;
        self.viewport = viewport;
        self.perform_layout();
    }

    pub fn update_viewport(&mut self, viewport: Viewport) {
        self.viewport = viewport;
        self.perform_layout();
    }

    pub fn deactivate(&mut self) {
        info!("Deactivating group: {}", self.name());
        for window in self.iter() {
            window.without_tracking(|w| w.unmap());
        }
        self.active = false;
    }

    fn perform_layout(&mut self) {
        if !self.active {
            return;
        }

        // Allow the layout to map and position windows it cares about.
        let focused = self.stack.focused().map(|window_id| {
            GroupWindow {
                connection: &self.connection,
                window_id: &window_id,
            }
        });
        self.layouts
            .focused()
            .map(|l| l.layout(&self.viewport, focused, self.iter()));

        // Tell X to focus the focused window for this group.
        self.stack
            .focused()
            .map(|window_id| self.connection.focus_window(&window_id));
    }

    pub fn add_window(&mut self, window_id: WindowId) {
        info!("Adding window to group {}: {}", self.name(), window_id);
        self.stack.push(window_id);
        self.perform_layout();
    }

    pub fn remove_window(&mut self, window_id: &WindowId) -> WindowId {
        info!("Removing window from group {}: {}", self.name(), window_id);
        let removed = self.stack.remove(|w| w == window_id);
        self.perform_layout();
        removed
    }

    pub fn remove_focused(&mut self) -> Option<WindowId> {
        info!(
            "Removing focused window from group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        let removed = self.stack.remove_focused();
        self.perform_layout();
        removed.map(|window| {
            self.connection.disable_window_tracking(&window);
            self.connection.unmap_window(&window);
            self.connection.enable_window_tracking(&window);
            window
        })
    }

    pub fn contains(&self, window_id: &WindowId) -> bool {
        self.stack.iter().any(|w| w == window_id)
    }

    pub fn focus(&mut self, window_id: &WindowId) {
        info!("Focusing window in group {}: {}", self.name(), window_id);
        self.stack.focus(|id| id == window_id);
        self.perform_layout();
    }

    fn iter<'a>(&'a self) -> GroupIter<'a> {
        GroupIter {
            connection: &self.connection,
            inner: self.stack.iter(),
        }
    }

    pub fn get_focused<'a>(&'a self) -> Option<GroupWindow<'a>> {
        self.stack.focused().map(move |ref id| {
            GroupWindow {
                connection: &self.connection,
                window_id: &id,
            }
        })
    }

    pub fn focus_next(&mut self) {
        self.stack.focus_next();
        info!(
            "Focusing next window in group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        self.perform_layout();
    }

    pub fn focus_previous(&mut self) {
        self.stack.focus_previous();
        info!(
            "Focusing previous window in group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        self.perform_layout();
    }

    pub fn shuffle_next(&mut self) {
        info!(
            "Shuffling focused window to next position in group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        self.stack.shuffle_next();
        self.perform_layout();
    }

    pub fn shuffle_previous(&mut self) {
        info!(
            "Shuffling focused window to previous position in group {}: {:?}",
            self.name(),
            self.stack.focused()
        );
        self.stack.shuffle_previous();
        self.perform_layout();
    }

    pub fn layout_next(&mut self) {
        self.layouts.focus_next();
        info!(
            "Switching to next layout in group {}: {:?}",
            self.name(),
            self.layouts.focused()
        );
        self.perform_layout();
    }

    pub fn layout_previous(&mut self) {
        self.layouts.focus_next();
        info!(
            "Switching to previous layout in group {}: {:?}",
            self.name(),
            self.layouts.focused()
        );
        self.layouts.focus_previous();
        self.perform_layout();
    }
}

pub struct GroupIter<'a> {
    connection: &'a Connection,
    inner: Iter<'a, WindowId>,
}

impl<'a> Iterator for GroupIter<'a> {
    type Item = GroupWindow<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next().map(|window_id| {
            GroupWindow {
                connection: self.connection,
                window_id: window_id,
            }
        })
    }
}

impl<'a> ExactSizeIterator for GroupIter<'a> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}

pub struct GroupWindow<'a> {
    connection: &'a Connection,
    window_id: &'a WindowId,
}

impl<'a> Window for GroupWindow<'a> {
    fn connection(&self) -> &Connection {
        self.connection
    }

    fn id(&self) -> &WindowId {
        self.window_id
    }
}
<|endoftext|>


<commit_before>use std::thread;
use std::time;

use chrono;
use float_duration::{FloatDuration, TimePoint};

use framerate::{FrameCounter, FrameRateSampler, FrameCount};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TimeProgression {
    FixedStep,
    VariableStep,
}

#[derive(Debug, Clone)]
pub struct GameTime {
    frame_wall_time: chrono::DateTime<chrono::Local>,
    frame_game_time: time::Duration,
    elapsed_game_time: FloatDuration,
    elapsed_wall_time: FloatDuration,
    frame_number: u64,
}

#[derive(Debug, Clone)]
pub struct GameClock {
    start_wall_time: chrono::DateTime<chrono::Local>,
    frame_wall_time: chrono::DateTime<chrono::Local>,
    total_game_time: time::Duration,
    elapsed_game_time: FloatDuration,
    elapsed_wall_time: FloatDuration,
    current_frame: u64,
    clock_multiplier: f64,
    time_progression: TimeProgression,
}

impl GameClock {
    pub fn new() -> GameClock {
        let now = chrono::Local::now();

        GameClock {
            start_wall_time: now,
            frame_wall_time: now,
            total_game_time: time::Duration::new(0, 0),
            elapsed_game_time: FloatDuration::zero(),
            elapsed_wall_time: FloatDuration::zero(),
            current_frame: 0,
            clock_multiplier: 1.0,
            time_progression: TimeProgression::VariableStep,
        }
    }

    pub fn current_frame_index(&self) -> u64 {
        self.current_frame
    }
    pub fn start_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.start_wall_time
    }
    pub fn frame_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.frame_wall_time
    }
    pub fn frame_elapsed_time(&self) -> FloatDuration {
        chrono::Local::now()
            .float_duration_since(self.frame_wall_time)
            .unwrap()
    }

    pub fn clock_multiplier(&self) -> f64 {
        self.clock_multiplier
    }
    pub fn with_clock_multiplier(&mut self, val: f64) -> &mut GameClock {
        self.clock_multiplier = val;
        self
    }

    pub fn tick<C>(&mut self, counter: &mut C) -> GameTime
        where C: FrameCount + ?Sized
    {
        let frame_start = chrono::Local::now();

        self.current_frame += 1;

        let elapsed_wall_time = frame_start
            .float_duration_since(self.frame_wall_time)
            .unwrap();

        let elapsed_game_time = self.elapsed_game_time_from_wall_time(counter, elapsed_wall_time);
        let total_game_time = self.total_game_time + elapsed_game_time.to_std().unwrap();

        self.frame_wall_time = frame_start;
        self.total_game_time = total_game_time;
        self.elapsed_game_time = elapsed_game_time;
        self.elapsed_wall_time = elapsed_wall_time;

        let time = GameTime {
            frame_wall_time: frame_start,
            frame_game_time: total_game_time,
            elapsed_game_time,
            elapsed_wall_time,
            frame_number: self.current_frame,
        };

        counter.tick(&time);

        time
    }

    fn elapsed_game_time_from_wall_time<C>(&self,
                                           counter: &mut C,
                                           elapsed_wall_time: FloatDuration)
                                           -> FloatDuration
        where C: FrameCount + ?Sized
    {
        match self.time_progression {
            TimeProgression::FixedStep => counter.target_time_per_frame() * self.clock_multiplier,
            TimeProgression::VariableStep => elapsed_wall_time * self.clock_multiplier,
        }
    }

    pub fn sleep_remaining_via<C, F>(&mut self, counter: &C, f: F)
        where C: FrameCount + ?Sized,
              F: FnOnce(FloatDuration)
    {
        let remaining_time = counter.target_time_per_frame() -
                             chrono::Local::now()
                                 .float_duration_since(self.frame_wall_time)
                                 .unwrap();
        f(remaining_time)
    }

    pub fn sleep_remaining<C>(&mut self, counter: &C)
        where C: FrameCount + ?Sized
    {
        self.sleep_remaining_via(counter, |rem| thread::sleep(rem.to_std().unwrap()))
    }
}

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

impl GameTime {
    pub fn frame_game_time(&self) -> time::Duration {
        self.frame_game_time
    }
    pub fn frame_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.frame_wall_time
    }
    pub fn elapsed_game_time(&self) -> FloatDuration {
        self.elapsed_game_time
    }
    pub fn elapsed_wall_time(&self) -> FloatDuration {
        self.elapsed_wall_time
    }
    pub fn elapsed_time_since_frame_start(&self) -> FloatDuration {
        chrono::Local::now()
            .float_duration_since(self.frame_wall_time)
            .unwrap()
    }
    pub fn frame_number(&self) -> u64 {
        self.frame_number
    }
}
<commit_msg>GameClock stores the most recent frame's GameTime.<commit_after>use std::thread;
use std::time;

use chrono;
use float_duration::{FloatDuration, TimePoint};

use framerate::{FrameCounter, FrameRateSampler, FrameCount};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TimeProgression {
    FixedStep,
    VariableStep,
}

#[derive(Debug, Clone)]
pub struct GameTime {
    frame_wall_time: chrono::DateTime<chrono::Local>,
    frame_game_time: time::Duration,
    elapsed_game_time: FloatDuration,
    elapsed_wall_time: FloatDuration,
    frame_number: u64,
}

#[derive(Debug, Clone)]
pub struct GameClock {
    last_frame_time: GameTime,
    start_wall_time: chrono::DateTime<chrono::Local>,
    total_game_time: time::Duration,
    current_frame: u64,
    clock_multiplier: f64,
    time_progression: TimeProgression,
}

impl GameClock {
    pub fn new() -> GameClock {
        let now = chrono::Local::now();
        let start_game_time = GameTime {
            frame_wall_time: now,
            frame_game_time: time::Duration::new(0, 0),
            elapsed_game_time: FloatDuration::zero(),
            elapsed_wall_time: FloatDuration::zero(),
            frame_number: 0,
        };

        GameClock {
            last_frame_time: start_game_time,
            start_wall_time: now,
            total_game_time: time::Duration::new(0, 0),
            current_frame: 0,
            clock_multiplier: 1.0,
            time_progression: TimeProgression::VariableStep,
        }
    }

    pub fn current_frame_index(&self) -> u64 {
        self.current_frame
    }
    pub fn start_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.start_wall_time
    }
    pub fn frame_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.last_frame_time.frame_wall_time
    }
    pub fn frame_elapsed_time(&self) -> FloatDuration {
        chrono::Local::now()
            .float_duration_since(self.frame_wall_time())
            .unwrap()
    }
    pub fn last_frame_time(&self) -> &GameTime {
        &self.last_frame_time
    }

    pub fn clock_multiplier(&self) -> f64 {
        self.clock_multiplier
    }
    pub fn with_clock_multiplier(&mut self, val: f64) -> &mut GameClock {
        self.clock_multiplier = val;
        self
    }

    pub fn tick<C>(&mut self, counter: &mut C) -> GameTime
        where C: FrameCount + ?Sized
    {
        let frame_start = chrono::Local::now();

        self.current_frame += 1;

        let elapsed_wall_time = frame_start
            .float_duration_since(self.frame_wall_time())
            .unwrap();

        let elapsed_game_time = self.elapsed_game_time_from_wall_time(counter, elapsed_wall_time);
        let total_game_time = self.total_game_time + elapsed_game_time.to_std().unwrap();

        self.total_game_time = total_game_time;

        let time = GameTime {
            frame_wall_time: frame_start,
            frame_game_time: total_game_time,
            elapsed_game_time,
            elapsed_wall_time,
            frame_number: self.current_frame,
        };

        self.last_frame_time = time.clone();

        counter.tick(&time);

        time
    }

    fn elapsed_game_time_from_wall_time<C>(&self,
                                           counter: &mut C,
                                           elapsed_wall_time: FloatDuration)
                                           -> FloatDuration
        where C: FrameCount + ?Sized
    {
        match self.time_progression {
            TimeProgression::FixedStep => counter.target_time_per_frame() * self.clock_multiplier,
            TimeProgression::VariableStep => elapsed_wall_time * self.clock_multiplier,
        }
    }

    pub fn sleep_remaining_via<C, F>(&mut self, counter: &C, f: F)
        where C: FrameCount + ?Sized,
              F: FnOnce(FloatDuration)
    {
        let remaining_time = counter.target_time_per_frame() -
                             chrono::Local::now()
                                 .float_duration_since(self.frame_wall_time())
                                 .unwrap();
        f(remaining_time)
    }

    pub fn sleep_remaining<C>(&mut self, counter: &C)
        where C: FrameCount + ?Sized
    {
        self.sleep_remaining_via(counter, |rem| thread::sleep(rem.to_std().unwrap()))
    }
}

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

impl GameTime {
    pub fn frame_game_time(&self) -> time::Duration {
        self.frame_game_time
    }
    pub fn frame_wall_time(&self) -> chrono::DateTime<chrono::Local> {
        self.frame_wall_time
    }
    pub fn elapsed_game_time(&self) -> FloatDuration {
        self.elapsed_game_time
    }
    pub fn elapsed_wall_time(&self) -> FloatDuration {
        self.elapsed_wall_time
    }
    pub fn elapsed_time_since_frame_start(&self) -> FloatDuration {
        chrono::Local::now()
            .float_duration_since(self.frame_wall_time)
            .unwrap()
    }
    pub fn frame_number(&self) -> u64 {
        self.frame_number
    }
}
<|endoftext|>


<commit_before>use header::{Header, HeaderList};
use frame::{Frame, Transmission};
use bytes::BytesMut;
use frame::Command;
use tokio_io::codec::{Encoder, Decoder};
use nom::{line_ending, anychar};

named!(parse_server_command(&[u8]) -> Command,
       alt!(
           map!(tag!("CONNECTED"), |_| Command::Connected) |
           map!(tag!("MESSAGE"), |_| Command::Message) |
           map!(tag!("RECEIPT"), |_| Command::Receipt) |
           map!(tag!("ERROR"), |_| Command::Error)
       )
);
named!(parse_header_character(&[u8]) -> char,
       alt_complete!(
           map!(tag!("\\n"), |_| '\n') |
           map!(tag!("\\r"), |_| '\r') |
           map!(tag!("\\c"), |_| ':') |
           map!(tag!("\\\\"), |_| '\\') |
           anychar
       )
);
named!(parse_header(&[u8]) -> Header,
       map!(
           do_parse!(
               k: flat_map!(is_not!(":\r\n"), many1!(parse_header_character)) >>
               tag!(":") >>
               v: flat_map!(is_not!("\r\n"), many1!(parse_header_character))>>
               line_ending >>
               (k, v)
           ),
           |(k, v)| {
               Header::new_raw(k.into_iter().collect::<String>(), v.into_iter().collect::<String>())
           }
       )
);
named!(parse_frame(&[u8]) -> Frame,
       map!(
           do_parse!(
               cmd: parse_server_command >>
               line_ending >>
               headers: many0!(parse_header) >>
               line_ending >>
               body: many0!(is_not!("\0")) >>
               tag!("\0") >>
               (cmd, headers, body)
           ),
           |(cmd, headers, body)| {
               let body = if body.len() == 0 {
                   &[]
               } else {
                   body.into_iter().nth(0).unwrap()
               };
               Frame {
                   command: cmd,
                   headers: HeaderList { headers },
                   body: body.into()
               }
           }
       )
);
named!(parse_transmission(&[u8]) -> Transmission,
       alt!(
           map!(many1!(line_ending), |_| Transmission::HeartBeat) |
           map!(parse_frame, |f| Transmission::CompleteFrame(f))
       )
);
pub struct Codec;

impl Encoder for Codec {
    type Item = Transmission;
    type Error = ::std::io::Error;
    fn encode(&mut self, item: Transmission, buffer: &mut BytesMut) -> Result<(), ::std::io::Error> {
        item.write(buffer);
        Ok(())
    }
}
impl Decoder for Codec {
    type Item = Transmission;
    type Error = ::std::io::Error;

    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Transmission>, ::std::io::Error> {
        use nom::IResult;
        use std::io::{Error, ErrorKind};

        trace!("decoding data: {:?}", src);
        let (point, data) = match parse_transmission(src) {
            IResult::Done(rest, data) => {
                (rest.len(), data)
            },
            IResult::Error(e) => {
                warn!("parse error: {:?}", e);
                return Err(Error::new(ErrorKind::Other, format!("parse error: {}", e)));
            },
            IResult::Incomplete(_) => return Ok(None)
        };
        let len = src.len().saturating_sub(point);
        src.split_to(len);
        Ok(Some(data))
    }
}
<commit_msg>handle content-length headers and partial input in headers properly<commit_after>use header::{Header, HeaderList};
use frame::{Frame, Transmission};
use bytes::BytesMut;
use frame::Command;
use tokio_io::codec::{Encoder, Decoder};
use nom::{line_ending, anychar};

named!(parse_server_command(&[u8]) -> Command,
       alt!(
           map!(tag!("CONNECTED"), |_| Command::Connected) |
           map!(tag!("MESSAGE"), |_| Command::Message) |
           map!(tag!("RECEIPT"), |_| Command::Receipt) |
           map!(tag!("ERROR"), |_| Command::Error)
       )
);
named!(parse_header_character(&[u8]) -> char,
       alt!(
           complete!(map!(tag!("\\n"), |_| '\n')) |
           complete!(map!(tag!("\\r"), |_| '\r')) |
           complete!(map!(tag!("\\c"), |_| ':')) |
           complete!(map!(tag!("\\\\"), |_| '\\')) |
           anychar
       )
);
named!(parse_header(&[u8]) -> Header,
       map!(
           do_parse!(
               k: flat_map!(is_not!(":\r\n"), many1!(parse_header_character)) >>
               tag!(":") >>
               v: flat_map!(is_not!("\r\n"), many1!(parse_header_character))>>
               line_ending >>
               (k, v)
           ),
           |(k, v)| {
               Header::new_raw(k.into_iter().collect::<String>(), v.into_iter().collect::<String>())
           }
       )
);
fn get_body<'a, 'b>(nb: &'a [u8], headers: &'b [Header]) -> ::nom::IResult<&'a [u8], &'a [u8]> {
    let mut cl = None;
    for hdr in headers {
        if hdr.0 == "content-length" {
            trace!("found content-length header");
            match hdr.1.parse::<u32>() {
                Ok(v) => cl = Some(v),
                Err(e) => warn!("failed to parse content-length header: {}", e)
            }
        }
    }
    if let Some(cl) = cl {
        trace!("using content-length header: {}", cl);
        take!(nb, cl)
    }
    else {
        trace!("using many0 method to parse body");
        map!(nb,
            many0!(is_not!("\0")),
            |body| {
                if body.len() == 0 {
                    &[]
                } else {
                    body.into_iter().nth(0).unwrap()
                }
            }
        )
    }
}
named!(parse_frame(&[u8]) -> Frame,
       map!(
           do_parse!(
               cmd: parse_server_command >>
               line_ending >>
               headers: many0!(parse_header) >>
               line_ending >>
               body: call!(get_body, &headers) >>
               tag!("\0") >>
               (cmd, headers, body)
           ),
           |(cmd, headers, body)| {
               Frame {
                   command: cmd,
                   headers: HeaderList { headers },
                   body: body.into()
               }
           }
       )
);
named!(parse_transmission(&[u8]) -> Transmission,
       alt!(
           map!(many1!(line_ending), |_| Transmission::HeartBeat) |
           map!(parse_frame, |f| Transmission::CompleteFrame(f))
       )
);
pub struct Codec;

impl Encoder for Codec {
    type Item = Transmission;
    type Error = ::std::io::Error;
    fn encode(&mut self, item: Transmission, buffer: &mut BytesMut) -> Result<(), ::std::io::Error> {
        item.write(buffer);
        Ok(())
    }
}
impl Decoder for Codec {
    type Item = Transmission;
    type Error = ::std::io::Error;

    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Transmission>, ::std::io::Error> {
        use nom::IResult;
        use std::io::{Error, ErrorKind};

        trace!("decoding data: {:?}", src);
        let (point, data) = match parse_transmission(src) {
            IResult::Done(rest, data) => {
                (rest.len(), data)
            },
            IResult::Error(e) => {
                warn!("parse error: {:?}", e);
                return Err(Error::new(ErrorKind::Other, format!("parse error: {}", e)));
            },
            IResult::Incomplete(_) => return Ok(None)
        };
        let len = src.len().saturating_sub(point);
        src.split_to(len);
        Ok(Some(data))
    }
}
<|endoftext|>