<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::path::{Path, PathBuf};

use bindgen::cargo::cargo_expand;
use bindgen::cargo::cargo_lock::{self, Lock};
use bindgen::cargo::cargo_metadata::{self, Metadata};
use bindgen::cargo::cargo_toml;

fn parse_dep_string(dep_string: &str) -> (&str, &str) {
    let split: Vec<&str> = dep_string.split_whitespace().collect();

    (split[0], split[1])
}

pub struct PackageRef {
    pub name: String,
    pub version: String,
}

pub struct Cargo {
    manifest_path: PathBuf,
    binding_crate_name: String,

    lock: Option<Lock>,
    metadata: Metadata,
}

impl Cargo {
    pub fn load(crate_dir: &Path,
                binding_crate_name: Option<&str>,
                use_cargo_lock: bool) -> Result<Cargo, String> {
        let toml_path = crate_dir.join("Cargo.toml");
        let lock_path = crate_dir.join("Cargo.lock");

        let lock = if use_cargo_lock {
            Some(cargo_lock::lock(&lock_path)
                            .map_err(|x| format!("couldn't load {:?}: {:?}", lock_path, x))?)
        } else {
            None
        };
        let metadata = cargo_metadata::metadata(&toml_path)
                                      .map_err(|_| format!("couldn't execute `cargo metadata` with manifest {:?}.", toml_path))?;

        // Use the specified binding crate name or infer it from the manifest
        let manifest = cargo_toml::manifest(&toml_path)
                                  .map_err(|_| format!("couldn't load {:?}.", toml_path))?;

        let binding_crate_name = binding_crate_name.map_or(manifest.package.name.clone(),
                                                           |x| x.to_owned());

        Ok(Cargo {
            manifest_path: toml_path,
            binding_crate_name: binding_crate_name,
            lock: lock,
            metadata: metadata,
        })
    }

    pub fn binding_crate_name(&self) -> &str {
        &self.binding_crate_name
    }
    pub fn binding_crate_ref(&self) -> PackageRef {
        self.find_pkg_ref(&self.binding_crate_name).unwrap()
    }

    fn find_pkg_ref(&self, package_name: &str) -> Option<PackageRef> {
        for package in &self.metadata.packages {
            if package.name == package_name {
                return Some(PackageRef {
                    name: package_name.to_owned(),
                    version: package.version.clone(),
                });
            }
        }
        None
    }

    pub fn find_dep_ref(&self, package: &PackageRef, dependency_name: &str) -> Option<PackageRef> {
        if self.lock.is_none() {
            return None;
        }

        // TODO
        if self.lock.as_ref().unwrap().root.name == package.name &&
           self.lock.as_ref().unwrap().root.version == package.version {
            if let Some(ref deps) = self.lock.as_ref().unwrap().root.dependencies {
                for dep in deps {
                    let (name, version) = parse_dep_string(dep);

                    if name == dependency_name {
                        return Some(PackageRef {
                            name: name.to_owned(),
                            version: version.to_owned(),
                        });
                    }
                }
            }
            return None;
        }

        for lock_package in &self.lock.as_ref().unwrap().package {
            if lock_package.name == package.name &&
               lock_package.version == package.version {
                if let Some(ref deps) = lock_package.dependencies {
                    for dep in deps {
                        let (name, version) = parse_dep_string(dep);

                        if name == dependency_name {
                            return Some(PackageRef {
                                name: name.to_owned(),
                                version: version.to_owned(),
                            });
                        }
                    }
                }
                return None;
            }
        }
        None
    }

    pub fn find_crate_dir(&self, package: &PackageRef) -> Option<PathBuf> {
        for meta_package in &self.metadata.packages {
            if meta_package.name == package.name &&
               meta_package.version == package.version {
                return Path::new(&meta_package.manifest_path).parent()
                                                             .map(|x| x.to_owned());
            }
        }
        None
    }

    pub fn find_crate_src(&self, package: &PackageRef) -> Option<PathBuf> {
        let kind_lib = String::from("lib");
        let kind_staticlib = String::from("staticlib");
        for meta_package in &self.metadata.packages {
            if meta_package.name == package.name &&
               meta_package.version == package.version {
                for target in &meta_package.targets {
                    if target.kind.contains(&kind_lib) ||
                       target.kind.contains(&kind_staticlib) {
                        return Some(PathBuf::from(&target.src_path));
                    }
                }
                break;
            }
        }
        None
    }

    pub fn expand_crate(&self, package: &PackageRef) -> Result<String, String> {
        cargo_expand::expand(&self.manifest_path, &package.name, &package.version)
    }
}
<commit_msg>Also generate headers for cdylib crates<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::path::{Path, PathBuf};

use bindgen::cargo::cargo_expand;
use bindgen::cargo::cargo_lock::{self, Lock};
use bindgen::cargo::cargo_metadata::{self, Metadata};
use bindgen::cargo::cargo_toml;

fn parse_dep_string(dep_string: &str) -> (&str, &str) {
    let split: Vec<&str> = dep_string.split_whitespace().collect();

    (split[0], split[1])
}

pub struct PackageRef {
    pub name: String,
    pub version: String,
}

pub struct Cargo {
    manifest_path: PathBuf,
    binding_crate_name: String,

    lock: Option<Lock>,
    metadata: Metadata,
}

impl Cargo {
    pub fn load(crate_dir: &Path,
                binding_crate_name: Option<&str>,
                use_cargo_lock: bool) -> Result<Cargo, String> {
        let toml_path = crate_dir.join("Cargo.toml");
        let lock_path = crate_dir.join("Cargo.lock");

        let lock = if use_cargo_lock {
            Some(cargo_lock::lock(&lock_path)
                            .map_err(|x| format!("couldn't load {:?}: {:?}", lock_path, x))?)
        } else {
            None
        };
        let metadata = cargo_metadata::metadata(&toml_path)
                                      .map_err(|_| format!("couldn't execute `cargo metadata` with manifest {:?}.", toml_path))?;

        // Use the specified binding crate name or infer it from the manifest
        let manifest = cargo_toml::manifest(&toml_path)
                                  .map_err(|_| format!("couldn't load {:?}.", toml_path))?;

        let binding_crate_name = binding_crate_name.map_or(manifest.package.name.clone(),
                                                           |x| x.to_owned());

        Ok(Cargo {
            manifest_path: toml_path,
            binding_crate_name: binding_crate_name,
            lock: lock,
            metadata: metadata,
        })
    }

    pub fn binding_crate_name(&self) -> &str {
        &self.binding_crate_name
    }
    pub fn binding_crate_ref(&self) -> PackageRef {
        self.find_pkg_ref(&self.binding_crate_name).unwrap()
    }

    fn find_pkg_ref(&self, package_name: &str) -> Option<PackageRef> {
        for package in &self.metadata.packages {
            if package.name == package_name {
                return Some(PackageRef {
                    name: package_name.to_owned(),
                    version: package.version.clone(),
                });
            }
        }
        None
    }

    pub fn find_dep_ref(&self, package: &PackageRef, dependency_name: &str) -> Option<PackageRef> {
        if self.lock.is_none() {
            return None;
        }

        // TODO
        if self.lock.as_ref().unwrap().root.name == package.name &&
           self.lock.as_ref().unwrap().root.version == package.version {
            if let Some(ref deps) = self.lock.as_ref().unwrap().root.dependencies {
                for dep in deps {
                    let (name, version) = parse_dep_string(dep);

                    if name == dependency_name {
                        return Some(PackageRef {
                            name: name.to_owned(),
                            version: version.to_owned(),
                        });
                    }
                }
            }
            return None;
        }

        for lock_package in &self.lock.as_ref().unwrap().package {
            if lock_package.name == package.name &&
               lock_package.version == package.version {
                if let Some(ref deps) = lock_package.dependencies {
                    for dep in deps {
                        let (name, version) = parse_dep_string(dep);

                        if name == dependency_name {
                            return Some(PackageRef {
                                name: name.to_owned(),
                                version: version.to_owned(),
                            });
                        }
                    }
                }
                return None;
            }
        }
        None
    }

    pub fn find_crate_dir(&self, package: &PackageRef) -> Option<PathBuf> {
        for meta_package in &self.metadata.packages {
            if meta_package.name == package.name &&
               meta_package.version == package.version {
                return Path::new(&meta_package.manifest_path).parent()
                                                             .map(|x| x.to_owned());
            }
        }
        None
    }

