<commit_before>//! This example demonstrates using Raft to implement a replicated hashmap over `n` servers and
//! interact with them over `m` clients.
//!
//! This example uses Bincode serialization.
//!
//! Comments below will aim to be tailored towards Raft and it's usage. If you have any questions,
//! Please, just open an issue.
//!
//! TODO: For the sake of simplicity of this example, we don't implement a `Log` and just use a
//! simple testing one. We should improve this in the future.

extern crate raft; // <--- Kind of a big deal for this!
extern crate docopt;
extern crate env_logger;
extern crate rustc_serialize;
extern crate bincode;

use std::net::SocketAddr;
use std::str::FromStr;
use std::collections::HashMap;

use docopt::Docopt;
use bincode::SizeLimit;

// Raft's major components. See comments in code on usage and things.
use raft::{
    state_machine,
    persistent_log,
    ServerId,
    Server,
    Client,
};

/// This is the defined message type for this example. For the sake of simplicity we don't go very
/// far with this. In a "real" application you may want to more distinctly distinguish between
/// data meant for `.query()` and data meant for `.propose()`.
#[derive(RustcEncodable, RustcDecodable, PartialEq)]
enum Message {
    Get,
    Put(Vec<u8>),
    Cas(Vec<u8>, Vec<u8>),
}

// Using docopt we define the overall usage of the application.
static USAGE: &'static str = "
A replicated mutable value. Operations on the register have serializable
consistency, but no durability (once all register servers are terminated the
value is lost).

Each register server holds a replica of the register, and coordinates with its
peers to update the register's value according to client commands. The register
is available for reading and writing only if a majority of register servers are
available.

Commands:

  get     Returns the current value of the register.

  put     Sets the current value of the register, and returns the previous
          value.

  cas     (compare and set) Conditionally sets the value of the register if the
          current value matches an expected value, returning true if the
          register was set.

  server  Starts a register server. Servers must be provided a unique ID and
          address (ip:port) at startup, along with the ID and address of all
          peer servers.

Usage:
  register get (<node-address>)...
  register put <new-value> (<node-address>)...
  register cas <expected-value> <new-value> (<node-address>)...
  register server <id> [<node-id> <node-address>]...
  register (-h | --help)

Options:
  -h --help   Show a help message.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_server: bool,
    cmd_get: bool,
    cmd_put: bool,
    cmd_cas: bool,

    // When creating a server you will necessarily need some sort of unique ID for it as well
    // as a list of peers. In this example we just accept them straight from args. You might
    // find it best to use a `toml` or `yaml` or `json` file.
    arg_id: Option<u64>,
    arg_node_id: Vec<u64>,
    arg_node_address: Vec<String>,
    arg_server_id: Option<u64>,

    arg_new_value: String,
    arg_expected_value: String,
}

/// Just a plain old boring "parse args and dispatch" call.
fn main() {
    let _ = env_logger::init();
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());
    if args.cmd_server {
        server(&args);
    } else if args.cmd_get {
        get(&args);
    } else if args.cmd_put {
        put(&args);
    } else if args.cmd_cas {
        cas(&args);
    }
}

/// A simple convenience method since this is an example and it should exit if given invalid params.
fn parse_addr(addr: &str) -> SocketAddr {
    SocketAddr::from_str(addr)
               .ok()
               .expect(&format!("unable to parse socket address: {}", addr))
}

/// Creates a Raft server using the specified ID from the list of nodes.
fn server(args: &Args) {
    // Creating a raft server requires several things:

    // A persistent log implementation, which manages the persistent, replicated log...
    let persistent_log = persistent_log::MemLog::new();

    // A state machine which replicated state. This state should be the same on all nodes.
    let state_machine = RegisterStateMachine::new();

    // As well as a unique server id.
    let id = ServerId::from(args.arg_id.unwrap());

    // ...  And a list of peers.
    let mut peers = args.arg_node_id
                    .iter()
                    .zip(args.arg_node_address.iter())
                    .map(|(&id, addr)| (ServerId::from(id), parse_addr(&addr)))
                    .collect::<HashMap<_,_>>();

    // The Raft Server will error if it's ID is inside of it's peer set. Don't do that.
    // Instead, take it out and use it!
    let addr = peers.remove(&id).unwrap();

    // Using all of the above components.
    // You probably shouldn't `.unwrap()` in production code unless you're totally sure it works
    // 100% of the time, all the time.
    Server::run(id, addr, peers, persistent_log, state_machine).unwrap();
}

/// Gets a value for the register from the provided Raft cluster.
fn get(args: &Args) {
    // Clients necessarily need to now the valid set of nodes which they can talk to.
    // This is both so they can try to talk to all the nodes if some are failing, and so that it
    // can verify that it's not being lead astray somehow in redirections on leadership changes.
    let cluster = args.arg_node_address.iter()
        .map(|v| parse_addr(&v))
        .collect();

    // Clients and be stored and reused, or used once and discarded.
    // There is very small overhead in connecting a new client to a cluster as it must discover and
    // identify itself to the leader.
    let mut client = Client::new(cluster);

    // Bincode makes it very easy to encode and fire off random enums and structs.
    let payload = Message::Get;
    let encoded = bincode::encode(&payload, SizeLimit::Infinite).unwrap();

    // A query executes **immutably** on the leader of the cluster and does not pass through the
    // persistent log. This is intended for querying the current state of the state machine.
    let response = client.query(&encoded).unwrap();

    // A response will block until it's query is complete. This is intended and expected behavior
    // based on the papers specifications.
    let val = bincode::decode::<String>(&response).unwrap();
    println!("{}", val)
}

/// Sets a value for a given key in the provided Raft cluster.
fn put(args: &Args) {
    // Same as above.
    let cluster = args.arg_node_address.iter()
        .map(|v| parse_addr(&v))
        .collect();
    let mut client = Client::new(cluster);

    let payload = Message::Put(args.arg_new_value.clone().into_bytes());
    let encoded = bincode::encode(&payload, SizeLimit::Infinite).unwrap();

    // A propose will go through the persistent log and mutably modify the state machine in some
    // way. This is **much** slower than `.query()`.
    let response = client.propose(&encoded).unwrap();

    let val = bincode::decode::<String>(&response).unwrap();
    println!("{}", val)
}

/// Compares and sets a value for a given key in the provided Raft cluster if the value is what is
/// expected.
fn cas(args: &Args) {
    // Same as above.
    let cluster = args.arg_node_address.iter()
        .map(|v| parse_addr(&v))
        .collect();
    let mut client = Client::new(cluster);

    let payload = Message::Cas(
        args.arg_expected_value.clone().into_bytes(),
        args.arg_new_value.clone().into_bytes());
    let encoded = bincode::encode(&payload, SizeLimit::Infinite).unwrap();

    let response = client.propose(&encoded).unwrap();

    let val = bincode::decode::<String>(&response).unwrap();
    println!("{}", val)
}

/// A state machine that holds a single mutable value.
#[derive(Debug)]
pub struct RegisterStateMachine {
    value: Vec<u8>,
}

/// Implement anything you want... A `new()` is generally a great idea.
impl RegisterStateMachine {
    pub fn new() -> RegisterStateMachine {
        RegisterStateMachine { value: vec![] }
    }
}

/// Implementing `state_machine::StateMachine` allows your application specific state machine to be
/// used in Raft. Feel encouraged to base yours of one of ours in these examples.
impl state_machine::StateMachine for RegisterStateMachine {

    /// `apply()` is called on when a client's `.propose()` is commited and reaches the state
    /// machine. At this point it is durable and is going to be applied on at least half the nodes
    /// within the next couple round trips.
    fn apply(&mut self, proposal: &[u8]) -> Vec<u8> {
        // Store the old value (example specific)
        let old_value = self.value.clone();

        // Deserialize
        let message = bincode::decode::<Message>(&proposal).unwrap();

        // Handle
        let response = (match message {
            Message::Put(val) => {
                self.value.clear();
                self.value.extend(val);
                bincode::encode(&old_value, SizeLimit::Infinite)
            },
            Message::Get => bincode::encode(&old_value, SizeLimit::Infinite),
            Message::Cas(test, new) => {
                if test == old_value {
                    self.value.clear();
                    self.value.extend(new);
                    bincode::encode(&true, SizeLimit::Infinite)
                } else {
                    bincode::encode(&false, SizeLimit::Infinite)
                }
            },
        }).unwrap();

        // Respond.
        response
    }

    /// `query()` is called on when a client's `.query()` is recieved. It does not go through the
    /// persistent log, it does not mutate the state of the state machine, and it is intended to be
    /// fast.
    fn query(&self, query: &[u8]) -> Vec<u8> {
        // Store the old value (example specific)
        let old_value = self.value.clone();

        // Deserialize
        let message = bincode::decode::<Message>(&query).unwrap();

        // Handle
        let response = (match message {
            Message::Get => bincode::encode(&old_value, SizeLimit::Infinite),
            _ => panic!("Cannot mutate from query!"),
        }).unwrap();

        // Respond.
        response
    }

    fn snapshot(&self) -> Vec<u8> {
        self.value.clone()
    }

    fn restore_snapshot(&mut self, snapshot_value: Vec<u8>) {
        self.value = snapshot_value;
        ()
    }
}
<commit_msg>Fix bincode too!<commit_after>//! This example demonstrates using Raft to implement a replicated hashmap over `n` servers and
//! interact with them over `m` clients.
//!
//! This example uses Bincode serialization.
//!
//! Comments below will aim to be tailored towards Raft and it's usage. If you have any questions,
//! Please, just open an issue.
//!
//! TODO: For the sake of simplicity of this example, we don't implement a `Log` and just use a
//! simple testing one. We should improve this in the future.

// In order to use Serde we need to enable these nightly features.
#![feature(plugin)]
#![feature(custom_derive)]
#![plugin(serde_macros)]

extern crate raft; // <--- Kind of a big deal for this!
extern crate docopt;
extern crate env_logger;
extern crate serde;
extern crate rustc_serialize;
extern crate bincode;

use std::net::SocketAddr;
use std::str::FromStr;
use std::collections::HashMap;

use docopt::Docopt;
use bincode::serde::{serialize, deserialize};
use bincode::SizeLimit;

// Raft's major components. See comments in code on usage and things.
use raft::{
    state_machine,
    persistent_log,
    ServerId,
    Server,
    Client,
};

/// This is the defined message type for this example. For the sake of simplicity we don't go very
/// far with this. In a "real" application you may want to more distinctly distinguish between
/// data meant for `.query()` and data meant for `.propose()`.
#[derive(Serialize, Deserialize, PartialEq)]
enum Message {
    Get,
    Put(Vec<u8>),
    Cas(Vec<u8>, Vec<u8>),
}

// Using docopt we define the overall usage of the application.
static USAGE: &'static str = "
A replicated mutable value. Operations on the register have serializable
consistency, but no durability (once all register servers are terminated the
value is lost).

Each register server holds a replica of the register, and coordinates with its
peers to update the register's value according to client commands. The register
is available for reading and writing only if a majority of register servers are
available.

