<commit_before>extern crate chrono;

use std::io::{stderr,BufRead, BufReader, Write};
use std::process::{Command,exit,Stdio};
use std::sync::mpsc::{channel, Sender};
use std::thread::{self, sleep};
use std::time::Duration;

const OCCUPIED_ICON: &'static str = "";
const FREE_ICON: &'static str = "";

enum Update {
    Workspaces(String),
    Time(String),
    Title(String),
}

fn workspace_info(sender: Sender<Update>) {
    // let mut old_message: Vec<String> = vec!["".to_owned()];

    let output = match Command::new("bspc").arg("subscribe").arg("report").stdout(Stdio::piped()).spawn() {
        Ok(out) => out,
        Err(_) => {
            let _ = stderr().write("Failed to run 'bspc'\n".as_bytes()).unwrap();
            exit(1);
        },
    };

    let reader = BufReader::new(output.stdout.unwrap());
    for line in reader.lines() {
        let mut message: Vec<String> = Vec::new();
        message.push(format!(" %{{l}}"));
        message.push(format!("%{{A4:bspc desktop -f prev:}}%{{A5:bspc desktop -f next:}}"));

        let line = line.unwrap();
        let line_vector = line.split(":").collect::<Vec<&str>>();

        for line in &line_vector {
            match &line[0..1] {
                // Occupied focused
                "O" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FFF6F9FF}} {}%{{F-}}", OCCUPIED_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Occupied unfocused
                "o" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FFA3A6AB}} {}%{{F-}}", OCCUPIED_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Free focused
                "F" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FFF6F9FF}} {}%{{F-}}", FREE_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Free unfocused
                "f" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FF6F7277}} {}%{{F-}}", FREE_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Urgent focused
                "U" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FF916255}} {}%{{F-}}", OCCUPIED_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Urgent unfocused
                "u" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FF543B3B}} {}%{{F-}}", OCCUPIED_ICON));
                    message.push(format!("%{{A}}"));
                }

                _ => {}
            }
        }
        message.push(format!("%{{A}}%{{A}}"));

        let _ = sender.send(Update::Workspaces(message.join("")));
    }
}

fn title(sender: Sender<Update>) {
    let output = match Command::new("xtitle").arg("-s").arg("-i").arg("-t").arg("100").stdout(Stdio::piped()).spawn() {
        Ok(out) => out,
        Err(_) => {
            let _ = stderr().write("Failed to run 'xtitle'\n".as_bytes()).unwrap();
            exit(1);
        },
    };

    let reader = BufReader::new(output.stdout.unwrap());
    for line in reader.lines() {
        let line = line.unwrap();
        let _ = sender.send(Update::Title(format!("%{{c}}{}", line)));
    }
}

fn time(sender: Sender<Update>) {
    loop {
        let time = chrono::Local::now().format("%I:%M %p");
        let _ = sender.send(Update::Time(format!("%{{r}}%{{B#FF665B5B}} {} %{{B-}}", time)));
        sleep(Duration::from_secs(1));
    }
}

fn main() {
    let (sender, receiver) = channel::<Update>();

    let mut workspace_message: String = "".to_owned();
    let mut title_message: String = "".to_owned();
    let mut time_message: String = "".to_owned();
    let mut message: String = "".to_owned();

    let sender_clone = sender.clone();
    let _ = thread::spawn(move || {
        workspace_info(sender_clone);
    });

    let sender_clone = sender.clone();
    let _ = thread::spawn(move || {
        title(sender_clone);
    });

    let sender_clone = sender.clone();
    let _ = thread::spawn(move || {
        time(sender_clone);
    });

    for line in receiver.iter() {
        match line {
            Update::Workspaces(info) => {
                workspace_message = info;
            }

            Update::Title(title) => {
                title_message = title;
            }

            Update::Time(time) => {
                time_message = time;
            }
        }

        if message != workspace_message.to_owned() + &title_message + &time_message {
            message = workspace_message.to_owned() + &title_message + &time_message;
            sleep(Duration::from_millis(5));
            println!("{}", message);
        }
    }
}
<commit_msg>Allow threads to panic<commit_after>extern crate chrono;

use std::io::{BufRead, BufReader};
use std::process::{Command, Stdio};
use std::sync::mpsc::{channel, Sender};
use std::thread::{self, sleep};
use std::time::Duration;

const OCCUPIED_ICON: &'static str = "";
const FREE_ICON: &'static str = "";

enum Update {
    Workspaces(String),
    Time(String),
    Title(String),
}

fn workspace_info(sender: Sender<Update>) {
    let output = Command::new("bspc").arg("subscribe").arg("report").stdout(Stdio::piped()).spawn().unwrap();

    let reader = BufReader::new(output.stdout.unwrap());
    for line in reader.lines() {
        let mut message: Vec<String> = Vec::new();
        message.push(format!(" %{{l}}"));
        message.push(format!("%{{A4:bspc desktop -f prev:}}%{{A5:bspc desktop -f next:}}"));

        let line = line.unwrap();
        let line_vector = line.split(":").collect::<Vec<&str>>();

        for line in &line_vector {
            match &line[0..1] {
                // Occupied focused
                "O" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FFF6F9FF}} {}%{{F-}}", OCCUPIED_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Occupied unfocused
                "o" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FFA3A6AB}} {}%{{F-}}", OCCUPIED_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Free focused
                "F" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FFF6F9FF}} {}%{{F-}}", FREE_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Free unfocused
                "f" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FF6F7277}} {}%{{F-}}", FREE_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Urgent focused
                "U" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FF916255}} {}%{{F-}}", OCCUPIED_ICON));
                    message.push(format!("%{{A}}"));
                }

                // Urgent unfocused
                "u" => {
                    message.push(format!("%{{A:bspc desktop -f {}:}}", &line[1..]));
                    message.push(format!("%{{F#FF543B3B}} {}%{{F-}}", OCCUPIED_ICON));
                    message.push(format!("%{{A}}"));
                }

                _ => {}
            }
        }
        message.push(format!("%{{A}}%{{A}}"));

        let _ = sender.send(Update::Workspaces(message.join("")));
    }
}

fn title(sender: Sender<Update>) {
    let output = Command::new("xtitle").arg("-s").arg("-i").arg("-t").arg("100").stdout(Stdio::piped()).spawn().unwrap();

    let reader = BufReader::new(output.stdout.unwrap());
    for line in reader.lines() {
        let line = line.unwrap();
        let _ = sender.send(Update::Title(format!("%{{c}}{}", line)));
    }
}

fn time(sender: Sender<Update>) {
    loop {
        let time = chrono::Local::now().format("%I:%M %p");
        let _ = sender.send(Update::Time(format!("%{{r}}%{{B#FF665B5B}} {} %{{B-}}", time)));
        sleep(Duration::from_secs(1));
    }
}

fn main() {
    let (sender, receiver) = channel::<Update>();

    let mut workspace_message: String = "".to_owned();
    let mut title_message: String = "".to_owned();
    let mut time_message: String = "".to_owned();
    let mut message: String = "".to_owned();

    let sender_clone = sender.clone();
    let _ = thread::spawn(move || {
        workspace_info(sender_clone);
    });

    let sender_clone = sender.clone();
    let _ = thread::spawn(move || {
        title(sender_clone);
    });

    let sender_clone = sender.clone();
    let _ = thread::spawn(move || {
        time(sender_clone);
    });

    for line in receiver.iter() {
        match line {
            Update::Workspaces(info) => {
                workspace_message = info;
            }

            Update::Title(title) => {
                title_message = title;
            }

            Update::Time(time) => {
                time_message = time;
            }
        }

        if message != workspace_message.to_owned() + &title_message + &time_message {
            message = workspace_message.to_owned() + &title_message + &time_message;
            sleep(Duration::from_millis(5));
            println!("{}", message);
        }
    }
}
<|endoftext|>


<commit_before>extern crate mio;
extern crate bytes;
extern crate log4rs;
#[macro_use]
extern crate log;
#[macro_use]
extern crate clap;

use mio::tcp::*;
use mio::{Sender,EventLoop};
use mio::{TryRead,TryWrite};
use mio::util::Slab;
use std::thread;
use std::sync::mpsc::{self,channel};
use std::io::Cursor;
use std::collections::VecDeque;
use clap::{Arg, App, SubCommand};

use bytes::{Buf, Take};

const SERVER: mio::Token = mio::Token(0);

#[derive(Debug)]
enum MiChatCommand {
    Broadcast(String),
}

#[derive(Debug)]
struct MiChatIoEvent (mio::Token, String);

struct MiChat {
    listener: TcpListener,
    connections: Slab<Connection>,
    register: String,
}

impl MiChat {
    fn new(listener: TcpListener) -> MiChat {
        MiChat {
            listener: listener,
            connections: Slab::new_starting_at(mio::Token(1), 1024),
            register: String::new(),
        }
    }
    fn process_action(&mut self, msg: &MiChatCommand) {
        trace!("{:p}; got {:?}", self, msg);
        match msg {
            &MiChatCommand::Broadcast(ref s) => {
                for c in self.connections.iter_mut() {
                    c.enqueue(&s);
                }
            }
        }
    }
}

#[derive(Debug)]
struct Connection {
    socket: TcpStream,
    sock_status: mio::EventSet,
    token: mio::Token,
    read_buf: Vec<u8>,
    read_eof: bool,
    failed: bool,
    write_buf: Vec<u8>,
}

impl Connection {
    fn new(socket: TcpStream, token: mio::Token) -> Connection {
        Connection {
            socket: socket,
            sock_status: mio::EventSet::none(),
            token: token,
            read_buf: Vec::with_capacity(1024),
            write_buf: Vec::new(),
            read_eof: false,
            failed: false,
        }
    }
    // Event updates arrive here
    fn ready(&mut self, event_loop: &mut mio::EventLoop<MiChat>, events: mio::EventSet) {
        self.sock_status.insert(events);
        info!("Connection::ready: {:?}; this time: {:?}; now: {:?}",
                self.socket.peer_addr(), events, self.sock_status);
    }

