<commit_before>use super::validator_statuses::{TotalBalances, ValidatorStatus, ValidatorStatuses};
use super::{Error, WinningRootHashSet};
use integer_sqrt::IntegerSquareRoot;
use types::*;

#[derive(Default, Clone)]
pub struct Delta {
    pub rewards: u64,
    pub penalties: u64,
}

impl std::ops::AddAssign for Delta {
    /// Use wrapping addition as that is how it's defined in the spec.
    fn add_assign(&mut self, other: Delta) {
        self.rewards += other.rewards;
        self.penalties += other.penalties;
    }
}

/// Apply attester and proposer rewards.
///
/// Spec v0.5.0
pub fn apply_rewards(
    state: &mut BeaconState,
    validator_statuses: &mut ValidatorStatuses,
    winning_root_for_shards: &WinningRootHashSet,
    spec: &ChainSpec,
) -> Result<(), Error> {
    // Guard against an out-of-bounds during the validator balance update.
    if validator_statuses.statuses.len() != state.validator_balances.len() {
        return Err(Error::ValidatorStatusesInconsistent);
    }
    // Guard against an out-of-bounds during the attester inclusion balance update.
    if validator_statuses.statuses.len() != state.validator_registry.len() {
        return Err(Error::ValidatorStatusesInconsistent);
    }

    let mut deltas = vec![Delta::default(); state.validator_balances.len()];

    get_justification_and_finalization_deltas(&mut deltas, state, &validator_statuses, spec)?;
    get_crosslink_deltas(&mut deltas, state, &validator_statuses, spec)?;

    // Apply the proposer deltas if we are finalizing normally.
    //
    // This is executed slightly differently to the spec because of the way our functions are
    // structured. It should be functionally equivalent.
    if epochs_since_finality(state, spec) <= 4 {
        get_proposer_deltas(
            &mut deltas,
            state,
            validator_statuses,
            winning_root_for_shards,
            spec,
        )?;
    }

    // Apply the deltas, over-flowing but not under-flowing (saturating at 0 instead).
    for (i, delta) in deltas.iter().enumerate() {
        state.validator_balances[i] += delta.rewards;
        state.validator_balances[i] = state.validator_balances[i].saturating_sub(delta.penalties);
    }

    Ok(())
}

/// Applies the attestation inclusion reward to each proposer for every validator who included an
/// attestation in the previous epoch.
///
/// Spec v0.5.0
fn get_proposer_deltas(
    deltas: &mut Vec<Delta>,
    state: &mut BeaconState,
    validator_statuses: &mut ValidatorStatuses,
    winning_root_for_shards: &WinningRootHashSet,
    spec: &ChainSpec,
) -> Result<(), Error> {
    // Update statuses with the information from winning roots.
    validator_statuses.process_winning_roots(state, winning_root_for_shards, spec)?;

    for (index, validator) in validator_statuses.statuses.iter().enumerate() {
        let mut delta = Delta::default();

        if validator.is_previous_epoch_attester {
            let inclusion = validator
                .inclusion_info
                .expect("It is a logic error for an attester not to have an inclusion distance.");

            let base_reward = get_base_reward(
                state,
                inclusion.proposer_index,
                validator_statuses.total_balances.previous_epoch,
                spec,
            )?;

            if inclusion.proposer_index >= deltas.len() {
                return Err(Error::ValidatorStatusesInconsistent);
            }

            delta.rewards += base_reward / spec.attestation_inclusion_reward_quotient;
        }

        deltas[index] += delta;
    }

    Ok(())
}

/// Apply rewards for participation in attestations during the previous epoch.
///
/// Spec v0.5.0
fn get_justification_and_finalization_deltas(
    deltas: &mut Vec<Delta>,
    state: &BeaconState,
    validator_statuses: &ValidatorStatuses,
    spec: &ChainSpec,
) -> Result<(), Error> {
    let epochs_since_finality = epochs_since_finality(state, spec);

    for (index, validator) in validator_statuses.statuses.iter().enumerate() {
        let base_reward = get_base_reward(
            state,
            index,
            validator_statuses.total_balances.previous_epoch,
            spec,
        )?;
        let inactivity_penalty = get_inactivity_penalty(
            state,
            index,
            epochs_since_finality.as_u64(),
            validator_statuses.total_balances.previous_epoch,
            spec,
        )?;

        let delta = if epochs_since_finality <= 4 {
            compute_normal_justification_and_finalization_delta(
                &validator,
                &validator_statuses.total_balances,
                base_reward,
                spec,
            )
        } else {
            compute_inactivity_leak_delta(&validator, base_reward, inactivity_penalty, spec)
        };

        deltas[index] += delta;
    }

    Ok(())
}

/// Determine the delta for a single validator, if the chain is finalizing normally.
///
/// Spec v0.5.0
fn compute_normal_justification_and_finalization_delta(
    validator: &ValidatorStatus,
    total_balances: &TotalBalances,
    base_reward: u64,
    spec: &ChainSpec,
) -> Delta {
    let mut delta = Delta::default();

    let boundary_attesting_balance = total_balances.previous_epoch_boundary_attesters;
    let total_balance = total_balances.previous_epoch;
    let total_attesting_balance = total_balances.previous_epoch_attesters;
    let matching_head_balance = total_balances.previous_epoch_boundary_attesters;

    // Expected FFG source.
    if validator.is_previous_epoch_attester {
        delta.rewards += base_reward * total_attesting_balance / total_balance;
        // Inclusion speed bonus
        let inclusion = validator
            .inclusion_info
            .expect("It is a logic error for an attester not to have an inclusion distance.");
        delta.rewards +=
            base_reward * spec.min_attestation_inclusion_delay / inclusion.distance.as_u64();
    } else if validator.is_active_in_previous_epoch {
        delta.penalties += base_reward;
    }

    // Expected FFG target.
    if validator.is_previous_epoch_boundary_attester {
        delta.rewards += base_reward / boundary_attesting_balance / total_balance;
    } else if validator.is_active_in_previous_epoch {
        delta.penalties += base_reward;
    }

    // Expected head.
    if validator.is_previous_epoch_head_attester {
        delta.rewards += base_reward * matching_head_balance / total_balance;
    } else if validator.is_active_in_previous_epoch {
        delta.penalties += base_reward;
    };

    // Proposer bonus is handled in `apply_proposer_deltas`.
    //
    // This function only computes the delta for a single validator, so it cannot also return a
    // delta for a validator.

    delta
}

/// Determine the delta for a single delta, assuming the chain is _not_ finalizing normally.
///
/// Spec v0.5.0
fn compute_inactivity_leak_delta(
    validator: &ValidatorStatus,
    base_reward: u64,
    inactivity_penalty: u64,
    spec: &ChainSpec,
) -> Delta {
    let mut delta = Delta::default();

    if validator.is_active_in_previous_epoch {
        if !validator.is_previous_epoch_attester {
            delta.penalties += inactivity_penalty;
        } else {
            // If a validator did attest, apply a small penalty for getting attestations included
            // late.
            let inclusion = validator
                .inclusion_info
                .expect("It is a logic error for an attester not to have an inclusion distance.");
            delta.rewards +=
                base_reward * spec.min_attestation_inclusion_delay / inclusion.distance.as_u64();
            delta.penalties += base_reward;
        }

        if !validator.is_previous_epoch_boundary_attester {
            delta.penalties += inactivity_penalty;
        }

        if !validator.is_previous_epoch_head_attester {
            delta.penalties += inactivity_penalty;
        }
    }

    // Penalize slashed-but-inactive validators as though they were active but offline.
    if !validator.is_active_in_previous_epoch
        & validator.is_slashed
        & !validator.is_withdrawable_in_current_epoch
    {
        delta.penalties += 2 * inactivity_penalty + base_reward;
    }

    delta
}

/// Calculate the deltas based upon the winning roots for attestations during the previous epoch.
///
/// Spec v0.5.0
fn get_crosslink_deltas(
    deltas: &mut Vec<Delta>,
    state: &BeaconState,
    validator_statuses: &ValidatorStatuses,
    spec: &ChainSpec,
) -> Result<(), Error> {
    for (index, validator) in validator_statuses.statuses.iter().enumerate() {
        let mut delta = Delta::default();

        let base_reward = get_base_reward(
            state,
            index,
            validator_statuses.total_balances.previous_epoch,
            spec,
        )?;

        if let Some(ref winning_root) = validator.winning_root_info {
            delta.rewards += base_reward * winning_root.total_attesting_balance
                / winning_root.total_committee_balance
        } else {
            delta.penalties += base_reward;
        }

        deltas[index] += delta;
    }

    Ok(())
}

/// Returns the base reward for some validator.
///
/// Spec v0.5.0
fn get_base_reward(
    state: &BeaconState,
    index: usize,
    previous_total_balance: u64,
    spec: &ChainSpec,
) -> Result<u64, BeaconStateError> {
    if previous_total_balance == 0 {
        Ok(0)
    } else {
        let adjusted_quotient = previous_total_balance.integer_sqrt() / spec.base_reward_quotient;
        Ok(state.get_effective_balance(index, spec)? / adjusted_quotient / 5)
    }
}

/// Returns the inactivity penalty for some validator.
///
/// Spec v0.5.0
fn get_inactivity_penalty(
    state: &BeaconState,
    index: usize,
    epochs_since_finality: u64,
    previous_total_balance: u64,
    spec: &ChainSpec,
) -> Result<u64, BeaconStateError> {
    Ok(get_base_reward(state, index, previous_total_balance, spec)?
        + state.get_effective_balance(index, spec)? * epochs_since_finality
            / spec.inactivity_penalty_quotient
            / 2)
}

/// Returns the epochs since the last finalized epoch.
///
/// Spec v0.5.0
fn epochs_since_finality(state: &BeaconState, spec: &ChainSpec) -> Epoch {
    state.current_epoch(spec) + 1 - state.finalized_epoch
}
<commit_msg>Tidy reward processing<commit_after>use super::validator_statuses::{TotalBalances, ValidatorStatus, ValidatorStatuses};
use super::{Error, WinningRootHashSet};
use integer_sqrt::IntegerSquareRoot;
use types::*;

/// Use to track the changes to a validators balance.
#[derive(Default, Clone)]
pub struct Delta {
    rewards: u64,
    penalties: u64,
}

impl Delta {
    /// Reward the validator with the `reward`.
    pub fn reward(&mut self, reward: u64) {
        self.rewards += reward;
    }

    /// Penalize the validator with the `penalty`.
    pub fn penalize(&mut self, penalty: u64) {
        self.penalties += penalty;
    }
}

impl std::ops::AddAssign for Delta {
    /// Use wrapping addition as that is how it's defined in the spec.
    fn add_assign(&mut self, other: Delta) {
        self.rewards += other.rewards;
        self.penalties += other.penalties;
    }
}

