<commit_before>use std::{io::Cursor, path::Path};

use rocksdb::{
    merge_operator::MergeFn, BlockBasedIndexType, BlockBasedOptions, ColumnFamily,
    ColumnFamilyDescriptor, DBWithThreadMode, IteratorMode, MergeOperands, Options, ReadOptions,
    SliceTransform, WriteBatch, DB,
};

use crate::model::{
    GameId, GameInfo, Key, KeyPrefix, MasterEntry, MasterGame, Month, PersonalEntry,
    PersonalStatus, UserId, Year,
};

#[derive(Debug)]
pub struct Database {
    inner: DB,
}

fn column_family(
    name: &str,
    merge: Option<&str>,
    merge_fn: impl MergeFn + Clone,
    prefix: Option<usize>,
    block_size: usize,
    bloom_filter: i32,
) -> ColumnFamilyDescriptor {
    let mut opts = Options::default();
    if let Some(merge) = merge {
        opts.set_merge_operator_associative(merge, merge_fn);
    }
    opts.set_prefix_extractor(match prefix {
        Some(prefix) => SliceTransform::create_fixed_prefix(prefix),
        None => SliceTransform::create_noop(),
    });
    let mut block_opts = BlockBasedOptions::default();
    block_opts.set_index_type(BlockBasedIndexType::HashSearch);
    block_opts.set_block_size(block_size);
    if bloom_filter > 0 {
        block_opts.set_bloom_filter(bloom_filter, true);
    }
    opts.set_block_based_table_factory(&block_opts);
    ColumnFamilyDescriptor::new(name, opts)
}

impl Database {
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Database, rocksdb::Error> {
        let mut db_opts = Options::default();
        db_opts.create_if_missing(true);
        db_opts.create_missing_column_families(true);

        let inner = DBWithThreadMode::open_cf_descriptors(
            &db_opts,
            path,
            vec![
                column_family(
                    "personal",
                    Some("personal merge"),
                    personal_merge,
                    Some(KeyPrefix::SIZE),
                    4 * 1024,
                    8,
                ),
                column_family("game", Some("game merge"), game_merge, None, 1024, 0),
                column_family("player", None, void_merge, None, 1024, 0),
                column_family(
                    "master",
                    Some("master merge"),
                    master_merge,
                    Some(KeyPrefix::SIZE),
                    4 * 1024,
                    8,
                ),
                column_family("master_game", None, void_merge, None, 4 * 1024, 0),
            ],
        )?;

        Ok(Database { inner })
    }

    pub fn queryable(&self) -> QueryableDatabase<'_> {
        QueryableDatabase {
            db: &self.inner,
            cf_personal: self.inner.cf_handle("personal").expect("cf personal"),
            cf_game: self.inner.cf_handle("game").expect("cf game"),
            cf_player: self.inner.cf_handle("player").expect("cf player"),
            cf_master: self.inner.cf_handle("master").expect("cf master"),
            cf_master_game: self.inner.cf_handle("master_game").expect("cf master_game"),
        }
    }
}

pub struct QueryableDatabase<'a> {
    db: &'a DB,
    cf_personal: &'a ColumnFamily,
    cf_game: &'a ColumnFamily,
    cf_player: &'a ColumnFamily,
    cf_master: &'a ColumnFamily,
    cf_master_game: &'a ColumnFamily,
}

impl QueryableDatabase<'_> {
    pub fn db_property(&self, name: &str) -> Result<Option<String>, rocksdb::Error> {
        self.db.property_value(name)
    }

    pub fn game_property(&self, name: &str) -> Result<Option<String>, rocksdb::Error> {
        self.db.property_value_cf(self.cf_game, name)
    }

    pub fn personal_property(&self, name: &str) -> Result<Option<String>, rocksdb::Error> {
        self.db.property_value_cf(self.cf_personal, name)
    }

    pub fn get_game_info(&self, id: GameId) -> Result<Option<GameInfo>, rocksdb::Error> {
        Ok(self.db.get_cf(self.cf_game, id.to_bytes())?.map(|buf| {
            let mut cursor = Cursor::new(buf);
            GameInfo::read(&mut cursor).expect("deserialize game info")
        }))
    }

    pub fn get_personal(
        &self,
        key: &KeyPrefix,
        since: Month,
        until: Month,
    ) -> Result<PersonalEntry, rocksdb::Error> {
        let mut opt = ReadOptions::default();
        opt.set_prefix_same_as_start(true);
        opt.set_iterate_lower_bound(key.with_month(since).into_bytes());
        opt.set_iterate_upper_bound(key.with_month(until.add_months_saturating(1)).into_bytes());

        let iterator = self
            .db
            .iterator_cf_opt(self.cf_personal, opt, IteratorMode::Start);

        let mut entry = PersonalEntry::default();
        for (_key, value) in iterator {
            let mut cursor = Cursor::new(value);
            entry
                .extend_from_reader(&mut cursor)
                .expect("deserialize personal entry");
        }

        Ok(entry)
    }

    pub fn get_player_status(&self, id: &UserId) -> Result<Option<PersonalStatus>, rocksdb::Error> {
        Ok(self.db.get_cf(self.cf_player, id.as_str())?.map(|buf| {
            let mut cursor = Cursor::new(buf);
            PersonalStatus::read(&mut cursor).expect("deserialize status")
        }))
    }

    pub fn put_player_status(
        &self,
        id: &UserId,
        status: &PersonalStatus,
    ) -> Result<(), rocksdb::Error> {
        let mut cursor = Cursor::new(Vec::with_capacity(PersonalStatus::SIZE_HINT));
        status.write(&mut cursor).expect("serialize status");
        self.db
            .put_cf(self.cf_player, id.as_str(), cursor.into_inner())
    }

    pub fn has_master_game(&self, id: GameId) -> Result<bool, rocksdb::Error> {
        self.db
            .get_cf(self.cf_master_game, id.to_bytes())
            .map(|maybe_entry| maybe_entry.is_some())
    }

    pub fn get_master_game(&self, id: GameId) -> Result<Option<MasterGame>, rocksdb::Error> {
        Ok(self
            .db
            .get_cf(self.cf_master_game, id.to_bytes())?
            .map(|buf| serde_json::from_slice(&buf).expect("deserialize master game")))
    }

    pub fn has_master(&self, key: Key) -> Result<bool, rocksdb::Error> {
        self.db
            .get_cf(self.cf_master, key.into_bytes())
            .map(|maybe_entry| maybe_entry.is_some())
    }

    pub fn get_master(
        &self,
        key: KeyPrefix,
        since: Year,
        until: Year,
    ) -> Result<MasterEntry, rocksdb::Error> {
        let mut opt = ReadOptions::default();
        opt.set_prefix_same_as_start(true);
        opt.set_iterate_lower_bound(key.with_year(since).into_bytes());
        opt.set_iterate_upper_bound(key.with_year(until.add_years_saturating(1)).into_bytes());

        let iterator = self
            .db
            .iterator_cf_opt(self.cf_master, opt, IteratorMode::Start);

        let mut entry = MasterEntry::default();
        for (_key, value) in iterator {
            let mut cursor = Cursor::new(value);
            entry
                .extend_from_reader(&mut cursor)
                .expect("deserialize master entry");
        }

        Ok(entry)
    }

    pub fn batch(&self) -> Batch<'_> {
        Batch {
            queryable: self,
            batch: WriteBatch::default(),
        }
    }
}

pub struct Batch<'a> {
    queryable: &'a QueryableDatabase<'a>,
    batch: WriteBatch,
}

impl Batch<'_> {
    pub fn merge_personal(&mut self, key: Key, entry: PersonalEntry) {
        let mut cursor = Cursor::new(Vec::with_capacity(PersonalEntry::SIZE_HINT));
        entry.write(&mut cursor).expect("serialize personal entry");
        self.batch.merge_cf(
            self.queryable.cf_personal,
            key.into_bytes(),
            cursor.into_inner(),
        );
    }

    pub fn merge_game_info(&mut self, id: GameId, info: GameInfo) {
        let mut cursor = Cursor::new(Vec::with_capacity(GameInfo::SIZE_HINT));
        info.write(&mut cursor).expect("serialize game info");
        self.batch
            .merge_cf(self.queryable.cf_game, id.to_bytes(), cursor.into_inner());
    }

    pub fn merge_master(&mut self, key: Key, entry: MasterEntry) {
        let mut cursor = Cursor::new(Vec::with_capacity(MasterEntry::SIZE_HINT));
        entry.write(&mut cursor).expect("serialize master entry");
        self.batch.merge_cf(
            self.queryable.cf_master,
            key.into_bytes(),
            cursor.into_inner(),
        );
    }

    pub fn put_master_game(&mut self, id: GameId, game: &MasterGame) {
        self.batch.put_cf(
            self.queryable.cf_master_game,
            id.to_bytes(),
            serde_json::to_vec(game).expect("serialize master game"),
        );
    }

    pub fn write(self) -> Result<(), rocksdb::Error> {
        self.queryable.db.write(self.batch)
    }
}

fn game_merge(
    _key: &[u8],
    existing: Option<&[u8]>,
    operands: &mut MergeOperands,
) -> Option<Vec<u8>> {
    // Take latest game info, but merge index status.
    let mut info: Option<GameInfo> = None;
    let mut size_hint = 0;
    for op in existing.into_iter().chain(operands.into_iter()) {
        let mut cursor = Cursor::new(op);
        let mut new_info = GameInfo::read(&mut cursor).expect("read for game merge");
        if let Some(old_info) = info {
            new_info.indexed.white |= old_info.indexed.white;
            new_info.indexed.black |= old_info.indexed.black;
        }
        info = Some(new_info);
        size_hint = op.len();
    }
    info.map(|info| {
        let mut cursor = Cursor::new(Vec::with_capacity(size_hint));
        info.write(&mut cursor).expect("write game");
        cursor.into_inner()
    })
}

fn personal_merge(
    _key: &[u8],
    existing: Option<&[u8]>,
    operands: &mut MergeOperands,
) -> Option<Vec<u8>> {
    let mut entry = PersonalEntry::default();
    let mut size_hint = 0;
    for op in existing.into_iter().chain(operands.into_iter()) {
        let mut cursor = Cursor::new(op);
        entry
            .extend_from_reader(&mut cursor)
            .expect("deserialize for personal merge");
        size_hint += op.len();
    }
    let mut cursor = Cursor::new(Vec::with_capacity(size_hint));
    entry.write(&mut cursor).expect("write personal entry");
    Some(cursor.into_inner())
}

fn master_merge(
    _key: &[u8],
    existing: Option<&[u8]>,
    operands: &mut MergeOperands,
) -> Option<Vec<u8>> {
    let mut entry = MasterEntry::default();
    let mut size_hint = 0;
    for op in existing.into_iter().chain(operands.into_iter()) {
        let mut cursor = Cursor::new(op);
        entry
            .extend_from_reader(&mut cursor)
            .expect("deserialize for master merge");
        size_hint += op.len();
    }
    let mut cursor = Cursor::new(Vec::with_capacity(size_hint));
    entry.write(&mut cursor).expect("write master entry");
    Some(cursor.into_inner())
}

fn void_merge(
    _key: &[u8],
    _existing: Option<&[u8]>,
    _operands: &mut MergeOperands,
) -> Option<Vec<u8>> {
    unreachable!("void merge operator only used to satisfy type checker")
}
<commit_msg>try impact of smaller bloom filters on ram usage<commit_after>use std::{io::Cursor, path::Path};

use rocksdb::{
    merge_operator::MergeFn, BlockBasedIndexType, BlockBasedOptions, ColumnFamily,
    ColumnFamilyDescriptor, DBWithThreadMode, IteratorMode, MergeOperands, Options, ReadOptions,
    SliceTransform, WriteBatch, DB,
};

