<commit_before>// Copyright 2012-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.

//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//! It is linked to all Rust crates by default.
//!
//! ## Intrinsic types and operations
//!
//! The [`ptr`](ptr/index.html) and [`mem`](mem/index.html)
//! modules deal with unsafe pointers and memory manipulation.
//! [`marker`](marker/index.html) defines the special built-in traits,
//! and [`raw`](raw/index.html) the runtime representation of Rust types.
//! These are some of the lowest-level building blocks in Rust.
//!
//! ## Math on primitive types and math traits
//!
//! Although basic operations on primitive types are implemented
//! directly by the compiler, the standard library additionally
//! defines many common operations through traits defined in
//! mod [`num`](num/index.html).
//!
//! ## Pervasive types
//!
//! The [`option`](option/index.html) and [`result`](result/index.html)
//! modules define optional and error-handling types, `Option` and `Result`.
//! [`iter`](iter/index.html) defines Rust's iterator protocol
//! along with a wide variety of iterators.
//! [`Cell` and `RefCell`](cell/index.html) are for creating types that
//! manage their own mutability.
//!
//! ## Vectors, slices and strings
//!
//! The common container type, `Vec`, a growable vector backed by an array,
//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
//! [`slice`](slice/index.html) module defines many methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! ## Platform abstractions
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives. The [`os`](os/index.html) module
//! provides a number of basic functions for interacting with the
//! operating environment, including program arguments, environment
//! variables, and directory navigation. The [`path`](path/index.html)
//! module encapsulates the platform-specific rules for dealing
//! with file paths.
//!
//! `std` also includes the [`ffi`](ffi/index.html) module for interoperating
//! with the C language.
//!
//! ## Concurrency, I/O, and the runtime
//!
//! The [`thread`](thread/index.html) module contains Rust's threading abstractions.
//! [`sync`](sync/index.html) contains further, primitive, shared memory types,
//! including [`atomic`](sync/atomic/index.html), and [`mpsc`](sync/mpsc/index.html),
//! which contains the channel types for message passing.
//!
//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets,
//! timers, and process spawning, are defined in the
//! [`old_io`](old_io/index.html) module.
//!
//! Rust's I/O and concurrency depends on a small runtime interface
//! that lives, along with its support code, in mod [`rt`](rt/index.html).
//! While a notable part of the standard library's architecture, this
//! module is not intended for public use.
//!
//! ## The Rust prelude and macros
//!
//! Finally, the [`prelude`](prelude/index.html) defines a
//! common set of traits, types, and functions that are made available
//! to all code by default. [`macros`](macros/index.html) contains
//! all the standard macros, such as `assert!`, `panic!`, `println!`,
//! and `format!`, also available to all Rust code.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]
#![doc(test(no_crate_inject))]

#![feature(alloc)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unsafe_destructor)]
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(macro_reexport)]
#![feature(unique)]
#![feature(allow_internal_unstable)]
#![feature(str_char)]
#![feature(into_cow)]
#![feature(std_misc)]
#![feature(slice_patterns)]
#![feature(debug_builders)]
#![cfg_attr(test, feature(test, rustc_private, std_misc))]

// Don't link to std. We are std.
#![feature(no_std)]
#![no_std]

#![allow(trivial_casts)]
#![deny(missing_docs)]

#[cfg(test)] extern crate test;
#[cfg(test)] #[macro_use] extern crate log;

#[macro_use]
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
    unreachable, unimplemented, write, writeln)]
extern crate core;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;

#[allow(deprecated)] extern crate rand as core_rand;
extern crate alloc;
extern crate unicode;
extern crate libc;

#[macro_use] #[no_link] extern crate rustc_bitflags;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate std as realstd;
#[cfg(test)] pub use realstd::marker;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::convert;
pub use core::default;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::marker;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::result;
pub use core::option;
pub mod error;

#[cfg(not(test))] pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::borrow;
pub use core_collections::fmt;
pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;

pub use unicode::char;

/* Exported macros */

#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

// NB: slice and str are primitive types too, but their module docs + primitive doc pages
// are inlined from the public re-exports of core_collections::{slice, str} above.

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;

pub mod thunk;

/* Common traits */

pub mod num;

/* Runtime and platform support */

#[macro_use]
pub mod thread;

pub mod collections;
pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;
pub mod io;
pub mod net;
pub mod old_io;
pub mod old_path;
pub mod os;
pub mod path;
pub mod process;
pub mod rand;
pub mod sync;
pub mod time;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;

// Modules that exist purely to document + host impl docs for primitive types

mod array;
mod bool;
mod unit;
mod tuple;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use sync; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    #[allow(deprecated)]
    pub use old_io; // used for println!()
    pub use option; // used for bitflags!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread; // used for thread_local!
    pub use marker;  // used for tls!
    pub use ops; // used for bitflags!

    // The test runner calls ::std::env::args() but really wants realstd
    #[cfg(test)] pub use realstd::env as env;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]
}
<commit_msg>Don't speak of old_io<commit_after>// Copyright 2012-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.

//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//! It is linked to all Rust crates by default.
//!
//! ## Intrinsic types and operations
//!
//! The [`ptr`](ptr/index.html) and [`mem`](mem/index.html)
//! modules deal with unsafe pointers and memory manipulation.
//! [`marker`](marker/index.html) defines the special built-in traits,
//! and [`raw`](raw/index.html) the runtime representation of Rust types.
//! These are some of the lowest-level building blocks in Rust.
//!
//! ## Math on primitive types and math traits
//!
//! Although basic operations on primitive types are implemented
//! directly by the compiler, the standard library additionally
//! defines many common operations through traits defined in
//! mod [`num`](num/index.html).
//!
//! ## Pervasive types
//!
//! The [`option`](option/index.html) and [`result`](result/index.html)
//! modules define optional and error-handling types, `Option` and `Result`.
//! [`iter`](iter/index.html) defines Rust's iterator protocol
//! along with a wide variety of iterators.
//! [`Cell` and `RefCell`](cell/index.html) are for creating types that
//! manage their own mutability.
//!
//! ## Vectors, slices and strings
//!
//! The common container type, `Vec`, a growable vector backed by an array,
//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
//! [`slice`](slice/index.html) module defines many methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! ## Platform abstractions
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives. The [`os`](os/index.html) module
//! provides a number of basic functions for interacting with the
//! operating environment, including program arguments, environment
//! variables, and directory navigation. The [`path`](path/index.html)
//! module encapsulates the platform-specific rules for dealing
//! with file paths.
//!
//! `std` also includes the [`ffi`](ffi/index.html) module for interoperating
//! with the C language.
//!
//! ## Concurrency, I/O, and the runtime
//!
//! The [`thread`](thread/index.html) module contains Rust's threading abstractions.
//! [`sync`](sync/index.html) contains further, primitive, shared memory types,
//! including [`atomic`](sync/atomic/index.html), and [`mpsc`](sync/mpsc/index.html),
//! which contains the channel types for message passing.
//!
//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets, and
//! process spawning, are defined in the [`io`](io/index.html) module.
//!
//! Rust's I/O and concurrency depends on a small runtime interface
//! that lives, along with its support code, in mod [`rt`](rt/index.html).
//! While a notable part of the standard library's architecture, this
//! module is not intended for public use.
//!
//! ## The Rust prelude and macros
//!
//! Finally, the [`prelude`](prelude/index.html) defines a
//! common set of traits, types, and functions that are made available
//! to all code by default. [`macros`](macros/index.html) contains
//! all the standard macros, such as `assert!`, `panic!`, `println!`,
//! and `format!`, also available to all Rust code.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]
#![doc(test(no_crate_inject))]

#![feature(alloc)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unsafe_destructor)]
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(macro_reexport)]
#![feature(unique)]
#![feature(allow_internal_unstable)]
#![feature(str_char)]
#![feature(into_cow)]
#![feature(std_misc)]
#![feature(slice_patterns)]
#![feature(debug_builders)]
#![cfg_attr(test, feature(test, rustc_private, std_misc))]

// Don't link to std. We are std.
#![feature(no_std)]
#![no_std]

#![allow(trivial_casts)]
#![deny(missing_docs)]

#[cfg(test)] extern crate test;
#[cfg(test)] #[macro_use] extern crate log;

#[macro_use]
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
    unreachable, unimplemented, write, writeln)]
extern crate core;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;

#[allow(deprecated)] extern crate rand as core_rand;
extern crate alloc;
extern crate unicode;
extern crate libc;

#[macro_use] #[no_link] extern crate rustc_bitflags;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate std as realstd;
#[cfg(test)] pub use realstd::marker;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::convert;
pub use core::default;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::marker;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::result;
pub use core::option;
pub mod error;

#[cfg(not(test))] pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::borrow;
pub use core_collections::fmt;
pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;

pub use unicode::char;

/* Exported macros */

#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

// NB: slice and str are primitive types too, but their module docs + primitive doc pages
// are inlined from the public re-exports of core_collections::{slice, str} above.

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;

pub mod thunk;

/* Common traits */

pub mod num;

/* Runtime and platform support */

#[macro_use]
pub mod thread;

pub mod collections;
pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;
pub mod io;
pub mod net;
pub mod old_io;
pub mod old_path;
pub mod os;
pub mod path;
pub mod process;
pub mod rand;
pub mod sync;
pub mod time;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;