    // actions are processed here on down.

    fn process_rules(&mut self, event_loop: &mut mio::EventLoop<MiChat>,
        to_parent: &mut VecDeque<MiChatCommand>) {
        if self.sock_status.is_readable() {
            self.read(event_loop);
            self.sock_status.remove(mio::EventSet::readable());
        }

        self.process_buffer(to_parent);

        if self.sock_status.is_writable() {
            self.write(event_loop);
            self.sock_status.remove(mio::EventSet::writable());
        }

        if !self.is_closed() {
            self.reregister(event_loop)
        }
    }

    fn process_buffer(&mut self, to_parent: &mut VecDeque<MiChatCommand>) {
        let mut prev = 0;
        info!("{:?}: Read buffer: {:?}", self.socket.peer_addr(), self.read_buf);
        for n in self.read_buf.iter().enumerate()
                .filter_map(|(i, e)| if *e == '\n' as u8 { Some(i) } else { None } ) {
            info!("{:?}: Pos: {:?}; chunk: {:?}", self.socket.peer_addr(), n, &self.read_buf[prev..n]);
            let s = String::from_utf8_lossy(&self.read_buf[prev..n]).to_string();
            let cmd = MiChatCommand::Broadcast(s);
            info!("Send! {:?}", cmd);
            to_parent.push_back(cmd);
            prev = n+1;
        }
        let remainder = self.read_buf[prev..].to_vec();
        info!("{:?}: read Remainder: {}", self.socket.peer_addr(), remainder.len());
        self.read_buf = remainder;
    }

    fn read(&mut self, event_loop: &mut mio::EventLoop<MiChat>) {
        let mut abuf = Vec::new();
        match self.socket.try_read_buf(&mut abuf) {
            Ok(Some(0)) => {
                info!("{:?}: EOF!", self.socket.peer_addr());
                self.read_eof = true
            },
            Ok(Some(n)) => {
                info!("{:?}: Read {}bytes", self.socket.peer_addr(), n);
                self.read_buf.extend(abuf);
            },
            Ok(None) => {
                info!("{:?}: Noop!", self.socket.peer_addr());
            },
            Err(e) => {
                error!("got an error trying to read; err={:?}", e);
                self.failed =true;
            }
        }
    }

    fn write(&mut self, event_loop: &mut mio::EventLoop<MiChat>) {
        match self.socket.try_write(&mut self.write_buf) {
            Ok(Some(n)) => {
                info!("{:?}: Wrote {} of {} in buffer ({:?}...)", self.socket.peer_addr(), n,
                    self.write_buf.len(), &self.write_buf[0..2]);
                self.write_buf = self.write_buf[n..].to_vec();
                info!("{:?}: Now {:?}b", self.socket.peer_addr(), self.write_buf.len());
            },
            Ok(None) => {
                info!("Write unready");
            },
            Err(e) => {
                error!("got an error trying to write; err={:?}", e);
                self.failed = true;
            }
        }
    }

    fn reregister(&mut self, event_loop: &mut mio::EventLoop<MiChat>) {
        let mut flags = mio::EventSet::readable();
        if !self.write_buf.is_empty() {
            flags.insert(mio::EventSet::writable());
        }
        info!("Registering {:?} with {:?}", self, flags);

        event_loop.reregister(
                &self.socket,
                self.token,
                flags,
                mio::PollOpt::oneshot()).expect("EventLoop#reregister")
    }

    fn buffer_slice(buf: &mut Vec<u8>, slice: &[u8]) {
        buf.extend(slice.iter().cloned());
    }

    fn is_closed(&self) -> bool {
        self.failed || (self.read_eof && self.write_buf.is_empty())
    }

    fn enqueue(&mut self, s: &str) {
        self.write_buf.extend(s.as_bytes());
        self.write_buf.push('\n' as u8);
    }
}

impl mio::Handler for MiChat {
    type Timeout = ();
    type Message = ();
    fn ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token, events: mio::EventSet) {
        info!("{:?}: {:?}", token, events);
        let mut next = VecDeque::new();

        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                info!("the listener socket is ready to accept a connection");
                match self.listener.accept() {
                    Ok(Some(socket)) => {
                        let token = self.connections
                            .insert_with(|token| Connection::new(socket, token))
                            .expect("token insert");

                        event_loop.register_opt(
                            &self.connections[token].socket,
                            token,
                            mio::EventSet::readable(),
                            mio::PollOpt::edge() | mio::PollOpt::oneshot())
                        .expect("event loop register");
                    }
                    Ok(None) => {
                        info!("the listener socket wasn't actually ready");
                    }
                    Err(e) => {
                        info!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            }
            _ => {
                self.connections[token].ready(event_loop, events);
                info!("TODO next on {:?}: {:?}", token, next);
                if self.connections[token].is_closed() {
                    info!("Removing; {:?}", token);
                    self.connections.remove(token);
                }
            }
        }

        loop {
            for conn in self.connections.iter_mut() {
                conn.process_rules(event_loop, &mut next);
            }
            if next.is_empty() { break; }

            for action in next.iter() {
                self.process_action(action);
            }
            next.clear();
        }
    }
}

#[derive(Debug)]
struct Model {
    value: String
}

impl Model {
    fn new() -> Model {
        Model { value: "".to_string() }
    }

    fn process_from(&mut self, rx: mpsc::Receiver<MiChatCommand>, replies: Sender<MiChatIoEvent>) {
        loop {
            let msg = rx.recv().expect("Model receive");

        }
    }
}

const LOG_FILE: &'static str = "log.toml";

fn main() {
    if let Err(e) = log4rs::init_file(LOG_FILE, Default::default()) {
        panic!("Could not init logger from file {}: {}", LOG_FILE, e);
    }
    let matches = App::new("michat")
        .arg(Arg::with_name("bind").short("l").takes_value(true).required(true))
        .get_matches();

    let address = value_t_or_exit!(matches.value_of("bind"), std::net::SocketAddr);
    let listener = TcpListener::bind(&address).expect("bind");

    let mut event_loop = mio::EventLoop::new().expect("Create event loop");
    event_loop.register(&listener, SERVER).expect("Register listener");

    info!("running michat listener at: {:?}", address);

    let mut service = MiChat::new(listener);
    event_loop.run(&mut service).expect("Run loop");
}
<commit_msg>GC un-used gubbins.<commit_after>extern crate mio;
extern crate bytes;
extern crate log4rs;
#[macro_use]
extern crate log;
#[macro_use]
extern crate clap;

use mio::tcp::*;
use mio::EventLoop;
use mio::{TryRead,TryWrite};
use mio::util::Slab;
use std::collections::VecDeque;
use clap::{Arg, App};

const SERVER: mio::Token = mio::Token(0);

#[derive(Debug)]
enum MiChatCommand {
    Broadcast(String),
}

struct MiChat {
    listener: TcpListener,
    connections: Slab<Connection>,
}

impl MiChat {
    fn new(listener: TcpListener) -> MiChat {
        MiChat {
            listener: listener,
            connections: Slab::new_starting_at(mio::Token(1), 1024),
        }
    }
    fn process_action(&mut self, msg: &MiChatCommand) {
        trace!("{:p}; got {:?}", self, msg);
        match msg {
            &MiChatCommand::Broadcast(ref s) => {
                for c in self.connections.iter_mut() {
                    c.enqueue(&s);
                }
            }
        }
    }
}

#[derive(Debug)]
struct Connection {
    socket: TcpStream,
    sock_status: mio::EventSet,
    token: mio::Token,
    read_buf: Vec<u8>,
    read_eof: bool,
    failed: bool,
    write_buf: Vec<u8>,
}

impl Connection {
    fn new(socket: TcpStream, token: mio::Token) -> Connection {
        Connection {
            socket: socket,
            sock_status: mio::EventSet::none(),
            token: token,
            read_buf: Vec::with_capacity(1024),
            write_buf: Vec::new(),
            read_eof: false,
            failed: false,
        }
    }
    // Event updates arrive here
    fn ready(&mut self, _event_loop: &mut mio::EventLoop<MiChat>, events: mio::EventSet) {
        self.sock_status.insert(events);
        info!("Connection::ready: {:?}; this time: {:?}; now: {:?}",
                self.socket.peer_addr(), events, self.sock_status);
    }

    // actions are processed here on down.

    fn process_rules(&mut self, event_loop: &mut mio::EventLoop<MiChat>,
        to_parent: &mut VecDeque<MiChatCommand>) {
        if self.sock_status.is_readable() {
            self.read();
            self.sock_status.remove(mio::EventSet::readable());
        }

        self.process_buffer(to_parent);

        if self.sock_status.is_writable() {
            self.write();
            self.sock_status.remove(mio::EventSet::writable());
        }

        if !self.is_closed() {
            self.reregister(event_loop)
        }
    }

    fn process_buffer(&mut self, to_parent: &mut VecDeque<MiChatCommand>) {
        let mut prev = 0;
        info!("{:?}: Read buffer: {:?}", self.socket.peer_addr(), self.read_buf);
        for n in self.read_buf.iter().enumerate()
                .filter_map(|(i, e)| if *e == '\n' as u8 { Some(i) } else { None } ) {
            info!("{:?}: Pos: {:?}; chunk: {:?}", self.socket.peer_addr(), n, &self.read_buf[prev..n]);
            let s = String::from_utf8_lossy(&self.read_buf[prev..n]).to_string();
            let cmd = MiChatCommand::Broadcast(s);
            info!("Send! {:?}", cmd);
            to_parent.push_back(cmd);
            prev = n+1;
        }
        let remainder = self.read_buf[prev..].to_vec();
        info!("{:?}: read Remainder: {}", self.socket.peer_addr(), remainder.len());
        self.read_buf = remainder;
    }