Commands:

  get     Returns the current value of the register.

  put     Sets the current value of the register, and returns the previous
          value.

  cas     (compare and set) Conditionally sets the value of the register if the
          current value matches an expected value, returning true if the
          register was set.

  server  Starts a register server. Servers must be provided a unique ID and
          address (ip:port) at startup, along with the ID and address of all
          peer servers.

Usage:
  register get (<node-address>)...
  register put <new-value> (<node-address>)...
  register cas <expected-value> <new-value> (<node-address>)...
  register server <id> [<node-id> <node-address>]...
  register (-h | --help)

Options:
  -h --help   Show a help message.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_server: bool,
    cmd_get: bool,
    cmd_put: bool,
    cmd_cas: bool,

    // When creating a server you will necessarily need some sort of unique ID for it as well
    // as a list of peers. In this example we just accept them straight from args. You might
    // find it best to use a `toml` or `yaml` or `json` file.
    arg_id: Option<u64>,
    arg_node_id: Vec<u64>,
    arg_node_address: Vec<String>,
    arg_server_id: Option<u64>,

    arg_new_value: String,
    arg_expected_value: String,
}

/// Just a plain old boring "parse args and dispatch" call.
fn main() {
    let _ = env_logger::init();
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());
    if args.cmd_server {
        server(&args);
    } else if args.cmd_get {
        get(&args);
    } else if args.cmd_put {
        put(&args);
    } else if args.cmd_cas {
        cas(&args);
    }
}

/// A simple convenience method since this is an example and it should exit if given invalid params.
fn parse_addr(addr: &str) -> SocketAddr {
    SocketAddr::from_str(addr)
               .ok()
               .expect(&format!("unable to parse socket address: {}", addr))
}

/// Creates a Raft server using the specified ID from the list of nodes.
fn server(args: &Args) {
    // Creating a raft server requires several things:

    // A persistent log implementation, which manages the persistent, replicated log...
    let persistent_log = persistent_log::MemLog::new();

    // A state machine which replicated state. This state should be the same on all nodes.
    let state_machine = RegisterStateMachine::new();

    // As well as a unique server id.
    let id = ServerId::from(args.arg_id.unwrap());

    // ...  And a list of peers.
    let mut peers = args.arg_node_id
                    .iter()
                    .zip(args.arg_node_address.iter())
                    .map(|(&id, addr)| (ServerId::from(id), parse_addr(&addr)))
                    .collect::<HashMap<_,_>>();

    // The Raft Server will error if it's ID is inside of it's peer set. Don't do that.
    // Instead, take it out and use it!
    let addr = peers.remove(&id).unwrap();

    // Using all of the above components.
    // You probably shouldn't `.unwrap()` in production code unless you're totally sure it works
    // 100% of the time, all the time.
    Server::run(id, addr, peers, persistent_log, state_machine).unwrap();
}

/// Gets a value for the register from the provided Raft cluster.
fn get(args: &Args) {
    // Clients necessarily need to now the valid set of nodes which they can talk to.
    // This is both so they can try to talk to all the nodes if some are failing, and so that it
    // can verify that it's not being lead astray somehow in redirections on leadership changes.
    let cluster = args.arg_node_address.iter()
        .map(|v| parse_addr(&v))
        .collect();

    // Clients and be stored and reused, or used once and discarded.
    // There is very small overhead in connecting a new client to a cluster as it must discover and
    // identify itself to the leader.
    let mut client = Client::new(cluster);

    // Bincode makes it very easy to encode and fire off random enums and structs.
    let payload = Message::Get;
    let encoded = serialize(&payload, SizeLimit::Infinite).unwrap();

    // A query executes **immutably** on the leader of the cluster and does not pass through the
    // persistent log. This is intended for querying the current state of the state machine.
    let response = client.query(&encoded).unwrap();

    // A response will block until it's query is complete. This is intended and expected behavior
    // based on the papers specifications.
    let val = deserialize::<String>(&response).unwrap();
    println!("{}", val)
}

/// Sets a value for a given key in the provided Raft cluster.
fn put(args: &Args) {
    // Same as above.
    let cluster = args.arg_node_address.iter()
        .map(|v| parse_addr(&v))
        .collect();
    let mut client = Client::new(cluster);

    let payload = Message::Put(args.arg_new_value.clone().into_bytes());
    let encoded = serialize(&payload, SizeLimit::Infinite).unwrap();

    // A propose will go through the persistent log and mutably modify the state machine in some
    // way. This is **much** slower than `.query()`.
    let response = client.propose(&encoded).unwrap();

    let val = deserialize::<String>(&response).unwrap();
    println!("{}", val)
}

/// Compares and sets a value for a given key in the provided Raft cluster if the value is what is
/// expected.
fn cas(args: &Args) {
    // Same as above.
    let cluster = args.arg_node_address.iter()
        .map(|v| parse_addr(&v))
        .collect();
    let mut client = Client::new(cluster);

    let payload = Message::Cas(
        args.arg_expected_value.clone().into_bytes(),
        args.arg_new_value.clone().into_bytes());
    let encoded = serialize(&payload, SizeLimit::Infinite).unwrap();

    let response = client.propose(&encoded).unwrap();

    let val = deserialize::<String>(&response).unwrap();
    println!("{}", val)
}

/// A state machine that holds a single mutable value.
#[derive(Debug)]
pub struct RegisterStateMachine {
    value: Vec<u8>,
}

/// Implement anything you want... A `new()` is generally a great idea.
impl RegisterStateMachine {
    pub fn new() -> RegisterStateMachine {
        RegisterStateMachine { value: vec![] }
    }
}

/// Implementing `state_machine::StateMachine` allows your application specific state machine to be
/// used in Raft. Feel encouraged to base yours of one of ours in these examples.
impl state_machine::StateMachine for RegisterStateMachine {

    /// `apply()` is called on when a client's `.propose()` is commited and reaches the state
    /// machine. At this point it is durable and is going to be applied on at least half the nodes
    /// within the next couple round trips.
    fn apply(&mut self, proposal: &[u8]) -> Vec<u8> {
        // Store the old value (example specific)
        let old_value = self.value.clone();

        // Deserialize
        let message = deserialize::<Message>(&proposal).unwrap();

        // Handle
        let response = (match message {
            Message::Put(val) => {
                self.value.clear();
                self.value.extend(val);
                serialize(&old_value, SizeLimit::Infinite)
            },
            Message::Get => serialize(&old_value, SizeLimit::Infinite),
            Message::Cas(test, new) => {
                if test == old_value {
                    self.value.clear();
                    self.value.extend(new);
                    serialize(&true, SizeLimit::Infinite)
                } else {
                    serialize(&false, SizeLimit::Infinite)
                }
            },
        }).unwrap();

        // Respond.
        response
    }

    /// `query()` is called on when a client's `.query()` is recieved. It does not go through the
    /// persistent log, it does not mutate the state of the state machine, and it is intended to be
    /// fast.
    fn query(&self, query: &[u8]) -> Vec<u8> {
        // Store the old value (example specific)
        let old_value = self.value.clone();

        // Deserialize
        let message = deserialize::<Message>(&query).unwrap();

        // Handle
        let response = (match message {
            Message::Get => serialize(&old_value, SizeLimit::Infinite),
            _ => panic!("Cannot mutate from query!"),
        }).unwrap();

        // Respond.
        response
    }

    fn snapshot(&self) -> Vec<u8> {
        self.value.clone()
    }

    fn restore_snapshot(&mut self, snapshot_value: Vec<u8>) {
        self.value = snapshot_value;
        ()
    }
}
<|endoftext|>


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

use self::TypeVariableValue::*;
use hir::def_id::{DefId};
use syntax::ast;
use syntax_pos::Span;
use ty::{self, Ty};

use std::cmp::min;
use std::marker::PhantomData;
use std::mem;
use std::u32;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::snapshot_vec as sv;
use rustc_data_structures::unify as ut;

pub struct TypeVariableTable<'tcx> {
    values: sv::SnapshotVec<Delegate<'tcx>>,

    /// Two variables are unified in `eq_relations` when we have a
    /// constraint `?X == ?Y`.
    eq_relations: ut::UnificationTable<ty::TyVid>,

    /// Two variables are unified in `eq_relations` when we have a
    /// constraint `?X <: ?Y` *or* a constraint `?Y <: ?X`. This second
    /// table exists only to help with the occurs check. In particular,
    /// we want to report constraints like these as an occurs check
    /// violation:
    ///
    ///     ?1 <: ?3
    ///     Box<?3> <: ?1
    ///
    /// This works because `?1` and `?3` are unified in the
    /// `sub_relations` relation (not in `eq_relations`). Then when we
    /// process the `Box<?3> <: ?1` constraint, we do an occurs check
    /// on `Box<?3>` and find a potential cycle.
    ///
    /// This is reasonable because, in Rust, subtypes have the same
    /// "skeleton" and hence there is no possible type such that
    /// (e.g.)  `Box<?3> <: ?3` for any `?3`.
    sub_relations: ut::UnificationTable<ty::TyVid>,
}

/// Reasons to create a type inference variable
#[derive(Copy, Clone, Debug)]
pub enum TypeVariableOrigin {
    MiscVariable(Span),
    NormalizeProjectionType(Span),
    TypeInference(Span),
    TypeParameterDefinition(Span, ast::Name),

    /// one of the upvars or closure kind parameters in a `ClosureSubsts`
    /// (before it has been determined)
    ClosureSynthetic(Span),
    SubstitutionPlaceholder(Span),
    AutoDeref(Span),
    AdjustmentType(Span),
    DivergingStmt(Span),
    DivergingBlockExpr(Span),
    DivergingFn(Span),
    LatticeVariable(Span),
    Generalized(ty::TyVid),
}

pub type TypeVariableMap = FxHashMap<ty::TyVid, TypeVariableOrigin>;

struct TypeVariableData<'tcx> {
    value: TypeVariableValue<'tcx>,
    origin: TypeVariableOrigin,
    diverging: bool
}

enum TypeVariableValue<'tcx> {
    Known {
        value: Ty<'tcx>
    },
    Bounded {
        default: Option<Default<'tcx>>
    }
}

// We will use this to store the required information to recapitulate what happened when
// an error occurs.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Default<'tcx> {
    pub ty: Ty<'tcx>,
    /// The span where the default was incurred
    pub origin_span: Span,
    /// The definition that the default originates from
    pub def_id: DefId
}

pub struct Snapshot {
    snapshot: sv::Snapshot,
    eq_snapshot: ut::Snapshot<ty::TyVid>,
    sub_snapshot: ut::Snapshot<ty::TyVid>,
}

struct Instantiate<'tcx> {
    vid: ty::TyVid,
    default: Option<Default<'tcx>>,
}

struct Delegate<'tcx>(PhantomData<&'tcx ()>);