    pub fn find_crate_src(&self, package: &PackageRef) -> Option<PathBuf> {
        let kind_lib = String::from("lib");
        let kind_staticlib = String::from("staticlib");
        let kind_cdylib = String::from("cdylib");
        for meta_package in &self.metadata.packages {
            if meta_package.name == package.name &&
               meta_package.version == package.version {
                for target in &meta_package.targets {
                    if target.kind.contains(&kind_lib) ||
                       target.kind.contains(&kind_staticlib) ||
                       target.kind.contains(&kind_cdylib) {
                        return Some(PathBuf::from(&target.src_path));
                    }
                }
                break;
            }
        }
        None
    }

    pub fn expand_crate(&self, package: &PackageRef) -> Result<String, String> {
        cargo_expand::expand(&self.manifest_path, &package.name, &package.version)
    }
}
<|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 target::TargetOptions;
use std::default::Default;

pub fn opts() -> TargetOptions {
    TargetOptions {
        pre_link_args: vec![
            // We want to be able to strip as much executable code as possible
            // from the linker command line, and this flag indicates to the
            // linker that it can avoid linking in dynamic libraries that don't
            // actually satisfy any symbols up to that point (as with many other
            // resolutions the linker does). This option only applies to all
            // following libraries so we're sure to pass it as one of the first
            // arguments.
            "-Wl,--as-needed".to_string(),

            // Always enable NX protection when it is available
            "-Wl,-z,noexecstack".to_string(),

            // Do not link libc
            "-nostdlib".to_string(),

            // Static link
            "-static".to_string()
        ],
        executables: true,
        relocation_model: "static".to_string(),
        disable_redzone: true,
        eliminate_frame_pointer: false,
        linker_is_gnu: true,
        no_default_libraries: true,
        has_elf_tls: true,
        .. Default::default()
    }
}
<commit_msg>Fix issue with setting cfg(unix)<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 target::TargetOptions;
use std::default::Default;

pub fn opts() -> TargetOptions {
    TargetOptions {
        pre_link_args: vec![
            // We want to be able to strip as much executable code as possible
            // from the linker command line, and this flag indicates to the
            // linker that it can avoid linking in dynamic libraries that don't
            // actually satisfy any symbols up to that point (as with many other
            // resolutions the linker does). This option only applies to all
            // following libraries so we're sure to pass it as one of the first
            // arguments.
            "-Wl,--as-needed".to_string(),

            // Always enable NX protection when it is available
            "-Wl,-z,noexecstack".to_string(),

            // Do not link libc
            "-nostdlib".to_string(),

            // Static link
            "-static".to_string()
        ],
        executables: true,
        relocation_model: "static".to_string(),
        disable_redzone: true,
        eliminate_frame_pointer: false,
        target_family: Some("redox".to_string()),
        linker_is_gnu: true,
        no_default_libraries: true,
        has_elf_tls: true,
        .. Default::default()
    }
}
<|endoftext|>


<commit_before>use std::hash;
use std::fmt::{mod, Show, Formatter};

use semver::Version;
use serialize::{Encoder,Encodable};

use core::source::SourceId;
use core::{
    Dependency,
    PackageId,
    Summary
};
use core::package_id::Metadata;
use core::dependency::SerializedDependency;
use util::{CargoResult, human};

/// Contains all the informations about a package, as loaded from a Cargo.toml.
#[deriving(PartialEq,Clone)]
pub struct Manifest {
    summary: Summary,
    authors: Vec<String>,
    targets: Vec<Target>,
    target_dir: Path,
    doc_dir: Path,
    sources: Vec<SourceId>,
    build: Vec<String>,
    warnings: Vec<String>,
    exclude: Vec<String>,
}

impl Show for Manifest {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Manifest({}, authors={}, targets={}, target_dir={}, \
                   build={})",
               self.summary, self.authors, self.targets,
               self.target_dir.display(), self.build)
    }
}

#[deriving(PartialEq,Clone,Encodable)]
pub struct SerializedManifest {
    name: String,
    version: String,
    dependencies: Vec<SerializedDependency>,
    authors: Vec<String>,
    targets: Vec<Target>,
    target_dir: String,
    doc_dir: String,
    build: Option<Vec<String>>,
}

impl<E, S: Encoder<E>> Encodable<S, E> for Manifest {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        SerializedManifest {
            name: self.summary.get_name().to_string(),
            version: self.summary.get_version().to_string(),
            dependencies: self.summary.get_dependencies().iter().map(|d| {
                SerializedDependency::from_dependency(d)
            }).collect(),
            authors: self.authors.clone(),
            targets: self.targets.clone(),
            target_dir: self.target_dir.display().to_string(),
            doc_dir: self.doc_dir.display().to_string(),
            build: if self.build.len() == 0 { None } else { Some(self.build.clone()) },
        }.encode(s)
    }
}

#[deriving(Show, Clone, PartialEq, Hash, Encodable)]
pub enum LibKind {
    Lib,
    Rlib,
    Dylib,
    StaticLib
}

impl LibKind {
    pub fn from_str(string: &str) -> CargoResult<LibKind> {
        match string {
            "lib" => Ok(Lib),
            "rlib" => Ok(Rlib),
            "dylib" => Ok(Dylib),
            "staticlib" => Ok(StaticLib),
            _ => Err(human(format!("{} was not one of lib|rlib|dylib|staticlib",
                                   string)))
        }
    }

    pub fn from_strs<S: Str>(strings: Vec<S>) -> CargoResult<Vec<LibKind>> {
        strings.iter().map(|s| LibKind::from_str(s.as_slice())).collect()
    }

    /// Returns the argument suitable for `--crate-type` to pass to rustc.
    pub fn crate_type(&self) -> &'static str {
        match *self {
            Lib => "lib",
            Rlib => "rlib",
            Dylib => "dylib",
            StaticLib => "staticlib"
        }
    }
}

#[deriving(Show, Clone, Hash, PartialEq, Encodable)]
pub enum TargetKind {
    LibTarget(Vec<LibKind>),
    BinTarget
}

#[deriving(Encodable, Decodable, Clone, PartialEq, Show)]
pub struct Profile {
    env: String, // compile, test, dev, bench, etc.
    opt_level: uint,
    codegen_units: Option<uint>,    // None = use rustc default
    debug: bool,
    rpath: bool,
    test: bool,
    doctest: bool,
    doc: bool,
    dest: Option<String>,
    plugin: bool,
    harness: bool, // whether to use the test harness (--test)
}

impl Profile {
    fn default() -> Profile {
        Profile {
            env: String::new(),
            opt_level: 0,
            codegen_units: None,
            debug: false,
            rpath: false,
            test: false,
            doc: false,
            dest: None,
            plugin: false,
            doctest: false,
            harness: true,
        }
    }

    pub fn default_dev() -> Profile {
        Profile {
            env: "compile".to_string(), // run in the default environment only
            opt_level: 0,
            debug: true,
            .. Profile::default()
        }
    }

    pub fn default_test() -> Profile {
        Profile {
            env: "test".to_string(),
            debug: true,
            test: true,
            dest: None,
            .. Profile::default()
        }
    }

    pub fn default_bench() -> Profile {
        Profile {
            env: "bench".to_string(),
            opt_level: 3,
            test: true,
            dest: Some("release".to_string()),
            .. Profile::default()
        }
    }

    pub fn default_release() -> Profile {
        Profile {
            env: "release".to_string(),
            opt_level: 3,
            dest: Some("release".to_string()),
            .. Profile::default()
        }
    }

    pub fn default_doc() -> Profile {
        Profile {
            env: "doc".to_string(),
            dest: None,
            doc: true,
            .. Profile::default()
        }
    }

    pub fn is_compile(&self) -> bool {
        self.env.as_slice() == "compile"
    }

    pub fn is_doc(&self) -> bool {
        self.doc
    }

    pub fn is_test(&self) -> bool {
        self.test
    }

    pub fn uses_test_harness(&self) -> bool {
        self.harness
    }

    pub fn is_doctest(&self) -> bool {
        self.doctest
    }

    pub fn is_plugin(&self) -> bool {
        self.plugin
    }

    pub fn get_opt_level(&self) -> uint {
        self.opt_level
    }

    pub fn get_codegen_units(&self) -> Option<uint> {
        self.codegen_units
    }