use crate::model::{
    GameId, GameInfo, Key, KeyPrefix, MasterEntry, MasterGame, Month, PersonalEntry,
    PersonalStatus, UserId, Year,
};

#[derive(Debug)]
pub struct Database {
    inner: DB,
}

fn column_family(
    name: &str,
    merge: Option<&str>,
    merge_fn: impl MergeFn + Clone,
    prefix: Option<usize>,
    block_size: usize,
    bloom_filter: i32,
) -> ColumnFamilyDescriptor {
    let mut opts = Options::default();
    if let Some(merge) = merge {
        opts.set_merge_operator_associative(merge, merge_fn);
    }
    opts.set_prefix_extractor(match prefix {
        Some(prefix) => SliceTransform::create_fixed_prefix(prefix),
        None => SliceTransform::create_noop(),
    });
    let mut block_opts = BlockBasedOptions::default();
    block_opts.set_index_type(BlockBasedIndexType::HashSearch);
    block_opts.set_block_size(block_size);
    if bloom_filter > 0 {
        block_opts.set_bloom_filter(bloom_filter, true);
    }
    opts.set_block_based_table_factory(&block_opts);
    ColumnFamilyDescriptor::new(name, opts)
}

impl Database {
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Database, rocksdb::Error> {
        let mut db_opts = Options::default();
        db_opts.create_if_missing(true);
        db_opts.create_missing_column_families(true);

        let inner = DBWithThreadMode::open_cf_descriptors(
            &db_opts,
            path,
            vec![
                column_family(
                    "personal",
                    Some("personal merge"),
                    personal_merge,
                    Some(KeyPrefix::SIZE),
                    4 * 1024,
                    6,
                ),
                column_family("game", Some("game merge"), game_merge, None, 1024, 0),
                column_family("player", None, void_merge, None, 1024, 0),
                column_family(
                    "master",
                    Some("master merge"),
                    master_merge,
                    Some(KeyPrefix::SIZE),
                    4 * 1024,
                    6,
                ),
                column_family("master_game", None, void_merge, None, 4 * 1024, 0),
            ],
        )?;

        Ok(Database { inner })
    }

    pub fn queryable(&self) -> QueryableDatabase<'_> {
        QueryableDatabase {
            db: &self.inner,
            cf_personal: self.inner.cf_handle("personal").expect("cf personal"),
            cf_game: self.inner.cf_handle("game").expect("cf game"),
            cf_player: self.inner.cf_handle("player").expect("cf player"),
            cf_master: self.inner.cf_handle("master").expect("cf master"),
            cf_master_game: self.inner.cf_handle("master_game").expect("cf master_game"),
        }
    }
}

pub struct QueryableDatabase<'a> {
    db: &'a DB,
    cf_personal: &'a ColumnFamily,
    cf_game: &'a ColumnFamily,
    cf_player: &'a ColumnFamily,
    cf_master: &'a ColumnFamily,
    cf_master_game: &'a ColumnFamily,
}

impl QueryableDatabase<'_> {
    pub fn db_property(&self, name: &str) -> Result<Option<String>, rocksdb::Error> {
        self.db.property_value(name)
    }

    pub fn game_property(&self, name: &str) -> Result<Option<String>, rocksdb::Error> {
        self.db.property_value_cf(self.cf_game, name)
    }

    pub fn personal_property(&self, name: &str) -> Result<Option<String>, rocksdb::Error> {
        self.db.property_value_cf(self.cf_personal, name)
    }

    pub fn get_game_info(&self, id: GameId) -> Result<Option<GameInfo>, rocksdb::Error> {
        Ok(self.db.get_cf(self.cf_game, id.to_bytes())?.map(|buf| {
            let mut cursor = Cursor::new(buf);
            GameInfo::read(&mut cursor).expect("deserialize game info")
        }))
    }

    pub fn get_personal(
        &self,
        key: &KeyPrefix,
        since: Month,
        until: Month,
    ) -> Result<PersonalEntry, rocksdb::Error> {
        let mut opt = ReadOptions::default();
        opt.set_prefix_same_as_start(true);
        opt.set_iterate_lower_bound(key.with_month(since).into_bytes());
        opt.set_iterate_upper_bound(key.with_month(until.add_months_saturating(1)).into_bytes());

        let iterator = self
            .db
            .iterator_cf_opt(self.cf_personal, opt, IteratorMode::Start);

        let mut entry = PersonalEntry::default();
        for (_key, value) in iterator {
            let mut cursor = Cursor::new(value);
            entry
                .extend_from_reader(&mut cursor)
                .expect("deserialize personal entry");
        }

        Ok(entry)
    }

    pub fn get_player_status(&self, id: &UserId) -> Result<Option<PersonalStatus>, rocksdb::Error> {
        Ok(self.db.get_cf(self.cf_player, id.as_str())?.map(|buf| {
            let mut cursor = Cursor::new(buf);
            PersonalStatus::read(&mut cursor).expect("deserialize status")
        }))
    }

    pub fn put_player_status(
        &self,
        id: &UserId,
        status: &PersonalStatus,
    ) -> Result<(), rocksdb::Error> {
        let mut cursor = Cursor::new(Vec::with_capacity(PersonalStatus::SIZE_HINT));
        status.write(&mut cursor).expect("serialize status");
        self.db
            .put_cf(self.cf_player, id.as_str(), cursor.into_inner())
    }

    pub fn has_master_game(&self, id: GameId) -> Result<bool, rocksdb::Error> {
        self.db
            .get_cf(self.cf_master_game, id.to_bytes())
            .map(|maybe_entry| maybe_entry.is_some())
    }

    pub fn get_master_game(&self, id: GameId) -> Result<Option<MasterGame>, rocksdb::Error> {
        Ok(self
            .db
            .get_cf(self.cf_master_game, id.to_bytes())?
            .map(|buf| serde_json::from_slice(&buf).expect("deserialize master game")))
    }

    pub fn has_master(&self, key: Key) -> Result<bool, rocksdb::Error> {
        self.db
            .get_cf(self.cf_master, key.into_bytes())
            .map(|maybe_entry| maybe_entry.is_some())
    }

    pub fn get_master(
        &self,
        key: KeyPrefix,
        since: Year,
        until: Year,
    ) -> Result<MasterEntry, rocksdb::Error> {
        let mut opt = ReadOptions::default();
        opt.set_prefix_same_as_start(true);
        opt.set_iterate_lower_bound(key.with_year(since).into_bytes());
        opt.set_iterate_upper_bound(key.with_year(until.add_years_saturating(1)).into_bytes());

        let iterator = self
            .db
            .iterator_cf_opt(self.cf_master, opt, IteratorMode::Start);

        let mut entry = MasterEntry::default();
        for (_key, value) in iterator {
            let mut cursor = Cursor::new(value);
            entry
                .extend_from_reader(&mut cursor)
                .expect("deserialize master entry");
        }

        Ok(entry)
    }

    pub fn batch(&self) -> Batch<'_> {
        Batch {
            queryable: self,
            batch: WriteBatch::default(),
        }
    }
}

pub struct Batch<'a> {
    queryable: &'a QueryableDatabase<'a>,
    batch: WriteBatch,
}

impl Batch<'_> {
    pub fn merge_personal(&mut self, key: Key, entry: PersonalEntry) {
        let mut cursor = Cursor::new(Vec::with_capacity(PersonalEntry::SIZE_HINT));
        entry.write(&mut cursor).expect("serialize personal entry");
        self.batch.merge_cf(
            self.queryable.cf_personal,
            key.into_bytes(),
            cursor.into_inner(),
        );
    }

    pub fn merge_game_info(&mut self, id: GameId, info: GameInfo) {
        let mut cursor = Cursor::new(Vec::with_capacity(GameInfo::SIZE_HINT));
        info.write(&mut cursor).expect("serialize game info");
        self.batch
            .merge_cf(self.queryable.cf_game, id.to_bytes(), cursor.into_inner());
    }

    pub fn merge_master(&mut self, key: Key, entry: MasterEntry) {
        let mut cursor = Cursor::new(Vec::with_capacity(MasterEntry::SIZE_HINT));
        entry.write(&mut cursor).expect("serialize master entry");
        self.batch.merge_cf(
            self.queryable.cf_master,
            key.into_bytes(),
            cursor.into_inner(),
        );
    }

    pub fn put_master_game(&mut self, id: GameId, game: &MasterGame) {
        self.batch.put_cf(
            self.queryable.cf_master_game,
            id.to_bytes(),
            serde_json::to_vec(game).expect("serialize master game"),
        );
    }

    pub fn write(self) -> Result<(), rocksdb::Error> {
        self.queryable.db.write(self.batch)
    }
}

fn game_merge(
    _key: &[u8],
    existing: Option<&[u8]>,
    operands: &mut MergeOperands,
) -> Option<Vec<u8>> {
    // Take latest game info, but merge index status.
    let mut info: Option<GameInfo> = None;
    let mut size_hint = 0;
    for op in existing.into_iter().chain(operands.into_iter()) {
        let mut cursor = Cursor::new(op);
        let mut new_info = GameInfo::read(&mut cursor).expect("read for game merge");
        if let Some(old_info) = info {
            new_info.indexed.white |= old_info.indexed.white;
            new_info.indexed.black |= old_info.indexed.black;
        }
        info = Some(new_info);
        size_hint = op.len();
    }
    info.map(|info| {
        let mut cursor = Cursor::new(Vec::with_capacity(size_hint));
        info.write(&mut cursor).expect("write game");
        cursor.into_inner()
    })
}

fn personal_merge(
    _key: &[u8],
    existing: Option<&[u8]>,
    operands: &mut MergeOperands,
) -> Option<Vec<u8>> {
    let mut entry = PersonalEntry::default();
    let mut size_hint = 0;
    for op in existing.into_iter().chain(operands.into_iter()) {
        let mut cursor = Cursor::new(op);
        entry
            .extend_from_reader(&mut cursor)
            .expect("deserialize for personal merge");
        size_hint += op.len();
    }
    let mut cursor = Cursor::new(Vec::with_capacity(size_hint));
    entry.write(&mut cursor).expect("write personal entry");
    Some(cursor.into_inner())
}

fn master_merge(
    _key: &[u8],
    existing: Option<&[u8]>,
    operands: &mut MergeOperands,
) -> Option<Vec<u8>> {
    let mut entry = MasterEntry::default();
    let mut size_hint = 0;
    for op in existing.into_iter().chain(operands.into_iter()) {
        let mut cursor = Cursor::new(op);
        entry
            .extend_from_reader(&mut cursor)
            .expect("deserialize for master merge");
        size_hint += op.len();
    }
    let mut cursor = Cursor::new(Vec::with_capacity(size_hint));
    entry.write(&mut cursor).expect("write master entry");
    Some(cursor.into_inner())
}

fn void_merge(
    _key: &[u8],
    _existing: Option<&[u8]>,
    _operands: &mut MergeOperands,
) -> Option<Vec<u8>> {
    unreachable!("void merge operator only used to satisfy type checker")
}
<|endoftext|>


<commit_before>use criterion::{criterion_group, criterion_main, Criterion};
use munkres::{solve_assignment, WeightMatrix};

fn gen_matrix(n: usize) -> Vec<i32> {
    (0..n * n)
        .map(|i| {
            let row = i / n;
            let col = i % n;
            (row * col) as i32
        })
        .collect()
}