impl<'tcx> TypeVariableTable<'tcx> {
    pub fn new() -> TypeVariableTable<'tcx> {
        TypeVariableTable {
            values: sv::SnapshotVec::new(),
            eq_relations: ut::UnificationTable::new(),
            sub_relations: ut::UnificationTable::new(),
        }
    }

    pub fn default(&self, vid: ty::TyVid) -> Option<Default<'tcx>> {
        match &self.values.get(vid.index as usize).value {
            &Known { .. } => None,
            &Bounded { ref default, .. } => default.clone()
        }
    }

    pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool {
        self.values.get(vid.index as usize).diverging
    }

    pub fn var_origin(&self, vid: ty::TyVid) -> &TypeVariableOrigin {
        &self.values.get(vid.index as usize).origin
    }

    /// Records that `a == b`, depending on `dir`.
    ///
    /// Precondition: neither `a` nor `b` are known.
    pub fn equate(&mut self, a: ty::TyVid, b: ty::TyVid) {
        debug_assert!(self.probe(a).is_none());
        debug_assert!(self.probe(b).is_none());
        self.eq_relations.union(a, b);
        self.sub_relations.union(a, b);
    }

    /// Records that `a <: b`, depending on `dir`.
    ///
    /// Precondition: neither `a` nor `b` are known.
    pub fn sub(&mut self, a: ty::TyVid, b: ty::TyVid) {
        debug_assert!(self.probe(a).is_none());
        debug_assert!(self.probe(b).is_none());
        self.sub_relations.union(a, b);
    }

    /// Instantiates `vid` with the type `ty`.
    ///
    /// Precondition: `vid` must not have been previously instantiated.
    pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) {
        let vid = self.root_var(vid);
        debug_assert!(self.probe_root(vid).is_none());

        let old_value = {
            let vid_data = &mut self.values[vid.index as usize];
            mem::replace(&mut vid_data.value, TypeVariableValue::Known { value: ty })
        };

        match old_value {
            TypeVariableValue::Bounded { default } => {
                self.values.record(Instantiate { vid: vid, default: default });
            }
            TypeVariableValue::Known { value: old_ty } => {
                bug!("instantiating type variable `{:?}` twice: new-value = {:?}, old-value={:?}",
                     vid, ty, old_ty)
            }
        }
    }

    pub fn new_var(&mut self,
                   diverging: bool,
                   origin: TypeVariableOrigin,
                   default: Option<Default<'tcx>>,) -> ty::TyVid {
        debug!("new_var(diverging={:?}, origin={:?})", diverging, origin);
        self.eq_relations.new_key(());
        self.sub_relations.new_key(());
        let index = self.values.push(TypeVariableData {
            value: Bounded { default: default },
            origin,
            diverging,
        });
        let v = ty::TyVid { index: index as u32 };
        debug!("new_var: diverging={:?} index={:?}", diverging, v);
        v
    }

    pub fn num_vars(&self) -> usize {
        self.values.len()
    }

    /// Returns the "root" variable of `vid` in the `eq_relations`
    /// equivalence table. All type variables that have been equated
    /// will yield the same root variable (per the union-find
    /// algorithm), so `root_var(a) == root_var(b)` implies that `a ==
    /// b` (transitively).
    pub fn root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
        self.eq_relations.find(vid)
    }

    /// Returns the "root" variable of `vid` in the `sub_relations`
    /// equivalence table. All type variables that have been are
    /// related via equality or subtyping will yield the same root
    /// variable (per the union-find algorithm), so `sub_root_var(a)
    /// == sub_root_var(b)` implies that:
    ///
    ///     exists X. (a <: X || X <: a) && (b <: X || X <: b)
    pub fn sub_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
        self.sub_relations.find(vid)
    }

    /// True if `a` and `b` have same "sub-root" (i.e., exists some
    /// type X such that `forall i in {a, b}. (i <: X || X <: i)`.
    pub fn sub_unified(&mut self, a: ty::TyVid, b: ty::TyVid) -> bool {
        self.sub_root_var(a) == self.sub_root_var(b)
    }

    pub fn probe(&mut self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
        let vid = self.root_var(vid);
        self.probe_root(vid)
    }

    pub fn origin(&self, vid: ty::TyVid) -> TypeVariableOrigin {
        self.values.get(vid.index as usize).origin.clone()
    }

    /// Retrieves the type of `vid` given that it is currently a root in the unification table
    pub fn probe_root(&mut self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
        debug_assert!(self.root_var(vid) == vid);
        match self.values.get(vid.index as usize).value {
            Bounded { .. } => None,
            Known { value } => Some(value)
        }
    }

    pub fn replace_if_possible(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
        match t.sty {
            ty::TyInfer(ty::TyVar(v)) => {
                match self.probe(v) {
                    None => t,
                    Some(u) => u
                }
            }
            _ => t,
        }
    }

    pub fn snapshot(&mut self) -> Snapshot {
        Snapshot {
            snapshot: self.values.start_snapshot(),
            eq_snapshot: self.eq_relations.snapshot(),
            sub_snapshot: self.sub_relations.snapshot(),
        }
    }

    pub fn rollback_to(&mut self, s: Snapshot) {
        debug!("rollback_to{:?}", {
            for action in self.values.actions_since_snapshot(&s.snapshot) {
                match *action {
                    sv::UndoLog::NewElem(index) => {
                        debug!("inference variable _#{}t popped", index)
                    }
                    _ => { }
                }
            }
        });

        let Snapshot { snapshot, eq_snapshot, sub_snapshot } = s;
        self.values.rollback_to(snapshot);
        self.eq_relations.rollback_to(eq_snapshot);
        self.sub_relations.rollback_to(sub_snapshot);
    }

    pub fn commit(&mut self, s: Snapshot) {
        let Snapshot { snapshot, eq_snapshot, sub_snapshot } = s;
        self.values.commit(snapshot);
        self.eq_relations.commit(eq_snapshot);
        self.sub_relations.commit(sub_snapshot);
    }

    /// Returns a map `{V1 -> V2}`, where the keys `{V1}` are
    /// ty-variables created during the snapshot, and the values
    /// `{V2}` are the root variables that they were unified with,
    /// along with their origin.
    pub fn types_created_since_snapshot(&mut self, s: &Snapshot) -> TypeVariableMap {
        let actions_since_snapshot = self.values.actions_since_snapshot(&s.snapshot);

        actions_since_snapshot
            .iter()
            .filter_map(|action| match action {
                &sv::UndoLog::NewElem(index) => Some(ty::TyVid { index: index as u32 }),
                _ => None,
            })
            .map(|vid| {
                let origin = self.values.get(vid.index as usize).origin.clone();
                (vid, origin)
            })
            .collect()
    }

    pub fn types_escaping_snapshot(&mut self, s: &Snapshot) -> Vec<Ty<'tcx>> {
        /*!
         * Find the set of type variables that existed *before* `s`
         * but which have only been unified since `s` started, and
         * return the types with which they were unified. So if we had
         * a type variable `V0`, then we started the snapshot, then we
         * created a type variable `V1`, unifed `V0` with `T0`, and
         * unified `V1` with `T1`, this function would return `{T0}`.
         */

        let mut new_elem_threshold = u32::MAX;
        let mut escaping_types = Vec::new();
        let actions_since_snapshot = self.values.actions_since_snapshot(&s.snapshot);
        debug!("actions_since_snapshot.len() = {}", actions_since_snapshot.len());
        for action in actions_since_snapshot {
            match *action {
                sv::UndoLog::NewElem(index) => {
                    // if any new variables were created during the
                    // snapshot, remember the lower index (which will
                    // always be the first one we see). Note that this
                    // action must precede those variables being
                    // specified.
                    new_elem_threshold = min(new_elem_threshold, index as u32);
                    debug!("NewElem({}) new_elem_threshold={}", index, new_elem_threshold);
                }

                sv::UndoLog::Other(Instantiate { vid, .. }) => {
                    if vid.index < new_elem_threshold {
                        // quick check to see if this variable was
                        // created since the snapshot started or not.
                        let escaping_type = match self.values.get(vid.index as usize).value {
                            Bounded { .. } => bug!(),
                            Known { value } => value,
                        };
                        escaping_types.push(escaping_type);
                    }
                    debug!("SpecifyVar({:?}) new_elem_threshold={}", vid, new_elem_threshold);
                }

                _ => { }
            }
        }

        escaping_types
    }

    pub fn unsolved_variables(&mut self) -> Vec<ty::TyVid> {
        (0..self.values.len())
            .filter_map(|i| {
                let vid = ty::TyVid { index: i as u32 };
                if self.probe(vid).is_some() {
                    None
                } else {
                    Some(vid)
                }
            })
            .collect()
    }
}

impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
    type Value = TypeVariableData<'tcx>;
    type Undo = Instantiate<'tcx>;

    fn reverse(values: &mut Vec<TypeVariableData<'tcx>>, action: Instantiate<'tcx>) {
        let Instantiate { vid, default } = action;
        values[vid.index as usize].value = Bounded {
            default,
        };
    }
}
<commit_msg>make `Default` Copy and Clone<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use self::TypeVariableValue::*;
use hir::def_id::{DefId};
use syntax::ast;
use syntax_pos::Span;
use ty::{self, Ty};

use std::cmp::min;
use std::marker::PhantomData;
use std::mem;
use std::u32;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::snapshot_vec as sv;
use rustc_data_structures::unify as ut;

pub struct TypeVariableTable<'tcx> {
    values: sv::SnapshotVec<Delegate<'tcx>>,

    /// Two variables are unified in `eq_relations` when we have a
    /// constraint `?X == ?Y`.
    eq_relations: ut::UnificationTable<ty::TyVid>,

    /// Two variables are unified in `eq_relations` when we have a
    /// constraint `?X <: ?Y` *or* a constraint `?Y <: ?X`. This second
    /// table exists only to help with the occurs check. In particular,
    /// we want to report constraints like these as an occurs check
    /// violation:
    ///
    ///     ?1 <: ?3
    ///     Box<?3> <: ?1
    ///
    /// This works because `?1` and `?3` are unified in the
    /// `sub_relations` relation (not in `eq_relations`). Then when we
    /// process the `Box<?3> <: ?1` constraint, we do an occurs check
    /// on `Box<?3>` and find a potential cycle.
    ///
    /// This is reasonable because, in Rust, subtypes have the same
    /// "skeleton" and hence there is no possible type such that
    /// (e.g.)  `Box<?3> <: ?3` for any `?3`.
    sub_relations: ut::UnificationTable<ty::TyVid>,
}

/// Reasons to create a type inference variable
#[derive(Copy, Clone, Debug)]
pub enum TypeVariableOrigin {
    MiscVariable(Span),
    NormalizeProjectionType(Span),
    TypeInference(Span),
    TypeParameterDefinition(Span, ast::Name),

    /// one of the upvars or closure kind parameters in a `ClosureSubsts`
    /// (before it has been determined)
    ClosureSynthetic(Span),
    SubstitutionPlaceholder(Span),
    AutoDeref(Span),
    AdjustmentType(Span),
    DivergingStmt(Span),
    DivergingBlockExpr(Span),
    DivergingFn(Span),
    LatticeVariable(Span),
    Generalized(ty::TyVid),
}

pub type TypeVariableMap = FxHashMap<ty::TyVid, TypeVariableOrigin>;

struct TypeVariableData<'tcx> {
    value: TypeVariableValue<'tcx>,
    origin: TypeVariableOrigin,
    diverging: bool
}

