<commit_before><commit_msg>Initial sketch of path2 module, starting with WindowsPath.<commit_after>extern mod std;

struct WindowsPath {
    host: option<~str>;
    device: option<~str>;
    is_absolute: bool;
    components: ~[~str];
}

struct PosixPath {
    is_absolute: bool;
    components: ~[~str];
}

trait Path {

    static fn from_str((&str)) -> self;
    fn to_str() -> ~str;

    fn dirname() -> ~str;
    fn filename() -> option<~str>;
    fn filestem() -> option<~str>;
    fn filetype() -> option<~str>;

    fn with_dirname((&str)) -> self;
    fn with_filename((&str)) -> self;
    fn with_filestem((&str)) -> self;
    fn with_filetype((&str)) -> self;

    fn push_components((&[~str])) -> self;
    fn pop_component() -> self;
}

impl WindowsPath : Path {

    fn to_str() -> ~str {
        match self.filename() {
          none => self.dirname(),
          some(ref f) =>
          if (self.components.len() == 1 &&
              !self.is_absolute &&
              self.host == none &&
              self.device == none) {
            copy *f
          } else {
            self.dirname() + "\\" + *f
          }
        }
    }

    static fn from_str(s: &str) -> WindowsPath {
        let host;
        let device;
        let rest;

        match windows::extract_drive_prefix(s) {
          some((ref d, ref r)) => {
            host = none;
            device = some(copy *d);
            rest = copy *r;
          }
          none => {
            match windows::extract_unc_prefix(s) {
              some((ref h, ref r)) => {
                host = some(copy *h);
                device = none;
                rest = copy *r;
              }
              none => {
                host = none;
                device = none;
                rest = str::from_slice(s);
              }
            }
          }
        }

        let mut components =
            str::split_nonempty(rest, |c| windows::is_sep(c as u8));
        let is_absolute = (rest.len() != 0 && windows::is_sep(rest[0]));
        return WindowsPath { host: host,
                             device: device,
                             is_absolute: is_absolute,
                            components: components }
    }

    fn dirname() -> ~str {
        let mut s = ~"";
        match self.host {
          some(h) => { s += "\\\\"; s += h; }
          none => { }
        }
        match self.device {
          some(d) => { s += d; s += ":"; }
          none => { }
        }
        if self.is_absolute {
            s += "\\";
        }
        let mut d = copy self.components;
        if d.len() != 0 {
            vec::pop(d);
        }
        s += str::connect(d, "\\");
        if s.len() == 0 {
            s = ~".";
        }
        return s;
    }

    fn filename() -> option<~str> {
        match self.components.len() {
          0 => none,
          1 => some(copy self.components[0]),
          n => some(copy self.components[n - 1])
        }
    }

    fn filestem() -> option<~str> {
        match self.filename() {
          none => none,
          some(ref f) => {
            match str::rfind_char(*f, '.') {
              some(p) => some(f.slice(0, p)),
              none => some(copy *f)
            }
          }
        }
    }

    fn filetype() -> option<~str> {
        match self.filename() {
          none => none,
          some(ref f) => {
            match str::rfind_char(*f, '.') {
              some(p) if p+1 < f.len() => some(f.slice(p+1, f.len())),
              _ => none
            }
          }
        }
    }

    fn with_dirname(d: &str) -> WindowsPath {
        let dpath = from_str::<WindowsPath>(d);
        match self.filename() {
          some(ref f) => dpath.push_components(~[copy *f]),
          none => dpath
        }
    }

    fn with_filename(f: &str) -> WindowsPath {
        assert ! str::any(f, |c| windows::is_sep(c as u8));
        self.dir_path().push_components(~[str::from_slice(f)])
    }

    fn with_filestem(s: &str) -> WindowsPath {
        match self.filetype() {
          none => self.with_filename(s),
          some(ref t) =>
          self.with_filename(str::from_slice(s) + "." + *t)
        }
    }

    fn with_filetype(t: &str) -> WindowsPath {
        let t = ~"." + str::from_slice(t);
        match self.filestem() {
          none => self.with_filename(t),
          some(ref s) =>
          self.with_filename(*s + t)
        }
    }

    fn dir_path() -> WindowsPath {
        if self.components.len() != 0 {
            self.pop_component()
        } else {
            copy self
        }
    }

    fn file_path() -> WindowsPath {
        let cs = match self.filename() {
          none => ~[],
          some(ref f) => ~[copy *f]
        };
        return WindowsPath { host: none,
                             device: none,
                             is_absolute: false,
                             components: cs }
    }

    fn push_components(cs: &[~str]) -> WindowsPath {
        return WindowsPath { components: self.components + cs, ..self }
    }

    fn pop_component() -> WindowsPath {
        let mut cs = copy self.components;
        if cs.len() != 0 {
            vec::pop(cs);
        }
        return WindowsPath { components: cs, ..self }
    }
}

// Various windows helpers, and tests for the impl.
mod windows {

    #[inline(always)]
    fn is_sep(u: u8) -> bool {
        u == '/' as u8 || u == '\\' as u8
    }

    fn extract_unc_prefix(s: &str) -> option<(~str,~str)> {
        if (s.len() > 1 &&
            s[0] == '\\' as u8 &&
            s[1] == '\\' as u8) {
            let mut i = 2;
            while i < s.len() {
                if s[i] == '\\' as u8 {
                    let pre = s.slice(2, i);
                    let rest = s.slice(i, s.len());
                    return some((pre, rest));
                }
                i += 1;
            }
        }
        none
    }

    fn extract_drive_prefix(s: &str) -> option<(~str,~str)> {
        if (s.len() > 1 &&
            libc::isalpha(s[0] as libc::c_int) != 0 &&
            s[1] == ':' as u8) {
            let rest = if s.len() == 2 { ~"" } else { s.slice(2, s.len()) };
            return some((s.slice(0,1), rest));
        }
        none
    }

    #[test]
    fn test_extract_unc_prefixes() {
        assert extract_unc_prefix("\\\\") == none;
        assert extract_unc_prefix("\\\\hi") == none;
        assert extract_unc_prefix("\\\\hi\\") == some((~"hi", ~"\\"));
        assert extract_unc_prefix("\\\\hi\\there") ==
            some((~"hi", ~"\\there"));
        assert extract_unc_prefix("\\\\hi\\there\\friends.txt") ==
            some((~"hi", ~"\\there\\friends.txt"));
    }

    #[test]
    fn test_extract_drive_prefixes() {
        assert extract_drive_prefix("c") == none;
        assert extract_drive_prefix("c:") == some((~"c", ~""));
        assert extract_drive_prefix("d:") == some((~"d", ~""));
        assert extract_drive_prefix("z:") == some((~"z", ~""));
        assert extract_drive_prefix("c:\\hi") == some((~"c", ~"\\hi"));
        assert extract_drive_prefix("d:hi") == some((~"d", ~"hi"));
        assert extract_drive_prefix("c:hi\\there.txt") ==
            some((~"c", ~"hi\\there.txt"));
        assert extract_drive_prefix("c:\\hi\\there.txt") ==
            some((~"c", ~"\\hi\\there.txt"));
    }

    #[test]
    fn test_windows_paths() {
        fn mk(s: &str) -> WindowsPath { from_str::<WindowsPath>(s) }
        fn t(wp: &WindowsPath, s: &str) {
            let ss = wp.to_str();
            let sss = str::from_slice(s);
            if (ss != sss) {
                debug!("got %s", ss);
                debug!("expected %s", sss);
                assert ss == sss;
            }
        }

        t(&(mk("hi")), "hi");
        t(&(mk("hi/there")), "hi\\there");
        t(&(mk("hi/there.txt")), "hi\\there.txt");

        t(&(mk("there.txt")
            .with_filetype("o")), "there.o");

        t(&(mk("hi/there.txt")
            .with_filetype("o")), "hi\\there.o");

        t(&(mk("hi/there.txt")
            .with_filetype("o")
            .with_dirname("c:\\program files A")),
          "c:\\program files A\\there.o");

        t(&(mk("hi/there.txt")
            .with_filetype("o")
            .with_dirname("c:\\program files B\\")),
          "c:\\program files B\\there.o");

        t(&(mk("hi/there.txt")
            .with_filetype("o")
            .with_dirname("c:\\program files C\\/")),
            "c:\\program files C\\there.o");

        t(&(mk("c:\\program files (x86)\\rust")
            .push_components([~"lib", ~"thingy.dll"])
            .with_filename("librustc.dll")),
          "c:\\program files (x86)\\rust\\lib\\librustc.dll");

    }

}
<|endoftext|>


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

/*!
Syntax extension to generate FourCCs.

Once loaded, fourcc!() is called with a single 4-character string,
and an optional ident that is either `big`, `little`, or `target`.
The ident represents endianness, and specifies in which direction
the characters should be read. If the ident is omitted, it is assumed
to be `big`, i.e. left-to-right order. It returns a u32.

# Examples

To load the extension and use it:

```rust,ignore
#[phase(syntax)]
extern crate fourcc;

fn main() {
    let val = fourcc!("\xC0\xFF\xEE!");
    assert_eq!(val, 0xC0FFEE21u32);
    let little_val = fourcc!("foo ", little);
    assert_eq!(little_val, 0x21EEFFC0u32);
}
 ```

# References

* [Wikipedia: FourCC](http://en.wikipedia.org/wiki/FourCC)

*/

#[crate_id = "fourcc#0.10-pre"];
#[crate_type = "rlib"];
#[crate_type = "dylib"];
#[license = "MIT/ASL2"];

#[feature(macro_registrar, managed_boxes)];

extern crate syntax;

use syntax::ast;
use syntax::ast::Name;
use syntax::attr::contains;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base;
use syntax::ext::base::{SyntaxExtension, BasicMacroExpander, NormalTT, ExtCtxt, MRExpr};
use syntax::ext::build::AstBuilder;
use syntax::parse;
use syntax::parse::token;
use syntax::parse::token::InternedString;

#[macro_registrar]
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
    register(token::intern("fourcc"),
        NormalTT(~BasicMacroExpander {
            expander: expand_syntax_ext,
            span: None,
        },
        None));
}

pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult {
    let (expr, endian) = parse_tts(cx, tts);

    let little = match endian {
        None => false,
        Some(Ident{ident, span}) => match token::get_ident(ident).get() {
            "little" => true,
            "big" => false,
            "target" => target_endian_little(cx, sp),
            _ => {
                cx.span_err(span, "invalid endian directive in fourcc!");
                target_endian_little(cx, sp)
            }
        }
    };

    let s = match expr.node {
        // expression is a literal
        ast::ExprLit(lit) => match lit.node {
            // string literal
            ast::LitStr(ref s, _) => {
                if s.get().char_len() != 4 {
                    cx.span_err(expr.span, "string literal with len != 4 in fourcc!");
                }
                s
            }
            _ => {
                cx.span_err(expr.span, "unsupported literal in fourcc!");
                return MRExpr(cx.expr_lit(sp, ast::LitUint(0u64, ast::TyU32)));
            }
        },
        _ => {
            cx.span_err(expr.span, "non-literal in fourcc!");
            return MRExpr(cx.expr_lit(sp, ast::LitUint(0u64, ast::TyU32)));
        }
    };

    let mut val = 0u32;
    for codepoint in s.get().chars().take(4) {
        let byte = if codepoint as u32 > 0xFF {
            cx.span_err(expr.span, "fourcc! literal character out of range 0-255");
            0u8
        } else {
            codepoint as u8
        };

        val = if little {
            (val >> 8) | ((byte as u32) << 24)
        } else {
            (val << 8) | (byte as u32)
        };
    }
    let e = cx.expr_lit(sp, ast::LitUint(val as u64, ast::TyU32));
    MRExpr(e)
}

struct Ident {
    ident: ast::Ident,
    span: Span
}

fn parse_tts(cx: &ExtCtxt, tts: &[ast::TokenTree]) -> (@ast::Expr, Option<Ident>) {
    let p = &mut parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts.to_owned());
    let ex = p.parse_expr();
    let id = if p.token == token::EOF {
        None
    } else {
        p.expect(&token::COMMA);
        let lo = p.span.lo;
        let ident = p.parse_ident();
        let hi = p.last_span.hi;
        Some(Ident{ident: ident, span: mk_sp(lo, hi)})
    };
    if p.token != token::EOF {
        p.unexpected();
    }
    (ex, id)
}

fn target_endian_little(cx: &ExtCtxt, sp: Span) -> bool {
    let meta = cx.meta_name_value(sp, InternedString::new("target_endian"),
        ast::LitStr(InternedString::new("little"), ast::CookedStr));
    contains(cx.cfg(), meta)
}

// FIXME (10872): This is required to prevent an LLVM assert on Windows
#[test]
fn dummy_test() { }
<commit_msg>libfourcc: Fix errors arising from the automated `~[T]` conversion<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
Syntax extension to generate FourCCs.

Once loaded, fourcc!() is called with a single 4-character string,
and an optional ident that is either `big`, `little`, or `target`.
The ident represents endianness, and specifies in which direction
the characters should be read. If the ident is omitted, it is assumed
to be `big`, i.e. left-to-right order. It returns a u32.

# Examples

To load the extension and use it:

```rust,ignore
#[phase(syntax)]
extern crate fourcc;

fn main() {
    let val = fourcc!("\xC0\xFF\xEE!");
    assert_eq!(val, 0xC0FFEE21u32);
    let little_val = fourcc!("foo ", little);
    assert_eq!(little_val, 0x21EEFFC0u32);
}
 ```

# References

* [Wikipedia: FourCC](http://en.wikipedia.org/wiki/FourCC)

*/

#[crate_id = "fourcc#0.10-pre"];
#[crate_type = "rlib"];
#[crate_type = "dylib"];
#[license = "MIT/ASL2"];

#[feature(macro_registrar, managed_boxes)];

extern crate syntax;

use syntax::ast;
use syntax::ast::Name;
use syntax::attr::contains;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base;
use syntax::ext::base::{SyntaxExtension, BasicMacroExpander, NormalTT, ExtCtxt, MRExpr};
use syntax::ext::build::AstBuilder;
use syntax::parse;
use syntax::parse::token;
use syntax::parse::token::InternedString;

#[macro_registrar]
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
    register(token::intern("fourcc"),
        NormalTT(~BasicMacroExpander {
            expander: expand_syntax_ext,
            span: None,
        },
        None));
}

pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult {
    let (expr, endian) = parse_tts(cx, tts);

    let little = match endian {
        None => false,
        Some(Ident{ident, span}) => match token::get_ident(ident).get() {
            "little" => true,
            "big" => false,
            "target" => target_endian_little(cx, sp),
            _ => {
                cx.span_err(span, "invalid endian directive in fourcc!");
                target_endian_little(cx, sp)
            }
        }
    };

    let s = match expr.node {
        // expression is a literal
        ast::ExprLit(lit) => match lit.node {
            // string literal
            ast::LitStr(ref s, _) => {
                if s.get().char_len() != 4 {
                    cx.span_err(expr.span, "string literal with len != 4 in fourcc!");
                }
                s
            }
            _ => {
                cx.span_err(expr.span, "unsupported literal in fourcc!");
                return MRExpr(cx.expr_lit(sp, ast::LitUint(0u64, ast::TyU32)));
            }
        },
        _ => {
            cx.span_err(expr.span, "non-literal in fourcc!");
            return MRExpr(cx.expr_lit(sp, ast::LitUint(0u64, ast::TyU32)));
        }
    };

    let mut val = 0u32;
    for codepoint in s.get().chars().take(4) {
        let byte = if codepoint as u32 > 0xFF {
            cx.span_err(expr.span, "fourcc! literal character out of range 0-255");
            0u8
        } else {
            codepoint as u8
        };

        val = if little {
            (val >> 8) | ((byte as u32) << 24)
        } else {
            (val << 8) | (byte as u32)
        };
    }
    let e = cx.expr_lit(sp, ast::LitUint(val as u64, ast::TyU32));
    MRExpr(e)
}

struct Ident {
    ident: ast::Ident,
    span: Span
}

fn parse_tts(cx: &ExtCtxt, tts: &[ast::TokenTree]) -> (@ast::Expr, Option<Ident>) {
    let p = &mut parse::new_parser_from_tts(cx.parse_sess(),
                                            cx.cfg(),
                                            tts.iter()
                                               .map(|x| (*x).clone())
                                               .collect());
    let ex = p.parse_expr();
    let id = if p.token == token::EOF {
        None
    } else {
        p.expect(&token::COMMA);
        let lo = p.span.lo;
        let ident = p.parse_ident();
        let hi = p.last_span.hi;
        Some(Ident{ident: ident, span: mk_sp(lo, hi)})
    };
    if p.token != token::EOF {
        p.unexpected();
    }
    (ex, id)
}

fn target_endian_little(cx: &ExtCtxt, sp: Span) -> bool {
    let meta = cx.meta_name_value(sp, InternedString::new("target_endian"),
        ast::LitStr(InternedString::new("little"), ast::CookedStr));
    contains(cx.cfg().as_slice(), meta)
}

// FIXME (10872): This is required to prevent an LLVM assert on Windows
#[test]
fn dummy_test() { }
<|endoftext|>


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

//! Runtime services
//!
//! The `rt` module provides a narrow set of runtime services,
//! including the global heap (exported in `heap`) and unwinding and
//! backtrace support. The APIs in this module are highly unstable,
//! and should be considered as private implementation details for the
//! time being.

#![experimental]

// FIXME: this should not be here.
#![allow(missing_docs)]

#![allow(dead_code)]

use os;
use thunk::Thunk;
use kinds::Send;
use thread::Thread;
use ops::FnOnce;
use sys;
use sys_common;
use sys_common::thread_info::{mod, NewThread};

// Reexport some of our utilities which are expected by other crates.
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
pub use self::unwind::{begin_unwind, begin_unwind_fmt};

// Reexport some functionality from liballoc.
pub use alloc::heap;

// Simple backtrace functionality (to print on panic)
pub mod backtrace;

// Internals
mod macros;

// These should be refactored/moved/made private over time
pub mod util;
pub mod unwind;
pub mod args;

mod at_exit_imp;
mod libunwind;

/// The default error code of the rust runtime if the main task panics instead
/// of exiting cleanly.
pub const DEFAULT_ERROR_CODE: int = 101;

#[cfg(any(windows, android))]
const OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
#[cfg(all(unix, not(android)))]
const OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);

#[cfg(not(test))]
#[lang = "start"]
fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
    use mem;
    use prelude::*;
    use rt;

    let something_around_the_top_of_the_stack = 1;
    let addr = &something_around_the_top_of_the_stack as *const int;
    let my_stack_top = addr as uint;

    // FIXME #11359 we just assume that this thread has a stack of a
    // certain size, and estimate that there's at most 20KB of stack
    // frames above our current position.
    let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;

    let failed = unsafe {
        // First, make sure we don't trigger any __morestack overflow checks,
        // and next set up our stack to have a guard page and run through our
        // own fault handlers if we hit it.
        sys_common::stack::record_os_managed_stack_bounds(my_stack_bottom,
                                                          my_stack_top);
        sys::thread::guard::init();
        sys::stack_overflow::init();

        // Next, set up the current Thread with the guard information we just
        // created. Note that this isn't necessary in general for new threads,
        // but we just do this to name the main thread and to give it correct
        // info about the stack bounds.
        let thread: Thread = NewThread::new(Some("<main>".into_string()));
        thread_info::set((my_stack_bottom, my_stack_top),
                         sys::thread::guard::main(),
                         thread);

        // By default, some platforms will send a *signal* when a EPIPE error
        // would otherwise be delivered. This runtime doesn't install a SIGPIPE
        // handler, causing it to kill the program, which isn't exactly what we
        // want!
        //
        // Hence, we set SIGPIPE to ignore when the program starts up in order
        // to prevent this problem.
        #[cfg(windows)] fn ignore_sigpipe() {}
        #[cfg(unix)] fn ignore_sigpipe() {
            use libc;
            use libc::funcs::posix01::signal::signal;
            unsafe {
                assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1);
            }
        }
        ignore_sigpipe();

        // Store our args if necessary in a squirreled away location
        args::init(argc, argv);

        // And finally, let's run some code!
        let res = unwind::try(|| {
            let main: fn() = mem::transmute(main);
            main();
        });
        cleanup();
        res.is_err()
    };

    // If the exit code wasn't set, then the try block must have panicked.
    if failed {
        rt::DEFAULT_ERROR_CODE
    } else {
        os::get_exit_status()
    }
}