fn criterion_benchmark(c: &mut Criterion) {
    c.bench_function_over_inputs(
        "solve_assignment",
        |b: &mut criterion::Bencher, n: &usize| {
            let n = *n;
            let matrix = gen_matrix(n);
            b.iter(|| {
                let mut weights: WeightMatrix<i32> = WeightMatrix::from_row_vec(n, matrix.clone());
                let _matching = solve_assignment(&mut weights);
            })
        },
        vec![100],
    );
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
<commit_msg>Run benchmark with N=50<commit_after>use criterion::{criterion_group, criterion_main, Criterion};
use munkres::{solve_assignment, WeightMatrix};

fn gen_matrix(n: usize) -> Vec<i32> {
    (0..n * n)
        .map(|i| {
            let row = i / n;
            let col = i % n;
            (row * col) as i32
        })
        .collect()
}

fn criterion_benchmark(c: &mut Criterion) {
    c.bench_function_over_inputs(
        "solve_assignment",
        |b: &mut criterion::Bencher, n: &usize| {
            let n = *n;
            let matrix = gen_matrix(n);
            b.iter(|| {
                let mut weights: WeightMatrix<i32> = WeightMatrix::from_row_vec(n, matrix.clone());
                let _matching = solve_assignment(&mut weights);
            })
        },
        vec![50],
    );
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
<|endoftext|>


<commit_before>use std::env;

fn main() {
    let os_args = env::args();
    let args: Vec<_> = os_args.collect();

    if args.len() != 4 {
        println!("usage : {} start numline width", args[0]);
        return;
    }

    let start_num = args[1].trim_right().parse::<u64>().unwrap_or(0);
    let stop_num = args[2].trim_right().parse::<u64>().unwrap_or(0);
    let width_num = args[3].trim_right().parse::<u64>().unwrap_or(0);

    gen_lines(start_num, stop_num, width_num);
}

fn gen_lines(start: u64, stop: u64, linewidth: u64) -> () {
    let string = gen_line(linewidth);

    for x in start..start + stop + 1 {
        print!("{:012} {}", x, string);
    }
}

fn gen_line(linewidth: u64) -> String {
    let mut string = String::new();

    let table = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
                 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                 'w', 'x', 'y', 'z'];

    for x in 0..linewidth {
        string.push(table[x as usize % table.len()]);
    }
    string.push('\n');

    return string;
}
<commit_msg>use BufWriter<commit_after>use std::env;
use std::io::BufWriter;
use std::io::{self, Write};

fn main() {
    let os_args = env::args();
    let args: Vec<_> = os_args.collect();

    if args.len() != 4 {
        println!("usage : {} start numline width", args[0]);
        return;
    }

    let start_num = args[1].trim_right().parse::<u64>().unwrap_or(0);
    let stop_num = args[2].trim_right().parse::<u64>().unwrap_or(0);
    let width_num = args[3].trim_right().parse::<u64>().unwrap_or(0);

    gen_lines(start_num, stop_num, width_num);
}

fn gen_lines(start: u64, stop: u64, linewidth: u64) -> () {
    let string = gen_line(linewidth);

    let stdout = io::stdout();
    let mut buff = BufWriter::new(stdout);
    for x in start..start + stop + 1 {
        buff.write_fmt(format_args!("{:012} {}", x, string)).unwrap();
    }
}

fn gen_line(linewidth: u64) -> String {
    let mut string = String::new();

    let table = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
                 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                 'w', 'x', 'y', 'z'];

    for x in 0..linewidth {
        string.push(table[x as usize % table.len()]);
    }
    string.push('\n');

    return string;
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{BufRead, BufReader, stderr, Write};
use std::net::{TcpListener};
use std::sync::Arc;
use std::thread;

extern crate clap;
extern crate time;
use clap::{App, Arg};

fn main() {
    let matches = App::new("qotd")
        .author("Justinas Stankevicius")
        .arg_required_else_help(true)
        .arg(
            Arg::with_name("quote_file").index(1).required(true)
            .help("The file with the quotes to use, one per line.")
        )
        .arg(Arg::with_name("port").short("p").takes_value(true))
        .get_matches();

    // unwrap() should be fine
    // as the existence of the argument is enforced by arg_required_else_help()
    let filename = matches.value_of("quote_file").unwrap();
    let port = matches.value_of("port").unwrap_or("17")
        .parse::<u16>().ok().unwrap_or_else(|| {
            write!(stderr(), "An invalid port number supplied, defaulting to 17.\n");
            17
        });

    let reader = BufReader::new(File::open(filename).ok().expect("Failed to open the quote file."));
    let quotes = Arc::new(reader.lines()
                           .map(|x| x.unwrap())
                           .filter(|x| x.len() != 0)
                           .collect::<Vec<String>>()
                          );

    let listener = TcpListener::bind(("127.0.0.1", port)).unwrap_or_else(|e| panic!("{}", e));
    let mut thread_handles = Vec::new();

    for inc in listener.incoming() {
        let mut conn = match inc {
            Ok(c) => c,
            Err(e) => {
                write!(stderr(), "Errror while trying to accept a connection: {}\n", e);
                continue;
            },
        };
        let peer_addr = conn.peer_addr().unwrap();
        write!(stderr(), "Successful connection from: {}\n", peer_addr);

        let local_quotes = quotes.clone();

        thread_handles.push(thread::spawn(move || {
            let tm = time::now_utc();
            let day = tm.tm_yday as usize;
            let quote = &local_quotes[day % local_quotes.len()];
            match conn.write(quote.as_bytes()) {
                Ok(_) => write!(stderr(), "Sent the quote successfully to {}.\n", peer_addr),
                Err(e) => write!(stderr(), "Error while sending the quote to {}: {}\n", peer_addr, e),
            };
        }));
    }

    for h in thread_handles {
        h.join();
    }
}
<commit_msg>[qotd] Simplify the error handling<commit_after>use std::fs::File;
use std::io::{BufRead, BufReader, stderr, Write};
use std::net::{TcpListener};
use std::sync::Arc;
use std::thread;

extern crate clap;
extern crate time;
use clap::{App, Arg};

fn main() {
    let matches = App::new("qotd")
        .author("Justinas Stankevicius")
        .arg_required_else_help(true)
        .arg(
            Arg::with_name("quote_file").index(1).required(true)
            .help("The file with the quotes to use, one per line.")
        )
        .arg(Arg::with_name("port").short("p").takes_value(true))
        .get_matches();

    // unwrap() should be fine
    // as the existence of the argument is enforced by arg_required_else_help()
    let filename = matches.value_of("quote_file").unwrap();
    let port = matches.value_of("port").unwrap_or("17")
        .parse::<u16>().ok().unwrap_or_else(|| {
            write!(stderr(), "An invalid port number supplied, defaulting to 17.\n");
            17
        });

    let reader = BufReader::new(File::open(filename).ok().expect("Failed to open the quote file."));
    let quotes = Arc::new(reader.lines()
                           .map(|x| x.unwrap())
                           .filter(|x| x.len() != 0)
                           .collect::<Vec<String>>()
                          );

    let listener = TcpListener::bind(("127.0.0.1", port)).unwrap();
    let mut thread_handles = Vec::new();

    for inc in listener.incoming() {
        let mut conn = match inc {
            Ok(c) => c,
            Err(e) => {
                write!(stderr(), "Errror while trying to accept a connection: {}\n", e);
                continue;
            },
        };
        let peer_addr = conn.peer_addr().unwrap();
        write!(stderr(), "Successful connection from: {}\n", peer_addr);

        let local_quotes = quotes.clone();

        thread_handles.push(thread::spawn(move || {
            let tm = time::now_utc();
            let day = tm.tm_yday as usize;
            let quote = &local_quotes[day % local_quotes.len()];
            match conn.write(quote.as_bytes()) {
                Ok(_) => write!(stderr(), "Sent the quote successfully to {}.\n", peer_addr),
                Err(e) => write!(stderr(), "Error while sending the quote to {}: {}\n", peer_addr, e),
            };
        }));
    }

    for h in thread_handles {
        h.join();
    }
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use rand::{thread_rng, Rng};
use std::collections::HashMap;
use cgmath::{Vector2};
use common::types::{Size2, ZInt, UnitId, PlayerId, MapPos};
use game_state::GameState;
use map::{distance};
use pathfinder::{MapPath};
use command::{Command};
use unit::{Unit, UnitTypeId, WeaponTypeId, WeaponType};
use object::{ObjectTypes};
use player::{Player};
use ai::{Ai};

#[derive(Clone)]
pub enum FireMode {
    Active,
    Reactive,
}

#[derive(Clone)]
pub enum CoreEvent {
    Move{unit_id: UnitId, path: MapPath},
    EndTurn{old_id: PlayerId, new_id: PlayerId},
    CreateUnit {
        unit_id: UnitId,
        pos: MapPos,
        type_id: UnitTypeId,
        player_id: PlayerId,
    },
    AttackUnit {
        attacker_id: UnitId,
        defender_id: UnitId,
        mode: FireMode,
        killed: bool,
    },
}

fn is_target_dead(event: &CoreEvent) -> bool {
    match event {
        &CoreEvent::AttackUnit{ref killed, ..} => *killed,
        _ => panic!("wrong event type"),
    }
}

pub struct Core {
    game_state: GameState,
    players: Vec<Player>,
    current_player_id: PlayerId,
    core_event_list: Vec<CoreEvent>,
    event_lists: HashMap<PlayerId, Vec<CoreEvent>>,
    pub object_types: ObjectTypes, // TODO: remove 'pub'
    ai: Ai,
}

fn get_event_lists() -> HashMap<PlayerId, Vec<CoreEvent>> {
    let mut map = HashMap::new();
    map.insert(PlayerId{id: 0}, Vec::new());
    map.insert(PlayerId{id: 1}, Vec::new());
    map
}

fn get_players_list() -> Vec<Player> {
    vec!(
        Player{id: PlayerId{id: 0}, is_ai: false},
        // Player{id: PlayerId{id: 1}, is_ai: true},
        Player{id: PlayerId{id: 1}, is_ai: false},
    )
}

impl Core {
    pub fn new() -> Core {
        let map_size = Size2{w: 10, h: 8};
        let mut core = Core {
            game_state: GameState::new(&map_size, None),
            players: get_players_list(),
            current_player_id: PlayerId{id: 0},
            core_event_list: Vec::new(),
            event_lists: get_event_lists(),
            object_types: ObjectTypes::new(),
            ai: Ai::new(&PlayerId{id:1}, &map_size),
        };
        core.get_units();
        core
    }

    pub fn object_types(&self) -> &ObjectTypes {
        &self.object_types
    }

    // TODO: Move to scenario.json
    fn get_units(&mut self) {
        let tank_id = self.object_types.get_unit_type_id("tank");
        let soldier_id = self.object_types.get_unit_type_id("soldier");
        let p_id_0 = PlayerId{id: 0};
        let p_id_1 = PlayerId{id: 1};
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 1}}, &tank_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 2}}, &soldier_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 3}}, &soldier_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 4}}, &soldier_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 5}}, &tank_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 6}}, &tank_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 1}}, &tank_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 2}}, &soldier_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 3}}, &soldier_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 4}}, &soldier_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 5}}, &tank_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 6}}, &tank_id, &p_id_1);
    }

    fn get_new_unit_id(&self) -> UnitId {
        // TODO: check max id
        let id = match self.game_state.units.keys().max_by(|&n| n) {
            Some(n) => n.id + 1,
            None => 0,
        };
        UnitId{id: id}
    }

    fn add_unit(&mut self, pos: &MapPos, type_id: &UnitTypeId, player_id: &PlayerId) {
        let event = CoreEvent::CreateUnit{
            unit_id: self.get_new_unit_id(),
            pos: pos.clone(),
            type_id: type_id.clone(),
            player_id: player_id.clone(),
        };
        self.do_core_event(event);
    }

    pub fn map_size(&self) -> &Size2<ZInt> {
        self.game_state.map.size()
    }

    fn get_unit<'a>(&'a self, id: &UnitId) -> &'a Unit {
        match self.game_state.units.get(id) {
            Some(unit) => unit,
            None => panic!("No unit with id = {}", id.id),
        }
    }

    pub fn get_weapon_type(&self, weapon_type_id: &WeaponTypeId) -> &WeaponType {
        &self.object_types.weapon_types[weapon_type_id.id as usize]
    }

    fn hit_test(&self, attacker_id: &UnitId, defender_id: &UnitId) -> bool {
        fn test(needed: ZInt) -> bool {
            let real = thread_rng().gen_range(-5i32, 5i32);
            let result = real < needed;
            println!("real:{} < needed:{} = {}", real, needed, result);
            result
        }
        println!("");
        let attacker = self.get_unit(attacker_id);
        let defender = self.get_unit(defender_id);
        let attacker_type = self.object_types.get_unit_type(&attacker.type_id);
        let defender_type = self.object_types.get_unit_type(&defender.type_id);
        let weapon_type = self.get_weapon_type(&attacker_type.weapon_type_id);
        if distance(&attacker.pos, &defender.pos) > weapon_type.max_distance {
            return false;
        }
        let hit_test_v = -15 + defender_type.size
            + weapon_type.accuracy + attacker_type.weapon_skill;
        let pierce_test_v = 5 + -defender_type.armor + weapon_type.ap;
        let wound_test_v = -defender_type.toughness + weapon_type.damage;
        println!("hit_test = {}, pierce_test = {}, wound_test_v = {}",
            hit_test_v, pierce_test_v, wound_test_v);
        print!("hit test: ");
        if !test(hit_test_v) {
            return false;
        }
        print!("pierce test: ");
        if !test(pierce_test_v) {
            return false;
        }
        print!("wound test: ");
        if !test(wound_test_v) {
            return false;
        }
        println!("HIT!");
        true
        // false
    }

    pub fn player(&self) -> &Player {
        &self.players[self.player_id().id as usize]
    }

    pub fn player_id(&self) -> &PlayerId {
        &self.current_player_id
    }

    pub fn get_event(&mut self) -> Option<CoreEvent> {
        let list = self.event_lists.get_mut(&self.current_player_id).unwrap();
        if list.len() == 0 {
            None
        } else {
            Some(list.remove(0))
        }
    }

    fn command_attack_unit_to_event(
        &self,
        attacker_id: UnitId,
        defender_id: UnitId,
        pos: &MapPos, // TODO: get pos from unit
        fire_mode: FireMode,
        // (apply coreevent to state after adding CoreEvent)
    ) -> Vec<CoreEvent> {
        let attacker = &self.game_state.units[attacker_id];
        // let defender = &self.game_state.units[defender_id];
        let attacker_type = self.object_types.get_unit_type(&attacker.type_id);
        let weapon_type = self.get_weapon_type(&attacker_type.weapon_type_id);
        // if distance(&attacker.pos, &defender.pos) < weapon_type.max_distance {
        if distance(&attacker.pos, pos) <= weapon_type.max_distance {
            let hit = self.hit_test(&attacker_id, &defender_id);
            vec![CoreEvent::AttackUnit {
                attacker_id: attacker_id,
                defender_id: defender_id,
                killed: hit,
                mode: fire_mode,
            }]
        } else {
            Vec::new()
        }
    }

    fn reaction_fire(&self, unit_id: &UnitId, pos: &MapPos) -> Vec<CoreEvent> {
        let mut events = Vec::new();
        for (_, enemy_unit) in self.game_state.units.iter() {
            // TODO: check if unit is still alive
            if enemy_unit.player_id == self.current_player_id {
                continue;
            }
            if enemy_unit.attack_points <= 0 {
                continue;
            }
            let max_distance = self.object_types
                .get_unit_max_attack_dist(enemy_unit);
            if distance(&enemy_unit.pos, pos) > max_distance {
                continue;
            }
            let e = self.command_attack_unit_to_event(
                enemy_unit.id.clone(), unit_id.clone(), pos, FireMode::Reactive);
            events.push_all(e.as_slice());
            if e.is_empty() {
                continue;
            }
            if is_target_dead(&e[0]) {
                break;
            }
        }
        events
    }

    fn reaction_fire_move(&self, path: &MapPath, unit_id: &UnitId) -> Vec<CoreEvent> {
        let mut events = Vec::new();
        let len = path.nodes().len();
        'path_loop: for i in range(1, len) {
            let (_, ref pos) = path.nodes()[i];
            let e = self.reaction_fire(unit_id, pos);
            if !e.is_empty() {
                let mut new_nodes = path.nodes().clone();
                new_nodes.truncate(i + 1);
                events.push(CoreEvent::Move {
                    unit_id: unit_id.clone(),
                    path: MapPath::new(new_nodes),
                });
                events.push_all(e.as_slice());
                break 'path_loop;
            }
        }
        events
    }

    // TODO: rename: simulation_step?
    // Apply events immidietly after adding event to array.
    fn command_to_event(&self, command: Command) -> Vec<CoreEvent> {
        let mut events = Vec::new();
        match command {
            Command::EndTurn => {
                let old_id = self.current_player_id.id;
                let max_id = self.players.len() as ZInt;
                let new_id = if old_id + 1 == max_id {
                    0
                } else {
                    old_id + 1
                };
                events.push(CoreEvent::EndTurn {
                    old_id: PlayerId{id: old_id},
                    new_id: PlayerId{id: new_id},
                });
            },
            Command::CreateUnit{pos} => {
                events.push(CoreEvent::CreateUnit {
                    unit_id: self.get_new_unit_id(),
                    pos: pos,
                    type_id: self.object_types.get_unit_type_id("soldier"),
                    player_id: self.current_player_id.clone(),
                });
            },
            Command::Move{ref unit_id, ref path} => {
                // TODO: do some checks?
                let e = self.reaction_fire_move(path, unit_id);
                if e.is_empty() {
                    events.push(CoreEvent::Move {
                        unit_id: unit_id.clone(),
                        path: path.clone(),
                    });
                } else {
                    events.push_all(e.as_slice());
                }
            },
            Command::AttackUnit{attacker_id, defender_id} => {
                // TODO: do some checks?
                let defender_pos = &self.game_state.units[defender_id].pos;
                let e = self.command_attack_unit_to_event(
                    attacker_id.clone(), defender_id, defender_pos, FireMode::Active);
                events.push_all(e.as_slice());
                if !e.is_empty() && !is_target_dead(&e[0]) {
                    let pos = &self.game_state.units[attacker_id].pos;
                    events.push_all(
                        self.reaction_fire(&attacker_id, pos).as_slice());
                }
            },
        };
        events
    }

    pub fn do_command(&mut self, command: Command) {
        let events = self.command_to_event(command);
        if events.is_empty() {
            println!("BAD COMMAND!");
        }
        for event in events.into_iter() {
            self.do_core_event(event);
        }
    }

    fn do_core_event(&mut self, core_event: CoreEvent) {
        self.core_event_list.push(core_event);
        self.make_events();
    }

    fn do_ai(&mut self) {
        loop {
            while let Some(event) = self.get_event() {
                self.ai.state.apply_event(&self.object_types, &event);
            }
            let command = self.ai.get_command(&self.object_types);
            self.do_command(command.clone());
            match command {
                Command::EndTurn => return,
                _ => {},
            }
        }
    }

    fn apply_event(&mut self, event: &CoreEvent) {
        match *event {
            CoreEvent::EndTurn{ref old_id, ref new_id} => {
                for player in self.players.iter() {
                    if player.id == *new_id {
                        if self.current_player_id == *old_id {
                            self.current_player_id = player.id.clone();
                        }
                        break;
                    }
                }
                if self.player().is_ai && *new_id == *self.player_id() {
                    self.do_ai();
                }
            },
            _ => {},
        };
    }

    fn make_events(&mut self) {
        while self.core_event_list.len() != 0 {
            let event = self.core_event_list.pop().unwrap();
            self.apply_event(&event);
            self.game_state.apply_event(&self.object_types, &event);
            for player in self.players.iter() {
                let event_list = self.event_lists.get_mut(&player.id).unwrap();
                // TODO: per player event filter
                event_list.push(event.clone());
            }
        }
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>core.rs: apply_event -> handle_end_turn_event<commit_after>// See LICENSE file for copyright and license details.

use rand::{thread_rng, Rng};
use std::collections::HashMap;
use cgmath::{Vector2};
use common::types::{Size2, ZInt, UnitId, PlayerId, MapPos};
use game_state::GameState;
use map::{distance};
use pathfinder::{MapPath};
use command::{Command};
use unit::{Unit, UnitTypeId, WeaponTypeId, WeaponType};
use object::{ObjectTypes};
use player::{Player};
use ai::{Ai};

#[derive(Clone)]
pub enum FireMode {
    Active,
    Reactive,
}

#[derive(Clone)]
pub enum CoreEvent {
    Move{unit_id: UnitId, path: MapPath},
    EndTurn{old_id: PlayerId, new_id: PlayerId},
    CreateUnit {
        unit_id: UnitId,
        pos: MapPos,
        type_id: UnitTypeId,
        player_id: PlayerId,
    },
    AttackUnit {
        attacker_id: UnitId,
        defender_id: UnitId,
        mode: FireMode,
        killed: bool,
    },
}

fn is_target_dead(event: &CoreEvent) -> bool {
    match event {
        &CoreEvent::AttackUnit{ref killed, ..} => *killed,
        _ => panic!("wrong event type"),
    }
}

pub struct Core {
    game_state: GameState,
    players: Vec<Player>,
    current_player_id: PlayerId,
    core_event_list: Vec<CoreEvent>,
    event_lists: HashMap<PlayerId, Vec<CoreEvent>>,
    pub object_types: ObjectTypes, // TODO: remove 'pub'
    ai: Ai,
}

fn get_event_lists() -> HashMap<PlayerId, Vec<CoreEvent>> {
    let mut map = HashMap::new();
    map.insert(PlayerId{id: 0}, Vec::new());
    map.insert(PlayerId{id: 1}, Vec::new());
    map
}

fn get_players_list() -> Vec<Player> {
    vec!(
        Player{id: PlayerId{id: 0}, is_ai: false},
        // Player{id: PlayerId{id: 1}, is_ai: true},
        Player{id: PlayerId{id: 1}, is_ai: false},
    )
}

impl Core {
    pub fn new() -> Core {
        let map_size = Size2{w: 10, h: 8};
        let mut core = Core {
            game_state: GameState::new(&map_size, None),
            players: get_players_list(),
            current_player_id: PlayerId{id: 0},
            core_event_list: Vec::new(),
            event_lists: get_event_lists(),
            object_types: ObjectTypes::new(),
            ai: Ai::new(&PlayerId{id:1}, &map_size),
        };
        core.get_units();
        core
    }

    pub fn object_types(&self) -> &ObjectTypes {
        &self.object_types
    }

    // TODO: Move to scenario.json
    fn get_units(&mut self) {
        let tank_id = self.object_types.get_unit_type_id("tank");
        let soldier_id = self.object_types.get_unit_type_id("soldier");
        let p_id_0 = PlayerId{id: 0};
        let p_id_1 = PlayerId{id: 1};
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 1}}, &tank_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 2}}, &soldier_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 3}}, &soldier_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 4}}, &soldier_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 5}}, &tank_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 0, y: 6}}, &tank_id, &p_id_0);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 1}}, &tank_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 2}}, &soldier_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 3}}, &soldier_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 4}}, &soldier_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 5}}, &tank_id, &p_id_1);
        self.add_unit(&MapPos{v: Vector2{x: 9, y: 6}}, &tank_id, &p_id_1);
    }

    fn get_new_unit_id(&self) -> UnitId {
        // TODO: check max id
        let id = match self.game_state.units.keys().max_by(|&n| n) {
            Some(n) => n.id + 1,
            None => 0,
        };
        UnitId{id: id}
    }

    fn add_unit(&mut self, pos: &MapPos, type_id: &UnitTypeId, player_id: &PlayerId) {
        let event = CoreEvent::CreateUnit{
            unit_id: self.get_new_unit_id(),
            pos: pos.clone(),
            type_id: type_id.clone(),
            player_id: player_id.clone(),
        };
        self.do_core_event(event);
    }

    pub fn map_size(&self) -> &Size2<ZInt> {
        self.game_state.map.size()
    }

    fn get_unit<'a>(&'a self, id: &UnitId) -> &'a Unit {
        match self.game_state.units.get(id) {
            Some(unit) => unit,
            None => panic!("No unit with id = {}", id.id),
        }
    }

    pub fn get_weapon_type(&self, weapon_type_id: &WeaponTypeId) -> &WeaponType {
        &self.object_types.weapon_types[weapon_type_id.id as usize]
    }

    fn hit_test(&self, attacker_id: &UnitId, defender_id: &UnitId) -> bool {
        fn test(needed: ZInt) -> bool {
            let real = thread_rng().gen_range(-5i32, 5i32);
            let result = real < needed;
            println!("real:{} < needed:{} = {}", real, needed, result);
            result
        }
        println!("");
        let attacker = self.get_unit(attacker_id);
        let defender = self.get_unit(defender_id);
        let attacker_type = self.object_types.get_unit_type(&attacker.type_id);
        let defender_type = self.object_types.get_unit_type(&defender.type_id);
        let weapon_type = self.get_weapon_type(&attacker_type.weapon_type_id);
        if distance(&attacker.pos, &defender.pos) > weapon_type.max_distance {
            return false;
        }
        let hit_test_v = -15 + defender_type.size
            + weapon_type.accuracy + attacker_type.weapon_skill;
        let pierce_test_v = 5 + -defender_type.armor + weapon_type.ap;
        let wound_test_v = -defender_type.toughness + weapon_type.damage;
        println!("hit_test = {}, pierce_test = {}, wound_test_v = {}",
            hit_test_v, pierce_test_v, wound_test_v);
        print!("hit test: ");
        if !test(hit_test_v) {
            return false;
        }
        print!("pierce test: ");
        if !test(pierce_test_v) {
            return false;
        }
        print!("wound test: ");
        if !test(wound_test_v) {
            return false;
        }
        println!("HIT!");
        true
        // false
    }

    pub fn player(&self) -> &Player {
        &self.players[self.player_id().id as usize]
    }

    pub fn player_id(&self) -> &PlayerId {
        &self.current_player_id
    }

    pub fn get_event(&mut self) -> Option<CoreEvent> {
        let list = self.event_lists.get_mut(&self.current_player_id).unwrap();
        if list.len() == 0 {
            None
        } else {
            Some(list.remove(0))
        }
    }

    fn command_attack_unit_to_event(
        &self,
        attacker_id: UnitId,
        defender_id: UnitId,
        pos: &MapPos, // TODO: get pos from unit
        fire_mode: FireMode,
        // (apply coreevent to state after adding CoreEvent)
    ) -> Vec<CoreEvent> {
        let attacker = &self.game_state.units[attacker_id];
        // let defender = &self.game_state.units[defender_id];
        let attacker_type = self.object_types.get_unit_type(&attacker.type_id);
        let weapon_type = self.get_weapon_type(&attacker_type.weapon_type_id);
        // if distance(&attacker.pos, &defender.pos) < weapon_type.max_distance {
        if distance(&attacker.pos, pos) <= weapon_type.max_distance {
            let hit = self.hit_test(&attacker_id, &defender_id);
            vec![CoreEvent::AttackUnit {
                attacker_id: attacker_id,
                defender_id: defender_id,
                killed: hit,
                mode: fire_mode,
            }]
        } else {
            Vec::new()
        }
    }

    fn reaction_fire(&self, unit_id: &UnitId, pos: &MapPos) -> Vec<CoreEvent> {
        let mut events = Vec::new();
        for (_, enemy_unit) in self.game_state.units.iter() {
            // TODO: check if unit is still alive
            if enemy_unit.player_id == self.current_player_id {
                continue;
            }
            if enemy_unit.attack_points <= 0 {
                continue;
            }
            let max_distance = self.object_types
                .get_unit_max_attack_dist(enemy_unit);
            if distance(&enemy_unit.pos, pos) > max_distance {
                continue;
            }
            let e = self.command_attack_unit_to_event(
                enemy_unit.id.clone(), unit_id.clone(), pos, FireMode::Reactive);
            events.push_all(e.as_slice());
            if e.is_empty() {
                continue;
            }
            if is_target_dead(&e[0]) {
                break;
            }
        }
        events
    }

    fn reaction_fire_move(&self, path: &MapPath, unit_id: &UnitId) -> Vec<CoreEvent> {
        let mut events = Vec::new();
        let len = path.nodes().len();
        'path_loop: for i in range(1, len) {
            let (_, ref pos) = path.nodes()[i];
            let e = self.reaction_fire(unit_id, pos);
            if !e.is_empty() {
                let mut new_nodes = path.nodes().clone();
                new_nodes.truncate(i + 1);
                events.push(CoreEvent::Move {
                    unit_id: unit_id.clone(),
                    path: MapPath::new(new_nodes),
                });
                events.push_all(e.as_slice());
                break 'path_loop;
            }
        }
        events
    }

    // TODO: rename: simulation_step?
    // Apply events immidietly after adding event to array.
    fn command_to_event(&self, command: Command) -> Vec<CoreEvent> {
        let mut events = Vec::new();
        match command {
            Command::EndTurn => {
                let old_id = self.current_player_id.id;
                let max_id = self.players.len() as ZInt;
                let new_id = if old_id + 1 == max_id {
                    0
                } else {
                    old_id + 1
                };
                events.push(CoreEvent::EndTurn {
                    old_id: PlayerId{id: old_id},
                    new_id: PlayerId{id: new_id},
                });
            },
            Command::CreateUnit{pos} => {
                events.push(CoreEvent::CreateUnit {
                    unit_id: self.get_new_unit_id(),
                    pos: pos,
                    type_id: self.object_types.get_unit_type_id("soldier"),
                    player_id: self.current_player_id.clone(),
                });
            },
            Command::Move{ref unit_id, ref path} => {
                // TODO: do some checks?
                let e = self.reaction_fire_move(path, unit_id);
                if e.is_empty() {
                    events.push(CoreEvent::Move {
                        unit_id: unit_id.clone(),
                        path: path.clone(),
                    });
                } else {
                    events.push_all(e.as_slice());
                }
            },
            Command::AttackUnit{attacker_id, defender_id} => {
                // TODO: do some checks?
                let defender_pos = &self.game_state.units[defender_id].pos;
                let e = self.command_attack_unit_to_event(
                    attacker_id.clone(), defender_id, defender_pos, FireMode::Active);
                events.push_all(e.as_slice());
                if !e.is_empty() && !is_target_dead(&e[0]) {
                    let pos = &self.game_state.units[attacker_id].pos;
                    events.push_all(
                        self.reaction_fire(&attacker_id, pos).as_slice());
                }
            },
        };
        events
    }

    pub fn do_command(&mut self, command: Command) {
        let events = self.command_to_event(command);
        if events.is_empty() {
            println!("BAD COMMAND!");
        }
        for event in events.into_iter() {
            self.do_core_event(event);
        }
    }

    fn do_core_event(&mut self, core_event: CoreEvent) {
        self.core_event_list.push(core_event);
        self.make_events();
    }

    fn do_ai(&mut self) {
        loop {
            while let Some(event) = self.get_event() {
                self.ai.state.apply_event(&self.object_types, &event);
            }
            let command = self.ai.get_command(&self.object_types);
            self.do_command(command.clone());
            match command {
                Command::EndTurn => return,
                _ => {},
            }
        }
    }

    fn handle_end_turn_event(&mut self, old_id: &PlayerId, new_id: &PlayerId) {
        for player in self.players.iter() {
            if player.id == *new_id {
                if self.current_player_id == *old_id {
                    self.current_player_id = player.id.clone();
                }
                break;
            }
        }
        if self.player().is_ai && *new_id == *self.player_id() {
            self.do_ai();
        }
    }

    fn make_events(&mut self) {
        while self.core_event_list.len() != 0 {
            let event = self.core_event_list.pop()
                .expect("core_event_list is empty");
            if let CoreEvent::EndTurn{ref old_id, ref new_id} = event {
                self.handle_end_turn_event(old_id, new_id);
            }
            self.game_state.apply_event(&self.object_types, &event);
            for player in self.players.iter() {
                let event_list = self.event_lists.get_mut(&player.id).unwrap();
                // TODO: per player event filter
                event_list.push(event.clone());
            }
        }
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>//! Various helpers for Actix applications to use during testing.
use std::sync::mpsc;
use std::{net, thread, time};

use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_rt::{Runtime, System};
use actix_server::{Server, StreamServiceFactory};
use awc::{error::PayloadError, ws, Client, ClientRequest, ClientResponse, Connector};
use bytes::Bytes;
use futures::future::lazy;
use futures::{Future, Stream};
use http::Method;
use net2::TcpBuilder;

/// The `TestServer` type.
///
/// `TestServer` is very simple test server that simplify process of writing
/// integration tests cases for actix web applications.
///
/// # Examples
///
/// ```rust
/// use actix_http::HttpService;
/// use actix_http_test::TestServer;
/// use actix_web::{web, App, HttpResponse};
///
/// fn my_handler() -> HttpResponse {
///     HttpResponse::Ok().into()
/// }
///
/// fn main() {
///     let mut srv = TestServer::new(
///         || HttpService::new(
///             App::new().service(
///                 web::resource("/").to(my_handler))
///         )
///     );
///
///     let req = srv.get("/");
///     let response = srv.block_on(req.send()).unwrap();
///     assert!(response.status().is_success());
/// }
/// ```
pub struct TestServer;

/// Test server controller
pub struct TestServerRuntime {
    addr: net::SocketAddr,
    rt: Runtime,
    client: Client,
}

impl TestServer {
    /// Start new test server with application factory
    pub fn new<F: StreamServiceFactory>(factory: F) -> TestServerRuntime {
        let (tx, rx) = mpsc::channel();

        // run server in separate thread
        thread::spawn(move || {
            let sys = System::new("actix-test-server");
            let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
            let local_addr = tcp.local_addr().unwrap();

            Server::build()
                .listen("test", tcp, factory)?
                .workers(1)
                .disable_signals()
                .start();

            tx.send((System::current(), local_addr)).unwrap();
            sys.run()
        });

        let (system, addr) = rx.recv().unwrap();
        let mut rt = Runtime::new().unwrap();

        let client = rt
            .block_on(lazy(move || {
                let connector = {
                    #[cfg(feature = "ssl")]
                    {
                        use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};

                        let mut builder =
                            SslConnector::builder(SslMethod::tls()).unwrap();
                        builder.set_verify(SslVerifyMode::NONE);
                        let _ = builder.set_alpn_protos(b"\x02h2\x08http/1.1").map_err(
                            |e| log::error!("Can not set alpn protocol: {:?}", e),
                        );
                        Connector::new()
                            .timeout(time::Duration::from_millis(500))
                            .ssl(builder.build())
                            .service()
                    }
                    #[cfg(not(feature = "ssl"))]
                    {
                        Connector::new()
                            .timeout(time::Duration::from_millis(500))
                            .service()
                    }
                };

                Ok::<Client, ()>(Client::build().connector(connector).finish())
            }))
            .unwrap();
        System::set_current(system);
        TestServerRuntime { addr, rt, client }
    }

    /// Get firat available unused address
    pub fn unused_addr() -> net::SocketAddr {
        let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
        let socket = TcpBuilder::new_v4().unwrap();
        socket.bind(&addr).unwrap();
        socket.reuse_address(true).unwrap();
        let tcp = socket.to_tcp_listener().unwrap();
        tcp.local_addr().unwrap()
    }
}