    fn read(&mut self) {
        let mut abuf = Vec::new();
        match self.socket.try_read_buf(&mut abuf) {
            Ok(Some(0)) => {
                info!("{:?}: EOF!", self.socket.peer_addr());
                self.read_eof = true
            },
            Ok(Some(n)) => {
                info!("{:?}: Read {}bytes", self.socket.peer_addr(), n);
                self.read_buf.extend(abuf);
            },
            Ok(None) => {
                info!("{:?}: Noop!", self.socket.peer_addr());
            },
            Err(e) => {
                error!("got an error trying to read; err={:?}", e);
                self.failed =true;
            }
        }
    }

    fn write(&mut self) {
        match self.socket.try_write(&mut self.write_buf) {
            Ok(Some(n)) => {
                info!("{:?}: Wrote {} of {} in buffer ({:?}...)", self.socket.peer_addr(), n,
                    self.write_buf.len(), &self.write_buf[0..2]);
                self.write_buf = self.write_buf[n..].to_vec();
                info!("{:?}: Now {:?}b", self.socket.peer_addr(), self.write_buf.len());
            },
            Ok(None) => {
                info!("Write unready");
            },
            Err(e) => {
                error!("got an error trying to write; err={:?}", e);
                self.failed = true;
            }
        }
    }

    fn reregister(&mut self, event_loop: &mut mio::EventLoop<MiChat>) {
        let mut flags = mio::EventSet::readable();
        if !self.write_buf.is_empty() {
            flags.insert(mio::EventSet::writable());
        }
        info!("Registering {:?} with {:?}", self, flags);

        event_loop.reregister(
                &self.socket,
                self.token,
                flags,
                mio::PollOpt::oneshot()).expect("EventLoop#reregister")
    }

    fn is_closed(&self) -> bool {
        self.failed || (self.read_eof && self.write_buf.is_empty())
    }

    fn enqueue(&mut self, s: &str) {
        self.write_buf.extend(s.as_bytes());
        self.write_buf.push('\n' as u8);
    }
}

impl mio::Handler for MiChat {
    type Timeout = ();
    type Message = ();
    fn ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token, events: mio::EventSet) {
        info!("{:?}: {:?}", token, events);
        let mut next = VecDeque::new();

        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                info!("the listener socket is ready to accept a connection");
                match self.listener.accept() {
                    Ok(Some(socket)) => {
                        let token = self.connections
                            .insert_with(|token| Connection::new(socket, token))
                            .expect("token insert");

                        event_loop.register_opt(
                            &self.connections[token].socket,
                            token,
                            mio::EventSet::readable(),
                            mio::PollOpt::edge() | mio::PollOpt::oneshot())
                        .expect("event loop register");
                    }
                    Ok(None) => {
                        info!("the listener socket wasn't actually ready");
                    }
                    Err(e) => {
                        info!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            }
            _ => {
                self.connections[token].ready(event_loop, events);
                info!("TODO next on {:?}: {:?}", token, next);
                if self.connections[token].is_closed() {
                    info!("Removing; {:?}", token);
                    self.connections.remove(token);
                }
            }
        }

        loop {
            for conn in self.connections.iter_mut() {
                conn.process_rules(event_loop, &mut next);
            }
            if next.is_empty() { break; }

            for action in next.iter() {
                self.process_action(action);
            }
            next.clear();
        }
    }
}

const LOG_FILE: &'static str = "log.toml";

fn main() {
    if let Err(e) = log4rs::init_file(LOG_FILE, Default::default()) {
        panic!("Could not init logger from file {}: {}", LOG_FILE, e);
    }
    let matches = App::new("michat")
        .arg(Arg::with_name("bind").short("l").takes_value(true).required(true))
        .get_matches();

    let address = value_t_or_exit!(matches.value_of("bind"), std::net::SocketAddr);
    let listener = TcpListener::bind(&address).expect("bind");

    let mut event_loop = mio::EventLoop::new().expect("Create event loop");
    event_loop.register(&listener, SERVER).expect("Register listener");

    info!("running michat listener at: {:?}", address);

    let mut service = MiChat::new(listener);
    event_loop.run(&mut service).expect("Run loop");
}
<|endoftext|>


<commit_before>extern crate sdl;

use std::rand::Rng;

use sdl::event::{Event, Key};
use sdl::video::{SurfaceFlag, VideoFlag};

struct Chip8Unit {
    /*
     * 0x000-0x1FF - Chip 8 interpreter (contains font set in emu)
     * 0x050-0x0A0 - Used for the built in 4x5 pixel font set (0-F)
     * 0x200-0xFFF - Program ROM and work RAM
     */
    memory:    [u8; 4096],

    /*
     * CPU registers: The Chip 8 has 15 8-bit general purpose registers
     * named V0,V1 up to VE. The 16th register is used  for the ‘carry flag’.
     */
    registers: [u8; 16],

    // Index register
    i: u16,

    // program counter
    pc: u16,

    // Screen - 64 x 32 pixels
    graphics: [u8; 64*32],

    // No timers, but 60hz counters
    delay_timer: u8,
    sound_timer: u8,

    // Stack needed to jump to certain addresses or call subroutines
    // The chip8 stack has 16 levels
    stack_pointer: u16,
    stack: [u16; 16],

    // Chip8 keypad had 16 keys - keep track of the kb state
    keypad: [u8; 16],
}

#[main]
fn main() {
    // Initialize SDL Video
    sdl::init([sdl::InitFlag::Video].as_slice());

    // Give our window a title
    sdl::wm::set_caption("rusty_chips a Chip8 emulator", "rusty_chips");

    // Initialize the screen
    let screen = match sdl::video::set_video_mode(800, 600, 32,
                                                  [SurfaceFlag::HWSurface].as_slice(),
                                                  [VideoFlag::DoubleBuf].as_slice()) {
        Ok(screen) => screen,
        Err(err) => panic!("Failed to set video mode: {}", err)
    };

    // SDL main loop
    'main : loop {
        'event : loop {
            match sdl::event::poll_event() {
                Event::Quit => break 'main,
                Event::None => break 'event,
                Event::Key (k,_,_,_)
                    if k == Key::Escape
                        => break 'main,
                    _ => {}
            }
        }
    }

    // Quit
    sdl::quit();
}
<commit_msg>initialize sdl in a separate function<commit_after>extern crate sdl;

use std::rand::Rng;

use sdl::event::{Event, Key};
use sdl::video::{SurfaceFlag, VideoFlag};

struct Chip8Unit {
    /*
     * 0x000-0x1FF - Chip 8 interpreter (contains font set in emu)
     * 0x050-0x0A0 - Used for the built in 4x5 pixel font set (0-F)
     * 0x200-0xFFF - Program ROM and work RAM
     */
    memory:    [u8; 4096],

    /*
     * CPU registers: The Chip 8 has 15 8-bit general purpose registers
     * named V0,V1 up to VE. The 16th register is used  for the ‘carry flag’.
     */
    registers: [u8; 16],

    // Index register
    i: u16,

    // program counter
    pc: u16,

    // Screen - 64 x 32 pixels
    graphics: [u8; 64*32],

    // No timers, but 60hz counters
    delay_timer: u8,
    sound_timer: u8,

    // Stack needed to jump to certain addresses or call subroutines
    // The chip8 stack has 16 levels
    stack_pointer: u16,
    stack: [u16; 16],

    // Chip8 keypad had 16 keys - keep track of the kb state
    keypad: [u8; 16],
}

fn init_sdl() {
    // Initialize SDL Video
    sdl::init([sdl::InitFlag::Video].as_slice());

    // Give our window a title
    sdl::wm::set_caption("rusty_chips a Chip8 emulator", "rusty_chips");

    // Initialize the screen
    let screen = match sdl::video::set_video_mode(800, 600, 32,
                                                  [SurfaceFlag::HWSurface].as_slice(),
                                                  [VideoFlag::DoubleBuf].as_slice()) {
        Ok(screen) => screen,
        Err(err) => panic!("Failed to set video mode: {}", err)
    };
}

fn main() {
    // Initialize SDL
    init_sdl();

    // SDL main loop
    'main : loop {
        'event : loop {
            match sdl::event::poll_event() {
                Event::Quit => break 'main,
                Event::None => break 'event,
                Event::Key (k,_,_,_)
                    if k == Key::Escape
                        => break 'main,
                    _ => {}
            }
        }
    }

    // Quit
    sdl::quit();
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
#![feature(phase)]
#[phase(plugin, link)] extern crate log;

extern crate syntax;
extern crate collections;
extern crate core;

#[cfg(not(test))]
use racer::Match;
#[cfg(not(test))]
use racer::util::getline;
#[cfg(not(test))]
use racer::nameres::{do_file_search, do_external_search};
#[cfg(not(test))]
use racer::scopes;

pub mod racer;

#[cfg(not(test))]
fn match_fn(m:Match) {
    let (linenum, charnum) = scopes::point_to_coords2(&m.filepath, m.point).unwrap();
    if m.matchstr.as_slice() == "" {
        panic!("MATCHSTR is empty - waddup?");
    }
    println!("MATCH {},{},{},{},{},{}", m.matchstr,
                                    linenum.to_string(),
                                    charnum.to_string(),
                                    m.filepath.as_str().unwrap(),
                                    m.mtype,
                                    m.contextstr
             );
}

#[cfg(not(test))]
fn complete() {
    let args = std::os::args();
    if args.len() < 3 {
        println!("Provide more arguments!");
        print_usage();
        std::os::set_exit_status(1);
        return;
    }
    match std::str::from_str(std::os::args().as_slice()[2].as_slice()) {
        Some(linenum) => {
            // input: linenum, colnum, fname
            if args.len() < 5 {
                println!("Provide more arguments!");
                print_usage();
                std::os::set_exit_status(1);
                return;
            }
            let charnum = std::str::from_str(std::os::args().as_slice()[3].as_slice()).unwrap();
            let fname = args.as_slice()[4].as_slice();
            let fpath = Path::new(fname);
            let src = racer::load_file(&fpath);
            let line = getline(&fpath, linenum);
            let (start, pos) = racer::util::expand_ident(line.as_slice(), charnum);
            println!("PREFIX {},{},{}", start, pos, line.as_slice().slice(start, pos));

            let point = scopes::coords_to_point(&*src, linenum, charnum);
            for m in racer::complete_from_file(&*src, &fpath, point) {
                match_fn(m);
            }
        }
        None => {
            // input: a command line string passed in
            let arg = args.as_slice()[2].as_slice();
            let it = arg.split_str("::");
            let p : Vec<&str> = it.collect();

            for m in do_file_search(p.as_slice()[0], &Path::new(".")) {
                if p.len() == 1 {
                    match_fn(m);
                } else {
                    for m in do_external_search(p.slice_from(1), &m.filepath, m.point, racer::SearchType::StartsWith, racer::Namespace::BothNamespaces) {
                        match_fn(m);
                    }
                }
            }
        }
    }
}