/// Enqueues a procedure to run when the runtime is cleaned up
///
/// The procedure passed to this function will be executed as part of the
/// runtime cleanup phase. For normal rust programs, this means that it will run
/// after all other tasks have exited.
///
/// The procedure is *not* executed with a local `Task` available to it, so
/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
/// This is meant for "bare bones" usage to clean up runtime details, this is
/// not meant as a general-purpose "let's clean everything up" function.
///
/// It is forbidden for procedures to register more `at_exit` handlers when they
/// are running, and doing so will lead to a process abort.
pub fn at_exit<F:FnOnce()+Send>(f: F) {
    at_exit_imp::push(Thunk::new(f));
}

/// One-time runtime cleanup.
///
/// This function is unsafe because it performs no checks to ensure that the
/// runtime has completely ceased running. It is the responsibility of the
/// caller to ensure that the runtime is entirely shut down and nothing will be
/// poking around at the internal components.
///
/// Invoking cleanup while portions of the runtime are still in use may cause
/// undefined behavior.
pub unsafe fn cleanup() {
    args::cleanup();
    sys::stack_overflow::cleanup();
    at_exit_imp::cleanup();
}
<commit_msg>Disable at_exit handlers<commit_after>// Copyright 2013 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.

//! Runtime services
//!
//! The `rt` module provides a narrow set of runtime services,
//! including the global heap (exported in `heap`) and unwinding and
//! backtrace support. The APIs in this module are highly unstable,
//! and should be considered as private implementation details for the
//! time being.

#![experimental]

// FIXME: this should not be here.
#![allow(missing_docs)]

#![allow(dead_code)]

use os;
use thunk::Thunk;
use kinds::Send;
use thread::Thread;
use ops::FnOnce;
use sys;
use sys_common;
use sys_common::thread_info::{mod, NewThread};

// Reexport some of our utilities which are expected by other crates.
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
pub use self::unwind::{begin_unwind, begin_unwind_fmt};

// Reexport some functionality from liballoc.
pub use alloc::heap;

// Simple backtrace functionality (to print on panic)
pub mod backtrace;

// Internals
mod macros;

// These should be refactored/moved/made private over time
pub mod util;
pub mod unwind;
pub mod args;

mod at_exit_imp;
mod libunwind;

/// The default error code of the rust runtime if the main task panics instead
/// of exiting cleanly.
pub const DEFAULT_ERROR_CODE: int = 101;

#[cfg(any(windows, android))]
const OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
#[cfg(all(unix, not(android)))]
const OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);

#[cfg(not(test))]
#[lang = "start"]
fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
    use mem;
    use prelude::*;
    use rt;

    let something_around_the_top_of_the_stack = 1;
    let addr = &something_around_the_top_of_the_stack as *const int;
    let my_stack_top = addr as uint;

    // FIXME #11359 we just assume that this thread has a stack of a
    // certain size, and estimate that there's at most 20KB of stack
    // frames above our current position.
    let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;

    let failed = unsafe {
        // First, make sure we don't trigger any __morestack overflow checks,
        // and next set up our stack to have a guard page and run through our
        // own fault handlers if we hit it.
        sys_common::stack::record_os_managed_stack_bounds(my_stack_bottom,
                                                          my_stack_top);
        sys::thread::guard::init();
        sys::stack_overflow::init();

        // Next, set up the current Thread with the guard information we just
        // created. Note that this isn't necessary in general for new threads,
        // but we just do this to name the main thread and to give it correct
        // info about the stack bounds.
        let thread: Thread = NewThread::new(Some("<main>".into_string()));
        thread_info::set((my_stack_bottom, my_stack_top),
                         sys::thread::guard::main(),
                         thread);

        // By default, some platforms will send a *signal* when a EPIPE error
        // would otherwise be delivered. This runtime doesn't install a SIGPIPE
        // handler, causing it to kill the program, which isn't exactly what we
        // want!
        //
        // Hence, we set SIGPIPE to ignore when the program starts up in order
        // to prevent this problem.
        #[cfg(windows)] fn ignore_sigpipe() {}
        #[cfg(unix)] fn ignore_sigpipe() {
            use libc;
            use libc::funcs::posix01::signal::signal;
            unsafe {
                assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1);
            }
        }
        ignore_sigpipe();

        // Store our args if necessary in a squirreled away location
        args::init(argc, argv);

        // And finally, let's run some code!
        let res = unwind::try(|| {
            let main: fn() = mem::transmute(main);
            main();
        });
        cleanup();
        res.is_err()
    };

    // If the exit code wasn't set, then the try block must have panicked.
    if failed {
        rt::DEFAULT_ERROR_CODE
    } else {
        os::get_exit_status()
    }
}

/// Enqueues a procedure to run when the runtime is cleaned up
///
/// The procedure passed to this function will be executed as part of the
/// runtime cleanup phase. For normal rust programs, this means that it will run
/// after all other tasks have exited.
///
/// The procedure is *not* executed with a local `Task` available to it, so
/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
/// This is meant for "bare bones" usage to clean up runtime details, this is
/// not meant as a general-purpose "let's clean everything up" function.
///
/// It is forbidden for procedures to register more `at_exit` handlers when they
/// are running, and doing so will lead to a process abort.
pub fn at_exit<F:FnOnce()+Send>(f: F) {
    at_exit_imp::push(Thunk::new(f));
}

/// One-time runtime cleanup.
///
/// This function is unsafe because it performs no checks to ensure that the
/// runtime has completely ceased running. It is the responsibility of the
/// caller to ensure that the runtime is entirely shut down and nothing will be
/// poking around at the internal components.
///
/// Invoking cleanup while portions of the runtime are still in use may cause
/// undefined behavior.
pub unsafe fn cleanup() {
    args::cleanup();
    sys::stack_overflow::cleanup();
    // FIXME: (#20012): the resources being cleaned up by at_exit
    // currently are not prepared for cleanup to happen asynchronously
    // with detached threads using the resources; for now, we leak.
    // at_exit_imp::cleanup();
}
<|endoftext|>


<commit_before><commit_msg>Add 'send_msg' example command<commit_after>extern crate erl_dist;
extern crate fibers;
extern crate futures;
extern crate handy_async;
extern crate clap;
extern crate eetf;

use clap::{App, Arg};
use fibers::Executor;
use futures::Future;
use handy_async::io::WriteInto;
use handy_async::pattern::Endian;

fn main() {
    let matches = App::new("handshake")
        .arg(Arg::with_name("EPMD_HOST").short("h").takes_value(true).default_value("127.0.0.1"))
        .arg(Arg::with_name("EPMD_PORT").short("p").takes_value(true).default_value("4369"))
        .arg(Arg::with_name("NODE_NAME").short("n").takes_value(true).default_value("foo"))
        .arg(Arg::with_name("COOKIE")
            .short("c")
            .takes_value(true)
            .default_value("WPKYDIOSJIMJUURLRUHV"))
        .arg(Arg::with_name("LOCAL_NODE")
            .short("l")
            .takes_value(true)
            .default_value("bar@127.0.0.1"))
        .arg(Arg::with_name("DESTINATION")
            .short("d")
            .takes_value(true)
            .default_value("foo"))
        .get_matches();
    let node_name = matches.value_of("NODE_NAME").unwrap();
    let local_node = matches.value_of("LOCAL_NODE").unwrap().to_string();
    let cookie = matches.value_of("COOKIE").unwrap().to_string();
    let epmd_host = matches.value_of("EPMD_HOST").unwrap();
    let epmd_port = matches.value_of("EPMD_PORT").unwrap();
    let epmd_addr = format!("{}:{}", epmd_host, epmd_port).parse().expect("Invalid epmd address");
    let dest_proc = matches.value_of("DESTINATION").unwrap().to_string();

    let client = erl_dist::epmd::Client::new(&epmd_addr);
    let mut executor = fibers::InPlaceExecutor::new().unwrap();

    let info = {
        let monitor = executor.spawn_monitor(client.port_please(&node_name));
        executor.run_fiber(monitor)
            .unwrap()
            .expect("'port_please' request failed")
            .expect("Unknown node")
    };

    let node_name = local_node.to_string();
    let monitor =
        executor.spawn_monitor(erl_dist::handshake::Handshake::connect(local_node.to_string(),
                                                                       epmd_addr.ip(),
                                                                       info,
                                                                       cookie)
            .and_then(move |socket| {
                let ty = 112u8;
                let ctrl = eetf::Tuple {
                    elements: vec![From::from(eetf::FixInteger { value: 6 }),
                                   From::from(eetf::Pid {
                                       node: eetf::Atom { name: node_name },
                                       id: 0,
                                       serial: 0,
                                       creation: 0,
                                   }),
                                   From::from(eetf::Atom { name: "nil".to_string() }),
                                   From::from(eetf::Atom { name: dest_proc })],
                };
                let msg = eetf::Atom { name: "send_test".to_string() };
                let mut buf = vec![ty];
                eetf::Term::from(ctrl).encode(&mut buf).unwrap();
                eetf::Term::from(msg).encode(&mut buf).unwrap();
                println!("SEND: {:?}", buf);
                ((buf.len() as u32).be(), buf).write_into(socket).then(|r| {
                    println!("DONE: {:?}", r);
                    Ok(())
                })
            }));
    let _ = executor.run_fiber(monitor).unwrap().expect("Handshake failed");
}
<|endoftext|>


<commit_before><commit_msg>Problem 60 (partially)<commit_after>enum BinaryTree<T> {
    Node(T, ~BinaryTree<T>, ~BinaryTree<T>),
    Empty
}

fn min_nodes(h: uint) -> uint {
    fn aux(h: uint, (acc1, acc0): (uint, uint)) -> uint {
        match h {
            0 => acc0,
            1 => acc1,
            _ => aux(h-1, (acc1 + acc0 + 1, acc1))
        }
    }
    aux(h, (1, 0))
}

fn max_height(n: uint) -> uint {
    std::iter::count(0u, 1).skip_while(|&i| min_nodes(i) <= n).next().unwrap() - 1
}

