<commit_before>use serde_json::builder::ObjectBuilder;
use serde_json::Value;
use std::sync::mpsc::{
    Receiver as MpscReceiver,
    Sender as MpscSender,
    TryRecvError,
};
use std::sync::{Arc, Mutex};
use std::time::{Duration as StdDuration, Instant};
use std::{env, thread};
use super::super::ClientError;
use super::{GatewayError, GatewayStatus};
use time::{self, Duration};
use websocket::client::request::Url as RequestUrl;
use websocket::client::{Receiver, Sender};
use websocket::stream::WebSocketStream;
use ::constants::{self, LARGE_THRESHOLD, OpCode};
use ::error::{Error, Result};
use ::internal::ws_impl::{ReceiverExt, SenderExt};
use ::model::event::{Event, GatewayEvent, ReadyEvent};

#[inline]
pub fn parse_ready(event: GatewayEvent,
                   tx: &MpscSender<GatewayStatus>,
                   receiver: &mut Receiver<WebSocketStream>,
                   identification: Value)
                   -> Result<(ReadyEvent, u64)> {
    match event {
        GatewayEvent::Dispatch(seq, Event::Ready(event)) => {
            Ok((event, seq))
        },
        GatewayEvent::InvalidateSession => {
            debug!("Session invalidation");

            let _ = tx.send(GatewayStatus::SendMessage(identification));

            match receiver.recv_json(GatewayEvent::decode)? {
                GatewayEvent::Dispatch(seq, Event::Ready(event)) => {
                    Ok((event, seq))
                },
                other => {
                    debug!("Unexpected event: {:?}", other);

                    Err(Error::Gateway(GatewayError::InvalidHandshake))
                },
            }
        },
        other => {
            debug!("Unexpected event: {:?}", other);

            Err(Error::Gateway(GatewayError::InvalidHandshake))
        },
    }
}

pub fn identify(token: &str, shard_info: Option<[u64; 2]>) -> Value {
    ObjectBuilder::new()
        .insert("op", OpCode::Identify.num())
        .insert_object("d", |mut object| {
            object = identify_compression(object)
                .insert("large_threshold", LARGE_THRESHOLD) // max value
                .insert_object("properties", |object| object
                    .insert("$browser", "Ergonomic and high-level Rust library")
                    .insert("$device", "serenity")
                    .insert("$os", env::consts::OS))
                .insert("token", token)
                .insert("v", constants::GATEWAY_VERSION);

            if let Some(shard_info) = shard_info {
                object = object.insert_array("shard", |a| a
                    .push(shard_info[0])
                    .push(shard_info[1]));
            }

            object
        })
        .build()
}

#[inline(always)]
pub fn identify_compression(object: ObjectBuilder) -> ObjectBuilder {
    object.insert("compression", !cfg!(feature="debug"))
}

pub fn build_gateway_url(base: &str) -> Result<RequestUrl> {
    RequestUrl::parse(&format!("{}?v={}", base, constants::GATEWAY_VERSION))
        .map_err(|_| Error::Client(ClientError::Gateway))
}

pub fn keepalive(interval: u64,
                 heartbeat_sent: Arc<Mutex<Instant>>,
                 mut sender: Sender<WebSocketStream>,
                 channel: MpscReceiver<GatewayStatus>) {
    let mut base_interval = Duration::milliseconds(interval as i64);
    let mut next_tick = time::get_time() + base_interval;

    let mut last_sequence = 0;
    let mut last_successful = false;

    'outer: loop {
        thread::sleep(StdDuration::from_millis(100));

        loop {
            match channel.try_recv() {
                Ok(GatewayStatus::Interval(interval)) => {
                    base_interval = Duration::milliseconds(interval as i64);
                },
                Ok(GatewayStatus::Sender(new_sender)) => {
                    sender = new_sender;
                },
                Ok(GatewayStatus::SendMessage(val)) => {
                    if let Err(why) = sender.send_json(&val) {
                        warn!("Error sending message: {:?}", why);
                    }
                },
                Ok(GatewayStatus::Sequence(seq)) => {
                    last_sequence = seq;
                },
                Err(TryRecvError::Empty) => break,
                Err(TryRecvError::Disconnected) => break 'outer,
            }
        }

        if time::get_time() >= next_tick {
            next_tick = next_tick + base_interval;

            let map = ObjectBuilder::new()
                .insert("d", last_sequence)
                .insert("op", OpCode::Heartbeat.num())
                .build();

            trace!("Sending heartbeat d: {}", last_sequence);

            match sender.send_json(&map) {
                Ok(_) => {
                    let now = Instant::now();

                    *heartbeat_sent.lock().unwrap() = now;
                },
                Err(why) => {
                    warn!("Error sending keepalive: {:?}", why);

                    if last_successful {
                        debug!("If next keepalive fails, closing");
                    } else {
                        break;
                    }

                    last_successful = false;
                },
            }
        }
    }

    debug!("Closing keepalive");

    match sender.shutdown_all() {
        Ok(_) => debug!("Successfully shutdown sender/receiver"),
        Err(why) => warn!("Failed to shutdown sender/receiver: {:?}", why),
    }
}
<commit_msg>Log only unexpected keepalive errors<commit_after>use serde_json::builder::ObjectBuilder;
use serde_json::Value;
use std::sync::mpsc::{
    Receiver as MpscReceiver,
    Sender as MpscSender,
    TryRecvError,
};
use std::sync::{Arc, Mutex};
use std::time::{Duration as StdDuration, Instant};
use std::{env, thread};
use super::super::ClientError;
use super::{GatewayError, GatewayStatus};
use time::{self, Duration};
use websocket::client::request::Url as RequestUrl;
use websocket::client::{Receiver, Sender};
use websocket::result::WebSocketError as WsError;
use websocket::stream::WebSocketStream;
use ::constants::{self, LARGE_THRESHOLD, OpCode};
use ::error::{Error, Result};
use ::internal::ws_impl::{ReceiverExt, SenderExt};
use ::model::event::{Event, GatewayEvent, ReadyEvent};

#[inline]
pub fn parse_ready(event: GatewayEvent,
                   tx: &MpscSender<GatewayStatus>,
                   receiver: &mut Receiver<WebSocketStream>,
                   identification: Value)
                   -> Result<(ReadyEvent, u64)> {
    match event {
        GatewayEvent::Dispatch(seq, Event::Ready(event)) => {
            Ok((event, seq))
        },
        GatewayEvent::InvalidateSession => {
            debug!("Session invalidation");

            let _ = tx.send(GatewayStatus::SendMessage(identification));

            match receiver.recv_json(GatewayEvent::decode)? {
                GatewayEvent::Dispatch(seq, Event::Ready(event)) => {
                    Ok((event, seq))
                },
                other => {
                    debug!("Unexpected event: {:?}", other);

                    Err(Error::Gateway(GatewayError::InvalidHandshake))
                },
            }
        },
        other => {
            debug!("Unexpected event: {:?}", other);

            Err(Error::Gateway(GatewayError::InvalidHandshake))
        },
    }
}

pub fn identify(token: &str, shard_info: Option<[u64; 2]>) -> Value {
    ObjectBuilder::new()
        .insert("op", OpCode::Identify.num())
        .insert_object("d", |mut object| {
            object = identify_compression(object)
                .insert("large_threshold", LARGE_THRESHOLD) // max value
                .insert_object("properties", |object| object
                    .insert("$browser", "Ergonomic and high-level Rust library")
                    .insert("$device", "serenity")
                    .insert("$os", env::consts::OS))
                .insert("token", token)
                .insert("v", constants::GATEWAY_VERSION);

            if let Some(shard_info) = shard_info {
                object = object.insert_array("shard", |a| a
                    .push(shard_info[0])
                    .push(shard_info[1]));
            }

            object
        })
        .build()
}

#[inline(always)]
pub fn identify_compression(object: ObjectBuilder) -> ObjectBuilder {
    object.insert("compression", !cfg!(feature="debug"))
}

