<commit_before>//! Tests for multiple `--target` flags to subcommands

use cargo_test_support::{basic_manifest, cross_compile, project, rustc_host};

#[cargo_test]
fn double_target_rejected() {
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build --target a --target b")
        .with_stderr("[ERROR] specifying multiple `--target` flags requires `-Zmultitarget`")
        .with_status(101)
        .run();
}

#[cargo_test]
fn double_target_rejected_with_config() {
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            r#"
                [build]
                target = ["a", "b"]
            "#,
        )
        .build();

    p.cargo("build")
        .with_stderr("[ERROR] specifying multiple `--target` flags requires `-Zmultitarget`")
        .with_status(101)
        .run();
}

#[cargo_test]
fn simple_build() {
    if cross_compile::disabled() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build -Z multitarget")
        .arg("--target")
        .arg(&t1)
        .arg("--target")
        .arg(&t2)
        .masquerade_as_nightly_cargo()
        .run();

    assert!(p.target_bin(t1, "foo").is_file());
    assert!(p.target_bin(t2, "foo").is_file());
}

#[cargo_test]
fn simple_build_with_config() {
    if cross_compile::disabled() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            &format!(
                r#"
                    [unstable]
                    multitarget = true
                    [build]
                    target = ["{t1}", "{t2}"]
                "#
            ),
        )
        .build();

    p.cargo("build").masquerade_as_nightly_cargo().run();

    assert!(p.target_bin(t1, "foo").is_file());
    assert!(p.target_bin(t2, "foo").is_file());
}

#[cargo_test]
fn simple_test() {
    if !cross_compile::can_run_on_host() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/lib.rs", "fn main() {}")
        .build();

    p.cargo("test -Z multitarget")
        .arg("--target")
        .arg(&t1)
        .arg("--target")
        .arg(&t2)
        .masquerade_as_nightly_cargo()
        .with_stderr_contains(&format!("[RUNNING] [..]{}[..]", t1))
        .with_stderr_contains(&format!("[RUNNING] [..]{}[..]", t2))
        .run();
}

#[cargo_test]
fn simple_run() {
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("run -Z multitarget --target a --target b")
        .with_stderr("[ERROR] only one `--target` argument is supported")
        .with_status(101)
        .masquerade_as_nightly_cargo()
        .run();
}

#[cargo_test]
fn simple_doc() {
    if cross_compile::disabled() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/lib.rs", "//! empty lib")
        .build();

    p.cargo("doc -Z multitarget")
        .arg("--target")
        .arg(&t1)
        .arg("--target")
        .arg(&t2)
        .masquerade_as_nightly_cargo()
        .run();

    assert!(p.build_dir().join(&t1).join("doc/foo/index.html").is_file());
    assert!(p.build_dir().join(&t2).join("doc/foo/index.html").is_file());
}

#[cargo_test]
fn simple_check() {
    if cross_compile::disabled() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("check -Z multitarget")
        .arg("--target")
        .arg(&t1)
        .arg("--target")
        .arg(&t2)
        .masquerade_as_nightly_cargo()
        .run();
}

#[cargo_test]
fn same_value_twice() {
    if cross_compile::disabled() {
        return;
    }
    let t = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build -Z multitarget")
        .arg("--target")
        .arg(&t)
        .arg("--target")
        .arg(&t)
        .masquerade_as_nightly_cargo()
        .run();

    assert!(p.target_bin(t, "foo").is_file());
}

#[cargo_test]
fn same_value_twice_with_config() {
    if cross_compile::disabled() {
        return;
    }
    let t = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            &format!(
                r#"
                    [unstable]
                    multitarget = true
                    [build]
                    target = ["{t}", "{t}"]
                "#
            ),
        )
        .build();

    p.cargo("build").masquerade_as_nightly_cargo().run();

    assert!(p.target_bin(t, "foo").is_file());
}

#[cargo_test]
fn works_with_config_in_both_string_or_list() {
    if cross_compile::disabled() {
        return;
    }
    let t = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            &format!(
                r#"
                    [unstable]
                    multitarget = true
                    [build]
                    target = "{t}"
                "#
            ),
        )
        .build();

    p.cargo("build").masquerade_as_nightly_cargo().run();

    assert!(p.target_bin(t, "foo").is_file());

    p.cargo("clean").run();

    p.change_file(
        ".cargo/config.toml",
        &format!(
            r#"
                [unstable]
                multitarget = true
                [build]
                target = ["{t}"]
            "#
        ),
    );

    p.cargo("build").masquerade_as_nightly_cargo().run();

    assert!(p.target_bin(t, "foo").is_file());
}

#[cargo_test]
fn works_with_env() {
    let t = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build")
        .env("CARGO_BUILD_TARGET", t)
        .masquerade_as_nightly_cargo()
        .run();

    assert!(p.target_bin(t, "foo").is_file());
}
<commit_msg>Remove unnecessary nightly masquerade<commit_after>//! Tests for multiple `--target` flags to subcommands

use cargo_test_support::{basic_manifest, cross_compile, project, rustc_host};

#[cargo_test]
fn double_target_rejected() {
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build --target a --target b")
        .with_stderr("[ERROR] specifying multiple `--target` flags requires `-Zmultitarget`")
        .with_status(101)
        .run();
}

#[cargo_test]
fn double_target_rejected_with_config() {
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            r#"
                [build]
                target = ["a", "b"]
            "#,
        )
        .build();

    p.cargo("build")
        .with_stderr("[ERROR] specifying multiple `--target` flags requires `-Zmultitarget`")
        .with_status(101)
        .run();
}

#[cargo_test]
fn simple_build() {
    if cross_compile::disabled() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build -Z multitarget")
        .arg("--target")
        .arg(&t1)
        .arg("--target")
        .arg(&t2)
        .masquerade_as_nightly_cargo()
        .run();

    assert!(p.target_bin(t1, "foo").is_file());
    assert!(p.target_bin(t2, "foo").is_file());
}

#[cargo_test]
fn simple_build_with_config() {
    if cross_compile::disabled() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            &format!(
                r#"
                    [unstable]
                    multitarget = true
                    [build]
                    target = ["{t1}", "{t2}"]
                "#
            ),
        )
        .build();

    p.cargo("build").masquerade_as_nightly_cargo().run();

    assert!(p.target_bin(t1, "foo").is_file());
    assert!(p.target_bin(t2, "foo").is_file());
}

#[cargo_test]
fn simple_test() {
    if !cross_compile::can_run_on_host() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/lib.rs", "fn main() {}")
        .build();

    p.cargo("test -Z multitarget")
        .arg("--target")
        .arg(&t1)
        .arg("--target")
        .arg(&t2)
        .masquerade_as_nightly_cargo()
        .with_stderr_contains(&format!("[RUNNING] [..]{}[..]", t1))
        .with_stderr_contains(&format!("[RUNNING] [..]{}[..]", t2))
        .run();
}

#[cargo_test]
fn simple_run() {
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("run -Z multitarget --target a --target b")
        .with_stderr("[ERROR] only one `--target` argument is supported")
        .with_status(101)
        .masquerade_as_nightly_cargo()
        .run();
}

#[cargo_test]
fn simple_doc() {
    if cross_compile::disabled() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/lib.rs", "//! empty lib")
        .build();

    p.cargo("doc -Z multitarget")
        .arg("--target")
        .arg(&t1)
        .arg("--target")
        .arg(&t2)
        .masquerade_as_nightly_cargo()
        .run();

    assert!(p.build_dir().join(&t1).join("doc/foo/index.html").is_file());
    assert!(p.build_dir().join(&t2).join("doc/foo/index.html").is_file());
}

#[cargo_test]
fn simple_check() {
    if cross_compile::disabled() {
        return;
    }
    let t1 = cross_compile::alternate();
    let t2 = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("check -Z multitarget")
        .arg("--target")
        .arg(&t1)
        .arg("--target")
        .arg(&t2)
        .masquerade_as_nightly_cargo()
        .run();
}

#[cargo_test]
fn same_value_twice() {
    if cross_compile::disabled() {
        return;
    }
    let t = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build -Z multitarget")
        .arg("--target")
        .arg(&t)
        .arg("--target")
        .arg(&t)
        .masquerade_as_nightly_cargo()
        .run();

    assert!(p.target_bin(t, "foo").is_file());
}

#[cargo_test]
fn same_value_twice_with_config() {
    if cross_compile::disabled() {
        return;
    }
    let t = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            &format!(
                r#"
                    [unstable]
                    multitarget = true
                    [build]
                    target = ["{t}", "{t}"]
                "#
            ),
        )
        .build();

    p.cargo("build").masquerade_as_nightly_cargo().run();

    assert!(p.target_bin(t, "foo").is_file());
}

#[cargo_test]
fn works_with_config_in_both_string_or_list() {
    if cross_compile::disabled() {
        return;
    }
    let t = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            &format!(
                r#"
                    [unstable]
                    multitarget = true
                    [build]
                    target = "{t}"
                "#
            ),
        )
        .build();

    p.cargo("build").masquerade_as_nightly_cargo().run();

    assert!(p.target_bin(t, "foo").is_file());

    p.cargo("clean").run();

    p.change_file(
        ".cargo/config.toml",
        &format!(
            r#"
                [unstable]
                multitarget = true
                [build]
                target = ["{t}"]
            "#
        ),
    );

    p.cargo("build").masquerade_as_nightly_cargo().run();

    assert!(p.target_bin(t, "foo").is_file());
}

#[cargo_test]
fn works_with_env() {
    let t = rustc_host();
    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build").env("CARGO_BUILD_TARGET", t).run();

    assert!(p.target_bin(t, "foo").is_file());
}
<|endoftext|>