enum TypeVariableValue<'tcx> {
    Known {
        value: Ty<'tcx>
    },
    Bounded {
        default: Option<Default<'tcx>>
    }
}

// We will use this to store the required information to recapitulate what happened when
// an error occurs.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Default<'tcx> {
    pub ty: Ty<'tcx>,
    /// The span where the default was incurred
    pub origin_span: Span,
    /// The definition that the default originates from
    pub def_id: DefId
}

pub struct Snapshot {
    snapshot: sv::Snapshot,
    eq_snapshot: ut::Snapshot<ty::TyVid>,
    sub_snapshot: ut::Snapshot<ty::TyVid>,
}

struct Instantiate<'tcx> {
    vid: ty::TyVid,
    default: Option<Default<'tcx>>,
}

struct Delegate<'tcx>(PhantomData<&'tcx ()>);

impl<'tcx> TypeVariableTable<'tcx> {
    pub fn new() -> TypeVariableTable<'tcx> {
        TypeVariableTable {
            values: sv::SnapshotVec::new(),
            eq_relations: ut::UnificationTable::new(),
            sub_relations: ut::UnificationTable::new(),
        }
    }

    pub fn default(&self, vid: ty::TyVid) -> Option<Default<'tcx>> {
        match &self.values.get(vid.index as usize).value {
            &Known { .. } => None,
            &Bounded { default, .. } => default,
        }
    }

    pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool {
        self.values.get(vid.index as usize).diverging
    }

    pub fn var_origin(&self, vid: ty::TyVid) -> &TypeVariableOrigin {
        &self.values.get(vid.index as usize).origin
    }

    /// Records that `a == b`, depending on `dir`.
    ///
    /// Precondition: neither `a` nor `b` are known.
    pub fn equate(&mut self, a: ty::TyVid, b: ty::TyVid) {
        debug_assert!(self.probe(a).is_none());
        debug_assert!(self.probe(b).is_none());
        self.eq_relations.union(a, b);
        self.sub_relations.union(a, b);
    }

    /// Records that `a <: b`, depending on `dir`.
    ///
    /// Precondition: neither `a` nor `b` are known.
    pub fn sub(&mut self, a: ty::TyVid, b: ty::TyVid) {
        debug_assert!(self.probe(a).is_none());
        debug_assert!(self.probe(b).is_none());
        self.sub_relations.union(a, b);
    }

    /// Instantiates `vid` with the type `ty`.
    ///
    /// Precondition: `vid` must not have been previously instantiated.
    pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) {
        let vid = self.root_var(vid);
        debug_assert!(self.probe_root(vid).is_none());

        let old_value = {
            let vid_data = &mut self.values[vid.index as usize];
            mem::replace(&mut vid_data.value, TypeVariableValue::Known { value: ty })
        };

        match old_value {
            TypeVariableValue::Bounded { default } => {
                self.values.record(Instantiate { vid: vid, default: default });
            }
            TypeVariableValue::Known { value: old_ty } => {
                bug!("instantiating type variable `{:?}` twice: new-value = {:?}, old-value={:?}",
                     vid, ty, old_ty)
            }
        }
    }

    pub fn new_var(&mut self,
                   diverging: bool,
                   origin: TypeVariableOrigin,
                   default: Option<Default<'tcx>>,) -> ty::TyVid {
        debug!("new_var(diverging={:?}, origin={:?})", diverging, origin);
        self.eq_relations.new_key(());
        self.sub_relations.new_key(());
        let index = self.values.push(TypeVariableData {
            value: Bounded { default },
            origin,
            diverging,
        });
        let v = ty::TyVid { index: index as u32 };
        debug!("new_var: diverging={:?} index={:?}", diverging, v);
        v
    }

    pub fn num_vars(&self) -> usize {
        self.values.len()
    }

    /// Returns the "root" variable of `vid` in the `eq_relations`
    /// equivalence table. All type variables that have been equated
    /// will yield the same root variable (per the union-find
    /// algorithm), so `root_var(a) == root_var(b)` implies that `a ==
    /// b` (transitively).
    pub fn root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
        self.eq_relations.find(vid)
    }

    /// Returns the "root" variable of `vid` in the `sub_relations`
    /// equivalence table. All type variables that have been are
    /// related via equality or subtyping will yield the same root
    /// variable (per the union-find algorithm), so `sub_root_var(a)
    /// == sub_root_var(b)` implies that:
    ///
    ///     exists X. (a <: X || X <: a) && (b <: X || X <: b)
    pub fn sub_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
        self.sub_relations.find(vid)
    }

    /// True if `a` and `b` have same "sub-root" (i.e., exists some
    /// type X such that `forall i in {a, b}. (i <: X || X <: i)`.
    pub fn sub_unified(&mut self, a: ty::TyVid, b: ty::TyVid) -> bool {
        self.sub_root_var(a) == self.sub_root_var(b)
    }

    pub fn probe(&mut self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
        let vid = self.root_var(vid);
        self.probe_root(vid)
    }

    pub fn origin(&self, vid: ty::TyVid) -> TypeVariableOrigin {
        self.values.get(vid.index as usize).origin.clone()
    }

    /// Retrieves the type of `vid` given that it is currently a root in the unification table
    pub fn probe_root(&mut self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
        debug_assert!(self.root_var(vid) == vid);
        match self.values.get(vid.index as usize).value {
            Bounded { .. } => None,
            Known { value } => Some(value)
        }
    }

    pub fn replace_if_possible(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
        match t.sty {
            ty::TyInfer(ty::TyVar(v)) => {
                match self.probe(v) {
                    None => t,
                    Some(u) => u
                }
            }
            _ => t,
        }
    }

    pub fn snapshot(&mut self) -> Snapshot {
        Snapshot {
            snapshot: self.values.start_snapshot(),
            eq_snapshot: self.eq_relations.snapshot(),
            sub_snapshot: self.sub_relations.snapshot(),
        }
    }

    pub fn rollback_to(&mut self, s: Snapshot) {
        debug!("rollback_to{:?}", {
            for action in self.values.actions_since_snapshot(&s.snapshot) {
                match *action {
                    sv::UndoLog::NewElem(index) => {
                        debug!("inference variable _#{}t popped", index)
                    }
                    _ => { }
                }
            }
        });

        let Snapshot { snapshot, eq_snapshot, sub_snapshot } = s;
        self.values.rollback_to(snapshot);
        self.eq_relations.rollback_to(eq_snapshot);
        self.sub_relations.rollback_to(sub_snapshot);
    }

    pub fn commit(&mut self, s: Snapshot) {
        let Snapshot { snapshot, eq_snapshot, sub_snapshot } = s;
        self.values.commit(snapshot);
        self.eq_relations.commit(eq_snapshot);
        self.sub_relations.commit(sub_snapshot);
    }

    /// Returns a map `{V1 -> V2}`, where the keys `{V1}` are
    /// ty-variables created during the snapshot, and the values
    /// `{V2}` are the root variables that they were unified with,
    /// along with their origin.
    pub fn types_created_since_snapshot(&mut self, s: &Snapshot) -> TypeVariableMap {
        let actions_since_snapshot = self.values.actions_since_snapshot(&s.snapshot);

        actions_since_snapshot
            .iter()
            .filter_map(|action| match action {
                &sv::UndoLog::NewElem(index) => Some(ty::TyVid { index: index as u32 }),
                _ => None,
            })
            .map(|vid| {
                let origin = self.values.get(vid.index as usize).origin.clone();
                (vid, origin)
            })
            .collect()
    }

    pub fn types_escaping_snapshot(&mut self, s: &Snapshot) -> Vec<Ty<'tcx>> {
        /*!
         * Find the set of type variables that existed *before* `s`
         * but which have only been unified since `s` started, and
         * return the types with which they were unified. So if we had
         * a type variable `V0`, then we started the snapshot, then we
         * created a type variable `V1`, unifed `V0` with `T0`, and
         * unified `V1` with `T1`, this function would return `{T0}`.
         */

        let mut new_elem_threshold = u32::MAX;
        let mut escaping_types = Vec::new();
        let actions_since_snapshot = self.values.actions_since_snapshot(&s.snapshot);
        debug!("actions_since_snapshot.len() = {}", actions_since_snapshot.len());
        for action in actions_since_snapshot {
            match *action {
                sv::UndoLog::NewElem(index) => {
                    // if any new variables were created during the
                    // snapshot, remember the lower index (which will
                    // always be the first one we see). Note that this
                    // action must precede those variables being
                    // specified.
                    new_elem_threshold = min(new_elem_threshold, index as u32);
                    debug!("NewElem({}) new_elem_threshold={}", index, new_elem_threshold);
                }

                sv::UndoLog::Other(Instantiate { vid, .. }) => {
                    if vid.index < new_elem_threshold {
                        // quick check to see if this variable was
                        // created since the snapshot started or not.
                        let escaping_type = match self.values.get(vid.index as usize).value {
                            Bounded { .. } => bug!(),
                            Known { value } => value,
                        };
                        escaping_types.push(escaping_type);
                    }
                    debug!("SpecifyVar({:?}) new_elem_threshold={}", vid, new_elem_threshold);
                }

                _ => { }
            }
        }

        escaping_types
    }

    pub fn unsolved_variables(&mut self) -> Vec<ty::TyVid> {
        (0..self.values.len())
            .filter_map(|i| {
                let vid = ty::TyVid { index: i as u32 };
                if self.probe(vid).is_some() {
                    None
                } else {
                    Some(vid)
                }
            })
            .collect()
    }
}

impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
    type Value = TypeVariableData<'tcx>;
    type Undo = Instantiate<'tcx>;

    fn reverse(values: &mut Vec<TypeVariableData<'tcx>>, action: Instantiate<'tcx>) {
        let Instantiate { vid, default } = action;
        values[vid.index as usize].value = Bounded {
            default,
        };
    }
}
<|endoftext|>


<commit_before>///! Generate a base bitmap for drawing an overland map with a paint program.
extern crate calx;
extern crate euclid;
extern crate image;
extern crate structopt;
#[macro_use]
extern crate structopt_derive;
extern crate world;

use calx::{hex_disc, CellVector, MinimapSpace, Prefab, ProjectedImage, SRgba};
use euclid::vec2;
use image::{GenericImage, Pixel, SubImage};
use std::collections::HashMap;
use std::iter::FromIterator;
use structopt::StructOpt;
use world::{Location, Sector, Terrain};

type ImageBuffer = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>;

#[derive(StructOpt, Debug)]
struct Opt {
    #[structopt(subcommand)] cmd: Command,
}

#[derive(StructOpt, Debug)]
enum Command {
    #[structopt(name = "generate", help = "Generate a blank overland map image")]
    Generate {
        #[structopt(long = "minimap", help = "Use minimap projection")]
        minimap: bool,

        #[structopt(short = "w", long = "width", default_value = "8", help = "Width in sectors")]
        width: u32,

        #[structopt(short = "h", long = "height", default_value = "9", help = "Height in sectors")]
        height: u32,

        #[structopt(help = "Output PNG file")]
        output: String,
    },