pub fn build_gateway_url(base: &str) -> Result<RequestUrl> {
    RequestUrl::parse(&format!("{}?v={}", base, constants::GATEWAY_VERSION))
        .map_err(|_| Error::Client(ClientError::Gateway))
}

pub fn keepalive(interval: u64,
                 heartbeat_sent: Arc<Mutex<Instant>>,
                 mut sender: Sender<WebSocketStream>,
                 channel: MpscReceiver<GatewayStatus>) {
    let mut base_interval = Duration::milliseconds(interval as i64);
    let mut next_tick = time::get_time() + base_interval;

    let mut last_sequence = 0;
    let mut last_successful = false;

    'outer: loop {
        thread::sleep(StdDuration::from_millis(100));

        loop {
            match channel.try_recv() {
                Ok(GatewayStatus::Interval(interval)) => {
                    base_interval = Duration::milliseconds(interval as i64);
                },
                Ok(GatewayStatus::Sender(new_sender)) => {
                    sender = new_sender;
                },
                Ok(GatewayStatus::SendMessage(val)) => {
                    if let Err(why) = sender.send_json(&val) {
                        warn!("Error sending message: {:?}", why);
                    }
                },
                Ok(GatewayStatus::Sequence(seq)) => {
                    last_sequence = seq;
                },
                Err(TryRecvError::Empty) => break,
                Err(TryRecvError::Disconnected) => break 'outer,
            }
        }

        if time::get_time() >= next_tick {
            next_tick = next_tick + base_interval;

            let map = ObjectBuilder::new()
                .insert("d", last_sequence)
                .insert("op", OpCode::Heartbeat.num())
                .build();

            trace!("Sending heartbeat d: {}", last_sequence);

            match sender.send_json(&map) {
                Ok(_) => {
                    let now = Instant::now();

                    *heartbeat_sent.lock().unwrap() = now;
                },
                Err(why) => {
                    match why {
                        Error::WebSocket(WsError::IoError(err)) => {
                            if err.raw_os_error() != Some(32) {
                                debug!("Err w/ keepalive: {:?}", err);
                            }
                        },
                        other => warn!("Other err w/ keepalive: {:?}", other),
                    }

                    if last_successful {
                        debug!("If next keepalive fails, closing");
                    } else {
                        break;
                    }

                    last_successful = false;
                },
            }
        }
    }

    debug!("Closing keepalive");

    match sender.shutdown_all() {
        Ok(_) => debug!("Successfully shutdown sender/receiver"),
        Err(why) => {
            // This can fail if the receiver already shutdown.
            if why.raw_os_error() != Some(107) {
                warn!("Failed to shutdown sender/receiver: {:?}", why);
            }
        },
    }
}
<|endoftext|>


<commit_before>extern crate alloc;

use self::alloc::boxed::*;

use core::ops::DerefMut;

use common::event::*;
use common::queue::*;
use common::scheduler;
use common::string::*;

use super::color::*;
use super::display::*;
use super::point::*;
use super::size::*;

/// A window
pub struct Window {
    /// The position of the window
    pub point: Point,
    /// The size of the window
    pub size: Size,
    /// The title of the window
    pub title: String,
    /// The content of the window
    pub content: Display,
    /// The color of the window title
    pub title_color: Color,
    /// The color of the border
    pub border_color: Color,
    /// Is the window focused?
    pub focused: bool,
    /// Is the window minimized?
    pub minimized: bool,
    dragging: bool,
    last_mouse_event: MouseEvent,
    events: Queue<Event>,
    ptr: *mut Window,
}

impl Window {
    /// Create a new window
    pub fn new(point: Point, size: Size, title: String) -> Box<Self> {
        let mut ret = Box::new(Window {
            point: point,
            size: size,
            title: title,
            content: Display::new(size.width, size.height),
            title_color: Color::new(255, 255, 255),
            border_color: Color::alpha(64, 64, 64, 128),
            focused: false,
            minimized: false,
            dragging: false,
            last_mouse_event: MouseEvent {
                x: 0,
                y: 0,
                left_button: false,
                right_button: false,
                middle_button: false,
            },
            events: Queue::new(),
            ptr: 0 as *mut Window,
        });

        unsafe {
            ret.ptr = ret.deref_mut();

            if ret.ptr as usize > 0 {
                (*::session_ptr).add_window(ret.ptr);
            }
        }

        ret
    }

    /// Poll the window (new)
    pub fn poll(&mut self) -> Option<Event> {
        let event_option;
        unsafe {
            let reenable = scheduler::start_no_ints();
            event_option = self.events.pop();
            scheduler::end_no_ints(reenable);
        }

        return event_option;
    }

    /// Redraw the window
    pub fn redraw(&mut self) {
        self.content.flip();
        RedrawEvent { redraw: REDRAW_ALL }.to_event().trigger();
    }

    /// Draw the window using a `Display`
    pub fn draw(&mut self, display: &Display) {
        if self.focused {
            self.border_color = Color::alpha(128, 128, 128, 192);
        } else {
            self.border_color = Color::alpha(64, 64, 64, 128);
        }

        if self.minimized {
            self.title_color = Color::new(0, 0, 0);
        } else {
            self.title_color = Color::new(255, 255, 255);

            display.rect(Point::new(self.point.x - 2, self.point.y - 18),
                         Size::new(self.size.width + 4, 18),
                         self.border_color);

            let mut cursor = Point::new(self.point.x, self.point.y - 17);
            for c in self.title.chars() {
                if cursor.x + 8 <= self.point.x + self.size.width as isize {
                    display.char(cursor, c, self.title_color);
                }
                cursor.x += 8;
            }

            display.rect(Point::new(self.point.x - 2, self.point.y),
                         Size::new(2, self.size.height),
                         self.border_color);
            display.rect(Point::new(self.point.x - 2,
                                    self.point.y + self.size.height as isize),
                         Size::new(self.size.width + 4, 2),
                         self.border_color);
            display.rect(Point::new(self.point.x + self.size.width as isize,
                                    self.point.y),
                         Size::new(2, self.size.height),
                         self.border_color);

            unsafe {
                let reenable = scheduler::start_no_ints();
                display.image(self.point,
                              self.content.onscreen as *const u32,
                              Size::new(self.content.width, self.content.height));
                scheduler::end_no_ints(reenable);
            }
        }
    }

    /// Called on key press
    pub fn on_key(&mut self, key_event: KeyEvent) {
        unsafe {
            let reenable = scheduler::start_no_ints();
            self.events.push(key_event.to_event());
            scheduler::end_no_ints(reenable);
        }
    }

    /// Called on mouse movement
    pub fn on_mouse(&mut self, orig_mouse_event: MouseEvent, allow_catch: bool) -> bool {
        let mut mouse_event = orig_mouse_event;

        mouse_event.x -= self.point.x;
        mouse_event.y -= self.point.y;

        let mut caught = false;

        if allow_catch {
            if mouse_event.left_button {
                if !self.minimized && mouse_event.x >= -2 &&
                   mouse_event.x < self.size.width as isize + 4 &&
                   mouse_event.y >= -18 &&
                   mouse_event.y < self.size.height as isize + 2 {
                    caught = true;
                }

                if !self.last_mouse_event.left_button && mouse_event.x >= -2 &&
                   mouse_event.x < self.size.width as isize + 4 &&
                   mouse_event.y >= -18 && mouse_event.y < 0 {
                    self.dragging = true;
                    caught = true;
                }
            } else {
                self.dragging = false;
            }

            if mouse_event.right_button {
                if !self.minimized && mouse_event.x >= -2 &&
                   mouse_event.x < self.size.width as isize + 4 &&
                   mouse_event.y >= -18 &&
                   mouse_event.y < self.size.height as isize + 2 {
                    caught = true;
                }

                if !self.last_mouse_event.right_button && mouse_event.x >= -2 &&
                   mouse_event.x < self.size.width as isize + 4 &&
                   mouse_event.y >= -18 && mouse_event.y < 0 {
                    self.minimized = !self.minimized;
                    caught = true;
                }
            }

            if self.dragging {
                self.point.x += orig_mouse_event.x - self.last_mouse_event.x;
                self.point.y += orig_mouse_event.y - self.last_mouse_event.y;
                caught = true;
            }
        } else {
            self.dragging = false;
        }

        self.last_mouse_event = orig_mouse_event;

        if caught && !self.dragging {
            unsafe {
                let reenable = scheduler::start_no_ints();
                self.events.push(mouse_event.to_event());
                scheduler::end_no_ints(reenable);
            }
        }

        caught
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        unsafe {
            if self.ptr as usize > 0 {
                (*::session_ptr).remove_window(self.ptr);
            }
        }
    }
}
<commit_msg>Fix crash<commit_after>extern crate alloc;