    pub fn get_debug(&self) -> bool {
        self.debug
    }

    pub fn get_rpath(&self) -> bool {
        self.rpath
    }

    pub fn get_env(&self) -> &str {
        self.env.as_slice()
    }

    pub fn get_dest(&self) -> Option<&str> {
        self.dest.as_ref().map(|d| d.as_slice())
    }

    pub fn opt_level(mut self, level: uint) -> Profile {
        self.opt_level = level;
        self
    }

    pub fn codegen_units(mut self, units: Option<uint>) -> Profile {
        self.codegen_units = units;
        self
    }

    pub fn debug(mut self, debug: bool) -> Profile {
        self.debug = debug;
        self
    }

    pub fn rpath(mut self, rpath: bool) -> Profile {
        self.rpath = rpath;
        self
    }

    pub fn test(mut self, test: bool) -> Profile {
        self.test = test;
        self
    }

    pub fn doctest(mut self, doctest: bool) -> Profile {
        self.doctest = doctest;
        self
    }

    pub fn doc(mut self, doc: bool) -> Profile {
        self.doc = doc;
        self
    }

    pub fn plugin(mut self, plugin: bool) -> Profile {
        self.plugin = plugin;
        self
    }

    pub fn harness(mut self, harness: bool) -> Profile {
        self.harness = harness;
        self
    }
}

impl<H: hash::Writer> hash::Hash<H> for Profile {
    fn hash(&self, into: &mut H) {
        // Be sure to match all fields explicitly, but ignore those not relevant
        // to the actual hash of a profile.
        let Profile {
            opt_level,
            codegen_units,
            debug,
            rpath,
            plugin,
            dest: ref dest,
            harness: harness,

            // test flags are separated by file, not by profile hash, and
            // env/doc also don't matter for the actual contents of the output
            // file, just where the output file is located.
            doc: _,
            env: _,
            test: _,
            doctest: _,
        } = *self;
        (opt_level, codegen_units, debug, rpath, plugin, dest, harness).hash(into)
    }
}

/// Informations about a binary, a library, an example, etc. that is part of the package.
#[deriving(Clone, Hash, PartialEq)]
pub struct Target {
    kind: TargetKind,
    name: String,
    src_path: Path,
    profile: Profile,
    metadata: Option<Metadata>,
}

#[deriving(Encodable)]
pub struct SerializedTarget {
    kind: Vec<&'static str>,
    name: String,
    src_path: String,
    profile: Profile,
    metadata: Option<Metadata>
}

impl<E, S: Encoder<E>> Encodable<S, E> for Target {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        let kind = match self.kind {
            LibTarget(ref kinds) => kinds.iter().map(|k| k.crate_type()).collect(),
            BinTarget => vec!("bin")
        };

        SerializedTarget {
            kind: kind,
            name: self.name.clone(),
            src_path: self.src_path.display().to_string(),
            profile: self.profile.clone(),
            metadata: self.metadata.clone()
        }.encode(s)
    }
}

impl Show for Target {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{}(name={}, path={}, profile={})", self.kind, self.name,
               self.src_path.display(), self.profile)
    }
}

impl Manifest {
    pub fn new(summary: Summary, targets: Vec<Target>,
               target_dir: Path, doc_dir: Path, sources: Vec<SourceId>,
               build: Vec<String>, exclude: Vec<String>) -> Manifest {
        Manifest {
            summary: summary,
            authors: Vec::new(),
            targets: targets,
            target_dir: target_dir,
            doc_dir: doc_dir,
            sources: sources,
            build: build,
            warnings: Vec::new(),
            exclude: exclude,
        }
    }

    pub fn get_summary(&self) -> &Summary {
        &self.summary
    }

    pub fn get_package_id(&self) -> &PackageId {
        self.get_summary().get_package_id()
    }

    pub fn get_name(&self) -> &str {
        self.get_package_id().get_name()
    }

    pub fn get_version(&self) -> &Version {
        self.get_summary().get_package_id().get_version()
    }

    pub fn get_authors(&self) -> &[String] {
        self.authors.as_slice()
    }

    pub fn get_dependencies(&self) -> &[Dependency] {
        self.get_summary().get_dependencies()
    }

    pub fn get_targets(&self) -> &[Target] {
        self.targets.as_slice()
    }

    pub fn get_target_dir(&self) -> &Path {
        &self.target_dir
    }

    pub fn get_doc_dir(&self) -> &Path {
        &self.doc_dir
    }

    /// Returns a list of all the potential `SourceId`s of the dependencies.
    pub fn get_source_ids(&self) -> &[SourceId] {
        self.sources.as_slice()
    }

    pub fn get_build(&self) -> &[String] {
        self.build.as_slice()
    }

    pub fn add_warning(&mut self, s: String) {
        self.warnings.push(s)
    }

    pub fn get_warnings(&self) -> &[String] {
        self.warnings.as_slice()
    }

    pub fn get_exclude(&self) -> &[String] {
        self.exclude.as_slice()
    }
}

impl Target {
    pub fn file_stem(&self) -> String {
        match self.metadata {
            Some(ref metadata) => format!("{}{}", self.name, metadata.extra_filename),
            None => self.name.clone()
        }
    }

    pub fn lib_target(name: &str, crate_targets: Vec<LibKind>,
                      src_path: &Path, profile: &Profile,
                      metadata: Metadata) -> Target {
        Target {
            kind: LibTarget(crate_targets),
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: Some(metadata)
        }
    }

    pub fn bin_target(name: &str, src_path: &Path, profile: &Profile,
                      metadata: Option<Metadata>) -> Target {
        Target {
            kind: BinTarget,
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: metadata,
        }
    }

    pub fn example_target(name: &str, src_path: &Path, profile: &Profile) -> Target {
        Target {
            kind: BinTarget,
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: None,
        }
    }

    pub fn test_target(name: &str, src_path: &Path,
                       profile: &Profile, metadata: Metadata) -> Target {
        Target {
            kind: BinTarget,
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: Some(metadata),
        }
    }

    pub fn bench_target(name: &str, src_path: &Path,
                        profile: &Profile, metadata: Metadata) -> Target {
        Target {
            kind: BinTarget,
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: Some(metadata),
        }
    }

    pub fn get_name(&self) -> &str {
        self.name.as_slice()
    }

    pub fn get_src_path(&self) -> &Path {
        &self.src_path
    }

    pub fn is_lib(&self) -> bool {
        match self.kind {
            LibTarget(_) => true,
            _ => false
        }
    }

    pub fn is_dylib(&self) -> bool {
        match self.kind {
            LibTarget(ref kinds) => kinds.iter().any(|&k| k == Dylib),
            _ => false
        }
    }

    pub fn is_rlib(&self) -> bool {
        match self.kind {
            LibTarget(ref kinds) =>
                kinds.iter().any(|&k| k == Rlib || k == Lib),
            _ => false
        }
    }

    pub fn is_staticlib(&self) -> bool {
        match self.kind {
            LibTarget(ref kinds) => kinds.iter().any(|&k| k == StaticLib),
            _ => false
        }
    }

    /// Returns true for binary, bench, tests and examples.
    pub fn is_bin(&self) -> bool {
        match self.kind {
            BinTarget => true,
            _ => false
        }
    }

    pub fn get_profile(&self) -> &Profile {
        &self.profile
    }

    pub fn get_metadata(&self) -> Option<&Metadata> {
        self.metadata.as_ref()
    }

    /// Returns the arguments suitable for `--crate-type` to pass to rustc.
    pub fn rustc_crate_types(&self) -> Vec<&'static str> {
        match self.kind {
            LibTarget(ref kinds) => {
                kinds.iter().map(|kind| kind.crate_type()).collect()
            },
            BinTarget => vec!("bin")
        }
    }
}
<commit_msg>fix two warnings<commit_after>use std::hash;
use std::fmt::{mod, Show, Formatter};

use semver::Version;
use serialize::{Encoder,Encodable};

use core::source::SourceId;
use core::{
    Dependency,
    PackageId,
    Summary
};
use core::package_id::Metadata;
use core::dependency::SerializedDependency;
use util::{CargoResult, human};