impl TestServerRuntime {
    /// Execute future on current core
    pub fn block_on<F, I, E>(&mut self, fut: F) -> Result<I, E>
    where
        F: Future<Item = I, Error = E>,
    {
        self.rt.block_on(fut)
    }

    /// Execute function on current core
    pub fn execute<F, R>(&mut self, fut: F) -> R
    where
        F: FnOnce() -> R,
    {
        self.rt.block_on(lazy(|| Ok::<_, ()>(fut()))).unwrap()
    }

    /// Construct test server url
    pub fn addr(&self) -> net::SocketAddr {
        self.addr
    }

    /// Construct test server url
    pub fn url(&self, uri: &str) -> String {
        if uri.starts_with('/') {
            format!("http://127.0.0.1:{}{}", self.addr.port(), uri)
        } else {
            format!("http://127.0.0.1:{}/{}", self.addr.port(), uri)
        }
    }

    /// Construct test https server url
    pub fn surl(&self, uri: &str) -> String {
        if uri.starts_with('/') {
            format!("https://127.0.0.1:{}{}", self.addr.port(), uri)
        } else {
            format!("https://127.0.0.1:{}/{}", self.addr.port(), uri)
        }
    }

    /// Create `GET` request
    pub fn get<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.get(self.url(path.as_ref()).as_str())
    }

    /// Create https `GET` request
    pub fn sget<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.get(self.surl(path.as_ref()).as_str())
    }

    /// Create `POST` request
    pub fn post<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.post(self.url(path.as_ref()).as_str())
    }

    /// Create https `POST` request
    pub fn spost<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.post(self.surl(path.as_ref()).as_str())
    }

    /// Create `HEAD` request
    pub fn head<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.head(self.url(path.as_ref()).as_str())
    }

    /// Create https `HEAD` request
    pub fn shead<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.head(self.surl(path.as_ref()).as_str())
    }

    /// Connect to test http server
    pub fn request<S: AsRef<str>>(&self, method: Method, path: S) -> ClientRequest {
        self.client.request(method, path.as_ref())
    }

    pub fn load_body<S>(
        &mut self,
        response: ClientResponse<S>,
    ) -> Result<Bytes, PayloadError>
    where
        S: Stream<Item = Bytes, Error = PayloadError> + 'static,
    {
        self.block_on(response.body().limit(10_485_760))
    }

    /// Connect to websocket server at a given path
    pub fn ws_at(
        &mut self,
        path: &str,
    ) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError>
    {
        let url = self.url(path);
        let connect = self.client.ws(url).connect();
        self.rt
            .block_on(lazy(move || connect.map(|(_, framed)| framed)))
    }

    /// Connect to a websocket server
    pub fn ws(
        &mut self,
    ) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError>
    {
        self.ws_at("/")
    }

    /// Stop http server
    fn stop(&mut self) {
        System::current().stop();
    }
}