use self::alloc::boxed::*;

use core::ops::DerefMut;

use common::event::*;
use common::queue::*;
use common::scheduler;
use common::string::*;

use super::color::*;
use super::display::*;
use super::point::*;
use super::size::*;

/// A window
pub struct Window {
    /// The position of the window
    pub point: Point,
    /// The size of the window
    pub size: Size,
    /// The title of the window
    pub title: String,
    /// The content of the window
    pub content: Display,
    /// The color of the window title
    pub title_color: Color,
    /// The color of the border
    pub border_color: Color,
    /// Is the window focused?
    pub focused: bool,
    /// Is the window minimized?
    pub minimized: bool,
    dragging: bool,
    last_mouse_event: MouseEvent,
    events: Queue<Event>,
    ptr: *mut Window,
}

impl Window {
    /// Create a new window
    pub fn new(point: Point, size: Size, title: String) -> Box<Self> {
        let mut ret = box Window {
            point: point,
            size: size,
            title: title,
            content: Display::new(size.width, size.height),
            title_color: Color::new(255, 255, 255),
            border_color: Color::alpha(64, 64, 64, 128),
            focused: false,
            minimized: false,
            dragging: false,
            last_mouse_event: MouseEvent {
                x: 0,
                y: 0,
                left_button: false,
                right_button: false,
                middle_button: false,
            },
            events: Queue::new(),
            ptr: 0 as *mut Window,
        };

        unsafe {
            ret.ptr = ret.deref_mut();

            if ret.ptr as usize > 0 {
                (*::session_ptr).add_window(ret.ptr);
            }
        }

        ret
    }

    /// Poll the window (new)
    pub fn poll(&mut self) -> Option<Event> {
        let event_option;
        unsafe {
            let reenable = scheduler::start_no_ints();
            event_option = self.events.pop();
            scheduler::end_no_ints(reenable);
        }

        return event_option;
    }

    /// Redraw the window
    pub fn redraw(&mut self) {
        self.content.flip();
        RedrawEvent { redraw: REDRAW_ALL }.to_event().trigger();
    }

    /// Draw the window using a `Display`
    pub fn draw(&mut self, display: &Display) {
        if self.focused {
            self.border_color = Color::alpha(128, 128, 128, 192);
        } else {
            self.border_color = Color::alpha(64, 64, 64, 128);
        }

        if self.minimized {
            self.title_color = Color::new(0, 0, 0);
        } else {
            self.title_color = Color::new(255, 255, 255);

            display.rect(Point::new(self.point.x - 2, self.point.y - 18),
                         Size::new(self.size.width + 4, 18),
                         self.border_color);

            let mut cursor = Point::new(self.point.x, self.point.y - 17);
            for c in self.title.chars() {
                if cursor.x + 8 <= self.point.x + self.size.width as isize {
                    display.char(cursor, c, self.title_color);
                }
                cursor.x += 8;
            }

            display.rect(Point::new(self.point.x - 2, self.point.y),
                         Size::new(2, self.size.height),
                         self.border_color);
            display.rect(Point::new(self.point.x - 2,
                                    self.point.y + self.size.height as isize),
                         Size::new(self.size.width + 4, 2),
                         self.border_color);
            display.rect(Point::new(self.point.x + self.size.width as isize,
                                    self.point.y),
                         Size::new(2, self.size.height),
                         self.border_color);

            unsafe {
                let reenable = scheduler::start_no_ints();
                display.image(self.point,
                              self.content.onscreen as *const u32,
                              Size::new(self.content.width, self.content.height));
                scheduler::end_no_ints(reenable);
            }
        }
    }

    /// Called on key press
    pub fn on_key(&mut self, key_event: KeyEvent) {
        unsafe {
            let reenable = scheduler::start_no_ints();
            self.events.push(key_event.to_event());
            scheduler::end_no_ints(reenable);
        }
    }