#[cfg(not(test))]
fn prefix() {
    let args_ = std::os::args();
    let args = args_.as_slice();
    if args.len() < 5 {
        println!("Provide more arguments!");
        print_usage();
        std::os::set_exit_status(1);
        return;
    }
    let linenum = std::str::from_str(args[2].as_slice()).unwrap();
    let charnum = std::str::from_str(args[3].as_slice()).unwrap();
    let fname = args[4].as_slice();

    // print the start, end, and the identifier prefix being matched
    let path = Path::new(fname);
    let line = getline(&path, linenum);
    let (start, pos) = racer::util::expand_ident(line.as_slice(), charnum);
    println!("PREFIX {},{},{}", start, pos, line.as_slice().slice(start, pos));
}

#[cfg(not(test))]
fn find_definition() {
    let args_ = std::os::args();
    let args = args_.as_slice();
    if args.len() < 5 {
        println!("Provide more arguments!");
        print_usage();
        std::os::set_exit_status(1);
        return;
    }
    let linenum = std::str::from_str(args[2].as_slice()).unwrap();
    let charnum = std::str::from_str(args[3].as_slice()).unwrap();
    let fname = args[4].as_slice();
    let fpath = Path::new(fname);
    let src = racer::load_file(&fpath);
    let pos = scopes::coords_to_point(&*src, linenum, charnum);

    racer::find_definition(&*src, &fpath, pos).map(match_fn);
}

#[cfg(not(test))]
fn print_usage() {
    let program = std::os::args().as_slice()[0].clone();
    println!("usage: {} complete linenum charnum fname", program);
    println!("or:    {} find-definition linenum charnum fname", program);
    println!("or:    {} complete fullyqualifiedname   (e.g. std::io::)",program);
    println!("or:    {} prefix linenum charnum fname",program);
}

#[cfg(not(test))]
fn main() {
    if std::os::getenv("RUST_SRC_PATH").is_none() {
        println!("RUST_SRC_PATH environment variable must be set");
        std::os::set_exit_status(1);
        return;
    }

    let args_ = std::os::args();
    let args = args_.as_slice();

    if args.len() == 1 {
        print_usage();
        std::os::set_exit_status(1);
        return;
    }

    let command = args[1].as_slice();
    match command.as_slice() {
        "prefix" => prefix(),
        "complete" => complete(),
        "find-definition" => find_definition(),
        "help" => print_usage(),
        _ => {
            println!("Sorry, I didn't understand command {}", command );
            print_usage();
            std::os::set_exit_status(1);
            return;
        }
    }
}
<commit_msg>std::str::from_str deprecated, replaced by .parse()<commit_after>#![feature(macro_rules)]
#![feature(phase)]
#[phase(plugin, link)] extern crate log;

extern crate syntax;
extern crate collections;
extern crate core;

#[cfg(not(test))]
use racer::Match;
#[cfg(not(test))]
use racer::util::getline;
#[cfg(not(test))]
use racer::nameres::{do_file_search, do_external_search};
#[cfg(not(test))]
use racer::scopes;

pub mod racer;

#[cfg(not(test))]
fn match_fn(m:Match) {
    let (linenum, charnum) = scopes::point_to_coords2(&m.filepath, m.point).unwrap();
    if m.matchstr.as_slice() == "" {
        panic!("MATCHSTR is empty - waddup?");
    }
    println!("MATCH {},{},{},{},{},{}", m.matchstr,
                                    linenum.to_string(),
                                    charnum.to_string(),
                                    m.filepath.as_str().unwrap(),
                                    m.mtype,
                                    m.contextstr
             );
}

#[cfg(not(test))]
fn complete() {
    let args = std::os::args();
    if args.len() < 3 {
        println!("Provide more arguments!");
        print_usage();
        std::os::set_exit_status(1);
        return;
    }
    match std::os::args().as_slice()[2].as_slice().parse::<uint>() {
        Some(linenum) => {
            // input: linenum, colnum, fname
            if args.len() < 5 {
                println!("Provide more arguments!");
                print_usage();
                std::os::set_exit_status(1);
                return;
            }
            let charnum = std::os::args().as_slice()[3].as_slice().parse::<uint>().unwrap();
            let fname = args.as_slice()[4].as_slice();
            let fpath = Path::new(fname);
            let src = racer::load_file(&fpath);
            let line = getline(&fpath, linenum);
            let (start, pos) = racer::util::expand_ident(line.as_slice(), charnum);
            println!("PREFIX {},{},{}", start, pos, line.as_slice().slice(start, pos));

            let point = scopes::coords_to_point(&*src, linenum, charnum);
            for m in racer::complete_from_file(&*src, &fpath, point) {
                match_fn(m);
            }
        }
        None => {
            // input: a command line string passed in
            let arg = args.as_slice()[2].as_slice();
            let it = arg.split_str("::");
            let p : Vec<&str> = it.collect();

            for m in do_file_search(p.as_slice()[0], &Path::new(".")) {
                if p.len() == 1 {
                    match_fn(m);
                } else {
                    for m in do_external_search(p.slice_from(1), &m.filepath, m.point, racer::SearchType::StartsWith, racer::Namespace::BothNamespaces) {
                        match_fn(m);
                    }
                }
            }
        }
    }
}

#[cfg(not(test))]
fn prefix() {
    let args_ = std::os::args();
    let args = args_.as_slice();
    if args.len() < 5 {
        println!("Provide more arguments!");
        print_usage();
        std::os::set_exit_status(1);
        return;
    }
    let linenum = args[2].as_slice().parse::<uint>().unwrap();
    let charnum = args[3].as_slice().parse::<uint>().unwrap();
    let fname = args[4].as_slice();

    // print the start, end, and the identifier prefix being matched
    let path = Path::new(fname);
    let line = getline(&path, linenum);
    let (start, pos) = racer::util::expand_ident(line.as_slice(), charnum);
    println!("PREFIX {},{},{}", start, pos, line.as_slice().slice(start, pos));
}

#[cfg(not(test))]
fn find_definition() {
    let args_ = std::os::args();
    let args = args_.as_slice();
    if args.len() < 5 {
        println!("Provide more arguments!");
        print_usage();
        std::os::set_exit_status(1);
        return;
    }
    let linenum = args[2].as_slice().parse::<uint>().unwrap();
    let charnum = args[3].as_slice().parse::<uint>().unwrap();
    let fname = args[4].as_slice();
    let fpath = Path::new(fname);
    let src = racer::load_file(&fpath);
    let pos = scopes::coords_to_point(&*src, linenum, charnum);

    racer::find_definition(&*src, &fpath, pos).map(match_fn);
}

#[cfg(not(test))]
fn print_usage() {
    let program = std::os::args().as_slice()[0].clone();
    println!("usage: {} complete linenum charnum fname", program);
    println!("or:    {} find-definition linenum charnum fname", program);
    println!("or:    {} complete fullyqualifiedname   (e.g. std::io::)",program);
    println!("or:    {} prefix linenum charnum fname",program);
}