/// Apply attester and proposer rewards.
///
/// Spec v0.5.0
pub fn apply_rewards(
    state: &mut BeaconState,
    validator_statuses: &mut ValidatorStatuses,
    winning_root_for_shards: &WinningRootHashSet,
    spec: &ChainSpec,
) -> Result<(), Error> {
    // Guard against an out-of-bounds during the validator balance update.
    if validator_statuses.statuses.len() != state.validator_balances.len() {
        return Err(Error::ValidatorStatusesInconsistent);
    }
    // Guard against an out-of-bounds during the attester inclusion balance update.
    if validator_statuses.statuses.len() != state.validator_registry.len() {
        return Err(Error::ValidatorStatusesInconsistent);
    }

    let mut deltas = vec![Delta::default(); state.validator_balances.len()];

    get_justification_and_finalization_deltas(&mut deltas, state, &validator_statuses, spec)?;
    get_crosslink_deltas(&mut deltas, state, &validator_statuses, spec)?;

    // Apply the proposer deltas if we are finalizing normally.
    //
    // This is executed slightly differently to the spec because of the way our functions are
    // structured. It should be functionally equivalent.
    if epochs_since_finality(state, spec) <= 4 {
        get_proposer_deltas(
            &mut deltas,
            state,
            validator_statuses,
            winning_root_for_shards,
            spec,
        )?;
    }

    // Apply the deltas, over-flowing but not under-flowing (saturating at 0 instead).
    for (i, delta) in deltas.iter().enumerate() {
        state.validator_balances[i] += delta.rewards;
        state.validator_balances[i] = state.validator_balances[i].saturating_sub(delta.penalties);
    }

    Ok(())
}

/// Applies the attestation inclusion reward to each proposer for every validator who included an
/// attestation in the previous epoch.
///
/// Spec v0.5.0
fn get_proposer_deltas(
    deltas: &mut Vec<Delta>,
    state: &mut BeaconState,
    validator_statuses: &mut ValidatorStatuses,
    winning_root_for_shards: &WinningRootHashSet,
    spec: &ChainSpec,
) -> Result<(), Error> {
    // Update statuses with the information from winning roots.
    validator_statuses.process_winning_roots(state, winning_root_for_shards, spec)?;

    for (index, validator) in validator_statuses.statuses.iter().enumerate() {
        let mut delta = Delta::default();

        if validator.is_previous_epoch_attester {
            let inclusion = validator
                .inclusion_info
                .expect("It is a logic error for an attester not to have an inclusion distance.");

            let base_reward = get_base_reward(
                state,
                inclusion.proposer_index,
                validator_statuses.total_balances.previous_epoch,
                spec,
            )?;

            if inclusion.proposer_index >= deltas.len() {
                return Err(Error::ValidatorStatusesInconsistent);
            }

            delta.reward(base_reward / spec.attestation_inclusion_reward_quotient);
        }

        deltas[index] += delta;
    }

    Ok(())
}

/// Apply rewards for participation in attestations during the previous epoch.
///
/// Spec v0.5.0
fn get_justification_and_finalization_deltas(
    deltas: &mut Vec<Delta>,
    state: &BeaconState,
    validator_statuses: &ValidatorStatuses,
    spec: &ChainSpec,
) -> Result<(), Error> {
    let epochs_since_finality = epochs_since_finality(state, spec);

    for (index, validator) in validator_statuses.statuses.iter().enumerate() {
        let base_reward = get_base_reward(
            state,
            index,
            validator_statuses.total_balances.previous_epoch,
            spec,
        )?;
        let inactivity_penalty = get_inactivity_penalty(
            state,
            index,
            epochs_since_finality.as_u64(),
            validator_statuses.total_balances.previous_epoch,
            spec,
        )?;

        let delta = if epochs_since_finality <= 4 {
            compute_normal_justification_and_finalization_delta(
                &validator,
                &validator_statuses.total_balances,
                base_reward,
                spec,
            )
        } else {
            compute_inactivity_leak_delta(&validator, base_reward, inactivity_penalty, spec)
        };

        deltas[index] += delta;
    }

    Ok(())
}

/// Determine the delta for a single validator, if the chain is finalizing normally.
///
/// Spec v0.5.0
fn compute_normal_justification_and_finalization_delta(
    validator: &ValidatorStatus,
    total_balances: &TotalBalances,
    base_reward: u64,
    spec: &ChainSpec,
) -> Delta {
    let mut delta = Delta::default();

    let boundary_attesting_balance = total_balances.previous_epoch_boundary_attesters;
    let total_balance = total_balances.previous_epoch;
    let total_attesting_balance = total_balances.previous_epoch_attesters;
    let matching_head_balance = total_balances.previous_epoch_boundary_attesters;

    // Expected FFG source.
    if validator.is_previous_epoch_attester {
        delta.reward(base_reward * total_attesting_balance / total_balance);
        // Inclusion speed bonus
        let inclusion = validator
            .inclusion_info
            .expect("It is a logic error for an attester not to have an inclusion distance.");
        delta.reward(
            base_reward * spec.min_attestation_inclusion_delay / inclusion.distance.as_u64(),
        );
    } else if validator.is_active_in_previous_epoch {
        delta.penalize(base_reward);
    }

    // Expected FFG target.
    if validator.is_previous_epoch_boundary_attester {
        delta.reward(base_reward / boundary_attesting_balance / total_balance);
    } else if validator.is_active_in_previous_epoch {
        delta.penalize(base_reward);
    }

    // Expected head.
    if validator.is_previous_epoch_head_attester {
        delta.reward(base_reward * matching_head_balance / total_balance);
    } else if validator.is_active_in_previous_epoch {
        delta.penalize(base_reward);
    };

    // Proposer bonus is handled in `apply_proposer_deltas`.
    //
    // This function only computes the delta for a single validator, so it cannot also return a
    // delta for a validator.

    delta
}

/// Determine the delta for a single delta, assuming the chain is _not_ finalizing normally.
///
/// Spec v0.5.0
fn compute_inactivity_leak_delta(
    validator: &ValidatorStatus,
    base_reward: u64,
    inactivity_penalty: u64,
    spec: &ChainSpec,
) -> Delta {
    let mut delta = Delta::default();

    if validator.is_active_in_previous_epoch {
        if !validator.is_previous_epoch_attester {
            delta.penalize(inactivity_penalty);
        } else {
            // If a validator did attest, apply a small penalty for getting attestations included
            // late.
            let inclusion = validator
                .inclusion_info
                .expect("It is a logic error for an attester not to have an inclusion distance.");
            delta.reward(
                base_reward * spec.min_attestation_inclusion_delay / inclusion.distance.as_u64(),
            );
            delta.penalize(base_reward);
        }

        if !validator.is_previous_epoch_boundary_attester {
            delta.reward(inactivity_penalty);
        }

        if !validator.is_previous_epoch_head_attester {
            delta.penalize(inactivity_penalty);
        }
    }

    // Penalize slashed-but-inactive validators as though they were active but offline.
    if !validator.is_active_in_previous_epoch
        & validator.is_slashed
        & !validator.is_withdrawable_in_current_epoch
    {
        delta.penalize(2 * inactivity_penalty + base_reward);
    }

    delta
}

/// Calculate the deltas based upon the winning roots for attestations during the previous epoch.
///
/// Spec v0.5.0
fn get_crosslink_deltas(
    deltas: &mut Vec<Delta>,
    state: &BeaconState,
    validator_statuses: &ValidatorStatuses,
    spec: &ChainSpec,
) -> Result<(), Error> {
    for (index, validator) in validator_statuses.statuses.iter().enumerate() {
        let mut delta = Delta::default();

        let base_reward = get_base_reward(
            state,
            index,
            validator_statuses.total_balances.previous_epoch,
            spec,
        )?;

        if let Some(ref winning_root) = validator.winning_root_info {
            delta.reward(
                base_reward * winning_root.total_attesting_balance
                    / winning_root.total_committee_balance,
            );
        } else {
            delta.penalize(base_reward);
        }

        deltas[index] += delta;
    }

    Ok(())
}

/// Returns the base reward for some validator.
///
/// Spec v0.5.0
fn get_base_reward(
    state: &BeaconState,
    index: usize,
    previous_total_balance: u64,
    spec: &ChainSpec,
) -> Result<u64, BeaconStateError> {
    if previous_total_balance == 0 {
        Ok(0)
    } else {
        let adjusted_quotient = previous_total_balance.integer_sqrt() / spec.base_reward_quotient;
        Ok(state.get_effective_balance(index, spec)? / adjusted_quotient / 5)
    }
}

/// Returns the inactivity penalty for some validator.
///
/// Spec v0.5.0
fn get_inactivity_penalty(
    state: &BeaconState,
    index: usize,
    epochs_since_finality: u64,
    previous_total_balance: u64,
    spec: &ChainSpec,
) -> Result<u64, BeaconStateError> {
    Ok(get_base_reward(state, index, previous_total_balance, spec)?
        + state.get_effective_balance(index, spec)? * epochs_since_finality
            / spec.inactivity_penalty_quotient
            / 2)
}

/// Returns the epochs since the last finalized epoch.
///
/// Spec v0.5.0
fn epochs_since_finality(state: &BeaconState, spec: &ChainSpec) -> Epoch {
    state.current_epoch(spec) + 1 - state.finalized_epoch
}
<|endoftext|>


<commit_before><commit_msg>Implement Label for some more wire-types. (#1418)<commit_after><|endoftext|>


<commit_before>// Copyright 2017 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.

//! # Note
//!
//! This API is completely unstable and subject to change.

#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(custom_attribute)]
#![allow(unused_attributes)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]

#![recursion_limit="256"]

extern crate flate2;
#[macro_use]
extern crate log;

#[macro_use]
extern crate rustc;
extern crate rustc_target;
extern crate rustc_mir;
extern crate rustc_incremental;
extern crate syntax;
extern crate syntax_pos;
#[macro_use] extern crate rustc_data_structures;
extern crate rustc_metadata_utils;

use rustc::ty::TyCtxt;

pub mod link;
pub mod codegen_backend;
pub mod symbol_names;
pub mod symbol_names_test;

/// check for the #[rustc_error] annotation, which forces an
/// error in codegen. This is used to write compile-fail tests
/// that actually test that compilation succeeds without
/// reporting an error.
pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
    if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
        let main_def_id = tcx.hir.local_def_id(id);

        if tcx.has_attr(main_def_id, "rustc_error") {
            tcx.sess.span_fatal(span, "compilation successful");
        }
    }
}

__build_diagnostic_array! { librustc_codegen_utils, DIAGNOSTICS }
<commit_msg>[nll] librustc_codegen_utils: enable feature(nll) for bootstrap<commit_after>// Copyright 2017 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.