<commit_before>use std::collections::{HashSet, HashMap};
use log;
use cpp_data::{CppData, CppTypeKind, CppVisibility};
use caption_strategy::MethodCaptionStrategy;
use cpp_method::{CppMethod, CppMethodKind};
use cpp_ffi_data::{CppAndFfiMethod, c_base_name};
use utils::add_to_multihash;
use serializable::CppLibSpec;

struct CGenerator<'a> {
  abstract_classes: Vec<String>,
  cpp_data: &'a CppData,
  cpp_lib_spec: CppLibSpec,
}

#[derive(Debug, Clone)]
pub struct CppFfiHeaderData {
  pub include_file: String,
  pub include_file_base_name: String,
  pub methods: Vec<CppAndFfiMethod>,
}

pub struct CppAndFfiData {
  pub cpp_data: CppData,
  pub cpp_ffi_headers: Vec<CppFfiHeaderData>,
}

/// Runs FFI generator
pub fn run(cpp_data: &CppData, cpp_lib_spec: CppLibSpec) -> Vec<CppFfiHeaderData> {
  let abstract_classes = cpp_data.types
    .iter()
    .filter_map(|t| {
      if let CppTypeKind::Class { .. } = t.kind {
        if cpp_data.get_pure_virtual_methods(&t.name).len() > 0 {
          Some(t.name.clone())
        } else {
          None
        }
      } else {
        None
      }
    })
    .collect();
  log::info(format!("Abstract classes: {:?}", abstract_classes));
  let generator = CGenerator {
    cpp_data: cpp_data,
    abstract_classes: abstract_classes,
    cpp_lib_spec: cpp_lib_spec,
  };

  let mut c_headers = Vec::new();
  let mut include_name_list: Vec<_> = generator.cpp_data.all_include_files().into_iter().collect();
  include_name_list.sort();

  for include_file in &include_name_list {
    if let Some(ref include_file_blacklist) = generator.cpp_lib_spec.include_file_blacklist {
      if include_file_blacklist.iter().find(|x| x == &include_file).is_some() {
        log::info(format!("Skipping include file {}", include_file));
        continue;
      }
    }
    let mut include_file_base_name = include_file.clone();

    if let Some(index) = include_file_base_name.find(".") {
      include_file_base_name = include_file_base_name[0..index].to_string();
    }
    let methods = generator.process_methods(&include_file,
                                            &include_file_base_name,
                                            generator.cpp_data
                                              .methods
                                              .iter()
                                              .filter(|x| &x.include_file == include_file));
    if methods.is_empty() {
      log::info(format!("Skipping empty include file {}", include_file));
    } else {
      c_headers.push(CppFfiHeaderData {
        include_file: include_file.clone(),
        include_file_base_name: include_file_base_name,
        methods: methods,
      });
    }
  }
  c_headers
}

impl<'a> CGenerator<'a> {
  /// Returns false if the method is excluded from processing
  /// for some reason
  fn should_process_method(&self, method: &CppMethod) -> bool {
    let full_name = method.full_name();
    let short_text = method.short_text();
    let class_name = method.class_name().unwrap_or(&String::new()).clone();
    log::debug(format!("method name: {}", full_name));
    log::debug(format!(" short_text: {}", short_text));
    if let Some(ref ffi_methods_blacklist) = self.cpp_lib_spec.ffi_methods_blacklist {
      if ffi_methods_blacklist.iter()
        .find(|&x| x == &full_name || x == &short_text || x == &class_name)
        .is_some() {
        log::noisy(format!("Skipping blacklisted method: \n{}\n", method.short_text()));
        return false;
      }
    }
    if let Some(ref membership) = method.class_membership {
      if membership.kind == CppMethodKind::Constructor {
        let class_name = &membership.class_type.name;
        if self.abstract_classes.iter().find(|&x| x == class_name).is_some() {
          log::noisy(format!("Method is skipped:\n{}\nConstructors are not allowed for abstract \
                              classes.\n",
                             method.short_text()));
          return false;
        }
      }
      if membership.visibility == CppVisibility::Private {
        return false;
      }
      if membership.visibility == CppVisibility::Protected {
        log::noisy(format!("Skipping protected method: \n{}\n", method.short_text()));
        return false;
      }
      if membership.is_signal {
        log::warning(format!("Skipping signal: \n{}\n", method.short_text()));
        return false;
      }
    }
    if method.template_arguments.is_some() {
      // TODO: check findChildren and similar instantiated methods
      log::noisy(format!("Skipping template method: \n{}\n", method.short_text()));
      return false;
    }
    if method.all_involved_types()
      .iter()
      .find(|x| x.base.is_or_contains_template_parameter())
      .is_some() {
      log::noisy(format!("Skipping method containing template parameters: \n{}\n",
                         method.short_text()));
      return false;
    }
    true
  }

  /// Generates FFI wrappers for all specified methods,
  /// resolving all name conflicts using additional method captions.
  fn process_methods<'b, I: Iterator<Item = &'b CppMethod>>(&self,
                                                            include_file: &String,
                                                            include_file_base_name: &String,
                                                            methods: I)
                                                            -> Vec<CppAndFfiMethod> {
    log::info(format!("Generating C++ FFI methods for header: {}", include_file));
    let mut hash_name_to_methods: HashMap<String, Vec<_>> = HashMap::new();
    for ref method in methods {
      if !self.should_process_method(method) {
        continue;
      }
      match method.to_ffi_signatures() {
        Err(msg) => {
          log::warning(format!("Unable to produce C function for method:\n{}\nError:{}\n",
                               method.short_text(),
                               msg));
        }
        Ok(results) => {
          for result in results {
            match c_base_name(&result.cpp_method,
                              &result.allocation_place,
                              include_file_base_name) {
              Err(msg) => {
                log::warning(format!("Unable to produce C function for method:\n{}\nError:{}\n",
                                     method.short_text(),
                                     msg));
              }
              Ok(name) => {

                add_to_multihash(&mut hash_name_to_methods,
                                 &format!("{}_{}", &self.cpp_lib_spec.name, name),
                                 result);
              }
            }
          }
        }
      }
    }

    let mut processed_methods = Vec::new();
    for (key, mut values) in hash_name_to_methods.into_iter() {
      if values.len() == 1 {
        processed_methods.push(CppAndFfiMethod::new(values.remove(0), key.clone()));
        continue;
      }
      let mut found_strategy = None;
      for strategy in MethodCaptionStrategy::all() {
        let mut type_captions: HashSet<_> = HashSet::new();
        let mut ok = true;
        for value in &values {
          let caption = value.c_signature.caption(strategy.clone());
          if type_captions.contains(&caption) {
            ok = false;
            break;
          }
          type_captions.insert(caption);
        }
        if ok {
          found_strategy = Some(strategy);
          break;
        }
      }
      if let Some(strategy) = found_strategy {
        for x in values {
          let caption = x.c_signature.caption(strategy.clone());
          let final_name = if caption.is_empty() {
            key.clone()
          } else {
            format!("{}_{}", key, caption)
          };
          processed_methods.push(CppAndFfiMethod::new(x, final_name));
        }
      } else {
        log::error(format!("values dump: {:?}\n", values));
        log::error(format!("All type caption strategies have failed! Involved functions:"));
        for value in values {
          log::error(format!("  {}", value.cpp_method.short_text()));
        }
        panic!("all type caption strategies have failed");
      }
    }
    processed_methods.sort_by(|a, b| a.c_name.cmp(&b.c_name));
    processed_methods
  }
}
<commit_msg>block template methods for now<commit_after>use std::collections::{HashSet, HashMap};
use log;
use cpp_data::{CppData, CppTypeKind, CppVisibility};
use caption_strategy::MethodCaptionStrategy;
use cpp_method::{CppMethod, CppMethodKind};
use cpp_ffi_data::{CppAndFfiMethod, c_base_name};
use utils::add_to_multihash;
use serializable::CppLibSpec;

struct CGenerator<'a> {
  abstract_classes: Vec<String>,
  cpp_data: &'a CppData,
  cpp_lib_spec: CppLibSpec,
}

#[derive(Debug, Clone)]
pub struct CppFfiHeaderData {
  pub include_file: String,
  pub include_file_base_name: String,
  pub methods: Vec<CppAndFfiMethod>,
}

pub struct CppAndFfiData {
  pub cpp_data: CppData,
  pub cpp_ffi_headers: Vec<CppFfiHeaderData>,
}

/// Runs FFI generator
pub fn run(cpp_data: &CppData, cpp_lib_spec: CppLibSpec) -> Vec<CppFfiHeaderData> {
  let abstract_classes = cpp_data.types
    .iter()
    .filter_map(|t| {
      if let CppTypeKind::Class { .. } = t.kind {
        if cpp_data.get_pure_virtual_methods(&t.name).len() > 0 {
          Some(t.name.clone())
        } else {
          None
        }
      } else {
        None
      }
    })
    .collect();
  log::info(format!("Abstract classes: {:?}", abstract_classes));
  let generator = CGenerator {
    cpp_data: cpp_data,
    abstract_classes: abstract_classes,
    cpp_lib_spec: cpp_lib_spec,
  };

  let mut c_headers = Vec::new();
  let mut include_name_list: Vec<_> = generator.cpp_data.all_include_files().into_iter().collect();
  include_name_list.sort();

  for include_file in &include_name_list {
    if let Some(ref include_file_blacklist) = generator.cpp_lib_spec.include_file_blacklist {
      if include_file_blacklist.iter().find(|x| x == &include_file).is_some() {
        log::info(format!("Skipping include file {}", include_file));
        continue;
      }
    }
    let mut include_file_base_name = include_file.clone();

    if let Some(index) = include_file_base_name.find(".") {
      include_file_base_name = include_file_base_name[0..index].to_string();
    }
    let methods = generator.process_methods(&include_file,
                                            &include_file_base_name,
                                            generator.cpp_data
                                              .methods
                                              .iter()
                                              .filter(|x| &x.include_file == include_file));
    if methods.is_empty() {
      log::info(format!("Skipping empty include file {}", include_file));
    } else {
      c_headers.push(CppFfiHeaderData {
        include_file: include_file.clone(),
        include_file_base_name: include_file_base_name,
        methods: methods,
      });
    }
  }
  c_headers
}