impl Drop for TestServerRuntime {
    fn drop(&mut self) {
        self.stop()
    }
}
<commit_msg>mut obj<commit_after>//! Various helpers for Actix applications to use during testing.
use std::sync::mpsc;
use std::{net, thread, time};

use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_rt::{Runtime, System};
use actix_server::{Server, StreamServiceFactory};
use awc::{error::PayloadError, ws, Client, ClientRequest, ClientResponse, Connector};
use bytes::Bytes;
use futures::future::lazy;
use futures::{Future, Stream};
use http::Method;
use net2::TcpBuilder;

/// The `TestServer` type.
///
/// `TestServer` is very simple test server that simplify process of writing
/// integration tests cases for actix web applications.
///
/// # Examples
///
/// ```rust
/// use actix_http::HttpService;
/// use actix_http_test::TestServer;
/// use actix_web::{web, App, HttpResponse};
///
/// fn my_handler() -> HttpResponse {
///     HttpResponse::Ok().into()
/// }
///
/// fn main() {
///     let mut srv = TestServer::new(
///         || HttpService::new(
///             App::new().service(
///                 web::resource("/").to(my_handler))
///         )
///     );
///
///     let req = srv.get("/");
///     let response = srv.block_on(req.send()).unwrap();
///     assert!(response.status().is_success());
/// }
/// ```
pub struct TestServer;