/// Contains all the informations about a package, as loaded from a Cargo.toml.
#[deriving(PartialEq,Clone)]
pub struct Manifest {
    summary: Summary,
    authors: Vec<String>,
    targets: Vec<Target>,
    target_dir: Path,
    doc_dir: Path,
    sources: Vec<SourceId>,
    build: Vec<String>,
    warnings: Vec<String>,
    exclude: Vec<String>,
}

impl Show for Manifest {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Manifest({}, authors={}, targets={}, target_dir={}, \
                   build={})",
               self.summary, self.authors, self.targets,
               self.target_dir.display(), self.build)
    }
}

#[deriving(PartialEq,Clone,Encodable)]
pub struct SerializedManifest {
    name: String,
    version: String,
    dependencies: Vec<SerializedDependency>,
    authors: Vec<String>,
    targets: Vec<Target>,
    target_dir: String,
    doc_dir: String,
    build: Option<Vec<String>>,
}

impl<E, S: Encoder<E>> Encodable<S, E> for Manifest {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        SerializedManifest {
            name: self.summary.get_name().to_string(),
            version: self.summary.get_version().to_string(),
            dependencies: self.summary.get_dependencies().iter().map(|d| {
                SerializedDependency::from_dependency(d)
            }).collect(),
            authors: self.authors.clone(),
            targets: self.targets.clone(),
            target_dir: self.target_dir.display().to_string(),
            doc_dir: self.doc_dir.display().to_string(),
            build: if self.build.len() == 0 { None } else { Some(self.build.clone()) },
        }.encode(s)
    }
}

#[deriving(Show, Clone, PartialEq, Hash, Encodable)]
pub enum LibKind {
    Lib,
    Rlib,
    Dylib,
    StaticLib
}

impl LibKind {
    pub fn from_str(string: &str) -> CargoResult<LibKind> {
        match string {
            "lib" => Ok(Lib),
            "rlib" => Ok(Rlib),
            "dylib" => Ok(Dylib),
            "staticlib" => Ok(StaticLib),
            _ => Err(human(format!("{} was not one of lib|rlib|dylib|staticlib",
                                   string)))
        }
    }

    pub fn from_strs<S: Str>(strings: Vec<S>) -> CargoResult<Vec<LibKind>> {
        strings.iter().map(|s| LibKind::from_str(s.as_slice())).collect()
    }

    /// Returns the argument suitable for `--crate-type` to pass to rustc.
    pub fn crate_type(&self) -> &'static str {
        match *self {
            Lib => "lib",
            Rlib => "rlib",
            Dylib => "dylib",
            StaticLib => "staticlib"
        }
    }
}

#[deriving(Show, Clone, Hash, PartialEq, Encodable)]
pub enum TargetKind {
    LibTarget(Vec<LibKind>),
    BinTarget
}

#[deriving(Encodable, Decodable, Clone, PartialEq, Show)]
pub struct Profile {
    env: String, // compile, test, dev, bench, etc.
    opt_level: uint,
    codegen_units: Option<uint>,    // None = use rustc default
    debug: bool,
    rpath: bool,
    test: bool,
    doctest: bool,
    doc: bool,
    dest: Option<String>,
    plugin: bool,
    harness: bool, // whether to use the test harness (--test)
}

impl Profile {
    fn default() -> Profile {
        Profile {
            env: String::new(),
            opt_level: 0,
            codegen_units: None,
            debug: false,
            rpath: false,
            test: false,
            doc: false,
            dest: None,
            plugin: false,
            doctest: false,
            harness: true,
        }
    }

    pub fn default_dev() -> Profile {
        Profile {
            env: "compile".to_string(), // run in the default environment only
            opt_level: 0,
            debug: true,
            .. Profile::default()
        }
    }

    pub fn default_test() -> Profile {
        Profile {
            env: "test".to_string(),
            debug: true,
            test: true,
            dest: None,
            .. Profile::default()
        }
    }

    pub fn default_bench() -> Profile {
        Profile {
            env: "bench".to_string(),
            opt_level: 3,
            test: true,
            dest: Some("release".to_string()),
            .. Profile::default()
        }
    }

    pub fn default_release() -> Profile {
        Profile {
            env: "release".to_string(),
            opt_level: 3,
            dest: Some("release".to_string()),
            .. Profile::default()
        }
    }

    pub fn default_doc() -> Profile {
        Profile {
            env: "doc".to_string(),
            dest: None,
            doc: true,
            .. Profile::default()
        }
    }

    pub fn is_compile(&self) -> bool {
        self.env.as_slice() == "compile"
    }

    pub fn is_doc(&self) -> bool {
        self.doc
    }

    pub fn is_test(&self) -> bool {
        self.test
    }

    pub fn uses_test_harness(&self) -> bool {
        self.harness
    }

    pub fn is_doctest(&self) -> bool {
        self.doctest
    }

    pub fn is_plugin(&self) -> bool {
        self.plugin
    }

    pub fn get_opt_level(&self) -> uint {
        self.opt_level
    }

    pub fn get_codegen_units(&self) -> Option<uint> {
        self.codegen_units
    }

    pub fn get_debug(&self) -> bool {
        self.debug
    }

    pub fn get_rpath(&self) -> bool {
        self.rpath
    }

    pub fn get_env(&self) -> &str {
        self.env.as_slice()
    }

    pub fn get_dest(&self) -> Option<&str> {
        self.dest.as_ref().map(|d| d.as_slice())
    }

    pub fn opt_level(mut self, level: uint) -> Profile {
        self.opt_level = level;
        self
    }

    pub fn codegen_units(mut self, units: Option<uint>) -> Profile {
        self.codegen_units = units;
        self
    }

    pub fn debug(mut self, debug: bool) -> Profile {
        self.debug = debug;
        self
    }

    pub fn rpath(mut self, rpath: bool) -> Profile {
        self.rpath = rpath;
        self
    }

    pub fn test(mut self, test: bool) -> Profile {
        self.test = test;
        self
    }

    pub fn doctest(mut self, doctest: bool) -> Profile {
        self.doctest = doctest;
        self
    }

    pub fn doc(mut self, doc: bool) -> Profile {
        self.doc = doc;
        self
    }

    pub fn plugin(mut self, plugin: bool) -> Profile {
        self.plugin = plugin;
        self
    }

    pub fn harness(mut self, harness: bool) -> Profile {
        self.harness = harness;
        self
    }
}

impl<H: hash::Writer> hash::Hash<H> for Profile {
    fn hash(&self, into: &mut H) {
        // Be sure to match all fields explicitly, but ignore those not relevant
        // to the actual hash of a profile.
        let Profile {
            opt_level,
            codegen_units,
            debug,
            rpath,
            plugin,
            ref dest,
            harness,

            // test flags are separated by file, not by profile hash, and
            // env/doc also don't matter for the actual contents of the output
            // file, just where the output file is located.
            doc: _,
            env: _,
            test: _,
            doctest: _,
        } = *self;
        (opt_level, codegen_units, debug, rpath, plugin, dest, harness).hash(into)
    }
}

/// Informations about a binary, a library, an example, etc. that is part of the package.
#[deriving(Clone, Hash, PartialEq)]
pub struct Target {
    kind: TargetKind,
    name: String,
    src_path: Path,
    profile: Profile,
    metadata: Option<Metadata>,
}

#[deriving(Encodable)]
pub struct SerializedTarget {
    kind: Vec<&'static str>,
    name: String,
    src_path: String,
    profile: Profile,
    metadata: Option<Metadata>
}

impl<E, S: Encoder<E>> Encodable<S, E> for Target {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        let kind = match self.kind {
            LibTarget(ref kinds) => kinds.iter().map(|k| k.crate_type()).collect(),
            BinTarget => vec!("bin")
        };

        SerializedTarget {
            kind: kind,
            name: self.name.clone(),
            src_path: self.src_path.display().to_string(),
            profile: self.profile.clone(),
            metadata: self.metadata.clone()
        }.encode(s)
    }
}

impl Show for Target {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{}(name={}, path={}, profile={})", self.kind, self.name,
               self.src_path.display(), self.profile)
    }
}

impl Manifest {
    pub fn new(summary: Summary, targets: Vec<Target>,
               target_dir: Path, doc_dir: Path, sources: Vec<SourceId>,
               build: Vec<String>, exclude: Vec<String>) -> Manifest {
        Manifest {
            summary: summary,
            authors: Vec::new(),
            targets: targets,
            target_dir: target_dir,
            doc_dir: doc_dir,
            sources: sources,
            build: build,
            warnings: Vec::new(),
            exclude: exclude,
        }
    }