impl<'a> CGenerator<'a> {
  /// Returns false if the method is excluded from processing
  /// for some reason
  fn should_process_method(&self, method: &CppMethod) -> bool {
    let full_name = method.full_name();
    let short_text = method.short_text();
    let class_name = method.class_name().unwrap_or(&String::new()).clone();
    log::debug(format!("method name: {}", full_name));
    log::debug(format!(" short_text: {}", short_text));
    if let Some(ref ffi_methods_blacklist) = self.cpp_lib_spec.ffi_methods_blacklist {
      if ffi_methods_blacklist.iter()
        .find(|&x| x == &full_name || x == &short_text || x == &class_name)
        .is_some() {
        log::noisy(format!("Skipping blacklisted method: \n{}\n", method.short_text()));
        return false;
      }
    }
    if let Some(ref membership) = method.class_membership {
      if membership.kind == CppMethodKind::Constructor {
        let class_name = &membership.class_type.name;
        if self.abstract_classes.iter().find(|&x| x == class_name).is_some() {
          log::noisy(format!("Method is skipped:\n{}\nConstructors are not allowed for abstract \
                              classes.\n",
                             method.short_text()));
          return false;
        }
      }
      if membership.visibility == CppVisibility::Private {
        return false;
      }
      if membership.visibility == CppVisibility::Protected {
        log::noisy(format!("Skipping protected method: \n{}\n", method.short_text()));
        return false;
      }
      if membership.is_signal {
        log::warning(format!("Skipping signal: \n{}\n", method.short_text()));
        return false;
      }
    }
    if method.template_arguments.is_some() {
      log::noisy(format!("Skipping template method: \n{}\n", method.short_text()));
      return false;
    }
    if method.template_arguments_values.is_some() {
      // TODO: re-enable after template test compilation (#24) is implemented
      log::noisy(format!("Skipping template method: \n{}\n", method.short_text()));
      return false;
    }
    if method.all_involved_types()
      .iter()
      .find(|x| x.base.is_or_contains_template_parameter())
      .is_some() {
      log::noisy(format!("Skipping method containing template parameters: \n{}\n",
                         method.short_text()));
      return false;
    }
    true
  }

  /// Generates FFI wrappers for all specified methods,
  /// resolving all name conflicts using additional method captions.
  fn process_methods<'b, I: Iterator<Item = &'b CppMethod>>(&self,
                                                            include_file: &String,
                                                            include_file_base_name: &String,
                                                            methods: I)
                                                            -> Vec<CppAndFfiMethod> {
    log::info(format!("Generating C++ FFI methods for header: {}", include_file));
    let mut hash_name_to_methods: HashMap<String, Vec<_>> = HashMap::new();
    for ref method in methods {
      if !self.should_process_method(method) {
        continue;
      }
      match method.to_ffi_signatures() {
        Err(msg) => {
          log::warning(format!("Unable to produce C function for method:\n{}\nError:{}\n",
                               method.short_text(),
                               msg));
        }
        Ok(results) => {
          for result in results {
            match c_base_name(&result.cpp_method,
                              &result.allocation_place,
                              include_file_base_name) {
              Err(msg) => {
                log::warning(format!("Unable to produce C function for method:\n{}\nError:{}\n",
                                     method.short_text(),
                                     msg));
              }
              Ok(name) => {

                add_to_multihash(&mut hash_name_to_methods,
                                 &format!("{}_{}", &self.cpp_lib_spec.name, name),
                                 result);
              }
            }
          }
        }
      }
    }

    let mut processed_methods = Vec::new();
    for (key, mut values) in hash_name_to_methods.into_iter() {
      if values.len() == 1 {
        processed_methods.push(CppAndFfiMethod::new(values.remove(0), key.clone()));
        continue;
      }
      let mut found_strategy = None;
      for strategy in MethodCaptionStrategy::all() {
        let mut type_captions: HashSet<_> = HashSet::new();
        let mut ok = true;
        for value in &values {
          let caption = value.c_signature.caption(strategy.clone());
          if type_captions.contains(&caption) {
            ok = false;
            break;
          }
          type_captions.insert(caption);
        }
        if ok {
          found_strategy = Some(strategy);
          break;
        }
      }
      if let Some(strategy) = found_strategy {
        for x in values {
          let caption = x.c_signature.caption(strategy.clone());
          let final_name = if caption.is_empty() {
            key.clone()
          } else {
            format!("{}_{}", key, caption)
          };
          processed_methods.push(CppAndFfiMethod::new(x, final_name));
        }
      } else {
        log::error(format!("values dump: {:?}\n", values));
        log::error(format!("All type caption strategies have failed! Involved functions:"));
        for value in values {
          log::error(format!("  {}", value.cpp_method.short_text()));
        }
        panic!("all type caption strategies have failed");
      }
    }
    processed_methods.sort_by(|a, b| a.c_name.cmp(&b.c_name));
    processed_methods
  }
}
<|endoftext|>


<commit_before>mod age;
mod block;
mod captures;
mod details;
mod ed;
mod gc;
mod na;
mod parse;
mod pool;
mod range;
mod ud;
mod ur;

use std::collections::HashMap;
use std::fs::File;
use std::io::{BufWriter, Write};

use byteorder::{BigEndian, WriteBytesExt};
use failure::Error;

use crate::age::age_handler;
use crate::block::block_handler;
use crate::details::Details;
use crate::ed::ed_handler;
use crate::gc::gc_handler;
use crate::na::na_handler;
use crate::parse::parse;
use crate::pool::{Pool, Popularity};
use crate::ud::ud_handler;
use crate::ur::ur_handler;

fn main() -> Result<(), Error> {
    let mut gc_labels = HashMap::default();

    parse(
        &mut gc_labels,
        gc_handler,
        "PropertyValueAliases.txt",
        r"^gc *; *(?P<key>[^ ]+) *; *(?P<value>([^ ]+))",
    )?;

    let mut ud = points();

    parse(
        &mut ud,
        |sink, captures| ud_handler(&gc_labels, sink, captures),
        "UnicodeData.txt",
        r"^(?P<point>[0-9A-F]+);(?P<name>[^;]+);(?P<gc>[^;]+)",
    )?;

    parse(
        &mut ud,
        block_handler,
        "Blocks.txt",
        r"^(?P<first>[0-9A-F]+)[.][.](?P<last>[0-9A-F]+); (?P<value>.+)",
    )?;

    parse(
        &mut ud,
        age_handler,
        "DerivedAge.txt",
        r"^(?P<first>[0-9A-F]+)(?:[.][.](?P<last>[0-9A-F]+))?\s*;\s*(?P<value>[^ ]+)",
    )?;

    parse(
        &mut ud,
        na_handler,
        "NameAliases.txt",
        r"^(?P<point>[0-9A-F]+);(?P<alias>[^;]+);(?P<type>[^;]+)",
    )?;

    parse(
        &mut ud,
        ur_handler,
        "Unihan_Readings.txt",
        r"^U[+](?P<point>[0-9A-F]+)\t(?P<key>kMandarin|kDefinition)\t(?P<value>.+)",
    )?;

    parse(
        &mut ud,
        ed_handler,
        "emoji-data.txt",
        r"^(?P<first>[0-9A-F]+)(?:[.][.](?P<last>[0-9A-F]+))?\s*;\s*Emoji_Presentation(\s|#|$)",
    )?;

    let mut popularity = Popularity::default();

    vote(&mut popularity, &ud, |x| x.name.as_ref());
    vote(&mut popularity, &ud, |x| x.gc.as_ref());
    vote(&mut popularity, &ud, |x| x.block.as_ref());
    vote(&mut popularity, &ud, |x| x.age.as_ref());
    vote(&mut popularity, &ud, |x| x.mpy.as_ref());

    let popularity = popularity.report();

    write("../data.string.json", |mut sink| {
        write!(sink, "{}", serde_json::to_string(&popularity)?)?;

        Ok(())
    })?;

    let mut pool = Pool::default();

    for string in popularity {
        pool.r#use(&string);
    }

    write_pool_indices(&ud, &mut pool, "../data.name.bin", |x| x.name.as_ref())?;
    write_pool_indices(&ud, &mut pool, "../data.gc.bin", |x| x.gc.as_ref())?;
    write_pool_indices(&ud, &mut pool, "../data.block.bin", |x| x.block.as_ref())?;
    write_pool_indices(&ud, &mut pool, "../data.age.bin", |x| x.age.as_ref())?;
    write_pool_indices(&ud, &mut pool, "../data.mpy.bin", |x| x.mpy.as_ref())?;

    Ok(())
}

fn points<T: Default>() -> Vec<T> {
    let mut result = Vec::with_capacity(0x110000);
    result.resize_with(0x110000, Default::default);

    result
}

fn vote<G: FnMut(&Details) -> Option<&String>>(
    sink: &mut Popularity,
    source: &Vec<Details>,
    mut getter: G,
) {
    for details in source {
        if let Some(string) = getter(details) {
            sink.vote(string);
        }
    }
}

fn write<W: FnOnce(BufWriter<File>) -> Result<(), Error>>(
    path: &str,
    writer: W,
) -> Result<(), Error> {
    println!("Writing {} ...", path);

    writer(BufWriter::new(File::create(path)?))
}