    /// Called on mouse movement
    pub fn on_mouse(&mut self, orig_mouse_event: MouseEvent, allow_catch: bool) -> bool {
        let mut mouse_event = orig_mouse_event;

        mouse_event.x -= self.point.x;
        mouse_event.y -= self.point.y;

        let mut caught = false;

        if allow_catch {
            if mouse_event.left_button {
                if !self.minimized && mouse_event.x >= -2 &&
                   mouse_event.x < self.size.width as isize + 4 &&
                   mouse_event.y >= -18 &&
                   mouse_event.y < self.size.height as isize + 2 {
                    caught = true;
                }

                if !self.last_mouse_event.left_button && mouse_event.x >= -2 &&
                   mouse_event.x < self.size.width as isize + 4 &&
                   mouse_event.y >= -18 && mouse_event.y < 0 {
                    self.dragging = true;
                    caught = true;
                }
            } else {
                self.dragging = false;
            }

            if mouse_event.right_button {
                if !self.minimized && mouse_event.x >= -2 &&
                   mouse_event.x < self.size.width as isize + 4 &&
                   mouse_event.y >= -18 &&
                   mouse_event.y < self.size.height as isize + 2 {
                    caught = true;
                }

                if !self.last_mouse_event.right_button && mouse_event.x >= -2 &&
                   mouse_event.x < self.size.width as isize + 4 &&
                   mouse_event.y >= -18 && mouse_event.y < 0 {
                    self.minimized = !self.minimized;
                    caught = true;
                }
            }

            if self.dragging {
                self.point.x += orig_mouse_event.x - self.last_mouse_event.x;
                self.point.y += orig_mouse_event.y - self.last_mouse_event.y;
                caught = true;
            }
        } else {
            self.dragging = false;
        }

        self.last_mouse_event = orig_mouse_event;

        if caught && !self.dragging {
            unsafe {
                let reenable = scheduler::start_no_ints();
                self.events.push(mouse_event.to_event());
                scheduler::end_no_ints(reenable);
            }
        }

        caught
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        unsafe {
            if self.ptr as usize > 0 {
                (*::session_ptr).remove_window(self.ptr);
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>route mob attack logic to gamestate handler<commit_after><|endoftext|>


<commit_before><commit_msg>Add title bar setting, add ability to produce any character using hex code<commit_after><|endoftext|>


<commit_before>use programs::common::*;

pub struct Application;

impl SessionItem for Application {
    fn main(&mut self, url: URL){
        let mut window = Window::new(Point::new((rand() % 400 + 50) as isize, (rand() % 300 + 50) as isize), Size::new(640, 480), "Example Game".to_string());
        let start_time = Duration::monotonic();
        let mut last_time = start_time;
        let mut running = true;
        while running {
            let current_time = Duration::monotonic();
            let run_time = current_time - start_time;
            let frame_time = current_time - last_time;
            last_time = current_time;

            loop {
                match window.poll() {
                    EventOption::Key(key_event) => {
                        if key_event.pressed && key_event.scancode == K_ESC {
                            running = false;
                            break;
                        }
                    },
                    EventOption::None => break,
                    _ => ()
                }
            }

            let content = &mut window.content;
            content.set(Color::new(255, 255, 255));

            { //Draw
                let mut y = 0;
                content.text(Point::new(0, y), &"Running Time".to_string(), Color::new(50, 50, 50));
                y += 16;
                content.text(Point::new(8, y), &String::from_num_signed(run_time.secs as isize), Color::new(50, 50, 50));
                y += 16;
                content.text(Point::new(8, y), &String::from_num(run_time.nanos as usize), Color::new(50, 50, 50));
                y += 32;

                content.text(Point::new(0, y), &"Frame Time".to_string(), Color::new(50, 50, 50));
                y += 16;
                content.text(Point::new(8, y), &String::from_num_signed(frame_time.secs as isize), Color::new(50, 50, 50));
                y += 16;
                content.text(Point::new(8, y), &String::from_num(frame_time.nanos as usize), Color::new(50, 50, 50));
                y += 32;
            }

            content.flip();

            RedrawEvent {
                redraw: REDRAW_ALL
            }.trigger();

            sys_yield();
        }
    }
}

impl Application {
    pub fn new() -> Application {
        Application
    }
}
<commit_msg>Game will load sprites, and sleep<commit_after>use programs::common::*;

use graphics::bmp::*;

pub fn sleep(duration: Duration){
    let start_time = Duration::monotonic();
    loop {
        let elapsed = Duration::monotonic() - start_time;
        if elapsed > duration {
            break;
        }else{
            sys_yield();
        }
    }
}

pub struct Sprite {
    point: Point,
    image: BMP
}

impl Sprite {
    pub fn draw(&self, content: &mut Display){
        content.image_alpha(self.point, self.image.data, self.image.size);
    }
}

pub struct Application;

impl SessionItem for Application {
    fn main(&mut self, url: URL){
        let mut window = Window::new(Point::new((rand() % 400 + 50) as isize, (rand() % 300 + 50) as isize), Size::new(640, 480), "Example Game (Loading)".to_string());

        let mut player;
        {
            let mut image = URL::from_string(&"file:///game/ninjaroofront.bmp".to_string()).open();
            let mut bytes: Vec<u8> = Vec::new();
            image.read_to_end(&mut bytes);
            player = Sprite {
                point: Point::new(200, 200),
                image: unsafe{ BMP::from_data(bytes.as_ptr() as usize) }
            };
        }

        window.title = "Example Game".to_string();

        let mut keys: Vec<u8> = Vec::new();
        let mut redraw = true;
        let mut running = true;
        while running {
            loop {
                match window.poll() {
                    EventOption::Key(key_event) => {
                        if key_event.pressed {
                            match key_event.scancode {
                                K_ESC => {
                                    running = false;
                                    break;
                                },
                                _ => ()
                            }

                            let mut found = false;
                            for key in keys.iter() {
                                if *key == key_event.scancode {
                                    found = true;
                                    break;
                                }
                            }
                            if ! found {
                                keys.push(key_event.scancode);
                            }
                        }else{
                            let mut i = 0;
                            while i < keys.len() {
                                let mut remove = false;
                                if let Option::Some(key) = keys.get(i) {
                                    if *key == key_event.scancode {
                                        remove = true;
                                    }
                                }
                                if remove {
                                    keys.remove(i);
                                }else{
                                    i += 1;
                                }
                            }
                        }
                    },
                    EventOption::None => break,
                    _ => ()
                }
            }

            for key in keys.iter() {
                match *key {
                    K_LEFT => {
                        player.point.x = max(0, player.point.x - 1);
                        redraw = true;
                    },
                    K_RIGHT => {
                        player.point.x = min(window.content.width as isize - 1, player.point.x + 1);
                        redraw = true;
                    },
                    K_UP => {
                        player.point.y = max(0, player.point.y - 1);
                        redraw = true;
                    },
                    K_DOWN => {
                        player.point.y = min(window.content.height as isize - 1, player.point.y + 1);
                        redraw = true;
                    },
                    _ => ()
                }
            }

            if redraw {
                redraw = false;

                let content = &mut window.content;
                content.set(Color::new(128, 128, 255));

                player.draw(content);

                content.flip();

                RedrawEvent {
                    redraw: REDRAW_ALL
                }.trigger();
            }

            sleep(Duration {
                secs: 0,
                nanos: 1000000000/120
            });
        }
    }
}

impl Application {
    pub fn new() -> Application {
        Application
    }
}
<|endoftext|>


<commit_before>use std::io::{IoResult, File};
use std::io::util::copy;
use http;
use http::headers::content_type::MediaType;
use time;
use mimes::get_media_type;

///A container for the response
pub struct Response<'a, 'b> {
    ///the original `http::server::ResponseWriter`
    pub origin: &'a mut http::server::ResponseWriter<'b>,
}

impl<'a, 'b> Response<'a, 'b> {

    pub fn from_internal<'c, 'd>(response: &'c mut http::server::ResponseWriter<'d>) -> Response<'c, 'd> {
        Response {
            origin: response
        }
    }

    /// Writes a response
    ///
    /// # Example
    /// ```rust
    /// response.send("hello world");
    /// ```
    pub fn send (&mut self, text: &str) {
        // TODO: This needs to be more sophisticated to return the correct headers
        // not just "some headers" :)
        Response::set_headers(self.origin);
        let _ = self.origin.write(text.as_bytes());
    }

    fn set_headers(response_writer: &mut http::server::ResponseWriter) {
        response_writer.headers.date = Some(time::now_utc());

        // we don't need to set this https://github.com/Ogeon/rustful/issues/3#issuecomment-44787613
        response_writer.headers.content_length = None;
        response_writer.headers.content_type = Some(MediaType {
            type_: String::from_str("text"),
            subtype: String::from_str("plain"),
            parameters: vec!((String::from_str("charset"), String::from_str("UTF-8")))
        });
        response_writer.headers.server = Some(String::from_str("Nickel"));
    }

    pub fn send_file(&mut self, path: &Path) -> IoResult<()> {
        let mut file = try!(File::open(path));
        self.origin.headers.content_length = None;

        self.origin.headers.content_type = path.extension_str().and_then(get_media_type);
        self.origin.headers.server = Some(String::from_str("Nickel"));
        copy(&mut file, self.origin)
    }
}

#[test]
fn matches_content_type () {
    let path = &Path::new("test.txt");
    let content_type = path.extension_str().and_then(get_media_type).unwrap();

    assert_eq!(content_type.type_.as_slice(), "text");
    assert_eq!(content_type.subtype.as_slice(), "plain");
}
<commit_msg>=BG= set default content type when not already set<commit_after>use std::io::{IoResult, File};
use std::io::util::copy;
use http;
use time;
use mimes::get_media_type;

///A container for the response
pub struct Response<'a, 'b> {
    ///the original `http::server::ResponseWriter`
    pub origin: &'a mut http::server::ResponseWriter<'b>,
}

impl<'a, 'b> Response<'a, 'b> {

    pub fn from_internal<'c, 'd>(response: &'c mut http::server::ResponseWriter<'d>) -> Response<'c, 'd> {
        Response {
            origin: response
        }
    }

    /// Writes a response
    ///
    /// # Example
    /// ```rust
    /// response.send("hello world");
    /// ```
    pub fn send (&mut self, text: &str) {
        // TODO: This needs to be more sophisticated to return the correct headers
        // not just "some headers" :)
        Response::set_headers(self.origin);
        let _ = self.origin.write(text.as_bytes());
    }

    fn set_headers(response_writer: &mut http::server::ResponseWriter) {
        response_writer.headers.date = Some(time::now_utc());

        // we don't need to set this https://github.com/Ogeon/rustful/issues/3#issuecomment-44787613
        response_writer.headers.content_length = None;
        response_writer.headers.content_type = Some(response_writer.headers.content_type
                                                        .clone()
                                                        .unwrap_or(get_media_type("txt").unwrap()));
        response_writer.headers.server = Some(String::from_str("Nickel"));
    }

    pub fn send_file(&mut self, path: &Path) -> IoResult<()> {
        let mut file = try!(File::open(path));
        self.origin.headers.content_length = None;

        self.origin.headers.content_type = path.extension_str().and_then(get_media_type);
        self.origin.headers.server = Some(String::from_str("Nickel"));
        copy(&mut file, self.origin)
    }
}

#[test]
fn matches_content_type () {
    let path = &Path::new("test.txt");
    let content_type = path.extension_str().and_then(get_media_type).unwrap();

    assert_eq!(content_type.type_.as_slice(), "text");
    assert_eq!(content_type.subtype.as_slice(), "plain");
}
<|endoftext|>


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

use borrow_check::nll::region_infer::values::ToElementIndex;
use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext};
use borrow_check::nll::type_check::Locations;
use rustc::hir::def_id::DefId;
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc::infer::InferCtxt;
use rustc::mir::{self, Location, Mir, Place, Rvalue, StatementKind, TerminatorKind};
use rustc::ty::RegionVid;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::IndexVec;
use std::fmt;
use syntax_pos::Span;

mod region_name;
mod var_name;

/// Constraints that are considered interesting can be categorized to
/// determine why they are interesting. Order of variants indicates
/// sort order of the category, thereby influencing diagnostic output.
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
enum ConstraintCategory {
    Cast,
    Assignment,
    AssignmentToUpvar,
    Return,
    CallArgument,
    Other,
    Boring,
}

impl fmt::Display for ConstraintCategory {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            ConstraintCategory::Assignment |
            ConstraintCategory::AssignmentToUpvar => write!(f, "assignment"),
            ConstraintCategory::Return => write!(f, "return"),
            ConstraintCategory::Cast => write!(f, "cast"),
            ConstraintCategory::CallArgument => write!(f, "argument"),
            _ => write!(f, "free region"),
        }
    }
}

impl<'tcx> RegionInferenceContext<'tcx> {
    /// Walks the graph of constraints (where `'a: 'b` is considered
    /// an edge `'a -> 'b`) to find all paths from `from_region` to
    /// `to_region`. The paths are accumulated into the vector
    /// `results`. The paths are stored as a series of
    /// `ConstraintIndex` values -- in other words, a list of *edges*.
    fn find_constraint_paths_between_regions(
        &self,
        from_region: RegionVid,
        target_test: impl Fn(RegionVid) -> bool,
    ) -> Vec<Vec<ConstraintIndex>> {
        let mut results = vec![];
        self.find_constraint_paths_between_regions_helper(
            from_region,
            from_region,
            &target_test,
            &mut FxHashSet::default(),
            &mut vec![],
            &mut results,
        );
        results
    }