    pub fn get_summary(&self) -> &Summary {
        &self.summary
    }

    pub fn get_package_id(&self) -> &PackageId {
        self.get_summary().get_package_id()
    }

    pub fn get_name(&self) -> &str {
        self.get_package_id().get_name()
    }

    pub fn get_version(&self) -> &Version {
        self.get_summary().get_package_id().get_version()
    }

    pub fn get_authors(&self) -> &[String] {
        self.authors.as_slice()
    }

    pub fn get_dependencies(&self) -> &[Dependency] {
        self.get_summary().get_dependencies()
    }

    pub fn get_targets(&self) -> &[Target] {
        self.targets.as_slice()
    }

    pub fn get_target_dir(&self) -> &Path {
        &self.target_dir
    }

    pub fn get_doc_dir(&self) -> &Path {
        &self.doc_dir
    }

    /// Returns a list of all the potential `SourceId`s of the dependencies.
    pub fn get_source_ids(&self) -> &[SourceId] {
        self.sources.as_slice()
    }

    pub fn get_build(&self) -> &[String] {
        self.build.as_slice()
    }

    pub fn add_warning(&mut self, s: String) {
        self.warnings.push(s)
    }

    pub fn get_warnings(&self) -> &[String] {
        self.warnings.as_slice()
    }

    pub fn get_exclude(&self) -> &[String] {
        self.exclude.as_slice()
    }
}

impl Target {
    pub fn file_stem(&self) -> String {
        match self.metadata {
            Some(ref metadata) => format!("{}{}", self.name, metadata.extra_filename),
            None => self.name.clone()
        }
    }

    pub fn lib_target(name: &str, crate_targets: Vec<LibKind>,
                      src_path: &Path, profile: &Profile,
                      metadata: Metadata) -> Target {
        Target {
            kind: LibTarget(crate_targets),
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: Some(metadata)
        }
    }

    pub fn bin_target(name: &str, src_path: &Path, profile: &Profile,
                      metadata: Option<Metadata>) -> Target {
        Target {
            kind: BinTarget,
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: metadata,
        }
    }

    pub fn example_target(name: &str, src_path: &Path, profile: &Profile) -> Target {
        Target {
            kind: BinTarget,
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: None,
        }
    }

    pub fn test_target(name: &str, src_path: &Path,
                       profile: &Profile, metadata: Metadata) -> Target {
        Target {
            kind: BinTarget,
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: Some(metadata),
        }
    }

    pub fn bench_target(name: &str, src_path: &Path,
                        profile: &Profile, metadata: Metadata) -> Target {
        Target {
            kind: BinTarget,
            name: name.to_string(),
            src_path: src_path.clone(),
            profile: profile.clone(),
            metadata: Some(metadata),
        }
    }

    pub fn get_name(&self) -> &str {
        self.name.as_slice()
    }

    pub fn get_src_path(&self) -> &Path {
        &self.src_path
    }

    pub fn is_lib(&self) -> bool {
        match self.kind {
            LibTarget(_) => true,
            _ => false
        }
    }

    pub fn is_dylib(&self) -> bool {
        match self.kind {
            LibTarget(ref kinds) => kinds.iter().any(|&k| k == Dylib),
            _ => false
        }
    }

    pub fn is_rlib(&self) -> bool {
        match self.kind {
            LibTarget(ref kinds) =>
                kinds.iter().any(|&k| k == Rlib || k == Lib),
            _ => false
        }
    }

    pub fn is_staticlib(&self) -> bool {
        match self.kind {
            LibTarget(ref kinds) => kinds.iter().any(|&k| k == StaticLib),
            _ => false
        }
    }

    /// Returns true for binary, bench, tests and examples.
    pub fn is_bin(&self) -> bool {
        match self.kind {
            BinTarget => true,
            _ => false
        }
    }

    pub fn get_profile(&self) -> &Profile {
        &self.profile
    }

    pub fn get_metadata(&self) -> Option<&Metadata> {
        self.metadata.as_ref()
    }

    /// Returns the arguments suitable for `--crate-type` to pass to rustc.
    pub fn rustc_crate_types(&self) -> Vec<&'static str> {
        match self.kind {
            LibTarget(ref kinds) => {
                kinds.iter().map(|kind| kind.crate_type()).collect()
            },
            BinTarget => vec!("bin")
        }
    }
}
<|endoftext|>


<commit_before>use qt_3d_core::cpp_utils::*;
use qt_3d_core::*;
use qt_3d_extras::*;
use qt_3d_input::*;
use qt_3d_render::*;
use qt_core::*;
use qt_gui::{
    q_surface_format::OpenGLContextProfile, QColor, QGuiApplication, QSurfaceFormat, QVector3D,
};
use std::cell::*;

fn setup_scene(root: &mut QEntity) -> Box<Fn() -> ()> {
    unsafe {
        let mut scene = MutPtr(root.static_upcast_mut().into());

        let mut sphere1 = MutPtr(scene.static_upcast_mut().into());
        let mut sphere1_mesh = QSphereMesh::new_0a();
        sphere1_mesh.set_radius(1.0);
        sphere1_mesh.set_rings(60);
        sphere1_mesh.set_slices(30);
        sphere1.add_component(
            sphere1_mesh
                .into_ptr()
                .static_upcast_mut()
                .static_upcast_mut()
                .into(),
        );
        let mut sphere1_material = QMetalRoughMaterial::new_0a();
        sphere1_material.set_base_color(
            QColor::from_rgb_3a(255, 255, 255)
                .to_qt_core_q_variant()
                .as_ref(),
        );
        sphere1_material.set_metalness(QVariant::new12(0.5).as_ref());
        sphere1_material.set_roughness(QVariant::new12(0.2).as_ref());
        sphere1.add_component(
            sphere1_material
                .into_ptr()
                .static_upcast_mut()
                .static_upcast_mut()
                .into(),
        );
        let mut sphere1_transform = QTransform::new_0a();
        sphere1_transform.set_translation(QVector3D::new2(-2.0, 0.0, 0.0).as_ref());
        sphere1.add_component(sphere1_transform.into_ptr().static_upcast_mut().into());
        sphere1.into_raw_ptr();

        let mut sphere2 = MutPtr(scene.static_upcast_mut().into());
        let mut sphere2_mesh = QSphereMesh::new_0a();
        sphere2_mesh.set_radius(1.0);
        sphere2_mesh.set_rings(60);
        sphere2_mesh.set_slices(30);
        sphere2.add_component(
            sphere2_mesh
                .into_ptr()
                .static_upcast_mut()
                .static_upcast_mut()
                .into(),
        );
        let mut sphere2_material = QMetalRoughMaterial::new_0a();
        sphere2_material.set_base_color(
            QColor::from_rgb_3a(255, 255, 255)
                .to_qt_core_q_variant()
                .as_ref(),
        );
        sphere2_material.set_metalness(QVariant::new12(0.5).as_ref());
        sphere2_material.set_roughness(QVariant::new12(0.2).as_ref());
        sphere2.add_component(
            sphere2_material
                .into_ptr()
                .static_upcast_mut()
                .static_upcast_mut()
                .into(),
        );
        let mut sphere2_transform = QTransform::new_0a();
        sphere2_transform.set_translation(QVector3D::new2(2.0, 0.0, 0.0).as_ref());
        sphere2.add_component(sphere2_transform.into_ptr().static_upcast_mut().into());
        sphere2.into_raw_ptr();

        let mut plane = MutPtr(scene.static_upcast_mut().into());
        plane.add_component(
            QPlaneMesh::new_0a()
                .into_ptr()
                .static_upcast_mut()
                .static_upcast_mut()
                .into(),
        );
        let mut plane_material = QMetalRoughMaterial::new_0a();
        plane_material.set_base_color(
            QColor::from_rgb_3a(255, 255, 255)
                .to_qt_core_q_variant()
                .as_ref(),
        );
        plane_material.set_metalness(QVariant::new12(0.5).as_ref());
        plane_material.set_roughness(QVariant::new12(0.5).as_ref());
        plane.add_component(
            plane_material
                .into_ptr()
                .static_upcast_mut()
                .static_upcast_mut()
                .into(),
        );
        let mut plane_transform = QTransform::new_0a();
        plane_transform.set_scale(100.0);
        plane_transform.set_translation(QVector3D::new2(0.0, -2.0, 0.0).as_ref());
        plane.add_component(plane_transform.into_ptr().static_upcast_mut().into());
        plane.into_raw_ptr();

        let mut directional_light = QDirectionalLight::new_0a();
        directional_light.set_enabled(true);
        directional_light.set_color(QColor::from_rgb_3a(255, 0, 0).as_ref());
        directional_light.set_intensity(1.0);
        directional_light.set_world_direction(QVector3D::new2(1.0, -1.0, 0.0).as_ref());
        let mut directional_light = directional_light.into_ptr();
        scene.add_component(
            directional_light
                .static_upcast_mut()
                .static_upcast_mut()
                .into(),
        );

        let mut point_light_entity = MutPtr(scene.static_upcast_mut().into());
        let mut point_light = QPointLight::new_0a();
        point_light.set_enabled(false);
        point_light.set_color(QColor::from_rgb_3a(0, 255, 0).as_ref());
        point_light.set_intensity(1.0);
        point_light.set_linear_attenuation(0.01);
        point_light.set_quadratic_attenuation(0.05);
        let mut point_light = point_light.into_ptr();
        point_light_entity
            .add_component(point_light.static_upcast_mut().static_upcast_mut().into());
        let mut point_light_transform = QTransform::new_0a();
        point_light_transform.set_translation(QVector3D::new2(0.0, 3.0, 1.0).as_ref());
        point_light_entity
            .add_component(point_light_transform.into_ptr().static_upcast_mut().into());
        point_light_entity.into_raw_ptr();

        let mut spot_light_entity = MutPtr(scene.static_upcast_mut().into());
        let mut spot_light = QSpotLight::new_0a();
        spot_light.set_enabled(false);
        spot_light.set_color(QColor::from_rgb_3a(0, 0, 255).as_ref());
        spot_light.set_intensity(1.0);
        spot_light.set_local_direction(QVector3D::new2(-1.0, -1.0, 0.0).as_ref());
        spot_light.set_cut_off_angle(45.0);
        spot_light.set_linear_attenuation(0.05);
        spot_light.set_quadratic_attenuation(0.005);
        let mut spot_light = spot_light.into_ptr();
        spot_light_entity.add_component(spot_light.static_upcast_mut().static_upcast_mut().into());
        let mut spot_light_transform = QTransform::new_0a();
        spot_light_transform.set_translation(QVector3D::new2(6.0, 6.0, 0.0).as_ref());
        spot_light_entity.add_component(spot_light_transform.into_ptr().static_upcast_mut().into());
        spot_light_entity.into_raw_ptr();

        scene.into_raw_ptr();

        let active_light_cell = RefCell::new(0);
        Box::new(move || {
            let active_light = (*active_light_cell.borrow() + 1) % 3;
            directional_light.clone().set_enabled(active_light == 0);
            point_light.clone().set_enabled(active_light == 1);
            spot_light.clone().set_enabled(active_light == 2);
            *active_light_cell.borrow_mut() = active_light;
        })
    }
}