fn write_pool_indices<G: FnMut(&Details) -> Option<&String>>(
    source: &Vec<Details>,
    pool: &mut Pool,
    path: &str,
    mut getter: G,
) -> Result<(), Error> {
    write(path, |mut sink| {
        for details in source {
            if let Some(string) = getter(details) {
                let index = pool.r#use(&string);
                assert!(index < 0xFFFF);
                sink.write_u16::<BigEndian>(index)?;
            } else {
                sink.write_u16::<BigEndian>(0xFFFF)?;
            }
        }

        Ok(())
    })
}
<commit_msg>port data.bits.bin writer to Rust<commit_after>mod age;
mod block;
mod captures;
mod details;
mod ed;
mod gc;
mod na;
mod parse;
mod pool;
mod range;
mod ud;
mod ur;

use std::collections::HashMap;
use std::fs::File;
use std::io::{BufWriter, Write};

use byteorder::{BigEndian, WriteBytesExt};
use failure::Error;

use crate::age::age_handler;
use crate::block::block_handler;
use crate::details::Details;
use crate::ed::ed_handler;
use crate::gc::gc_handler;
use crate::na::na_handler;
use crate::parse::parse;
use crate::pool::{Pool, Popularity};
use crate::ud::ud_handler;
use crate::ur::ur_handler;

fn main() -> Result<(), Error> {
    let mut gc_labels = HashMap::default();

    parse(
        &mut gc_labels,
        gc_handler,
        "PropertyValueAliases.txt",
        r"^gc *; *(?P<key>[^ ]+) *; *(?P<value>([^ ]+))",
    )?;

    let mut ud = points();

    parse(
        &mut ud,
        |sink, captures| ud_handler(&gc_labels, sink, captures),
        "UnicodeData.txt",
        r"^(?P<point>[0-9A-F]+);(?P<name>[^;]+);(?P<gc>[^;]+)",
    )?;

    parse(
        &mut ud,
        block_handler,
        "Blocks.txt",
        r"^(?P<first>[0-9A-F]+)[.][.](?P<last>[0-9A-F]+); (?P<value>.+)",
    )?;

    parse(
        &mut ud,
        age_handler,
        "DerivedAge.txt",
        r"^(?P<first>[0-9A-F]+)(?:[.][.](?P<last>[0-9A-F]+))?\s*;\s*(?P<value>[^ ]+)",
    )?;

    parse(
        &mut ud,
        na_handler,
        "NameAliases.txt",
        r"^(?P<point>[0-9A-F]+);(?P<alias>[^;]+);(?P<type>[^;]+)",
    )?;

    parse(
        &mut ud,
        ur_handler,
        "Unihan_Readings.txt",
        r"^U[+](?P<point>[0-9A-F]+)\t(?P<key>kMandarin|kDefinition)\t(?P<value>.+)",
    )?;

    parse(
        &mut ud,
        ed_handler,
        "emoji-data.txt",
        r"^(?P<first>[0-9A-F]+)(?:[.][.](?P<last>[0-9A-F]+))?\s*;\s*Emoji_Presentation(\s|#|$)",
    )?;

    let mut popularity = Popularity::default();

    vote(&mut popularity, &ud, |x| x.name.as_ref());
    vote(&mut popularity, &ud, |x| x.gc.as_ref());
    vote(&mut popularity, &ud, |x| x.block.as_ref());
    vote(&mut popularity, &ud, |x| x.age.as_ref());
    vote(&mut popularity, &ud, |x| x.mpy.as_ref());

    let popularity = popularity.report();

    write("../data.string.json", |mut sink| {
        write!(sink, "{}", serde_json::to_string(&popularity)?)?;

        Ok(())
    })?;

    let mut pool = Pool::default();

    for string in popularity {
        pool.r#use(&string);
    }

    write_pool_indices(&ud, &mut pool, "../data.name.bin", |x| x.name.as_ref())?;
    write_pool_indices(&ud, &mut pool, "../data.gc.bin", |x| x.gc.as_ref())?;
    write_pool_indices(&ud, &mut pool, "../data.block.bin", |x| x.block.as_ref())?;
    write_pool_indices(&ud, &mut pool, "../data.age.bin", |x| x.age.as_ref())?;
    write_pool_indices(&ud, &mut pool, "../data.mpy.bin", |x| x.mpy.as_ref())?;

    write("../data.bits.bin", |mut sink| {
        for details in ud {
            sink.write_u8(details.bits)?;
        }

        Ok(())
    })?;

    Ok(())
}

fn points<T: Default>() -> Vec<T> {
    let mut result = Vec::with_capacity(0x110000);
    result.resize_with(0x110000, Default::default);

    result
}

fn vote<G: FnMut(&Details) -> Option<&String>>(
    sink: &mut Popularity,
    source: &Vec<Details>,
    mut getter: G,
) {
    for details in source {
        if let Some(string) = getter(details) {
            sink.vote(string);
        }
    }
}

fn write<W: FnOnce(BufWriter<File>) -> Result<(), Error>>(
    path: &str,
    writer: W,
) -> Result<(), Error> {
    println!("Writing {} ...", path);

    writer(BufWriter::new(File::create(path)?))
}

fn write_pool_indices<G: FnMut(&Details) -> Option<&String>>(
    source: &Vec<Details>,
    pool: &mut Pool,
    path: &str,
    mut getter: G,
) -> Result<(), Error> {
    write(path, |mut sink| {
        for details in source {
            if let Some(string) = getter(details) {
                let index = pool.r#use(&string);
                assert!(index < 0xFFFF);
                sink.write_u16::<BigEndian>(index)?;
            } else {
                sink.write_u16::<BigEndian>(0xFFFF)?;
            }
        }

        Ok(())
    })
}
<|endoftext|>


<commit_before>use glium::{Frame, VertexBuffer, Blend, Surface};
use glium::Display;
use glium::index::{IndexBuffer, PrimitiveType};
use glium::draw_parameters::DrawParameters;
use glium::draw_parameters::LinearBlendingFactor::*;
use glium::draw_parameters::BlendingFunction::*;
use glium::uniforms::{Uniforms, UniformsStorage, AsUniformValue, MagnifySamplerFilter, MinifySamplerFilter};

use nalgebra::Norm;
use std::convert::AsRef;

use {GameContext, Node, Vect};
use super::{RenderContext, Vertex, vert};
use math::*;
use quantum_circuit_wars::circuit::{GameView, Game, Port};

fn input_pos(gen: &Game<Node>, input: Port<u32>, _size: f32) -> Vect {
    let node = gen.get(input.node).unwrap();
    let pos = node.1.pos;
    let percent = (input.port + 1) as f32 / (node.0.max_in() + 1) as f32;
    Vect::new(pos[0] - 0.5 + percent, -(pos[1] - 0.5))
}

fn output_pos(gen: &Game<Node>, output: Port<u32>, size: f32) -> Vect {
    let node = gen.get(output.node).unwrap();
    let pos = node.1.pos;
    let percent = (output.port + 1) as f32 / (node.0.max_out() + 1) as f32;
    Vect::new(pos[0] - 0.5 + percent, -(pos[1] + 0.5 + size))
}

pub fn render(display: &Display, rctx: &mut RenderContext, world: GameView<Node>, ctx: &GameContext) {
    let mut target = display.draw();
    target.clear_color(0.0157, 0.0173, 0.0204, 1.);
    let draw_params = DrawParameters {
        blend: Blend {
            color: Addition {
                source: SourceAlpha,
                destination: OneMinusSourceAlpha,
            },
            alpha: Addition {
                source: SourceAlpha,
                destination: OneMinusSourceAlpha,
            },
            constant_value: (0f32, 0f32, 0f32, 1f32),
        },
        smooth: None,
        ..Default::default()
    };
    let dims = display.get_framebuffer_dimensions();
    for (_, data) in world.iter() {
        let pos = flip_y(data.pos);
        let corner_pos = pos - Vect::new(ctx.node_width, ctx.node_width) * 0.5;
        let matrix = rctx.cam * translation(corner_pos.x, corner_pos.y);
        let uniforms = uniform! {
            matrix: *matrix.as_ref(),
        };
        draw(&mut target, &rctx, "back", "plain", &uniforms, &draw_params);
        let matrix = rctx.cam * translation(corner_pos.x + 0.05, corner_pos.y + 0.05) * scale(0.9, 0.9);
        let program = rctx.programs.get("plain");
        let program = program.as_ref().expect("Node didn't have shader.");
        let uniforms = uniform! {
            matrix: *matrix.as_ref(),
        };
        let model = rctx.models.get("node").unwrap();
        target.draw(&model.vertices, &model.indices, &program, &uniforms, &draw_params).expect("Drawing node failed.");

        let mut draw = |things: &[_]| {
            for p in things {
                let p = pos + flip_y(*p) - Vect::new(ctx.port_size, ctx.port_size) * 0.5;
                let matrix = rctx.cam * translation(p.x, p.y) * scale(ctx.port_size, ctx.port_size);
                let uniforms = uniform! {
                    matrix: *matrix.as_ref(),
                };
                draw(&mut target, &rctx, "node", "plain", &uniforms, &draw_params);
            }
        };
        draw(&data.outputs.borrow());
        draw(&data.inputs.borrow());
    }
    let mut lines = Vec::with_capacity(world.connections());
    for (src, trg) in world.iter_connections() {
        let src = output_pos(&world, src, ctx.port_size);
        let trg = input_pos(&world, trg, ctx.port_size);
        let trg = Vect::new(trg[0], trg[1] + ctx.port_size);
        add_arrow(&mut lines, src, trg, 0.1, 0.1 * TAU);
    }
    let vertices = VertexBuffer::new(display, &lines).unwrap();
    let indices = (0..lines.len() as u32).collect::<Vec<_>>();
    let indices = IndexBuffer::new(display, PrimitiveType::LinesList, &indices).unwrap();
    let matrix = rctx.cam * translation(0., 0.);
    let uniforms = uniform! {
        matrix: *matrix.as_ref(),
    };
    let program = rctx.programs.get("plain").unwrap();
    target.draw(&vertices, &indices, program, &uniforms, &draw_params).unwrap();
    target.finish().unwrap();
}