    /// Helper for `find_constraint_paths_between_regions`.
    fn find_constraint_paths_between_regions_helper(
        &self,
        from_region: RegionVid,
        current_region: RegionVid,
        target_test: &impl Fn(RegionVid) -> bool,
        visited: &mut FxHashSet<RegionVid>,
        stack: &mut Vec<ConstraintIndex>,
        results: &mut Vec<Vec<ConstraintIndex>>,
    ) {
        // Check if we already visited this region.
        if !visited.insert(current_region) {
            return;
        }

        // Check if we reached the region we were looking for.
        if target_test(current_region) {
            if !stack.is_empty() {
                assert_eq!(self.constraints[stack[0]].sup, from_region);
                results.push(stack.clone());
            }
            return;
        }

        for constraint in self.constraint_graph.outgoing_edges(current_region) {
            assert_eq!(self.constraints[constraint].sup, current_region);
            stack.push(constraint);
            self.find_constraint_paths_between_regions_helper(
                from_region,
                self.constraints[constraint].sub,
                target_test,
                visited,
                stack,
                results,
            );
            stack.pop();
        }
    }

    /// This function will return true if a constraint is interesting and false if a constraint
    /// is not. It is useful in filtering constraint paths to only interesting points.
    fn constraint_is_interesting(&self, index: ConstraintIndex) -> bool {
        let constraint = self.constraints[index];
        debug!(
            "constraint_is_interesting: locations={:?} constraint={:?}",
            constraint.locations, constraint
        );
        if let Locations::Interesting(_) = constraint.locations {
            true
        } else {
            false
        }
    }

    /// This function classifies a constraint from a location.
    fn classify_constraint(
        &self,
        index: ConstraintIndex,
        mir: &Mir<'tcx>,
        infcx: &InferCtxt<'_, '_, 'tcx>,
    ) -> (ConstraintCategory, Span) {
        let constraint = self.constraints[index];
        debug!("classify_constraint: constraint={:?}", constraint);
        let span = constraint.locations.span(mir);
        let location = constraint.locations.from_location().unwrap_or(Location::START);

        if !self.constraint_is_interesting(index) {
            return (ConstraintCategory::Boring, span);
        }

        let data = &mir[location.block];
        debug!("classify_constraint: location={:?} data={:?}", location, data);
        let category = if location.statement_index == data.statements.len() {
            if let Some(ref terminator) = data.terminator {
                debug!("classify_constraint: terminator.kind={:?}", terminator.kind);
                match terminator.kind {
                    TerminatorKind::DropAndReplace { .. } => ConstraintCategory::Assignment,
                    TerminatorKind::Call { .. } => ConstraintCategory::CallArgument,
                    _ => ConstraintCategory::Other,
                }
            } else {
                ConstraintCategory::Other
            }
        } else {
            let statement = &data.statements[location.statement_index];
            debug!("classify_constraint: statement.kind={:?}", statement.kind);
            match statement.kind {
                StatementKind::Assign(ref place, ref rvalue) => {
                    debug!("classify_constraint: place={:?} rvalue={:?}", place, rvalue);
                    let initial_category = if *place == Place::Local(mir::RETURN_PLACE) {
                        ConstraintCategory::Return
                    } else {
                        match rvalue {
                            Rvalue::Cast(..) => ConstraintCategory::Cast,
                            Rvalue::Use(..) |
                            Rvalue::Aggregate(..) => ConstraintCategory::Assignment,
                            _ => ConstraintCategory::Other,
                        }
                    };

                    if initial_category == ConstraintCategory::Assignment
                            && place.is_upvar_field_projection(mir, &infcx.tcx).is_some() {
                        ConstraintCategory::AssignmentToUpvar
                    } else {
                        initial_category
                    }
                }
                _ => ConstraintCategory::Other,
            }
        };

        (category, span)
    }

    /// Report an error because the universal region `fr` was required to outlive
    /// `outlived_fr` but it is not known to do so. For example:
    ///
    /// ```
    /// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
    /// ```
    ///
    /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
    pub(super) fn report_error(
        &self,
        mir: &Mir<'tcx>,
        infcx: &InferCtxt<'_, '_, 'tcx>,
        mir_def_id: DefId,
        fr: RegionVid,
        outlived_fr: RegionVid,
        blame_span: Span,
    ) {
        debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);