// Modules that exist purely to document + host impl docs for primitive types

mod array;
mod bool;
mod unit;
mod tuple;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use sync; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    #[allow(deprecated)]
    pub use old_io; // used for println!()
    pub use option; // used for bitflags!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread; // used for thread_local!
    pub use marker;  // used for tls!
    pub use ops; // used for bitflags!

    // The test runner calls ::std::env::args() but really wants realstd
    #[cfg(test)] pub use realstd::env as env;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::Deref;
use std::path::Path;

use anim::Cont;
use entity::Entity;
use model::Model;
use resource::ResourceManager;

/// A typed identifier.
#[derive(Debug)]
pub struct Id<'a, T> where T: 'a {
  pub id: u32,
  _t: PhantomData<&'a T>
}

impl<'a, T> Id<'a, T> {
  pub fn new(id: u32) -> Self {
    Id {
      id: id,
      _t: PhantomData
    }
  }
}

impl<'a, T> Clone for Id<'a, T> {
  fn clone(&self) -> Self {
    self.id.into()
  }
}

impl<'a, T> Deref for Id<'a, T> {
  type Target = u32;

  fn deref(&self) -> &Self::Target {
    &self.id
  }
}

impl<'a, T> From<u32> for Id<'a, T> {
  fn from(id: u32) -> Self {
    Id::new(id)
  }
}

/// The scene type.
///
/// This type gathers all the required objects a scene needs to correctly handle and render all
/// visual effects.
pub struct Scene<'a> {
  /// Resource manager; used to handle scarce resources.
  res_manager: ResourceManager,
  /// All models used in the scene.
  models: Vec<Model>,
  /// Model cache used to resolve Id based on instance name.
  model_cache: HashMap<String, Id<'a, Model>>,
  /// Model entities used in the scene, containing `Id` to the models of the scene.
  model_entities: HashMap<String, SceneModelEntity<'a>>
}

impl<'a> Scene<'a> {
  pub fn new<P>(root: P) -> Self where P: AsRef<Path>{
    Scene {
      res_manager: ResourceManager::new(root),
      models: Vec::new(),
      model_cache: HashMap::new(),
      model_entities: HashMap::new()
    }
  }

  pub fn resource_manager(&mut self) -> &mut ResourceManager {
    &mut self.res_manager
  }
}

/// An model entity living in a scene.
///
/// It can either be a static model entity, in which case it just holds a transform object or it can
/// be a dynamic model entity, which holds a continuous model entity you can sample in time to
/// retrieve the varying transform.
pub enum SceneModelEntity<'a> {
  Static(Entity<Id<'a, Model>>),
  Dynamic(Cont<'a, Entity<Id<'a, Model>>>)
}

pub trait Get<T>: Sized {
  fn get_id(&mut self, name: &str) -> Option<Id<T>>;
  fn get(&self, id: Id<Self>) -> Option<&T>;
}

impl<'a> Get<Model> for Scene<'a> {
  fn get_id(&mut self, name: &str) -> Option<Id<Model>> {
    match self.model_cache.get(name).cloned() {
      id@Some(..) => {
        deb!("cache hit for model \"{}\"", name);
        id
      },
      None => {
        // cache miss; load then
        let path_str = format!("data/models/{}.obj", name);
        let path = Path::new(&path_str);

        deb!("cache miss for model \"{}\"", name);

        if path.exists() {
          match Model::load(&mut self.res_manager, path) {
            Ok(model) => {
              let model_id: Id<Model> = (self.models.len() as u32).into();

              // add the model to the list of loaded models
              self.models.push(model);
              // add the model to the cache
              self.model_cache.insert(name.to_owned(), model_id.clone());

              Some(model_id)
            },
            Err(e) => {
              err!("unable to load model '{}': '{:?}'", name, e);
              None
            }
          }
        } else { // TODO: add a manifest override to look in somewhere else
          err!("model '{}' cannot be found", name);
          None
        }
      }
    }
  }

  fn get(&self, id: Id<Self>) -> Option<&Model> {
    self.models.get(*id as usize)
  }
}
<commit_msg>Made the Get trait methods better.<commit_after>use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::Deref;
use std::path::Path;

use anim::Cont;
use entity::Entity;
use model::Model;
use resource::ResourceManager;

/// A typed identifier.
#[derive(Debug)]
pub struct Id<'a, T> where T: 'a {
  pub id: u32,
  _t: PhantomData<&'a T>
}

impl<'a, T> Id<'a, T> {
  pub fn new(id: u32) -> Self {
    Id {
      id: id,
      _t: PhantomData
    }
  }
}

impl<'a, T> Clone for Id<'a, T> {
  fn clone(&self) -> Self {
    self.id.into()
  }
}

impl<'a, T> Deref for Id<'a, T> {
  type Target = u32;

  fn deref(&self) -> &Self::Target {
    &self.id
  }
}

impl<'a, T> From<u32> for Id<'a, T> {
  fn from(id: u32) -> Self {
    Id::new(id)
  }
}

/// The scene type.
///
/// This type gathers all the required objects a scene needs to correctly handle and render all
/// visual effects.
pub struct Scene<'a> {
  /// Resource manager; used to handle scarce resources.
  res_manager: ResourceManager,
  /// All models used in the scene.
  models: Vec<Model>,
  /// Model cache used to resolve Id based on instance name.
  model_cache: HashMap<String, Id<'a, Model>>,
  /// Model entities used in the scene, containing `Id` to the models of the scene.
  model_entities: HashMap<String, SceneModelEntity<'a>>
}

impl<'a> Scene<'a> {
  pub fn new<P>(root: P) -> Self where P: AsRef<Path>{
    Scene {
      res_manager: ResourceManager::new(root),
      models: Vec::new(),
      model_cache: HashMap::new(),
      model_entities: HashMap::new()
    }
  }

  pub fn resource_manager(&mut self) -> &mut ResourceManager {
    &mut self.res_manager
  }
}

/// An model entity living in a scene.
///
/// It can either be a static model entity, in which case it just holds a transform object or it can
/// be a dynamic model entity, which holds a continuous model entity you can sample in time to
/// retrieve the varying transform.
pub enum SceneModelEntity<'a> {
  Static(Entity<Id<'a, Model>>),
  Dynamic(Cont<'a, Entity<Id<'a, Model>>>)
}

pub trait Get<T>: Sized {
  type Id;

  fn get_id(&mut self, name: &str) -> Option<Self::Id>;
  fn get_by_id(&self, id: Self::Id) -> Option<&T>;
  fn get(&mut self, name: &str) -> Option<&T> {
    self.get_id(name).and_then(move |i| self.get_by_id(i))
  }
}

impl<'a> Get<Model> for Scene<'a> {
  type Id = Id<'a, Model>;

  fn get_id(&mut self, name: &str) -> Option<Self::Id> {
    match self.model_cache.get(name).cloned() {
      id@Some(..) => {
        deb!("cache hit for model \"{}\"", name);
        id
      },
      None => {
        // cache miss; load then
        let path_str = format!("data/models/{}.obj", name);
        let path = Path::new(&path_str);

        deb!("cache miss for model \"{}\"", name);

        if path.exists() {
          match Model::load(&mut self.res_manager, path) {
            Ok(model) => {
              let model_id: Id<Model> = (self.models.len() as u32).into();

              // add the model to the list of loaded models
              self.models.push(model);
              // add the model to the cache
              self.model_cache.insert(name.to_owned(), model_id.clone());

              Some(model_id)
            },
            Err(e) => {
              err!("unable to load model '{}': '{:?}'", name, e);
              None
            }
          }
        } else { // TODO: add a manifest override to look in somewhere else
          err!("model '{}' cannot be found", name);
          None
        }
      }
    }
  }

  fn get_by_id(&self, id: Self::Id) -> Option<&Model> {
    self.models.get(*id as usize)
  }
}
<|endoftext|>


<commit_before>use vecmath::*;

use shape::*;
use vec3d::*;
use light::*;
use color::*;

use std;

pub struct Scene {
    shapes: Vec<Box<Shape + Sync>>,
    light: Light,
    camera_pos: Vec3d,
    camera_dir: Vec3d,
    camera_up: Vec3d,
    max_reflection: i32,
}

impl Scene {
    pub fn new(light: Light, camera_pos: Vec3d, camera_dir: Vec3d, camera_up: Vec3d) -> Scene {
        Scene {
            shapes: Vec::new(),
            light: light,
            camera_pos: camera_pos,
            camera_dir: camera_dir,
            camera_up: camera_up,
            max_reflection: 4,
        }
    }

    pub fn add_shape(&mut self, s: Box<Shape + Sync>) {
        self.shapes.push(s);
    }

    pub fn step(&mut self) {
        //self.light.translate(&[1.0, 0.0, 0.0]);
    }

    pub fn mv_camera_fwd(&mut self) {
        self.camera_pos = vec3_add(self.camera_pos, self.camera_dir);
    }

    pub fn mv_camera_back(&mut self) {
        self.camera_pos = vec3_sub(self.camera_pos, self.camera_dir);
    }