pub fn render_splashscreen(display: &Display, render_context: &mut RenderContext) {
    use math::translation;
    let mut target = display.draw();
    let draw_params = DrawParameters {
        blend: Blend {
            color: Addition {
                source: SourceAlpha,
                destination: OneMinusSourceAlpha,
            },
            alpha: Addition {
                source: SourceAlpha,
                destination: OneMinusSourceAlpha,
            },
            constant_value: (0f32, 0f32, 0f32, 1f32),
        },
        smooth: None,
        ..Default::default()
    };
    let texture = render_context.textures.get("splash").unwrap();
    let model = render_context.models.get("node").unwrap();
    let program = render_context.programs.get("texture").unwrap();
    let splash_matrix = render_context.cam * translation(0., 0.) * scale(5., 5.);
    let uniforms = uniform! {
        matrix: *splash_matrix.as_ref(),
        tex: texture.sampled()
            .magnify_filter(MagnifySamplerFilter::Nearest)
            .minify_filter(MinifySamplerFilter::Nearest),

    };
    target.clear_color(0.,0.,0.,1.);
    target.draw(&model.vertices, &model.indices, program, &uniforms, &draw_params);
    target.finish().unwrap();
}

fn draw<A, B>(target: &mut Frame, rctx: &RenderContext, model: &str, program: &str, uniforms: &UniformsStorage<A, B>, draw_params: &DrawParameters)
    where A: AsUniformValue,
          B: Uniforms,
{
    let model = rctx.models.get(model).unwrap();
    let program = rctx.programs.get(program).unwrap();
    target.draw(&model.vertices, &model.indices, program, uniforms, draw_params).unwrap();
}

fn add_arrow(lines: &mut Vec<Vertex>, src: Vect, trg: Vect, len: f32, theta: f32) {
    lines.push(vert(src.x, src.y));
    lines.push(vert(trg.x, trg.y));
    let vec = (src - trg).normalize();
    let mut add_part = |theta: f32| {
        let (sin, cos) = theta.sin_cos();
        let arrow = Vect::new(
            vec.x * cos - vec.y * sin,
            vec.x * sin + vec.y * cos);
        lines.push(vert(trg.x, trg.y));
        let v = trg + (arrow * len);
        lines.push(vert(v.x, v.y));
    };
    add_part(theta);
    add_part(-theta);
}
<commit_msg>preparing to merge<commit_after>use glium::{Frame, VertexBuffer, Blend, Surface};
use glium::Display;
use glium::index::{IndexBuffer, PrimitiveType};
use glium::draw_parameters::DrawParameters;
use glium::draw_parameters::LinearBlendingFactor::*;
use glium::draw_parameters::BlendingFunction::*;
use glium::uniforms::{Uniforms, UniformsStorage, AsUniformValue, MagnifySamplerFilter, MinifySamplerFilter};

use nalgebra::Norm;
use std::convert::AsRef;

use {GameContext, Node, Vect};
use super::{RenderContext, Vertex, vert};
use math::*;
use quantum_circuit_wars::circuit::{GameView, Game, Port};

fn input_pos(gen: &Game<Node>, input: Port<u32>, _size: f32) -> Vect {
    let node = gen.get(input.node).unwrap();
    let pos = node.1.pos;
    let percent = (input.port + 1) as f32 / (node.0.max_in() + 1) as f32;
    Vect::new(pos[0] - 0.5 + percent, -(pos[1] - 0.5))
}

fn output_pos(gen: &Game<Node>, output: Port<u32>, size: f32) -> Vect {
    let node = gen.get(output.node).unwrap();
    let pos = node.1.pos;
    let percent = (output.port + 1) as f32 / (node.0.max_out() + 1) as f32;
    Vect::new(pos[0] - 0.5 + percent, -(pos[1] + 0.5 + size))
}

pub fn render(display: &Display, rctx: &mut RenderContext, world: GameView<Node>, ctx: &GameContext) {
    let mut target = display.draw();
    target.clear_color(0.0157, 0.0173, 0.0204, 1.);
    let draw_params = DrawParameters {
        blend: Blend {
            color: Addition {
                source: SourceAlpha,
                destination: OneMinusSourceAlpha,
            },
            alpha: Addition {
                source: SourceAlpha,
                destination: OneMinusSourceAlpha,
            },
            constant_value: (0f32, 0f32, 0f32, 1f32),
        },
        smooth: None,
        ..Default::default()
    };
    let dims = display.get_framebuffer_dimensions();
    for (_, data) in world.iter() {
        let pos = flip_y(data.pos);
        let corner_pos = pos - Vect::new(ctx.node_width, ctx.node_width) * 0.5;
        let matrix = rctx.cam * translation(corner_pos.x, corner_pos.y);
        let uniforms = uniform! {
            matrix: *matrix.as_ref(),
        };
        draw(&mut target, &rctx, "back", "plain", &uniforms, &draw_params);
        let matrix = rctx.cam * translation(corner_pos.x + 0.05, corner_pos.y + 0.05) * scale(0.9, 0.9);
        let program = rctx.programs.get("plain");
        let program = program.as_ref().expect("Node didn't have shader.");
        let uniforms = uniform! {
            matrix: *matrix.as_ref(),
        };
        let model = rctx.models.get("node").unwrap();
        target.draw(&model.vertices, &model.indices, &program, &uniforms, &draw_params).expect("Drawing node failed.");

        let mut draw = |things: &[_]| {
            for p in things {
                let p = pos + flip_y(*p) - Vect::new(ctx.port_size, ctx.port_size) * 0.5;
                let matrix = rctx.cam * translation(p.x, p.y) * scale(ctx.port_size, ctx.port_size);
                let uniforms = uniform! {
                    matrix: *matrix.as_ref(),
                };
                draw(&mut target, &rctx, "node", "plain", &uniforms, &draw_params);
            }
        };
        draw(&data.outputs.borrow());
        draw(&data.inputs.borrow());
    }
    let mut lines = Vec::with_capacity(world.connections());
    for (src, trg) in world.iter_connections() {
        let src = output_pos(&world, src, ctx.port_size);
        let trg = input_pos(&world, trg, ctx.port_size);
        let trg = Vect::new(trg[0], trg[1] + ctx.port_size);
        add_arrow(&mut lines, src, trg, 0.1, 0.1 * TAU);
    }
    let vertices = VertexBuffer::new(display, &lines).unwrap();
    let indices = (0..lines.len() as u32).collect::<Vec<_>>();
    let indices = IndexBuffer::new(display, PrimitiveType::LinesList, &indices).unwrap();
    let matrix = rctx.cam * translation(0., 0.);
    let uniforms = uniform! {
        matrix: *matrix.as_ref(),
    };
    let program = rctx.programs.get("plain").unwrap();
    target.draw(&vertices, &indices, program, &uniforms, &draw_params).unwrap();
    target.finish().unwrap();
}

pub fn render_splashscreen(display: &Display, render_context: &mut RenderContext) {
    use math::translation;
    let mut target = display.draw();
    let draw_params = DrawParameters {
        blend: Blend {
            color: Addition {
                source: SourceAlpha,
                destination: OneMinusSourceAlpha,
            },
            alpha: Addition {
                source: SourceAlpha,
                destination: OneMinusSourceAlpha,
            },
            constant_value: (0f32, 0f32, 0f32, 1f32),
        },
        smooth: None,
        ..Default::default()
    };
    let texture = render_context.textures.get("splash").unwrap();
    let model = render_context.models.get("node").unwrap();
    let program = render_context.programs.get("texture").unwrap();
    let splash_matrix = render_context.cam * translation(-(texture.width() as f32)/2., -(texture.height() as f32)/2.) * scale(texture.width() as f32, texture.height() as f32);
    let uniforms = uniform! {
        matrix: *splash_matrix.as_ref(),
        tex: texture.sampled()
            .magnify_filter(MagnifySamplerFilter::Nearest)
            .minify_filter(MinifySamplerFilter::Nearest),

    };
    target.clear_color(0.,0.,0.,1.);
    target.draw(&model.vertices, &model.indices, program, &uniforms, &draw_params);
    target.finish().unwrap();
}

fn draw<A, B>(target: &mut Frame, rctx: &RenderContext, model: &str, program: &str, uniforms: &UniformsStorage<A, B>, draw_params: &DrawParameters)
    where A: AsUniformValue,
          B: Uniforms,
{
    let model = rctx.models.get(model).unwrap();
    let program = rctx.programs.get(program).unwrap();
    target.draw(&model.vertices, &model.indices, program, uniforms, draw_params).unwrap();
}

fn add_arrow(lines: &mut Vec<Vertex>, src: Vect, trg: Vect, len: f32, theta: f32) {
    lines.push(vert(src.x, src.y));
    lines.push(vert(trg.x, trg.y));
    let vec = (src - trg).normalize();
    let mut add_part = |theta: f32| {
        let (sin, cos) = theta.sin_cos();
        let arrow = Vect::new(
            vec.x * cos - vec.y * sin,
            vec.x * sin + vec.y * cos);
        lines.push(vert(trg.x, trg.y));
        let v = trg + (arrow * len);
        lines.push(vert(v.x, v.y));
    };
    add_part(theta);
    add_part(-theta);
}
<|endoftext|>


<commit_before>///! fff-lang
///!
///! util/date_time for Readonly UTC date time

// TODO: UTC now + now, time zone, format method

use std::fmt;

/// Readonly UTC date time
#[derive(Clone, Eq, PartialEq)]
pub struct DateTime {
    m_year: u32,
    m_month: u32,
    m_day: u32,
    m_hour: u32,
    m_minute: u32,
    m_second: u32,
}
impl DateTime {