#[cfg(not(test))]
fn main() {
    if std::os::getenv("RUST_SRC_PATH").is_none() {
        println!("RUST_SRC_PATH environment variable must be set");
        std::os::set_exit_status(1);
        return;
    }

    let args_ = std::os::args();
    let args = args_.as_slice();

    if args.len() == 1 {
        print_usage();
        std::os::set_exit_status(1);
        return;
    }

    let command = args[1].as_slice();
    match command.as_slice() {
        "prefix" => prefix(),
        "complete" => complete(),
        "find-definition" => find_definition(),
        "help" => print_usage(),
        _ => {
            println!("Sorry, I didn't understand command {}", command );
            print_usage();
            std::os::set_exit_status(1);
            return;
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate cgmath;

use std::io::Read;
use std::fs::File;
use std::path::{Path, PathBuf};

use glium::{DisplayBuild, Surface};
use glium::glutin::{Event, ElementState};

use cgmath::{Vector3, Point3};

mod scene;
mod camera;
use camera::Camera;

/// Get the root directory of the project
fn get_project_root() -> PathBuf {
    let exe_dir = std::env::current_exe().unwrap();
    let mut parent_dir = exe_dir.parent().unwrap();
    // This fails if the executable is not in the project tree
    while !parent_dir.ends_with("rusty") {
        parent_dir = parent_dir.parent().unwrap();
    }
    parent_dir.to_path_buf()
}

/// Read a shader found at path
fn read_shader_from_file(shader_path: &Path) -> String {
    let mut file = File::open(shader_path).unwrap();
    let mut shader_src = String::new();
    file.read_to_string(&mut shader_src).unwrap();
    shader_src
}

fn main() {
    let display = glium::glutin::WindowBuilder::new().with_depth_buffer(24).build_glium().unwrap();

    let root_path = get_project_root();
    // TODO: Enable use of arbitrary scene
    let scenes = vec!("scenes/cornell/cornell.obj",
                      "scenes/cornell/cornell_chesterfield.obj",
                      "scenes/cornell-box/CornellBox-Original.obj",
                      "scenes/cornell-box/CornellBox-Glossy.obj",
                      "scenes/cornell-box/CornellBox-Water.obj",
                      "scenes/nanosuit/nanosuit.obj",
                      "scenes/sibenik/sibenik.obj");
    let mut scene = scene::load_scene(&root_path.join(scenes[0]), &display);

    let src_path = root_path.join("src");
    let vertex_shader_src = read_shader_from_file(&src_path.join("vertex.glsl"));
    let fragment_shader_src = read_shader_from_file(&src_path.join("fragment.glsl"));
    let program = glium::Program::from_source(&display, &vertex_shader_src, &fragment_shader_src, None)
        .expect("Failed to create program!");

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

    let mut camera = Camera::new(Point3::from(scene.get_center())
                                 + scene.get_size() * Vector3::new(0.0, 0.0, 1.0f32),
                                 Vector3::new(0.0, 0.0, -1.0f32));

    loop {
        let mut target = display.draw();

        let (width, height) = target.get_dimensions();
        let camera_to_clip = camera.get_camera_to_clip(width, height);
        let world_to_camera = camera.get_world_to_camera();

        target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
        // Draw meshes one at a time
        for mesh in &scene.meshes {
            mesh.draw(&mut target, &program, &params, camera_to_clip * world_to_camera);
        }
        target.finish().unwrap();

        for event in display.poll_events() {
            camera.handle_event(&event);
            match event {
                // Not sure how portable this is
                Event::KeyboardInput(ElementState::Pressed, code @ 2...11, _) => {
                    let i = code as usize - 2;
                    if i < scenes.len() {
                        scene = scene::load_scene(&root_path.join(scenes[i]), &display);
                        camera.set_position(Point3::from(scene.get_center())
                                 + scene.get_size() * Vector3::new(0.0, 0.0, 1.0f32),
                                 Vector3::new(0.0, 0.0, -1.0f32));
                    }
                }
                Event::Closed => return,
                _ => ()
            }
        }
    }
}
<commit_msg>Fix crash when minimizing window<commit_after>#[macro_use]
extern crate glium;
extern crate cgmath;

use std::io::Read;
use std::fs::File;
use std::path::{Path, PathBuf};

use glium::{DisplayBuild, Surface};
use glium::glutin::{Event, ElementState};

use cgmath::{Vector3, Point3};

mod scene;
mod camera;
use camera::Camera;

/// Get the root directory of the project
fn get_project_root() -> PathBuf {
    let exe_dir = std::env::current_exe().unwrap();
    let mut parent_dir = exe_dir.parent().unwrap();
    // This fails if the executable is not in the project tree
    while !parent_dir.ends_with("rusty") {
        parent_dir = parent_dir.parent().unwrap();
    }
    parent_dir.to_path_buf()
}

/// Read a shader found at path
fn read_shader_from_file(shader_path: &Path) -> String {
    let mut file = File::open(shader_path).unwrap();
    let mut shader_src = String::new();
    file.read_to_string(&mut shader_src).unwrap();
    shader_src
}

fn main() {
    let display = glium::glutin::WindowBuilder::new().with_depth_buffer(24).build_glium().unwrap();

    let root_path = get_project_root();
    // TODO: Enable use of arbitrary scene
    let scenes = vec!("scenes/cornell/cornell.obj",
                      "scenes/cornell/cornell_chesterfield.obj",
                      "scenes/cornell-box/CornellBox-Original.obj",
                      "scenes/cornell-box/CornellBox-Glossy.obj",
                      "scenes/cornell-box/CornellBox-Water.obj",
                      "scenes/nanosuit/nanosuit.obj",
                      "scenes/sibenik/sibenik.obj");
    let mut scene = scene::load_scene(&root_path.join(scenes[0]), &display);

    let src_path = root_path.join("src");
    let vertex_shader_src = read_shader_from_file(&src_path.join("vertex.glsl"));
    let fragment_shader_src = read_shader_from_file(&src_path.join("fragment.glsl"));
    let program = glium::Program::from_source(&display, &vertex_shader_src, &fragment_shader_src, None)
        .expect("Failed to create program!");

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

    let mut camera = Camera::new(Point3::from(scene.get_center())
                                 + scene.get_size() * Vector3::new(0.0, 0.0, 1.0f32),
                                 Vector3::new(0.0, 0.0, -1.0f32));

    loop {
        let mut target = display.draw();

        let (width, height) = target.get_dimensions();
        // Don't draw if the window is minimized
        if width != 0 && height != 0 {
            let camera_to_clip = camera.get_camera_to_clip(width, height);
            let world_to_camera = camera.get_world_to_camera();

            target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
            // Draw meshes one at a time
            for mesh in &scene.meshes {
                mesh.draw(&mut target, &program, &params, camera_to_clip * world_to_camera);
            }
        }
        target.finish().unwrap();

        for event in display.poll_events() {
            camera.handle_event(&event);
            match event {
                // Not sure how portable this is
                Event::KeyboardInput(ElementState::Pressed, code @ 2...11, _) => {
                    let i = code as usize - 2;
                    if i < scenes.len() {
                        scene = scene::load_scene(&root_path.join(scenes[i]), &display);
                        camera.set_position(Point3::from(scene.get_center())
                                 + scene.get_size() * Vector3::new(0.0, 0.0, 1.0f32),
                                 Vector3::new(0.0, 0.0, -1.0f32));
                    }
                }
                Event::Closed => return,
                _ => ()
            }
        }
    }
}
<|endoftext|>


<commit_before>// This is so cargo actually considers linking to the fucking manifest,
// since the build scripts' documentation can do the digital equivalent of fucking off
#[cfg(target_os="windows")]
#[link(name="cargo-install-update-manifest", kind="static")]
extern "C" {}

extern crate cargo_update;
extern crate tabwriter;
extern crate regex;

use std::process::{Command, exit};
use std::io::{Write, stdout};
use std::fs::{self, File};
use tabwriter::TabWriter;
use regex::Regex;
use std::env;

fn main() {
    let result = actual_main().err().unwrap_or(0);
    exit(result);
}

fn actual_main() -> Result<(), i32> {
    let opts = cargo_update::Options::parse();

    if cfg!(target_os = "windows") {
        let old_version_r = Regex::new(r"cargo-install-update\.exe-v.+").unwrap();
        for old_version in fs::read_dir(env::current_exe().unwrap().parent().unwrap().canonicalize().unwrap())
            .unwrap()
            .map(Result::unwrap)
            .filter(|f| old_version_r.is_match(&f.file_name().into_string().unwrap())) {
            fs::remove_file(old_version.path()).unwrap();
        }
    }

    let mut packages = cargo_update::ops::installed_main_repo_packages(&opts.cargo_dir.1);

    if !opts.to_update.is_empty() {
        packages = cargo_update::ops::intersect_packages(packages, &opts.to_update);
    }

    {
        // Searching for "" will just update the registry
        let search_res = Command::new("cargo").arg("search").arg("").status().unwrap();
        if !search_res.success() {
            try!(Err(search_res.code().unwrap_or(-1)));
        }
        println!("");
    }

    let registry = cargo_update::ops::get_index_path(&opts.cargo_dir.1);

    for package in &mut packages {
        package.pull_version(&registry);
    }

    {
        let mut out = TabWriter::new(stdout());
        writeln!(out, "Package\tInstalled\tLatest\tNeeds update").unwrap();
        for package in &packages {
            writeln!(out,
                     "{}\tv{}\tv{}\t{}",
                     package.name,
                     package.version,
                     package.newest_version.as_ref().unwrap(),
                     if package.version < *package.newest_version.as_ref().unwrap() {
                         "Yes"
                     } else {
                         "No"
                     })
                .unwrap();
        }
        writeln!(out, "").unwrap();
        out.flush().unwrap();
    }

    if opts.update {
        if !opts.force {
            packages = packages.into_iter().filter(|pkg| pkg.version < *pkg.newest_version.as_ref().unwrap()).collect();
        }

        if !packages.is_empty() {
            for package in &packages {
                println!("Updating {}", package.name);

                if cfg!(target_os = "windows") && package.name == "cargo-update" {
                    let cur_exe = env::current_exe().unwrap();
                    let mut new_exe = cur_exe.clone();

                    new_exe.set_extension(format!("exe-v{}", package.version));
                    fs::rename(&cur_exe, new_exe).unwrap();
                    // This way the past-current exec will be "replaced" we'll get no dupes in .cargo.toml
                    File::create(cur_exe).unwrap();
                }

                let install_res = Command::new("cargo").arg("install").arg("-f").arg(&package.name).status().unwrap();
                if !install_res.success() {
                    try!(Err(install_res.code().unwrap_or(-1)));
                }

                println!("");
            }
        } else {
            println!("No packages need updating.");
        }
    }

    Ok(())
}
<commit_msg>Try to update as many packages as possible before failing<commit_after>// This is so cargo actually considers linking to the fucking manifest,
// since the build scripts' documentation can do the digital equivalent of fucking off
#[cfg(target_os="windows")]
#[link(name="cargo-install-update-manifest", kind="static")]
extern "C" {}

extern crate cargo_update;
extern crate tabwriter;
extern crate regex;

use std::process::{Command, exit};
use std::io::{Write, stdout};
use std::fs::{self, File};
use tabwriter::TabWriter;
use regex::Regex;
use std::env;

fn main() {
    let result = actual_main().err().unwrap_or(0);
    exit(result);
}

fn actual_main() -> Result<(), i32> {
    let opts = cargo_update::Options::parse();

    if cfg!(target_os = "windows") {
        let old_version_r = Regex::new(r"cargo-install-update\.exe-v.+").unwrap();
        for old_version in fs::read_dir(env::current_exe().unwrap().parent().unwrap().canonicalize().unwrap())
            .unwrap()
            .map(Result::unwrap)
            .filter(|f| old_version_r.is_match(&f.file_name().into_string().unwrap())) {
            fs::remove_file(old_version.path()).unwrap();
        }
    }

    let mut packages = cargo_update::ops::installed_main_repo_packages(&opts.cargo_dir.1);

    if !opts.to_update.is_empty() {
        packages = cargo_update::ops::intersect_packages(packages, &opts.to_update);
    }

    {
        // Searching for "" will just update the registry
        let search_res = Command::new("cargo").arg("search").arg("").status().unwrap();
        if !search_res.success() {
            try!(Err(search_res.code().unwrap_or(-1)));
        }
        println!("");
    }

    let registry = cargo_update::ops::get_index_path(&opts.cargo_dir.1);

    for package in &mut packages {
        package.pull_version(&registry);
    }

    {
        let mut out = TabWriter::new(stdout());
        writeln!(out, "Package\tInstalled\tLatest\tNeeds update").unwrap();
        for package in &packages {
            writeln!(out,
                     "{}\tv{}\tv{}\t{}",
                     package.name,
                     package.version,
                     package.newest_version.as_ref().unwrap(),
                     if package.version < *package.newest_version.as_ref().unwrap() {
                         "Yes"
                     } else {
                         "No"
                     })
                .unwrap();
        }
        writeln!(out, "").unwrap();
        out.flush().unwrap();
    }

    if opts.update {
        if !opts.force {
            packages = packages.into_iter().filter(|pkg| pkg.version < *pkg.newest_version.as_ref().unwrap()).collect();
        }

        if !packages.is_empty() {
            let (success_n, errored, result): (usize, Vec<String>, Option<i32>) = packages.into_iter()
                .map(|package| -> Result<(), (i32, String)> {
                    println!("Updating {}", package.name);

                    if cfg!(target_os = "windows") && package.name == "cargo-update" {
                        let cur_exe = env::current_exe().unwrap();
                        let mut new_exe = cur_exe.clone();

                        new_exe.set_extension(format!("exe-v{}", package.version));
                        fs::rename(&cur_exe, new_exe).unwrap();
                        // This way the past-current exec will be "replaced" we'll get no dupes in .cargo.toml
                        File::create(cur_exe).unwrap();
                    }

                    let install_res = Command::new("cargo").arg("install").arg("-f").arg(&package.name).status().unwrap();
                    if !install_res.success() {
                        try!(Err((install_res.code().unwrap_or(-1), package.name)));
                    }

                    println!("");

                    Ok(())
                })
                .collect::<Vec<_>>()
                .into_iter()
                .fold((0, vec![], None), |(s, mut e, r), p| match p {
                    Ok(()) => (s + 1, e, r),
                    Err((pr, pn)) => {
                        e.push(pn);
                        (s, e, r.or(Some(pr)))
                    }
                });

            println!("");
            println!("Updated {} package{}.", success_n, if success_n == 1 { "" } else { "s" });
            if !errored.is_empty() && result.is_some() {
                println!("Failed to update {}.", &errored.iter().fold("".to_string(), |s, e| s + ", " + e)[2..]);
                try!(Err(result.unwrap()));
            }
        } else {
            println!("No packages need updating.");
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>use std::env;
use std::io;
use std::process;
use std::process::Command;
use std::io::Write;
use std::os::unix::process::CommandExt;

mod auth;
use auth::authenticate_current_user_n;
use auth::get_username;

mod settings;
use settings::Settings;

extern crate getopts;
use getopts::Options;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

// Global config
static CONFIG_PATH: &'static str = "/etc/rudo.json";
static DEFAULT_PROMPT: &'static str = "Password: ";

fn print_help(program_name: &str, opts: Options) {
    let brief = format!("Usage: {} [flags] [command]", program_name);
    writeln!(&mut io::stderr(), "{}", opts.usage(&brief))
    .expect("Failed to write to stderr!");
}

fn generate_empty_config() {
    // Create a new settings object
    let new_settings = Settings::new();

    // Get a serialized string representation of the object
    let settings_str = new_settings.to_string()
    .expect("Unable to generate empty settings file!");

    // Output the new settings string to stdout
    println!("{}", settings_str);
}

/**
 * Handles default behavior of program - Authenticate and run a command
 * @param command program to launch
 * @param args arguments to launch the program with
 */
fn run_command(command: &str, args: &Vec<String>) {
    // Load the settings file
    let settings = Settings::from_file(CONFIG_PATH)
    .expect("Unable to read configuration file! Run --genconfig.");

    // Give the user 3 tries to authenticate
    let auth_res = authenticate_current_user_n(&settings, 3);
    if !auth_res {
        process::exit(1);
    }

    // Confirm that user is in the settings file and has permission
    let username: String = get_username();
    let can_run = settings.can_run_command(&username, command);
    if can_run.is_err() {
        writeln!(&mut io::stderr(),
        "You are not in the rudo.json file! This incident won't be reported.")
        .expect("Failed to write to stderr!");
        process::exit(1);
    }
    let can_run = can_run.unwrap();
    if !can_run {
        writeln!(&mut io::stderr(),
        "You don't have permission to run that! This incident won't be reported.")
        .expect("Failed to write to stderr!");
        process::exit(1);
    }

    // Now that the user is authenticated, run the provided command
    // TODO: Allow impersonating users other than root
    Command::new(command).args(args).uid(0).gid(0).exec();

    // If we got here, it means the command failed
    writeln!(&mut io::stderr(), "rudo: {}: command not found", &command)
    .expect("Failed to write to stderr!");
}

/**
 * Handles listing of current user's permissions to STDOUT
 */
fn list_permissions() {
    // Load the settings file
    let settings = Settings::from_file(CONFIG_PATH)
    .expect("Unable to read configuration file! Run --genconfig.");

    // Get this user's User struct
    let username = get_username();
    let user = settings.get_user(&username);
    if user.is_err() {
        writeln!(&mut io::stderr(),
        "You are not in the rudo.json file! This incident won't be reported.")
        .expect("Failed to write to stderr!");
        process::exit(1);
    }
    let user = user.unwrap();

    // Create a string of all commands the user can run
    let mut all_commands: String = String::new();
    for cmd in &user.permissions.allowed_commands {
        all_commands += cmd;
        all_commands += " ";
    }

    println!("You are allowed to run the following commands: {}", all_commands);
    process::exit(0);
}

fn main() {
    let mut args: Vec<String> = env::args().collect();
    let program_name = args[0].clone();
    let mut opts = Options::new();

    // Set up arguments
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("l", "list", "list all permissions for current user");
    opts.optflag("", "genconfig", "Generate an empty config and output to STDOUT");
    if args.len() < 2 {
        print_help(&program_name, opts);
        process::exit(1);
    }
    let matches = match opts.parse(&args[1..2]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    // Handle help
    if matches.opt_present("h") {
        print_help(&program_name, opts);
        process::exit(0);
    }

    // Handle --list
    if matches.opt_present("l") {
        list_permissions();
        process::exit(0);
    }

    // Handle --genconfig
    if matches.opt_present("genconfig") {
        generate_empty_config();
        process::exit(0);
    }

    // Otherwise, handle default behavior (run command)
    let command = &args[1].clone();
    let mut command_args = &mut args[1..].to_vec();
    command_args.remove(0);
    run_command(&command, &command_args);
}
<commit_msg>Add support for impersonating other users with -u<commit_after>use std::env;
use std::io;
use std::process;
use std::process::Command;
use std::io::Write;
use std::os::unix::process::CommandExt;

mod auth;
use auth::authenticate_current_user_n;
use auth::get_username;

mod settings;
use settings::Settings;

extern crate getopts;
use getopts::Options;
use getopts::ParsingStyle;

extern crate users;
use users::get_user_by_name;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

// Global config
static CONFIG_PATH: &'static str = "/etc/rudo.json";
static DEFAULT_PROMPT: &'static str = "Password: ";

fn print_help(program_name: &str, opts: Options) {
    let brief = format!("Usage: {} [flags] [command]", program_name);
    writeln!(&mut io::stderr(), "{}", opts.usage(&brief))
    .expect("Failed to write to stderr!");
}

fn generate_empty_config() {
    // Create a new settings object
    let new_settings = Settings::new();

    // Get a serialized string representation of the object
    let settings_str = new_settings.to_string()
    .expect("Unable to generate empty settings file!");

    // Output the new settings string to stdout
    println!("{}", settings_str);
}

/**
* Handles listing of current user's permissions to STDOUT
*/
fn list_permissions() {
    // Load the settings file
    let settings = Settings::from_file(CONFIG_PATH)
    .expect("Unable to read configuration file! Run --genconfig.");

    // Get this user's User struct
    let username = get_username();
    let user = settings.get_user(&username);
    if user.is_err() {
        writeln!(&mut io::stderr(),
        "You are not in the rudo.json file! This incident won't be reported.")
        .expect("Failed to write to stderr!");
        process::exit(1);
    }
    let user = user.unwrap();

    // Create a string of all commands the user can run
    let mut all_commands: String = String::new();
    for cmd in &user.permissions.allowed_commands {
        all_commands += cmd;
        all_commands += " ";
    }

    println!("You are allowed to run the following commands: {}", all_commands);
    process::exit(0);
}

/**
 * Handles default behavior of program - Authenticate and run a command
 * @param user user to run command as
 * @param command program to launch
 * @param args arguments to launch the program with
 */
fn run_command(user: Option<String>, command: &str, args: &Vec<String>) {
    // Load the settings file
    let settings = Settings::from_file(CONFIG_PATH)
    .expect("Unable to read configuration file! Run --genconfig.");

    // Give the user 3 tries to authenticate
    let auth_res = authenticate_current_user_n(&settings, 3);
    if !auth_res {
        process::exit(1);
    }

    // Confirm that user is in the settings file and has permission
    let username: String = get_username();
    let can_run = settings.can_run_command(&username, command);
    if can_run.is_err() {
        writeln!(&mut io::stderr(),
        "You are not in the rudo.json file! This incident won't be reported.")
        .expect("Failed to write to stderr!");
        process::exit(1);
    }
    let can_run = can_run.unwrap();
    if !can_run {
        writeln!(&mut io::stderr(),
        "You don't have permission to run that! This incident won't be reported.")
        .expect("Failed to write to stderr!");
        process::exit(1);
    }

    // Determine the uid of the user to impersonate
    let mut uid: u32 = 0;
    if let Some(username) = user {
        let u = get_user_by_name(&username);
        if u.is_none() {
            writeln!(&mut io::stderr(),
            "Invalid username! See --help for more information.")
            .expect("Failed to write to stderr!");
            process::exit(1);
        }
        uid = u.unwrap().uid();
    }

    // Now that the user is authenticated, run the provided command
    // TODO: Allow impersonating groups other than wheel
    Command::new(command).args(args).uid(uid).gid(0).exec();

    // If we got here, it means the command failed
    writeln!(&mut io::stderr(), "rudo: {}: command not found", &command)
    .expect("Failed to write to stderr!");
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program_name = args[0].clone();
    let mut opts = Options::new();
    opts.parsing_style(ParsingStyle::StopAtFirstFree);

    let mut user: Option<String> = None;

    // Set up arguments
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("l", "list", "list all permissions for current user");
    opts.optopt("u", "user", "run as the specified user", "<user>");
    opts.optflag("", "genconfig", "Generate an empty config and output to STDOUT");

    // Create a vec of up to 2 arguments to parse
    // We ignore all arguments past the first
    let mut matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(_) => { print_help(&program_name, opts); process::exit(1); }
    };

    if matches.free.len() < 1 {
        print_help(&program_name, opts);
        process::exit(1);
    }

    // Handle help
    if matches.opt_present("h") {
        print_help(&program_name, opts);
        process::exit(0);
    }

    // Handle --list
    if matches.opt_present("l") {
        list_permissions();
        process::exit(0);
    }

    // Handle --user
    if matches.opt_present("u") {
        // Set the user to the provided user
        user = match matches.opt_str("u") {
            Some(x) => Some(x),
            None => { print_help(&program_name, opts); process::exit(1); }
        };
    }

    // Handle --genconfig
    if matches.opt_present("genconfig") {
        generate_empty_config();
        process::exit(0);
    }

    // Handle default behavior (run command)
    let command = matches.free[0].clone();
    let mut command_args = &mut matches.free[0..].to_vec();
    command_args.remove(0);
    run_command(user, &command, &command_args);
}
<|endoftext|>


<commit_before>extern crate piston_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;

mod drawing;
mod game;
mod models;
mod traits;

use piston_window::{Button, Event, Events, EventLoop, Input, Motion, OpenGL, PistonWindow,
    WindowSettings};
use opengl_graphics::GlGraphics;

use game::Game;

fn main() {
    let opengl = OpenGL::V3_2;

    let mut game = Game::new(drawing::Size::new(1024.0, 600.0));

    let mut window: PistonWindow = WindowSettings::new("Rocket!", [1024, 600])
        .opengl(opengl).samples(8).exit_on_esc(true).build().unwrap();

    window.set_ups(60);
    window.set_max_fps(60);

    let mut gl = GlGraphics::new(opengl);

    let mut events = window.events();

    while let Some(e) = events.next(&mut window) {
        // Event handling
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Input(Input::Press(Button::Controller(button))) => {
                game.button_press(button);
            }

            Event::Input(Input::Release(Button::Controller(button))) => {
                game.button_release(button);
            }

            // Controller Axis are Move Input types
            Event::Input(Input::Move(Motion::ControllerAxis(axis))) => {
                game.handle_axis(axis);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }
}
<commit_msg>Simplify event loop logic.<commit_after>extern crate piston_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;

mod drawing;
mod game;
mod models;
mod traits;

use piston_window::{Button, Event, EventLoop, Input, Motion, OpenGL, PistonWindow,
    WindowSettings};
use opengl_graphics::GlGraphics;

use game::Game;

fn main() {
    let opengl = OpenGL::V3_2;

    let mut game = Game::new(drawing::Size::new(1024.0, 600.0));

    let mut window: PistonWindow = WindowSettings::new("Rocket!", [1024, 600])
        .opengl(opengl).samples(8).exit_on_esc(true).build().unwrap();

    window.set_ups(60);
    window.set_max_fps(60);

    let mut gl = GlGraphics::new(opengl);

    while let Some(e) = window.next() {
        // Event handling
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Input(Input::Press(Button::Controller(button))) => {
                game.button_press(button);
            }

            Event::Input(Input::Release(Button::Controller(button))) => {
                game.button_release(button);
            }

            // Controller Axis are Move Input types
            Event::Input(Input::Move(Motion::ControllerAxis(axis))) => {
                game.handle_axis(axis);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>//*****************************
// Output to MELO format

extern crate classreader;

use codecity::{MeasureMeta, MusicMeta};
use midi_file::core::{Channel, Clocks, DurationName, GeneralMidi, NoteNumber, Velocity};
use midi_file::file::{QuartersPerMinute, Track};
use midi_file::MidiFile;
use std::cmp::{min, max};
use std::fs::File;
use std::io::prelude::*;

// durations
const QUARTER: u32 = 1024;
const EIGHTH: u32 = QUARTER / 2;
const WHOLE: u32 = QUARTER * 4;
const DOTTED_QUARTER: u32 = QUARTER + EIGHTH;

// pitches
const C4: NoteNumber = NoteNumber::new(72);
const D4: NoteNumber = NoteNumber::new(74);
const E4: NoteNumber = NoteNumber::new(76);

// some arbitrary velocity
const V: Velocity = Velocity::new(64);

// channel zero (displayed as channel 1 in any sequencer UI)
const CH: Channel = Channel::new(0);

pub fn write_to_file(path: &String, music: &Vec<MusicMeta>) {
    let mut mfile = MidiFile::new();

    // set up track metadata
    let mut track = Track::default();
    track.set_name("Singer").unwrap();
    track.set_instrument_name("The Java Code").unwrap();
    track.set_general_midi(CH, GeneralMidi::Oboe).unwrap();

    // set time signature and tempo
    track
        .push_time_signature(0, 6, DurationName::Eighth, Clocks::Quarter)
        .unwrap();
    track.push_tempo(0, QuartersPerMinute::new(116)).unwrap();

    for c in music {
        for (i, m) in c.methods().iter().enumerate() {
            render_chord(&mut track, m, i%3);
        }
    }

    // finish and write the file ///////////////////////////////////////////////////////////////////

    // add the track to the file
    mfile.push_track(track).unwrap();

    mfile.save(path).unwrap();
}

fn render_chord(track: &mut Track, m: &MeasureMeta, finger: usize) {
    if m.lines == 0 {return;}
    let note = get_tone( m.size, finger);
    let duration = max(min((m.lines as u32)*32, WHOLE), EIGHTH);
    track.push_lyric(0, format!("{}\n", m.name)).unwrap();
    track
        .push_note_on(0, CH, note, Velocity::new((max(60, m.complexity)) as u8))
        .unwrap();
    // the note-off event determines the duration of the note
    track
        .push_note_off(duration, CH, note, Velocity::new(m.size as u8))
        .unwrap();
}

fn get_tone(size: usize, offset: usize) -> NoteNumber {
    let i = 40 + min(128, size)/4 + offset*8;
    NoteNumber::new(i as u8)
}

//*****************************
// Unit tests
<commit_msg>Remove the unused lines<commit_after>//*****************************
// Output to MELO format

extern crate classreader;

use codecity::{MeasureMeta, MusicMeta};
use midi_file::core::{Channel, Clocks, DurationName, GeneralMidi, NoteNumber, Velocity};
use midi_file::file::{QuartersPerMinute, Track};
use midi_file::MidiFile;
use std::cmp::{min, max};

// durations
const QUARTER: u32 = 1024;
const EIGHTH: u32 = QUARTER / 2;
const WHOLE: u32 = QUARTER * 4;

// channel zero (displayed as channel 1 in any sequencer UI)
const CH: Channel = Channel::new(0);

pub fn write_to_file(path: &String, music: &Vec<MusicMeta>) {
    let mut mfile = MidiFile::new();

    // set up track metadata
    let mut track = Track::default();
    track.set_name("Singer").unwrap();
    track.set_instrument_name("The Java Code").unwrap();
    track.set_general_midi(CH, GeneralMidi::Oboe).unwrap();

    // set time signature and tempo
    track
        .push_time_signature(0, 6, DurationName::Eighth, Clocks::Quarter)
        .unwrap();
    track.push_tempo(0, QuartersPerMinute::new(116)).unwrap();

    for c in music {
        for (i, m) in c.methods().iter().enumerate() {
            render_chord(&mut track, m, i%3);
        }
    }

    // finish and write the file ///////////////////////////////////////////////////////////////////

    // add the track to the file
    mfile.push_track(track).unwrap();

    mfile.save(path).unwrap();
}

fn render_chord(track: &mut Track, m: &MeasureMeta, finger: usize) {
    if m.lines == 0 {return;}
    let note = get_tone( m.size, finger);
    let duration = max(min((m.lines as u32)*32, WHOLE), EIGHTH);
    track.push_lyric(0, format!("{}\n", m.name)).unwrap();
    track
        .push_note_on(0, CH, note, Velocity::new((max(60, m.complexity)) as u8))
        .unwrap();
    // the note-off event determines the duration of the note
    track
        .push_note_off(duration, CH, note, Velocity::new(m.size as u8))
        .unwrap();
}

fn get_tone(size: usize, offset: usize) -> NoteNumber {
    let i = 40 + min(128, size)/4 + offset*8;
    NoteNumber::new(i as u8)
}

//*****************************
// Unit tests
<|endoftext|>


<commit_before>/**
Katy Williamson kcw4sn
Ben Terner bt3ze
@virginia.edu

Final Project for CS4414 - Operating Systems
A parallel MST implementation on images in Rust

*/

/*
some documentation:
Pixel object is composed of r,g,b values, a color, and an x,y index that takes the place of its adjacency list
Point is just an (x,y) value to denote a pixel's location
Edge contains two points: source and dest, along with the edge cost between them

*/

extern mod extra;
use std::{os, num,hashmap} ;
use extra::{arc,priority_queue};

struct Pixel{
    r: int,
    b: int,
    g: int,
    color: int,
    x: int,
    y: int
}

impl Pixel {
    fn new(red: int, blue: int, green: int, x: int, y: int) -> Pixel {
        Pixel{
            r: red,
            b: blue,
            g: green,
            color: -1,
            x: x,
            y: y
        }
    }
}

impl Clone for Pixel{
    fn clone(&self) -> Pixel {
        Pixel{
            r: self.r,
            b: self.b,
            g: self.g,
            color: self.color,
            x: self.x,
            y: self.y
        }
    }
}

struct Point {
    x: int,
    y: int
}

impl Point{
    fn new(x: int, y: int)-> Point {
        Point {
            x: x,
            y: y
        }
    }
}

struct Edge {
    source: Point,
    dest: Point,
    cost: float
}

impl Edge {
    fn new(s: Point, d: Point, cost: float) -> Edge {
        Edge {
            source: s,
            dest: d,
            cost: cost
        }
    }
}

impl Ord for Edge {
    fn lt(&self, other: &Edge) -> bool {
        self.cost < other.cost
    }
}

fn edgeCost(a: &Pixel, b: &Pixel) -> float {
    num::sqrt( (
            a.r*a.r-b.r*b.r + a.g*a.g-b.g*b.g + a.b*a.b-b.b*b.b ) as float)
}

fn readImage( filename: &~str) -> ~ [ ~[Pixel]] {
    ~[~[]]
}

fn main(){
    let argv =  os::args();
    println(argv.to_str());

    let pixels: ~[ ~[Pixel] ] = readImage(&argv[1]);

    // width and height should be replaced by just reading them from the file
    let width = match from_str::<int>(argv[2]) {
        Some(x) => x,
        None() => 0
    };
    let height = match from_str::<int>(argv[3]) {
        Some(x) => x,
        None() => 0
    };

    let mut find_arcs: ~[ ~[arc::RWArc<Pixel>] ] =  ~[ ~[]];
    let mut heit = 0;
    let mut wid = 0;
    loop {
        loop {
            find_arcs[heit][wid] = arc::RWArc::new(pixels[heit][wid]);
                wid+=1;
            if(wid == width) {
                wid = 0;
                break;
            }
        }
        heit+=1;
        if(heit == height) {
            break;
        }
    }

    let arcs = find_arcs; // now we have an immutable array that can be shared

    let corners = [ (0,0),(0,width-1),(height-1,0),(height-1,width-1) ];

    for &corner in corners.iter() {
        let (a,b) = corner;
        let shared_arcs = arcs.clone();
        let shared_pixels = pixels.clone();
        do spawn { // split into threads here

            let mut x=a;
            let mut y=b;

            let mut queue: priority_queue::PriorityQueue<Edge> =  priority_queue::PriorityQueue::new();
            let mut visited: hashmap::HashMap<(int,int),bool> = hashmap::HashMap::new();

            let mut newvisit: bool = true;

            loop { // iterate through items in the queue, which contains all of the edges/vertices
                if(newvisit){
                    let neighbors = [ (x,y-1),(x+1,y), (x,y+1), (x,y-1)];
                    for &coord in neighbors.iter() {
                        let (w,z) = coord;
                        if w >=0 && w < width && z >=0 && z < height { // bounds checking
                            // if neighbor at coord has not been or colored
                            let mut col = 0;
                            let mut newvertex = false;
                            do shared_arcs[w][z].write |dest| {
                                if dest.color < 0 {
                                    do shared_arcs[x][y].read |src| {
                                        dest.color = src.color;
                                    }
                                    newvertex = true;
                                }
                            }

                            if newvertex { // then we have a new vertex
                                queue.push( Edge::new(Point::new(x,y),Point::new(w,z),edgeCost(&shared_pixels[x][y],&shared_pixels[w][z])));
                            }
                        }
                    }
                }

                let edge = queue.maybe_pop();
                match edge {
                Some(e) => {
                        let mut col = 0;
                        do shared_arcs[e.dest.x][e.dest.y].read |dest| {
                        col = dest.color;
                        }
                        if col < 0 {
                            // not in any tree
                            let coord = (e.dest.x,e.dest.y);
                            if *visited.get(&coord) == false { // use visited hashmap to figure out if we're at a new vertex
                                visited.insert(coord,true);
                                x = e.dest.x;
                                y = e.dest.y;
                                newvisit = true;
                            } else {
                                newvisit = false;
                            }
                        }
                    }
                    None => { break; } // this should execute at the end when there are no more unvisited or uncolored nodes for a thread
                }
            }
        }
    }
}
<commit_msg>we're just really arc-happy.<commit_after>/**
Katy Williamson kcw4sn
Ben Terner bt3ze
@virginia.edu

Final Project for CS4414 - Operating Systems
A parallel MST implementation on images in Rust

*/

/*
some documentation:
Pixel object is composed of r,g,b values, a color, and an x,y index that takes the place of its adjacency list
Point is just an (x,y) value to denote a pixel's location
Edge contains two points: source and dest, along with the edge cost between them

*/

extern mod extra;
use std::{os, num,hashmap} ;
use extra::{arc,priority_queue};

struct Pixel{
    r: int,
    b: int,
    g: int,
    color: int,
    x: int,
    y: int
}

impl Pixel {
    fn new(red: int, blue: int, green: int, x: int, y: int) -> Pixel {
        Pixel{
            r: red,
            b: blue,
            g: green,
            color: -1,
            x: x,
            y: y
        }
    }
}

impl Clone for Pixel{
    fn clone(&self) -> Pixel {
        Pixel{
            r: self.r,
            b: self.b,
            g: self.g,
            color: self.color,
            x: self.x,
            y: self.y
        }
    }
}

struct Point {
    x: int,
    y: int
}

impl Point{
    fn new(x: int, y: int)-> Point {
        Point {
            x: x,
            y: y
        }
    }
}

struct Edge {
    source: Point,
    dest: Point,
    cost: float
}

impl Edge {
    fn new(s: Point, d: Point, cost: float) -> Edge {
        Edge {
            source: s,
            dest: d,
            cost: cost
        }
    }
}

impl Ord for Edge {
    fn lt(&self, other: &Edge) -> bool {
        self.cost < other.cost
    }
}

fn edgeCost(a: &Pixel, b: &Pixel) -> float {
    num::sqrt( (
            a.r*a.r-b.r*b.r + a.g*a.g-b.g*b.g + a.b*a.b-b.b*b.b ) as float)
}

fn readImage( filename: &~str) -> ~ [ ~[Pixel]] {
    ~[~[]]
}

fn main(){
    let argv =  os::args();
    println(argv.to_str());

    let pixels: ~[ ~[Pixel] ] = readImage(&argv[1]);

    // width and height should be replaced by just reading them from the file
    let width = match from_str::<int>(argv[2]) {
        Some(x) => x,
        None() => 0
    };
    let height = match from_str::<int>(argv[3]) {
        Some(x) => x,
        None() => 0
    };

    let mut find_arcs: ~[ ~[arc::RWArc<Pixel>] ] =  ~[ ~[]];
    let mut heit = 0;
    let mut wid = 0;
    loop {
        loop {
            find_arcs[heit][wid] = arc::RWArc::new(pixels[heit][wid]);
                wid+=1;
            if(wid == width) {
                wid = 0;
                break;
            }
        }
        heit+=1;
        if(heit == height) {
            break;
        }
    }

    let arcs = find_arcs; // now we have an immutable array that can be shared

    let corners = [ (0,0),(0,width-1),(height-1,0),(height-1,width-1) ];

    for &corner in corners.iter() {
        let (a,b) = corner;
        let shared_arcs = arcs.clone();
        do spawn { // split into threads here

            let mut x=a;
            let mut y=b;
            /*
            weird compiler error:
            let corners = [ (0,0),(0,width-1),(height-1,0),(height-1,width-1) ];
            for &corner in corners.iter(){
            do spawn {
            let mut x = 0;
            let mut y = 0;
            (x,y) = corner
                 }
             }
             */

            let mut queue: priority_queue::PriorityQueue<Edge> =  priority_queue::PriorityQueue::new();
            let mut visited: hashmap::HashMap<(int,int),bool> = hashmap::HashMap::new();

            let mut newvisit: bool = true;

            loop { // iterate through items in the queue, which contains all of the edges/vertices
                if(newvisit){
                    let neighbors = [ (x,y-1),(x+1,y), (x,y+1), (x,y-1)];
                    for &coord in neighbors.iter() {
                        let (w,z) = coord;
                        if w >=0 && w < width && z >=0 && z < height { // bounds checking
                            // if neighbor at coord has not been or colored
                            let mut newvertex = false;
                            let mut uncolored = false;
                            do shared_arcs[w][z].read |dest| {
                                if dest.color < 0 {
                                    uncolored = true; }
                            }
                            if uncolored {
                                do shared_arcs[w][z].write |dest| {
                                    if dest.color < 0 {
                                        do shared_arcs[x][y].read |src| {
                                            dest.color = src.color;
                                        }
                                        newvertex = true;
                                    }
                                }
                            }
                            if newvertex { // then we have a new vertex
                                do shared_arcs[x][y].read |src| {
                                    do shared_arcs[w][z].read |dest| {
                                        queue.push( Edge::new(Point::new(x,y),Point::new(w,z),edgeCost(src,dest)));
                                    }
                                }
                            }
                        }
                    }
                }

                let edge = queue.maybe_pop();
                match edge {
                Some(e) => {
                        let mut col = 0;
                        do shared_arcs[e.dest.x][e.dest.y].read |dest| {
                        col = dest.color;
                        }
                        if col < 0 {
                            // not in any tree
                            let coord = (e.dest.x,e.dest.y);
                            if *visited.get(&coord) == false { // use visited hashmap to figure out if we're at a new vertex
                                visited.insert(coord,true);
                                x = e.dest.x;
                                y = e.dest.y;
                                newvisit = true;
                            } else {
                                newvisit = false;
                            }
                        }
                    }
                    None => { break; } // this should execute at the end when there are no more unvisited or uncolored nodes for a thread
                }
            }
        }
    }
}
<|endoftext|>