    pub fn rot_camera(&mut self, x_rot: f64, y_rot: f64) {
        self.camera_dir = vec3_roty(self.camera_dir, x_rot);

        // project camera_dir to X plane
        let mut x_proj = self.camera_dir;
        x_proj[1] = 0.0;
        x_proj = vec3_normalized(x_proj);

        let angle = if x_proj[0] < 0.0 {
            -vec3_dot([0.0, 0.0, 1.0], x_proj).acos()
        } else {
            vec3_dot([0.0, 0.0, 1.0], x_proj).acos()
        };

        self.camera_dir = vec3_roty(self.camera_dir, -angle);
        self.camera_dir = vec3_rotx(self.camera_dir, y_rot);
        self.camera_dir = vec3_roty(self.camera_dir, angle);

        self.camera_dir = vec3_normalized(self.camera_dir);
    }

    /// Returns an iterator that scans a full frame at given resolution
    pub fn draw_iter(&self, h: usize, v: usize) -> DrawIter {
        DrawIter::new(self, h, v)
    }

    /// draw_iter converted to (u8, u8, u8)
    pub fn draw_iter_u8(&self,
                        h: usize,
                        v: usize)
                        -> std::iter::Map<DrawIter, fn(Color) -> (u8, u8, u8)> {
        self.draw_iter(h, v).map(Color::col_to_u8)
    }

    /// Returns an iterator for a line at given resolution
    pub fn line_iter(&self, h: usize, v: usize, l: usize) -> LineIter {
        LineIter::new(self, h, v, l)
    }

    /// line_iter converted to (u8, u8, u8)
    pub fn line_iter_u8(&self,
                        h: usize,
                        v: usize,
                        l: usize)
                        -> std::iter::Map<LineIter, fn(Color) -> (u8, u8, u8)> {
        self.line_iter(h, v, l).map(Color::col_to_u8)
    }

    // Recursively trace lines
    fn trace(&self, point: &Vec3d, dir: &Vec3d, depth: i32) -> Color {
        if depth >= self.max_reflection {
            return BLACK;
        }

        let intersect_res = self.closest_q(point, dir);
        if let Some(intersect) = intersect_res {
            let feeler_d = vec3_sub(*self.light.get_pos(), intersect.point);
            let dist_light = vec3_len(feeler_d);
            let feeler_d_unit = vec3_normalized(feeler_d);
            let direct_light =
                self.is_direct_light(&intersect.point, &feeler_d_unit, dist_light);

            let local = phong(point, &intersect, &self.light, direct_light);

            let tmp = vec3_normalized_sub(intersect.point, *point);
            let reflection_dir =
                vec3_normalized_sub(tmp,
                                    vec3_scale(intersect.normal,
                                               2.0 * vec3_dot(tmp, intersect.normal)));

            let reflected = self.trace(&intersect.point, &reflection_dir, depth + 1);

            Color::add(&local, &(Color::scale(&reflected, intersect.material.reflectivity)))
        } else {
            BLACK
        }
    }

    // Is there anything on the path to the light
    fn is_direct_light(&self, point: &Vec3d, dir: &Vec3d, dl: f64) -> bool {
        let unitd = vec3_normalized(*dir);
        !self.shapes
            .iter()
            .map(|&ref x| x.intersect_dist(point, &unitd))
            .any(|dist_opt| dist_opt.map(|i| i < dl).unwrap_or(false))
    }

    // Checks against all objects and returns closest intersection
    fn closest_q(&self, point: &Vec3d, dir: &Vec3d) -> Option<Intersection> {
        let unitd = vec3_normalized(*dir);

        let closest = self.shapes
            .iter()
            .map(|&ref x| x.intersect_dist(point, &unitd))
            .zip(&self.shapes)
            .fold(None, |min, (dist_op, shape)| {
                match (dist_op, min) {
                    (Some(dist_val), Some((dist_min, _))) if dist_val < dist_min => {
                        Some((dist_val, shape))
                    }
                    (Some(dist_val), None) => Some((dist_val, shape)),
                    _ => min,
                }
            });

        // get intersection point info
        if let Some((_, shape)) = closest {
            shape.intersect(point, dir)
        } else {
            None
        }
    }
}

/// Iterator that iterates over a full frame
pub struct DrawIter<'a> {
    h_res: usize,
    v_res: usize,
    x: usize,
    y: usize,
    left: Vec3d,
    right_step: Vec3d,
    down_step: Vec3d,
    point: Vec3d,
    scene: &'a Scene,
}

impl<'a> DrawIter<'a> {
    fn new(scene: &Scene, h: usize, v: usize) -> DrawIter {
        let left = vec3_normalized(vec3_cross(scene.camera_dir, scene.camera_up));
        let up = vec3_normalized(vec3_cross(left, scene.camera_dir));
        let point = vec3_add(vec3_add(left, up), scene.camera_dir);
        let right_step = vec3_scale(left, -2.0 / h as f64);
        let down_step = vec3_scale(up, -2.0 / v as f64);
        DrawIter {
            h_res: h,
            v_res: v,
            x: 0,
            y: 0,
            left: left,
            point: point,
            right_step: right_step,
            down_step: down_step,
            scene: scene,
        }
    }
}

impl<'a> Iterator for DrawIter<'a> {
    type Item = Color;

    fn next(&mut self) -> Option<Self::Item> {
        if self.y >= self.v_res {
            return None;
        }

        self.point = vec3_add(self.point, self.right_step);

        let c = self.scene.trace(&self.scene.camera_pos, &vec3_normalized(self.point), 0);

        self.x += 1;
        if self.x >= self.h_res {
            self.x = 0;
            self.y += 1;
            self.point = vec3_add(self.point, self.left);
            self.point = vec3_add(self.point, self.left);
            self.point = vec3_add(self.point, self.down_step);
        }

        Some(c)
    }
}

/// Iterator that iterates over a single line
pub struct LineIter<'a> {
    h_res: usize,
    x: usize,
    right_step: Vec3d,
    point: Vec3d,
    scene: &'a Scene,
}

impl<'a> LineIter<'a> {
    fn new(scene: &Scene, h: usize, v: usize, l: usize) -> LineIter {
        let left = vec3_normalized(vec3_cross(scene.camera_dir, scene.camera_up));
        let up = vec3_normalized(vec3_cross(left, scene.camera_dir));
        let mut point = vec3_add(vec3_add(left, up), scene.camera_dir);
        let right_step = vec3_scale(left, -2.0 / h as f64);
        let down_step = vec3_scale(up, -2.0 / v as f64);

        point = vec3_add(point, vec3_scale(down_step, l as f64));
        LineIter {
            h_res: h,
            x: 0,
            point: point,
            right_step: right_step,
            scene: scene,
        }
    }
}

impl<'a> Iterator for LineIter<'a> {
    type Item = Color;

    fn next(&mut self) -> Option<Self::Item> {
        if self.x >= self.h_res {
            return None;
        }
        self.x += 1;

        self.point = vec3_add(self.point, self.right_step);

        let c = self.scene.trace(&self.scene.camera_pos, &vec3_normalized(self.point), 0);

        Some(c)
    }
}

// Calculate color with Phong model
fn phong(view_point: &Vec3d,
         intersection: &Intersection,
         light: &Light,
         direct_light: bool)
         -> Color {

    let point_material = intersection.material;
    let light_pos = light.get_pos();
    let light_color = light.get_color();
    let mut d = vec3_dot(vec3_normalized_sub(*light_pos, intersection.point),
                         intersection.normal);

    if d < 0.0 {
        d = 0.0;
    }

    let r_diffuse = if direct_light {
        light_color.0 * point_material.diffuse_color.0 * d
    } else {
        0.0
    };
    let g_diffuse = if direct_light {
        light_color.1 * point_material.diffuse_color.1 * d
    } else {
        0.0
    };
    let b_diffuse = if direct_light {
        light_color.2 * point_material.diffuse_color.2 * d
    } else {
        0.0
    };

    let r_ambient = point_material.ambient_color.0;
    let g_ambient = point_material.ambient_color.1;
    let b_ambient = point_material.ambient_color.2;

    let v = vec3_normalized_sub(*view_point, intersection.point);
    let lt = vec3_normalized_sub(*light_pos, intersection.point);
    let r = vec3_normalized_sub(vec3_scale(intersection.normal,
                                           2.0 * vec3_dot(intersection.normal, lt)),
                                lt);

    let mut s = vec3_dot(r, v).powf(point_material.shininess);
    if s < 0.0 {
        s = 0.0;
    }

    let r_specular = if direct_light {
        light_color.0 * point_material.specular_color.0 * s
    } else {
        0.0
    };
    let g_specular = if direct_light {
        light_color.1 * point_material.specular_color.1 * s
    } else {
        0.0
    };
    let b_specular = if direct_light {
        light_color.2 * point_material.specular_color.2 * s
    } else {
        0.0
    };

    let mut r_sum = r_ambient + r_diffuse + r_specular;
    let mut g_sum = g_ambient + g_diffuse + g_specular;
    let mut b_sum = b_ambient + b_diffuse + b_specular;

    if r_sum > 1.0 {
        r_sum = 1.0;
    }

    if g_sum > 1.0 {
        g_sum = 1.0;
    }

    if b_sum > 1.0 {
        b_sum = 1.0;
    }

    Color(r_sum, g_sum, b_sum)
}
<commit_msg>Minor perf improvement w/ enumerate instead of zip<commit_after>use vecmath::*;