//! # Note
//!
//! This API is completely unstable and subject to change.

#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(custom_attribute)]
#![cfg_attr(not(stage0), feature(nll))]
#![allow(unused_attributes)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]

#![recursion_limit="256"]

extern crate flate2;
#[macro_use]
extern crate log;

#[macro_use]
extern crate rustc;
extern crate rustc_target;
extern crate rustc_mir;
extern crate rustc_incremental;
extern crate syntax;
extern crate syntax_pos;
#[macro_use] extern crate rustc_data_structures;
extern crate rustc_metadata_utils;

use rustc::ty::TyCtxt;

pub mod link;
pub mod codegen_backend;
pub mod symbol_names;
pub mod symbol_names_test;

/// check for the #[rustc_error] annotation, which forces an
/// error in codegen. This is used to write compile-fail tests
/// that actually test that compilation succeeds without
/// reporting an error.
pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
    if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
        let main_def_id = tcx.hir.local_def_id(id);

        if tcx.has_attr(main_def_id, "rustc_error") {
            tcx.sess.span_fatal(span, "compilation successful");
        }
    }
}

__build_diagnostic_array! { librustc_codegen_utils, DIAGNOSTICS }
<|endoftext|>


<commit_before>//! A small demonstration of how to use the `draw.scale(s)` and `draw.rotate(r)` transform methods
//! to transform the drawing context. This can be useful when applying transformations to whole
//! groups of drawings, rather than one at a time. Note that `scale` and `rotate` are only two of
//! many transform methods. See the link below to find a whole suite of interesting draw methods:
//!
//! https://docs.rs/nannou/latest/nannou/draw/struct.Draw.html

use nannou::prelude::*;

fn main() {
    nannou::sketch(view).run()
}

fn view(app: &App, frame: Frame) {
    frame.clear(BLACK);

    // Begin drawing
    let draw = app.draw();
    let w = app.window_rect();

    // Slowly turn the whole drawing inside out.
    let draw = draw.scale((app.time * 0.1).cos());

    // Draw a tunnel of rectangles.
    let max_side = w.right().max(w.top());
    let gap = 30.0;
    let len = (max_side / gap) as u32;
    for i in 1..=len {
        let f = i as f32 / len as f32;

        // Return a new rotated draw instance.
        // This will rotate both the rect and text around the origin.
        let rotate = (app.time * 0.5).sin() * (app.time * 0.25 + f * PI * 2.0).cos();
        let draw = draw.rotate(rotate);

        let hue = app.time + f * 2.0 * PI;
        let color = hsl(hue, 0.5, 0.5);
        let rect_scale = f.powi(2) * max_side * 2.0;
        draw.scale(rect_scale)
            .rect()
            .w_h(1.0, 1.0)
            .stroke(color)
            .stroke_weight(1.0 / len as f32)
            .no_fill()
            .w_h(1.0, 1.0);

        let text_scale = rect_scale * 0.001;
        draw.scale(text_scale)
            .text("woah")
            .wh(w.wh() * 0.8)
            .align_text_bottom()
            .color(color)
            .font_size(96);
    }

    // Write the result of our drawing to the window's frame.
    draw.to_frame(app, &frame).unwrap();
}
<commit_msg>Make draw_transform example a little nicer<commit_after>//! A small demonstration of how to use the `draw.scale(s)` and `draw.rotate(r)` transform methods
//! to transform the drawing context. This can be useful when applying transformations to whole
//! groups of drawings, rather than one at a time. Note that `scale` and `rotate` are only two of
//! many transform methods. See the link below to find a whole suite of interesting draw methods:
//!
//! https://docs.rs/nannou/latest/nannou/draw/struct.Draw.html

use nannou::prelude::*;

fn main() {
    nannou::sketch(view).run()
}

fn view(app: &App, frame: Frame) {
    frame.clear(BLACK);

    // Begin drawing
    let draw = app.draw();
    let w = app.window_rect();

    // Slowly turn the whole drawing inside out.
    let draw = draw.scale((app.time * 0.1).cos());

    // Draw a tunnel of rectangles.
    let max_side = w.right().max(w.top());
    let gap = 30.0;
    let len = (max_side / gap) as u32;
    for i in 1..=len {
        let f = i as f32 / len as f32;

        // Return a new rotated draw instance.
        // This will rotate both the rect and text around the origin.
        let rotate = (app.time * 0.5).sin() * (app.time * 0.25 + f * PI * 2.0).cos();
        let draw = draw.rotate(rotate);

        let hue = app.time + f * 2.0 * PI;
        let dive = (f + app.time * 0.1) % 1.0;
        let color = hsla(hue, 0.5, 0.5, 1.0 - dive.powi(3));
        let rect_scale = dive.powi(2) * max_side * 2.0;
        draw.scale(rect_scale)
            .rect()
            .w_h(1.0, 1.0)
            .stroke(color)
            .stroke_weight(1.0 / len as f32)
            .no_fill()
            .w_h(1.0, 1.0);

        let text_scale = rect_scale * 0.001;
        draw.scale(text_scale)
            .text("woah")
            .wh(w.wh() * 0.8)
            .align_text_bottom()
            .color(color)
            .font_size(96);
    }

    // Write the result of our drawing to the window's frame.
    draw.to_frame(app, &frame).unwrap();
}
<|endoftext|>


<commit_before>use opentelemetry::{
    sdk::export::trace,
    trace::{Event, SpanKind, StatusCode},
    Key, KeyValue,
};
use std::collections::HashMap;
use std::time::{Duration, SystemTime};

pub(crate) mod annotation;
pub(crate) mod endpoint;
pub(crate) mod span;

use endpoint::Endpoint;

/// Instrument Library name MUST be reported in Jaeger Span tags with the following key
const INSTRUMENTATION_LIBRARY_NAME: &str = "otel.library.name";

/// Instrument Library version MUST be reported in Jaeger Span tags with the following key
const INSTRUMENTATION_LIBRARY_VERSION: &str = "otel.library.version";

/// Converts `Event` into an `annotation::Annotation`
impl Into<annotation::Annotation> for Event {
    fn into(self) -> annotation::Annotation {
        let timestamp = self
            .timestamp
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap_or_else(|_| Duration::from_secs(0))
            .as_micros() as u64;

        annotation::Annotation::builder()
            .timestamp(timestamp)
            .value(self.name)
            .build()
    }
}

/// Converts StatusCode to str
fn from_statuscode_to_str(status_code: StatusCode) -> &'static str {
    match status_code {
        StatusCode::Ok => "OK",
        StatusCode::Unset => "UNSET",
        StatusCode::Error => "ERROR",
    }
}

/// Converts `SpanKind` into an `Option<span::Kind>`
fn into_zipkin_span_kind(kind: SpanKind) -> Option<span::Kind> {
    match kind {
        SpanKind::Client => Some(span::Kind::Client),
        SpanKind::Server => Some(span::Kind::Server),
        SpanKind::Producer => Some(span::Kind::Producer),
        SpanKind::Consumer => Some(span::Kind::Consumer),
        SpanKind::Internal => None,
    }
}

/// Converts a `trace::SpanData` to a `span::SpanData` for a given `ExporterConfig`, which can then
/// be ingested into a Zipkin collector.
pub(crate) fn into_zipkin_span(local_endpoint: Endpoint, span_data: trace::SpanData) -> span::Span {
    let mut user_defined_span_kind = false;
    let mut tags = map_from_kvs(
        span_data
            .attributes
            .into_iter()
            .map(|(k, v)| {
                if k == Key::new("span.kind") {
                    user_defined_span_kind = true;
                }
                KeyValue::new(k, v)
            })
            .chain(
                span_data
                    .resource
                    .iter()
                    .map(|(k, v)| KeyValue::new(k.clone(), v.clone())),
            )
            .chain(
                [
                    (
                        INSTRUMENTATION_LIBRARY_NAME,
                        Some(span_data.instrumentation_lib.name),
                    ),
                    (
                        INSTRUMENTATION_LIBRARY_VERSION,
                        span_data.instrumentation_lib.version,
                    ),
                ]
                .iter()
                .filter_map(|(key, val)| val.map(|val| KeyValue::new(*key, val))),
            ),
    );

    tags.insert(
        "otel.status_code".into(),
        from_statuscode_to_str(span_data.status_code).into(),
    );
    tags.insert("otel.status_description".into(), span_data.status_message);

    span::Span::builder()
        .trace_id(span_data.span_context.trace_id().to_hex())
        .parent_id(span_data.parent_span_id.to_hex())
        .id(span_data.span_context.span_id().to_hex())
        .name(span_data.name)
        .kind(if user_defined_span_kind {
            None
        } else {
            into_zipkin_span_kind(span_data.span_kind)
        })
        .timestamp(
            span_data
                .start_time
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap_or_else(|_| Duration::from_secs(0))
                .as_micros() as u64,
        )
        .duration(
            span_data
                .end_time
                .duration_since(span_data.start_time)
                .unwrap_or_else(|_| Duration::from_secs(0))
                .as_micros() as u64,
        )
        .local_endpoint(local_endpoint)
        .annotations(
            span_data
                .message_events
                .into_iter()
                .map(Into::into)
                .collect(),
        )
        .tags(tags)
        .build()
}

fn map_from_kvs<T>(kvs: T) -> HashMap<String, String>
where
    T: IntoIterator<Item = KeyValue>,
{
    let mut map: HashMap<String, String> = HashMap::new();
    for kv in kvs {
        map.insert(kv.key.into(), kv.value.to_string());
    }
    map
}
<commit_msg>feat: exclude status code if unset (#382)<commit_after>use opentelemetry::{
    sdk::export::trace,
    trace::{Event, SpanKind, StatusCode},
    Key, KeyValue,
};
use std::collections::HashMap;
use std::time::{Duration, SystemTime};

pub(crate) mod annotation;
pub(crate) mod endpoint;
pub(crate) mod span;

use endpoint::Endpoint;

/// Instrument Library name MUST be reported in Jaeger Span tags with the following key
const INSTRUMENTATION_LIBRARY_NAME: &str = "otel.library.name";

/// Instrument Library version MUST be reported in Jaeger Span tags with the following key
const INSTRUMENTATION_LIBRARY_VERSION: &str = "otel.library.version";

/// Converts `Event` into an `annotation::Annotation`
impl Into<annotation::Annotation> for Event {
    fn into(self) -> annotation::Annotation {
        let timestamp = self
            .timestamp
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap_or_else(|_| Duration::from_secs(0))
            .as_micros() as u64;

        annotation::Annotation::builder()
            .timestamp(timestamp)
            .value(self.name)
            .build()
    }
}