    /// Attention: no validate because I'm lazy
    pub fn with6(year: u32, month: u32, day: u32, hour: u32, minute: u32, second: u32) -> DateTime {
        DateTime{ m_year: year, m_month: month, m_day: day, m_hour: hour, m_minute: minute, m_second: second }
    }
    pub fn new() -> DateTime {
        DateTime::with6(1970, 1, 1, 0, 0, 0)
    }

    pub fn get_year(&self) -> u32 { self.m_year }
    pub fn get_month(&self) -> u32 { self.m_month }
    pub fn get_day(&self) -> u32 { self.m_day }
    pub fn get_hour(&self) -> u32 { self.m_hour }
    pub fn get_minute(&self) -> u32 { self.m_minute }
    pub fn get_second(&self) -> u32 { self.m_second }

    /// Currently only ISO8601 and UTC
    pub fn format(&self, _formatter : &str) -> String {
        format!("{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z", self.m_year, self.m_month, self.m_day, self.m_hour, self.m_minute, self.m_second)
    }
}
impl fmt::Debug for DateTime {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.format("iso8601"))
    }
}

#[cfg(windows)]
mod native {
    use std::mem;
    use super::DateTime;

    #[repr(C, packed)]
    struct SystemTime {
        year: u16,
        month: u16,
        _day_of_week: u16, // not used here
        day: u16,
        hour: u16,
        minute: u16,
        second: u16,
        _milli_second: u16, // not used here
    }
    #[repr(C, packed)]
    struct FileTime {
        low_part: u32,
        high_part: u32,
    }

    #[link(name = "kernel32")] extern "stdcall" {
        fn GetSystemTime(retval: *mut SystemTime);
        fn SystemTimeToFileTime(systime: *const SystemTime, filetime: *mut FileTime);
        fn FileTimeToSystemTime(filetime: *const FileTime, systime: *mut SystemTime);
    }

    const FILETIME_TIMESTAMP_OFFSET: u64 = 11644473600u64;

    pub fn now() -> DateTime {
        unsafe {
            let mut ret_val = mem::uninitialized::<SystemTime>();
            GetSystemTime(&mut ret_val as *mut SystemTime);
            DateTime::with6(
                ret_val.year as u32, ret_val.month as u32, ret_val.day as u32,
                ret_val.hour as u32, ret_val.minute as u32, ret_val.second as u32)
        }
    }
    pub fn with_timestamp(timestamp: u64) -> DateTime {
        unsafe {
            timestamp += FILETIME_TIMESTAMP_OFFSET;
            timestamp *= 10_000_000u64;
            let filetime = FileTime{ low_part: (timestamp & 0xFFFFFFFF) as u32, high_part: (timestamp >> 32) as u32 };
            let mut systime = mem::uninitialized::<SystemTime>();
            FileTimeToSystemTime(&filetime as *const FileTime, &mut systime as *mut SystemTime);
            DateTime::with6(
                systime.year as u32, systime.month as u32, systime.day as u32,
                systime.hour as u32, systime.minute as u32, systime.second as u32)
        }
    }
    pub fn as_timestamp(this: &DateTime) -> u64 {
        unsafe {
            let systime = SystemTime{
                year: this.m_year as u16, month: this.m_month as u16, day: this.m_day as u16,
                hour: this.m_hour as u16, minute: this.m_minute as u16, second: this.m_second as u16,
                _day_of_week: 0, _milli_second: 0
            };
            let mut filetime = mem::uninitialized::<FileTime>();
            SystemTimeToFileTime(&systime as *const SystemTime, &mut filetime as *mut FileTime);
            (filetime.low_part as u64 + ((filetime.high_part as u64) << 32)) / 10_000_000u64 - 11_644_473_600u64
        }
    }
}
#[cfg(unix)]
mod native {
    use super::DateTime;

    #[repr(C, packed)]
    struct tm {
        second: i32,        // 0-60
        minute: i32,        // 0-59
        hour: i32,          // 0-23
        day_of_month: i32,  // 1-31
        month: i32,         // 0-11
        year: i32,          // 1900+
        _day_of_week: i32,   // Sunday as 0
        _day_of_year: i32,   // 0-365
        _is_daylight_saving_time: i32,
        _gmt_offset: i64,    // second from GMT   // currently only UTC so not used
        _zone: *mut u8,                           // not used, too
    }
    impl tm {
        fn into_datetime(&self) -> DateTime { // because you may not own a struct tm
            DateTime::with6(
                self.year as u32 + 1900, self.month as u32 + 1, self.day_of_month as u32,
                self.hour as u32, self.minute as u32, self.second as u32,
            )
        }
    }

    #[link(name = "c")] extern "cdecl" {
        fn time(stamp: *mut u64) -> u64;
        fn gmtime(stamp: *const u64) -> *const tm;
        fn timegm(t: *mut tm) -> u64;
    }

    pub fn now() -> DateTime {
        unsafe { tm::into_datetime(&*gmtime(&time(0 as *mut u64) as *const u64)) }
    }
    pub fn with_timestamp(timestamp: u64) -> DateTime {
        unsafe { tm::into_datetime(&*gmtime(&timestamp as *const u64)) }
    }
    pub fn as_timestamp(this: &DateTime) -> u64 {
        let mut zone = ['G' as u32 as u8, 'M' as u32 as u8, 'T' as u32 as u8, 0u8]; // C style `"GMT"`, 0 for null terminate
        unsafe { timegm(&mut tm {
            second: this.m_second as i32,
            minute: this.m_minute as i32,
            hour: this.m_hour as i32,
            day_of_month: this.m_day as i32,
            month: this.m_month as i32 - 1,
            year: this.m_year as i32 - 1900,
            _day_of_week: 0,  // mktime says ignored
            _day_of_year: 0,  // mktime says ignored
            _is_daylight_saving_time: -1, // auto
            _gmt_offset: 0,   // only UTC is used here
            _zone: &mut zone[0] as *mut u8,
        } as *mut tm)
    } }
}

impl DateTime {

    pub fn now() -> DateTime { self::native::now() }
    pub fn with_timestamp(timestamp: u64) -> DateTime { self::native::with_timestamp(timestamp) }
    pub fn as_timestamp(&self) -> u64 { self::native::as_timestamp(self) }
}

#[cfg(test)] #[test]
fn date_time_timestamp() {

    assert_eq!(DateTime::with6(2017, 3, 13, 6, 40, 40).as_timestamp(), 1489387240);
    assert_eq!(DateTime::with_timestamp(0), DateTime::new());
    assert_eq!(DateTime::with_timestamp(1489387240), DateTime::with6(2017, 3, 13, 6, 40, 40));
    assert_eq!(DateTime::with_timestamp(12345678).as_timestamp(), 12345678);
    assert_eq!(DateTime::new().format("iso8601"), "1970-01-01T00:00:00Z");
}<commit_msg>[util] fix typo<commit_after>///! fff-lang
///!
///! util/date_time for Readonly UTC date time

use std::fmt;

/// Readonly UTC date time
#[derive(Clone, Eq, PartialEq)]
pub struct DateTime {
    m_year: u32,
    m_month: u32,
    m_day: u32,
    m_hour: u32,
    m_minute: u32,
    m_second: u32,
}
impl DateTime {

    /// Attention: no validate because I'm lazy
    pub fn with6(year: u32, month: u32, day: u32, hour: u32, minute: u32, second: u32) -> DateTime {
        DateTime{ m_year: year, m_month: month, m_day: day, m_hour: hour, m_minute: minute, m_second: second }
    }
    pub fn new() -> DateTime {
        DateTime::with6(1970, 1, 1, 0, 0, 0)
    }

    pub fn get_year(&self) -> u32 { self.m_year }
    pub fn get_month(&self) -> u32 { self.m_month }
    pub fn get_day(&self) -> u32 { self.m_day }
    pub fn get_hour(&self) -> u32 { self.m_hour }
    pub fn get_minute(&self) -> u32 { self.m_minute }
    pub fn get_second(&self) -> u32 { self.m_second }

    /// Currently only ISO8601 and UTC
    pub fn format(&self, _formatter : &str) -> String {
        format!("{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z", self.m_year, self.m_month, self.m_day, self.m_hour, self.m_minute, self.m_second)
    }
}
impl fmt::Debug for DateTime {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.format("iso8601"))
    }
}

#[cfg(windows)]
mod native {
    use std::mem;
    use super::DateTime;

    #[repr(C, packed)]
    struct SystemTime {
        year: u16,
        month: u16,
        _day_of_week: u16, // not used here
        day: u16,
        hour: u16,
        minute: u16,
        second: u16,
        _milli_second: u16, // not used here
    }
    #[repr(C, packed)]
    struct FileTime {
        low_part: u32,
        high_part: u32,
    }

