1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use ron;
#[macro_use]
extern crate maplit;

#[macro_use]
extern crate quicli;

// use quicli::prelude::*;
use colored::Colorize;
use crossbeam_channel::{
    unbounded,
    Receiver,
};
use edit_client::{
    client::ClientDoc,
    log::*,
    proxy::ProxyClientController,
    Client,
    ClientController,
};
use edit_common::commands::*;
use failure::Error;
use std::cell::RefCell;
use std::io::prelude::*;
use std::rc::Rc;
use std::sync::{
    atomic::AtomicBool,
    Arc,
};
use structopt::StructOpt;

fn init_new_client(
    client_id: &str,
) -> (
    ProxyClientController,
    Receiver<FrontendCommand>,
    Receiver<ServerCommand>,
) {
    let (tx_client, rx_client) = unbounded();
    let (tx_sync, rx_sync) = unbounded();
    let client = ProxyClientController {
        state: Rc::new(RefCell::new(Client {
            client_doc: ClientDoc::new(client_id.to_owned()),
            last_controls: None,
            last_caret_state: None,

            monkey: Arc::new(AtomicBool::new(false)),
            alive: Arc::new(AtomicBool::new(true)),
            task_count: 0,
        })),

        tx_client,
        tx_sync,
    };
    (client, rx_client, rx_sync)
}

#[derive(StructOpt)]
struct Opt {
    #[structopt(long = "filter")]
    filter: Option<String>,
}

main!(|opts: Opt| {
    let (tx_line, rx_line) = unbounded();
    ::std::thread::spawn(move || -> Result<(), Error> {
        // let f = ::std::fs::File::open("../logs/client")?;
        // let file = ::std::io::BufReader::new(&*f);
        let file = ::std::io::stdin();

        for line in file.lock().lines() {
            if let Ok(line) = line {
                if line.trim().len() != 0 {
                    let hi: LogWasm = ron::de::from_str(&line)?;
                    tx_line.send(hi);
                }
            }
        }

        Ok(())
    });

    let mut clients = hashmap![];

    let mut i = 0;

    if let Some(ref filter_id) = opts.filter {
        println!("\n!!! Using filter {:?}\n", filter_id);
    }

    while let Some(hi) = rx_line.recv() {
        i += 1;
        println!("TASK ~~~~ {:?} ~~~~", i);
        match hi {
            LogWasm::Setup(client_id) => {
                clients.insert(client_id.clone(), init_new_client(&client_id));
            }
            LogWasm::Task(client_id, task) => {
                // TODO real command-line subfilters
                // if let Some(ref filter_id) = opts.filter {
                //     if client_id != *filter_id {
                //         continue;
                //     }
                // }

                println!("{}", format!("{:?}: {:?}", client_id, task).green().bold());
                println!();
                match clients.get_mut(&client_id) {
                    Some(&mut (ref mut client, _, _)) => {
                        client.handle_task(task)?;
                    }
                    None => {
                        panic!("Client {:?} was not set up.", client_id);
                    }
                }
            }
            _ => {}
        }
    }

    eprintln!();
    eprintln!("(edit-replay is done.)");
});