        if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
            let tables = infcx.tcx.typeck_tables_of(mir_def_id);
            let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables));
            if let Some(_error_reported) = nice.try_report() {
                return;
            }
        }

        // Find all paths
        let constraint_paths = self.find_constraint_paths_between_regions(fr, |r| r == outlived_fr);
        debug!("report_error: constraint_paths={:#?}", constraint_paths);

        // Find the shortest such path.
        let path = constraint_paths.iter().min_by_key(|p| p.len()).unwrap();
        debug!("report_error: shortest_path={:?}", path);

        // Classify each of the constraints along the path.
        let mut categorized_path: Vec<(ConstraintCategory, Span)> = path.iter()
            .map(|&index| self.classify_constraint(index, mir, infcx))
            .collect();
        debug!("report_error: categorized_path={:?}", categorized_path);

        // Find what appears to be the most interesting path to report to the user.
        categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0));
        debug!("report_error: sorted_path={:?}", categorized_path);

        // Get a span
        let (category, span) = categorized_path.first().unwrap();

        match category {
            ConstraintCategory::AssignmentToUpvar =>
                self.report_closure_error(mir, infcx, fr, outlived_fr, span),
            _ =>
                self.report_general_error(mir, infcx, mir_def_id, fr, outlived_fr, category, span),
        }
    }

    fn report_closure_error(
        &self,
        mir: &Mir<'tcx>,
        infcx: &InferCtxt<'_, '_, 'tcx>,
        fr: RegionVid,
        outlived_fr: RegionVid,
        span: &Span,
    ) {
        let diag = &mut infcx.tcx.sess.struct_span_err(
            *span, &format!("borrowed data escapes outside of closure"),
        );

        let (outlived_fr_name, outlived_fr_span) = self.get_var_name_and_span_for_region(
            infcx.tcx, mir, outlived_fr);

        if let Some(name) = outlived_fr_name {
            diag.span_label(
                outlived_fr_span,
                format!("`{}` is declared here, outside of the closure body", name),
            );
        }

        let (fr_name, fr_span) = self.get_var_name_and_span_for_region(infcx.tcx, mir, fr);

        if let Some(name) = fr_name {
            diag.span_label(
                fr_span,
                format!("`{}` is a reference that is only valid in the closure body", name),
            );

            diag.span_label(*span, format!("`{}` escapes the closure body here", name));
        }

        diag.emit();
    }

    fn report_general_error(
        &self,
        mir: &Mir<'tcx>,
        infcx: &InferCtxt<'_, '_, 'tcx>,
        mir_def_id: DefId,
        fr: RegionVid,
        outlived_fr: RegionVid,
        category: &ConstraintCategory,
        span: &Span,
    ) {
        let diag = &mut infcx.tcx.sess.struct_span_err(
            *span, &format!("unsatisfied lifetime constraints"), // FIXME
        );

        let counter = &mut 1;
        let fr_name = self.give_region_a_name(
            infcx.tcx, mir, mir_def_id, fr, counter, diag);
        let outlived_fr_name = self.give_region_a_name(
            infcx.tcx, mir, mir_def_id, outlived_fr, counter, diag);

        diag.span_label(*span, format!(
            "{} requires that `{}` must outlive `{}`",
            category, fr_name, outlived_fr_name,
        ));

        diag.emit();
    }

    // Find some constraint `X: Y` where:
    // - `fr1: X` transitively
    // - and `Y` is live at `elem`
    crate fn find_constraint(&self, fr1: RegionVid, elem: Location) -> RegionVid {
        let index = self.blame_constraint(fr1, elem);
        self.constraints[index].sub
    }

    /// Tries to finds a good span to blame for the fact that `fr1`
    /// contains `fr2`.
    pub(super) fn blame_constraint(
        &self,
        fr1: RegionVid,
        elem: impl ToElementIndex,
    ) -> ConstraintIndex {
        // Find everything that influenced final value of `fr`.
        let influenced_fr1 = self.dependencies(fr1);

        // Try to find some outlives constraint `'X: fr2` where `'X`
        // influenced `fr1`. Blame that.
        //
        // NB, this is a pretty bad choice most of the time. In
        // particular, the connection between `'X` and `fr1` may not
        // be obvious to the user -- not to mention the naive notion
        // of dependencies, which doesn't account for the locations of
        // contraints at all. But it will do for now.
        let relevant_constraint = self.constraints
            .iter_enumerated()
            .filter_map(|(i, constraint)| {
                if !self.liveness_constraints.contains(constraint.sub, elem) {
                    None
                } else {
                    influenced_fr1[constraint.sup]
                        .map(|distance| (distance, i))
                }
            })
            .min() // constraining fr1 with fewer hops *ought* to be more obvious
            .map(|(_dist, i)| i);

        relevant_constraint.unwrap_or_else(|| {
            bug!(
                "could not find any constraint to blame for {:?}: {:?}",
                fr1,
                elem,
            );
        })
    }

    /// Finds all regions whose values `'a` may depend on in some way.
    /// For each region, returns either `None` (does not influence
    /// `'a`) or `Some(d)` which indicates that it influences `'a`
    /// with distinct `d` (minimum number of edges that must be
    /// traversed).
    ///
    /// Used during error reporting, extremely naive and inefficient.
    fn dependencies(&self, r0: RegionVid) -> IndexVec<RegionVid, Option<usize>> {
        let mut result_set = IndexVec::from_elem(None, &self.definitions);
        let mut changed = true;
        result_set[r0] = Some(0); // distance 0 from `r0`

        while changed {
            changed = false;
            for constraint in self.constraints.iter() {
                if let Some(n) = result_set[constraint.sup] {
                    let m = n + 1;
                    if result_set[constraint.sub]
                        .map(|distance| m < distance)
                        .unwrap_or(true)
                    {
                        result_set[constraint.sub] = Some(m);
                        changed = true;
                    }
                }
            }
        }

        result_set
    }
}
<commit_msg>Modified how constraint classification happens to upvars, can now handle function call case.<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use borrow_check::nll::region_infer::values::ToElementIndex;
use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext};
use borrow_check::nll::type_check::Locations;
use rustc::hir::def_id::DefId;
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc::infer::InferCtxt;
use rustc::mir::{self, Location, Mir, Place, Rvalue, StatementKind, TerminatorKind};
use rustc::ty::RegionVid;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::IndexVec;
use std::fmt;
use syntax_pos::Span;

mod region_name;
mod var_name;

/// Constraints that are considered interesting can be categorized to
/// determine why they are interesting. Order of variants indicates
/// sort order of the category, thereby influencing diagnostic output.
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
enum ConstraintCategory {
    Cast,
    Assignment,
    AssignmentToUpvar,
    Return,
    CallArgumentToUpvar,
    CallArgument,
    Other,
    Boring,
}

impl fmt::Display for ConstraintCategory {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            ConstraintCategory::Assignment |
            ConstraintCategory::AssignmentToUpvar => write!(f, "assignment"),
            ConstraintCategory::Return => write!(f, "return"),
            ConstraintCategory::Cast => write!(f, "cast"),
            ConstraintCategory::CallArgument |
            ConstraintCategory::CallArgumentToUpvar => write!(f, "argument"),
            _ => write!(f, "free region"),
        }
    }
}

impl<'tcx> RegionInferenceContext<'tcx> {
    /// Walks the graph of constraints (where `'a: 'b` is considered
    /// an edge `'a -> 'b`) to find all paths from `from_region` to
    /// `to_region`. The paths are accumulated into the vector
    /// `results`. The paths are stored as a series of
    /// `ConstraintIndex` values -- in other words, a list of *edges*.
    fn find_constraint_paths_between_regions(
        &self,
        from_region: RegionVid,
        target_test: impl Fn(RegionVid) -> bool,
    ) -> Vec<Vec<ConstraintIndex>> {
        let mut results = vec![];
        self.find_constraint_paths_between_regions_helper(
            from_region,
            from_region,
            &target_test,
            &mut FxHashSet::default(),
            &mut vec![],
            &mut results,
        );
        results
    }

    /// Helper for `find_constraint_paths_between_regions`.
    fn find_constraint_paths_between_regions_helper(
        &self,
        from_region: RegionVid,
        current_region: RegionVid,
        target_test: &impl Fn(RegionVid) -> bool,
        visited: &mut FxHashSet<RegionVid>,
        stack: &mut Vec<ConstraintIndex>,
        results: &mut Vec<Vec<ConstraintIndex>>,
    ) {
        // Check if we already visited this region.
        if !visited.insert(current_region) {
            return;
        }

        // Check if we reached the region we were looking for.
        if target_test(current_region) {
            if !stack.is_empty() {
                assert_eq!(self.constraints[stack[0]].sup, from_region);
                results.push(stack.clone());
            }
            return;
        }

        for constraint in self.constraint_graph.outgoing_edges(current_region) {
            assert_eq!(self.constraints[constraint].sup, current_region);
            stack.push(constraint);
            self.find_constraint_paths_between_regions_helper(
                from_region,
                self.constraints[constraint].sub,
                target_test,
                visited,
                stack,
                results,
            );
            stack.pop();
        }
    }

    /// This function will return true if a constraint is interesting and false if a constraint
    /// is not. It is useful in filtering constraint paths to only interesting points.
    fn constraint_is_interesting(&self, index: ConstraintIndex) -> bool {
        let constraint = self.constraints[index];
        debug!(
            "constraint_is_interesting: locations={:?} constraint={:?}",
            constraint.locations, constraint
        );
        if let Locations::Interesting(_) = constraint.locations {
            true
        } else {
            false
        }
    }