    #[link(name = "kernel32")] extern "stdcall" {
        fn GetSystemTime(retval: *mut SystemTime);
        fn SystemTimeToFileTime(systime: *const SystemTime, filetime: *mut FileTime);
        fn FileTimeToSystemTime(filetime: *const FileTime, systime: *mut SystemTime);
    }

    const FILETIME_TIMESTAMP_OFFSET: u64 = 11644473600u64;

    pub fn now() -> DateTime {
        unsafe {
            let mut ret_val = mem::uninitialized::<SystemTime>();
            GetSystemTime(&mut ret_val as *mut SystemTime);
            DateTime::with6(
                ret_val.year as u32, ret_val.month as u32, ret_val.day as u32,
                ret_val.hour as u32, ret_val.minute as u32, ret_val.second as u32)
        }
    }
    pub fn with_timestamp(timestamp: u64) -> DateTime {
        unsafe {
            timestamp += FILETIME_TIMESTAMP_OFFSET;
            timestamp *= 10_000_000u64;
            let filetime = FileTime{ low_part: (timestamp & 0xFFFFFFFF) as u32, high_part: (timestamp >> 32) as u32 };
            let mut systime = mem::uninitialized::<SystemTime>();
            FileTimeToSystemTime(&filetime as *const FileTime, &mut systime as *mut SystemTime);
            DateTime::with6(
                systime.year as u32, systime.month as u32, systime.day as u32,
                systime.hour as u32, systime.minute as u32, systime.second as u32)
        }
    }
    pub fn as_timestamp(this: &DateTime) -> u64 {
        unsafe {
            let systime = SystemTime{
                year: this.m_year as u16, month: this.m_month as u16, day: this.m_day as u16,
                hour: this.m_hour as u16, minute: this.m_minute as u16, second: this.m_second as u16,
                _day_of_week: 0, _milli_second: 0
            };
            let mut filetime = mem::uninitialized::<FileTime>();
            SystemTimeToFileTime(&systime as *const SystemTime, &mut filetime as *mut FileTime);
            (filetime.low_part as u64 + ((filetime.high_part as u64) << 32)) / 10_000_000u64 - FILETIME_TIMESTAMP_OFFSET
        }
    }
}
#[cfg(unix)]
mod native {
    use super::DateTime;

    #[repr(C, packed)]
    struct tm {
        second: i32,         // 0-60
        minute: i32,         // 0-59
        hour: i32,           // 0-23
        day_of_month: i32,   // 1-31
        month: i32,          // 0-11
        year: i32,           // 1900+
        _day_of_week: i32,   // Sunday as 0
        _day_of_year: i32,   // 0-365
        _is_daylight_saving_time: i32,
        _gmt_offset: i64,    // second from GMT   // currently only UTC so not used
        _zone: *mut u8,                           // not used, too
    }
    impl tm {
        fn into_datetime(&self) -> DateTime { // because you may not own a struct tm
            DateTime::with6(
                self.year as u32 + 1900, self.month as u32 + 1, self.day_of_month as u32,
                self.hour as u32, self.minute as u32, self.second as u32,
            )
        }
    }

    #[link(name = "c")] extern "cdecl" {
        fn time(stamp: *mut u64) -> u64;
        fn gmtime(stamp: *const u64) -> *const tm;
        fn timegm(t: *mut tm) -> u64;
    }

    pub fn now() -> DateTime {
        unsafe { tm::into_datetime(&*gmtime(&time(0 as *mut u64) as *const u64)) }
    }
    pub fn with_timestamp(timestamp: u64) -> DateTime {
        unsafe { tm::into_datetime(&*gmtime(&timestamp as *const u64)) }
    }
    pub fn as_timestamp(this: &DateTime) -> u64 {
        let mut zone = ['G' as u32 as u8, 'M' as u32 as u8, 'T' as u32 as u8, 0u8]; // C style `"GMT"`, 0 for null terminate
        unsafe { timegm(&mut tm {
            second: this.m_second as i32,
            minute: this.m_minute as i32,
            hour: this.m_hour as i32,
            day_of_month: this.m_day as i32,
            month: this.m_month as i32 - 1,
            year: this.m_year as i32 - 1900,
            _day_of_week: 0,  // mktime says ignored
            _day_of_year: 0,  // mktime says ignored
            _is_daylight_saving_time: -1, // auto
            _gmt_offset: 0,   // only UTC is used here
            _zone: &mut zone[0] as *mut u8,
        } as *mut tm)
    } }
}

impl DateTime {

    pub fn now() -> DateTime { self::native::now() }
    pub fn with_timestamp(timestamp: u64) -> DateTime { self::native::with_timestamp(timestamp) }
    pub fn as_timestamp(&self) -> u64 { self::native::as_timestamp(self) }
}

#[cfg(test)] #[test]
fn date_time_timestamp() {

    assert_eq!(DateTime::with6(2017, 3, 13, 6, 40, 40).as_timestamp(), 1489387240);
    assert_eq!(DateTime::with_timestamp(0), DateTime::new());
    assert_eq!(DateTime::with_timestamp(1489387240), DateTime::with6(2017, 3, 13, 6, 40, 40));
    assert_eq!(DateTime::with_timestamp(12345678).as_timestamp(), 12345678);
    assert_eq!(DateTime::new().format("iso8601"), "1970-01-01T00:00:00Z");
}<|endoftext|>


<commit_before>extern crate iron;
extern crate bodyparser;
extern crate persistent;
extern crate "rustc-serialize" as rustc_serialize;

use persistent::Read;
use iron::status;
use iron::prelude::*;

#[derive(Debug, Clone, RustcDecodable)]
struct MyStructure {
    a: String,
    b: Option<String>,
}

fn log_body(req: &mut Request) -> IronResult<Response> {
    let body = req.get::<bodyparser::Raw>();
    match body {
        Ok(Some(body)) => println!("Read body:\n{}", body),
        Ok(None) => println!("No body"),
        Err(err) => println!("Error: {:?}", err)
    }

    let json_body = req.get::<bodyparser::Json>();
    match json_body {
        Ok(Some(json_body)) => println!("Parsed body:\n{:?}", json_body),
        Ok(None) => println!("No body"),
        Err(err) => println!("Error: {:?}", err)
    }

    let struct_body = req.get::<bodyparser::Struct<MyStructure>>();
    match struct_body {
        Ok(Some(struct_body)) => println!("Parsed body:\n{:?}", struct_body),
        Ok(None) => println!("No body"),
        Err(err) => println!("Error: {:?}", err)
    }

    Ok(Response::with(status::Ok))
}

const MAX_BODY_LENGTH: usize = 1024 * 1024 * 10;

// `curl -i "localhost:3000/" -H "application/json" -d '{"name":"jason","age":"2"}'`
// and check out the printed json in your terminal.
fn main() {
    let mut chain = Chain::new(log_body);
    chain.link_before(Read::<bodyparser::MaxBodyLength>::one(MAX_BODY_LENGTH));
    Iron::new(chain).http("localhost:3000").unwrap();
}

<commit_msg>proper crate extern for serialize<commit_after>extern crate iron;
extern crate bodyparser;
extern crate persistent;
extern crate rustc_serialize;

use persistent::Read;
use iron::status;
use iron::prelude::*;

#[derive(Debug, Clone, RustcDecodable)]
struct MyStructure {
    a: String,
    b: Option<String>,
}

fn log_body(req: &mut Request) -> IronResult<Response> {
    let body = req.get::<bodyparser::Raw>();
    match body {
        Ok(Some(body)) => println!("Read body:\n{}", body),
        Ok(None) => println!("No body"),
        Err(err) => println!("Error: {:?}", err)
    }

    let json_body = req.get::<bodyparser::Json>();
    match json_body {
        Ok(Some(json_body)) => println!("Parsed body:\n{:?}", json_body),
        Ok(None) => println!("No body"),
        Err(err) => println!("Error: {:?}", err)
    }

    let struct_body = req.get::<bodyparser::Struct<MyStructure>>();
    match struct_body {
        Ok(Some(struct_body)) => println!("Parsed body:\n{:?}", struct_body),
        Ok(None) => println!("No body"),
        Err(err) => println!("Error: {:?}", err)
    }

    Ok(Response::with(status::Ok))
}

const MAX_BODY_LENGTH: usize = 1024 * 1024 * 10;

// `curl -i "localhost:3000/" -H "application/json" -d '{"name":"jason","age":"2"}'`
// and check out the printed json in your terminal.
fn main() {
    let mut chain = Chain::new(log_body);
    chain.link_before(Read::<bodyparser::MaxBodyLength>::one(MAX_BODY_LENGTH));
    Iron::new(chain).http("localhost:3000").unwrap();
}

<|endoftext|>


<commit_before>#![feature(std_misc, thread_sleep)]

extern crate graphics;
extern crate glium;
extern crate glutin;
extern crate glium_graphics;
extern crate image;

use std::path::Path;
use std::thread::sleep;
use std::time::duration::Duration;
use glium::{ DisplayBuild, Surface, Texture2d };
use glium_graphics::{ Glium2d, GliumGraphics, DrawTexture, OpenGL };

fn main() {
    let window = glutin::WindowBuilder::new()
        .with_dimensions(300, 300)
        .with_title("glium_graphics: image_test".to_string())
        .build_glium().unwrap();

    let rust_logo = DrawTexture::new({
        let image = image::open(&Path::new("assets/rust.png")).unwrap();
        Texture2d::new(&window, image)
    });

    let mut g2d = Glium2d::new(OpenGL::_3_2, &window);
    let (w, h) = window.get_framebuffer_dimensions();
    let transform = graphics::abs_transform(w as f64, h as f64);

    loop {
        let mut target = window.draw();
        {
            use graphics::*;

            let mut g = GliumGraphics::new(&mut g2d, &mut target);

            clear(color::WHITE, &mut g);
            rectangle([1.0, 0.0, 0.0, 1.0],
                      [0.0, 0.0, 100.0, 100.0],
                      transform,
                      &mut g);
            rectangle([0.0, 1.0, 0.0, 0.3],
                      [50.0, 50.0, 100.0, 100.0],
                      transform,
                      &mut g);
            image(&rust_logo, transform.trans(100.0, 100.0), &mut g);
        }
        target.finish();

        window.poll_events().last();
        if window.is_closed() {
            break
        }
        sleep(Duration::milliseconds(15));
    }
}
<commit_msg>Remove usage of unstable features from example<commit_after>extern crate graphics;
extern crate glium;
extern crate glutin;
extern crate glium_graphics;
extern crate image;

use std::path::Path;
use std::thread::sleep_ms;
use glium::{ DisplayBuild, Surface, Texture2d };
use glium_graphics::{ Glium2d, GliumGraphics, DrawTexture, OpenGL };