    #[structopt(name = "convert",
                help = "Convert map from one projection to another and normalize the checkerboard pattern")]
    Convert {
        #[structopt(long = "input-minimap", help = "Input file has minimap projection")]
        input_minimap: bool,

        #[structopt(long = "output-minimap", help = "Use minimap projection in output file")]
        output_minimap: bool,

        #[structopt(help = "Input file")]
        input: String,

        #[structopt(help = "Output file (if different from input)")]
        output: Option<String>,
    },
}

fn default_map(width: u32, height: u32) -> Prefab<Terrain> {
    fn p(loc: Location) -> CellVector { vec2(loc.x as i32, loc.y as i32) }

    let mut terrain = HashMap::new();

    for &loc in &overland_locs(width, height) {
        for edge in hex_disc(loc, 1) {
            // Ensure land is surrounded by water past the sector edges.
            terrain.entry(p(edge)).or_insert(Terrain::Water);
        }
        terrain.insert(p(loc), Terrain::Grass);
    }

    Prefab::from_iter(terrain.into_iter())
}

fn dark(color: SRgba) -> SRgba {
    let mut color = color;
    color.r &= !0xF;
    color.g &= !0xF;
    color.b &= !0xF;
    color
}

fn light(color: SRgba) -> SRgba {
    let mut color = dark(color);
    color.r += 0xF;
    color.g += 0xF;
    color.b += 0xF;
    color
}

fn checkerboard((pos, color): (CellVector, SRgba)) -> (CellVector, SRgba) {
    let sec = Location::new(pos.x as i16, pos.y as i16, 0).sector();
    let is_dark = (sec.x + sec.y) % 2 != 0;
    (pos, if is_dark { dark(color) } else { light(color) })
}

fn terrain_to_color((pos, terrain): (CellVector, Terrain)) -> (CellVector, SRgba) {
    checkerboard((pos, terrain.color()))
}

fn overland_locs(width: u32, height: u32) -> Vec<Location> {
    let mut ret = Vec::new();
    for y in 0..(height as i16) {
        for x in 0..(width as i16) {
            let sec = Sector::new(x, y, 0);
            for loc in sec.iter() {
                ret.push(loc);
            }
        }
    }
    ret
}

fn save(prefab: Prefab<SRgba>, is_minimap: bool, output_path: String) {
    let image: ImageBuffer = if is_minimap {
        let p: ProjectedImage<ImageBuffer, MinimapSpace> = prefab.into();
        p.image
    } else {
        prefab.into()
    };

    // Impose palette
    let mut result = ImageBuffer::new(image.width(), image.height() + 1);
    result.copy_from(&image, 0, 0);

    for (x, t) in Terrain::iter().filter(|t| t.is_regular()).enumerate() {
        let light = light(t.color());
        let dark = dark(t.color());
        let y = result.height() - 1;
        result.put_pixel(
            x as u32 * 2,
            y,
            image::Rgba::from_channels(light.r, light.g, light.b, 0xff),
        );
        result.put_pixel(
            x as u32 * 2 + 1,
            y,
            image::Rgba::from_channels(dark.r, dark.g, dark.b, 0xff),
        );
    }

    image::save_buffer(
        output_path,
        &result,
        result.width(),
        result.height(),
        image::ColorType::RGBA(8),
    ).unwrap();
}

fn generate(width: u32, height: u32, is_minimap: bool, output_path: String) {
    let prefab: Prefab<SRgba> = default_map(width, height)
        .into_iter()
        .map(terrain_to_color)
        .collect();

    save(prefab, is_minimap, output_path);
}

fn convert(
    input_path: String,
    input_is_minimap: bool,
    output_path: Option<String>,
    output_is_minimap: bool,
) {
    let mut input =
        image::open(input_path.clone()).expect(&format!("Unable to load '{}'", input_path.clone()));
    // Slice off the bottom row containing palette (h - 1).
    let (w, h) = (input.width(), input.height());
    let input_map = SubImage::new(&mut input, 0, 0, w, h - 1);

    let prefab: Prefab<SRgba> = if input_is_minimap {
        let p: ProjectedImage<_, MinimapSpace> = ProjectedImage::new(input_map);
        Prefab::parse(p).expect("Bad map image")
    } else {
        Prefab::parse(input_map).expect("Bad map image")
    };

    // Impose sector checkerboard.
    let prefab: Prefab<SRgba> = prefab.into_iter().map(checkerboard).collect();

    save(prefab, output_is_minimap, output_path.unwrap_or(input_path));
}

fn main() {
    let opt = Opt::from_args();
    match opt.cmd {
        Command::Generate {
            width,
            height,
            minimap,
            output,
        } => generate(width, height, minimap, output),
        Command::Convert {
            input,
            input_minimap,
            output,
            output_minimap,
        } => convert(input, input_minimap, output, output_minimap),
    }
}
<commit_msg>Rustfmt<commit_after>///! Generate a base bitmap for drawing an overland map with a paint program.
extern crate calx;
extern crate euclid;
extern crate image;
extern crate structopt;
#[macro_use]
extern crate structopt_derive;
extern crate world;

use calx::{hex_disc, CellVector, MinimapSpace, Prefab, ProjectedImage, SRgba};
use euclid::vec2;
use image::{GenericImage, Pixel, SubImage};
use std::collections::HashMap;
use std::iter::FromIterator;
use structopt::StructOpt;
use world::{Location, Sector, Terrain};

type ImageBuffer = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>;

#[derive(StructOpt, Debug)]
struct Opt {
    #[structopt(subcommand)]
    cmd: Command,
}

#[derive(StructOpt, Debug)]
enum Command {
    #[structopt(name = "generate", help = "Generate a blank overland map image")]
    Generate {
        #[structopt(long = "minimap", help = "Use minimap projection")]
        minimap: bool,

        #[structopt(short = "w", long = "width", default_value = "8", help = "Width in sectors")]
        width: u32,

        #[structopt(short = "h", long = "height", default_value = "9", help = "Height in sectors")]
        height: u32,

        #[structopt(help = "Output PNG file")]
        output: String,
    },

    #[structopt(name = "convert",
                help = "Convert map from one projection to another and normalize the checkerboard pattern")]
    Convert {
        #[structopt(long = "input-minimap", help = "Input file has minimap projection")]
        input_minimap: bool,

        #[structopt(long = "output-minimap", help = "Use minimap projection in output file")]
        output_minimap: bool,

        #[structopt(help = "Input file")]
        input: String,

        #[structopt(help = "Output file (if different from input)")]
        output: Option<String>,
    },
}

fn default_map(width: u32, height: u32) -> Prefab<Terrain> {
    fn p(loc: Location) -> CellVector { vec2(loc.x as i32, loc.y as i32) }

    let mut terrain = HashMap::new();

    for &loc in &overland_locs(width, height) {
        for edge in hex_disc(loc, 1) {
            // Ensure land is surrounded by water past the sector edges.
            terrain.entry(p(edge)).or_insert(Terrain::Water);
        }
        terrain.insert(p(loc), Terrain::Grass);
    }

    Prefab::from_iter(terrain.into_iter())
}

fn dark(color: SRgba) -> SRgba {
    let mut color = color;
    color.r &= !0xF;
    color.g &= !0xF;
    color.b &= !0xF;
    color
}

fn light(color: SRgba) -> SRgba {
    let mut color = dark(color);
    color.r += 0xF;
    color.g += 0xF;
    color.b += 0xF;
    color
}

fn checkerboard((pos, color): (CellVector, SRgba)) -> (CellVector, SRgba) {
    let sec = Location::new(pos.x as i16, pos.y as i16, 0).sector();
    let is_dark = (sec.x + sec.y) % 2 != 0;
    (pos, if is_dark { dark(color) } else { light(color) })
}

fn terrain_to_color((pos, terrain): (CellVector, Terrain)) -> (CellVector, SRgba) {
    checkerboard((pos, terrain.color()))
}

fn overland_locs(width: u32, height: u32) -> Vec<Location> {
    let mut ret = Vec::new();
    for y in 0..(height as i16) {
        for x in 0..(width as i16) {
            let sec = Sector::new(x, y, 0);
            for loc in sec.iter() {
                ret.push(loc);
            }
        }
    }
    ret
}

fn save(prefab: Prefab<SRgba>, is_minimap: bool, output_path: String) {
    let image: ImageBuffer = if is_minimap {
        let p: ProjectedImage<ImageBuffer, MinimapSpace> = prefab.into();
        p.image
    } else {
        prefab.into()
    };

    // Impose palette
    let mut result = ImageBuffer::new(image.width(), image.height() + 1);
    result.copy_from(&image, 0, 0);

    for (x, t) in Terrain::iter().filter(|t| t.is_regular()).enumerate() {
        let light = light(t.color());
        let dark = dark(t.color());
        let y = result.height() - 1;
        result.put_pixel(
            x as u32 * 2,
            y,
            image::Rgba::from_channels(light.r, light.g, light.b, 0xff),
        );
        result.put_pixel(
            x as u32 * 2 + 1,
            y,
            image::Rgba::from_channels(dark.r, dark.g, dark.b, 0xff),
        );
    }

    image::save_buffer(
        output_path,
        &result,
        result.width(),
        result.height(),
        image::ColorType::RGBA(8),
    ).unwrap();
}

fn generate(width: u32, height: u32, is_minimap: bool, output_path: String) {
    let prefab: Prefab<SRgba> = default_map(width, height)
        .into_iter()
        .map(terrain_to_color)
        .collect();

    save(prefab, is_minimap, output_path);
}

fn convert(
    input_path: String,
    input_is_minimap: bool,
    output_path: Option<String>,
    output_is_minimap: bool,
) {
    let mut input =
        image::open(input_path.clone()).expect(&format!("Unable to load '{}'", input_path.clone()));
    // Slice off the bottom row containing palette (h - 1).
    let (w, h) = (input.width(), input.height());
    let input_map = SubImage::new(&mut input, 0, 0, w, h - 1);

    let prefab: Prefab<SRgba> = if input_is_minimap {
        let p: ProjectedImage<_, MinimapSpace> = ProjectedImage::new(input_map);
        Prefab::parse(p).expect("Bad map image")
    } else {
        Prefab::parse(input_map).expect("Bad map image")
    };

    // Impose sector checkerboard.
    let prefab: Prefab<SRgba> = prefab.into_iter().map(checkerboard).collect();

    save(prefab, output_is_minimap, output_path.unwrap_or(input_path));
}

fn main() {
    let opt = Opt::from_args();
    match opt.cmd {
        Command::Generate {
            width,
            height,
            minimap,
            output,
        } => generate(width, height, minimap, output),
        Command::Convert {
            input,
            input_minimap,
            output,
            output_minimap,
        } => convert(input, input_minimap, output, output_minimap),
    }
}
<|endoftext|>


<commit_before>#![allow(unknown_lints)]
#![allow(unreadable_literal)]

use num_bigint::BigInt;

const DECIMAL_MULT_I64: [i64; 19] = [
    1,
    10,
    100,
    1000,
    10000,
    100000,
    1000000,
    10000000,
    100000000,
    1000000000,
    10000000000,
    100000000000,
    1000000000000,
    10000000000000,
    100000000000000,
    1000000000000000,
    10000000000000000,
    100000000000000000,
    1000000000000000000
];