use shape::*;
use vec3d::*;
use light::*;
use color::*;

use std;

pub struct Scene {
    shapes: Vec<Box<Shape + Sync>>,
    light: Light,
    camera_pos: Vec3d,
    camera_dir: Vec3d,
    camera_up: Vec3d,
    max_reflection: i32,
}

impl Scene {
    pub fn new(light: Light, camera_pos: Vec3d, camera_dir: Vec3d, camera_up: Vec3d) -> Scene {
        Scene {
            shapes: Vec::new(),
            light: light,
            camera_pos: camera_pos,
            camera_dir: camera_dir,
            camera_up: camera_up,
            max_reflection: 4,
        }
    }

    pub fn add_shape(&mut self, s: Box<Shape + Sync>) {
        self.shapes.push(s);
    }

    pub fn step(&mut self) {
        //self.light.translate(&[1.0, 0.0, 0.0]);
    }

    pub fn mv_camera_fwd(&mut self) {
        self.camera_pos = vec3_add(self.camera_pos, self.camera_dir);
    }

    pub fn mv_camera_back(&mut self) {
        self.camera_pos = vec3_sub(self.camera_pos, self.camera_dir);
    }

    pub fn rot_camera(&mut self, x_rot: f64, y_rot: f64) {
        self.camera_dir = vec3_roty(self.camera_dir, x_rot);

        // project camera_dir to X plane
        let mut x_proj = self.camera_dir;
        x_proj[1] = 0.0;
        x_proj = vec3_normalized(x_proj);

        let angle = if x_proj[0] < 0.0 {
            -vec3_dot([0.0, 0.0, 1.0], x_proj).acos()
        } else {
            vec3_dot([0.0, 0.0, 1.0], x_proj).acos()
        };

        self.camera_dir = vec3_roty(self.camera_dir, -angle);
        self.camera_dir = vec3_rotx(self.camera_dir, y_rot);
        self.camera_dir = vec3_roty(self.camera_dir, angle);

        self.camera_dir = vec3_normalized(self.camera_dir);
    }

    /// Returns an iterator that scans a full frame at given resolution
    pub fn draw_iter(&self, h: usize, v: usize) -> DrawIter {
        DrawIter::new(self, h, v)
    }

    /// draw_iter converted to (u8, u8, u8)
    pub fn draw_iter_u8(&self,
                        h: usize,
                        v: usize)
                        -> std::iter::Map<DrawIter, fn(Color) -> (u8, u8, u8)> {
        self.draw_iter(h, v).map(Color::col_to_u8)
    }

    /// Returns an iterator for a line at given resolution
    pub fn line_iter(&self, h: usize, v: usize, l: usize) -> LineIter {
        LineIter::new(self, h, v, l)
    }

    /// line_iter converted to (u8, u8, u8)
    pub fn line_iter_u8(&self,
                        h: usize,
                        v: usize,
                        l: usize)
                        -> std::iter::Map<LineIter, fn(Color) -> (u8, u8, u8)> {
        self.line_iter(h, v, l).map(Color::col_to_u8)
    }

    // Recursively trace lines
    fn trace(&self, point: &Vec3d, dir: &Vec3d, depth: i32) -> Color {
        if depth >= self.max_reflection {
            return BLACK;
        }

        let intersect_res = self.closest_q(point, dir);
        if let Some(intersect) = intersect_res {
            let feeler_d = vec3_sub(*self.light.get_pos(), intersect.point);
            let dist_light = vec3_len(feeler_d);
            let feeler_d_unit = vec3_normalized(feeler_d);
            let direct_light =
                self.is_direct_light(&intersect.point, &feeler_d_unit, dist_light);

            let local = phong(point, &intersect, &self.light, direct_light);

            let tmp = vec3_normalized_sub(intersect.point, *point);
            let reflection_dir =
                vec3_normalized_sub(tmp,
                                    vec3_scale(intersect.normal,
                                               2.0 * vec3_dot(tmp, intersect.normal)));

            let reflected = self.trace(&intersect.point, &reflection_dir, depth + 1);

            Color::add(&local, &(Color::scale(&reflected, intersect.material.reflectivity)))
        } else {
            BLACK
        }
    }

    // Is there anything on the path to the light
    fn is_direct_light(&self, point: &Vec3d, dir: &Vec3d, dl: f64) -> bool {
        let unitd = vec3_normalized(*dir);
        !self.shapes
            .iter()
            .map(|&ref x| x.intersect_dist(point, &unitd))
            .any(|dist_opt| dist_opt.map(|i| i < dl).unwrap_or(false))
    }

    // Checks against all objects and returns closest intersection
    fn closest_q(&self, point: &Vec3d, dir: &Vec3d) -> Option<Intersection> {
        let unitd = vec3_normalized(*dir);

        let closest = self.shapes
            .iter()
            .map(|x| x.intersect_dist(point, &unitd))
            .enumerate()
            .fold(None, |min, (idx, dist_op)| {
                match (min, dist_op) {
                    (Some((_, dist_min)), Some(dist_val)) if dist_val < dist_min => {
                        Some((idx, dist_val))
                    }
                    (None, Some(dist_val)) => Some((idx, dist_val)),
                    _ => min,
                }
            });

        // get intersection point info
        if let Some((idx, _)) = closest {
            self.shapes[idx].intersect(point, dir)
        } else {
            None
        }
    }
}

/// Iterator that iterates over a full frame
pub struct DrawIter<'a> {
    h_res: usize,
    v_res: usize,
    x: usize,
    y: usize,
    left: Vec3d,
    right_step: Vec3d,
    down_step: Vec3d,
    point: Vec3d,
    scene: &'a Scene,
}

impl<'a> DrawIter<'a> {
    fn new(scene: &Scene, h: usize, v: usize) -> DrawIter {
        let left = vec3_normalized(vec3_cross(scene.camera_dir, scene.camera_up));
        let up = vec3_normalized(vec3_cross(left, scene.camera_dir));
        let point = vec3_add(vec3_add(left, up), scene.camera_dir);
        let right_step = vec3_scale(left, -2.0 / h as f64);
        let down_step = vec3_scale(up, -2.0 / v as f64);
        DrawIter {
            h_res: h,
            v_res: v,
            x: 0,
            y: 0,
            left: left,
            point: point,
            right_step: right_step,
            down_step: down_step,
            scene: scene,
        }
    }
}

impl<'a> Iterator for DrawIter<'a> {
    type Item = Color;

    fn next(&mut self) -> Option<Self::Item> {
        if self.y >= self.v_res {
            return None;
        }

        self.point = vec3_add(self.point, self.right_step);

        let c = self.scene.trace(&self.scene.camera_pos, &vec3_normalized(self.point), 0);

        self.x += 1;
        if self.x >= self.h_res {
            self.x = 0;
            self.y += 1;
            self.point = vec3_add(self.point, self.left);
            self.point = vec3_add(self.point, self.left);
            self.point = vec3_add(self.point, self.down_step);
        }

        Some(c)
    }
}

/// Iterator that iterates over a single line
pub struct LineIter<'a> {
    h_res: usize,
    x: usize,
    right_step: Vec3d,
    point: Vec3d,
    scene: &'a Scene,
}

impl<'a> LineIter<'a> {
    fn new(scene: &Scene, h: usize, v: usize, l: usize) -> LineIter {
        let left = vec3_normalized(vec3_cross(scene.camera_dir, scene.camera_up));
        let up = vec3_normalized(vec3_cross(left, scene.camera_dir));
        let mut point = vec3_add(vec3_add(left, up), scene.camera_dir);
        let right_step = vec3_scale(left, -2.0 / h as f64);
        let down_step = vec3_scale(up, -2.0 / v as f64);

        point = vec3_add(point, vec3_scale(down_step, l as f64));
        LineIter {
            h_res: h,
            x: 0,
            point: point,
            right_step: right_step,
            scene: scene,
        }
    }
}

impl<'a> Iterator for LineIter<'a> {
    type Item = Color;

    fn next(&mut self) -> Option<Self::Item> {
        if self.x >= self.h_res {
            return None;
        }
        self.x += 1;

        self.point = vec3_add(self.point, self.right_step);

        let c = self.scene.trace(&self.scene.camera_pos, &vec3_normalized(self.point), 0);

        Some(c)
    }
}