    /// This function classifies a constraint from a location.
    fn classify_constraint(
        &self,
        index: ConstraintIndex,
        mir: &Mir<'tcx>,
        _infcx: &InferCtxt<'_, '_, 'tcx>,
    ) -> (ConstraintCategory, Span) {
        let constraint = self.constraints[index];
        debug!("classify_constraint: constraint={:?}", constraint);
        let span = constraint.locations.span(mir);
        let location = constraint.locations.from_location().unwrap_or(Location::START);

        if !self.constraint_is_interesting(index) {
            return (ConstraintCategory::Boring, span);
        }

        let data = &mir[location.block];
        debug!("classify_constraint: location={:?} data={:?}", location, data);
        let category = if location.statement_index == data.statements.len() {
            if let Some(ref terminator) = data.terminator {
                debug!("classify_constraint: terminator.kind={:?}", terminator.kind);
                match terminator.kind {
                    TerminatorKind::DropAndReplace { .. } => ConstraintCategory::Assignment,
                    TerminatorKind::Call { .. } => ConstraintCategory::CallArgument,
                    _ => ConstraintCategory::Other,
                }
            } else {
                ConstraintCategory::Other
            }
        } else {
            let statement = &data.statements[location.statement_index];
            debug!("classify_constraint: statement.kind={:?}", statement.kind);
            match statement.kind {
                StatementKind::Assign(ref place, ref rvalue) => {
                    debug!("classify_constraint: place={:?} rvalue={:?}", place, rvalue);
                    if *place == Place::Local(mir::RETURN_PLACE) {
                        ConstraintCategory::Return
                    } else {
                        match rvalue {
                            Rvalue::Cast(..) => ConstraintCategory::Cast,
                            Rvalue::Use(..) |
                            Rvalue::Aggregate(..) => ConstraintCategory::Assignment,
                            _ => ConstraintCategory::Other,
                        }
                    }
                }
                _ => ConstraintCategory::Other,
            }
        };

        (category, span)
    }

    /// Report an error because the universal region `fr` was required to outlive
    /// `outlived_fr` but it is not known to do so. For example:
    ///
    /// ```
    /// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
    /// ```
    ///
    /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
    pub(super) fn report_error(
        &self,
        mir: &Mir<'tcx>,
        infcx: &InferCtxt<'_, '_, 'tcx>,
        mir_def_id: DefId,
        fr: RegionVid,
        outlived_fr: RegionVid,
        blame_span: Span,
    ) {
        debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);

        if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
            let tables = infcx.tcx.typeck_tables_of(mir_def_id);
            let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables));
            if let Some(_error_reported) = nice.try_report() {
                return;
            }
        }

        // Find all paths
        let constraint_paths = self.find_constraint_paths_between_regions(fr, |r| r == outlived_fr);
        debug!("report_error: constraint_paths={:#?}", constraint_paths);

        // Find the shortest such path.
        let path = constraint_paths.iter().min_by_key(|p| p.len()).unwrap();
        debug!("report_error: shortest_path={:?}", path);

        // Classify each of the constraints along the path.
        let mut categorized_path: Vec<(ConstraintCategory, Span)> = path.iter()
            .map(|&index| self.classify_constraint(index, mir, infcx))
            .collect();
        debug!("report_error: categorized_path={:?}", categorized_path);

        // Find what appears to be the most interesting path to report to the user.
        categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0));
        debug!("report_error: sorted_path={:?}", categorized_path);

        // Get a span
        let (category, span) = categorized_path.first().unwrap();

        let category = match (
            category,
            self.universal_regions.is_local_free_region(fr),
            self.universal_regions.is_local_free_region(outlived_fr),
        ) {
            (ConstraintCategory::Assignment, true, false) =>
                &ConstraintCategory::AssignmentToUpvar,
            (ConstraintCategory::CallArgument, true, false) =>
                &ConstraintCategory::CallArgumentToUpvar,
            (category, _, _) => category,
        };

        debug!("report_error: category={:?}", category);
        match category {
            ConstraintCategory::AssignmentToUpvar |
            ConstraintCategory::CallArgumentToUpvar =>
                self.report_closure_error(mir, infcx, fr, outlived_fr, span),
            _ =>
                self.report_general_error(mir, infcx, mir_def_id, fr, outlived_fr, category, span),
        }
    }

    fn report_closure_error(
        &self,
        mir: &Mir<'tcx>,
        infcx: &InferCtxt<'_, '_, 'tcx>,
        fr: RegionVid,
        outlived_fr: RegionVid,
        span: &Span,
    ) {
        let diag = &mut infcx.tcx.sess.struct_span_err(
            *span, &format!("borrowed data escapes outside of closure"),
        );

        let (outlived_fr_name, outlived_fr_span) = self.get_var_name_and_span_for_region(
            infcx.tcx, mir, outlived_fr);

        if let Some(name) = outlived_fr_name {
            diag.span_label(
                outlived_fr_span,
                format!("`{}` is declared here, outside of the closure body", name),
            );
        }

        let (fr_name, fr_span) = self.get_var_name_and_span_for_region(infcx.tcx, mir, fr);

        if let Some(name) = fr_name {
            diag.span_label(
                fr_span,
                format!("`{}` is a reference that is only valid in the closure body", name),
            );

            diag.span_label(*span, format!("`{}` escapes the closure body here", name));
        }

        diag.emit();
    }

    fn report_general_error(
        &self,
        mir: &Mir<'tcx>,
        infcx: &InferCtxt<'_, '_, 'tcx>,
        mir_def_id: DefId,
        fr: RegionVid,
        outlived_fr: RegionVid,
        category: &ConstraintCategory,
        span: &Span,
    ) {
        let diag = &mut infcx.tcx.sess.struct_span_err(
            *span, &format!("unsatisfied lifetime constraints"), // FIXME
        );

        let counter = &mut 1;
        let fr_name = self.give_region_a_name(
            infcx.tcx, mir, mir_def_id, fr, counter, diag);
        let outlived_fr_name = self.give_region_a_name(
            infcx.tcx, mir, mir_def_id, outlived_fr, counter, diag);

        diag.span_label(*span, format!(
            "{} requires that `{}` must outlive `{}`",
            category, fr_name, outlived_fr_name,
        ));

        diag.emit();
    }

    // Find some constraint `X: Y` where:
    // - `fr1: X` transitively
    // - and `Y` is live at `elem`
    crate fn find_constraint(&self, fr1: RegionVid, elem: Location) -> RegionVid {
        let index = self.blame_constraint(fr1, elem);
        self.constraints[index].sub
    }

    /// Tries to finds a good span to blame for the fact that `fr1`
    /// contains `fr2`.
    pub(super) fn blame_constraint(
        &self,
        fr1: RegionVid,
        elem: impl ToElementIndex,
    ) -> ConstraintIndex {
        // Find everything that influenced final value of `fr`.
        let influenced_fr1 = self.dependencies(fr1);

        // Try to find some outlives constraint `'X: fr2` where `'X`
        // influenced `fr1`. Blame that.
        //
        // NB, this is a pretty bad choice most of the time. In
        // particular, the connection between `'X` and `fr1` may not
        // be obvious to the user -- not to mention the naive notion
        // of dependencies, which doesn't account for the locations of
        // contraints at all. But it will do for now.
        let relevant_constraint = self.constraints
            .iter_enumerated()
            .filter_map(|(i, constraint)| {
                if !self.liveness_constraints.contains(constraint.sub, elem) {
                    None
                } else {
                    influenced_fr1[constraint.sup]
                        .map(|distance| (distance, i))
                }
            })
            .min() // constraining fr1 with fewer hops *ought* to be more obvious
            .map(|(_dist, i)| i);

        relevant_constraint.unwrap_or_else(|| {
            bug!(
                "could not find any constraint to blame for {:?}: {:?}",
                fr1,
                elem,
            );
        })
    }

    /// Finds all regions whose values `'a` may depend on in some way.
    /// For each region, returns either `None` (does not influence
    /// `'a`) or `Some(d)` which indicates that it influences `'a`
    /// with distinct `d` (minimum number of edges that must be
    /// traversed).
    ///
    /// Used during error reporting, extremely naive and inefficient.
    fn dependencies(&self, r0: RegionVid) -> IndexVec<RegionVid, Option<usize>> {
        let mut result_set = IndexVec::from_elem(None, &self.definitions);
        let mut changed = true;
        result_set[r0] = Some(0); // distance 0 from `r0`

        while changed {
            changed = false;
            for constraint in self.constraints.iter() {
                if let Some(n) = result_set[constraint.sup] {
                    let m = n + 1;
                    if result_set[constraint.sub]
                        .map(|distance| m < distance)
                        .unwrap_or(true)
                    {
                        result_set[constraint.sub] = Some(m);
                        changed = true;
                    }
                }
            }
        }

        result_set
    }
}
<|endoftext|>