const DECIMAL_MULT_I128: [i128; 39] = [
    1,
    10,
    100,
    1000,
    10000,
    100000,
    1000000,
    10000000,
    100000000,
    1000000000,
    10000000000,
    100000000000,
    1000000000000,
    10000000000000,
    100000000000000,
    1000000000000000,
    10000000000000000,
    100000000000000000,
    1000000000000000000,
    10000000000000000000,
    100000000000000000000,
    1000000000000000000000,
    10000000000000000000000,
    100000000000000000000000,
    1000000000000000000000000,
    10000000000000000000000000,
    100000000000000000000000000,
    1000000000000000000000000000,
    10000000000000000000000000000,
    100000000000000000000000000000,
    1000000000000000000000000000000,
    10000000000000000000000000000000,
    100000000000000000000000000000000,
    1000000000000000000000000000000000,
    10000000000000000000000000000000000,
    100000000000000000000000000000000000,
    1000000000000000000000000000000000000,
    10000000000000000000000000000000000000,
    100000000000000000000000000000000000000
];

macro_rules! create_decimal_fn {
    ($ty:ty, $set_decimals:ident, $DECIMAL_MULT:ident) => (
        pub fn $set_decimals(num: $ty, orig_dec: u8, new_dec: u8) -> Option<$ty> {
            if orig_dec > new_dec {
                num.checked_div($DECIMAL_MULT[(orig_dec - new_dec) as usize])
            } else if orig_dec < new_dec {
                num.checked_mul($DECIMAL_MULT[(new_dec - orig_dec) as usize])
            } else {
                Some(num)
            }
        }
    )
}

create_decimal_fn!(i64, set_decimals_i64, DECIMAL_MULT_I64);
create_decimal_fn!(i128, set_decimals_i128, DECIMAL_MULT_I128);

pub fn set_decimals_big(num: &BigInt, orig_dec: u16, new_dec: u16) -> BigInt {
    if orig_dec > new_dec {
        let delta = (orig_dec - new_dec) as usize;
        if delta < DECIMAL_MULT_I64.len() {
            num / DECIMAL_MULT_I64[delta]
        } else {
            let mut rep = String::from("1");
            rep.push_str(&"0".repeat(delta));
            num / rep.parse::<BigInt>().unwrap()
        }
    } else if orig_dec < new_dec {
        let delta = (new_dec - orig_dec) as usize;
        if delta < DECIMAL_MULT_I64.len() {
            num * DECIMAL_MULT_I64[delta]
        } else {
            let mut rep = String::from("1");
            rep.push_str(&"0".repeat(delta));
            num * rep.parse::<BigInt>().unwrap()
        }
    } else {
        num.clone()
    }
}
<commit_msg>Update allowance of unreadable literals<commit_after>#![allow(clippy::unreadable_literal)]

use num_bigint::BigInt;

const DECIMAL_MULT_I64: [i64; 19] = [
    1,
    10,
    100,
    1000,
    10000,
    100000,
    1000000,
    10000000,
    100000000,
    1000000000,
    10000000000,
    100000000000,
    1000000000000,
    10000000000000,
    100000000000000,
    1000000000000000,
    10000000000000000,
    100000000000000000,
    1000000000000000000
];

const DECIMAL_MULT_I128: [i128; 39] = [
    1,
    10,
    100,
    1000,
    10000,
    100000,
    1000000,
    10000000,
    100000000,
    1000000000,
    10000000000,
    100000000000,
    1000000000000,
    10000000000000,
    100000000000000,
    1000000000000000,
    10000000000000000,
    100000000000000000,
    1000000000000000000,
    10000000000000000000,
    100000000000000000000,
    1000000000000000000000,
    10000000000000000000000,
    100000000000000000000000,
    1000000000000000000000000,
    10000000000000000000000000,
    100000000000000000000000000,
    1000000000000000000000000000,
    10000000000000000000000000000,
    100000000000000000000000000000,
    1000000000000000000000000000000,
    10000000000000000000000000000000,
    100000000000000000000000000000000,
    1000000000000000000000000000000000,
    10000000000000000000000000000000000,
    100000000000000000000000000000000000,
    1000000000000000000000000000000000000,
    10000000000000000000000000000000000000,
    100000000000000000000000000000000000000
];

macro_rules! create_decimal_fn {
    ($ty:ty, $set_decimals:ident, $DECIMAL_MULT:ident) => (
        pub fn $set_decimals(num: $ty, orig_dec: u8, new_dec: u8) -> Option<$ty> {
            if orig_dec > new_dec {
                num.checked_div($DECIMAL_MULT[(orig_dec - new_dec) as usize])
            } else if orig_dec < new_dec {
                num.checked_mul($DECIMAL_MULT[(new_dec - orig_dec) as usize])
            } else {
                Some(num)
            }
        }
    )
}

create_decimal_fn!(i64, set_decimals_i64, DECIMAL_MULT_I64);
create_decimal_fn!(i128, set_decimals_i128, DECIMAL_MULT_I128);

pub fn set_decimals_big(num: &BigInt, orig_dec: u16, new_dec: u16) -> BigInt {
    if orig_dec > new_dec {
        let delta = (orig_dec - new_dec) as usize;
        if delta < DECIMAL_MULT_I64.len() {
            num / DECIMAL_MULT_I64[delta]
        } else {
            let mut rep = String::from("1");
            rep.push_str(&"0".repeat(delta));
            num / rep.parse::<BigInt>().unwrap()
        }
    } else if orig_dec < new_dec {
        let delta = (new_dec - orig_dec) as usize;
        if delta < DECIMAL_MULT_I64.len() {
            num * DECIMAL_MULT_I64[delta]
        } else {
            let mut rep = String::from("1");
            rep.push_str(&"0".repeat(delta));
            num * rep.parse::<BigInt>().unwrap()
        }
    } else {
        num.clone()
    }
}
<|endoftext|>


<commit_before>extern crate gl;
extern crate sdl2;
extern crate yaglw;

use gl::types::*;
use sdl2::event::Event;
use std::mem;
use std::time::duration::Duration;
use std::old_io::timer;

use yaglw::gl_context::GLContext;
use yaglw::shader::Shader;
use yaglw::vertex_buffer::{GLArray, GLBuffer, GLType, VertexAttribData, DrawMode};

#[repr(C)]
#[derive(Copy)]
struct Vertex {
  pub position: [GLfloat; 2],
  pub color: [GLfloat; 3],
}

const VERTEX_SHADER: &'static str = "
  #version 130

  in vec2 position;
  in vec3 color;

  out vec3 v_color;

  void main() {
    v_color = color;
    gl_Position = vec4(position, 0, 1);
  }
";

const FRAGMENT_SHADER: &'static str = "
  #version 130

  in vec3 v_color;

  void main() {
    gl_FragColor = vec4(v_color, 1.0);
  }
";

pub fn main() {
  let window = make_window();

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| unsafe {
    mem::transmute(sdl2::video::gl_get_proc_address(s))
  });

  let (gl, mut gl_context) = unsafe {
    GLContext::new()
  };

  let vertices = [
    Vertex {
      position: [0.0, 0.5],
      color: [1.0, 0.0, 0.0],
    },
    Vertex {
      position: [-0.5, -0.5],
      color: [0.0, 1.0, 0.0],
    },
    Vertex {
      position: [0.5, -0.5],
      color: [0.0, 0.0, 1.0],
    },
  ];

  let mut vbo = GLBuffer::new(&gl, &mut gl_context, 3);
  vbo.push(&mut gl_context, &vertices);

  let attribs = [
    VertexAttribData {
      name: "position",
      size: 2,
      unit: GLType::Float,
    },
    VertexAttribData {
      name: "color",
      size: 3,
      unit: GLType::Float,
    },
  ];

  let components = [
    ((gl::VERTEX_SHADER, VERTEX_SHADER)),
    ((gl::FRAGMENT_SHADER, FRAGMENT_SHADER)),
  ];

  let shader = Shader::new(&gl, components.iter().map(|&(ty, s)| (ty, String::from_str(s))));
  shader.use_shader(&mut gl_context);

  let vao =
    GLArray::new(
      &gl,
      &mut gl_context,
      &shader,
      &attribs,
      DrawMode::Triangles,
      vbo,
    );
  vao.bind(&mut gl_context);

  match gl_context.get_error() {
    gl::NO_ERROR => {},
    err => {
      println!("OpenGL error 0x{:x} in setup", err);
      return;
    },
  }

  while !quit_event() {
    gl_context.clear_buffer();
    vao.draw(&mut gl_context);
    // swap buffers
    window.gl_swap_window();

    timer::sleep(Duration::milliseconds(10));
  }
}

fn make_window() -> sdl2::video::Window {
  sdl2::init(sdl2::INIT_EVERYTHING);

  sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLContextMajorVersion, 3);
  sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLContextMinorVersion, 0);
  sdl2::video::gl_set_attribute(
    sdl2::video::GLAttr::GLContextProfileMask,
    sdl2::video::GLProfile::GLCoreProfile as i32,
  );

  sdl2::video::Window::new(
    "Triangle",
    sdl2::video::WindowPos::PosCentered,
    sdl2::video::WindowPos::PosCentered,
    800,
    600,
    sdl2::video::OPENGL,
  ).unwrap()
}

fn quit_event() -> bool {
  loop {
    match sdl2::event::poll_event() {
      Event::None => {
        return false;
      },
      Event::Quit(_) => {
        return true;
      }
      Event::AppTerminating(_) => {
        return true;
      }
      _ => {},
    }
  }
}
<commit_msg>rustup the example.<commit_after>extern crate gl;
extern crate sdl2;
extern crate yaglw;

use gl::types::*;
use sdl2::event::Event;
use std::mem;
use std::time::duration::Duration;
use std::old_io::timer;

use yaglw::gl_context::GLContext;
use yaglw::shader::Shader;
use yaglw::vertex_buffer::{GLArray, GLBuffer, GLType, VertexAttribData, DrawMode};

#[repr(C)]
#[derive(Copy)]
struct Vertex {
  pub position: [GLfloat; 2],
  pub color: [GLfloat; 3],
}

const VERTEX_SHADER: &'static str = "
  #version 130

  in vec2 position;
  in vec3 color;

  out vec3 v_color;

  void main() {
    v_color = color;
    gl_Position = vec4(position, 0, 1);
  }
";

const FRAGMENT_SHADER: &'static str = "
  #version 130

  in vec3 v_color;

  void main() {
    gl_FragColor = vec4(v_color, 1.0);
  }
";