fn hbal_tree_nodes<T>(n: uint) -> ~[BinaryTree<T>] {
    unimplemented!()
}

fn main() {
    assert_eq!(min_nodes(42), 701408732);
    assert_eq!(max_height(701408732), 42);
    assert_eq!(max_height(701408731), 41);
    assert_eq!(max_height(1<<63), 90);
}

<|endoftext|>


<commit_before>#[legacy_modes];
#[legacy_exports];

#[allow(ctypes)];
#[allow(heap_memory)];
#[allow(implicit_copies)];
#[allow(managed_heap_memory)];
#[allow(non_camel_case_types)];
#[allow(non_implicitly_copyable_typarams)];
#[allow(owned_heap_memory)];
#[allow(path_statement)];
#[allow(structural_records)];
#[allow(unrecognized_lint)];
#[allow(unused_imports)];
#[allow(vecs_implicitly_copyable)];
#[allow(while_true)];

extern mod std;

fn print<T>(+result: T) {
    io::println(fmt!("%?", result));
}
<commit_msg>rusti: Remove legacy modes and exports<commit_after>#[allow(ctypes)];
#[allow(heap_memory)];
#[allow(implicit_copies)];
#[allow(managed_heap_memory)];
#[allow(non_camel_case_types)];
#[allow(non_implicitly_copyable_typarams)];
#[allow(owned_heap_memory)];
#[allow(path_statement)];
#[allow(structural_records)];
#[allow(unrecognized_lint)];
#[allow(unused_imports)];
#[allow(vecs_implicitly_copyable)];
#[allow(while_true)];

extern mod std;

fn print<T>(+result: T) {
    io::println(fmt!("%?", result));
}
<|endoftext|>


<commit_before><commit_msg>Fix wallet serialization to not use "" as a key anywhere<commit_after><|endoftext|>


<commit_before><commit_msg>EEWBuffer: Add tests<commit_after>#![cfg(test)]

extern crate chrono;
extern crate tina;

use chrono::*;
use tina::*;

fn make_dummy_eew(eew_id: &str, number: u32) -> EEW
{
	EEW { source: Source::Tokyo, kind: Kind::Cancel, issued_at: UTC.timestamp(12345, 0),
		occurred_at: UTC.timestamp(12345, 0), id: eew_id.to_string(), status: Status::Normal,
		number: number, detail: EEWDetail::Cancel
	}
}

#[test]
fn it_should_hold_related_eews_within_the_same_block()
{
	let eew1 = make_dummy_eew("A", 1);
	let eew2 = make_dummy_eew("A", 2);
	let eew3 = make_dummy_eew("A", 3);
	let eew4 = make_dummy_eew("B", 1);

	let mut buf = EEWBuffer::with_capacity(4);
	let es1 = [eew1.clone(), eew2.clone(), eew3.clone()];
	let es2 = [eew4.clone()];

	buf.append(eew1);
	buf.append(eew2);
	assert!(buf.append(eew3) == &es1);
	assert!(buf.append(eew4) == &es2);
}

#[test]
fn it_should_not_save_old_eew()
{
	let eew1 = make_dummy_eew("A", 1);
	let eew2 = make_dummy_eew("A", 2);
	let eew3 = make_dummy_eew("A", 3);
	let eew4 = make_dummy_eew("A", 4);

	let mut buf = EEWBuffer::with_capacity(4);
	let es1 = [eew1.clone(), eew4.clone()];

	buf.append(eew1);
	buf.append(eew4);
	buf.append(eew2);
	assert!(buf.append(eew3) == &es1);
}

#[test]
fn it_should_erase_old_blocks_with_fifo_manner()
{
	let eewa1 = make_dummy_eew("A", 1);
	let eewa2 = make_dummy_eew("A", 2);
	let eewb = make_dummy_eew("B", 1);
	let eewc = make_dummy_eew("C", 1);
	let eewd1 = make_dummy_eew("D", 1);
	let eewd2 = make_dummy_eew("D", 2);

	let mut buf = EEWBuffer::with_capacity(2);
	let esa = [eewa2.clone()];
	let esd = [eewd1.clone(), eewd2.clone()];

	buf.append(eewa1);
	buf.append(eewb);
	buf.append(eewc);
	buf.append(eewd1);

	assert!(buf.append(eewa2) == &esa);
	assert!(buf.append(eewd2) == &esd);
}
<|endoftext|>


<commit_before>#![cfg(target_os = "macos")]

use CreationError;
use CreationError::OsError;
use ContextError;
use GlAttributes;
use GlContext;
use PixelFormat;
use PixelFormatRequirements;
use Robustness;
use WindowAttributes;
use os::macos::ActivationPolicy;

use objc::runtime::{BOOL, NO};

use cgl::{CGLEnable, kCGLCECrashOnRemovedFunctions};

use cocoa::base::{id, nil};
use cocoa::foundation::NSAutoreleasePool;
use cocoa::appkit::{self, NSOpenGLContext, NSOpenGLPixelFormat};

use core_foundation::base::TCFType;
use core_foundation::string::CFString;
use core_foundation::bundle::{CFBundleGetBundleWithIdentifier, CFBundleGetFunctionPointerForName};

use std::str::FromStr;
use std::ops::Deref;

use libc;

use winit;
use winit::os::macos::WindowExt;
pub use winit::{MonitorId, NativeMonitorId, get_available_monitors, get_primary_monitor};
pub use self::headless::HeadlessContext;
pub use self::headless::PlatformSpecificHeadlessBuilderAttributes;

mod headless;
mod helpers;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes {
    pub activation_policy: ActivationPolicy,
}

pub struct Window {
    context: IdRef,
    pixel_format: PixelFormat,
    winit_window: winit::Window,
}

pub struct WaitEventsIterator<'a> {
    window: &'a Window,
    winit_iterator: winit::WaitEventsIterator<'a>,
}

impl<'a> Iterator for WaitEventsIterator<'a> {
    type Item = winit::Event;

    fn next(&mut self) -> Option<winit::Event> {
        let event = self.winit_iterator.next();
        match event {
            Some(winit::Event::Resized(_, _)) => unsafe { self.window.context.update() },
            _ => {},
        }
        event
    }
}

pub struct PollEventsIterator<'a> {
    window: &'a Window,
    winit_iterator: winit::PollEventsIterator<'a>,
}

impl<'a> Iterator for PollEventsIterator<'a> {
    type Item = winit::Event;

    fn next(&mut self) -> Option<winit::Event> {
        let event = self.winit_iterator.next();
        match event {
            Some(winit::Event::Resized(_, _)) => unsafe { self.window.context.update() },
            _ => {},
        }
        event
    }
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

impl Window {
    pub fn new(win_attribs: &WindowAttributes,
               pf_reqs: &PixelFormatRequirements,
               opengl: &GlAttributes<&Window>,
               _pl_attribs: &PlatformSpecificWindowBuilderAttributes,
               winit_builder: winit::WindowBuilder)
               -> Result<Window, CreationError> {
        if opengl.sharing.is_some() {
            unimplemented!()
        }

        match opengl.robustness {
            Robustness::RobustNoResetNotification |
            Robustness::RobustLoseContextOnReset => {
                return Err(CreationError::RobustnessNotSupported);
            }
            _ => (),
        }

        let winit_window = winit_builder.build().unwrap();
        let view = winit_window.get_nsview() as id;
        let (context, pf) = match Window::create_context(view, pf_reqs, opengl) {
            Ok((context, pf)) => (context, pf),
            Err(e) => {
                return Err(OsError(format!("Couldn't create OpenGL context: {}", e)));
            }
        };

        let window = Window {
            context: context,
            pixel_format: pf,
            winit_window: winit_window,
        };

        Ok(window)
    }

    fn create_context(view: id,
                      pf_reqs: &PixelFormatRequirements,
                      opengl: &GlAttributes<&Window>)
                      -> Result<(IdRef, PixelFormat), CreationError> {
        let attributes = try!(helpers::build_nsattributes(pf_reqs, opengl));
        unsafe {
            let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil)
                .initWithAttributes_(&attributes));