<commit_before><commit_msg>add reader benchmark (#147)<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#![feature(test)]
extern crate parquet;
extern crate test;

use std::fs::File;
use std::path::Path;

use parquet::file::reader::{FileReader, SerializedFileReader};
use test::Bencher;

#[bench]
fn record_reader_10k_collect(bench: &mut Bencher) {
  let path = Path::new("data/10k-v2.parquet");
  let file = File::open(&path).unwrap();
  let len = file.metadata().unwrap().len();
  let parquet_reader = SerializedFileReader::new(file).unwrap();

  bench.bytes = len;
  bench.iter(|| {
    let iter = parquet_reader.get_row_iter(None).unwrap();
    let _ = iter.collect::<Vec<_>>();
  })
}
<|endoftext|>


<commit_before><commit_msg>chore(examples): add ping/pong low level frame access example<commit_after>/// An example demonstrating how to send and recieve a custom ping/pong frame.
/// This example also shows using a separate thread to represent another
/// component of your system as well as how to use a custom Factory.
extern crate ws;
extern crate env_logger;
extern crate time;

use std::thread;
use std::thread::sleep;
use std::time::Duration;
use std::str::from_utf8;
use std::sync::mpsc::channel;
use std::sync::mpsc::Sender as ThreadOut;

use ws::{Builder, CloseCode, OpCode, Sender, Frame, Factory, Handler, Message, Result};

fn main () {

    // Setup logging
    env_logger::init().unwrap();

    // Set timer channel
    let (tx, rx) = channel();

    // Create WebSocket
    let socket = ws::Builder::new().build(ServerFactory { timer: tx }).unwrap();

    // Get broadcaster for timer
    let all = socket.broadcaster();

    // Start timer thread
    let timer = thread::spawn(move || {
        loop {
            // Test latency every 5 seconds
            sleep(Duration::from_secs(5));

            // Check if timer needs to go down
            if let Ok(_) = rx.try_recv() {
                println!("Timer is going down.");
                break;
            }

            // Ping all connections with current time
            if let Err(err) = all.ping(time::precise_time_ns().to_string().into()) {
                println!("Unable to ping connections: {:?}", err);
                println!("Timer is going down.");
                break;
            }
        }
    });

    // Start WebSocket server
    socket.listen("127.0.0.1:3012").unwrap();

    // Once the server is done, wait for the timer to shutdown as well
    timer.join().unwrap();
}

struct ServerFactory {
    timer: ThreadOut<usize>,
}

impl Factory for ServerFactory {
    type Handler = Server;

    fn connection_made(&mut self, out: Sender) -> Self::Handler {
        Server { out: out }
    }

    fn on_shutdown(&mut self) {
        if let Err(err) = self.timer.send(0) {
            println!("Unable to shut down timer: {:?}", err)
        }
    }

}

// For accessing the default handler implementation
struct DefaultHandler;

impl Handler for DefaultHandler {}

// Server WebSocket handler
struct Server {
    out: Sender,
}

impl Handler for Server {

    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("Server got message '{}'. ", msg);
        self.out.send(msg)
    }

    fn on_close(&mut self, code: CloseCode, reason: &str) {
        println!("WebSocket closing for ({:?}) {}", code, reason);
        println!("Shutting down server after first connection closes.");
        self.out.shutdown().unwrap();
    }

    fn on_frame(&mut self, frame: Frame) -> Result<Option<Frame>> {
        if frame.opcode() == OpCode::Pong {
            if let Ok(pong) = try!(from_utf8(frame.payload())).parse::<u64>() {
                let now = time::precise_time_ns();
                println!("Latency is {:.3}ms.", (now - pong) as f64 / 1_000_000f64);
            } else {
                println!("Received bad pong.");
            }
        }

        // Run default frame validation
        DefaultHandler.on_frame(frame)
    }
}

<|endoftext|>


<commit_before><commit_msg>Add test<commit_after>// Copyright 2018 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.

// Checks if the correct registers are being used to pass arguments
// when the sysv64 ABI is specified.

// compile-flags: -Zepoch=2018

pub trait Foo {}

// should compile without the dyn trait feature flag
fn foo(x: &dyn Foo) {}

pub fn main() {}
<|endoftext|>


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

// compile-pass

// Bastion of the Turbofish
// ------------------------
// Beware travellers, lest you venture into waters callous and unforgiving,
// where hope must be abandoned, ere it is cruelly torn from you. For here
// stands the bastion of the Turbofish: an impenetrable fortress holding
// unshaking against those who would dare suggest the supererogation of the
// Turbofish.
//
// Once I was young and foolish and had the impudence to imagine that I could
// shake free from the coils by which that creature had us tightly bound. I
// dared to suggest that there was a better way: a brighter future, in which
// Rustaceans both new and old could be rid of that vile beast. But alas! In
// my foolhardiness my ignorance was unveiled and my dreams were dashed
// unforgivingly against the rock of syntactic ambiguity.
//
// This humble program, small and insignificant though it might seem,
// demonstrates that to which we had previously cast a blind eye: an ambiguity
// in permitting generic arguments to be provided without the consent of the
// Great Turbofish. Should you be so naïve as to try to revolt against its
// mighty clutches, here shall its wrath be indomitably displayed. This
// program must pass for all eternity, fundamentally at odds with an impetuous
// rebellion against the Turbofish.
//
// My heart aches in sorrow, for I know I am defeated. Let this be a warning
// to all those who come after. Here stands the bastion of the Turbofish.

fn main() {
    let (oh, woe, is, me) = ("the", "Turbofish", "remains", "undefeated");
    let _: (bool, bool) = (oh<woe, is>(me));
}
<commit_msg>Rollup merge of #53562 - varkor:bastion-of-the-turbofish, r=nagisa<commit_after>// Copyright 2018 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.

// compile-pass

// Bastion of the Turbofish
// ------------------------
// Beware travellers, lest you venture into waters callous and unforgiving,
// where hope must be abandoned, ere it is cruelly torn from you. For here
// stands the bastion of the Turbofish: an impenetrable fortress holding
// unshaking against those who would dare suggest the supererogation of the
// Turbofish.
//
// Once I was young and foolish and had the impudence to imagine that I could
// shake free from the coils by which that creature had us tightly bound. I
// dared to suggest that there was a better way: a brighter future, in which
// Rustaceans both new and old could be rid of that vile beast. But alas! In
// my foolhardiness my ignorance was unveiled and my dreams were dashed
// unforgivingly against the rock of syntactic ambiguity.
//
// This humble program, small and insignificant though it might seem,
// demonstrates that to which we had previously cast a blind eye: an ambiguity
// in permitting generic arguments to be provided without the consent of the
// Great Turbofish. Should you be so naïve as to try to revolt against its
// mighty clutches, here shall its wrath be indomitably displayed. This
// program must pass for all eternity, fundamentally at odds with an impetuous
// rebellion against the Turbofish.
//
// My heart aches in sorrow, for I know I am defeated. Let this be a warning
// to all those who come after. Here stands the bastion of the Turbofish.

// See https://github.com/rust-lang/rust/pull/53562
// and https://github.com/rust-lang/rfcs/pull/2527
// for context.

fn main() {
    let (oh, woe, is, me) = ("the", "Turbofish", "remains", "undefeated");
    let _: (bool, bool) = (oh<woe, is>(me));
}
<|endoftext|>


<commit_before><commit_msg>Long Jump + Test<commit_after><|endoftext|>


<commit_before><commit_msg>Initial tests<commit_after><|endoftext|>