pub fn main() {
  let window = make_window();

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| unsafe {
    mem::transmute(sdl2::video::gl_get_proc_address(s))
  });

  let (gl, mut gl_context) = unsafe {
    GLContext::new()
  };

  let vertices = [
    Vertex {
      position: [0.0, 0.5],
      color: [1.0, 0.0, 0.0],
    },
    Vertex {
      position: [-0.5, -0.5],
      color: [0.0, 1.0, 0.0],
    },
    Vertex {
      position: [0.5, -0.5],
      color: [0.0, 0.0, 1.0],
    },
  ];

  let mut vbo = GLBuffer::new(&gl, &mut gl_context, 3);
  vbo.push(&mut gl_context, &vertices);

  let attribs = [
    VertexAttribData {
      name: "position",
      size: 2,
      unit: GLType::Float,
    },
    VertexAttribData {
      name: "color",
      size: 3,
      unit: GLType::Float,
    },
  ];

  let components = [
    ((gl::VERTEX_SHADER, VERTEX_SHADER)),
    ((gl::FRAGMENT_SHADER, FRAGMENT_SHADER)),
  ];

  let shader = Shader::new(&gl, components.iter().map(|&(ty, s)| (ty, String::from_str(s))));
  shader.use_shader(&mut gl_context);

  let vao =
    GLArray::new(
      &gl,
      &mut gl_context,
      &shader,
      &attribs,
      DrawMode::Triangles,
      vbo,
    );
  vao.bind(&mut gl_context);

  match gl_context.get_error() {
    gl::NO_ERROR => {},
    err => {
      println!("OpenGL error 0x{:x} in setup", err);
      return;
    },
  }

  while !quit_event() {
    gl_context.clear_buffer();
    vao.draw(&mut gl_context);
    // swap buffers
    window.gl_swap_window();

    timer::sleep(Duration::milliseconds(10));
  }
}

fn make_window() -> sdl2::video::Window {
  sdl2::init(sdl2::INIT_EVERYTHING);

  sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLContextMajorVersion, 3);
  sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLContextMinorVersion, 0);
  sdl2::video::gl_set_attribute(
    sdl2::video::GLAttr::GLContextProfileMask,
    sdl2::video::GLProfile::GLCoreProfile as i32,
  );

  sdl2::video::Window::new(
    "Triangle",
    sdl2::video::WindowPos::PosCentered,
    sdl2::video::WindowPos::PosCentered,
    800,
    600,
    sdl2::video::OPENGL,
  ).unwrap()
}

fn quit_event() -> bool {
  loop {
    match sdl2::event::poll_event() {
      Event::None => {
        return false;
      },
      Event::Quit{..} => {
        return true;
      }
      Event::AppTerminating{..} => {
        return true;
      }
      _ => {},
    }
  }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::rc::Rc;

use rational::Rational64;
use data::audiosample::{Soniton, ChannelMap};
use data::pixel::Formaton;

#[derive(Clone,Debug,PartialEq)]
pub struct VideoInfo {
    pub width: usize,
    pub height: usize,
    pub format: Option<Rc<Formaton>>,
}

#[derive(Clone,Debug,PartialEq)]
pub struct AudioInfo {
    pub rate: usize,
    pub map: Option<ChannelMap>,
    pub format: Option<Rc<Soniton>>,
}

#[derive(Clone,Debug,PartialEq)]
pub enum MediaKind {
    Video(VideoInfo),
    Audio(AudioInfo),
}

#[derive(Clone,Debug,PartialEq)]
pub struct CodecParams {
    pub kind: Option<MediaKind>,
    pub codec_id: Option<String>,
    pub extradata: Option<Vec<u8>>,
//    pub tag: Option<u32>,
    pub bit_rate: usize,
//    pub bits_per_coded_sample: usize,
}

#[derive(Clone,Debug,PartialEq)]
pub struct Stream {
    pub id: usize,
    pub index: usize,
    pub params : CodecParams,
    pub start: Option<u64>,
    pub duration: Option<u64>,
    pub timebase : Rational64,
//  seek_index : SeekIndex
}

pub struct StreamGroup<'a> {
    pub id: usize,
    pub start: u64,
    pub end: u64,
    pub streams: &'a [Stream],
}
<commit_msg>format: Add convergence_window and delay to the codec parameters<commit_after>#![allow(dead_code)]

use std::rc::Rc;

use rational::Rational64;
use data::audiosample::{Soniton, ChannelMap};
use data::pixel::Formaton;

#[derive(Clone,Debug,PartialEq)]
pub struct VideoInfo {
    pub width: usize,
    pub height: usize,
    pub format: Option<Rc<Formaton>>,
}

#[derive(Clone,Debug,PartialEq)]
pub struct AudioInfo {
    pub rate: usize,
    pub map: Option<ChannelMap>,
    pub format: Option<Rc<Soniton>>,
}

#[derive(Clone,Debug,PartialEq)]
pub enum MediaKind {
    Video(VideoInfo),
    Audio(AudioInfo),
}

#[derive(Clone,Debug,PartialEq)]
pub struct CodecParams {
    pub kind: Option<MediaKind>,
    pub codec_id: Option<String>,
    pub extradata: Option<Vec<u8>>,
//    pub tag: Option<u32>,
    pub bit_rate: usize,
//    pub bits_per_coded_sample: usize,
    /// Number of samples the decode must process
    /// before outputting valid data
    pub convergence_window: usize,
    /// Number of samples the codec needs to process
    /// before returning data
    pub delay: usize,
}

#[derive(Clone,Debug,PartialEq)]
pub struct Stream {
    pub id: usize,
    pub index: usize,
    pub params : CodecParams,
    pub start: Option<u64>,
    pub duration: Option<u64>,
    pub timebase : Rational64,
//  seek_index : SeekIndex
}

pub struct StreamGroup<'a> {
    pub id: usize,
    pub start: u64,
    pub end: u64,
    pub streams: &'a [Stream],
}
<|endoftext|>


<commit_before>use base::world::{CHUNK_SIZE, Chunk, ChunkIndex, HEX_OUTER_RADIUS, World};
use base::math::*;
use glium::{self, DrawParameters, VertexBuffer};
use glium::draw_parameters::{BackfaceCullingMode, DepthTest};
use glium::backend::Facade;
use glium::texture::Texture2d;
use glium::uniforms::SamplerWrapFunction;
use glium::uniforms::MinifySamplerFilter;
use Camera;
use DayTime;
// use SimpleCull;
// use LOCATION;
use util::ToArr;
use world::ChunkRenderer;
use std::rc::Rc;
use base::world::ground::GroundMaterial;

/// Graphical representation of the `base::Chunk`.
pub struct ChunkView {
    offset: AxialPoint,
    renderer: Rc<ChunkRenderer>,
    /// Instance data buffer.
    pillar_buf: VertexBuffer<Instance>, /* save corner positions for draw
                                         * corner_ps: Vec<Point3f>, */
}

impl ChunkView {
    /// Creates the graphical representation of given chunk at the given chunk
    /// offset
    pub fn from_chunk<F: Facade>(chunk: &Chunk,
                                 offset: AxialPoint,
                                 chunk_renderer: Rc<ChunkRenderer>,
                                 facade: &F)
                                 -> Self {

        let mut sections = Vec::new();
        // let mut i = 0;
        // let mut vec = Vec::new();
        {
            // scope so we can borrow mut vec
            // let mut c = |x, pos: Point2f, z| {
            // if x == 0 || x == CHUNK_SIZE || x == (CHUNK_SIZE * CHUNK_SIZE -
            // CHUNK_SIZE) ||
            //        x == (CHUNK_SIZE * CHUNK_SIZE - 1) {
            //         vec.push(Point3f::new(pos.x, pos.y, z));
            //     }
            // };
            for (axial, pillar) in chunk.pillars() {
                let pos = offset.to_real() + axial.to_real();
                // let height = 150.;
                // save if corner (assume fixed location of corners)
                // c(i, pos, height);
                // c(i, pos, 0.);
                // i += 1;
                for section in pillar.sections() {
                    let g = match section.ground {
                        GroundMaterial::Grass => 1,
                        GroundMaterial::Sand => 2,
                        GroundMaterial::Snow => 3,
                        GroundMaterial::Dirt => 4,
                        GroundMaterial::Stone => 5,
                        GroundMaterial::JungleGrass => 1,
                        GroundMaterial::Mulch => 7,
                        GroundMaterial::Debug => 8,
                    };
                    sections.push(Instance {
                        material_color: section.ground.get_color(),
                        ground: g,
                        offset: [pos.x, pos.y, section.bottom.to_real()],
                        height: (section.top.units() - section.bottom.units()) as f32,
                    });
                }
            }
        }

        ChunkView {
            offset: offset,
            renderer: chunk_renderer,
            pillar_buf: VertexBuffer::dynamic(facade, &sections).unwrap(), // corner_ps: vec,
        }
    }

    pub fn draw_shadow<S: glium::Surface>(&self, surface: &mut S, camera: &Camera) {
        let uniforms = uniform! {
            proj_matrix: camera.proj_matrix().to_arr(),
            view_matrix: camera.view_matrix().to_arr(),
        };

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

        surface.draw((self.renderer.pillar_vertices(), self.pillar_buf.per_instance().unwrap()),
                  self.renderer.pillar_indices(),
                  self.renderer.shadow_program(),
                  &uniforms,
                  &params)
            .unwrap();
    }

    pub fn update<F: Facade>(&mut self, facade: &F, world: &mut World) {
        let chunk = world.chunk_at(ChunkIndex(self.offset));

        if chunk.is_none() {
            return;
        }

        let mut sections = Vec::new();

        for (axial, pillar) in chunk.unwrap().pillars() {
            let pos = self.offset.to_real() + axial.to_real();
            for section in pillar.sections() {
                let g = match section.ground {
                    GroundMaterial::Grass => 1,
                    GroundMaterial::Sand => 2,
                    GroundMaterial::Snow => 3,
                    GroundMaterial::Dirt => 4,
                    GroundMaterial::Stone => 5,
                    GroundMaterial::JungleGrass => 1,
                    GroundMaterial::Mulch => 7,
                    GroundMaterial::Debug => 8,
                };
                sections.push(Instance {
                    ground: g,
                    material_color: section.ground.get_color(),
                    offset: [pos.x, pos.y, section.bottom.to_real()],
                    height: (section.top.units() - section.bottom.units()) as f32,
                });
            }
        }
        self.pillar_buf = VertexBuffer::dynamic(facade, &sections).unwrap();
    }