// Calculate color with Phong model
fn phong(view_point: &Vec3d,
         intersection: &Intersection,
         light: &Light,
         direct_light: bool)
         -> Color {

    let point_material = intersection.material;
    let light_pos = light.get_pos();
    let light_color = light.get_color();
    let mut d = vec3_dot(vec3_normalized_sub(*light_pos, intersection.point),
                         intersection.normal);

    if d < 0.0 {
        d = 0.0;
    }

    let r_diffuse = if direct_light {
        light_color.0 * point_material.diffuse_color.0 * d
    } else {
        0.0
    };
    let g_diffuse = if direct_light {
        light_color.1 * point_material.diffuse_color.1 * d
    } else {
        0.0
    };
    let b_diffuse = if direct_light {
        light_color.2 * point_material.diffuse_color.2 * d
    } else {
        0.0
    };

    let r_ambient = point_material.ambient_color.0;
    let g_ambient = point_material.ambient_color.1;
    let b_ambient = point_material.ambient_color.2;

    let v = vec3_normalized_sub(*view_point, intersection.point);
    let lt = vec3_normalized_sub(*light_pos, intersection.point);
    let r = vec3_normalized_sub(vec3_scale(intersection.normal,
                                           2.0 * vec3_dot(intersection.normal, lt)),
                                lt);

    let mut s = vec3_dot(r, v).powf(point_material.shininess);
    if s < 0.0 {
        s = 0.0;
    }

    let r_specular = if direct_light {
        light_color.0 * point_material.specular_color.0 * s
    } else {
        0.0
    };
    let g_specular = if direct_light {
        light_color.1 * point_material.specular_color.1 * s
    } else {
        0.0
    };
    let b_specular = if direct_light {
        light_color.2 * point_material.specular_color.2 * s
    } else {
        0.0
    };

    let mut r_sum = r_ambient + r_diffuse + r_specular;
    let mut g_sum = g_ambient + g_diffuse + g_specular;
    let mut b_sum = b_ambient + b_diffuse + b_specular;

    if r_sum > 1.0 {
        r_sum = 1.0;
    }

    if g_sum > 1.0 {
        g_sum = 1.0;
    }

    if b_sum > 1.0 {
        b_sum = 1.0;
    }

    Color(r_sum, g_sum, b_sum)
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::path::Path;

use anim::Cont;
use id::Id;
use model::Model;
use resource::ResourceManager;

/// The scene type.
///
/// This type gathers all the required objects a scene needs to correctly handle and render all
/// visual effects.
pub struct Scene<'a> {
  /// Resource manager; used to handle scarce resources.
  res_manager: ResourceManager,
  /// All models used in the scene.
  models: Vec<Model>,
  /// Model cache used to resolve Id based on instance name.
  model_cache: HashMap<String, Id<'a, Model>>,
}

impl<'a> Scene<'a> {
  pub fn new<P>(root: P) -> Self where P: AsRef<Path>{
    Scene {
      res_manager: ResourceManager::new(root),
      models: Vec::new(),
      model_cache: HashMap::new(),
    }
  }

  pub fn resource_manager(&mut self) -> &mut ResourceManager {
    &mut self.res_manager
  }
}

pub trait Get<T>: Sized {
  type Id;

  fn get_id(&mut self, name: &str) -> Option<Self::Id>;
  fn get_by_id(&self, id: Self::Id) -> Option<&T>;
  fn get(&mut self, name: &str) -> Option<&T> {
    self.get_id(name).and_then(move |i| self.get_by_id(i))
  }
}

impl<'a> Get<Model> for Scene<'a> {
  type Id = Id<'a, Model>;

  fn get_id(&mut self, name: &str) -> Option<Self::Id> {
    match self.model_cache.get(name).cloned() {
      id@Some(..) => {
        deb!("cache hit for model \"{}\"", name);
        id
      },
      None => {
        // cache miss; load then
        let path_str = format!("data/models/{}.obj", name);
        let path = Path::new(&path_str);

        deb!("cache miss for model \"{}\"", name);

        if path.exists() {
          match Model::load(&mut self.res_manager, path) {
            Ok(model) => {
              let model_id: Id<Model> = (self.models.len() as u32).into();

              // add the model to the list of loaded models
              self.models.push(model);
              // add the model to the cache
              self.model_cache.insert(name.to_owned(), model_id.clone());

              Some(model_id)
            },
            Err(e) => {
              err!("unable to load model '{}': '{:?}'", name, e);
              None
            }
          }
        } else { // TODO: add a manifest override to look in somewhere else
          err!("model '{}' cannot be found", name);
          None
        }
      }
    }
  }

  fn get_by_id(&self, id: Self::Id) -> Option<&Model> {
    self.models.get(*id as usize)
  }
}
<commit_msg>Removed useless space.<commit_after>use std::collections::HashMap;
use std::path::Path;

use anim::Cont;
use id::Id;
use model::Model;
use resource::ResourceManager;

/// The scene type.
///
/// This type gathers all the required objects a scene needs to correctly handle and render all
/// visual effects.
pub struct Scene<'a> {
  /// Resource manager; used to handle scarce resources.
  res_manager: ResourceManager,
  /// All models used in the scene.
  models: Vec<Model>,
  /// Model cache used to resolve Id based on instance name.
  model_cache: HashMap<String, Id<'a, Model>>,
}

impl<'a> Scene<'a> {
  pub fn new<P>(root: P) -> Self where P: AsRef<Path>{
    Scene {
      res_manager: ResourceManager::new(root),
      models: Vec::new(),
      model_cache: HashMap::new(),
    }
  }

  pub fn resource_manager(&mut self) -> &mut ResourceManager {
    &mut self.res_manager
  }
}

pub trait Get<T>: Sized {
  type Id;

  fn get_id(&mut self, name: &str) -> Option<Self::Id>;
  fn get_by_id(&self, id: Self::Id) -> Option<&T>;
  fn get(&mut self, name: &str) -> Option<&T> {
    self.get_id(name).and_then(move |i| self.get_by_id(i))
  }
}

impl<'a> Get<Model> for Scene<'a> {
  type Id = Id<'a, Model>;

  fn get_id(&mut self, name: &str) -> Option<Self::Id> {
    match self.model_cache.get(name).cloned() {
      id@Some(..) => {
        deb!("cache hit for model \"{}\"", name);
        id
      },
      None => {
        // cache miss; load then
        let path_str = format!("data/models/{}.obj", name);
        let path = Path::new(&path_str);

        deb!("cache miss for model \"{}\"", name);

        if path.exists() {
          match Model::load(&mut self.res_manager, path) {
            Ok(model) => {
              let model_id: Id<Model> = (self.models.len() as u32).into();

              // add the model to the list of loaded models
              self.models.push(model);
              // add the model to the cache
              self.model_cache.insert(name.to_owned(), model_id.clone());

              Some(model_id)
            },
            Err(e) => {
              err!("unable to load model '{}': '{:?}'", name, e);
              None
            }
          }
        } else { // TODO: add a manifest override to look in somewhere else
          err!("model '{}' cannot be found", name);
          None
        }
      }
    }
  }

  fn get_by_id(&self, id: Self::Id) -> Option<&Model> {
    self.models.get(*id as usize)
  }
}
<|endoftext|>


<commit_before>use serialize::json::{ToJson, Json, Array};

/// A scope for retrieving permissions and properties.
///
/// A scope is an optional limitation on which some property or permission applies. A scope
/// consists of three different elements:
///
/// * The `network` indicates for which network some property or permission should be stored.
/// * The `sender` indicates the IRC user for which some property or permission should be stored.
/// * The `receiver` indicates the channel for which some property or permission should be stored.
///
/// Note that for a sender or receiver scope, you also should provide a network, as it makes no
/// sense to for example provide a permission to the same channel on different networks (they are
/// only the same in name, but might be completely different in context).
///
/// The most generic scope (and easiest one to start with) is one applied to everything. Such a
/// scope can be created by the `Scope::any()` method.
#[derive(Debug, Clone, PartialEq)]
pub struct Scope {
    /// The network on which the scope is limited (if any).
    pub network: Option<String>,

    /// The sender on which the scope is limited (if any).
    pub sender: Option<String>,

    /// The receiver on which the scope is limited (if any).
    pub receiver: Option<String>,
}

impl Scope {
    /// Construct a new scope with the specified limitations for network, sender and receiver
    pub fn new(network: Option<String>, sender: Option<String>, receiver: Option<String>) -> Scope {
        Scope { network: network, sender: sender, receiver: receiver }
    }

    /// Scope to everyone and anything
    pub fn any() -> Scope {
        Scope::new(None, None, None)
    }

    /// Scope to a specific network
    pub fn network(network: &str) -> Scope {
        Scope::new(Some(network.to_string()), None, None)
    }

    /// Scope to a specific sender (typically a channel)
    pub fn sender(network: &str, sender: &str) -> Scope {
        Scope::new(Some(network.to_string()), Some(sender.to_string()), None)
    }

    /// Scope to a specific receiver (typically a user)
    pub fn receiver(network: &str, receiver: &str) -> Scope {
        Scope::new(Some(network.to_string()), None, Some(receiver.to_string()))
    }

    /// Scope to a specific receiver and channel (typically a user in a channel)
    pub fn to(network: &str, sender: &str, receiver: &str) -> Scope {
        Scope::new(Some(network.to_string()), Some(sender.to_string()), Some(receiver.to_string()))
    }

    /// Checks whether the scope is set to be applied to everything.
    pub fn is_any(&self) -> bool {
        self.network == None && self.sender == None && self.receiver == None
    }
}

impl ToJson for Scope {
    fn to_json(&self) -> Json {
        let mut arr = Array::new();
        arr.push(match self.network {
            None => Json::Null,
            Some(ref s) => Json::String(s.clone()),
        });
        arr.push(match self.sender {
            None => Json::Null,
            Some(ref s) => Json::String(s.clone()),
        });
        arr.push(match self.receiver {
            None => Json::Null,
            Some(ref s) => Json::String(s.clone()),
        });
        Json::Array(arr)
    }
}
<commit_msg>Optimized json output of scope<commit_after>use serialize::json::{ToJson, Json, Array};