/// Test server controller
pub struct TestServerRuntime {
    addr: net::SocketAddr,
    rt: Runtime,
    client: Client,
}

impl TestServer {
    /// Start new test server with application factory
    pub fn new<F: StreamServiceFactory>(factory: F) -> TestServerRuntime {
        let (tx, rx) = mpsc::channel();

        // run server in separate thread
        thread::spawn(move || {
            let sys = System::new("actix-test-server");
            let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
            let local_addr = tcp.local_addr().unwrap();

            Server::build()
                .listen("test", tcp, factory)?
                .workers(1)
                .disable_signals()
                .start();

            tx.send((System::current(), local_addr)).unwrap();
            sys.run()
        });

        let (system, addr) = rx.recv().unwrap();
        let mut rt = Runtime::new().unwrap();

        let client = rt
            .block_on(lazy(move || {
                let connector = {
                    #[cfg(feature = "ssl")]
                    {
                        use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};

                        let mut builder =
                            SslConnector::builder(SslMethod::tls()).unwrap();
                        builder.set_verify(SslVerifyMode::NONE);
                        let _ = builder.set_alpn_protos(b"\x02h2\x08http/1.1").map_err(
                            |e| log::error!("Can not set alpn protocol: {:?}", e),
                        );
                        Connector::new()
                            .timeout(time::Duration::from_millis(500))
                            .ssl(builder.build())
                            .service()
                    }
                    #[cfg(not(feature = "ssl"))]
                    {
                        Connector::new()
                            .timeout(time::Duration::from_millis(500))
                            .service()
                    }
                };

                Ok::<Client, ()>(Client::build().connector(connector).finish())
            }))
            .unwrap();
        System::set_current(system);
        TestServerRuntime { addr, rt, client }
    }

    /// Get firat available unused address
    pub fn unused_addr() -> net::SocketAddr {
        let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
        let socket = TcpBuilder::new_v4().unwrap();
        socket.bind(&addr).unwrap();
        socket.reuse_address(true).unwrap();
        let tcp = socket.to_tcp_listener().unwrap();
        tcp.local_addr().unwrap()
    }
}

impl TestServerRuntime {
    /// Execute future on current core
    pub fn block_on<F, I, E>(&mut self, fut: F) -> Result<I, E>
    where
        F: Future<Item = I, Error = E>,
    {
        self.rt.block_on(fut)
    }

    /// Execute function on current core
    pub fn execute<F, R>(&mut self, fut: F) -> R
    where
        F: FnOnce() -> R,
    {
        self.rt.block_on(lazy(|| Ok::<_, ()>(fut()))).unwrap()
    }

    /// Construct test server url
    pub fn addr(&self) -> net::SocketAddr {
        self.addr
    }

    /// Construct test server url
    pub fn url(&self, uri: &str) -> String {
        if uri.starts_with('/') {
            format!("http://127.0.0.1:{}{}", self.addr.port(), uri)
        } else {
            format!("http://127.0.0.1:{}/{}", self.addr.port(), uri)
        }
    }

    /// Construct test https server url
    pub fn surl(&self, uri: &str) -> String {
        if uri.starts_with('/') {
            format!("https://127.0.0.1:{}{}", self.addr.port(), uri)
        } else {
            format!("https://127.0.0.1:{}/{}", self.addr.port(), uri)
        }
    }

    /// Create `GET` request
    pub fn get<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.get(self.url(path.as_ref()).as_str())
    }

    /// Create https `GET` request
    pub fn sget<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.get(self.surl(path.as_ref()).as_str())
    }

    /// Create `POST` request
    pub fn post<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.post(self.url(path.as_ref()).as_str())
    }

    /// Create https `POST` request
    pub fn spost<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.post(self.surl(path.as_ref()).as_str())
    }

    /// Create `HEAD` request
    pub fn head<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.head(self.url(path.as_ref()).as_str())
    }

    /// Create https `HEAD` request
    pub fn shead<S: AsRef<str>>(&self, path: S) -> ClientRequest {
        self.client.head(self.surl(path.as_ref()).as_str())
    }

    /// Connect to test http server
    pub fn request<S: AsRef<str>>(&self, method: Method, path: S) -> ClientRequest {
        self.client.request(method, path.as_ref())
    }

    pub fn load_body<S>(
        &mut self,
        mut response: ClientResponse<S>,
    ) -> Result<Bytes, PayloadError>
    where
        S: Stream<Item = Bytes, Error = PayloadError> + 'static,
    {
        self.block_on(response.body().limit(10_485_760))
    }

    /// Connect to websocket server at a given path
    pub fn ws_at(
        &mut self,
        path: &str,
    ) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError>
    {
        let url = self.url(path);
        let connect = self.client.ws(url).connect();
        self.rt
            .block_on(lazy(move || connect.map(|(_, framed)| framed)))
    }

    /// Connect to a websocket server
    pub fn ws(
        &mut self,
    ) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError>
    {
        self.ws_at("/")
    }

    /// Stop http server
    fn stop(&mut self) {
        System::current().stop();
    }
}

impl Drop for TestServerRuntime {
    fn drop(&mut self) {
        self.stop()
    }
}
<|endoftext|>


<commit_before>extern crate netcode;
extern crate time;
extern crate log;
extern crate env_logger;

use netcode::{UdpServer, ServerEvent, UdpClient, ClientEvent, ClientState, NETCODE_MAX_PAYLOAD_SIZE};

use std::thread;
use std::sync::mpsc;
use std::time::Duration;
use std::io::{self, BufRead};

const MAX_CLIENTS: usize = 256;     //Total number of clients we support
const PROTOCOL_ID: u64 = 0xFFDDEE;  //Unique protocol id for our application.
const TOKEN_LIFETIME: usize = 15;   //Our token lives 15 seconds.

const CLIENT_ID: u64 = 0xDDEEFF;    //Single unique client id, you'll want to tie this into
                                    // your user store in production.

const TICK_TIME_MS: f64 = 0.016; //Tick every 16ms

//Helper function for sleeping at a regular interval
fn sleep_for_tick(last_tick: &mut f64) -> f64 {
    let now = time::precise_time_s();

    let elapsed = (now - *last_tick).min(TICK_TIME_MS);

    if elapsed < TICK_TIME_MS {
        let sleep_ms = ((TICK_TIME_MS - elapsed) * 1000.0).floor() as u64;
        thread::sleep(Duration::from_millis(sleep_ms));
    }

    *last_tick = now;
    TICK_TIME_MS
}