            if let Some(pixelformat) = pixelformat.non_nil() {

                // TODO: Add context sharing
                let context = IdRef::new(NSOpenGLContext::alloc(nil)
                    .initWithFormat_shareContext_(*pixelformat, nil));

                if let Some(cxt) = context.non_nil() {
                    let pf = {
                        let get_attr = |attrib: appkit::NSOpenGLPixelFormatAttribute| -> i32 {
                            let mut value = 0;

                            NSOpenGLPixelFormat::getValues_forAttribute_forVirtualScreen_(
                                *pixelformat,
                                &mut value,
                                attrib,
                                NSOpenGLContext::currentVirtualScreen(*cxt));

                            value
                        };

                        PixelFormat {
                            hardware_accelerated: get_attr(appkit::NSOpenGLPFAAccelerated) != 0,
                            color_bits: (get_attr(appkit::NSOpenGLPFAColorSize) - get_attr(appkit::NSOpenGLPFAAlphaSize)) as u8,
                            alpha_bits: get_attr(appkit::NSOpenGLPFAAlphaSize) as u8,
                            depth_bits: get_attr(appkit::NSOpenGLPFADepthSize) as u8,
                            stencil_bits: get_attr(appkit::NSOpenGLPFAStencilSize) as u8,
                            stereoscopy: get_attr(appkit::NSOpenGLPFAStereo) != 0,
                            double_buffer: get_attr(appkit::NSOpenGLPFADoubleBuffer) != 0,
                            multisampling: if get_attr(appkit::NSOpenGLPFAMultisample) > 0 {
                                Some(get_attr(appkit::NSOpenGLPFASamples) as u16)
                            } else {
                                None
                            },
                            srgb: true,
                        }
                    };

                    cxt.setView_(view);
                    let value = if opengl.vsync { 1 } else { 0 };
                    cxt.setValues_forParameter_(&value, appkit::NSOpenGLContextParameter::NSOpenGLCPSwapInterval);

                    CGLEnable(cxt.CGLContextObj() as *mut _, kCGLCECrashOnRemovedFunctions);

                    Ok((cxt, pf))
                } else {
                    Err(CreationError::NotSupported)
                }
            } else {
                Err(CreationError::NoAvailablePixelFormat)
            }
        }
    }

    pub fn set_title(&self, title: &str) {
        self.winit_window.set_title(title)
    }

    #[inline]
    pub fn as_winit_window(&self) -> &winit::Window {
        &self.winit_window
    }

    #[inline]
    pub fn as_winit_window_mut(&mut self) -> &mut winit::Window {
        &mut self.winit_window
    }

    pub fn show(&self) {
        self.winit_window.show()
    }

    pub fn hide(&self) {
        self.winit_window.hide()
    }

    pub fn get_position(&self) -> Option<(i32, i32)> {
        self.winit_window.get_position()
    }

    pub fn set_position(&self, x: i32, y: i32) {
        self.winit_window.set_position(x, y)
    }

    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size()
    }

    pub fn get_inner_size_points(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size()
    }

    pub fn get_inner_size_pixels(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size().map(|(x, y)| {
            let hidpi = self.hidpi_factor();
            ((x as f32 * hidpi) as u32, (y as f32 * hidpi) as u32)
        })
    }

    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.winit_window.get_outer_size()
    }

    pub fn set_inner_size(&self, x: u32, y: u32) {
        self.winit_window.set_inner_size(x, y)
    }

    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator {
            window: self,
            winit_iterator: self.winit_window.poll_events()
        }
    }

    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator {
            window: self,
            winit_iterator: self.winit_window.wait_events()
        }
    }

    pub unsafe fn platform_display(&self) -> *mut libc::c_void {
        self.winit_window.platform_display()
    }

    pub unsafe fn platform_window(&self) -> *mut libc::c_void {
        self.winit_window.platform_window()
    }

    pub fn create_window_proxy(&self) -> winit::WindowProxy {
        self.winit_window.create_window_proxy()
    }

    pub fn set_window_resize_callback(&mut self, callback: Option<fn(u32, u32)>) {
        self.winit_window.set_window_resize_callback(callback);
    }

    pub fn set_cursor(&self, cursor: winit::MouseCursor) {
        self.winit_window.set_cursor(cursor);
    }

    pub fn hidpi_factor(&self) -> f32 {
        self.winit_window.hidpi_factor()
    }

    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        self.winit_window.set_cursor_position(x, y)
    }

    pub fn set_cursor_state(&self, state: winit::CursorState) -> Result<(), String> {
        self.winit_window.set_cursor_state(state)
    }
}

impl GlContext for Window {
    #[inline]
    unsafe fn make_current(&self) -> Result<(), ContextError> {
        let _: () = msg_send![*self.context, update];
        self.context.makeCurrentContext();
        Ok(())
    }

    #[inline]
    fn is_current(&self) -> bool {
        unsafe {
            let current = NSOpenGLContext::currentContext(nil);
            if current != nil {
                let is_equal: BOOL = msg_send![current, isEqual:*self.context];
                is_equal != NO
            } else {
                false
            }
        }
    }

    fn get_proc_address(&self, addr: &str) -> *const () {
        let symbol_name: CFString = FromStr::from_str(addr).unwrap();
        let framework_name: CFString = FromStr::from_str("com.apple.opengl").unwrap();
        let framework =
            unsafe { CFBundleGetBundleWithIdentifier(framework_name.as_concrete_TypeRef()) };
        let symbol = unsafe {
            CFBundleGetFunctionPointerForName(framework, symbol_name.as_concrete_TypeRef())
        };
        symbol as *const _
    }

    #[inline]
    fn swap_buffers(&self) -> Result<(), ContextError> {
        unsafe {
            let pool = NSAutoreleasePool::new(nil);
            self.context.flushBuffer();
            let _: () = msg_send![pool, release];
        }
        Ok(())
    }

    #[inline]
    fn get_api(&self) -> ::Api {
        ::Api::OpenGl
    }

    #[inline]
    fn get_pixel_format(&self) -> PixelFormat {
        self.pixel_format.clone()
    }
}

struct IdRef(id);

impl IdRef {
    fn new(i: id) -> IdRef {
        IdRef(i)
    }

    #[allow(dead_code)]
    fn retain(i: id) -> IdRef {
        if i != nil {
            let _: id = unsafe { msg_send![i, retain] };
        }
        IdRef(i)
    }

    fn non_nil(self) -> Option<IdRef> {
        if self.0 == nil { None } else { Some(self) }
    }
}

impl Drop for IdRef {
    fn drop(&mut self) {
        if self.0 != nil {
            let _: () = unsafe { msg_send![self.0, release] };
        }
    }
}

impl Deref for IdRef {
    type Target = id;
    fn deref<'a>(&'a self) -> &'a id {
        &self.0
    }
}

impl Clone for IdRef {
    fn clone(&self) -> IdRef {
        if self.0 != nil {
            let _: id = unsafe { msg_send![self.0, retain] };
        }
        IdRef(self.0)
    }
}
<commit_msg>Fix window transparency on macOS<commit_after>#![cfg(target_os = "macos")]

use CreationError;
use CreationError::OsError;
use ContextError;
use GlAttributes;
use GlContext;
use PixelFormat;
use PixelFormatRequirements;
use Robustness;
use WindowAttributes;
use os::macos::ActivationPolicy;

use objc::runtime::{BOOL, NO};

use cgl::{CGLEnable, kCGLCECrashOnRemovedFunctions, CGLSetParameter, kCGLCPSurfaceOpacity};

use cocoa::base::{id, nil};
use cocoa::foundation::NSAutoreleasePool;
use cocoa::appkit::{self, NSOpenGLContext, NSOpenGLPixelFormat};

use core_foundation::base::TCFType;
use core_foundation::string::CFString;
use core_foundation::bundle::{CFBundleGetBundleWithIdentifier, CFBundleGetFunctionPointerForName};

use std::str::FromStr;
use std::ops::Deref;

use libc;

use winit;
use winit::os::macos::WindowExt;
pub use winit::{MonitorId, NativeMonitorId, get_available_monitors, get_primary_monitor};
pub use self::headless::HeadlessContext;
pub use self::headless::PlatformSpecificHeadlessBuilderAttributes;

mod headless;
mod helpers;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes {
    pub activation_policy: ActivationPolicy,
}

pub struct Window {
    context: IdRef,
    pixel_format: PixelFormat,
    winit_window: winit::Window,
}

pub struct WaitEventsIterator<'a> {
    window: &'a Window,
    winit_iterator: winit::WaitEventsIterator<'a>,
}

impl<'a> Iterator for WaitEventsIterator<'a> {
    type Item = winit::Event;

    fn next(&mut self) -> Option<winit::Event> {
        let event = self.winit_iterator.next();
        match event {
            Some(winit::Event::Resized(_, _)) => unsafe { self.window.context.update() },
            _ => {},
        }
        event
    }
}

pub struct PollEventsIterator<'a> {
    window: &'a Window,
    winit_iterator: winit::PollEventsIterator<'a>,
}

impl<'a> Iterator for PollEventsIterator<'a> {
    type Item = winit::Event;

    fn next(&mut self) -> Option<winit::Event> {
        let event = self.winit_iterator.next();
        match event {
            Some(winit::Event::Resized(_, _)) => unsafe { self.window.context.update() },
            _ => {},
        }
        event
    }
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

impl Window {
    pub fn new(win_attribs: &WindowAttributes,
               pf_reqs: &PixelFormatRequirements,
               opengl: &GlAttributes<&Window>,
               _pl_attribs: &PlatformSpecificWindowBuilderAttributes,
               winit_builder: winit::WindowBuilder)
               -> Result<Window, CreationError> {
        if opengl.sharing.is_some() {
            unimplemented!()
        }

        match opengl.robustness {
            Robustness::RobustNoResetNotification |
            Robustness::RobustLoseContextOnReset => {
                return Err(CreationError::RobustnessNotSupported);
            }
            _ => (),
        }

        let winit_attribs = winit_builder.window.clone();

        let winit_window = winit_builder.build().unwrap();
        let view = winit_window.get_nsview() as id;
        let (context, pf) = match Window::create_context(&winit_attribs, view, pf_reqs, opengl) {
            Ok((context, pf)) => (context, pf),
            Err(e) => {
                return Err(OsError(format!("Couldn't create OpenGL context: {}", e)));
            }
        };

        let window = Window {
            context: context,
            pixel_format: pf,
            winit_window: winit_window,
        };

        Ok(window)
    }

    fn create_context(winit_attribs: &winit::WindowAttributes,
                      view: id,
                      pf_reqs: &PixelFormatRequirements,
                      opengl: &GlAttributes<&Window>)
                      -> Result<(IdRef, PixelFormat), CreationError> {
        let attributes = try!(helpers::build_nsattributes(pf_reqs, opengl));
        unsafe {
            let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil)
                .initWithAttributes_(&attributes));