/// A scope for retrieving permissions and properties.
///
/// A scope is an optional limitation on which some property or permission applies. A scope
/// consists of three different elements:
///
/// * The `network` indicates for which network some property or permission should be stored.
/// * The `sender` indicates the IRC user for which some property or permission should be stored.
/// * The `receiver` indicates the channel for which some property or permission should be stored.
///
/// Note that for a sender or receiver scope, you also should provide a network, as it makes no
/// sense to for example provide a permission to the same channel on different networks (they are
/// only the same in name, but might be completely different in context).
///
/// The most generic scope (and easiest one to start with) is one applied to everything. Such a
/// scope can be created by the `Scope::any()` method.
#[derive(Debug, Clone, PartialEq)]
pub struct Scope {
    /// The network on which the scope is limited (if any).
    pub network: Option<String>,

    /// The sender on which the scope is limited (if any).
    pub sender: Option<String>,

    /// The receiver on which the scope is limited (if any).
    pub receiver: Option<String>,
}

impl Scope {
    /// Construct a new scope with the specified limitations for network, sender and receiver
    pub fn new(network: Option<String>, sender: Option<String>, receiver: Option<String>) -> Scope {
        Scope { network: network, sender: sender, receiver: receiver }
    }

    /// Scope to everyone and anything
    pub fn any() -> Scope {
        Scope::new(None, None, None)
    }

    /// Scope to a specific network
    pub fn network(network: &str) -> Scope {
        Scope::new(Some(network.to_string()), None, None)
    }

    /// Scope to a specific sender (typically a channel)
    pub fn sender(network: &str, sender: &str) -> Scope {
        Scope::new(Some(network.to_string()), Some(sender.to_string()), None)
    }

    /// Scope to a specific receiver (typically a user)
    pub fn receiver(network: &str, receiver: &str) -> Scope {
        Scope::new(Some(network.to_string()), None, Some(receiver.to_string()))
    }

    /// Scope to a specific receiver and channel (typically a user in a channel)
    pub fn to(network: &str, sender: &str, receiver: &str) -> Scope {
        Scope::new(Some(network.to_string()), Some(sender.to_string()), Some(receiver.to_string()))
    }

    /// Checks whether the scope is set to be applied to everything.
    pub fn is_any(&self) -> bool {
        self.network == None && self.sender == None && self.receiver == None
    }
}

impl ToJson for Scope {
    fn to_json(&self) -> Json {
        let mut arr = Array::new();
        if self.network.is_some() || self.sender.is_some() || self.receiver.is_some() {
            arr.push(match self.network {
                None => Json::Null,
                Some(ref s) => Json::String(s.clone()),
            });

            if self.sender.is_some() || self.receiver.is_some() {
                arr.push(match self.sender {
                    None => Json::Null,
                    Some(ref s) => Json::String(s.clone()),
                });

                if let Some(ref s) = self.receiver {
                    arr.push(Json::String(s.clone()));
                }
            }
        }
        Json::Array(arr)
    }
}
<|endoftext|>


<commit_before>//! Sieve of Erastothenes

use core::iter::range_step;
use collections::dlist::DList;
use collections::deque::Deque;

/// A prime number sieve suitable for factoring.
pub struct Sieve {
    sieve : Vec<uint>
}

impl Sieve {
    /// Sieves primes up to `n`. Internally stores the largest prime factor of every number.
    pub fn sieve_to(n : uint) -> Sieve {
        let mut s = Sieve {sieve : Vec::from_elem(n+1, 0u)};
        for p in range(2,n+1) {
            if *s.sieve.get(p) == 0 {
                for i in range_step(p, n+1, p) {
                    *s.sieve.get_mut(i) = p;
                }
            }
        }
        return s;
    }

    /// Sieves primes up to `n`. Returns the sieve as well as a list of primes.
    pub fn sieve_to_list(n : uint) -> (Sieve, DList<uint>) {
        let mut s = Sieve {sieve : Vec::from_elem(n+1,0u)};
        let mut primes = DList::new();
        for p in range(2,n+1) {
            if *s.sieve.get(p) == 0 {
                primes.push_back(p);
                for i in range_step(p, n+1, p) {
                    *s.sieve.get_mut(i) = p;
                }
            }
        }
        return (s, primes);
    }

    /// Factors n. Returns a list of (p,k) pairs for every prime power p^k dividing `n`. For `n` = 1 returns the empty list. Fails when `n` is too large or 0.
    pub fn factor(&self, n : uint) -> DList<(uint,uint)> {
        if n >= self.sieve.len() {
            fail!("Trying to factor {} while the size of the sieve is {}", n, self.sieve.len() - 1);
        }
        if n == 0 {
            fail!("Trying to factor 0.");
        }
        let mut n = n;
        let mut res : DList<(uint,uint)> = DList::new();
        while n > 1 {
            let p = *self.sieve.get(n);
            let mut k = 0;
            while n % p == 0 {
                n /= p;
                k+=1;
            }
            res.push_front((p,k));
        }
        return res;
    }
}

<commit_msg>Added a divisors function to the sieve.<commit_after>//! Sieve of Erastothenes

use core::iter::range_step;
use collections::dlist::DList;
use collections::deque::Deque;

/// A prime number sieve suitable for factoring.
pub struct Sieve {
    sieve: Vec<uint>
}

impl Sieve {
    /// Sieves primes up to `n`. Internally stores the largest prime factor of every number.
    pub fn sieve_to(n: uint) -> Sieve {
        let mut s = Sieve {sieve: Vec::from_elem(n+1, 0u)};
        for p in range(2,n+1) {
            if *s.sieve.get(p) == 0 {
                for i in range_step(p, n+1, p) {
                    *s.sieve.get_mut(i) = p;
                }
            }
        }
        return s;
    }

    /// Sieves primes up to `n`. Returns the sieve as well as a list of primes.
    pub fn sieve_to_list(n: uint) -> (Sieve, DList<uint>) {
        let mut s = Sieve {sieve: Vec::from_elem(n+1,0u)};
        let mut primes = DList::new();
        for p in range(2,n+1) {
            if *s.sieve.get(p) == 0 {
                primes.push_back(p);
                for i in range_step(p, n+1, p) {
                    *s.sieve.get_mut(i) = p;
                }
            }
        }
        return (s, primes);
    }

    /// A wrapper to sieve_to.
    pub fn new(n: uint) -> Sieve {
        Sieve::sieve_to(n)
    }

    /// Factors n. Returns a list of (p,k) pairs for every prime power p^k dividing `n`. For `n` = 1 returns the empty list. Fails when `n` is too large or 0.
    pub fn factor(&self, n: uint) -> DList<(uint,uint)> {
        if n >= self.sieve.len() {
            fail!("Trying to factor {} while the size of the sieve is {}", n, self.sieve.len() - 1);
        }
        if n == 0 {
            fail!("Trying to factor 0.");
        }
        let mut n = n;
        let mut res: DList<(uint,uint)> = DList::new();
        while n > 1 {
            let p = *self.sieve.get(n);
            let mut k = 0;
            while n % p == 0 {
                n /= p;
                k+=1;
            }
            res.push_front((p,k));
        }
        return res;
    }

    /// Finds divisors of `n`.
    pub fn divisors(&self, mut n: uint) -> DList<uint> {
        if n >= self.sieve.len() {
            fail!("Trying to find divisors of {} while the size of the sieve is {}", n, self.sieve.len() - 1);
        }
        if n == 0 {
            fail!("Trying to find divisors of 0.");
        }
        if n == 1 {
            let mut l = DList::new();
            l.push_front(1);
            return l;
        }
        let p = *self.sieve.get(n);
        let mut k = 0;
        while n % p == 0 {
            n/=p;
            k+=1;
        }
        let l = self.divisors(n);
        let mut res = DList::new();
        for d in l.iter() {
            let mut pp = 1;
            for _ in range(0,k+1) {
                res.push_back(d*pp);
                pp*=p;
            }
        }
        return res;
    }
}

<|endoftext|>


<commit_before>use std::collections::VecDeque;
use std::mem::swap;

/// A stack that maintains a pointer to a focused element.
///
/// This primarily exists to keep track of the stack of windows in each
/// group and to remember which window within the stack is currently focused.
///
/// The order of the stack and the pointer to the focused element can be moved
/// independently:
///
/// - [`shuffle_next()`]/[`shuffle_previous()`] can be used to change
///   the order of the elements in the stack.
/// - [`focus_next()`]/[`focus_previous()`]
///   can be used to change the focused element, without affecting ordering.
///
/// [`shuffle_next()`]: #method.shuffle_next
/// [`shuffle_previous()`]: #method.shuffle_previous
/// [`focus_next()`]: #method.focus_next
/// [`focus_previous()`]: #method.focus_previous
#[derive(Clone, Debug, PartialEq)]
pub struct Stack<T> {
    // This is implemented as a zipper, where the first element of `after` is
    // currently focused. e.g. A stack of `[1, 2, 3, 4]` where `3` is focused is
    // stored as `{before: [1, 2], after: [3, 4]}`.
    before: VecDeque<T>,
    after: VecDeque<T>,
}

impl<T> Stack<T> {
    pub fn new() -> Stack<T> {
        Stack {
            before: VecDeque::new(),
            after: VecDeque::new(),
        }
    }