fn main() {
    let window = glutin::WindowBuilder::new()
        .with_dimensions(300, 300)
        .with_title("glium_graphics: image_test".to_string())
        .build_glium().unwrap();

    let rust_logo = DrawTexture::new({
        let image = image::open(&Path::new("assets/rust.png")).unwrap();
        Texture2d::new(&window, image)
    });

    let mut g2d = Glium2d::new(OpenGL::_3_2, &window);
    let (w, h) = window.get_framebuffer_dimensions();
    let transform = graphics::abs_transform(w as f64, h as f64);

    loop {
        let mut target = window.draw();
        {
            use graphics::*;

            let mut g = GliumGraphics::new(&mut g2d, &mut target);

            clear(color::WHITE, &mut g);
            rectangle([1.0, 0.0, 0.0, 1.0],
                      [0.0, 0.0, 100.0, 100.0],
                      transform,
                      &mut g);
            rectangle([0.0, 1.0, 0.0, 0.3],
                      [50.0, 50.0, 100.0, 100.0],
                      transform,
                      &mut g);
            image(&rust_logo, transform.trans(100.0, 100.0), &mut g);
        }
        target.finish();

        window.poll_events().last();
        if window.is_closed() {
            break
        }
        sleep_ms(15);
    }
}
<|endoftext|>


<commit_before>extern crate specs;

use self::specs::{Fetch, Join, WriteStorage, ReadStorage, System};

use model::comp::{Pos, Vel, Bounciness, Bounds, Actor};
use model::game::{Id, Vector};
use collision::World;
use util::angle;
use std::sync::RwLock;

pub struct Bounce;
impl<'a> System<'a> for Bounce {
    #[allow(type_complexity)]
    type SystemData = (ReadStorage<'a, Pos>,
     WriteStorage<'a, Vel>,
     ReadStorage<'a, Actor>,
     ReadStorage<'a, Bounciness>,
     Fetch<'a, Bounds<Pos>>,
     Fetch<'a, RwLock<World<Id>>>);

    fn run(&mut self, (pos, mut vel, actor, bounciness, pos_bounds, world): Self::SystemData) {
        let world = world.read().unwrap();
        for (pos, mut vel, actor, _) in (&pos, &mut vel, &actor, &bounciness).join() {
            handle_movement(actor, pos, &mut vel, &pos_bounds, &world);
        }
    }
}

fn handle_movement(
    actor: &Actor,
    pos: &Pos,
    vel: &mut Vel,
    bounds: &Bounds<Pos>,
    world: &World<Id>,
) {
    world.query_intersects_id(&actor.id, |other| {
        let own: Vector = Vector {
            x: pos.x,
            y: pos.y,
        };
        let other = Vector {
            x: other.bounds.x,
            y: other.bounds.y,
        };
        let angle = angle(&own, &other);
        if angle > 270.0 || angle < 90.0 {
            vel.x = -vel.x.abs();
        } else {
            vel.x = vel.x.abs();
        }
    });
    let next_x = pos.x + vel.x;
    let next_y = pos.y + vel.y;
    if next_x > bounds.max.x || next_x < bounds.min.x {
        // Score and respawn
    }
    if next_y > bounds.max.y || next_y < bounds.min.y {
        vel.y = -vel.y;
    }
}
<commit_msg>Core: Run rustfmt<commit_after>extern crate specs;

use self::specs::{Fetch, Join, WriteStorage, ReadStorage, System};

use model::comp::{Pos, Vel, Bounciness, Bounds, Actor};
use model::game::{Id, Vector};
use collision::World;
use util::angle;
use std::sync::RwLock;

pub struct Bounce;
impl<'a> System<'a> for Bounce {
    #[allow(type_complexity)]
    type SystemData = (ReadStorage<'a, Pos>,
     WriteStorage<'a, Vel>,
     ReadStorage<'a, Actor>,
     ReadStorage<'a, Bounciness>,
     Fetch<'a, Bounds<Pos>>,
     Fetch<'a, RwLock<World<Id>>>);

    fn run(&mut self, (pos, mut vel, actor, bounciness, pos_bounds, world): Self::SystemData) {
        let world = world.read().unwrap();
        for (pos, mut vel, actor, _) in (&pos, &mut vel, &actor, &bounciness).join() {
            handle_movement(actor, pos, &mut vel, &pos_bounds, &world);
        }
    }
}

fn handle_movement(
    actor: &Actor,
    pos: &Pos,
    vel: &mut Vel,
    bounds: &Bounds<Pos>,
    world: &World<Id>,
) {
    world.query_intersects_id(&actor.id, |other| {
        let own: Vector = Vector { x: pos.x, y: pos.y };
        let other = Vector {
            x: other.bounds.x,
            y: other.bounds.y,
        };
        let angle = angle(&own, &other);
        if angle > 270.0 || angle < 90.0 {
            vel.x = -vel.x.abs();
        } else {
            vel.x = vel.x.abs();
        }
    });
    let next_x = pos.x + vel.x;
    let next_y = pos.y + vel.y;
    if next_x > bounds.max.x || next_x < bounds.min.x {
        // Score and respawn
    }
    if next_y > bounds.max.y || next_y < bounds.min.y {
        vel.y = -vel.y;
    }
}
<|endoftext|>


<commit_before><commit_msg>Cleanup projects test module<commit_after><|endoftext|>


<commit_before><commit_msg>Added method to classify chars in input string<commit_after><|endoftext|>


<commit_before>mod analysis_stats;

use std::{io::Read, error::Error};

use clap::{App, Arg, SubCommand};
use ra_ide_api::{file_structure, Analysis};
use ra_syntax::{SourceFile, TreeArc, AstNode};
use flexi_logger::Logger;
use ra_prof::profile;

type Result<T> = ::std::result::Result<T, Box<dyn Error + Send + Sync>>;

fn main() -> Result<()> {
    Logger::with_env().start()?;
    let matches = App::new("ra-cli")
        .setting(clap::AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump")))
        .subcommand(SubCommand::with_name("symbols"))
        .subcommand(
            SubCommand::with_name("highlight")
                .arg(Arg::with_name("rainbow").short("r").long("rainbow")),
        )
        .subcommand(
            SubCommand::with_name("analysis-stats")
                .arg(Arg::with_name("verbose").short("v").long("verbose"))
                .arg(Arg::with_name("only").short("o").takes_value(true))
                .arg(Arg::with_name("path")),
        )
        .get_matches();
    match matches.subcommand() {
        ("parse", Some(matches)) => {
            let _p = profile("parsing");
            let file = file()?;
            if !matches.is_present("no-dump") {
                println!("{}", file.syntax().debug_dump());
            }
            std::mem::forget(file);
        }
        ("symbols", _) => {
            let file = file()?;
            for s in file_structure(&file) {
                println!("{:?}", s);
            }
        }
        ("highlight", Some(matches)) => {
            let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
            let html = analysis.highlight_as_html(file_id, matches.is_present("rainbow")).unwrap();
            println!("{}", html);
        }
        ("analysis-stats", Some(matches)) => {
            let verbose = matches.is_present("verbose");
            let path = matches.value_of("path").unwrap_or("");
            let only = matches.value_of("only");
            analysis_stats::run(verbose, path, only)?;
        }
        _ => unreachable!(),
    }
    Ok(())
}

fn file() -> Result<TreeArc<SourceFile>> {
    let text = read_stdin()?;
    Ok(SourceFile::parse(&text).tree)
}

fn read_stdin() -> Result<String> {
    let mut buff = String::new();
    std::io::stdin().read_to_string(&mut buff)?;
    Ok(buff)
}
<commit_msg>Cleanup<commit_after>mod analysis_stats;

use std::{io::Read, error::Error};

use clap::{App, Arg, SubCommand};
use ra_ide_api::{file_structure, Analysis};
use ra_syntax::{SourceFile, TreeArc, AstNode};
use flexi_logger::Logger;
use ra_prof::profile;

type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;

fn main() -> Result<()> {
    Logger::with_env().start()?;
    let matches = App::new("ra-cli")
        .setting(clap::AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump")))
        .subcommand(SubCommand::with_name("symbols"))
        .subcommand(
            SubCommand::with_name("highlight")
                .arg(Arg::with_name("rainbow").short("r").long("rainbow")),
        )
        .subcommand(
            SubCommand::with_name("analysis-stats")
                .arg(Arg::with_name("verbose").short("v").long("verbose"))
                .arg(Arg::with_name("only").short("o").takes_value(true))
                .arg(Arg::with_name("path")),
        )
        .get_matches();
    match matches.subcommand() {
        ("parse", Some(matches)) => {
            let _p = profile("parsing");
            let file = file()?;
            if !matches.is_present("no-dump") {
                println!("{}", file.syntax().debug_dump());
            }
            std::mem::forget(file);
        }
        ("symbols", _) => {
            let file = file()?;
            for s in file_structure(&file) {
                println!("{:?}", s);
            }
        }
        ("highlight", Some(matches)) => {
            let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
            let html = analysis.highlight_as_html(file_id, matches.is_present("rainbow")).unwrap();
            println!("{}", html);
        }
        ("analysis-stats", Some(matches)) => {
            let verbose = matches.is_present("verbose");
            let path = matches.value_of("path").unwrap_or("");
            let only = matches.value_of("only");
            analysis_stats::run(verbose, path, only)?;
        }
        _ => unreachable!(),
    }
    Ok(())
}

fn file() -> Result<TreeArc<SourceFile>> {
    let text = read_stdin()?;
    Ok(SourceFile::parse(&text).tree)
}

fn read_stdin() -> Result<String> {
    let mut buff = String::new();
    std::io::stdin().read_to_string(&mut buff)?;
    Ok(buff)
}
<|endoftext|>