            if let Some(pixelformat) = pixelformat.non_nil() {

                // TODO: Add context sharing
                let context = IdRef::new(NSOpenGLContext::alloc(nil)
                    .initWithFormat_shareContext_(*pixelformat, nil));

                if let Some(cxt) = context.non_nil() {
                    let pf = {
                        let get_attr = |attrib: appkit::NSOpenGLPixelFormatAttribute| -> i32 {
                            let mut value = 0;

                            NSOpenGLPixelFormat::getValues_forAttribute_forVirtualScreen_(
                                *pixelformat,
                                &mut value,
                                attrib,
                                NSOpenGLContext::currentVirtualScreen(*cxt));

                            value
                        };

                        PixelFormat {
                            hardware_accelerated: get_attr(appkit::NSOpenGLPFAAccelerated) != 0,
                            color_bits: (get_attr(appkit::NSOpenGLPFAColorSize) - get_attr(appkit::NSOpenGLPFAAlphaSize)) as u8,
                            alpha_bits: get_attr(appkit::NSOpenGLPFAAlphaSize) as u8,
                            depth_bits: get_attr(appkit::NSOpenGLPFADepthSize) as u8,
                            stencil_bits: get_attr(appkit::NSOpenGLPFAStencilSize) as u8,
                            stereoscopy: get_attr(appkit::NSOpenGLPFAStereo) != 0,
                            double_buffer: get_attr(appkit::NSOpenGLPFADoubleBuffer) != 0,
                            multisampling: if get_attr(appkit::NSOpenGLPFAMultisample) > 0 {
                                Some(get_attr(appkit::NSOpenGLPFASamples) as u16)
                            } else {
                                None
                            },
                            srgb: true,
                        }
                    };

                    cxt.setView_(view);
                    let value = if opengl.vsync { 1 } else { 0 };
                    cxt.setValues_forParameter_(&value, appkit::NSOpenGLContextParameter::NSOpenGLCPSwapInterval);

                    if winit_attribs.transparent {
                        let mut opacity = 0;
                        CGLSetParameter(cxt.CGLContextObj() as *mut _, kCGLCPSurfaceOpacity, &mut opacity);
                    }

                    CGLEnable(cxt.CGLContextObj() as *mut _, kCGLCECrashOnRemovedFunctions);

                    Ok((cxt, pf))
                } else {
                    Err(CreationError::NotSupported)
                }
            } else {
                Err(CreationError::NoAvailablePixelFormat)
            }
        }
    }

    pub fn set_title(&self, title: &str) {
        self.winit_window.set_title(title)
    }

    #[inline]
    pub fn as_winit_window(&self) -> &winit::Window {
        &self.winit_window
    }

    #[inline]
    pub fn as_winit_window_mut(&mut self) -> &mut winit::Window {
        &mut self.winit_window
    }

    pub fn show(&self) {
        self.winit_window.show()
    }

    pub fn hide(&self) {
        self.winit_window.hide()
    }

    pub fn get_position(&self) -> Option<(i32, i32)> {
        self.winit_window.get_position()
    }

    pub fn set_position(&self, x: i32, y: i32) {
        self.winit_window.set_position(x, y)
    }

    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size()
    }

    pub fn get_inner_size_points(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size()
    }

    pub fn get_inner_size_pixels(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size().map(|(x, y)| {
            let hidpi = self.hidpi_factor();
            ((x as f32 * hidpi) as u32, (y as f32 * hidpi) as u32)
        })
    }

    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.winit_window.get_outer_size()
    }

    pub fn set_inner_size(&self, x: u32, y: u32) {
        self.winit_window.set_inner_size(x, y)
    }

    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator {
            window: self,
            winit_iterator: self.winit_window.poll_events()
        }
    }

    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator {
            window: self,
            winit_iterator: self.winit_window.wait_events()
        }
    }

    pub unsafe fn platform_display(&self) -> *mut libc::c_void {
        self.winit_window.platform_display()
    }

    pub unsafe fn platform_window(&self) -> *mut libc::c_void {
        self.winit_window.platform_window()
    }

    pub fn create_window_proxy(&self) -> winit::WindowProxy {
        self.winit_window.create_window_proxy()
    }

    pub fn set_window_resize_callback(&mut self, callback: Option<fn(u32, u32)>) {
        self.winit_window.set_window_resize_callback(callback);
    }

    pub fn set_cursor(&self, cursor: winit::MouseCursor) {
        self.winit_window.set_cursor(cursor);
    }

    pub fn hidpi_factor(&self) -> f32 {
        self.winit_window.hidpi_factor()
    }

    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        self.winit_window.set_cursor_position(x, y)
    }

    pub fn set_cursor_state(&self, state: winit::CursorState) -> Result<(), String> {
        self.winit_window.set_cursor_state(state)
    }
}

impl GlContext for Window {
    #[inline]
    unsafe fn make_current(&self) -> Result<(), ContextError> {
        let _: () = msg_send![*self.context, update];
        self.context.makeCurrentContext();
        Ok(())
    }

    #[inline]
    fn is_current(&self) -> bool {
        unsafe {
            let current = NSOpenGLContext::currentContext(nil);
            if current != nil {
                let is_equal: BOOL = msg_send![current, isEqual:*self.context];
                is_equal != NO
            } else {
                false
            }
        }
    }

    fn get_proc_address(&self, addr: &str) -> *const () {
        let symbol_name: CFString = FromStr::from_str(addr).unwrap();
        let framework_name: CFString = FromStr::from_str("com.apple.opengl").unwrap();
        let framework =
            unsafe { CFBundleGetBundleWithIdentifier(framework_name.as_concrete_TypeRef()) };
        let symbol = unsafe {
            CFBundleGetFunctionPointerForName(framework, symbol_name.as_concrete_TypeRef())
        };
        symbol as *const _
    }

    #[inline]
    fn swap_buffers(&self) -> Result<(), ContextError> {
        unsafe {
            let pool = NSAutoreleasePool::new(nil);
            self.context.flushBuffer();
            let _: () = msg_send![pool, release];
        }
        Ok(())
    }

    #[inline]
    fn get_api(&self) -> ::Api {
        ::Api::OpenGl
    }

    #[inline]
    fn get_pixel_format(&self) -> PixelFormat {
        self.pixel_format.clone()
    }
}

struct IdRef(id);

impl IdRef {
    fn new(i: id) -> IdRef {
        IdRef(i)
    }

    #[allow(dead_code)]
    fn retain(i: id) -> IdRef {
        if i != nil {
            let _: id = unsafe { msg_send![i, retain] };
        }
        IdRef(i)
    }

    fn non_nil(self) -> Option<IdRef> {
        if self.0 == nil { None } else { Some(self) }
    }
}

impl Drop for IdRef {
    fn drop(&mut self) {
        if self.0 != nil {
            let _: () = unsafe { msg_send![self.0, release] };
        }
    }
}

impl Deref for IdRef {
    type Target = id;
    fn deref<'a>(&'a self) -> &'a id {
        &self.0
    }
}

impl Clone for IdRef {
    fn clone(&self) -> IdRef {
        if self.0 != nil {
            let _: id = unsafe { msg_send![self.0, retain] };
        }
        IdRef(self.0)
    }
}
<|endoftext|>


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

// ignore-stage0
// ignore-stage1

// ignore-emscripten

#![feature(i128_type, test)]

extern crate test;
use test::black_box as b;

fn main() {
    let x: u128 = 0xFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFF;
    assert_eq!(0, !x);
    assert_eq!(0, !x);
    let y: u128 = 0xFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFE;
    assert_eq!(!1, y);
    assert_eq!(x, y | 1);
    assert_eq!(0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFE,
               y &
               0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFF);
    let z: u128 = 0xABCD_EF;
    assert_eq!(z * z, 0x734C_C2F2_A521);
    assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41);
    assert_eq!(z + z + z + z, 0x2AF3_7BC);
    let k: u128 = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
    assert_eq!(k + k, 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420);
    assert_eq!(0, k - k);
    assert_eq!(0x1234_5678_9ABC_DEFF_EDCB_A987_5A86_421, k - z);
    assert_eq!(0x1000_0000_0000_0000_0000_0000_0000_000,
               k - 0x234_5678_9ABC_DEFF_EDCB_A987_6543_210);
    assert_eq!(0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42);
    assert_eq!(0, k % 42);
    assert_eq!(15, z % 42);
    assert_eq!(0x169D_A8020_CEC18, k % 0x3ACB_FE49_FF24_AC);
    assert_eq!(0x91A2_B3C4_D5E6_F7, k >> 65);
    assert_eq!(0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65);
    assert!(k > z);
    assert!(y > k);
    assert!(y < x);
    assert_eq!(x as u64, !0);
    assert_eq!(z as u64, 0xABCD_EF);
    assert_eq!(k as u64, 0xFEDC_BA98_7654_3210);
    assert_eq!(k as i128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210);
    assert_eq!((z as f64) as u128, z);
    assert_eq!((z as f32) as u128, z);
    assert_eq!((z as f64 * 16.0) as u128, z * 16);
    assert_eq!((z as f32 * 16.0) as u128, z * 16);
    let l :u128 = 432 << 100;
    assert_eq!((l as f32) as u128, l);
    assert_eq!((l as f64) as u128, l);
    // formatting
    let j: u128 = 1 << 67;
    assert_eq!("147573952589676412928", format!("{}", j));
    assert_eq!("80000000000000000", format!("{:x}", j));
    assert_eq!("20000000000000000000000", format!("{:o}", j));
    assert_eq!("10000000000000000000000000000000000000000000000000000000000000000000",
               format!("{:b}", j));
    assert_eq!("340282366920938463463374607431768211455",
        format!("{}", u128::max_value()));
    assert_eq!("147573952589676412928", format!("{:?}", j));
    // common traits
    assert_eq!(x, b(x.clone()));
    // overflow checks
    assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521));
    assert_eq!((k).checked_mul(k), None);
    let l: u128 = b(u128::max_value() - 10);
    let o: u128 = b(17);
    assert_eq!(l.checked_add(b(11)), None);
    assert_eq!(l.checked_sub(l), Some(0));
    assert_eq!(o.checked_sub(b(18)), None);
    assert_eq!(b(1u128).checked_shl(b(127)), Some(1 << 127));
    assert_eq!(o.checked_shl(b(128)), None);
}
<commit_msg>Rollup merge of #39604 - est31:i128_tests, r=alexcrichton<commit_after>// Copyright 2016 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.

// ignore-emscripten

#![feature(i128_type, test)]

extern crate test;
use test::black_box as b;