    /// Returns the number of elements in the stack.
    pub fn len(&self) -> usize {
        self.before.len() + self.after.len()
    }

    /// Adds an element to the stack (at the end) and focuses it.
    pub fn push(&mut self, value: T) {
        self.before.extend(self.after.drain(..));
        self.after.push_front(value);
    }

    /// Returns an iterator over the elements in order, ignoring focus.
    pub fn iter(&self) -> impl Iterator<Item = &T> {
        self.before.iter().chain(self.after.iter())
    }

    /// Returns an iterator mutably over the element in order, ignoring focus.
    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
        self.before.iter_mut().chain(self.after.iter_mut())
    }

    /// Returns a reference to the focused element.
    pub fn focused(&self) -> Option<&T> {
        self.after.get(0)
    }

    /// Returns a mutable reference to the focued element.
    pub fn focused_mut(&mut self) -> Option<&mut T> {
        self.after.get_mut(0)
    }

    // If there is no element focused, try to focus the last element.
    fn ensure_after_not_empty(&mut self) {
        if self.after.is_empty() && !self.before.is_empty() {
            self.after.push_front(self.before.pop_back().unwrap());
        }
    }

    /// Removes and returns the first element matching the predicate.
    ///
    /// If the removed element is currently focused, focus shifts to the
    /// next element.
    ///
    /// # Panics
    ///
    /// Panics if no element matches the predicate.
    pub fn remove<P>(&mut self, mut p: P) -> T
    where
        P: FnMut(&T) -> bool,
    {
        if let Some(position) = self.before.iter().position(&mut p) {
            self.before.remove(position).unwrap()
        } else {
            let position = self.after
                .iter()
                .position(&mut p)
                .expect("No element in stack matches predicate");
            let removed = self.after.remove(position).unwrap();
            self.ensure_after_not_empty();
            removed
        }
    }

    /// Removes and returns the focused element (if any), shifting focus to the
    /// next element.
    pub fn remove_focused(&mut self) -> Option<T> {
        let removed = self.after.pop_front();
        self.ensure_after_not_empty();
        removed
    }

    /// Focuses the first element in the stack that matches the predicate.
    ///
    /// # Panics
    ///
    /// Panics if no element matches the predicate.
    pub fn focus<P>(&mut self, mut p: P)
    where
        P: FnMut(&T) -> bool,
    {
        if let Some(position) = self.before.iter().position(&mut p) {
            for elem in self.before.drain(position..).rev() {
                self.after.push_front(elem);
            }
        } else if let Some(position) = self.after.iter().position(&mut p) {
            if position == 0 {
                return; // Already focused.
            }
            for elem in self.after.drain(..position) {
                self.before.push_back(elem);
            }
        } else {
            panic!("No element in stack matches predicate");
        }
    }

    /// Shifts focus to the next element.
    pub fn focus_next(&mut self) {
        if self.len() < 2 {
            return;
        }
        self.before.push_back(self.after.pop_front().unwrap());
        if self.after.is_empty() {
            swap(&mut self.after, &mut self.before);
        }
    }

    /// Shifts focus to the previous element.
    pub fn focus_previous(&mut self) {
        if self.before.is_empty() {
            swap(&mut self.after, &mut self.before);
        }
        if let Some(elem) = self.before.pop_back() {
            self.after.push_front(elem);
        }
    }

    /// Inserts the currently focused element after the next element.
    pub fn shuffle_next(&mut self) {
        if self.len() < 2 {
            return;
        }
        if self.after.len() > 1 {
            self.before.push_back(self.after.remove(1).unwrap());
        } else if self.after.len() == 1 && self.before.len() >= 1 {
            self.before.push_front(self.after.pop_front().unwrap());
            swap(&mut self.after, &mut self.before);
        }
    }

    /// Inserts the currently focused element before the previous element.
    pub fn shuffle_previous(&mut self) {
        if self.after.len() >= 1 && self.before.len() >= 1 {
            self.after.insert(1, self.before.pop_back().unwrap());
        } else if self.after.len() >= 1 {
            self.before.extend(self.after.drain(1..));
        }
    }
}

impl<T> From<Vec<T>> for Stack<T> {
    fn from(vec: Vec<T>) -> Self {
        Stack {
            before: VecDeque::new(),
            after: VecDeque::from(vec),
        }
    }
}

#[cfg(test)]
mod test {
    use std::cmp::PartialEq;
    use std::collections::VecDeque;

    use super::Stack;

    impl<T> PartialEq<Vec<T>> for Stack<T>
    where
        T: PartialEq + Clone,
    {
        fn eq(&self, other: &Vec<T>) -> bool {
            let mut vec = Vec::new();
            vec.extend(self.before.clone());
            vec.extend(self.after.clone());
            &vec == other
        }
    }

    fn stack_from_pieces<T>(before: Vec<T>, after: Vec<T>) -> Stack<T> {
        Stack {
            before: VecDeque::from(before),
            after: VecDeque::from(after),
        }
    }

    #[test]
    fn test_from() {
        let vec = vec![1, 2, 3];
        let stack = Stack::from(vec.clone());
        assert_eq!(stack, vec);
        assert_eq!(stack.focused(), Some(&vec[0]));
    }

    #[test]
    fn len() {
        let stack = stack_from_pieces(vec![1, 2], vec![2, 3]);
        assert_eq!(stack.len(), 4);
    }

    #[test]
    fn test_push() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        assert_eq!(stack, vec![2]);
        assert_eq!(stack.focused(), Some(&2));
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));
        // Resulting order is also important:
        assert_eq!(stack, vec![2, 3]);
    }

    #[test]
    fn test_focused() {
        let stack = stack_from_pieces(vec![], vec![2]);
        assert_eq!(stack.focused(), Some(&2));
        let stack: Stack<u8> = stack_from_pieces(vec![], vec![]);
        assert_eq!(stack.focused(), None);
    }

    #[test]
    fn test_remove() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.remove(|v| v == &3);
        assert_eq!(stack, vec![2, 4]);
    }

    #[test]
    fn test_remove_focused() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));

        let element = stack.remove_focused();
        assert_eq!(element, Some(3));
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack, vec![2]);
    }

    #[test]
    fn test_remove_focused_when_no_focus() {
        let mut stack = Stack::<u8>::new();
        assert_eq!(stack.focused(), None);
        let element = stack.remove_focused();
        assert_eq!(element, None);
        assert_eq!(stack.focused(), None);
    }

    #[test]
    fn test_iter() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        let mut iter = stack.iter();
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), Some(&4));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn test_set_get_focus() {
        let mut stack = Stack::<u8>::new();
        assert_eq!(stack.focused(), None);
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack, vec![2, 3]);
        stack.focus(|v| v == &2);
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack, vec![2, 3]);
        stack.focus(|v| v == &3);
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack, vec![2, 3]);
    }

    #[test]
    fn test_focus_next() {
        let vec = vec![1, 2, 3];
        let mut stack = Stack::from(vec.clone());

        // We constantly assert the order of the stack, as it's very easy
        // to write a non-order-preserving implementation!

        assert_eq!(stack.focused(), Some(&1));
        assert_eq!(stack, vec);

        stack.focus_next();
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack, vec);

        stack.focus_next();
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack, vec);

        stack.focus_next();
        assert_eq!(stack.focused(), Some(&1));
        assert_eq!(stack, vec);
    }

    #[test]
    fn test_focus_previous() {
        let vec = vec![1, 2, 3];
        let mut stack = Stack::from(vec.clone());

        // We constantly assert the order of the stack, as it's very easy
        // to write a non-order-preserving implementation!

        assert_eq!(stack.focused(), Some(&1));
        assert_eq!(stack, vec);

        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack, vec);

        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack, vec);

        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&1));
        assert_eq!(stack, vec);
    }

    #[test]
    fn test_shuffle_next() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&4));

        assert_eq!(stack, vec![2, 3, 4]);
        stack.shuffle_next();
        assert_eq!(stack, vec![4, 2, 3]);
        stack.shuffle_next();
        assert_eq!(stack, vec![2, 4, 3]);
        stack.shuffle_next();
        assert_eq!(stack, vec![2, 3, 4]);
    }

    #[test]
    fn test_shuffle_previous() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&4));

        assert_eq!(stack, vec![2, 3, 4]);
        stack.shuffle_previous();
        assert_eq!(stack, vec![2, 4, 3]);
        stack.shuffle_previous();
        assert_eq!(stack, vec![4, 2, 3]);
        println!("current: {:?}", stack);
        stack.shuffle_previous();
        assert_eq!(stack, vec![2, 3, 4]);
    }
}
<commit_msg>Insert extra new-line between top-level defn.<commit_after>use std::collections::VecDeque;
use std::mem::swap;

/// A stack that maintains a pointer to a focused element.
///
/// This primarily exists to keep track of the stack of windows in each
/// group and to remember which window within the stack is currently focused.
///
/// The order of the stack and the pointer to the focused element can be moved
/// independently:
///
/// - [`shuffle_next()`]/[`shuffle_previous()`] can be used to change
///   the order of the elements in the stack.
/// - [`focus_next()`]/[`focus_previous()`]
///   can be used to change the focused element, without affecting ordering.
///
/// [`shuffle_next()`]: #method.shuffle_next
/// [`shuffle_previous()`]: #method.shuffle_previous
/// [`focus_next()`]: #method.focus_next
/// [`focus_previous()`]: #method.focus_previous
#[derive(Clone, Debug, PartialEq)]
pub struct Stack<T> {
    // This is implemented as a zipper, where the first element of `after` is
    // currently focused. e.g. A stack of `[1, 2, 3, 4]` where `3` is focused is
    // stored as `{before: [1, 2], after: [3, 4]}`.
    before: VecDeque<T>,
    after: VecDeque<T>,
}