/// Converts StatusCode to Option<&'static str>
/// `Unset` status code is unused.
fn from_statuscode_to_str(status_code: StatusCode) -> Option<&'static str> {
    match status_code {
        StatusCode::Ok => Some("OK"),
        StatusCode::Unset => None,
        StatusCode::Error => Some("ERROR"),
    }
}

/// Converts `SpanKind` into an `Option<span::Kind>`
fn into_zipkin_span_kind(kind: SpanKind) -> Option<span::Kind> {
    match kind {
        SpanKind::Client => Some(span::Kind::Client),
        SpanKind::Server => Some(span::Kind::Server),
        SpanKind::Producer => Some(span::Kind::Producer),
        SpanKind::Consumer => Some(span::Kind::Consumer),
        SpanKind::Internal => None,
    }
}

/// Converts a `trace::SpanData` to a `span::SpanData` for a given `ExporterConfig`, which can then
/// be ingested into a Zipkin collector.
pub(crate) fn into_zipkin_span(local_endpoint: Endpoint, span_data: trace::SpanData) -> span::Span {
    let mut user_defined_span_kind = false;
    let mut tags = map_from_kvs(
        span_data
            .attributes
            .into_iter()
            .map(|(k, v)| {
                if k == Key::new("span.kind") {
                    user_defined_span_kind = true;
                }
                KeyValue::new(k, v)
            })
            .chain(
                span_data
                    .resource
                    .iter()
                    .map(|(k, v)| KeyValue::new(k.clone(), v.clone())),
            )
            .chain(
                [
                    (
                        INSTRUMENTATION_LIBRARY_NAME,
                        Some(span_data.instrumentation_lib.name),
                    ),
                    (
                        INSTRUMENTATION_LIBRARY_VERSION,
                        span_data.instrumentation_lib.version,
                    ),
                ]
                .iter()
                .filter_map(|(key, val)| val.map(|val| KeyValue::new(*key, val))),
            ),
    );

    if let Some(status_code) = from_statuscode_to_str(span_data.status_code) {
        tags.insert("otel.status_code".into(), status_code.into());
    }

    tags.insert("otel.status_description".into(), span_data.status_message);

    span::Span::builder()
        .trace_id(span_data.span_context.trace_id().to_hex())
        .parent_id(span_data.parent_span_id.to_hex())
        .id(span_data.span_context.span_id().to_hex())
        .name(span_data.name)
        .kind(if user_defined_span_kind {
            None
        } else {
            into_zipkin_span_kind(span_data.span_kind)
        })
        .timestamp(
            span_data
                .start_time
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap_or_else(|_| Duration::from_secs(0))
                .as_micros() as u64,
        )
        .duration(
            span_data
                .end_time
                .duration_since(span_data.start_time)
                .unwrap_or_else(|_| Duration::from_secs(0))
                .as_micros() as u64,
        )
        .local_endpoint(local_endpoint)
        .annotations(
            span_data
                .message_events
                .into_iter()
                .map(Into::into)
                .collect(),
        )
        .tags(tags)
        .build()
}

fn map_from_kvs<T>(kvs: T) -> HashMap<String, String>
where
    T: IntoIterator<Item = KeyValue>,
{
    let mut map: HashMap<String, String> = HashMap::new();
    for kv in kvs {
        map.insert(kv.key.into(), kv.value.to_string());
    }
    map
}
<|endoftext|>


<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 https://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

// Box-shadow, etc.
<% data.new_style_struct("Effects", inherited=False) %>

${helpers.predefined_type(
    "opacity",
    "Opacity",
    "1.0",
    animation_value_type="ComputedValue",
    flags="APPLIES_TO_CUE CREATES_STACKING_CONTEXT APPLIES_TO_PLACEHOLDER \
           CAN_ANIMATE_ON_COMPOSITOR",
    spec="https://drafts.csswg.org/css-color/#opacity",
    servo_restyle_damage = "reflow_out_of_flow",
)}

${helpers.predefined_type(
    "box-shadow",
    "BoxShadow",
    None,
    vector=True,
    simple_vector_bindings=True,
    animation_value_type="AnimatedBoxShadowList",
    vector_animation_type="with_zero",
    extra_prefixes="webkit",
    ignored_when_colors_disabled=True,
    flags="APPLIES_TO_FIRST_LETTER",
    spec="https://drafts.csswg.org/css-backgrounds/#box-shadow",
)}

${helpers.predefined_type(
    "clip",
    "ClipRectOrAuto",
    "computed::ClipRectOrAuto::auto()",
    animation_value_type="ComputedValue",
    boxed=True,
    allow_quirks="Yes",
    spec="https://drafts.fxtf.org/css-masking/#clip-property",
)}

${helpers.predefined_type(
    "filter",
    "Filter",
    None,
    vector=True,
    simple_vector_bindings=True,
    gecko_ffi_name="mFilters",
    separator="Space",
    animation_value_type="AnimatedFilterList",
    vector_animation_type="with_zero",
    extra_prefixes="webkit",
    flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
    spec="https://drafts.fxtf.org/filters/#propdef-filter",
)}

${helpers.single_keyword(
    "mix-blend-mode",
    """normal multiply screen overlay darken lighten color-dodge
    color-burn hard-light soft-light difference exclusion hue
    saturation color luminosity""",
    gecko_constant_prefix="NS_STYLE_BLEND",
    animation_value_type="discrete",
    flags="CREATES_STACKING_CONTEXT",
    spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode",
)}
<commit_msg>style: Parse backdrop-filter CSS property.<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 https://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

// Box-shadow, etc.
<% data.new_style_struct("Effects", inherited=False) %>

${helpers.predefined_type(
    "opacity",
    "Opacity",
    "1.0",
    animation_value_type="ComputedValue",
    flags="APPLIES_TO_CUE CREATES_STACKING_CONTEXT APPLIES_TO_PLACEHOLDER \
           CAN_ANIMATE_ON_COMPOSITOR",
    spec="https://drafts.csswg.org/css-color/#opacity",
    servo_restyle_damage = "reflow_out_of_flow",
)}

${helpers.predefined_type(
    "box-shadow",
    "BoxShadow",
    None,
    vector=True,
    simple_vector_bindings=True,
    animation_value_type="AnimatedBoxShadowList",
    vector_animation_type="with_zero",
    extra_prefixes="webkit",
    ignored_when_colors_disabled=True,
    flags="APPLIES_TO_FIRST_LETTER",
    spec="https://drafts.csswg.org/css-backgrounds/#box-shadow",
)}

${helpers.predefined_type(
    "clip",
    "ClipRectOrAuto",
    "computed::ClipRectOrAuto::auto()",
    animation_value_type="ComputedValue",
    boxed=True,
    allow_quirks="Yes",
    spec="https://drafts.fxtf.org/css-masking/#clip-property",
)}

${helpers.predefined_type(
    "filter",
    "Filter",
    None,
    vector=True,
    simple_vector_bindings=True,
    gecko_ffi_name="mFilters",
    separator="Space",
    animation_value_type="AnimatedFilterList",
    vector_animation_type="with_zero",
    extra_prefixes="webkit",
    flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
    spec="https://drafts.fxtf.org/filters/#propdef-filter",
)}

${helpers.predefined_type(
    "backdrop-filter",
    "Filter",
    None,
    vector=True,
    simple_vector_bindings=True,
    gecko_ffi_name="mBackdropFilters",
    separator="Space",
    animation_value_type="AnimatedFilterList",
    vector_animation_type="with_zero",
    flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
    gecko_pref="layout.css.backdrop-filter.enabled",
    spec="https://drafts.fxtf.org/filter-effects-2/#propdef-backdrop-filter",
)}

${helpers.single_keyword(
    "mix-blend-mode",
    """normal multiply screen overlay darken lighten color-dodge
    color-burn hard-light soft-light difference exclusion hue
    saturation color luminosity""",
    gecko_constant_prefix="NS_STYLE_BLEND",
    animation_value_type="discrete",
    flags="CREATES_STACKING_CONTEXT",
    spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode",
)}
<|endoftext|>


<commit_before>extern crate scrabble_score;

use scrabble_score::*;

#[test]
fn a_is_worth_one_point() {
    assert_eq!(score("a"), 1);
}

#[test]
#[ignore]
fn scoring_is_case_insensitive() {
    assert_eq!(score("A"), 1);
}

#[test]
#[ignore]
fn f_is_worth_four() {
    assert_eq!(score("f"), 4);
}

#[test]
#[ignore]
fn two_one_point_letters_make_a_two_point_word() {
    assert_eq!(score("at"), 2);
}

#[test]
#[ignore]
fn three_letter_word() {
    assert_eq!(score("zoo"), 12);
}

#[test]
#[ignore]
fn medium_word() {
    assert_eq!(score("street"), 6);
}

#[test]
#[ignore]
fn longer_words_with_valuable_letters() {
    assert_eq!(score("quirky"), 22);
}

#[test]
#[ignore]
fn long_mixed_case_word() {
    assert_eq!(score("OxyphenButazone"), 41);
}

#[test]
#[ignore]
fn non_english_scrabble_letters_do_not_score() {
    assert_eq!(score("pinata"), 8);
    assert_eq!(score("piñata"), 7);
}

#[test]
#[ignore]
fn empty_words_are_worth_zero() {
    assert_eq!(score(""), 0);
}