fn main() {
    unsafe {
        let mut format = QSurfaceFormat::new_0a();
        format.set_version(3, 3);
        format.set_profile(OpenGLContextProfile::CoreProfile);
        format.set_depth_buffer_size(24);
        format.set_samples(4);
        format.set_stencil_buffer_size(8);
        QSurfaceFormat::set_default_format(format.as_ref());

        QGuiApplication::init(|_| {
            let mut window = Qt3DWindow::new_0a();

            let mut root = QEntity::new_0a();
            let activate_next_light = setup_scene(&mut root);
            let next_light_slot = Slot::new(activate_next_light.as_ref());

            let mut keyboard_device = QKeyboardDevice::new_1a(root.static_upcast_mut().into());
            let mut handler = MutPtr(root.static_upcast_mut().into());
            let mut keyboard_handler = QKeyboardHandler::new_0a();
            keyboard_handler.set_source_device(keyboard_device.as_mut_ptr());
            keyboard_handler.set_focus(true);
            keyboard_handler.tab_pressed().connect(&next_light_slot);
            keyboard_handler.space_pressed().connect(&next_light_slot);
            handler.add_component(keyboard_handler.static_upcast_mut().into());
            handler.into_raw_ptr();

            let mut camera = window.camera();
            camera.set_position(QVector3D::new2(0.0, 0.0, 30.0).as_ref());
            camera.set_view_center(QVector3D::new2(0.0, 0.0, 0.0).as_ref());

            let mut controller = QOrbitCameraController::new_1a(root.static_upcast_mut().into());
            controller.set_camera(camera);
            controller.set_linear_speed(50.0);
            controller.set_look_speed(180.0);
            controller.into_raw_ptr();

            window.set_root_entity(root.into_ptr());

            let mut window = window.into_ptr();
            window.show();
            QGuiApplication::exec()
        })
    }
}
<commit_msg>update lights example<commit_after>use qt_3d_core::cpp_utils::*;
use qt_3d_core::*;
use qt_3d_extras::*;
use qt_3d_input::*;
use qt_3d_render::*;
use qt_core::*;
use qt_gui::{
    q_surface_format::OpenGLContextProfile, QColor, QGuiApplication, QSurfaceFormat, QVector3D,
};
use std::cell::*;

fn setup_scene(root: MutPtr<QEntity>) -> Box<Fn() -> ()> {
    unsafe {
        let mut scene = QEntity::new_1a(root);

        let mut sphere1 = QEntity::new_1a(&mut scene);
        let mut sphere1_mesh = QSphereMesh::new_0a();
        sphere1_mesh.set_radius(1.0);
        sphere1_mesh.set_rings(60);
        sphere1_mesh.set_slices(30);
        sphere1.add_component(sphere1_mesh.into_ptr());
        let mut sphere1_material = QMetalRoughMaterial::new_0a();
        sphere1_material.set_base_color_q_color(&QColor::from_rgb_3a(255, 255, 255));
        sphere1_material.set_metalness_float(0.5);
        sphere1_material.set_roughness_float(0.2);
        sphere1.add_component(sphere1_material.into_ptr());
        let mut sphere1_transform = QTransform::new_0a();
        sphere1_transform.set_translation(&QVector3D::from_3_float(-2.0, 0.0, 0.0));
        sphere1.add_component(sphere1_transform.into_ptr());
        sphere1.into_raw_ptr();

        let mut sphere2 = QEntity::new_1a(&mut scene);
        let mut sphere2_mesh = QSphereMesh::new_0a();
        sphere2_mesh.set_radius(1.0);
        sphere2_mesh.set_rings(60);
        sphere2_mesh.set_slices(30);
        sphere2.add_component(sphere2_mesh.into_ptr());
        let mut sphere2_material = QMetalRoughMaterial::new_0a();
        sphere2_material.set_base_color_q_color(&QColor::from_rgb_3a(255, 255, 255));
        sphere2_material.set_metalness_float(0.5);
        sphere2_material.set_roughness_float(0.2);
        sphere2.add_component(sphere2_material.into_ptr());
        let mut sphere2_transform = QTransform::new_0a();
        sphere2_transform.set_translation(&QVector3D::from_3_float(2.0, 0.0, 0.0));
        sphere2.add_component(sphere2_transform.into_ptr());
        sphere2.into_raw_ptr();

        let mut plane = QEntity::new_1a(&mut scene);
        plane.add_component(QPlaneMesh::new_0a().into_ptr());
        let mut plane_material = QMetalRoughMaterial::new_0a();
        plane_material.set_base_color_q_color(&QColor::from_rgb_3a(255, 255, 255));
        plane_material.set_metalness_float(0.5);
        plane_material.set_roughness_float(0.5);
        plane.add_component(plane_material.into_ptr());
        let mut plane_transform = QTransform::new_0a();
        plane_transform.set_scale(100.0);
        plane_transform.set_translation(&QVector3D::from_3_float(0.0, -2.0, 0.0));
        plane.add_component(plane_transform.into_ptr());
        plane.into_raw_ptr();

        let mut directional_light = QDirectionalLight::new_0a();
        directional_light.set_enabled(true);
        directional_light.set_color(&QColor::from_rgb_3a(255, 0, 0));
        directional_light.set_intensity(1.0);
        directional_light.set_world_direction(&QVector3D::from_3_float(1.0, -1.0, 0.0));
        let directional_light = directional_light.into_ptr();
        scene.add_component(directional_light);

        let mut point_light_entity = QEntity::new_1a(&mut scene);
        let mut point_light = QPointLight::new_0a();
        point_light.set_enabled(false);
        point_light.set_color(&QColor::from_rgb_3a(0, 255, 0));
        point_light.set_intensity(1.0);
        point_light.set_linear_attenuation(0.01);
        point_light.set_quadratic_attenuation(0.05);
        let point_light = point_light.into_ptr();
        point_light_entity.add_component(point_light);
        let mut point_light_transform = QTransform::new_0a();
        point_light_transform.set_translation(&QVector3D::from_3_float(0.0, 3.0, 1.0));
        point_light_entity.add_component(point_light_transform.into_ptr());
        point_light_entity.into_raw_ptr();

        let mut spot_light_entity = QEntity::new_1a(&mut scene);
        let mut spot_light = QSpotLight::new_0a();
        spot_light.set_enabled(false);
        spot_light.set_color(&QColor::from_rgb_3a(0, 0, 255));
        spot_light.set_intensity(1.0);
        spot_light.set_local_direction(&QVector3D::from_3_float(-1.0, -1.0, 0.0));
        spot_light.set_cut_off_angle(45.0);
        spot_light.set_linear_attenuation(0.05);
        spot_light.set_quadratic_attenuation(0.005);
        let spot_light = spot_light.into_ptr();
        spot_light_entity.add_component(spot_light);
        let mut spot_light_transform = QTransform::new_0a();
        spot_light_transform.set_translation(&QVector3D::from_3_float(6.0, 6.0, 0.0));
        spot_light_entity.add_component(spot_light_transform.into_ptr());
        spot_light_entity.into_raw_ptr();

        scene.into_raw_ptr();

        let active_light_cell = RefCell::new(0);
        Box::new(move || {
            let active_light = (*active_light_cell.borrow() + 1) % 3;
            directional_light.clone().set_enabled(active_light == 0);
            point_light.clone().set_enabled(active_light == 1);
            spot_light.clone().set_enabled(active_light == 2);
            *active_light_cell.borrow_mut() = active_light;
        })
    }
}