impl<T> Stack<T> {
    pub fn new() -> Stack<T> {
        Stack {
            before: VecDeque::new(),
            after: VecDeque::new(),
        }
    }

    /// Returns the number of elements in the stack.
    pub fn len(&self) -> usize {
        self.before.len() + self.after.len()
    }

    /// Adds an element to the stack (at the end) and focuses it.
    pub fn push(&mut self, value: T) {
        self.before.extend(self.after.drain(..));
        self.after.push_front(value);
    }

    /// Returns an iterator over the elements in order, ignoring focus.
    pub fn iter(&self) -> impl Iterator<Item = &T> {
        self.before.iter().chain(self.after.iter())
    }

    /// Returns an iterator mutably over the element in order, ignoring focus.
    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
        self.before.iter_mut().chain(self.after.iter_mut())
    }

    /// Returns a reference to the focused element.
    pub fn focused(&self) -> Option<&T> {
        self.after.get(0)
    }

    /// Returns a mutable reference to the focued element.
    pub fn focused_mut(&mut self) -> Option<&mut T> {
        self.after.get_mut(0)
    }

    // If there is no element focused, try to focus the last element.
    fn ensure_after_not_empty(&mut self) {
        if self.after.is_empty() && !self.before.is_empty() {
            self.after.push_front(self.before.pop_back().unwrap());
        }
    }

    /// Removes and returns the first element matching the predicate.
    ///
    /// If the removed element is currently focused, focus shifts to the
    /// next element.
    ///
    /// # Panics
    ///
    /// Panics if no element matches the predicate.
    pub fn remove<P>(&mut self, mut p: P) -> T
    where
        P: FnMut(&T) -> bool,
    {
        if let Some(position) = self.before.iter().position(&mut p) {
            self.before.remove(position).unwrap()
        } else {
            let position = self.after
                .iter()
                .position(&mut p)
                .expect("No element in stack matches predicate");
            let removed = self.after.remove(position).unwrap();
            self.ensure_after_not_empty();
            removed
        }
    }

    /// Removes and returns the focused element (if any), shifting focus to the
    /// next element.
    pub fn remove_focused(&mut self) -> Option<T> {
        let removed = self.after.pop_front();
        self.ensure_after_not_empty();
        removed
    }

    /// Focuses the first element in the stack that matches the predicate.
    ///
    /// # Panics
    ///
    /// Panics if no element matches the predicate.
    pub fn focus<P>(&mut self, mut p: P)
    where
        P: FnMut(&T) -> bool,
    {
        if let Some(position) = self.before.iter().position(&mut p) {
            for elem in self.before.drain(position..).rev() {
                self.after.push_front(elem);
            }
        } else if let Some(position) = self.after.iter().position(&mut p) {
            if position == 0 {
                return; // Already focused.
            }
            for elem in self.after.drain(..position) {
                self.before.push_back(elem);
            }
        } else {
            panic!("No element in stack matches predicate");
        }
    }

    /// Shifts focus to the next element.
    pub fn focus_next(&mut self) {
        if self.len() < 2 {
            return;
        }
        self.before.push_back(self.after.pop_front().unwrap());
        if self.after.is_empty() {
            swap(&mut self.after, &mut self.before);
        }
    }

    /// Shifts focus to the previous element.
    pub fn focus_previous(&mut self) {
        if self.before.is_empty() {
            swap(&mut self.after, &mut self.before);
        }
        if let Some(elem) = self.before.pop_back() {
            self.after.push_front(elem);
        }
    }

    /// Inserts the currently focused element after the next element.
    pub fn shuffle_next(&mut self) {
        if self.len() < 2 {
            return;
        }
        if self.after.len() > 1 {
            self.before.push_back(self.after.remove(1).unwrap());
        } else if self.after.len() == 1 && self.before.len() >= 1 {
            self.before.push_front(self.after.pop_front().unwrap());
            swap(&mut self.after, &mut self.before);
        }
    }

    /// Inserts the currently focused element before the previous element.
    pub fn shuffle_previous(&mut self) {
        if self.after.len() >= 1 && self.before.len() >= 1 {
            self.after.insert(1, self.before.pop_back().unwrap());
        } else if self.after.len() >= 1 {
            self.before.extend(self.after.drain(1..));
        }
    }
}

impl<T> From<Vec<T>> for Stack<T> {
    fn from(vec: Vec<T>) -> Self {
        Stack {
            before: VecDeque::new(),
            after: VecDeque::from(vec),
        }
    }
}

#[cfg(test)]
mod test {
    use std::cmp::PartialEq;
    use std::collections::VecDeque;

    use super::Stack;

    impl<T> PartialEq<Vec<T>> for Stack<T>
    where
        T: PartialEq + Clone,
    {
        fn eq(&self, other: &Vec<T>) -> bool {
            let mut vec = Vec::new();
            vec.extend(self.before.clone());
            vec.extend(self.after.clone());
            &vec == other
        }
    }

    fn stack_from_pieces<T>(before: Vec<T>, after: Vec<T>) -> Stack<T> {
        Stack {
            before: VecDeque::from(before),
            after: VecDeque::from(after),
        }
    }

    #[test]
    fn test_from() {
        let vec = vec![1, 2, 3];
        let stack = Stack::from(vec.clone());
        assert_eq!(stack, vec);
        assert_eq!(stack.focused(), Some(&vec[0]));
    }

    #[test]
    fn len() {
        let stack = stack_from_pieces(vec![1, 2], vec![2, 3]);
        assert_eq!(stack.len(), 4);
    }

    #[test]
    fn test_push() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        assert_eq!(stack, vec![2]);
        assert_eq!(stack.focused(), Some(&2));
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));
        // Resulting order is also important:
        assert_eq!(stack, vec![2, 3]);
    }

    #[test]
    fn test_focused() {
        let stack = stack_from_pieces(vec![], vec![2]);
        assert_eq!(stack.focused(), Some(&2));
        let stack: Stack<u8> = stack_from_pieces(vec![], vec![]);
        assert_eq!(stack.focused(), None);
    }

    #[test]
    fn test_remove() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.remove(|v| v == &3);
        assert_eq!(stack, vec![2, 4]);
    }

    #[test]
    fn test_remove_focused() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));

        let element = stack.remove_focused();
        assert_eq!(element, Some(3));
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack, vec![2]);
    }

    #[test]
    fn test_remove_focused_when_no_focus() {
        let mut stack = Stack::<u8>::new();
        assert_eq!(stack.focused(), None);
        let element = stack.remove_focused();
        assert_eq!(element, None);
        assert_eq!(stack.focused(), None);
    }

    #[test]
    fn test_iter() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        let mut iter = stack.iter();
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), Some(&4));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn test_set_get_focus() {
        let mut stack = Stack::<u8>::new();
        assert_eq!(stack.focused(), None);
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack, vec![2, 3]);
        stack.focus(|v| v == &2);
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack, vec![2, 3]);
        stack.focus(|v| v == &3);
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack, vec![2, 3]);
    }

    #[test]
    fn test_focus_next() {
        let vec = vec![1, 2, 3];
        let mut stack = Stack::from(vec.clone());

        // We constantly assert the order of the stack, as it's very easy
        // to write a non-order-preserving implementation!

        assert_eq!(stack.focused(), Some(&1));
        assert_eq!(stack, vec);

        stack.focus_next();
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack, vec);

        stack.focus_next();
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack, vec);

        stack.focus_next();
        assert_eq!(stack.focused(), Some(&1));
        assert_eq!(stack, vec);
    }

    #[test]
    fn test_focus_previous() {
        let vec = vec![1, 2, 3];
        let mut stack = Stack::from(vec.clone());

        // We constantly assert the order of the stack, as it's very easy
        // to write a non-order-preserving implementation!

        assert_eq!(stack.focused(), Some(&1));
        assert_eq!(stack, vec);

        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack, vec);

        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack, vec);

        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&1));
        assert_eq!(stack, vec);
    }

    #[test]
    fn test_shuffle_next() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&4));

        assert_eq!(stack, vec![2, 3, 4]);
        stack.shuffle_next();
        assert_eq!(stack, vec![4, 2, 3]);
        stack.shuffle_next();
        assert_eq!(stack, vec![2, 4, 3]);
        stack.shuffle_next();
        assert_eq!(stack, vec![2, 3, 4]);
    }

    #[test]
    fn test_shuffle_previous() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&4));

        assert_eq!(stack, vec![2, 3, 4]);
        stack.shuffle_previous();
        assert_eq!(stack, vec![2, 4, 3]);
        stack.shuffle_previous();
        assert_eq!(stack, vec![4, 2, 3]);
        println!("current: {:?}", stack);
        stack.shuffle_previous();
        assert_eq!(stack, vec![2, 3, 4]);
    }
}
<|endoftext|>