fn main() {
    {
        use env_logger::LogBuilder;
        use log::LogLevelFilter;

        //Uncomment the below line to turn on verbose debugging for netcode
        //LogBuilder::new().filter(None, LogLevelFilter::Trace).init().unwrap();
    }

    let mut server = UdpServer::new("127.0.0.1:0", MAX_CLIENTS, PROTOCOL_ID, &netcode::generate_key()).unwrap();
    let token = server.generate_token(TOKEN_LIFETIME, CLIENT_ID, None).unwrap();

    let server_thread = thread::spawn(move || {
        let mut last = 0.0;
        loop {
            let elapsed = sleep_for_tick(&mut last);
            server.update(elapsed).unwrap();

            let mut packet = [0; NETCODE_MAX_PAYLOAD_SIZE];
            while let Some(event) = server.next_event(&mut packet).unwrap() {
                match event {
                    ServerEvent::ClientConnect(_id) => println!("Server: client connected"),
                    ServerEvent::ClientDisconnect(_id) => {
                        //Once our single client is done we should exit.
                        return
                    },
                    ServerEvent::Packet(id, size) => {
                        println!("Heard packet, echoing back");
                        server.send(id, &packet[..size]).unwrap();
                    },
                    ServerEvent::SentKeepAlive(_id) => {},
                    ServerEvent::RejectedClient => {},
                    ServerEvent::ReplayRejected(_id) => {},
                    ServerEvent::ClientSlotFull => {}
                }
            }
        }
    });

    let mut client = UdpClient::new(&token).unwrap();

    let (tx, rx) = mpsc::channel();
    let client_thread = thread::spawn(move || {
        let mut last = 0.0;
        loop {
            let elapsed = sleep_for_tick(&mut last);
            client.update(elapsed).unwrap();

            let mut packet = [0; NETCODE_MAX_PAYLOAD_SIZE];
            while let Some(event) = client.next_event(&mut packet).unwrap() {
                match event {
                    ClientEvent::NewState(state) => match state {
                        ClientState::Disconnected => return,
                        s => println!("Client: new state {:?}", s)
                    },
                    ClientEvent::Packet(len) => {
                        println!("{}", String::from_utf8_lossy(&packet[..len]));
                    },
                    ClientEvent::SentKeepAlive => {}
                }
            }

            let result: Option<String> = match rx.try_recv() {
                Ok(v) => Some(v),
                Err(mpsc::TryRecvError::Empty) => None,
                Err(_) => {
                    client.disconnect().unwrap_or(());
                    None
                }
            };

            match result {
                Some(ref s) if s == "exit" => {
                    client.disconnect().unwrap_or(());
                    return
                },
                Some(s) => client.send(&s.into_bytes()).map(|_| ()).unwrap_or(()),
                None => ()
            }
        }
    });

    //Read a line from stdin and send it to our client to process.
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let value = line.unwrap();
        if value == "exit" {
            tx.send(value).unwrap();
            break;
        } else {
            tx.send(value).unwrap()
        }
    }

    client_thread.join().unwrap();
    server_thread.join().unwrap();
}<commit_msg>Updating example.<commit_after>//! Sample netcode echo client + server. This is the bare minimum needed to show a full
//! working example. Creates two threads one for the server and one for the client.
//! The main thread listens for new lines and sends them to the client with a mpsc channel.
//! The client will then send the string to the server and the server will echo it back to the
//! client. Note that since this is a UDP based protocol it's expected some messages will be dropped.
//! Once done the string "exit" will cause the client to disconnect which the server will then
//! terminate when it hears the disconnect from the client.

extern crate netcode;
extern crate time;
extern crate log;
extern crate env_logger;

use netcode::{UdpServer, ServerEvent, UdpClient, ClientEvent, ClientState, NETCODE_MAX_PAYLOAD_SIZE};

use std::thread;
use std::sync::mpsc;
use std::time::Duration;
use std::io::{self, BufRead};

const MAX_CLIENTS: usize = 256;     //Total number of clients we support
const PROTOCOL_ID: u64 = 0xFFDDEE;  //Unique protocol id for our application.
const TOKEN_LIFETIME: usize = 15;   //Our token lives 15 seconds.

const CLIENT_ID: u64 = 0xDDEEFF;    //Single unique client id, you'll want to tie this into
                                    // your user store in production.

const TICK_TIME_MS: f64 = 0.016; //Tick every 16ms

//Helper function for sleeping at a regular interval
fn sleep_for_tick(last_tick: &mut f64) -> f64 {
    let now = time::precise_time_s();

    let elapsed = (now - *last_tick).min(TICK_TIME_MS);

    if elapsed < TICK_TIME_MS {
        let sleep_ms = ((TICK_TIME_MS - elapsed) * 1000.0).floor() as u64;
        thread::sleep(Duration::from_millis(sleep_ms));
    }

    *last_tick = now;
    TICK_TIME_MS
}

fn main() {
    //Uncomment the below block to turn on verbose debugging for netcode
    /*
    {
        use env_logger::LogBuilder;
        use log::LogLevelFilter;

        LogBuilder::new().filter(None, LogLevelFilter::Trace).init().unwrap();
    }
    */

    let mut server = UdpServer::new("127.0.0.1:0", MAX_CLIENTS, PROTOCOL_ID, &netcode::generate_key()).unwrap();
    let token = server.generate_token(TOKEN_LIFETIME, CLIENT_ID, None).unwrap();

    let server_thread = thread::spawn(move || {
        let mut last = 0.0;
        loop {
            let elapsed = sleep_for_tick(&mut last);
            server.update(elapsed).unwrap();

            let mut packet = [0; NETCODE_MAX_PAYLOAD_SIZE];
            while let Some(event) = server.next_event(&mut packet).unwrap() {
                match event {
                    ServerEvent::ClientConnect(_id) => println!("Server: client connected"),
                    ServerEvent::ClientDisconnect(_id) => {
                        //Once our single client is done we should exit.
                        return
                    },
                    ServerEvent::Packet(id, size) => {
                        println!("Heard packet, echoing back");
                        server.send(id, &packet[..size]).unwrap();
                    },
                    ServerEvent::SentKeepAlive(_id) => {},
                    ServerEvent::RejectedClient => {},
                    ServerEvent::ReplayRejected(_id) => {},
                    ServerEvent::ClientSlotFull => {}
                }
            }
        }
    });

    let mut client = UdpClient::new(&token).unwrap();

    let (tx, rx) = mpsc::channel();
    let client_thread = thread::spawn(move || {
        let mut last = 0.0;
        loop {
            let elapsed = sleep_for_tick(&mut last);
            client.update(elapsed).unwrap();

            let mut packet = [0; NETCODE_MAX_PAYLOAD_SIZE];
            while let Some(event) = client.next_event(&mut packet).unwrap() {
                match event {
                    ClientEvent::NewState(state) => match state {
                        ClientState::Disconnected => return,
                        s => println!("Client: new state {:?}", s)
                    },
                    ClientEvent::Packet(len) => {
                        println!("{}", String::from_utf8_lossy(&packet[..len]));
                    },
                    ClientEvent::SentKeepAlive => {}
                }
            }

            let result: Option<String> = match rx.try_recv() {
                Ok(v) => Some(v),
                Err(mpsc::TryRecvError::Empty) => None,
                Err(_) => {
                    client.disconnect().unwrap_or(());
                    None
                }
            };

            match result {
                Some(ref s) if s == "exit" => {
                    client.disconnect().unwrap_or(());
                    return
                },
                Some(s) => client.send(&s.into_bytes()).map(|_| ()).unwrap_or(()),
                None => ()
            }
        }
    });

    //Read a line from stdin and send it to our client to process.
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let value = line.unwrap();
        if value == "exit" {
            tx.send(value).unwrap();
            break;
        } else {
            tx.send(value).unwrap()
        }
    }

    client_thread.join().unwrap();
    server_thread.join().unwrap();
}<|endoftext|>


<commit_before>// test main
extern crate twobit;
use std::os;
use twobit::TwoBit;

fn print_sequence(seq: &str) {
   let mut i = 0;

   for base in seq.chars() {
     if i != 0 && (i % 50) == 0 {
       println!("");
     }
     print!("{}", base);
     i = i + 1;
   }
   println!("");
}

fn main() {
  let args = os::args();

	match args.as_slice() {
		[ _, ref filename, ref chrom, ref start, ref end ] => {

			let start = from_str::<u32>(start.as_slice()).expect("Invalid start coordinate");
			let end = from_str::<u32>(end.as_slice()).expect("Invalid end coordinate");

			let tb = TwoBit::new(filename.as_slice());

			match tb {
				Ok(tbv) => {
					// get chromosome size
 					match tbv.sequence_len(chrom.as_slice()) {
   						Some(n) => println!("{}: size = {}", chrom, n),
   						None => {
     						println!("unknown sequence: {}", chrom);
     						return;
   						}
 					};

					let seq = tbv.sequence(chrom.as_slice(), start, end);
					match seq {
    	    			Some(seqstr) => {
      	    			println!(">{}:{}-{}", chrom, start, end + 1);
     					//println!("{}", seqstr);
     					print_sequence(seqstr.as_slice());
   					},
   					None => println!("nothing")
 					};
				},
				Err(std::io::IoError{ kind: _, desc: x, detail: _}) => println!("{}: {}", x, filename)
			}
		},
		[ ref prog, ..] => println!("Usage: {} <2bit filename> <name> <start> <end>", prog),
		_ => fail!()
	}
}
<commit_msg>Indentation fixes (2)<commit_after>// test main
extern crate twobit;
use std::os;
use twobit::TwoBit;

fn print_sequence(seq: &str) {
   let mut i = 0;

   for base in seq.chars() {
	 if i != 0 && (i % 50) == 0 {
	   println!("");
	 }
	 print!("{}", base);
	 i = i + 1;
   }
   println!("");
}

fn main() {
	let args = os::args();

	match args.as_slice() {
		[ _, ref filename, ref chrom, ref start, ref end ] => {

			let start = from_str::<u32>(start.as_slice()).expect("Invalid start coordinate");
			let end = from_str::<u32>(end.as_slice()).expect("Invalid end coordinate");

			let tb = TwoBit::new(filename.as_slice());

			match tb {
				Ok(tbv) => {
					// get chromosome size
					match tbv.sequence_len(chrom.as_slice()) {
						Some(n) => println!("{}: size = {}", chrom, n),
						None => {
							println!("unknown sequence: {}", chrom);
							return;
						}
					};

					let seq = tbv.sequence(chrom.as_slice(), start, end);
					match seq {
						Some(seqstr) => {
						println!(">{}:{}-{}", chrom, start, end + 1);
						//println!("{}", seqstr);
						print_sequence(seqstr.as_slice());
					},
					None => println!("nothing")
					};
				},
				Err(std::io::IoError{ kind: _, desc: x, detail: _}) => println!("{}: {}", x, filename)
			}
		},
		[ ref prog, ..] => println!("Usage: {} <2bit filename> <name> <start> <end>", prog),
		_ => fail!()
	}
}
<|endoftext|>


<commit_before>//! Find the last but one (last and penultimate) elements of a list.
///# example
///```
///use p99::p2::last_two;
///assert_eq!(last_two(&['a','b','c','d']),Some(['c','d']));
///assert_eq!(last_two(&['a']),None);
///assert_eq!(last_two(&[]),None);
///```

pub fn last_two(list: &[char]) -> Option<[char; 2]> {
    if list.len() > 1 {
        Some([list[list.len() - 2], list[list.len() - 1]])
    } else {
        None
    }
}
<commit_msg>generic p2<commit_after>//! Find the last but one (last and penultimate) elements of a list.
///# example
///```
///use p99::p2::last_two;
///assert_eq!(last_two(&['a','b','c','d']),Some(['c','d']));
///assert_eq!(last_two(&['a']),None);
///let list:&[char] = &[];
///assert_eq!(last_two(list),None);
///```

use std::clone::Clone;
pub fn last_two<T: PartialEq + Clone>(list: &[T]) -> Option<[T; 2]> {
    if list.len() > 1 {
        Some([list[list.len() - 2].clone(), list[list.len() - 1].clone()])
    } else {
        None
    }
}
<|endoftext|>


<commit_before>use ffi::prelude::LLVMTypeRef;
use ffi::{core, target, LLVMTypeKind};
use libc::{c_int, c_uint};
use compile::Compile;
use context::{Context, GetContext};
use target::TargetData;
use util::{self, CastFrom};
use std::{fmt, mem};
use std::iter::Iterator;
use std::ops::Deref;