fn main() {
    unsafe {
        let mut format = QSurfaceFormat::new_0a();
        format.set_version(3, 3);
        format.set_profile(OpenGLContextProfile::CoreProfile);
        format.set_depth_buffer_size(24);
        format.set_samples(4);
        format.set_stencil_buffer_size(8);
        QSurfaceFormat::set_default_format(&format);

        QGuiApplication::init(|_| {
            let mut window = Qt3DWindow::new_0a();

            let mut root = QEntity::new_0a();
            let activate_next_light = setup_scene(root.as_mut_ptr());
            let next_light_slot = Slot::new(activate_next_light.as_ref());

            let keyboard_device = QKeyboardDevice::new_1a(&mut root);
            let mut handler = QEntity::new_1a(&mut root);
            let mut keyboard_handler = QKeyboardHandler::new_0a();
            keyboard_handler.set_source_device(keyboard_device.into_ptr());
            keyboard_handler.set_focus(true);
            keyboard_handler.tab_pressed().connect(&next_light_slot);
            keyboard_handler.space_pressed().connect(&next_light_slot);
            handler.add_component(keyboard_handler.into_ptr());
            handler.into_ptr();

            let mut camera = window.camera();
            camera.set_position(&QVector3D::from_3_float(0.0, 0.0, 30.0));
            camera.set_view_center(&QVector3D::from_3_float(0.0, 0.0, 0.0));

            let mut controller = QOrbitCameraController::new_1a(&mut root);
            controller.set_camera(camera);
            controller.set_linear_speed(50.0);
            controller.set_look_speed(180.0);
            controller.into_ptr();

            window.set_root_entity(root.into_ptr());
            window.show();
            QGuiApplication::exec()
        })
    }
}
<|endoftext|>


<commit_before>import front.ast;
import front.ast.ident;
import front.ast.def;
import front.ast.ann;
import driver.session;
import util.common.span;
import std.map.hashmap;
import std.list.list;
import std.list.nil;
import std.list.cons;
import std.option;
import std.option.some;
import std.option.none;
import std._str;
import std._vec;

tag scope {
    scope_crate(@ast.crate);
    scope_item(@ast.item);
    scope_block(ast.block);
    scope_arm(ast.arm);
}

type env = rec(list[scope] scopes,
               session.session sess);

fn lookup_name(&env e, ast.ident i) -> option.t[def] {

    // log "resolving name " + i;

    fn found_def_item(@ast.item i) -> option.t[def] {
        alt (i.node) {
            case (ast.item_const(_, _, _, ?id, _)) {
                ret some[def](ast.def_const(id));
            }
            case (ast.item_fn(_, _, _, ?id, _)) {
                ret some[def](ast.def_fn(id));
            }
            case (ast.item_mod(_, _, ?id)) {
                ret some[def](ast.def_mod(id));
            }
            case (ast.item_ty(_, _, _, ?id, _)) {
                ret some[def](ast.def_ty(id));
            }
            case (ast.item_tag(_, _, _, ?id)) {
                ret some[def](ast.def_ty(id));
            }
        }
    }

    fn found_decl_stmt(@ast.stmt s) -> option.t[def] {
        alt (s.node) {
            case (ast.stmt_decl(?d)) {
                alt (d.node) {
                    case (ast.decl_local(?loc)) {
                        ret some[def](ast.def_local(loc.id));
                    }
                    case (ast.decl_item(?it)) {
                        ret found_def_item(it);
                    }
                }
            }
        }
        ret none[def];
    }

    fn check_mod(ast.ident i, ast._mod m) -> option.t[def] {
        alt (m.index.find(i)) {
            case (some[ast.mod_index_entry](?ent)) {
                alt (ent) {
                    case (ast.mie_item(?ix)) {
                        ret found_def_item(m.items.(ix));
                    }
                    case (ast.mie_tag_variant(?item_idx, ?variant_idx)) {
                        alt (m.items.(item_idx).node) {
                            case (ast.item_tag(_, ?variants, _, ?tid)) {
                                auto vid = variants.(variant_idx).id;
                                ret some[def](ast.def_variant(tid, vid));
                            }
                            case (_) {
                                log "tag item not actually a tag";
                                fail;
                            }
                        }
                    }
                }
            }
        }
        ret none[def];
    }

    fn in_scope(ast.ident i, &scope s) -> option.t[def] {
        alt (s) {

            case (scope_crate(?c)) {
                ret check_mod(i, c.node.module);
            }

            case (scope_item(?it)) {
                alt (it.node) {
                    case (ast.item_fn(_, ?f, _, _, _)) {
                        for (ast.arg a in f.inputs) {
                            if (_str.eq(a.ident, i)) {
                                ret some[def](ast.def_arg(a.id));
                            }
                        }
                    }
                    case (ast.item_mod(_, ?m, _)) {
                        ret check_mod(i, m);
                    }
                    case (_) { /* fall through */ }
                }
            }

            case (scope_block(?b)) {
                alt (b.node.index.find(i)) {
                    case (some[uint](?ix)) {
                        ret found_decl_stmt(b.node.stmts.(ix));
                    }
                    case (_) { /* fall through */  }
                }
            }

            case (scope_arm(?a)) {
                alt (a.index.find(i)) {
                    case (some[ast.def_id](?did)) {
                        ret some[def](ast.def_binding(did));
                    }
                    case (_) { /* fall through */  }
                }
            }
        }
        ret none[def];
    }

    ret std.list.find[scope,def](e.scopes, bind in_scope(i, _));
}

fn fold_expr_name(&env e, &span sp, &ast.name n,
                  &option.t[def] d, ann a) -> @ast.expr {

    if (_vec.len[@ast.ty](n.node.types) > 0u) {
        e.sess.unimpl("resoling name expr with ty params");
    }

    auto d_ = lookup_name(e, n.node.ident);

    alt (d_) {
        case (some[def](_)) {
            // log "resolved name " + n.node.ident;
        }
        case (none[def]) {
            e.sess.err("unresolved name: " + n.node.ident);
        }
    }

    ret @fold.respan[ast.expr_](sp, ast.expr_name(n, d_, a));
}