    pub fn draw<S: glium::Surface>(&self,
                                   surface: &mut S,
                                   camera: &Camera,
                                   shadow_map: &Texture2d,
                                   depth_view_proj: &Matrix4<f32>,
                                   daytime: &DayTime,
                                   sun_dir: Vector3f) {

        // // such skill much wow :D
        // let mut i = 0;
        // let mut c = || {
        //     let a = i;
        //     i += 1;
        //     &self.corner_ps[a]
        // };
        // let corner = [c(), c(), c(), c(), c(), c(), c(), c()];

        // let render = match frustum.is_vis(corner) {
        //     LOCATION::Outside => 0,
        //     LOCATION::Inside => 1,
        //     LOCATION::Intersect => 1,
        // };
        // if render == 0 {
        //     return;
        // }

        let real_off = self.offset.to_real();
        let look_at2 = Vector2::new(camera.get_look_at_vector().x, camera.get_look_at_vector().y).normalize();
        let pos2 = Point2::new(camera.position.x, camera.position.y);

        let player_to_chunk = real_off -
                              (pos2 + -look_at2 * CHUNK_SIZE.into() * HEX_OUTER_RADIUS * 2.8);
        if camera.get_look_at_vector().z.abs() < 0.6 && dot(player_to_chunk, look_at2) < 0.0 {
            return;
        }

        let uniforms = uniform! {
            proj_matrix: camera.proj_matrix().to_arr(),
            view_matrix: camera.view_matrix().to_arr(),
            shadow_map: shadow_map.sampled().wrap_function(SamplerWrapFunction::Clamp),
            depth_view_proj: depth_view_proj.to_arr(),
            sun_dir: sun_dir.to_arr(),
            cam_pos: camera.position.to_arr(),
            sun_color: daytime.get_sun_color().to_arr(),
            sky_light: daytime.get_sky_light().to_arr(),

            // Mipmapping and repeating the textures
            sand_texture:  self.renderer.noise_sand.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            snow_texture:  self.renderer.noise_snow.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            grass_texture: self.renderer.noise_grass.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            stone_texture: self.renderer.noise_stone.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            dirt_texture: self.renderer.noise_dirt.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            mulch_texture: self.renderer.noise_mulch.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),

            normal_sand: &self.renderer.normal_sand,
            normal_snow: &self.renderer.normal_snow,
            normal_grass: &self.renderer.normal_grass,
            normal_stone: &self.renderer.normal_stone,
            normal_dirt: &self.renderer.normal_dirt,
            normal_mulch: &self.renderer.normal_mulch,
        };
        let params = DrawParameters {
            depth: glium::Depth {
                write: true,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            backface_culling: BackfaceCullingMode::CullCounterClockwise,
            ..Default::default()
        };

        // Draw hexagons
        surface.draw((self.renderer.pillar_vertices(), self.pillar_buf.per_instance().unwrap()),
                  self.renderer.pillar_indices(),
                  self.renderer.program(),
                  &uniforms,
                  &params)
            .unwrap();
    }
}

/// Vertex type used to render chunks (or hex pillars).
#[derive(Debug, Copy, Clone)]
pub struct Vertex {
    pub position: [f32; 3],
    pub normal: [f32; 3],
    pub radius: f32,
    pub tex_coords: [f32; 2],
}

implement_vertex!(Vertex, position, normal, radius, tex_coords);

/// Instance data for each pillar section.
#[derive(Debug, Copy, Clone)]
pub struct Instance {
    ground: i32,
    /// Material color.
    material_color: [f32; 3],
    /// Offset in world coordinates.
    offset: [f32; 3],
    /// Pillar height.
    height: f32,
}

implement_vertex!(Instance, material_color, offset, ground, height);
<commit_msg>Fix format<commit_after>use base::world::{CHUNK_SIZE, Chunk, ChunkIndex, HEX_OUTER_RADIUS, World};
use base::math::*;
use glium::{self, DrawParameters, VertexBuffer};
use glium::draw_parameters::{BackfaceCullingMode, DepthTest};
use glium::backend::Facade;
use glium::texture::Texture2d;
use glium::uniforms::SamplerWrapFunction;
use glium::uniforms::MinifySamplerFilter;
use Camera;
use DayTime;
// use SimpleCull;
// use LOCATION;
use util::ToArr;
use world::ChunkRenderer;
use std::rc::Rc;
use base::world::ground::GroundMaterial;

/// Graphical representation of the `base::Chunk`.
pub struct ChunkView {
    offset: AxialPoint,
    renderer: Rc<ChunkRenderer>,
    /// Instance data buffer.
    pillar_buf: VertexBuffer<Instance>, /* save corner positions for draw
                                         * corner_ps: Vec<Point3f>, */
}

impl ChunkView {
    /// Creates the graphical representation of given chunk at the given chunk
    /// offset
    pub fn from_chunk<F: Facade>(chunk: &Chunk,
                                 offset: AxialPoint,
                                 chunk_renderer: Rc<ChunkRenderer>,
                                 facade: &F)
                                 -> Self {

        let mut sections = Vec::new();
        // let mut i = 0;
        // let mut vec = Vec::new();
        {
            // scope so we can borrow mut vec
            // let mut c = |x, pos: Point2f, z| {
            // if x == 0 || x == CHUNK_SIZE || x == (CHUNK_SIZE * CHUNK_SIZE -
            // CHUNK_SIZE) ||
            //        x == (CHUNK_SIZE * CHUNK_SIZE - 1) {
            //         vec.push(Point3f::new(pos.x, pos.y, z));
            //     }
            // };
            for (axial, pillar) in chunk.pillars() {
                let pos = offset.to_real() + axial.to_real();
                // let height = 150.;
                // save if corner (assume fixed location of corners)
                // c(i, pos, height);
                // c(i, pos, 0.);
                // i += 1;
                for section in pillar.sections() {
                    let g = match section.ground {
                        GroundMaterial::Grass => 1,
                        GroundMaterial::Sand => 2,
                        GroundMaterial::Snow => 3,
                        GroundMaterial::Dirt => 4,
                        GroundMaterial::Stone => 5,
                        GroundMaterial::JungleGrass => 1,
                        GroundMaterial::Mulch => 7,
                        GroundMaterial::Debug => 8,
                    };
                    sections.push(Instance {
                        material_color: section.ground.get_color(),
                        ground: g,
                        offset: [pos.x, pos.y, section.bottom.to_real()],
                        height: (section.top.units() - section.bottom.units()) as f32,
                    });
                }
            }
        }

        ChunkView {
            offset: offset,
            renderer: chunk_renderer,
            pillar_buf: VertexBuffer::dynamic(facade, &sections).unwrap(), // corner_ps: vec,
        }
    }

    pub fn draw_shadow<S: glium::Surface>(&self, surface: &mut S, camera: &Camera) {
        let uniforms = uniform! {
            proj_matrix: camera.proj_matrix().to_arr(),
            view_matrix: camera.view_matrix().to_arr(),
        };

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

        surface.draw((self.renderer.pillar_vertices(), self.pillar_buf.per_instance().unwrap()),
                  self.renderer.pillar_indices(),
                  self.renderer.shadow_program(),
                  &uniforms,
                  &params)
            .unwrap();
    }

    pub fn update<F: Facade>(&mut self, facade: &F, world: &mut World) {
        let chunk = world.chunk_at(ChunkIndex(self.offset));

        if chunk.is_none() {
            return;
        }

        let mut sections = Vec::new();

        for (axial, pillar) in chunk.unwrap().pillars() {
            let pos = self.offset.to_real() + axial.to_real();
            for section in pillar.sections() {
                let g = match section.ground {
                    GroundMaterial::Grass => 1,
                    GroundMaterial::Sand => 2,
                    GroundMaterial::Snow => 3,
                    GroundMaterial::Dirt => 4,
                    GroundMaterial::Stone => 5,
                    GroundMaterial::JungleGrass => 1,
                    GroundMaterial::Mulch => 7,
                    GroundMaterial::Debug => 8,
                };
                sections.push(Instance {
                    ground: g,
                    material_color: section.ground.get_color(),
                    offset: [pos.x, pos.y, section.bottom.to_real()],
                    height: (section.top.units() - section.bottom.units()) as f32,
                });
            }
        }
        self.pillar_buf = VertexBuffer::dynamic(facade, &sections).unwrap();
    }

    pub fn draw<S: glium::Surface>(&self,
                                   surface: &mut S,
                                   camera: &Camera,
                                   shadow_map: &Texture2d,
                                   depth_view_proj: &Matrix4<f32>,
                                   daytime: &DayTime,
                                   sun_dir: Vector3f) {

        // // such skill much wow :D
        // let mut i = 0;
        // let mut c = || {
        //     let a = i;
        //     i += 1;
        //     &self.corner_ps[a]
        // };
        // let corner = [c(), c(), c(), c(), c(), c(), c(), c()];

        // let render = match frustum.is_vis(corner) {
        //     LOCATION::Outside => 0,
        //     LOCATION::Inside => 1,
        //     LOCATION::Intersect => 1,
        // };
        // if render == 0 {
        //     return;
        // }

        let real_off = self.offset.to_real();
        let look_at2 = Vector2::new(camera.get_look_at_vector().x, camera.get_look_at_vector().y)
            .normalize();
        let pos2 = Point2::new(camera.position.x, camera.position.y);

        let player_to_chunk = real_off -
                              (pos2 + -look_at2 * CHUNK_SIZE.into() * HEX_OUTER_RADIUS * 2.8);
        if camera.get_look_at_vector().z.abs() < 0.6 && dot(player_to_chunk, look_at2) < 0.0 {
            return;
        }

        let uniforms = uniform! {
            proj_matrix: camera.proj_matrix().to_arr(),
            view_matrix: camera.view_matrix().to_arr(),
            shadow_map: shadow_map.sampled().wrap_function(SamplerWrapFunction::Clamp),
            depth_view_proj: depth_view_proj.to_arr(),
            sun_dir: sun_dir.to_arr(),
            cam_pos: camera.position.to_arr(),
            sun_color: daytime.get_sun_color().to_arr(),
            sky_light: daytime.get_sky_light().to_arr(),

            // Mipmapping and repeating the textures
            sand_texture:  self.renderer.noise_sand.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            snow_texture:  self.renderer.noise_snow.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            grass_texture: self.renderer.noise_grass.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            stone_texture: self.renderer.noise_stone.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            dirt_texture: self.renderer.noise_dirt.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),
            mulch_texture: self.renderer.noise_mulch.sampled()
                .minify_filter(MinifySamplerFilter::NearestMipmapLinear)
                .wrap_function(SamplerWrapFunction::Repeat),

            normal_sand: &self.renderer.normal_sand,
            normal_snow: &self.renderer.normal_snow,
            normal_grass: &self.renderer.normal_grass,
            normal_stone: &self.renderer.normal_stone,
            normal_dirt: &self.renderer.normal_dirt,
            normal_mulch: &self.renderer.normal_mulch,
        };
        let params = DrawParameters {
            depth: glium::Depth {
                write: true,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            backface_culling: BackfaceCullingMode::CullCounterClockwise,
            ..Default::default()
        };

        // Draw hexagons
        surface.draw((self.renderer.pillar_vertices(), self.pillar_buf.per_instance().unwrap()),
                  self.renderer.pillar_indices(),
                  self.renderer.program(),
                  &uniforms,
                  &params)
            .unwrap();
    }
}

/// Vertex type used to render chunks (or hex pillars).
#[derive(Debug, Copy, Clone)]
pub struct Vertex {
    pub position: [f32; 3],
    pub normal: [f32; 3],
    pub radius: f32,
    pub tex_coords: [f32; 2],
}

implement_vertex!(Vertex, position, normal, radius, tex_coords);

/// Instance data for each pillar section.
#[derive(Debug, Copy, Clone)]
pub struct Instance {
    ground: i32,
    /// Material color.
    material_color: [f32; 3],
    /// Offset in world coordinates.
    offset: [f32; 3],
    /// Pillar height.
    height: f32,
}

implement_vertex!(Instance, material_color, offset, ground, height);
<|endoftext|>