#[test]
#[ignore]
fn all_letters_work() {
    assert_eq!(score("abcdefghijklmnopqrstuvwxyz"), 87);
}
<commit_msg>scrabble-score: improve non-english letter tests (#421)<commit_after>extern crate scrabble_score;

use scrabble_score::*;

#[test]
fn a_is_worth_one_point() {
    assert_eq!(score("a"), 1);
}

#[test]
#[ignore]
fn scoring_is_case_insensitive() {
    assert_eq!(score("A"), 1);
}

#[test]
#[ignore]
fn f_is_worth_four() {
    assert_eq!(score("f"), 4);
}

#[test]
#[ignore]
fn two_one_point_letters_make_a_two_point_word() {
    assert_eq!(score("at"), 2);
}

#[test]
#[ignore]
fn three_letter_word() {
    assert_eq!(score("zoo"), 12);
}

#[test]
#[ignore]
fn medium_word() {
    assert_eq!(score("street"), 6);
}

#[test]
#[ignore]
fn longer_words_with_valuable_letters() {
    assert_eq!(score("quirky"), 22);
}

#[test]
#[ignore]
fn long_mixed_case_word() {
    assert_eq!(score("OxyphenButazone"), 41);
}

#[test]
#[ignore]
fn non_english_scrabble_letters_do_not_score() {
    assert_eq!(score("pinata"), 8, "'n' should score 1");
    assert_eq!(score("piñata"), 7, "'ñ' should score 0");
}

#[test]
#[ignore]
fn empty_words_are_worth_zero() {
    assert_eq!(score(""), 0);
}

#[test]
#[ignore]
fn all_letters_work() {
    assert_eq!(score("abcdefghijklmnopqrstuvwxyz"), 87);
}

#[test]
#[ignore]
fn german_letters_do_not_score() {
    assert_eq!(score("STRASSE"), 7, "\"SS\" should score 2");
    assert_eq!(score("STRAßE"), 5, "'ß' should score 0");
}
<|endoftext|>


<commit_before>use std::time::Duration;

use calloop::timer::Timer;
use smithay::{
    backend::{
        renderer::{gles2::Gles2Renderer, Frame, Renderer},
        winit::{self, WinitEvent, WinitEventLoop, WinitGraphicsBackend},
    },
    desktop::space::SurfaceTree,
    reexports::{calloop::EventLoop, wayland_server::protocol::wl_output},
    utils::{Rectangle, Transform},
    wayland::output::{Mode, Output, PhysicalProperties},
};

use slog::Logger;

use crate::CalloopData;

smithay::custom_elements! {
    pub CustomElem<=Gles2Renderer>;
    SurfaceTree=SurfaceTree,
}

pub fn run_winit(
    event_loop: &mut EventLoop<CalloopData>,
    data: &mut CalloopData,
    log: Logger,
) -> Result<(), Box<dyn std::error::Error>> {
    let display = &mut data.display;
    let state = &mut data.state;

    let (mut backend, mut winit) = winit::init(log.clone())?;

    let mode = Mode {
        size: backend.window_size().physical_size,
        refresh: 60_000,
    };

    let (output, _global) = Output::new(
        display,
        "winit".to_string(),
        PhysicalProperties {
            size: (0, 0).into(),
            subpixel: wl_output::Subpixel::Unknown,
            make: "Smithay".into(),
            model: "Winit".into(),
        },
        log.clone(),
    );
    output.change_current_state(
        &mut display.handle(),
        Some(mode),
        Some(wl_output::Transform::Flipped180),
        None,
        Some((0, 0).into()),
    );
    output.set_preferred(mode);

    state.space.map_output(&output, 1.0, (0, 0));

    std::env::set_var("WAYLAND_DISPLAY", "wayland-5");

    let mut full_redraw = 0u8;

    let timer = Timer::<()>::new().unwrap();

    timer.handle().add_timeout(Duration::ZERO, ());
    event_loop.handle().insert_source(timer, move |_, timer, data| {
        // run_test(&mut backend, &mut winit, data, &output);
        winit_dispatch(&mut backend, &mut winit, data, &output, &mut full_redraw).unwrap();
        timer.add_timeout(Duration::from_millis(16), ());
    })?;

    Ok(())
}

pub fn winit_dispatch(
    backend: &mut WinitGraphicsBackend,
    winit: &mut WinitEventLoop,
    data: &mut CalloopData,
    output: &Output,
    full_redraw: &mut u8,
) -> Result<(), Box<dyn std::error::Error>> {
    let display = &mut data.display;
    let state = &mut data.state;

    winit.dispatch_new_events(|event| match event {
        WinitEvent::Resized { size, .. } => {
            output.change_current_state(
                &mut display.handle(),
                Some(Mode {
                    size,
                    refresh: 60_000,
                }),
                None,
                None,
                None,
            );
        }
        WinitEvent::Input(event) => state.process_input_event(display, event),
        _ => (),
    })?;

    *full_redraw = full_redraw.saturating_sub(1);

    let size = backend.window_size().physical_size;
    let damage = Rectangle::from_loc_and_size((0, 0), size);

    backend.bind().ok().and_then(|_| {
        state
            .space
            .render_output::<Gles2Renderer, CustomElem>(
                &mut display.handle(),
                backend.renderer(),
                &output,
                0,
                [0.1, 0.1, 0.1, 1.0],
                &[],
            )
            .unwrap()
    });

    backend.submit(Some(&[damage.to_logical(1)]), 1.0).unwrap();

    state.space.send_frames(
        &mut display.handle(),
        state.start_time.elapsed().as_millis() as u32,
    );

    state.space.refresh(&mut display.handle());
    display.flush_clients()?;

    Ok(())
}
<commit_msg>smallvil: Remove unnecessary custom render element<commit_after>use std::time::Duration;

use calloop::timer::Timer;
use smithay::{
    backend::{
        renderer::{gles2::Gles2Renderer, Frame, Renderer},
        winit::{self, WinitEvent, WinitEventLoop, WinitGraphicsBackend},
    },
    desktop::space::SurfaceTree,
    reexports::{calloop::EventLoop, wayland_server::protocol::wl_output},
    utils::{Rectangle, Transform},
    wayland::output::{Mode, Output, PhysicalProperties},
};

use slog::Logger;

use crate::CalloopData;

pub fn run_winit(
    event_loop: &mut EventLoop<CalloopData>,
    data: &mut CalloopData,
    log: Logger,
) -> Result<(), Box<dyn std::error::Error>> {
    let display = &mut data.display;
    let state = &mut data.state;

    let (mut backend, mut winit) = winit::init(log.clone())?;

    let mode = Mode {
        size: backend.window_size().physical_size,
        refresh: 60_000,
    };

    let (output, _global) = Output::new(
        display,
        "winit".to_string(),
        PhysicalProperties {
            size: (0, 0).into(),
            subpixel: wl_output::Subpixel::Unknown,
            make: "Smithay".into(),
            model: "Winit".into(),
        },
        log.clone(),
    );
    output.change_current_state(
        &mut display.handle(),
        Some(mode),
        Some(wl_output::Transform::Flipped180),
        None,
        Some((0, 0).into()),
    );
    output.set_preferred(mode);

    state.space.map_output(&output, 1.0, (0, 0));

    std::env::set_var("WAYLAND_DISPLAY", "wayland-5");

    let mut full_redraw = 0u8;

    let timer = Timer::<()>::new().unwrap();

    timer.handle().add_timeout(Duration::ZERO, ());
    event_loop.handle().insert_source(timer, move |_, timer, data| {
        // run_test(&mut backend, &mut winit, data, &output);
        winit_dispatch(&mut backend, &mut winit, data, &output, &mut full_redraw).unwrap();
        timer.add_timeout(Duration::from_millis(16), ());
    })?;

    Ok(())
}

pub fn winit_dispatch(
    backend: &mut WinitGraphicsBackend,
    winit: &mut WinitEventLoop,
    data: &mut CalloopData,
    output: &Output,
    full_redraw: &mut u8,
) -> Result<(), Box<dyn std::error::Error>> {
    let display = &mut data.display;
    let state = &mut data.state;

    winit.dispatch_new_events(|event| match event {
        WinitEvent::Resized { size, .. } => {
            output.change_current_state(
                &mut display.handle(),
                Some(Mode {
                    size,
                    refresh: 60_000,
                }),
                None,
                None,
                None,
            );
        }
        WinitEvent::Input(event) => state.process_input_event(display, event),
        _ => (),
    })?;

    *full_redraw = full_redraw.saturating_sub(1);

    let size = backend.window_size().physical_size;
    let damage = Rectangle::from_loc_and_size((0, 0), size);

    backend.bind().ok().and_then(|_| {
        state
            .space
            .render_output::<Gles2Renderer, SurfaceTree>(
                &mut display.handle(),
                backend.renderer(),
                &output,
                0,
                [0.1, 0.1, 0.1, 1.0],
                &[],
            )
            .unwrap()
    });

    backend.submit(Some(&[damage.to_logical(1)]), 1.0).unwrap();

    state.space.send_frames(
        &mut display.handle(),
        state.start_time.elapsed().as_millis() as u32,
    );

    state.space.refresh(&mut display.handle());
    display.flush_clients()?;

    Ok(())
}
<|endoftext|>


<commit_before>extern crate kafka;
extern crate getopts;
extern crate env_logger;

use std::collections::HashMap;
use std::cmp;
use std::env;
use std::process;
use std::io;

use kafka::client::{KafkaClient, FetchOffset};

/// Dumps available topic metadata to stdout.
fn main() {
    env_logger::init().unwrap();

    let cfg = match Config::from_cmdline() {
        Ok(cfg) => cfg,
        Err(e) => {
            println!("{}", e);
            process::exit(1);
        }
    };
    if let Err(e) = dump_metadata(cfg) {
        println!("{}", e);
        process::exit(1);
    }
}

struct Offsets {
    earliest: i64,
    latest: i64,
}

impl Default for Offsets {
    fn default() -> Self {
        Offsets {
            earliest: -1,
            latest: -1,
        }
    }
}

fn dump_metadata(cfg: Config) -> Result<(), String> {
    // ~ establish connection to kafka
    let mut client = KafkaClient::new(cfg.brokers);
    try!(client.load_metadata_all().map_err(|e| e.to_string()));
    // ~ determine the list of topics we're supposed to report about
    let topics = if cfg.topics.is_empty() {
        let topics = client.topics();
        let mut names = Vec::with_capacity(topics.len());
        for topic in topics.names() {
            names.push(topic.to_owned());
        }
        names.sort();
        names
    } else {
        cfg.topics
    };
    // ~ fetch the topics' earliest and latest offsets
    let (topic_width, offsets) = {
        let mut topic_width = 0;
        let mut m = HashMap::with_capacity(topics.len());
        let mut offsets = try!(client.fetch_offsets(&topics, FetchOffset::Latest)
            .map_err(|e| e.to_string()));
        for (topic, offsets) in offsets {
            topic_width = cmp::max(topic_width, topic.len());
            let mut offs = Vec::with_capacity(offsets.len());

            {
                // make sure to init the `offs` table based on the
                // clients metadata since that represents the set of
                // known partitions whereas the offsets we retrieved
                // can be missing some partitions if there are no
                // offsets for them, e.g. partition=0 might have no
                // offsets or might be out of order, while for
                // partition=1 we might have obtained an offset.  this
                // allows us later to use the partition as an index
                // into the table.
                let num_partitions =
                    client.topics().partitions(&topic).map(|ps| ps.len()).unwrap_or(0);
                for _ in 0..num_partitions {
                    offs.push(Offsets::default());
                }
            }

            for offset in offsets {
                offs[offset.partition as usize].latest = offset.offset;
            }

            m.insert(topic, offs);
        }

        offsets = try!(client.fetch_offsets(&topics, FetchOffset::Earliest)
            .map_err(|e| e.to_string()));

        for (topic, offsets) in offsets {
            let mut offs = m.get_mut(&topic).expect("unknown topic");
            for offset in offsets {
                offs[offset.partition as usize].earliest = offset.offset;
            }
        }

        (topic_width + 2, m)
    };
    // ~ produce the output
    let mut out = io::stdout();
    let mut out_buf = String::with_capacity(128);
    let mut fmt_buf = if cfg.size {
        String::with_capacity(30)
    } else {
        String::new()
    };
    // ~ compute the width of the leader-hosts column
    let md = client.topics();
    let host_width = if cfg.host {
        2 +
        topics.iter()
            .flat_map(|t| md.partitions(t).expect("unkonwn topic metadata"))
            .map(|p| p.leader().map(|b| b.host().len()).unwrap_or(0))
            .fold(0, cmp::max)
    } else {
        0
    };
    // ~ print header line
    if cfg.header {
        use std::fmt::Write;
        let _ = write!(out_buf, "{1:0$} {2:4} {3:4}", topic_width, "topic", "p-id", "l-id");
        if cfg.host {
            let _ = write!(out_buf, " {1:>0$}", host_width, "(l-host)");
        }
        let _ = write!(out_buf, " {:>12} {:>12}", "earliest", "latest");
        if cfg.size {
            let _ = write!(out_buf, " {:>12}", "(size)");
        }
        out_buf.push('\n');
        {
            use std::io::Write;
            let _ = out.write_all(out_buf.as_bytes());
        }
    }
    // ~ print each topic partition on its own line
    for (ti, topic) in topics.iter().enumerate() {
        let offsets = &offsets[topic.as_str()];
        let tmd = md.partitions(topic).expect("unknown topic metadata");
        for (pi, p) in offsets.iter().enumerate() {
            use std::fmt::Write;
            out_buf.clear();
            if cfg.topic_separators && ti != 0 && pi == 0 {
                out_buf.push('\n');
            }
            let (leader_id, leader_host) = tmd.partition(pi as i32)
                .expect("unknown topic partition metadata")
                .leader()
                .map(|b| (b.id(), b.host()))
                .unwrap_or((-1, ""));
            let _ = write!(out_buf, "{1:0$} {2:>4} {3:>4}", topic_width, topic, pi, leader_id);
            if cfg.host {
                fmt_buf.clear();
                let _ = write!(fmt_buf, "({})", leader_host);
                let _ = write!(out_buf, " {1:0$}", host_width, fmt_buf);
            }
            let _ = write!(out_buf, " {:>12} {:>12}", p.earliest, p.latest);
            if cfg.size {
                fmt_buf.clear();
                let _ = write!(fmt_buf, "({})", p.latest - p.earliest);
                let _ = write!(out_buf, " {:>12}", fmt_buf);
            }
            out_buf.push('\n');
            {
                use std::io::Write;
                let _ = out.write_all(out_buf.as_bytes());
            }
        }
    }
    Ok(())
}

// --------------------------------------------------------------------

struct Config {
    brokers: Vec<String>,
    topics: Vec<String>,
    header: bool,
    host: bool,
    size: bool,
    topic_separators: bool,
}

impl Config {
    fn from_cmdline() -> Result<Config, String> {
        let args: Vec<_> = env::args().collect();
        let mut opts = getopts::Options::new();
        opts.optflag("h", "help", "Print this help screen");
        opts.optflag("", "no-header", "Don't print headers");
        opts.optopt("", "brokers", "Specify kafka brokers (comma separated)", "HOSTS");
        opts.optopt("", "topics", "Specify topics (comma separated)", "NAMES");
        opts.optflag("", "no-host", "Don't print host:port of leaders");
        opts.optflag("", "no-size", "Don't print partition sizes");
        opts.optflag("", "no-empty-lines", "Don't separate topics by empty lines");
        let m = match opts.parse(&args[1..]) {
            Ok(m) => m,
            Err(e) => return Err(e.to_string()),
        };
        if m.opt_present("help") {
            let brief = format!("{} [options]", &args[0]);
            return Err(opts.usage(&brief));
        }
        Ok(Config {
            brokers: m.opt_str("brokers")
                .unwrap_or_else(|| "localhost:9092".to_owned())
                .split(',')
                .map(|s| s.trim().to_owned())
                .collect(),
            topics: match m.opt_str("topics") {
                None => Vec::new(),
                Some(s) => s.split(',').map(|s| s.trim().to_owned()).collect(),
            },
            header: !m.opt_present("no-header"),
            host: !m.opt_present("no-host"),
            size: !m.opt_present("no-size"),
            topic_separators: !m.opt_present("no-empty-lines"),
        })
    }
}
<commit_msg>#! [example/topic-metadata] Fix panic when dealing with non-existent topics<commit_after>extern crate kafka;
extern crate getopts;
extern crate env_logger;

use std::collections::HashMap;
use std::cmp;
use std::env;
use std::process;
use std::io;

use kafka::client::{KafkaClient, FetchOffset};

/// Dumps available topic metadata to stdout.
fn main() {
    env_logger::init().unwrap();

    let cfg = match Config::from_cmdline() {
        Ok(cfg) => cfg,
        Err(e) => {
            println!("{}", e);
            process::exit(1);
        }
    };
    if let Err(e) = dump_metadata(cfg) {
        println!("{}", e);
        process::exit(1);
    }
}

struct Offsets {
    earliest: i64,
    latest: i64,
}

impl Default for Offsets {
    fn default() -> Self {
        Offsets {
            earliest: -1,
            latest: -1,
        }
    }
}

fn dump_metadata(cfg: Config) -> Result<(), String> {
    // ~ establish connection to kafka
    let mut client = KafkaClient::new(cfg.brokers);
    try!(client.load_metadata_all().map_err(|e| e.to_string()));
    // ~ determine the list of topics we're supposed to report about
    let topics = if cfg.topics.is_empty() {
        let topics = client.topics();
        let mut names = Vec::with_capacity(topics.len());
        for topic in topics.names() {
            names.push(topic.to_owned());
        }
        names.sort();
        names
    } else {
        cfg.topics
    };
    // ~ fetch the topics' earliest and latest offsets
    let (topic_width, offsets) = {
        let mut topic_width = 0;
        let mut m = HashMap::with_capacity(topics.len());
        let mut offsets = try!(client.fetch_offsets(&topics, FetchOffset::Latest)
            .map_err(|e| e.to_string()));
        for (topic, offsets) in offsets {
            topic_width = cmp::max(topic_width, topic.len());
            let mut offs = Vec::with_capacity(offsets.len());

            {
                // make sure to init the `offs` table based on the
                // clients metadata since that represents the set of
                // known partitions whereas the offsets we retrieved
                // can be missing some partitions if there are no
                // offsets for them, e.g. partition=0 might have no
                // offsets or might be out of order, while for
                // partition=1 we might have obtained an offset.  this
                // allows us later to use the partition as an index
                // into the table.
                let num_partitions =
                    client.topics().partitions(&topic).map(|ps| ps.len()).unwrap_or(0);
                for _ in 0..num_partitions {
                    offs.push(Offsets::default());
                }
            }

            for offset in offsets {
                offs[offset.partition as usize].latest = offset.offset;
            }

            m.insert(topic, offs);
        }

        offsets = try!(client.fetch_offsets(&topics, FetchOffset::Earliest)
            .map_err(|e| e.to_string()));

        for (topic, offsets) in offsets {
            let mut offs = m.get_mut(&topic).expect("unknown topic");
            for offset in offsets {
                offs[offset.partition as usize].earliest = offset.offset;
            }
        }

        (topic_width + 2, m)
    };
    // ~ produce the output
    let mut out = io::stdout();
    let mut out_buf = String::with_capacity(128);
    let mut fmt_buf = if cfg.size {
        String::with_capacity(30)
    } else {
        String::new()
    };
    // ~ compute the width of the leader-hosts column
    let md = client.topics();
    let host_width = if cfg.host {
        2 +
        topics.iter()
            .filter_map(|t| md.partitions(t))
            .flat_map(|t| t)
            .map(|p| p.leader().map(|b| b.host().len()).unwrap_or(0))
            .fold(0, cmp::max)
    } else {
        0
    };
    // ~ print header line
    if cfg.header {
        use std::fmt::Write;
        let _ = write!(out_buf, "{1:0$} {2:4} {3:4}", topic_width, "topic", "p-id", "l-id");
        if cfg.host {
            let _ = write!(out_buf, " {1:>0$}", host_width, "(l-host)");
        }
        let _ = write!(out_buf, " {:>12} {:>12}", "earliest", "latest");
        if cfg.size {
            let _ = write!(out_buf, " {:>12}", "(size)");
        }
        out_buf.push('\n');
        {
            use std::io::Write;
            let _ = out.write_all(out_buf.as_bytes());
        }
    }
    // ~ print each topic partition on its own line
    for (ti, topic) in topics.iter().enumerate() {
        match md.partitions(topic) {
            None => {
                use std::fmt::Write;
                out_buf.clear();
                if cfg.topic_separators && ti != 0 {
                    out_buf.push('\n');
                }
                let _ = write!(out_buf, "{1:0$} - not available!\n", topic_width, topic);
                {
                    use std::io::Write;
                    let _ = out.write_all(out_buf.as_bytes());
                }
            }
            Some(tmd) => {
                let offsets = &offsets[topic.as_str()];
                for (pi, p) in offsets.iter().enumerate() {
                    use std::fmt::Write;
                    out_buf.clear();
                    if cfg.topic_separators && ti != 0 && pi == 0 {
                        out_buf.push('\n');
                    }
                    let (leader_id, leader_host) = tmd.partition(pi as i32)
                        .expect("unknown topic partition metadata")
                        .leader()
                        .map(|b| (b.id(), b.host()))
                        .unwrap_or((-1, ""));
                    let _ = write!(out_buf, "{1:0$} {2:>4} {3:>4}", topic_width, topic, pi, leader_id);
                    if cfg.host {
                        fmt_buf.clear();
                        let _ = write!(fmt_buf, "({})", leader_host);
                        let _ = write!(out_buf, " {1:0$}", host_width, fmt_buf);
                    }
                    let _ = write!(out_buf, " {:>12} {:>12}", p.earliest, p.latest);
                    if cfg.size {
                        fmt_buf.clear();
                        let _ = write!(fmt_buf, "({})", p.latest - p.earliest);
                        let _ = write!(out_buf, " {:>12}", fmt_buf);
                    }
                    out_buf.push('\n');
                    {
                        use std::io::Write;
                        let _ = out.write_all(out_buf.as_bytes());
                    }
                }
            }
        }
    }
    Ok(())
}

// --------------------------------------------------------------------

struct Config {
    brokers: Vec<String>,
    topics: Vec<String>,
    header: bool,
    host: bool,
    size: bool,
    topic_separators: bool,
}

impl Config {
    fn from_cmdline() -> Result<Config, String> {
        let args: Vec<_> = env::args().collect();
        let mut opts = getopts::Options::new();
        opts.optflag("h", "help", "Print this help screen");
        opts.optflag("", "no-header", "Don't print headers");
        opts.optopt("", "brokers", "Specify kafka brokers (comma separated)", "HOSTS");
        opts.optopt("", "topics", "Specify topics (comma separated)", "NAMES");
        opts.optflag("", "no-host", "Don't print host:port of leaders");
        opts.optflag("", "no-size", "Don't print partition sizes");
        opts.optflag("", "no-empty-lines", "Don't separate topics by empty lines");
        let m = match opts.parse(&args[1..]) {
            Ok(m) => m,
            Err(e) => return Err(e.to_string()),
        };
        if m.opt_present("help") {
            let brief = format!("{} [options]", &args[0]);
            return Err(opts.usage(&brief));
        }
        Ok(Config {
            brokers: m.opt_str("brokers")
                .unwrap_or_else(|| "localhost:9092".to_owned())
                .split(',')
                .map(|s| s.trim().to_owned())
                .collect(),
            topics: match m.opt_str("topics") {
                None => Vec::new(),
                Some(s) => s.split(',').map(|s| s.trim().to_owned()).collect(),
            },
            header: !m.opt_present("no-header"),
            host: !m.opt_present("no-host"),
            size: !m.opt_present("no-size"),
            topic_separators: !m.opt_present("no-empty-lines"),
        })
    }
}
<|endoftext|>


<commit_before>
#![feature(start)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_variables)]
#![allow(non_snake_case)]

extern crate num;
extern crate libc;

extern crate glfw;
extern crate gl;
extern crate nanovg;

use glfw::Context;
use std::cell::Cell; // for glfw error count
use nanovg::Ctx;

/// evaluate the expression, then check for GL error.
macro_rules! glcheck {
    ($e: expr) => (
        {
            $e;
            assert_eq!(unsafe {gl::GetError()}, 0);
        }
    )
}

mod perf;
mod demo;

/// give GLFW a way to report errors, and count them.
fn error_callback(_: glfw::Error, description: String, error_count: &Cell<usize>) {
    println!("GLFW error {}: {}", error_count.get(), description);
    error_count.set(error_count.get() + 1);
}

fn init_gl() {
    glcheck!(unsafe {gl::FrontFace(gl::CCW)});
    glcheck!(unsafe {gl::Enable(gl::DEPTH_TEST)});
    glcheck!(unsafe {gl::Enable(gl::SCISSOR_TEST)});
    glcheck!(unsafe {gl::DepthFunc(gl::LEQUAL)});
    glcheck!(unsafe {gl::FrontFace(gl::CCW)});
    glcheck!(unsafe {gl::Enable(gl::CULL_FACE)});
    glcheck!(unsafe {gl::CullFace(gl::BACK)});
}

static mut blowup: bool = false;
static mut screenshot: bool = false;
static mut premult: bool = false;

fn main()
{
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

	// set up GLFW error callback, with an error-counter
	glfw.set_error_callback(Some(
	    glfw::Callback {
	        f: error_callback as fn(glfw::Error, String, &Cell<usize>),
	        data: Cell::new(0),
	    }
	));

	glfw.window_hint(glfw::WindowHint::ContextVersion(3, 2));
 	glfw.window_hint(glfw::WindowHint::OpenglForwardCompat(true));
 	glfw.window_hint(glfw::WindowHint::OpenglProfile(glfw::OpenGlProfileHint::Core));
 	glfw.window_hint(glfw::WindowHint::OpenglDebugContext(true));

    let (mut window, events) = glfw.create_window(1100, 800, "NanoVG GL3 Rust demo", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

	// window.set_key_callback(key);
    window.set_key_polling(true);

    window.make_current();

    // use glfw to load GL function pointers
    glcheck!(gl::load_with(|name| window.get_proc_address(name)));
    init_gl();

   	let vg: nanovg::Ctx = nanovg::Ctx::create_gl3(nanovg::ANTIALIAS | nanovg::STENCIL_STROKES);
   	//assert!(!vg.ptr.is_null());

    let data = demo::DemoData::load(&vg, "../../res");

//    return test_linebreaks(vg);

	glfw.set_swap_interval(0);

	glfw.set_time(0.0);
	let mut prevt = glfw.get_time();

	let mut fps = perf::PerfGraph::init(perf::Style::FPS, "Frame Time");

    while !window.should_close()
    {
    	let t: f64 = glfw.get_time();
    	let dt: f64 = t - prevt;
    	prevt = t;
    	fps.update(dt);

        let (mx, my) = window.get_cursor_pos(); // (f64,f64)
        let (winWidth, winHeight) = window.get_size();  // (i32,i32)
        let (fbWidth, fbHeight) = window.get_framebuffer_size();
        // Calculate pixel ration for hi-dpi devices.
        let pxRatio = fbWidth as f32 / winWidth as f32;

        // Update and render
        glcheck!(unsafe {gl::Viewport(0, 0, fbWidth, fbHeight)});
        if unsafe {premult} {
            glcheck!(unsafe {gl::ClearColor(0.0, 0.0, 0.0, 0.0)});
        } else {
            glcheck!(unsafe {gl::ClearColor(0.3, 0.3, 0.32, 1.0)});
        }
        glcheck!(unsafe {gl::Clear(gl::COLOR_BUFFER_BIT|gl::DEPTH_BUFFER_BIT|gl::STENCIL_BUFFER_BIT)});

        glcheck!(unsafe {gl::Enable(gl::BLEND)});
        glcheck!(unsafe {gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA)});
        glcheck!(unsafe {gl::Enable(gl::CULL_FACE)});
        glcheck!(unsafe {gl::Disable(gl::DEPTH_TEST)});

        vg.begin_frame(winWidth, winHeight, pxRatio as f32);

        unsafe { demo::render_demo(&vg, mx as f32,my as f32, winWidth as f32,winHeight as f32, t as f32, blowup, &data); }
        fps.render(&vg, 5.0, 5.0);

        vg.end_frame();

        unsafe {gl::Enable(gl::DEPTH_TEST);}
        unsafe {
	        if screenshot {
	        	screenshot = false;
	        	demo::save_screenshot(fbWidth as u32, fbHeight as u32, premult, "dump.png");
	        }
        }

    	window.swap_buffers();

        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            handle_window_event(&mut window, event);
        }
    }
}

fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
    match event {
        glfw::WindowEvent::Key(glfw::Key::Escape, _, glfw::Action::Press, _) => {
            window.set_should_close(true)
        }
        glfw::WindowEvent::Key(glfw::Key::Space, _, glfw::Action::Press, _) => {
            unsafe {blowup = !blowup};
        }
        glfw::WindowEvent::Key(glfw::Key::S, _, glfw::Action::Press, _) => {
            unsafe {screenshot = true};
        }
        glfw::WindowEvent::Key(glfw::Key::P, _, glfw::Action::Press, _) => {
            unsafe {premult = !premult};
        }
        _ => {}
    }
}

//// think linebreaks api needs some love
//fn test_linebreaks(vg:Ctx) {
//    let x=0.0; let y=0.0;
//    let width = 120.0;
//
//    let text = "This is longer chunk of text.\n  \n  Would have used lorem ipsum but she    was busy jumping over the lazy dog with the fox and all the men who came to the aid of the party.";
//    //let text = "01234 6789 1234 6789 1234 6789 123456789012345678901234567890123456789012345678901234567890123456789";
//
//
//    // The text break API can be used to fill a large buffer of rows,
//    // or to iterate over the text just few lines (or just one) at a time.
//    // The "next" variable of the last returned item tells where to continue.
//    let mut start: uint = 0;    // byte pos in utf8 'text' str
//    let end: uint = text.len(); // exclusive
//    'chunks: loop {
//        let text = text.slice(start, end);
//
//println!("{}", text);
//
//        let rows = vg.text_break_lines(text, width, 3);
//        let nrows = rows.len();
//        if nrows == 0 { break 'chunks; }
//        for i in range(0, nrows) {
//            let row = &rows[i];
//            let line = text.slice(row.start_index(), row.end_index());
//
//println!("i: {}  st: {}, en: {}  \t {} \tnext: {}", i, row.start_index(), row.end_index(), line, row.next_index());
//
//        }
//        // Keep going...
//        start += rows[nrows-1].next_index();
//    }
//}
<commit_msg>Fixed warnings from new Rust nightly.<commit_after>
#![feature(core, std_misc, libc, collections)] // unstable features, should be able to remove this post-rust-1.0
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_variables)]
#![allow(non_snake_case)]