fn fold_ty_path(&env e, &span sp, ast.path p,
                &option.t[def] d) -> @ast.ty {

    let uint len = _vec.len[ast.name](p);
    check (len != 0u);
    if (len > 1u) {
        e.sess.unimpl("resoling path ty with >1 component");
    }

    let ast.name n = p.(0);

    if (_vec.len[@ast.ty](n.node.types) > 0u) {
        e.sess.unimpl("resoling path ty with ty params");
    }

    auto d_ = lookup_name(e, n.node.ident);

    alt (d_) {
        case (some[def](_)) {
            // log "resolved name " + n.node.ident;
        }
        case (none[def]) {
            e.sess.err("unresolved name: " + n.node.ident);
        }
    }

    ret @fold.respan[ast.ty_](sp, ast.ty_path(p, d_));
}

fn update_env_for_crate(&env e, @ast.crate c) -> env {
    ret rec(scopes = cons[scope](scope_crate(c), @e.scopes) with e);
}

fn update_env_for_item(&env e, @ast.item i) -> env {
    ret rec(scopes = cons[scope](scope_item(i), @e.scopes) with e);
}

fn update_env_for_block(&env e, &ast.block b) -> env {
    ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e);
}

fn update_env_for_arm(&env e, &ast.arm p) -> env {
    ret rec(scopes = cons[scope](scope_arm(p), @e.scopes) with e);
}

fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {

    let fold.ast_fold[env] fld = fold.new_identity_fold[env]();

    fld = @rec( fold_expr_name = bind fold_expr_name(_,_,_,_,_),
                fold_ty_path = bind fold_ty_path(_,_,_,_),
                update_env_for_crate = bind update_env_for_crate(_,_),
                update_env_for_item = bind update_env_for_item(_,_),
                update_env_for_block = bind update_env_for_block(_,_),
                update_env_for_arm = bind update_env_for_arm(_,_)
                with *fld );

    auto e = rec(scopes = nil[scope],
                 sess = sess);

    ret fold.fold_crate[env](e, fld, crate);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>rustc: "resoling" -> "resolving" typo<commit_after>import front.ast;
import front.ast.ident;
import front.ast.def;
import front.ast.ann;
import driver.session;
import util.common.span;
import std.map.hashmap;
import std.list.list;
import std.list.nil;
import std.list.cons;
import std.option;
import std.option.some;
import std.option.none;
import std._str;
import std._vec;

tag scope {
    scope_crate(@ast.crate);
    scope_item(@ast.item);
    scope_block(ast.block);
    scope_arm(ast.arm);
}

type env = rec(list[scope] scopes,
               session.session sess);

fn lookup_name(&env e, ast.ident i) -> option.t[def] {

    // log "resolving name " + i;

    fn found_def_item(@ast.item i) -> option.t[def] {
        alt (i.node) {
            case (ast.item_const(_, _, _, ?id, _)) {
                ret some[def](ast.def_const(id));
            }
            case (ast.item_fn(_, _, _, ?id, _)) {
                ret some[def](ast.def_fn(id));
            }
            case (ast.item_mod(_, _, ?id)) {
                ret some[def](ast.def_mod(id));
            }
            case (ast.item_ty(_, _, _, ?id, _)) {
                ret some[def](ast.def_ty(id));
            }
            case (ast.item_tag(_, _, _, ?id)) {
                ret some[def](ast.def_ty(id));
            }
        }
    }

    fn found_decl_stmt(@ast.stmt s) -> option.t[def] {
        alt (s.node) {
            case (ast.stmt_decl(?d)) {
                alt (d.node) {
                    case (ast.decl_local(?loc)) {
                        ret some[def](ast.def_local(loc.id));
                    }
                    case (ast.decl_item(?it)) {
                        ret found_def_item(it);
                    }
                }
            }
        }
        ret none[def];
    }

    fn check_mod(ast.ident i, ast._mod m) -> option.t[def] {
        alt (m.index.find(i)) {
            case (some[ast.mod_index_entry](?ent)) {
                alt (ent) {
                    case (ast.mie_item(?ix)) {
                        ret found_def_item(m.items.(ix));
                    }
                    case (ast.mie_tag_variant(?item_idx, ?variant_idx)) {
                        alt (m.items.(item_idx).node) {
                            case (ast.item_tag(_, ?variants, _, ?tid)) {
                                auto vid = variants.(variant_idx).id;
                                ret some[def](ast.def_variant(tid, vid));
                            }
                            case (_) {
                                log "tag item not actually a tag";
                                fail;
                            }
                        }
                    }
                }
            }
        }
        ret none[def];
    }

    fn in_scope(ast.ident i, &scope s) -> option.t[def] {
        alt (s) {

            case (scope_crate(?c)) {
                ret check_mod(i, c.node.module);
            }

            case (scope_item(?it)) {
                alt (it.node) {
                    case (ast.item_fn(_, ?f, _, _, _)) {
                        for (ast.arg a in f.inputs) {
                            if (_str.eq(a.ident, i)) {
                                ret some[def](ast.def_arg(a.id));
                            }
                        }
                    }
                    case (ast.item_mod(_, ?m, _)) {
                        ret check_mod(i, m);
                    }
                    case (_) { /* fall through */ }
                }
            }

            case (scope_block(?b)) {
                alt (b.node.index.find(i)) {
                    case (some[uint](?ix)) {
                        ret found_decl_stmt(b.node.stmts.(ix));
                    }
                    case (_) { /* fall through */  }
                }
            }

            case (scope_arm(?a)) {
                alt (a.index.find(i)) {
                    case (some[ast.def_id](?did)) {
                        ret some[def](ast.def_binding(did));
                    }
                    case (_) { /* fall through */  }
                }
            }
        }
        ret none[def];
    }

    ret std.list.find[scope,def](e.scopes, bind in_scope(i, _));
}

fn fold_expr_name(&env e, &span sp, &ast.name n,
                  &option.t[def] d, ann a) -> @ast.expr {

    if (_vec.len[@ast.ty](n.node.types) > 0u) {
        e.sess.unimpl("resolving name expr with ty params");
    }

    auto d_ = lookup_name(e, n.node.ident);

    alt (d_) {
        case (some[def](_)) {
            // log "resolved name " + n.node.ident;
        }
        case (none[def]) {
            e.sess.err("unresolved name: " + n.node.ident);
        }
    }

    ret @fold.respan[ast.expr_](sp, ast.expr_name(n, d_, a));
}

fn fold_ty_path(&env e, &span sp, ast.path p,
                &option.t[def] d) -> @ast.ty {

    let uint len = _vec.len[ast.name](p);
    check (len != 0u);
    if (len > 1u) {
        e.sess.unimpl("resolving path ty with >1 component");
    }

    let ast.name n = p.(0);

    if (_vec.len[@ast.ty](n.node.types) > 0u) {
        e.sess.unimpl("resolving path ty with ty params");
    }

    auto d_ = lookup_name(e, n.node.ident);

    alt (d_) {
        case (some[def](_)) {
            // log "resolved name " + n.node.ident;
        }
        case (none[def]) {
            e.sess.err("unresolved name: " + n.node.ident);
        }
    }

    ret @fold.respan[ast.ty_](sp, ast.ty_path(p, d_));
}

fn update_env_for_crate(&env e, @ast.crate c) -> env {
    ret rec(scopes = cons[scope](scope_crate(c), @e.scopes) with e);
}

fn update_env_for_item(&env e, @ast.item i) -> env {
    ret rec(scopes = cons[scope](scope_item(i), @e.scopes) with e);
}

fn update_env_for_block(&env e, &ast.block b) -> env {
    ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e);
}

fn update_env_for_arm(&env e, &ast.arm p) -> env {
    ret rec(scopes = cons[scope](scope_arm(p), @e.scopes) with e);
}

fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {

    let fold.ast_fold[env] fld = fold.new_identity_fold[env]();

    fld = @rec( fold_expr_name = bind fold_expr_name(_,_,_,_,_),
                fold_ty_path = bind fold_ty_path(_,_,_,_),
                update_env_for_crate = bind update_env_for_crate(_,_),
                update_env_for_item = bind update_env_for_item(_,_),
                update_env_for_block = bind update_env_for_block(_,_),
                update_env_for_arm = bind update_env_for_arm(_,_)
                with *fld );

    auto e = rec(scopes = nil[scope],
                 sess = sess);

    ret fold.fold_crate[env](e, fld, crate);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>