/// Defines how a value should be laid out in memory.
pub struct Type;
native_ref!(&Type = LLVMTypeRef);
impl Type {
    #[inline(always)]
    /// Get the type given as an LLVM type descriptor in the context given.
    pub fn get<'a, T>(context:&'a Context) -> &'a Type where T:Compile<'a> {
        T::get_type(context)
    }
    /// Make a new function signature with the return type and arguments given.
    pub fn new_function<'a>(ret: &'a Type, args: &[&'a Type]) -> &'a FunctionType {
        unsafe { core::LLVMFunctionType(ret.into(), args.as_ptr() as *mut LLVMTypeRef, args.len() as c_uint, 0) }.into()
    }
    /// Make a new array with the length given.
    pub fn new_array<'a>(element: &'a Type, length: usize) -> &'a Type {
        unsafe { core::LLVMArrayType(element.into(), length as c_uint) }.into()
    }
    /// Make a new vector with the length given.
    pub fn new_vector<'a>(element: &'a Type, length: usize) -> &'a Type {
        unsafe { core::LLVMVectorType(element.into(), length as c_uint) }.into()
    }
    /// Make a new pointer with the given element type.
    pub fn new_pointer<'a>(elem: &'a Type) -> &'a Type {
        unsafe { core::LLVMPointerType(elem.into(), 0 as c_uint) }.into()
    }
    /// Make a new structure type with the given types.
    pub fn new_struct<'a>(elems: &[&'a Type], packed: bool) -> &'a Type {
        unsafe { core::LLVMStructType(elems.as_ptr() as *mut LLVMTypeRef, elems.len() as c_uint, packed as c_int) }.into()
    }
    /// Returns true if the size of the type is known at compile-time.
    ///
    /// This is equivalent to the type implementing `Sized` in Rust
    pub fn is_sized(&self) -> bool {
        unsafe { core::LLVMTypeIsSized(self.into()) != 0 }
    }
    /// Returns true if this type is a function.
    pub fn is_function(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMFunctionTypeKind as c_uint
    }
    /// Returns true if this type is a struct.
    pub fn is_struct(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMStructTypeKind as c_uint
    }
    /// Returns the size of the type in bytes.
    pub fn get_size(&self, target: &TargetData) -> usize {
        unsafe { target::LLVMABISizeOfType(target.into(), self.into()) as usize }
    }
    /// Returns the element of this pointer type.
    pub fn get_element(&self) -> Option<&Type> {
        unsafe { mem::transmute(core::LLVMGetElementType(self.into())) }
    }
}
get_context!(Type, LLVMGetTypeContext);
to_str!(Type, LLVMPrintTypeToString);

/// A structure type, such as a tuple or struct
pub struct StructType;
native_ref!(&StructType = LLVMTypeRef);
impl StructType {
    /// Make a new struct with the given fields and packed representation.
    pub fn new<'a>(context: &'a Context, fields: &[&'a Type], packed: bool) -> &'a StructType {
        unsafe { core::LLVMStructTypeInContext(context.into(), fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int) }.into()
    }
    /// Make a new named struct with the given fields and packed representation.
    pub fn new_named<'a>(context: &'a Context, name: &str, fields: &[&'a Type], packed: bool) -> &'a StructType {
        util::with_cstr(name, |name| unsafe {
            let ty = core::LLVMStructCreateNamed(context.into(), name);
            core::LLVMStructSetBody(ty, fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int);
            ty.into()
        })
    }
    /// Returns the elements (AKA fields) that make up this struct.
    pub fn get_elements(&self) -> Vec<Type> {
        unsafe {
            let size = core::LLVMCountStructElementTypes(self.into());
            let mut els:Vec<_> = (0..size).map(|_| mem::uninitialized()).collect();
            core::LLVMGetStructElementTypes(self.into(), els.as_mut_ptr() as *mut LLVMTypeRef);
            els
        }
    }
}
impl CastFrom for StructType {
    type From = Type;
    fn cast(ty: &Type) -> Option<&StructType> {
        unsafe {
            let kind = core::LLVMGetTypeKind(ty.into());
            if kind as c_uint == LLVMTypeKind::LLVMStructTypeKind as c_uint {
                mem::transmute(ty)
            } else {
                None
            }
        }
    }
}
deref!(StructType, Type);
get_context!(StructType, LLVMGetTypeContext);
to_str!(StructType, LLVMPrintTypeToString);

/// A function signature type
pub struct FunctionType;
native_ref!(&FunctionType = LLVMTypeRef);
deref!(FunctionType, Type);
impl CastFrom for FunctionType {
    type From = Type;
    fn cast(mut ty: &Type) -> Option<&FunctionType> {
        unsafe {
            use libc::c_uint;
            while let Some(elem) = ty.get_element() {
                ty = elem;
            }
            let kind = core::LLVMGetTypeKind(ty.into());
            if kind as c_uint == LLVMTypeKind::LLVMFunctionTypeKind as c_uint {
                mem::transmute(ty)
            } else {
                None
            }
        }
    }
}
impl FunctionType {
    /// Returns how many parameters this signature takes.
    pub fn num_params(&self) -> usize {
        unsafe { core::LLVMCountParamTypes(self.into()) as usize }
    }
    /// Returns a vector of this signature's parameters' types.
    pub fn get_params(&self) -> Vec<&Type> {
        unsafe {
            let count = core::LLVMCountParamTypes(self.into());
            let mut types:Vec<_> = (0..count).map(|_| mem::uninitialized()).collect();
            core::LLVMGetParamTypes(self.into(), types.as_mut_ptr() as *mut LLVMTypeRef);
            types
        }
    }
    /// Returns the type that this function returns.
    pub fn get_return(&self) -> &Type {
        unsafe { core::LLVMGetReturnType(self.into()).into() }
    }
}
get_context!(FunctionType, LLVMGetTypeContext);
to_str!(FunctionType, LLVMPrintTypeToString);
<commit_msg>Add Type.is_void<commit_after>use ffi::prelude::LLVMTypeRef;
use ffi::{core, target, LLVMTypeKind};
use libc::{c_int, c_uint};
use compile::Compile;
use context::{Context, GetContext};
use target::TargetData;
use util::{self, CastFrom};
use std::{fmt, mem};
use std::iter::Iterator;
use std::ops::Deref;

/// Defines how a value should be laid out in memory.
pub struct Type;
native_ref!(&Type = LLVMTypeRef);
impl Type {
    #[inline(always)]
    /// Get the type given as an LLVM type descriptor in the context given.
    pub fn get<'a, T>(context:&'a Context) -> &'a Type where T:Compile<'a> {
        T::get_type(context)
    }
    /// Make a new function signature with the return type and arguments given.
    pub fn new_function<'a>(ret: &'a Type, args: &[&'a Type]) -> &'a FunctionType {
        unsafe { core::LLVMFunctionType(ret.into(), args.as_ptr() as *mut LLVMTypeRef, args.len() as c_uint, 0) }.into()
    }
    /// Make a new array with the length given.
    pub fn new_array<'a>(element: &'a Type, length: usize) -> &'a Type {
        unsafe { core::LLVMArrayType(element.into(), length as c_uint) }.into()
    }
    /// Make a new vector with the length given.
    pub fn new_vector<'a>(element: &'a Type, length: usize) -> &'a Type {
        unsafe { core::LLVMVectorType(element.into(), length as c_uint) }.into()
    }
    /// Make a new pointer with the given element type.
    pub fn new_pointer<'a>(elem: &'a Type) -> &'a Type {
        unsafe { core::LLVMPointerType(elem.into(), 0 as c_uint) }.into()
    }
    /// Make a new structure type with the given types.
    pub fn new_struct<'a>(elems: &[&'a Type], packed: bool) -> &'a Type {
        unsafe { core::LLVMStructType(elems.as_ptr() as *mut LLVMTypeRef, elems.len() as c_uint, packed as c_int) }.into()
    }
    /// Returns true if the size of the type is known at compile-time.
    ///
    /// This is equivalent to the type implementing `Sized` in Rust
    pub fn is_sized(&self) -> bool {
        unsafe { core::LLVMTypeIsSized(self.into()) != 0 }
    }
    /// Returns true if this type is a function.
    pub fn is_function(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMFunctionTypeKind as c_uint
    }
    /// Returns true if this type is a struct.
    pub fn is_struct(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMStructTypeKind as c_uint
    }
    /// Returns true if this type is void.
    pub fn is_void(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMVoidTypeKind as c_uint
    }
    /// Returns the size of the type in bytes.
    pub fn get_size(&self, target: &TargetData) -> usize {
        unsafe { target::LLVMABISizeOfType(target.into(), self.into()) as usize }
    }
    /// Returns the element of this pointer type.
    pub fn get_element(&self) -> Option<&Type> {
        unsafe { mem::transmute(core::LLVMGetElementType(self.into())) }
    }
}
get_context!(Type, LLVMGetTypeContext);
to_str!(Type, LLVMPrintTypeToString);

/// A structure type, such as a tuple or struct
pub struct StructType;
native_ref!(&StructType = LLVMTypeRef);
impl StructType {
    /// Make a new struct with the given fields and packed representation.
    pub fn new<'a>(context: &'a Context, fields: &[&'a Type], packed: bool) -> &'a StructType {
        unsafe { core::LLVMStructTypeInContext(context.into(), fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int) }.into()
    }
    /// Make a new named struct with the given fields and packed representation.
    pub fn new_named<'a>(context: &'a Context, name: &str, fields: &[&'a Type], packed: bool) -> &'a StructType {
        util::with_cstr(name, |name| unsafe {
            let ty = core::LLVMStructCreateNamed(context.into(), name);
            core::LLVMStructSetBody(ty, fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int);
            ty.into()
        })
    }
    /// Returns the elements (AKA fields) that make up this struct.
    pub fn get_elements(&self) -> Vec<Type> {
        unsafe {
            let size = core::LLVMCountStructElementTypes(self.into());
            let mut els:Vec<_> = (0..size).map(|_| mem::uninitialized()).collect();
            core::LLVMGetStructElementTypes(self.into(), els.as_mut_ptr() as *mut LLVMTypeRef);
            els
        }
    }
}
impl CastFrom for StructType {
    type From = Type;
    fn cast(ty: &Type) -> Option<&StructType> {
        unsafe {
            let kind = core::LLVMGetTypeKind(ty.into());
            if kind as c_uint == LLVMTypeKind::LLVMStructTypeKind as c_uint {
                mem::transmute(ty)
            } else {
                None
            }
        }
    }
}
deref!(StructType, Type);
get_context!(StructType, LLVMGetTypeContext);
to_str!(StructType, LLVMPrintTypeToString);

/// A function signature type
pub struct FunctionType;
native_ref!(&FunctionType = LLVMTypeRef);
deref!(FunctionType, Type);
impl CastFrom for FunctionType {
    type From = Type;
    fn cast(mut ty: &Type) -> Option<&FunctionType> {
        unsafe {
            use libc::c_uint;
            while let Some(elem) = ty.get_element() {
                ty = elem;
            }
            let kind = core::LLVMGetTypeKind(ty.into());
            if kind as c_uint == LLVMTypeKind::LLVMFunctionTypeKind as c_uint {
                mem::transmute(ty)
            } else {
                None
            }
        }
    }
}
impl FunctionType {
    /// Returns how many parameters this signature takes.
    pub fn num_params(&self) -> usize {
        unsafe { core::LLVMCountParamTypes(self.into()) as usize }
    }
    /// Returns a vector of this signature's parameters' types.
    pub fn get_params(&self) -> Vec<&Type> {
        unsafe {
            let count = core::LLVMCountParamTypes(self.into());
            let mut types:Vec<_> = (0..count).map(|_| mem::uninitialized()).collect();
            core::LLVMGetParamTypes(self.into(), types.as_mut_ptr() as *mut LLVMTypeRef);
            types
        }
    }
    /// Returns the type that this function returns.
    pub fn get_return(&self) -> &Type {
        unsafe { core::LLVMGetReturnType(self.into()).into() }
    }
}
get_context!(FunctionType, LLVMGetTypeContext);
to_str!(FunctionType, LLVMPrintTypeToString);
<|endoftext|>