extern crate num;
extern crate libc;

extern crate glfw;
extern crate gl;
extern crate nanovg;

use glfw::Context;
use std::cell::Cell; // for glfw error count
use nanovg::Ctx;

/// evaluate the expression, then check for GL error.
macro_rules! glcheck {
    ($e: expr) => (
        {
            $e;
            assert_eq!(unsafe {gl::GetError()}, 0);
        }
    )
}

mod perf;
mod demo;

/// give GLFW a way to report errors, and count them.
fn error_callback(_: glfw::Error, description: String, error_count: &Cell<usize>) {
    println!("GLFW error {}: {}", error_count.get(), description);
    error_count.set(error_count.get() + 1);
}

fn init_gl() {
    glcheck!(unsafe {gl::FrontFace(gl::CCW)});
    glcheck!(unsafe {gl::Enable(gl::DEPTH_TEST)});
    glcheck!(unsafe {gl::Enable(gl::SCISSOR_TEST)});
    glcheck!(unsafe {gl::DepthFunc(gl::LEQUAL)});
    glcheck!(unsafe {gl::FrontFace(gl::CCW)});
    glcheck!(unsafe {gl::Enable(gl::CULL_FACE)});
    glcheck!(unsafe {gl::CullFace(gl::BACK)});
}

static mut blowup: bool = false;
static mut screenshot: bool = false;
static mut premult: bool = false;