fn main() {
    let x: u128 = 0xFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFF;
    assert_eq!(0, !x);
    assert_eq!(0, !x);
    let y: u128 = 0xFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFE;
    assert_eq!(!1, y);
    assert_eq!(x, y | 1);
    assert_eq!(0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFE,
               y &
               0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFF);
    let z: u128 = 0xABCD_EF;
    assert_eq!(z * z, 0x734C_C2F2_A521);
    assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41);
    assert_eq!(z + z + z + z, 0x2AF3_7BC);
    let k: u128 = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
    assert_eq!(k + k, 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420);
    assert_eq!(0, k - k);
    assert_eq!(0x1234_5678_9ABC_DEFF_EDCB_A987_5A86_421, k - z);
    assert_eq!(0x1000_0000_0000_0000_0000_0000_0000_000,
               k - 0x234_5678_9ABC_DEFF_EDCB_A987_6543_210);
    assert_eq!(0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42);
    assert_eq!(0, k % 42);
    assert_eq!(15, z % 42);
    assert_eq!(0x169D_A8020_CEC18, k % 0x3ACB_FE49_FF24_AC);
    assert_eq!(0x91A2_B3C4_D5E6_F7, k >> 65);
    assert_eq!(0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65);
    assert!(k > z);
    assert!(y > k);
    assert!(y < x);
    assert_eq!(x as u64, !0);
    assert_eq!(z as u64, 0xABCD_EF);
    assert_eq!(k as u64, 0xFEDC_BA98_7654_3210);
    assert_eq!(k as i128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210);
    assert_eq!((z as f64) as u128, z);
    assert_eq!((z as f32) as u128, z);
    assert_eq!((z as f64 * 16.0) as u128, z * 16);
    assert_eq!((z as f32 * 16.0) as u128, z * 16);
    let l :u128 = 432 << 100;
    assert_eq!((l as f32) as u128, l);
    assert_eq!((l as f64) as u128, l);
    // formatting
    let j: u128 = 1 << 67;
    assert_eq!("147573952589676412928", format!("{}", j));
    assert_eq!("80000000000000000", format!("{:x}", j));
    assert_eq!("20000000000000000000000", format!("{:o}", j));
    assert_eq!("10000000000000000000000000000000000000000000000000000000000000000000",
               format!("{:b}", j));
    assert_eq!("340282366920938463463374607431768211455",
        format!("{}", u128::max_value()));
    assert_eq!("147573952589676412928", format!("{:?}", j));
    // common traits
    assert_eq!(x, b(x.clone()));
    // overflow checks
    assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521));
    assert_eq!((k).checked_mul(k), None);
    let l: u128 = b(u128::max_value() - 10);
    let o: u128 = b(17);
    assert_eq!(l.checked_add(b(11)), None);
    assert_eq!(l.checked_sub(l), Some(0));
    assert_eq!(o.checked_sub(b(18)), None);
    assert_eq!(b(1u128).checked_shl(b(127)), Some(1 << 127));
    assert_eq!(o.checked_shl(b(128)), None);
}
<|endoftext|>


<commit_before>fn main() {
  // This just tests whether the vec leaks its members.
  let vec[@tup(int,int)] pvec = vec(tup(1,2),tup(3,4),tup(5,6));
}
<commit_msg>Box the args entering the vec-drop test.<commit_after>fn main() {
  // This just tests whether the vec leaks its members.
  let vec[@tup(int,int)] pvec = vec(@tup(1,2),@tup(3,4),@tup(5,6));
}
<|endoftext|>


<commit_before>#![feature(phase)]
#![feature(globs)]
#![crate_name = "cube"]

extern crate current;
extern crate shader_version;
extern crate vecmath;
extern crate event;
extern crate input;
extern crate cam;
extern crate gfx;
// extern crate glfw_window;
extern crate sdl2;
extern crate sdl2_window;
#[phase(plugin)]
extern crate gfx_macros;
extern crate native;
extern crate time;

use current::{ Set };
use std::cell::RefCell;
// use glfw_window::GlfwWindow;
use sdl2_window::Sdl2Window;
use gfx::{ Device, DeviceHelper, ToSlice };
use event::{ Events, WindowSettings };
use event::window::{ CaptureCursor };

//----------------------------------------
// Cube associated data

#[vertex_format]
struct Vertex {
    #[as_float]
    a_pos: [i8, ..3],
    #[as_float]
    a_tex_coord: [u8, ..2],
}

impl Vertex {
    fn new(pos: [i8, ..3], tc: [u8, ..2]) -> Vertex {
        Vertex {
            a_pos: pos,
            a_tex_coord: tc,
        }
    }
}

#[shader_param(CubeBatch)]
struct Params {
    u_model_view_proj: [[f32, ..4], ..4],
    t_color: gfx::shade::TextureParam,
}

static VERTEX_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120
    attribute vec3 a_pos;
    attribute vec2 a_tex_coord;
    varying vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec3 a_pos;
    in vec2 a_tex_coord;
    out vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120
    varying vec2 v_TexCoord;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture2D(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec2 v_TexCoord;
    out vec4 o_Color;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        o_Color = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
};

//----------------------------------------

// We need to run on the main thread, so ensure we are using the `native` runtime. This is
// technically not needed, since this is the default, but it's not guaranteed.
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let (win_width, win_height) = (640, 480);
    let mut window = Sdl2Window::new(
        shader_version::opengl::OpenGL_3_2,
        WindowSettings {
            title: "cube".to_string(),
            size: [win_width, win_height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    window.set_mut(CaptureCursor(true));

    let mut device = gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    });
    let frame = gfx::Frame::new(win_width as u16, win_height as u16);
    let state = gfx::DrawState::new().depth(gfx::state::LessEqual, true);

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = device.create_mesh(vertex_data.as_slice());

    let index_data: &[u8] = [
         0,  1,  2,  2,  3,  0, // top
         4,  5,  6,  6,  7,  4, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 13, 14, 14, 16, 12, // left
        16, 17, 18, 18, 19, 16, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = device
        .create_buffer_static::<u8>(index_data)
        .to_slice(gfx::TriangleList);

    let tinfo = gfx::tex::TextureInfo {
        width: 1,
        height: 1,
        depth: 1,
        levels: 1,
        kind: gfx::tex::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let img_info = tinfo.to_image_info();
    let texture = device.create_texture(tinfo).unwrap();
    device.update_texture(
            &texture,
            &img_info,
            vec![0x20u8, 0xA0u8, 0xC0u8, 0x00u8].as_slice()
        ).unwrap();

    let sampler = device.create_sampler(
        gfx::tex::SamplerInfo::new(
            gfx::tex::Bilinear,
            gfx::tex::Clamp
        )
    );

    let program = device.link_program(
            VERTEX_SRC.clone(),
            FRAGMENT_SRC.clone()
        ).unwrap();

    let mut graphics = gfx::Graphics::new(device);
    let batch: CubeBatch = graphics.make_batch(&program, &mesh, slice, &state).unwrap();

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
    };

    let model = vecmath::mat4_id();
    let projection = cam::CameraPerspective {
            fov: 90.0f32,
            near_clip: 0.1,
            far_clip: 1000.0,
            aspect_ratio: (win_width as f32) / (win_height as f32)
        }.projection();
    let mut first_person = cam::FirstPerson::new(
        [0.5f32, 0.5, 4.0],
        cam::FirstPersonSettings::keyboard_wasd()
    );

    let window = RefCell::new(window);
    for e in Events::new(&window) {
        use event::RenderEvent;

        first_person.event(&e);
        e.render(|args| {
            graphics.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                },
                gfx::COLOR | gfx::DEPTH,
                &frame
            );
            data.u_model_view_proj = cam::model_view_projection(
                    model,
                    first_person.camera(args.ext_dt).orthogonal(),
                    projection
                );
            graphics.draw(&batch, &data, &frame);
            graphics.end_frame();
        });
    }
}

<commit_msg>Correct cube face winding in gfx_cube example.<commit_after>#![feature(phase)]
#![feature(globs)]
#![crate_name = "cube"]

extern crate current;
extern crate shader_version;
extern crate vecmath;
extern crate event;
extern crate input;
extern crate cam;
extern crate gfx;
// extern crate glfw_window;
extern crate sdl2;
extern crate sdl2_window;
#[phase(plugin)]
extern crate gfx_macros;
extern crate native;
extern crate time;

use current::{ Set };
use std::cell::RefCell;
// use glfw_window::GlfwWindow;
use sdl2_window::Sdl2Window;
use gfx::{ Device, DeviceHelper, ToSlice };
use event::{ Events, WindowSettings };
use event::window::{ CaptureCursor };

//----------------------------------------
// Cube associated data

#[vertex_format]
struct Vertex {
    #[as_float]
    a_pos: [i8, ..3],
    #[as_float]
    a_tex_coord: [u8, ..2],
}

impl Vertex {
    fn new(pos: [i8, ..3], tc: [u8, ..2]) -> Vertex {
        Vertex {
            a_pos: pos,
            a_tex_coord: tc,
        }
    }
}

#[shader_param(CubeBatch)]
struct Params {
    u_model_view_proj: [[f32, ..4], ..4],
    t_color: gfx::shade::TextureParam,
}

static VERTEX_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120
    attribute vec3 a_pos;
    attribute vec2 a_tex_coord;
    varying vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec3 a_pos;
    in vec2 a_tex_coord;
    out vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120
    varying vec2 v_TexCoord;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture2D(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec2 v_TexCoord;
    out vec4 o_Color;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        o_Color = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
};

//----------------------------------------

// We need to run on the main thread, so ensure we are using the `native` runtime. This is
// technically not needed, since this is the default, but it's not guaranteed.
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let (win_width, win_height) = (640, 480);
    let mut window = Sdl2Window::new(
        shader_version::opengl::OpenGL_3_2,
        WindowSettings {
            title: "cube".to_string(),
            size: [win_width, win_height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    window.set_mut(CaptureCursor(true));

    let mut device = gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    });
    let frame = gfx::Frame::new(win_width as u16, win_height as u16);
    let state = gfx::DrawState::new().depth(gfx::state::LessEqual, true);

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = device.create_mesh(vertex_data.as_slice());

    let index_data: &[u8] = [
         0,  1,  2,  2,  3,  0, // top
         4,  6,  5,  6,  4,  7, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 14, 13, 14, 12, 16, // left
        16, 18, 17, 18, 16, 19, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = device
        .create_buffer_static::<u8>(index_data)
        .to_slice(gfx::TriangleList);

    let tinfo = gfx::tex::TextureInfo {
        width: 1,
        height: 1,
        depth: 1,
        levels: 1,
        kind: gfx::tex::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let img_info = tinfo.to_image_info();
    let texture = device.create_texture(tinfo).unwrap();
    device.update_texture(
            &texture,
            &img_info,
            vec![0x20u8, 0xA0u8, 0xC0u8, 0x00u8].as_slice()
        ).unwrap();

    let sampler = device.create_sampler(
        gfx::tex::SamplerInfo::new(
            gfx::tex::Bilinear,
            gfx::tex::Clamp
        )
    );

    let program = device.link_program(
            VERTEX_SRC.clone(),
            FRAGMENT_SRC.clone()
        ).unwrap();

    let mut graphics = gfx::Graphics::new(device);
    let batch: CubeBatch = graphics.make_batch(&program, &mesh, slice, &state).unwrap();

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
    };

    let model = vecmath::mat4_id();
    let projection = cam::CameraPerspective {
            fov: 90.0f32,
            near_clip: 0.1,
            far_clip: 1000.0,
            aspect_ratio: (win_width as f32) / (win_height as f32)
        }.projection();
    let mut first_person = cam::FirstPerson::new(
        [0.5f32, 0.5, 4.0],
        cam::FirstPersonSettings::keyboard_wasd()
    );

    let window = RefCell::new(window);
    for e in Events::new(&window) {
        use event::RenderEvent;

        first_person.event(&e);
        e.render(|args| {
            graphics.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                },
                gfx::COLOR | gfx::DEPTH,
                &frame
            );
            data.u_model_view_proj = cam::model_view_projection(
                    model,
                    first_person.camera(args.ext_dt).orthogonal(),
                    projection
                );
            graphics.draw(&batch, &data, &frame);
            graphics.end_frame();
        });
    }
}