fn main()
{
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

	// set up GLFW error callback, with an error-counter
	glfw.set_error_callback(Some(
	    glfw::Callback {
	        f: error_callback as fn(glfw::Error, String, &Cell<usize>),
	        data: Cell::new(0),
	    }
	));

	glfw.window_hint(glfw::WindowHint::ContextVersion(3, 2));
 	glfw.window_hint(glfw::WindowHint::OpenglForwardCompat(true));
 	glfw.window_hint(glfw::WindowHint::OpenglProfile(glfw::OpenGlProfileHint::Core));
 	glfw.window_hint(glfw::WindowHint::OpenglDebugContext(true));

    let (mut window, events) = glfw.create_window(1100, 800, "NanoVG GL3 Rust demo", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

	// window.set_key_callback(key);
    window.set_key_polling(true);

    window.make_current();

    // use glfw to load GL function pointers
    glcheck!(gl::load_with(|name| window.get_proc_address(name)));
    init_gl();

   	let vg: nanovg::Ctx = nanovg::Ctx::create_gl3(nanovg::ANTIALIAS | nanovg::STENCIL_STROKES);
   	//assert!(!vg.ptr.is_null());

    let data = demo::DemoData::load(&vg, "../../res");

//    return test_linebreaks(vg);

	glfw.set_swap_interval(0);

	glfw.set_time(0.0);
	let mut prevt = glfw.get_time();

	let mut fps = perf::PerfGraph::init(perf::Style::FPS, "Frame Time");

    while !window.should_close()
    {
    	let t: f64 = glfw.get_time();
    	let dt: f64 = t - prevt;
    	prevt = t;
    	fps.update(dt);

        let (mx, my) = window.get_cursor_pos(); // (f64,f64)
        let (winWidth, winHeight) = window.get_size();  // (i32,i32)
        let (fbWidth, fbHeight) = window.get_framebuffer_size();
        // Calculate pixel ration for hi-dpi devices.
        let pxRatio = fbWidth as f32 / winWidth as f32;

        // Update and render
        glcheck!(unsafe {gl::Viewport(0, 0, fbWidth, fbHeight)});
        if unsafe {premult} {
            glcheck!(unsafe {gl::ClearColor(0.0, 0.0, 0.0, 0.0)});
        } else {
            glcheck!(unsafe {gl::ClearColor(0.3, 0.3, 0.32, 1.0)});
        }
        glcheck!(unsafe {gl::Clear(gl::COLOR_BUFFER_BIT|gl::DEPTH_BUFFER_BIT|gl::STENCIL_BUFFER_BIT)});

        glcheck!(unsafe {gl::Enable(gl::BLEND)});
        glcheck!(unsafe {gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA)});
        glcheck!(unsafe {gl::Enable(gl::CULL_FACE)});
        glcheck!(unsafe {gl::Disable(gl::DEPTH_TEST)});

        vg.begin_frame(winWidth, winHeight, pxRatio as f32);

        unsafe { demo::render_demo(&vg, mx as f32,my as f32, winWidth as f32,winHeight as f32, t as f32, blowup, &data); }
        fps.render(&vg, 5.0, 5.0);

        vg.end_frame();

        unsafe {gl::Enable(gl::DEPTH_TEST);}
        unsafe {
	        if screenshot {
	        	screenshot = false;
	        	demo::save_screenshot(fbWidth as u32, fbHeight as u32, premult, "dump.png");
	        }
        }

    	window.swap_buffers();

        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            handle_window_event(&mut window, event);
        }
    }
}

fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
    match event {
        glfw::WindowEvent::Key(glfw::Key::Escape, _, glfw::Action::Press, _) => {
            window.set_should_close(true)
        }
        glfw::WindowEvent::Key(glfw::Key::Space, _, glfw::Action::Press, _) => {
            unsafe {blowup = !blowup};
        }
        glfw::WindowEvent::Key(glfw::Key::S, _, glfw::Action::Press, _) => {
            unsafe {screenshot = true};
        }
        glfw::WindowEvent::Key(glfw::Key::P, _, glfw::Action::Press, _) => {
            unsafe {premult = !premult};
        }
        _ => {}
    }
}

//// think linebreaks api needs some love
//fn test_linebreaks(vg:Ctx) {
//    let x=0.0; let y=0.0;
//    let width = 120.0;
//
//    let text = "This is longer chunk of text.\n  \n  Would have used lorem ipsum but she    was busy jumping over the lazy dog with the fox and all the men who came to the aid of the party.";
//    //let text = "01234 6789 1234 6789 1234 6789 123456789012345678901234567890123456789012345678901234567890123456789";
//
//
//    // The text break API can be used to fill a large buffer of rows,
//    // or to iterate over the text just few lines (or just one) at a time.
//    // The "next" variable of the last returned item tells where to continue.
//    let mut start: uint = 0;    // byte pos in utf8 'text' str
//    let end: uint = text.len(); // exclusive
//    'chunks: loop {
//        let text = text.slice(start, end);
//
//println!("{}", text);
//
//        let rows = vg.text_break_lines(text, width, 3);
//        let nrows = rows.len();
//        if nrows == 0 { break 'chunks; }
//        for i in range(0, nrows) {
//            let row = &rows[i];
//            let line = text.slice(row.start_index(), row.end_index());
//
//println!("i: {}  st: {}, en: {}  \t {} \tnext: {}", i, row.start_index(), row.end_index(), line, row.next_index());
//
//        }
//        // Keep going...
//        start += rows[nrows-1].next_index();
//    }
//}
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::io;

use bytes::BytesMut;
use byteorder::{LittleEndian, ByteOrder};
use tokio_io::codec::{Decoder, Encoder};

use messages::{HEADER_LENGTH, MessageBuffer, RawMessage};
use super::error::other_error;

#[derive(Debug)]
pub struct MessagesCodec {
    /// Maximum message length (in bytes), gets populated from `ConsensusConfig`.
    max_message_len: u32,
}

impl MessagesCodec {
    pub fn new(max_message_len: u32) -> MessagesCodec {
        MessagesCodec { max_message_len }
    }
}

impl Decoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        // Read header
        if buf.len() < HEADER_LENGTH {
            return Ok(None);
        }
        // Check payload len
        let total_len = LittleEndian::read_u32(&buf[6..10]) as usize;

        if total_len as u32 > self.max_message_len {
            return Err(other_error(format!(
                "Received message is too long: {}, maximum allowed length is {} bytes",
                total_len,
                self.max_message_len,
            )));
        }

        if total_len < HEADER_LENGTH {
            return Err(other_error(format!(
                "Received malicious message with insufficient \
                size in header: {}, expected header size {}",
                total_len,
                HEADER_LENGTH
            )));
        }

        // Read message
        if buf.len() >= total_len {
            let data = buf.split_to(total_len).to_vec();
            let raw = RawMessage::new(MessageBuffer::from_vec(data));
            return Ok(Some(raw));
        }
        Ok(None)
    }
}

impl Encoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        buf.extend_from_slice(msg.as_ref());
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::MessagesCodec;

    use messages::{MessageBuffer, RawMessage};
    use bytes::BytesMut;
    use tokio_io::codec::Decoder;
    #[test]
    fn decode_message_valid_header_size() {
        let data = vec![0u8, 0, 0, 0, 0, 0, 10, 0, 0, 0];
        let mut bytes: BytesMut = data.as_slice().into();
        let mut codec = MessagesCodec;
        match codec.decode(&mut bytes) {
            Ok(Some(ref r)) if r == &RawMessage::new(MessageBuffer::from_vec(data)) => {}
            _ => panic!("Wrong input"),
        };
    }

    #[test]
    fn decode_message_small_size_in_header() {
        let data = vec![0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let mut bytes: BytesMut = data.as_slice().into();
        let mut codec = MessagesCodec;
        assert!(codec.decode(&mut bytes).is_err());
    }
}
<commit_msg>Fix tests<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::io;

use bytes::BytesMut;
use byteorder::{LittleEndian, ByteOrder};
use tokio_io::codec::{Decoder, Encoder};

use messages::{HEADER_LENGTH, MessageBuffer, RawMessage};
use super::error::other_error;

#[derive(Debug)]
pub struct MessagesCodec {
    /// Maximum message length (in bytes), gets populated from `ConsensusConfig`.
    max_message_len: u32,
}

impl MessagesCodec {
    pub fn new(max_message_len: u32) -> MessagesCodec {
        MessagesCodec { max_message_len }
    }
}

impl Decoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        // Read header
        if buf.len() < HEADER_LENGTH {
            return Ok(None);
        }
        // Check payload len
        let total_len = LittleEndian::read_u32(&buf[6..10]) as usize;

        if total_len as u32 > self.max_message_len {
            return Err(other_error(format!(
                "Received message is too long: {}, maximum allowed length is {} bytes",
                total_len,
                self.max_message_len,
            )));
        }

        if total_len < HEADER_LENGTH {
            return Err(other_error(format!(
                "Received malicious message with insufficient \
                size in header: {}, expected header size {}",
                total_len,
                HEADER_LENGTH
            )));
        }

        // Read message
        if buf.len() >= total_len {
            let data = buf.split_to(total_len).to_vec();
            let raw = RawMessage::new(MessageBuffer::from_vec(data));
            return Ok(Some(raw));
        }
        Ok(None)
    }
}

impl Encoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        buf.extend_from_slice(msg.as_ref());
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::MessagesCodec;

    use messages::{MessageBuffer, RawMessage};
    use bytes::BytesMut;
    use tokio_io::codec::Decoder;

    #[test]
    fn decode_message_valid_header_size() {
        let data = vec![0u8, 0, 0, 0, 0, 0, 10, 0, 0, 0];
        let mut bytes: BytesMut = data.as_slice().into();
        let mut codec = MessagesCodec { max_message_len: 10000 };
        match codec.decode(&mut bytes) {
            Ok(Some(ref r)) if r == &RawMessage::new(MessageBuffer::from_vec(data)) => {}
            _ => panic!("Wrong input"),
        };
    }

    #[test]
    fn decode_message_small_size_in_header() {
        let data = vec![0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let mut bytes: BytesMut = data.as_slice().into();
        let mut codec = MessagesCodec { max_message_len: 10000 };
        assert!(codec.decode(&mut bytes).is_err());
    }
}
<|endoftext|>


<commit_before>#![feature(repr_simd, platform_intrinsics)]

#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
struct i32x2(i32, i32);
#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
struct i32x3(i32, i32, i32);
#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
struct i32x4(i32, i32, i32, i32);
#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
struct i32x8(i32, i32, i32, i32,
             i32, i32, i32, i32);

fn main() {
    let _x2 = i32x2(20, 21);
    let _x3 = i32x3(30, 31, 32);
    let _x4 = i32x4(40, 41, 42, 43);
    let _x8 = i32x8(80, 81, 82, 83, 84, 85, 86, 87);

    let _y2 = i32x2(120, 121);
    let _y3 = i32x3(130, 131, 132);
    let _y4 = i32x4(140, 141, 142, 143);
    let _y8 = i32x8(180, 181, 182, 183, 184, 185, 186, 187);

}
<commit_msg>Remove non-power-of-two SIMD vectors<commit_after>#![feature(repr_simd, platform_intrinsics)]

#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
struct i32x2(i32, i32);
#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
struct i32x4(i32, i32, i32, i32);
#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
struct i32x8(i32, i32, i32, i32,
             i32, i32, i32, i32);

fn main() {
    let _x2 = i32x2(20, 21);
    let _x4 = i32x4(40, 41, 42, 43);
    let _x8 = i32x8(80, 81, 82, 83, 84, 85, 86, 87);

    let _y2 = i32x2(120, 121);
    let _y4 = i32x4(140, 141, 142, 143);
    let _y8 = i32x8(180, 181, 182, 183, 184, 185, 186, 187);

}
<|endoftext|>