<|endoftext|>


<commit_before>extern crate piston;
extern crate piston_window;
extern crate vecmath;
extern crate camera_controllers;
#[macro_use]
extern crate gfx;
extern crate gfx_device_gl;
extern crate glfw_window;

use std::cell::RefCell;
use std::rc::Rc;
use piston_window::*;
use piston::event::*;
use piston::window::{ AdvancedWindow, WindowSettings };
use camera_controllers::{
    FirstPersonSettings,
    FirstPerson,
    CameraPerspective,
    model_view_projection
};
use gfx::attrib::Floater;
use gfx::traits::*;
use glfw_window::{ GlfwWindow, OpenGL };

//----------------------------------------
// Cube associated data

gfx_vertex!( Vertex {
    a_pos@ a_pos: [Floater<i8>; 3],
    a_tex_coord@ a_tex_coord: [Floater<u8>; 2],
});

impl Vertex {
    fn new(pos: [i8; 3], tc: [u8; 2]) -> Vertex {
        Vertex {
            a_pos: Floater::cast3(pos),
            a_tex_coord: Floater::cast2(tc),
        }
    }
}

gfx_parameters!( Params/ParamsLink {
    u_model_view_project@ u_model_view_proj: [[f32; 4]; 4],
    t_color@ t_color: gfx::shade::TextureParam<R>,
});

//----------------------------------------

fn main() {
    let (win_width, win_height) = (640, 480);
    let window = Rc::new(RefCell::new(GlfwWindow::new(
        OpenGL::_3_2,
        WindowSettings::new("piston-example-gfx_cube", [win_width, win_height])
        .exit_on_esc(true)
        .samples(4)
    ).capture_cursor(true)));

    let events = PistonWindow::new(window, empty_app());

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = events.canvas.borrow_mut().factory.create_mesh(&vertex_data);

    let index_data: &[u8] = &[
         0,  1,  2,  2,  3,  0, // top
         4,  6,  5,  6,  4,  7, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 14, 13, 14, 12, 16, // left
        16, 18, 17, 18, 16, 19, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = events.canvas.borrow_mut().factory.create_buffer_index(index_data)
                       .to_slice(gfx::PrimitiveType::TriangleList);

    let tinfo = gfx::tex::TextureInfo {
        width: 1, height: 1, depth: 1, levels: 1,
        kind: gfx::tex::TextureKind::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let img_info = tinfo.to_image_info();
    let texture = events.canvas.borrow_mut().factory.create_texture(tinfo).unwrap();
    events.canvas.borrow_mut().factory.update_texture(
        &texture,
        &img_info,
        &[0x20u8, 0xA0, 0xC0, 0x00],
        Some(gfx::tex::TextureKind::Texture2D)
    ).unwrap();

    let sampler = events.canvas.borrow_mut().factory.create_sampler(
        gfx::tex::SamplerInfo::new(gfx::tex::FilterMethod::Bilinear,
            gfx::tex::WrapMode::Clamp));

    let program = {
        let canvas = &mut *events.canvas.borrow_mut();
        let vertex = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("cube_120.glslv")),
            glsl_150: Some(include_bytes!("cube_150.glslv")),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("cube_120.glslf")),
            glsl_150: Some(include_bytes!("cube_150.glslf")),
            .. gfx::ShaderSource::empty()
        };
        canvas.factory.link_program_source(vertex, fragment,
            &canvas.device.get_capabilities()).unwrap()
    };

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
        _r: std::marker::PhantomData,
    };

    let get_projection = |w: &PistonWindow<GlfwWindow>| {
        use piston::window::Window;

        let draw_size = w.window.borrow().draw_size();
        CameraPerspective {
            fov: 90.0, near_clip: 0.1, far_clip: 1000.0,
            aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32)
        }.projection()
    };

    let model = vecmath::mat4_id();
    let mut projection = get_projection(&events);
    let mut first_person = FirstPerson::new([0.5, 0.5, 4.0],
        FirstPersonSettings::keyboard_wasd());
    let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

    for e in events {
        first_person.event(&e);

        e.draw_3d(|canvas| {
            let args = e.render_args().unwrap();
            canvas.renderer.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                },
                gfx::COLOR | gfx::DEPTH,
                &canvas.output
            );
            data.u_model_view_proj = model_view_projection(
                model,
                first_person.camera(args.ext_dt).orthogonal(),
                projection
            );
            canvas.renderer.draw(&(&mesh, slice.clone(), &program, &data, &state),
                &canvas.output).unwrap();
        });

        if let Some(_) = e.resize_args() {
            projection = get_projection(&e);
        }
    }
}
<commit_msg>Fixed parameter name<commit_after>extern crate piston;
extern crate piston_window;
extern crate vecmath;
extern crate camera_controllers;
#[macro_use]
extern crate gfx;
extern crate gfx_device_gl;
extern crate glfw_window;

use std::cell::RefCell;
use std::rc::Rc;
use piston_window::*;
use piston::event::*;
use piston::window::{ AdvancedWindow, WindowSettings };
use camera_controllers::{
    FirstPersonSettings,
    FirstPerson,
    CameraPerspective,
    model_view_projection
};
use gfx::attrib::Floater;
use gfx::traits::*;
use glfw_window::{ GlfwWindow, OpenGL };

//----------------------------------------
// Cube associated data

gfx_vertex!( Vertex {
    a_pos@ a_pos: [Floater<i8>; 3],
    a_tex_coord@ a_tex_coord: [Floater<u8>; 2],
});

impl Vertex {
    fn new(pos: [i8; 3], tc: [u8; 2]) -> Vertex {
        Vertex {
            a_pos: Floater::cast3(pos),
            a_tex_coord: Floater::cast2(tc),
        }
    }
}

gfx_parameters!( Params/ParamsLink {
    u_model_view_proj@ u_model_view_proj: [[f32; 4]; 4],
    t_color@ t_color: gfx::shade::TextureParam<R>,
});

//----------------------------------------

fn main() {
    let (win_width, win_height) = (640, 480);
    let window = Rc::new(RefCell::new(GlfwWindow::new(
        OpenGL::_3_2,
        WindowSettings::new("piston-example-gfx_cube", [win_width, win_height])
        .exit_on_esc(true)
        .samples(4)
    ).capture_cursor(true)));

    let events = PistonWindow::new(window, empty_app());

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = events.canvas.borrow_mut().factory.create_mesh(&vertex_data);

    let index_data: &[u8] = &[
         0,  1,  2,  2,  3,  0, // top
         4,  6,  5,  6,  4,  7, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 14, 13, 14, 12, 16, // left
        16, 18, 17, 18, 16, 19, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = events.canvas.borrow_mut().factory.create_buffer_index(index_data)
                       .to_slice(gfx::PrimitiveType::TriangleList);

    let tinfo = gfx::tex::TextureInfo {
        width: 1, height: 1, depth: 1, levels: 1,
        kind: gfx::tex::TextureKind::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let img_info = tinfo.to_image_info();
    let texture = events.canvas.borrow_mut().factory.create_texture(tinfo).unwrap();
    events.canvas.borrow_mut().factory.update_texture(
        &texture,
        &img_info,
        &[0x20u8, 0xA0, 0xC0, 0x00],
        Some(gfx::tex::TextureKind::Texture2D)
    ).unwrap();

    let sampler = events.canvas.borrow_mut().factory.create_sampler(
        gfx::tex::SamplerInfo::new(gfx::tex::FilterMethod::Bilinear,
            gfx::tex::WrapMode::Clamp));

    let program = {
        let canvas = &mut *events.canvas.borrow_mut();
        let vertex = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("cube_120.glslv")),
            glsl_150: Some(include_bytes!("cube_150.glslv")),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("cube_120.glslf")),
            glsl_150: Some(include_bytes!("cube_150.glslf")),
            .. gfx::ShaderSource::empty()
        };
        canvas.factory.link_program_source(vertex, fragment,
            &canvas.device.get_capabilities()).unwrap()
    };

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
        _r: std::marker::PhantomData,
    };

    let get_projection = |w: &PistonWindow<GlfwWindow>| {
        use piston::window::Window;

        let draw_size = w.window.borrow().draw_size();
        CameraPerspective {
            fov: 90.0, near_clip: 0.1, far_clip: 1000.0,
            aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32)
        }.projection()
    };

    let model = vecmath::mat4_id();
    let mut projection = get_projection(&events);
    let mut first_person = FirstPerson::new([0.5, 0.5, 4.0],
        FirstPersonSettings::keyboard_wasd());
    let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

    for e in events {
        first_person.event(&e);

        e.draw_3d(|canvas| {
            let args = e.render_args().unwrap();
            canvas.renderer.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                },
                gfx::COLOR | gfx::DEPTH,
                &canvas.output
            );
            data.u_model_view_proj = model_view_projection(
                model,
                first_person.camera(args.ext_dt).orthogonal(),
                projection
            );
            canvas.renderer.draw(&(&mesh, slice.clone(), &program, &data, &state),
                &canvas.output).unwrap();
        });

        if let Some(_) = e.resize_args() {
            projection = get_projection(&e);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add ID reporting in imag-link<commit_after><|endoftext|>


<commit_before><commit_msg>Only borrow builtin args when needed<commit_after><|endoftext|>