<commit_before>use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::higher;
use clippy_utils::is_lang_ctor;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{eq_expr_value, path_to_local, path_to_local_id};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultOk};
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, PatKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;

declare_clippy_lint! {
    /// ### What it does
    /// Checks for expressions that could be replaced by the question mark operator.
    ///
    /// ### Why is this bad?
    /// Question mark usage is more idiomatic.
    ///
    /// ### Example
    /// ```ignore
    /// if option.is_none() {
    ///     return None;
    /// }
    /// ```
    ///
    /// Could be written:
    ///
    /// ```ignore
    /// option?;
    /// ```
    pub QUESTION_MARK,
    style,
    "checks for expressions that could be replaced by the question mark operator"
}

declare_lint_pass!(QuestionMark => [QUESTION_MARK]);

impl QuestionMark {
    /// Checks if the given expression on the given context matches the following structure:
    ///
    /// ```ignore
    /// if option.is_none() {
    ///    return None;
    /// }
    /// ```
    ///
    /// ```ignore
    /// if result.is_err() {
    ///     return result;
    /// }
    /// ```
    ///
    /// If it matches, it will suggest to use the question mark operator instead
    fn check_is_none_or_err_and_early_return(cx: &LateContext<'_>, expr: &Expr<'_>) {
        if_chain! {
            if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr);
            if let ExprKind::MethodCall(segment, _, args, _) = &cond.kind;
            if let Some(subject) = args.get(0);
            if (Self::option_check_and_early_return(cx, subject, then) && segment.ident.name == sym!(is_none)) ||
                (Self::result_check_and_early_return(cx, subject, then) && segment.ident.name == sym!(is_err));
            then {
                let mut applicability = Applicability::MachineApplicable;
                let receiver_str = &Sugg::hir_with_applicability(cx, subject, "..", &mut applicability);
                let mut replacement: Option<String> = None;
                if let Some(else_inner) = r#else {
                    if_chain! {
                        if let ExprKind::Block(block, None) = &else_inner.kind;
                        if block.stmts.is_empty();
                        if let Some(block_expr) = &block.expr;
                        if eq_expr_value(cx, subject, block_expr);
                        then {
                            replacement = Some(format!("Some({}?)", receiver_str));
                        }
                    }
                } else if Self::moves_by_default(cx, subject)
                    && !matches!(subject.kind, ExprKind::Call(..) | ExprKind::MethodCall(..))
                {
                    replacement = Some(format!("{}.as_ref()?;", receiver_str));
                } else {
                    replacement = Some(format!("{}?;", receiver_str));
                }

                if let Some(replacement_str) = replacement {
                    span_lint_and_sugg(
                        cx,
                        QUESTION_MARK,
                        expr.span,
                        "this block may be rewritten with the `?` operator",
                        "replace it with",
                        replacement_str,
                        applicability,
                    );
                }
            }
        }
    }

    fn check_if_let_some_or_err_and_early_return(cx: &LateContext<'_>, expr: &Expr<'_>) {
        if_chain! {
            if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else: Some(if_else) })
                = higher::IfLet::hir(cx, expr);
            if let PatKind::TupleStruct(ref path1, fields, None) = let_pat.kind;
            if (Self::option_check_and_early_return(cx, let_expr, if_else) && is_lang_ctor(cx, path1, OptionSome)) ||
                (Self::result_check_and_early_return(cx, let_expr, if_else) && is_lang_ctor(cx, path1, ResultOk));

            if let PatKind::Binding(annot, bind_id, _, _) = fields[0].kind;
            let by_ref = matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut);
            if let ExprKind::Block(block, None) = if_then.kind;
            if block.stmts.is_empty();
            if let Some(trailing_expr) = &block.expr;
            if path_to_local_id(trailing_expr, bind_id);
            then {
                let mut applicability = Applicability::MachineApplicable;
                let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
                let replacement = format!("{}{}?", receiver_str, if by_ref { ".as_ref()" } else { "" },);

                span_lint_and_sugg(
                    cx,
                    QUESTION_MARK,
                    expr.span,
                    "this if-let-else may be rewritten with the `?` operator",
                    "replace it with",
                    replacement,
                    applicability,
                );
            }
        }
    }

    fn result_check_and_early_return(cx: &LateContext<'_>, expr: &Expr<'_>, nested_expr: &Expr<'_>) -> bool {
        Self::is_result(cx, expr) && Self::expression_returns_unmodified_err(cx, nested_expr, expr)
    }

    fn option_check_and_early_return(cx: &LateContext<'_>, expr: &Expr<'_>, nested_expr: &Expr<'_>) -> bool {
        Self::is_option(cx, expr) && Self::expression_returns_none(cx, nested_expr)
    }

    fn moves_by_default(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool {
        let expr_ty = cx.typeck_results().expr_ty(expression);

        !expr_ty.is_copy_modulo_regions(cx.tcx.at(expression.span), cx.param_env)
    }

    fn is_option(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool {
        let expr_ty = cx.typeck_results().expr_ty(expression);

        is_type_diagnostic_item(cx, expr_ty, sym::Option)
    }

    fn is_result(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool {
        let expr_ty = cx.typeck_results().expr_ty(expression);

        is_type_diagnostic_item(cx, expr_ty, sym::Result)
    }

    fn expression_returns_none(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool {
        match expression.kind {
            ExprKind::Block(block, _) => {
                if let Some(return_expression) = Self::return_expression(block) {
                    return Self::expression_returns_none(cx, return_expression);
                }

                false
            },
            ExprKind::Ret(Some(expr)) => Self::expression_returns_none(cx, expr),
            ExprKind::Path(ref qpath) => is_lang_ctor(cx, qpath, OptionNone),
            _ => false,
        }
    }

    fn expression_returns_unmodified_err(cx: &LateContext<'_>, expression: &Expr<'_>, cond_expr: &Expr<'_>) -> bool {
        match expression.kind {
            ExprKind::Block(block, _) => {
                if let Some(return_expression) = Self::return_expression(block) {
                    return Self::expression_returns_unmodified_err(cx, return_expression, cond_expr);
                }

                false
            },
            ExprKind::Ret(Some(expr)) => Self::expression_returns_unmodified_err(cx, expr, cond_expr),
            ExprKind::Path(_) => path_to_local(expression) == path_to_local(cond_expr),
            _ => false,
        }
    }

    fn return_expression<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> {
        // Check if last expression is a return statement. Then, return the expression
        if_chain! {
            if block.stmts.len() == 1;
            if let Some(expr) = block.stmts.iter().last();
            if let StmtKind::Semi(expr) = expr.kind;
            if let ExprKind::Ret(Some(ret_expr)) = expr.kind;

            then {
                return Some(ret_expr);
            }
        }

        // Check for `return` without a semicolon.
        if_chain! {
            if block.stmts.is_empty();
            if let Some(ExprKind::Ret(Some(ret_expr))) = block.expr.as_ref().map(|e| &e.kind);
            then {
                return Some(ret_expr);
            }
        }

        None
    }
}

impl<'tcx> LateLintPass<'tcx> for QuestionMark {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
        Self::check_is_none_or_err_and_early_return(cx, expr);
        Self::check_if_let_some_or_err_and_early_return(cx, expr);
    }
}
<commit_msg>Rename variable name in `question_mark`<commit_after>use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::higher;
use clippy_utils::is_lang_ctor;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{eq_expr_value, path_to_local, path_to_local_id};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultOk};
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, PatKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;

declare_clippy_lint! {
    /// ### What it does
    /// Checks for expressions that could be replaced by the question mark operator.
    ///
    /// ### Why is this bad?
    /// Question mark usage is more idiomatic.
    ///
    /// ### Example
    /// ```ignore
    /// if option.is_none() {
    ///     return None;
    /// }
    /// ```
    ///
    /// Could be written:
    ///
    /// ```ignore
    /// option?;
    /// ```
    pub QUESTION_MARK,
    style,
    "checks for expressions that could be replaced by the question mark operator"
}

declare_lint_pass!(QuestionMark => [QUESTION_MARK]);

impl QuestionMark {
    /// Checks if the given expression on the given context matches the following structure:
    ///
    /// ```ignore
    /// if option.is_none() {
    ///    return None;
    /// }
    /// ```
    ///
    /// ```ignore
    /// if result.is_err() {
    ///     return result;
    /// }
    /// ```
    ///
    /// If it matches, it will suggest to use the question mark operator instead
    fn check_is_none_or_err_and_early_return(cx: &LateContext<'_>, expr: &Expr<'_>) {
        if_chain! {
            if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr);
            if let ExprKind::MethodCall(segment, _, args, _) = &cond.kind;
            if let Some(subject) = args.get(0);
            if (Self::option_check_and_early_return(cx, subject, then) && segment.ident.name == sym!(is_none)) ||
                (Self::result_check_and_early_return(cx, subject, then) && segment.ident.name == sym!(is_err));
            then {
                let mut applicability = Applicability::MachineApplicable;
                let receiver_str = &Sugg::hir_with_applicability(cx, subject, "..", &mut applicability);
                let mut replacement: Option<String> = None;
                if let Some(else_inner) = r#else {
                    if_chain! {
                        if let ExprKind::Block(block, None) = &else_inner.kind;
                        if block.stmts.is_empty();
                        if let Some(block_expr) = &block.expr;
                        if eq_expr_value(cx, subject, block_expr);
                        then {
                            replacement = Some(format!("Some({}?)", receiver_str));
                        }
                    }
                } else if Self::moves_by_default(cx, subject)
                    && !matches!(subject.kind, ExprKind::Call(..) | ExprKind::MethodCall(..))
                {
                    replacement = Some(format!("{}.as_ref()?;", receiver_str));
                } else {
                    replacement = Some(format!("{}?;", receiver_str));
                }

                if let Some(replacement_str) = replacement {
                    span_lint_and_sugg(
                        cx,
                        QUESTION_MARK,
                        expr.span,
                        "this block may be rewritten with the `?` operator",
                        "replace it with",
                        replacement_str,
                        applicability,
                    );
                }
            }
        }
    }

    fn check_if_let_some_or_err_and_early_return(cx: &LateContext<'_>, expr: &Expr<'_>) {
        if_chain! {
            if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else: Some(if_else) })
                = higher::IfLet::hir(cx, expr);
            if let PatKind::TupleStruct(ref path1, fields, None) = let_pat.kind;
            if (Self::option_check_and_early_return(cx, let_expr, if_else) && is_lang_ctor(cx, path1, OptionSome)) ||
                (Self::result_check_and_early_return(cx, let_expr, if_else) && is_lang_ctor(cx, path1, ResultOk));

            if let PatKind::Binding(annot, bind_id, _, _) = fields[0].kind;
            let by_ref = matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut);
            if let ExprKind::Block(block, None) = if_then.kind;
            if block.stmts.is_empty();
            if let Some(trailing_expr) = &block.expr;
            if path_to_local_id(trailing_expr, bind_id);
            then {
                let mut applicability = Applicability::MachineApplicable;
                let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
                let replacement = format!("{}{}?", receiver_str, if by_ref { ".as_ref()" } else { "" },);

                span_lint_and_sugg(
                    cx,
                    QUESTION_MARK,
                    expr.span,
                    "this if-let-else may be rewritten with the `?` operator",
                    "replace it with",
                    replacement,
                    applicability,
                );
            }
        }
    }

    fn result_check_and_early_return(cx: &LateContext<'_>, expr: &Expr<'_>, nested_expr: &Expr<'_>) -> bool {
        Self::is_result(cx, expr) && Self::expression_returns_unmodified_err(cx, nested_expr, expr)
    }

    fn option_check_and_early_return(cx: &LateContext<'_>, expr: &Expr<'_>, nested_expr: &Expr<'_>) -> bool {
        Self::is_option(cx, expr) && Self::expression_returns_none(cx, nested_expr)
    }

    fn moves_by_default(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool {
        let expr_ty = cx.typeck_results().expr_ty(expression);

        !expr_ty.is_copy_modulo_regions(cx.tcx.at(expression.span), cx.param_env)
    }

    fn is_option(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool {
        let expr_ty = cx.typeck_results().expr_ty(expression);

        is_type_diagnostic_item(cx, expr_ty, sym::Option)
    }

    fn is_result(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool {
        let expr_ty = cx.typeck_results().expr_ty(expression);

        is_type_diagnostic_item(cx, expr_ty, sym::Result)
    }

    fn expression_returns_none(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool {
        match expression.kind {
            ExprKind::Block(block, _) => {
                if let Some(return_expression) = Self::return_expression(block) {
                    return Self::expression_returns_none(cx, return_expression);
                }

                false
            },
            ExprKind::Ret(Some(expr)) => Self::expression_returns_none(cx, expr),
            ExprKind::Path(ref qpath) => is_lang_ctor(cx, qpath, OptionNone),
            _ => false,
        }
    }

    fn expression_returns_unmodified_err(cx: &LateContext<'_>, expr: &Expr<'_>, cond_expr: &Expr<'_>) -> bool {
        match expr.kind {
            ExprKind::Block(block, _) => {
                if let Some(return_expression) = Self::return_expression(block) {
                    return Self::expression_returns_unmodified_err(cx, return_expression, cond_expr);
                }

                false
            },
            ExprKind::Ret(Some(ret_expr)) => Self::expression_returns_unmodified_err(cx, ret_expr, cond_expr),
            ExprKind::Path(_) => path_to_local(expr) == path_to_local(cond_expr),
            _ => false,
        }
    }

    fn return_expression<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> {
        // Check if last expression is a return statement. Then, return the expression
        if_chain! {
            if block.stmts.len() == 1;
            if let Some(expr) = block.stmts.iter().last();
            if let StmtKind::Semi(expr) = expr.kind;
            if let ExprKind::Ret(Some(ret_expr)) = expr.kind;

            then {
                return Some(ret_expr);
            }
        }

        // Check for `return` without a semicolon.
        if_chain! {
            if block.stmts.is_empty();
            if let Some(ExprKind::Ret(Some(ret_expr))) = block.expr.as_ref().map(|e| &e.kind);
            then {
                return Some(ret_expr);
            }
        }

        None
    }
}

impl<'tcx> LateLintPass<'tcx> for QuestionMark {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
        Self::check_is_none_or_err_and_early_return(cx, expr);
        Self::check_if_let_some_or_err_and_early_return(cx, expr);
    }
}
<|endoftext|>


<commit_before>use rand::distributions::{IndependentSample, Range};
use rand;
use gl;
use std;
use shader::Shader;
use shader::ShaderProgram;
use shader::ShaderType;
use super::graphics::vao::VAO;
use super::Miliseconds;
use cgmath;
use cgmath::SquareMatrix;
use cgmath::Matrix4;

#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Position {
    x: f32,
    y: f32,
    z: f32,
    w: f32
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Velocity {
    x: f32,
    y: f32,
    z: f32,
    w: f32
}

pub struct ParticleSystem {
    particle_pos: [Vec<Position>; 2],
    particle_vel: [Vec<Velocity>; 2],
    draw_shader_program: ShaderProgram,
    compute_shader_program: ShaderProgram,
    vao: VAO,
    now: std::time::Instant,
    gl_handle_pos_buffer: u32,
    active_buffer: usize
}

impl ParticleSystem {
    pub fn new(particle_count: usize) -> ParticleSystem {
        let mut system = ParticleSystem {
            particle_pos: [Vec::with_capacity(particle_count), Vec::with_capacity(particle_count)],
            particle_vel: [Vec::with_capacity(particle_count), Vec::with_capacity(particle_count)],
            draw_shader_program: ShaderProgram::new(),
            compute_shader_program: ShaderProgram::new(),
            vao: VAO::new(),
            now: std::time::Instant::now(),
            gl_handle_pos_buffer: 0,
            active_buffer: 0
        };

        let mut rng = rand::thread_rng();
        let range = Range::new(-1.0, 1.0);

        for i in 0..particle_count {
            let particle = Position {
                x : range.ind_sample(&mut rng),
                y : range.ind_sample(&mut rng),
                z : 0.0, //range.ind_sample(&mut rng),
                w : 0.0
            };

            for i in 0..2 {
                system.particle_pos[i].push(particle);
            }
        }

        system
    }

    pub fn update(&mut self, dt: f64) {

        let active_buffer = self.active_buffer;
        let output_buffer = self.get_output_buffer_index();

        for i in 0..self.particle_pos[0].len() {
            let mut input_y = 0.0;
            {
                let ref input_buffer = &(self.particle_pos[active_buffer]);
                input_y = input_buffer[i].y;
            }

            let ref mut output_buffer = &mut (self.particle_pos[output_buffer]);

            output_buffer[i].y = input_y + (-0.100 * dt) as f32;
        }

    }

    fn get_output_buffer_index(&self) -> usize {
        ((self.active_buffer + 1) % 2) as usize
    }

    fn get_input_buffer_index(&self) -> usize {
        self.active_buffer
    }

    pub fn init_graphics_resources(&mut self) {
        unsafe {
            //TODO is there another way to do this?
            let memory = std::slice::from_raw_parts(self.particle_pos.as_ptr() as *const f32,
                self.particle_pos.len()*4);
            self.gl_handle_pos_buffer = VAO::create_buffer();
            self.vao.set_buffer(self.gl_handle_pos_buffer, memory, 0, 4*4);
        }

        let mut vertex_shader = Shader::new(ShaderType::Vertex, "shaders/vertex_shader.v.glsl");
        vertex_shader.compile();

        let mut fragment_shader = Shader::new(ShaderType::Fragment, "shaders/pixel_shader.p.glsl");
        fragment_shader.compile();

        let mut geometry_shader = Shader::new(ShaderType::Geometry, "shaders/geometry_shader.g.glsl");
        geometry_shader.compile();

        self.draw_shader_program.attach_shader(&vertex_shader);
        self.draw_shader_program.attach_shader(&fragment_shader);
        self.draw_shader_program.attach_shader(&geometry_shader);
        self.draw_shader_program.link();

        let mut compute_shader = Shader::new(ShaderType::Compute, "shaders/compute_shader.c.glsl");
        compute_shader.compile();

        self.compute_shader_program.attach_shader(&compute_shader);
        self.compute_shader_program.link();
    }

    pub fn render(&mut self) {

        self.draw_shader_program.start_use();

        let elapsed = self.now.elapsed().as_milis();
        let colorg = (elapsed % 1000) as f32 / 1000.0f32;
        self.draw_shader_program.set_uniform4f("vtx_color", &[0.3, colorg, 0.3, 1.0]);

        let identity_mtx = cgmath::Matrix4::<f32>::identity();
        self.draw_shader_program.set_uniform_matrix4("view_from_world", identity_mtx.as_ref());
        self.draw_shader_program.set_uniform_matrix4("proj_from_view", identity_mtx.as_ref());

        let buffer_to_draw_index = self.get_output_buffer_index();
        let ref pos_buffer_to_draw = &self.particle_pos[buffer_to_draw_index];
        unsafe {
            //TODO is there another way to do this?
            let memory = std::slice::from_raw_parts(pos_buffer_to_draw.as_ptr() as *const f32,
                pos_buffer_to_draw.len()*4);
            self.vao.set_buffer(self.gl_handle_pos_buffer, memory, 0, 4*4);
        }
        self.vao.bind();

        unsafe {
            gl::DrawArrays(gl::POINTS, 0, pos_buffer_to_draw.len() as i32);
        }

        self.draw_shader_program.stop_use();

        self.active_buffer = (self.active_buffer + 1) % 2;
    }
}<commit_msg>Clarified ownership of the two buffers.<commit_after>use rand::distributions::{IndependentSample, Range};
use rand;
use gl;
use std;
use shader::Shader;
use shader::ShaderProgram;
use shader::ShaderType;
use super::graphics::vao::VAO;
use super::Miliseconds;
use cgmath;
use cgmath::SquareMatrix;
use cgmath::Matrix4;

#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Position {
    x: f32,
    y: f32,
    z: f32,
    w: f32
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Velocity {
    x: f32,
    y: f32,
    z: f32,
    w: f32
}

pub struct ParticleSystem {
    particle_pos: [Vec<Position>; 2],
    particle_vel: [Vec<Velocity>; 2],
    draw_shader_program: ShaderProgram,
    compute_shader_program: ShaderProgram,
    vao: VAO,
    now: std::time::Instant,
    gl_handle_pos_buffer: u32,
    should_swap_buffers: bool
}

impl ParticleSystem {
    pub fn new(particle_count: usize) -> ParticleSystem {
        let mut system = ParticleSystem {
            particle_pos: [Vec::with_capacity(particle_count), Vec::with_capacity(particle_count)],
            particle_vel: [Vec::with_capacity(particle_count), Vec::with_capacity(particle_count)],
            draw_shader_program: ShaderProgram::new(),
            compute_shader_program: ShaderProgram::new(),
            vao: VAO::new(),
            now: std::time::Instant::now(),
            gl_handle_pos_buffer: 0,
            should_swap_buffers: false
        };

        let mut rng = rand::thread_rng();
        let range = Range::new(-1.0, 1.0);

        for i in 0..particle_count {
            let particle = Position {
                x : range.ind_sample(&mut rng),
                y : range.ind_sample(&mut rng),
                z : 0.0, //range.ind_sample(&mut rng),
                w : 0.0
            };

            for i in 0..2 {
                system.particle_pos[i].push(particle);
            }
        }

        system
    }

    pub fn update(&mut self, dt: f64) {

        let output_buffer = self.get_output_buffer_index();

        let count = self.particle_pos[0].len();
        let (input_buffer, output_buffer) = self.get_input_and_output_buffer();

        for i in 0..count {
            let mut input_y = input_buffer[i].y;
            output_buffer[i].y = input_y + (-0.100 * dt) as f32;
        }
    }

    fn get_input_and_output_buffer(&mut self) -> (&mut [Position], &mut [Position]) {
        let (in_buff, out_buff) = self.particle_pos.split_at_mut(1);

        match self.should_swap_buffers {
            false => {
                (&mut in_buff[0], &mut out_buff[0])
            }
            true => {
                (&mut out_buff[0], &mut in_buff[0])
            }
        }
    }

    fn get_output_buffer_index(&self) -> usize {
        if self.should_swap_buffers {
            1 as usize
        }
        else {
            0 as usize
        }
    }

    pub fn init_graphics_resources(&mut self) {
        unsafe {
            //TODO is there another way to do this?
            let memory = std::slice::from_raw_parts(self.particle_pos.as_ptr() as *const f32,
                self.particle_pos.len()*4);
            self.gl_handle_pos_buffer = VAO::create_buffer();
            self.vao.set_buffer(self.gl_handle_pos_buffer, memory, 0, 4*4);
        }

        let mut vertex_shader = Shader::new(ShaderType::Vertex, "shaders/vertex_shader.v.glsl");
        vertex_shader.compile();

        let mut fragment_shader = Shader::new(ShaderType::Fragment, "shaders/pixel_shader.p.glsl");
        fragment_shader.compile();

        let mut geometry_shader = Shader::new(ShaderType::Geometry, "shaders/geometry_shader.g.glsl");
        geometry_shader.compile();

        self.draw_shader_program.attach_shader(&vertex_shader);
        self.draw_shader_program.attach_shader(&fragment_shader);
        self.draw_shader_program.attach_shader(&geometry_shader);
        self.draw_shader_program.link();

        let mut compute_shader = Shader::new(ShaderType::Compute, "shaders/compute_shader.c.glsl");
        compute_shader.compile();

        self.compute_shader_program.attach_shader(&compute_shader);
        self.compute_shader_program.link();
    }

    pub fn render(&mut self) {

        self.draw_shader_program.start_use();

        let elapsed = self.now.elapsed().as_milis();
        let colorg = (elapsed % 1000) as f32 / 1000.0f32;
        self.draw_shader_program.set_uniform4f("vtx_color", &[0.3, colorg, 0.3, 1.0]);

        let identity_mtx = cgmath::Matrix4::<f32>::identity();
        self.draw_shader_program.set_uniform_matrix4("view_from_world", identity_mtx.as_ref());
        self.draw_shader_program.set_uniform_matrix4("proj_from_view", identity_mtx.as_ref());

        let buffer_to_draw_index = self.get_output_buffer_index();
        let ref pos_buffer_to_draw = &self.particle_pos[buffer_to_draw_index];
        unsafe {
            //TODO is there another way to do this?
            let memory = std::slice::from_raw_parts(pos_buffer_to_draw.as_ptr() as *const f32,
                pos_buffer_to_draw.len()*4);
            self.vao.set_buffer(self.gl_handle_pos_buffer, memory, 0, 4*4);
        }
        self.vao.bind();

        unsafe {
            gl::DrawArrays(gl::POINTS, 0, pos_buffer_to_draw.len() as i32);
        }

        self.draw_shader_program.stop_use();

        self.should_swap_buffers = !self.should_swap_buffers;
    }
}<|endoftext|>


<commit_before>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

// TODO: add diagram

#![allow(dead_code)]
pub mod buffer_manager;
pub mod commit_phase;
pub mod errors;
pub mod execution_phase;
pub mod ordering_state_computer;
pub mod persisting_phase;
pub mod pipeline_phase;
pub mod signing_phase;

#[cfg(test)]
mod tests;
<commit_msg>[decoupled-execution] diagram<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

/*
 *         ┌──────────────────┐
 *         │ 2. Signing Phase │
 *         └──────────────▲─┬─┘
 *                        │ │
 * ┌────────────────────┐ │ │ ┌─────────────────────┐
 * │ 1. Execution Phase │ │ │ │ 4. Persisting Phase │
 * └─────────────────▲─┬┘ │ │ └┬─▲──────────────────┘
 *                   │ │  │ │  │ │
 *     0. Ordered  ┌─┴─▼──┴─▼──▼─┴────┐ 3. Commit Vote  ┌─────────┐
 *        Blocks   │                  ├─────────────────►         │
 *       ┌─────────►  Buffer Manager  │                 │ Network │
 *       │         │                  ◄─────────────────┤         │
 *  ┌────┴─────┐   └─────────▲────────┘    Commit Vote  └─────────┘
 *  │ Ordering │             │
 *  │ State    │   Sync Req  │
 *  │ Computer ├─────────────┘
 *  └──────────┘
 */

#![allow(dead_code)]
pub mod buffer_manager;
pub mod commit_phase;
pub mod errors;
pub mod execution_phase;
pub mod ordering_state_computer;
pub mod persisting_phase;
pub mod pipeline_phase;
pub mod signing_phase;

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>/// This module takes a (parsed) definition of `macro_rules` invocation, a
/// `tt::TokenTree` representing an argument of macro invocation, and produces a
/// `tt::TokenTree` for the result of the expansion.
use rustc_hash::FxHashMap;
use ra_syntax::SmolStr;
use tt::TokenId;

use crate::ExpandError;
use crate::tt_cursor::TtCursor;

pub(crate) fn expand(
    rules: &crate::MacroRules,
    input: &tt::Subtree,
) -> Result<tt::Subtree, ExpandError> {
    rules.rules.iter().find_map(|it| expand_rule(it, input).ok()).ok_or(ExpandError::NoMatchingRule)
}

fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> Result<tt::Subtree, ExpandError> {
    let mut input = TtCursor::new(input);
    let bindings = match_lhs(&rule.lhs, &mut input)?;
    if !input.is_eof() {
        return Err(ExpandError::UnexpectedToken);
    }
    expand_subtree(&rule.rhs, &bindings, &mut Vec::new())
}

/// The actual algorithm for expansion is not too hard, but is pretty tricky.
/// `Bindings` structure is the key to understanding what we are doing here.
///
/// On the high level, it stores mapping from meta variables to the bits of
/// syntax it should be substituted with. For example, if `$e:expr` is matched
/// with `1 + 1` by macro_rules, the `Binding` will store `$e -> 1 + 1`.
///
/// The tricky bit is dealing with repetitions (`$()*`). Consider this example:
///
/// ```not_rust
/// macro_rules! foo {
///     ($($ i:ident $($ e:expr),*);*) => {
///         $(fn $ i() { $($ e);*; })*
///     }
/// }
/// foo! { foo 1,2,3; bar 4,5,6 }
/// ```
///
/// Here, the `$i` meta variable is matched first with `foo` and then with
/// `bar`, and `$e` is matched in turn with `1`, `2`, `3`, `4`, `5`, `6`.
///
/// To represent such "multi-mappings", we use a recursive structures: we map
/// variables not to values, but to *lists* of values or other lists (that is,
/// to the trees).
///
/// For the above example, the bindings would store
///
/// ```not_rust
/// i -> [foo, bar]
/// e -> [[1, 2, 3], [4, 5, 6]]
/// ```
///
/// We construct `Bindings` in the `match_lhs`. The interesting case is
/// `TokenTree::Repeat`, where we use `push_nested` to create the desired
/// nesting structure.
///
/// The other side of the puzzle is `expand_subtree`, where we use the bindings
/// to substitute meta variables in the output template. When expanding, we
/// maintain a `nesting` stack of indices which tells us which occurrence from
/// the `Bindings` we should take. We push to the stack when we enter a
/// repetition.
///
/// In other words, `Bindings` is a *multi* mapping from `SmolStr` to
/// `tt::TokenTree`, where the index to select a particular `TokenTree` among
/// many is not a plain `usize`, but an `&[usize]`.
#[derive(Debug, Default)]
struct Bindings {
    inner: FxHashMap<SmolStr, Binding>,
}

#[derive(Debug)]
enum Binding {
    Simple(tt::TokenTree),
    Nested(Vec<Binding>),
}

impl Bindings {
    fn get(&self, name: &SmolStr, nesting: &[usize]) -> Result<&tt::TokenTree, ExpandError> {
        let mut b = self
            .inner
            .get(name)
            .ok_or(ExpandError::BindingError(format!("could not find binding `{}`", name)))?;
        for &idx in nesting.iter() {
            b = match b {
                Binding::Simple(_) => break,
                Binding::Nested(bs) => bs.get(idx).ok_or(ExpandError::BindingError(format!(
                    "could not find nested binding `{}`",
                    name
                )))?,
            };
        }
        match b {
            Binding::Simple(it) => Ok(it),
            Binding::Nested(_) => Err(ExpandError::BindingError(format!(
                "expected simple binding, found nested binding `{}`",
                name
            ))),
        }
    }

    fn push_nested(&mut self, nested: Bindings) -> Result<(), ExpandError> {
        for (key, value) in nested.inner {
            if !self.inner.contains_key(&key) {
                self.inner.insert(key.clone(), Binding::Nested(Vec::new()));
            }
            match self.inner.get_mut(&key) {
                Some(Binding::Nested(it)) => it.push(value),
                _ => {
                    return Err(ExpandError::BindingError(format!(
                        "could not find binding `{}`",
                        key
                    )));
                }
            }
        }
        Ok(())
    }
}

fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, ExpandError> {
    let mut res = Bindings::default();
    for pat in pattern.token_trees.iter() {
        match pat {
            crate::TokenTree::Leaf(leaf) => match leaf {
                crate::Leaf::Var(crate::Var { text, kind }) => {
                    let kind = kind.clone().ok_or(ExpandError::UnexpectedToken)?;
                    match kind.as_str() {
                        "ident" => {
                            let ident =
                                input.eat_ident().ok_or(ExpandError::UnexpectedToken)?.clone();
                            res.inner.insert(
                                text.clone(),
                                Binding::Simple(tt::Leaf::from(ident).into()),
                            );
                        }
                        _ => return Err(ExpandError::UnexpectedToken),
                    }
                }
                crate::Leaf::Punct(punct) => {
                    if input.eat_punct() != Some(punct) {
                        return Err(ExpandError::UnexpectedToken);
                    }
                }
                crate::Leaf::Ident(ident) => {
                    if input.eat_ident().map(|i| &i.text) != Some(&ident.text) {
                        return Err(ExpandError::UnexpectedToken);
                    }
                }
                _ => return Err(ExpandError::UnexpectedToken),
            },
            crate::TokenTree::Repeat(crate::Repeat { subtree, kind: _, separator }) => {
                while let Ok(nested) = match_lhs(subtree, input) {
                    res.push_nested(nested)?;
                    if let Some(separator) = *separator {
                        if !input.is_eof() {
                            if input.eat_punct().map(|p| p.char) != Some(separator) {
                                return Err(ExpandError::UnexpectedToken);
                            }
                        }
                    }
                }
            }
            _ => {}
        }
    }
    Ok(res)
}

fn expand_subtree(
    template: &crate::Subtree,
    bindings: &Bindings,
    nesting: &mut Vec<usize>,
) -> Result<tt::Subtree, ExpandError> {
    let token_trees = template
        .token_trees
        .iter()
        .map(|it| expand_tt(it, bindings, nesting))
        .collect::<Result<Vec<_>, ExpandError>>()?;

    Ok(tt::Subtree { token_trees, delimiter: template.delimiter })
}

fn expand_tt(
    template: &crate::TokenTree,
    bindings: &Bindings,
    nesting: &mut Vec<usize>,
) -> Result<tt::TokenTree, ExpandError> {
    let res: tt::TokenTree = match template {
        crate::TokenTree::Subtree(subtree) => expand_subtree(subtree, bindings, nesting)?.into(),
        crate::TokenTree::Repeat(repeat) => {
            let mut token_trees = Vec::new();
            nesting.push(0);
            while let Ok(t) = expand_subtree(&repeat.subtree, bindings, nesting) {
                let idx = nesting.pop().unwrap();
                nesting.push(idx + 1);
                token_trees.push(t.into())
            }
            nesting.pop().unwrap();
            tt::Subtree { token_trees, delimiter: tt::Delimiter::None }.into()
        }
        crate::TokenTree::Leaf(leaf) => match leaf {
            crate::Leaf::Ident(ident) => {
                tt::Leaf::from(tt::Ident { text: ident.text.clone(), id: TokenId::unspecified() })
                    .into()
            }
            crate::Leaf::Punct(punct) => tt::Leaf::from(punct.clone()).into(),
            crate::Leaf::Var(v) => bindings.get(&v.text, nesting)?.clone(),
            crate::Leaf::Literal(l) => tt::Leaf::from(tt::Literal { text: l.text.clone() }).into(),
        },
    };
    Ok(res)
}

#[cfg(test)]
mod tests {
    use ra_syntax::{ast, AstNode};

    use super::*;
    use crate::ast_to_token_tree;

    #[test]
    fn test_expand_rule() {
        assert_err(
            "($i:ident) => ($j)",
            "foo!{a}",
            ExpandError::BindingError(String::from("could not find binding `j`")),
        );

        assert_err(
            "($($i:ident);*) => ($i)",
            "foo!{a}",
            ExpandError::BindingError(String::from(
                "expected simple binding, found nested binding `i`",
            )),
        );

        assert_err("($i) => ($i)", "foo!{a}", ExpandError::UnexpectedToken);
        assert_err("($i:) => ($i)", "foo!{a}", ExpandError::UnexpectedToken);
    }

    fn assert_err(macro_body: &str, invocation: &str, err: ExpandError) {
        assert_eq!(expand_first(&create_rules(&format_macro(macro_body)), invocation), Err(err));
    }

    fn format_macro(macro_body: &str) -> String {
        format!(
            "
        macro_rules! foo {{
            {}
        }}
",
            macro_body
        )
    }

    fn create_rules(macro_definition: &str) -> crate::MacroRules {
        let source_file = ast::SourceFile::parse(macro_definition);
        let macro_definition =
            source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();

        let (definition_tt, _) = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
        crate::MacroRules::parse(&definition_tt).unwrap()
    }

    fn expand_first(
        rules: &crate::MacroRules,
        invocation: &str,
    ) -> Result<tt::Subtree, ExpandError> {
        let source_file = ast::SourceFile::parse(invocation);
        let macro_invocation =
            source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();

        let (invocation_tt, _) = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap();

        expand_rule(&rules.rules[0], &invocation_tt)
    }
}
<commit_msg>hack around non-terminating macro expansion<commit_after>/// This module takes a (parsed) definition of `macro_rules` invocation, a
/// `tt::TokenTree` representing an argument of macro invocation, and produces a
/// `tt::TokenTree` for the result of the expansion.
use rustc_hash::FxHashMap;
use ra_syntax::SmolStr;
use tt::TokenId;

use crate::ExpandError;
use crate::tt_cursor::TtCursor;

pub(crate) fn expand(
    rules: &crate::MacroRules,
    input: &tt::Subtree,
) -> Result<tt::Subtree, ExpandError> {
    rules.rules.iter().find_map(|it| expand_rule(it, input).ok()).ok_or(ExpandError::NoMatchingRule)
}

fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> Result<tt::Subtree, ExpandError> {
    let mut input = TtCursor::new(input);
    let bindings = match_lhs(&rule.lhs, &mut input)?;
    if !input.is_eof() {
        return Err(ExpandError::UnexpectedToken);
    }
    expand_subtree(&rule.rhs, &bindings, &mut Vec::new())
}

/// The actual algorithm for expansion is not too hard, but is pretty tricky.
/// `Bindings` structure is the key to understanding what we are doing here.
///
/// On the high level, it stores mapping from meta variables to the bits of
/// syntax it should be substituted with. For example, if `$e:expr` is matched
/// with `1 + 1` by macro_rules, the `Binding` will store `$e -> 1 + 1`.
///
/// The tricky bit is dealing with repetitions (`$()*`). Consider this example:
///
/// ```not_rust
/// macro_rules! foo {
///     ($($ i:ident $($ e:expr),*);*) => {
///         $(fn $ i() { $($ e);*; })*
///     }
/// }
/// foo! { foo 1,2,3; bar 4,5,6 }
/// ```
///
/// Here, the `$i` meta variable is matched first with `foo` and then with
/// `bar`, and `$e` is matched in turn with `1`, `2`, `3`, `4`, `5`, `6`.
///
/// To represent such "multi-mappings", we use a recursive structures: we map
/// variables not to values, but to *lists* of values or other lists (that is,
/// to the trees).
///
/// For the above example, the bindings would store
///
/// ```not_rust
/// i -> [foo, bar]
/// e -> [[1, 2, 3], [4, 5, 6]]
/// ```
///
/// We construct `Bindings` in the `match_lhs`. The interesting case is
/// `TokenTree::Repeat`, where we use `push_nested` to create the desired
/// nesting structure.
///
/// The other side of the puzzle is `expand_subtree`, where we use the bindings
/// to substitute meta variables in the output template. When expanding, we
/// maintain a `nesting` stack of indices which tells us which occurrence from
/// the `Bindings` we should take. We push to the stack when we enter a
/// repetition.
///
/// In other words, `Bindings` is a *multi* mapping from `SmolStr` to
/// `tt::TokenTree`, where the index to select a particular `TokenTree` among
/// many is not a plain `usize`, but an `&[usize]`.
#[derive(Debug, Default)]
struct Bindings {
    inner: FxHashMap<SmolStr, Binding>,
}

#[derive(Debug)]
enum Binding {
    Simple(tt::TokenTree),
    Nested(Vec<Binding>),
}

impl Bindings {
    fn get(&self, name: &SmolStr, nesting: &[usize]) -> Result<&tt::TokenTree, ExpandError> {
        let mut b = self
            .inner
            .get(name)
            .ok_or(ExpandError::BindingError(format!("could not find binding `{}`", name)))?;
        for &idx in nesting.iter() {
            b = match b {
                Binding::Simple(_) => break,
                Binding::Nested(bs) => bs.get(idx).ok_or(ExpandError::BindingError(format!(
                    "could not find nested binding `{}`",
                    name
                )))?,
            };
        }
        match b {
            Binding::Simple(it) => Ok(it),
            Binding::Nested(_) => Err(ExpandError::BindingError(format!(
                "expected simple binding, found nested binding `{}`",
                name
            ))),
        }
    }

    fn push_nested(&mut self, nested: Bindings) -> Result<(), ExpandError> {
        for (key, value) in nested.inner {
            if !self.inner.contains_key(&key) {
                self.inner.insert(key.clone(), Binding::Nested(Vec::new()));
            }
            match self.inner.get_mut(&key) {
                Some(Binding::Nested(it)) => it.push(value),
                _ => {
                    return Err(ExpandError::BindingError(format!(
                        "could not find binding `{}`",
                        key
                    )));
                }
            }
        }
        Ok(())
    }
}

fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, ExpandError> {
    let mut res = Bindings::default();
    for pat in pattern.token_trees.iter() {
        match pat {
            crate::TokenTree::Leaf(leaf) => match leaf {
                crate::Leaf::Var(crate::Var { text, kind }) => {
                    let kind = kind.clone().ok_or(ExpandError::UnexpectedToken)?;
                    match kind.as_str() {
                        "ident" => {
                            let ident =
                                input.eat_ident().ok_or(ExpandError::UnexpectedToken)?.clone();
                            res.inner.insert(
                                text.clone(),
                                Binding::Simple(tt::Leaf::from(ident).into()),
                            );
                        }
                        _ => return Err(ExpandError::UnexpectedToken),
                    }
                }
                crate::Leaf::Punct(punct) => {
                    if input.eat_punct() != Some(punct) {
                        return Err(ExpandError::UnexpectedToken);
                    }
                }
                crate::Leaf::Ident(ident) => {
                    if input.eat_ident().map(|i| &i.text) != Some(&ident.text) {
                        return Err(ExpandError::UnexpectedToken);
                    }
                }
                _ => return Err(ExpandError::UnexpectedToken),
            },
            crate::TokenTree::Repeat(crate::Repeat { subtree, kind: _, separator }) => {
                // Dirty hack to make macro-expansion terminate.
                // This should be replaced by a propper macro-by-example implementation
                let mut limit = 128;
                while let Ok(nested) = match_lhs(subtree, input) {
                    limit -= 1;
                    if limit == 0 {
                        break;
                    }
                    res.push_nested(nested)?;
                    if let Some(separator) = *separator {
                        if !input.is_eof() {
                            if input.eat_punct().map(|p| p.char) != Some(separator) {
                                return Err(ExpandError::UnexpectedToken);
                            }
                        }
                    }
                }
            }
            _ => {}
        }
    }
    Ok(res)
}

fn expand_subtree(
    template: &crate::Subtree,
    bindings: &Bindings,
    nesting: &mut Vec<usize>,
) -> Result<tt::Subtree, ExpandError> {
    let token_trees = template
        .token_trees
        .iter()
        .map(|it| expand_tt(it, bindings, nesting))
        .collect::<Result<Vec<_>, ExpandError>>()?;

    Ok(tt::Subtree { token_trees, delimiter: template.delimiter })
}

fn expand_tt(
    template: &crate::TokenTree,
    bindings: &Bindings,
    nesting: &mut Vec<usize>,
) -> Result<tt::TokenTree, ExpandError> {
    let res: tt::TokenTree = match template {
        crate::TokenTree::Subtree(subtree) => expand_subtree(subtree, bindings, nesting)?.into(),
        crate::TokenTree::Repeat(repeat) => {
            let mut token_trees = Vec::new();
            nesting.push(0);
            // Dirty hack to make macro-expansion terminate.
            // This should be replaced by a propper macro-by-example implementation
            let mut limit = 128;
            while let Ok(t) = expand_subtree(&repeat.subtree, bindings, nesting) {
                limit -= 1;
                if limit == 0 {
                    break;
                }
                let idx = nesting.pop().unwrap();
                nesting.push(idx + 1);
                token_trees.push(t.into())
            }
            nesting.pop().unwrap();
            tt::Subtree { token_trees, delimiter: tt::Delimiter::None }.into()
        }
        crate::TokenTree::Leaf(leaf) => match leaf {
            crate::Leaf::Ident(ident) => {
                tt::Leaf::from(tt::Ident { text: ident.text.clone(), id: TokenId::unspecified() })
                    .into()
            }
            crate::Leaf::Punct(punct) => tt::Leaf::from(punct.clone()).into(),
            crate::Leaf::Var(v) => bindings.get(&v.text, nesting)?.clone(),
            crate::Leaf::Literal(l) => tt::Leaf::from(tt::Literal { text: l.text.clone() }).into(),
        },
    };
    Ok(res)
}

#[cfg(test)]
mod tests {
    use ra_syntax::{ast, AstNode};

    use super::*;
    use crate::ast_to_token_tree;

    #[test]
    fn test_expand_rule() {
        assert_err(
            "($i:ident) => ($j)",
            "foo!{a}",
            ExpandError::BindingError(String::from("could not find binding `j`")),
        );

        assert_err(
            "($($i:ident);*) => ($i)",
            "foo!{a}",
            ExpandError::BindingError(String::from(
                "expected simple binding, found nested binding `i`",
            )),
        );

        assert_err("($i) => ($i)", "foo!{a}", ExpandError::UnexpectedToken);
        assert_err("($i:) => ($i)", "foo!{a}", ExpandError::UnexpectedToken);
    }

    fn assert_err(macro_body: &str, invocation: &str, err: ExpandError) {
        assert_eq!(expand_first(&create_rules(&format_macro(macro_body)), invocation), Err(err));
    }

    fn format_macro(macro_body: &str) -> String {
        format!(
            "
        macro_rules! foo {{
            {}
        }}
",
            macro_body
        )
    }

    fn create_rules(macro_definition: &str) -> crate::MacroRules {
        let source_file = ast::SourceFile::parse(macro_definition);
        let macro_definition =
            source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();

        let (definition_tt, _) = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
        crate::MacroRules::parse(&definition_tt).unwrap()
    }

    fn expand_first(
        rules: &crate::MacroRules,
        invocation: &str,
    ) -> Result<tt::Subtree, ExpandError> {
        let source_file = ast::SourceFile::parse(invocation);
        let macro_invocation =
            source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();

        let (invocation_tt, _) = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap();

        expand_rule(&rules.rules[0], &invocation_tt)
    }
}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]

extern crate rustup_dist;
extern crate rustup_utils;
#[macro_use]
extern crate error_chain;

extern crate clap;
extern crate regex;
extern crate rustup;
extern crate term;
extern crate itertools;
extern crate time;
extern crate rand;
extern crate scopeguard;
extern crate tempdir;
extern crate sha2;
extern crate markdown;
extern crate toml;
extern crate wait_timeout;

#[cfg(windows)]
extern crate gcc;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate winreg;
#[cfg(windows)]
extern crate user32;
#[cfg(windows)]
extern crate kernel32;
extern crate libc;

#[macro_use]
mod log;
mod common;
mod download_tracker;
mod proxy_mode;
mod setup_mode;
mod rustup_mode;
mod self_update;
mod job;
mod term2;
mod errors;
mod help;

use std::env;
use std::path::PathBuf;
use errors::*;
use rustup_dist::dist::TargetTriple;
use rustup::env_var::RUST_RECURSION_COUNT_MAX;

fn main() {
    if let Err(ref e) = run_multirust() {
        common::report_error(e);
        std::process::exit(1);
    }
}

fn run_multirust() -> Result<()> {
    // Guard against infinite recursion
    let recursion_count = env::var("RUST_RECURSION_COUNT").ok()
        .and_then(|s| s.parse().ok()).unwrap_or(0);
    if recursion_count > RUST_RECURSION_COUNT_MAX {
        return Err(ErrorKind::InfiniteRecursion.into());
    }

    // Do various things to clean up past messes
    // FIXME: Remove this soon to get it out of the proxy path
    do_compatibility_hacks();

    // The name of arg0 determines how the program is going to behave
    let arg0 = env::args().next().map(PathBuf::from);
    let name = arg0.as_ref()
        .and_then(|a| a.file_stem())
        .and_then(|a| a.to_str());
    match name {
        Some("rustup") => {
            rustup_mode::main()
        }
        Some(n) if n.starts_with("multirust-setup")||
                   n.starts_with("rustup-setup") ||
                   n.starts_with("rustup-init") => {
            // NB: The above check is only for the prefix of the file
            // name. Browsers rename duplicates to
            // e.g. multirust-setup(2), and this allows all variations
            // to work.
            setup_mode::main()
        }
        Some(n) if n.starts_with("rustup-gc-") => {
            // This is the final uninstallation stage on windows where
            // multirust deletes its own exe
            self_update::complete_windows_uninstall()
        }
        Some(n) if n.starts_with("multirust-") => {
            // This is for compatibility with previous revisions of
            // multirust-rs self-update, which expect multirust-rs to
            // be available on the server, downloads it to
            // ~/.multirust/tmp/multirust-$random, and execute it with
            // `self install` as the arguments.  FIXME: Verify this
            // works.
            let opts = self_update::InstallOpts {
                default_host_triple: TargetTriple::from_host_or_build().to_string(),
                default_toolchain: "stable".to_string(),
                no_modify_path: false,
            };
            if cfg!(windows) {
                self_update::install(false, false, opts)
            } else {
                self_update::install(true, false, opts)
            }
        }
        Some(_) => {
            proxy_mode::main()
        }
        None => {
            // Weird case. No arg0, or it's unparsable.
            Err(ErrorKind::NoExeName.into())
        }
    }
}

fn do_compatibility_hacks() {
    make_environment_compatible();
    fix_windows_reg_key();
    delete_multirust_bin();
}

// Convert any MULTIRUST_ env vars to RUSTUP_ and warn about them
fn make_environment_compatible() {
    let ref vars = ["HOME", "TOOLCHAIN", "DIST_ROOT", "UPDATE_ROOT", "GPG_KEY"];
    for var in vars {
        let ref mvar = format!("MULTIRUST_{}", var);
        let ref rvar = format!("RUSTUP_{}", var);
        let mval = env::var_os(mvar);
        let rval = env::var_os(rvar);

        match (mval, rval) {
            (Some(mval), None) => {
                env::set_var(rvar, mval);
                warn!("environment variable {} is deprecated. Use {}.", mvar, rvar);
            }
            _ => ()
        }
    }
}

// #261 We previously incorrectly set HKCU/Environment/PATH to a
// REG_SZ type, when it should be REG_EXPAND_SZ. Silently fix it.
#[cfg(windows)]
fn fix_windows_reg_key() {
    use winreg::RegKey;
    use winreg::enums::RegType;
    use winapi::*;

    let root = RegKey::predef(HKEY_CURRENT_USER);
    let env = root.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE);

    let env = if let Ok(e) = env { e } else { return };

    let path = env.get_raw_value("PATH");

    let mut path = if let Ok(p) = path { p } else { return };

    if path.vtype == RegType::REG_EXPAND_SZ { return }

    path.vtype = RegType::REG_EXPAND_SZ;

    let _ = env.set_raw_value("PATH", &path);
}

#[cfg(not(windows))]
fn fix_windows_reg_key() { }

// rustup used to be called 'multirust'. This deletes the old bin.
fn delete_multirust_bin() {
    use rustup_utils::utils;
    use std::env::consts::EXE_SUFFIX;
    use std::fs;

    if let Ok(home) = utils::cargo_home() {
        let legacy_bin = home.join(format!("bin/multirust{}", EXE_SUFFIX));
        if legacy_bin.exists() {
            let _ = fs::remove_file(legacy_bin);
        }
    }
}
<commit_msg>Clean up main a bit<commit_after>//! The main rustup commandline application
//!
//! The rustup binary is a chimera, changing its behavior based on the
//! name of the binary. This is used most prominently to enable
//! rustup's tool 'proxies' - that is, rustup itself and the rustup
//! proxies are the same binary; when the binary is called 'rustup' or
//! 'rustup.exe' rustup behaves like the rustup commandline
//! application; when it is called 'rustc' it behaves as a proxy to
//! 'rustc'.
//!
//! This scheme is further used to distingush the rustup installer,
//! called 'rustup-init' which is again just the rustup binary under a
//! different name.

#![recursion_limit = "1024"]

extern crate rustup_dist;
extern crate rustup_utils;
#[macro_use]
extern crate error_chain;

extern crate clap;
extern crate regex;
extern crate rustup;
extern crate term;
extern crate itertools;
extern crate time;
extern crate rand;
extern crate scopeguard;
extern crate tempdir;
extern crate sha2;
extern crate markdown;
extern crate toml;
extern crate wait_timeout;

#[cfg(windows)]
extern crate gcc;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate winreg;
#[cfg(windows)]
extern crate user32;
#[cfg(windows)]
extern crate kernel32;
extern crate libc;

#[macro_use]
mod log;
mod common;
mod download_tracker;
mod proxy_mode;
mod setup_mode;
mod rustup_mode;
mod self_update;
mod job;
mod term2;
mod errors;
mod help;

use std::env;
use std::path::PathBuf;
use errors::*;
use rustup_dist::dist::TargetTriple;
use rustup::env_var::RUST_RECURSION_COUNT_MAX;

fn main() {
    if let Err(ref e) = run_rustup() {
        common::report_error(e);
        std::process::exit(1);
    }
}

fn run_rustup() -> Result<()> {
    // Guard against infinite proxy recursion. This mostly happens due to
    // bugs in rustup.
    do_recursion_guard()?;

    // Do various hacks to clean up past messes
    do_compatibility_hacks();

    // The name of arg0 determines how the program is going to behave
    let arg0 = env::args().next().map(PathBuf::from);
    let name = arg0.as_ref()
        .and_then(|a| a.file_stem())
        .and_then(|a| a.to_str());

    match name {
        Some("rustup") => {
            rustup_mode::main()
        }
        Some(n) if n.starts_with("multirust-setup")||
                   n.starts_with("rustup-setup") ||
                   n.starts_with("rustup-init") => {
            // NB: The above check is only for the prefix of the file
            // name. Browsers rename duplicates to
            // e.g. multirust-setup(2), and this allows all variations
            // to work.
            setup_mode::main()
        }
        Some(n) if n.starts_with("rustup-gc-") => {
            // This is the final uninstallation stage on windows where
            // multirust deletes its own exe
            self_update::complete_windows_uninstall()
        }
        Some(n) if n.starts_with("multirust-") => {
            // This is for compatibility with previous revisions of
            // multirust-rs self-update, which expect multirust-rs to
            // be available on the server, downloads it to
            // ~/.multirust/tmp/multirust-$random, and execute it with
            // `self install` as the arguments.  FIXME: Verify this
            // works.
            let opts = self_update::InstallOpts {
                default_host_triple: TargetTriple::from_host_or_build().to_string(),
                default_toolchain: "stable".to_string(),
                no_modify_path: false,
            };
            if cfg!(windows) {
                self_update::install(false, false, opts)
            } else {
                self_update::install(true, false, opts)
            }
        }
        Some(_) => {
            proxy_mode::main()
        }
        None => {
            // Weird case. No arg0, or it's unparsable.
            Err(ErrorKind::NoExeName.into())
        }
    }
}

fn do_recursion_guard() -> Result<()> {
    let recursion_count = env::var("RUST_RECURSION_COUNT").ok()
        .and_then(|s| s.parse().ok()).unwrap_or(0);
    if recursion_count > RUST_RECURSION_COUNT_MAX {
        return Err(ErrorKind::InfiniteRecursion.into());
    }

    Ok(())
}

fn do_compatibility_hacks() {
    make_environment_compatible();
    fix_windows_reg_key();
    delete_multirust_bin();
}

// Convert any MULTIRUST_ env vars to RUSTUP_ and warn about them
fn make_environment_compatible() {
    let ref vars = ["HOME", "TOOLCHAIN", "DIST_ROOT", "UPDATE_ROOT", "GPG_KEY"];
    for var in vars {
        let ref mvar = format!("MULTIRUST_{}", var);
        let ref rvar = format!("RUSTUP_{}", var);
        let mval = env::var_os(mvar);
        let rval = env::var_os(rvar);

        match (mval, rval) {
            (Some(mval), None) => {
                env::set_var(rvar, mval);
                warn!("environment variable {} is deprecated. Use {}.", mvar, rvar);
            }
            _ => ()
        }
    }
}

// #261 We previously incorrectly set HKCU/Environment/PATH to a
// REG_SZ type, when it should be REG_EXPAND_SZ. Silently fix it.
#[cfg(windows)]
fn fix_windows_reg_key() {
    use winreg::RegKey;
    use winreg::enums::RegType;
    use winapi::*;

    let root = RegKey::predef(HKEY_CURRENT_USER);
    let env = root.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE);

    let env = if let Ok(e) = env { e } else { return };

    let path = env.get_raw_value("PATH");

    let mut path = if let Ok(p) = path { p } else { return };

    if path.vtype == RegType::REG_EXPAND_SZ { return }

    path.vtype = RegType::REG_EXPAND_SZ;

    let _ = env.set_raw_value("PATH", &path);
}

#[cfg(not(windows))]
fn fix_windows_reg_key() { }

// rustup used to be called 'multirust'. This deletes the old bin.
fn delete_multirust_bin() {
    use rustup_utils::utils;
    use std::env::consts::EXE_SUFFIX;
    use std::fs;

    if let Ok(home) = utils::cargo_home() {
        let legacy_bin = home.join(format!("bin/multirust{}", EXE_SUFFIX));
        if legacy_bin.exists() {
            let _ = fs::remove_file(legacy_bin);
        }
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

extern crate glib;
#[macro_use]
extern crate webkit2gtk_webextension;

use glib::Cast;
use glib::Object;
use glib::closure::Closure;
use glib::variant::Variant;
use webkit2gtk_webextension::{
    DOMDocumentExt,
    DOMElementExt,
    DOMEventTargetExt,
    DOMMouseEvent,
    DOMMouseEventExt,
    WebExtension,
    WebExtensionExt,
    WebPage,
    WebPageExt,
};

/*web_extension_init!();

pub fn web_extension_initialize(extension: &WebExtension) {
    extension.connect_page_created(|_, page| {
        page.connect_document_loaded(|page| {
            println!("Page {} created for {:?}", page.get_id(), page.get_uri());
            let document = page.get_dom_document().unwrap();
            println!("URL: {:?}", document.get_url());
            println!("Title: {:?}", document.get_title());
            document.set_title("My Web Page");

            let handler = Closure::new(|values| {
                if let Some(event) = values[1].get::<Object>() {
                    if let Ok(mouse_event) = event.downcast::<DOMMouseEvent>() {
                        println!("Click at ({}, {})", mouse_event.get_x(), mouse_event.get_y());
                    }
                }
                None
            });
            document.add_event_listener_with_closure("click", &handler, false);

            println!("{}%", scroll_percentage(page));
            scroll_by(page, 45);

            println!("{}%", scroll_percentage(page));
            scroll_bottom(page);

            println!("{}%", scroll_percentage(page));
            scroll_top(page);

            println!("{}%", scroll_percentage(page));
        });
    });
}*/

web_extension_init_with_data!();

pub fn web_extension_initialize(extension: &WebExtension, user_data: Option<&Variant>) {
    let user_string = user_data.map(|v| v.get_str()).and_then(|s| s.to_owned());
    dbg!(user_string);

    extension.connect_page_created(|_, page| {
        page.connect_document_loaded(|page| {
            println!("Page {} created for {:?}", page.get_id(), page.get_uri());
            let document = page.get_dom_document().unwrap();
            println!("URL: {:?}", document.get_url());
            println!("Title: {:?}", document.get_title());
            document.set_title("My Web Page");

            let handler = Closure::new(|values| {
                if let Some(event) = values[1].get::<Object>() {
                    if let Ok(mouse_event) = event.downcast::<DOMMouseEvent>() {
                        println!("Click at ({}, {})", mouse_event.get_x(), mouse_event.get_y());
                    }
                }
                None
            });
            document.add_event_listener_with_closure("click", &handler, false);

            println!("{}%", scroll_percentage(page));
            scroll_by(page, 45);

            println!("{}%", scroll_percentage(page));
            scroll_bottom(page);

            println!("{}%", scroll_percentage(page));
            scroll_top(page);

            println!("{}%", scroll_percentage(page));
        });
    });
}

fn scroll_by(page: &WebPage, pixels: i64) {
    let document = page.get_dom_document().unwrap();
    let body = document.get_body().unwrap();
    body.set_scroll_top(body.get_scroll_top() + pixels);
}

fn scroll_bottom(page: &WebPage) {
    let document = page.get_dom_document().unwrap();
    let body = document.get_body().unwrap();
    body.set_scroll_top(body.get_scroll_height());
}

fn scroll_percentage(page: &WebPage) -> i64 {
    let document = page.get_dom_document().unwrap();
    let body = document.get_body().unwrap();
    let document = document.get_document_element().unwrap();
    let height = document.get_client_height();
    (body.get_scroll_top() as f64 / (body.get_scroll_height() as f64 - height) * 100.0) as i64
}

fn scroll_top(page: &WebPage) {
    let document = page.get_dom_document().unwrap();
    let body = document.get_body().unwrap();
    body.set_scroll_top(0);
}
<commit_msg>clippy: fix redundant closure<commit_after>/*
 * Copyright (c) 2016 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

extern crate glib;
#[macro_use]
extern crate webkit2gtk_webextension;

use glib::closure::Closure;
use glib::variant::Variant;
use glib::Cast;
use glib::Object;
use webkit2gtk_webextension::{
    DOMDocumentExt, DOMElementExt, DOMEventTargetExt, DOMMouseEvent, DOMMouseEventExt,
    WebExtension, WebExtensionExt, WebPage, WebPageExt,
};

/*web_extension_init!();

pub fn web_extension_initialize(extension: &WebExtension) {
    extension.connect_page_created(|_, page| {
        page.connect_document_loaded(|page| {
            println!("Page {} created for {:?}", page.get_id(), page.get_uri());
            let document = page.get_dom_document().unwrap();
            println!("URL: {:?}", document.get_url());
            println!("Title: {:?}", document.get_title());
            document.set_title("My Web Page");

            let handler = Closure::new(|values| {
                if let Some(event) = values[1].get::<Object>() {
                    if let Ok(mouse_event) = event.downcast::<DOMMouseEvent>() {
                        println!("Click at ({}, {})", mouse_event.get_x(), mouse_event.get_y());
                    }
                }
                None
            });
            document.add_event_listener_with_closure("click", &handler, false);

            println!("{}%", scroll_percentage(page));
            scroll_by(page, 45);

            println!("{}%", scroll_percentage(page));
            scroll_bottom(page);

            println!("{}%", scroll_percentage(page));
            scroll_top(page);

            println!("{}%", scroll_percentage(page));
        });
    });
}*/

web_extension_init_with_data!();

pub fn web_extension_initialize(extension: &WebExtension, user_data: Option<&Variant>) {
    let user_string: Option<String> = user_data.and_then(Variant::get_str).map(ToOwned::to_owned);
    dbg!(user_string);

    extension.connect_page_created(|_, page| {
        page.connect_document_loaded(|page| {
            println!("Page {} created for {:?}", page.get_id(), page.get_uri());
            let document = page.get_dom_document().unwrap();
            println!("URL: {:?}", document.get_url());
            println!("Title: {:?}", document.get_title());
            document.set_title("My Web Page");

            let handler = Closure::new(|values| {
                if let Some(event) = values[1].get::<Object>() {
                    if let Ok(mouse_event) = event.downcast::<DOMMouseEvent>() {
                        println!(
                            "Click at ({}, {})",
                            mouse_event.get_x(),
                            mouse_event.get_y()
                        );
                    }
                }
                None
            });
            document.add_event_listener_with_closure("click", &handler, false);

            println!("{}%", scroll_percentage(page));
            scroll_by(page, 45);

            println!("{}%", scroll_percentage(page));
            scroll_bottom(page);

            println!("{}%", scroll_percentage(page));
            scroll_top(page);

            println!("{}%", scroll_percentage(page));
        });
    });
}

fn scroll_by(page: &WebPage, pixels: i64) {
    let document = page.get_dom_document().unwrap();
    let body = document.get_body().unwrap();
    body.set_scroll_top(body.get_scroll_top() + pixels);
}

fn scroll_bottom(page: &WebPage) {
    let document = page.get_dom_document().unwrap();
    let body = document.get_body().unwrap();
    body.set_scroll_top(body.get_scroll_height());
}

fn scroll_percentage(page: &WebPage) -> i64 {
    let document = page.get_dom_document().unwrap();
    let body = document.get_body().unwrap();
    let document = document.get_document_element().unwrap();
    let height = document.get_client_height();
    (body.get_scroll_top() as f64 / (body.get_scroll_height() as f64 - height) * 100.0) as i64
}

fn scroll_top(page: &WebPage) {
    let document = page.get_dom_document().unwrap();
    let body = document.get_body().unwrap();
    body.set_scroll_top(0);
}
<|endoftext|>


<commit_before>use orbtk::prelude::*;
use std::cell::Cell;

use euc::{buffer::Buffer2d, rasterizer, Pipeline};
use vek::*;

// Cube is copied from euc spinning_cube example
// https://github.com/zesterer/euc/blob/master/examples/spinning_cube.rs
struct Cube<'a> {
    mvp: Mat4<f32>,
    positions: &'a [Vec4<f32>],
}

impl<'a> Pipeline for Cube<'a> {
    type Vertex = (usize, Rgba<f32>);
    type VsOut = Rgba<f32>;
    type Pixel = u32;

    #[inline(always)]
    fn vert(&self, (v_index, v_color): &Self::Vertex) -> ([f32; 4], Self::VsOut) {
        ((self.mvp * self.positions[*v_index]).into_array(), *v_color)
    }

    #[inline(always)]
    fn frag(&self, v_color: &Self::VsOut) -> Self::Pixel {
        let bytes = v_color.map(|e| (e * 255.0) as u8).into_array();
        (bytes[2] as u32) << 0
            | (bytes[1] as u32) << 8
            | (bytes[0] as u32) << 16
            | (bytes[3] as u32) << 24
    }
}

#[derive(Clone, Default, PartialEq, Pipeline)]
struct CubePipeline {
    spin: Cell<f32>,
}

impl RenderPipeline for CubePipeline {
    fn draw(&self, render_target: &mut RenderTarget) {
        if render_target.width() == 0. || render_target.height() == 0. {
            return;
        }

        let mut color = Buffer2d::new(
            [
                render_target.width() as usize,
                render_target.height() as usize,
            ],
            0,
        );
        let mut depth = Buffer2d::new(
            [
                render_target.width() as usize,
                render_target.height() as usize,
            ],
            1.0,
        );

        let mvp = Mat4::perspective_fov_rh_no(
            1.3,
            render_target.width() as f32,
            render_target.height() as f32,
            0.01,
            100.0,
        ) * Mat4::translation_3d(Vec3::new(0.0, 0.0, -2.0))
            * Mat4::<f32>::scaling_3d(0.4)
            * Mat4::rotation_x((self.spin.get() * 0.002) * 8.0)
            * Mat4::rotation_y((self.spin.get() as f32 * 0.004).cos() * 4.0)
            * Mat4::rotation_z((self.spin.get() as f32 * 0.008).sin() * 2.0);

        Cube {
            mvp,
            positions: &[
                Vec4::new(-1.0, -1.0, -1.0, 1.0), // 0
                Vec4::new(-1.0, -1.0, 1.0, 1.0),  // 1
                Vec4::new(-1.0, 1.0, -1.0, 1.0),  // 2
                Vec4::new(-1.0, 1.0, 1.0, 1.0),   // 3
                Vec4::new(1.0, -1.0, -1.0, 1.0),  // 4
                Vec4::new(1.0, -1.0, 1.0, 1.0),   // 5
                Vec4::new(1.0, 1.0, -1.0, 1.0),   // 6
                Vec4::new(1.0, 1.0, 1.0, 1.0),    // 7
            ],
        }
        .draw::<rasterizer::Triangles<_, rasterizer::BackfaceCullingEnabled>, _>(
            &[
                // -x
                (0, Rgba::green()),
                (3, Rgba::blue()),
                (2, Rgba::red()),
                (0, Rgba::green()),
                (1, Rgba::red()),
                (3, Rgba::blue()),
                // +x
                (7, Rgba::blue()),
                (4, Rgba::green()),
                (6, Rgba::red()),
                (5, Rgba::red()),
                (4, Rgba::green()),
                (7, Rgba::blue()),
                // -y
                (5, Rgba::blue()),
                (0, Rgba::red()),
                (4, Rgba::green()),
                (1, Rgba::green()),
                (0, Rgba::red()),
                (5, Rgba::blue()),
                // +y
                (2, Rgba::red()),
                (7, Rgba::blue()),
                (6, Rgba::green()),
                (2, Rgba::red()),
                (3, Rgba::green()),
                (7, Rgba::blue()),
                // -z
                (0, Rgba::red()),
                (6, Rgba::green()),
                (4, Rgba::blue()),
                (0, Rgba::red()),
                (2, Rgba::blue()),
                (6, Rgba::green()),
                // +z
                (7, Rgba::green()),
                (1, Rgba::red()),
                (5, Rgba::blue()),
                (3, Rgba::blue()),
                (1, Rgba::red()),
                (7, Rgba::green()),
            ],
            &mut color,
            Some(&mut depth),
        );

        render_target.draw(color.as_ref());
    }
}

// OrbTk 2D drawing
#[derive(Clone, Default, PartialEq, Pipeline)]
struct Graphic2DPipeline;

impl RenderPipeline for Graphic2DPipeline {
    fn draw(&self, render_target: &mut RenderTarget) {
        let mut render_context =
            RenderContext2D::new(render_target.width(), render_target.height());

        let width = 120.0;
        let height = 120.0;

        let x = (render_target.width() - width) / 2.0;
        let y = (render_target.height() - height) / 2.0;
        // render_context.set_fill_style(utils::Brush::SolidColor(Color::from("#000000")));

        render_context.set_fill_style(utils::Brush::LinearGradient {
            start: Point::new(x, y),
            end: Point::new(x + width, y + height),
            stops: vec![
                LinearGradientStop {
                    position: 0.0,
                    color: Color::from("#0021EB"),
                },
                LinearGradientStop {
                    position: 0.5,
                    color: Color::from("#CE2F24"),
                },
                LinearGradientStop {
                    position: 1.0,
                    color: Color::from("#70EF49"),
                },
            ],
        });
        render_context.fill_rect(x, y, width, height);
        // render_target.draw(render_context.data());
    }
}

#[derive(Default, AsAny)]
pub struct MainViewState {
    cube_spin: f32,
}

impl MainViewState {
    fn spin(&mut self) {
        self.cube_spin += 32.0;
    }
}

impl State for MainViewState {
    fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
        if let Some(cube) = ctx
            .widget()
            .get_mut::<DefaultRenderPipeline>("render_pipeline")
            .0
            .as_any()
            .downcast_ref::<CubePipeline>()
        {
            cube.spin.set(self.cube_spin);
        }
    }
}

widget!(
    MainView<MainViewState> {
         render_pipeline: DefaultRenderPipeline
    }
);

impl Template for MainView {
    fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
        self.name("MainView")
            .render_pipeline(DefaultRenderPipeline(Box::new(CubePipeline::default())))
            .child(
                Grid::new()
                    .rows(Rows::create().push("auto").push("*").push("auto").push("*"))
                    .child(
                        TextBlock::new()
                            .attach(Grid::row(0))
                            .text("Canvas (render with euc crate)")
                            .style("text-block")
                            .style("text_block_header")
                            .margin(4.0)
                            .build(ctx),
                    )
                    .child(
                        Canvas::new()
                            .attach(Grid::row(1))
                            .render_pipeline(id)
                            .build(ctx),
                    )
                    .child(
                        Button::new()
                            .text("spin cube")
                            .v_align("end")
                            .attach(Grid::row(1))
                            .margin(4.0)
                            .on_click(move |states, _| {
                                states.get_mut::<MainViewState>(id).spin();
                                true
                            })
                            .build(ctx),
                    )
                    .child(
                        TextBlock::new()
                            .attach(Grid::row(2))
                            .text("Canvas (render with OrbTk)")
                            .style("text-block")
                            .style("text_block_header")
                            .margin(4.0)
                            .build(ctx),
                    )
                    .child(
                        Canvas::new()
                            .attach(Grid::row(3))
                            .render_pipeline(DefaultRenderPipeline(Box::new(
                                Graphic2DPipeline::default(),
                            )))
                            .build(ctx),
                    )
                    .build(ctx),
            )
    }
}

fn main() {
    // use this only if you want to run it as web application.
    orbtk::initialize();

    Application::new()
        .window(|ctx| {
            Window::new()
                .title("OrbTk - canvas example")
                .position((100.0, 100.0))
                .size(420.0, 730.0)
                .resizeable(true)
                .child(MainView::new().build(ctx))
                .build(ctx)
        })
        .run();
}
<commit_msg>clippy<commit_after>use orbtk::prelude::*;
use std::cell::Cell;

use euc::{buffer::Buffer2d, rasterizer, Pipeline};
use vek::*;

// Cube is copied from euc spinning_cube example
// https://github.com/zesterer/euc/blob/master/examples/spinning_cube.rs
struct Cube<'a> {
    mvp: Mat4<f32>,
    positions: &'a [Vec4<f32>],
}

impl<'a> Pipeline for Cube<'a> {
    type Vertex = (usize, Rgba<f32>);
    type VsOut = Rgba<f32>;
    type Pixel = u32;

    #[inline(always)]
    fn vert(&self, (v_index, v_color): &Self::Vertex) -> ([f32; 4], Self::VsOut) {
        ((self.mvp * self.positions[*v_index]).into_array(), *v_color)
    }

    #[inline(always)]
    fn frag(&self, v_color: &Self::VsOut) -> Self::Pixel {
        let bytes = v_color.map(|e| (e * 255.0) as u8).into_array();
        (bytes[2] as u32)
            | (bytes[1] as u32) << 8
            | (bytes[0] as u32) << 16
            | (bytes[3] as u32) << 24
    }
}

#[derive(Clone, Default, PartialEq, Pipeline)]
struct CubePipeline {
    spin: Cell<f32>,
}

impl RenderPipeline for CubePipeline {
    fn draw(&self, render_target: &mut RenderTarget) {
        if render_target.width() == 0. || render_target.height() == 0. {
            return;
        }

        let mut color = Buffer2d::new(
            [
                render_target.width() as usize,
                render_target.height() as usize,
            ],
            0,
        );
        let mut depth = Buffer2d::new(
            [
                render_target.width() as usize,
                render_target.height() as usize,
            ],
            1.0,
        );

        let mvp = Mat4::perspective_fov_rh_no(
            1.3,
            render_target.width() as f32,
            render_target.height() as f32,
            0.01,
            100.0,
        ) * Mat4::translation_3d(Vec3::new(0.0, 0.0, -2.0))
            * Mat4::<f32>::scaling_3d(0.4)
            * Mat4::rotation_x((self.spin.get() * 0.002) * 8.0)
            * Mat4::rotation_y((self.spin.get() as f32 * 0.004).cos() * 4.0)
            * Mat4::rotation_z((self.spin.get() as f32 * 0.008).sin() * 2.0);

        Cube {
            mvp,
            positions: &[
                Vec4::new(-1.0, -1.0, -1.0, 1.0), // 0
                Vec4::new(-1.0, -1.0, 1.0, 1.0),  // 1
                Vec4::new(-1.0, 1.0, -1.0, 1.0),  // 2
                Vec4::new(-1.0, 1.0, 1.0, 1.0),   // 3
                Vec4::new(1.0, -1.0, -1.0, 1.0),  // 4
                Vec4::new(1.0, -1.0, 1.0, 1.0),   // 5
                Vec4::new(1.0, 1.0, -1.0, 1.0),   // 6
                Vec4::new(1.0, 1.0, 1.0, 1.0),    // 7
            ],
        }
        .draw::<rasterizer::Triangles<_, rasterizer::BackfaceCullingEnabled>, _>(
            &[
                // -x
                (0, Rgba::green()),
                (3, Rgba::blue()),
                (2, Rgba::red()),
                (0, Rgba::green()),
                (1, Rgba::red()),
                (3, Rgba::blue()),
                // +x
                (7, Rgba::blue()),
                (4, Rgba::green()),
                (6, Rgba::red()),
                (5, Rgba::red()),
                (4, Rgba::green()),
                (7, Rgba::blue()),
                // -y
                (5, Rgba::blue()),
                (0, Rgba::red()),
                (4, Rgba::green()),
                (1, Rgba::green()),
                (0, Rgba::red()),
                (5, Rgba::blue()),
                // +y
                (2, Rgba::red()),
                (7, Rgba::blue()),
                (6, Rgba::green()),
                (2, Rgba::red()),
                (3, Rgba::green()),
                (7, Rgba::blue()),
                // -z
                (0, Rgba::red()),
                (6, Rgba::green()),
                (4, Rgba::blue()),
                (0, Rgba::red()),
                (2, Rgba::blue()),
                (6, Rgba::green()),
                // +z
                (7, Rgba::green()),
                (1, Rgba::red()),
                (5, Rgba::blue()),
                (3, Rgba::blue()),
                (1, Rgba::red()),
                (7, Rgba::green()),
            ],
            &mut color,
            Some(&mut depth),
        );

        render_target.draw(color.as_ref());
    }
}

// OrbTk 2D drawing
#[derive(Clone, Default, PartialEq, Pipeline)]
struct Graphic2DPipeline;

impl RenderPipeline for Graphic2DPipeline {
    fn draw(&self, render_target: &mut RenderTarget) {
        let mut render_context =
            RenderContext2D::new(render_target.width(), render_target.height());

        let width = 120.0;
        let height = 120.0;

        let x = (render_target.width() - width) / 2.0;
        let y = (render_target.height() - height) / 2.0;
        // render_context.set_fill_style(utils::Brush::SolidColor(Color::from("#000000")));

        render_context.set_fill_style(utils::Brush::LinearGradient {
            start: Point::new(x, y),
            end: Point::new(x + width, y + height),
            stops: vec![
                LinearGradientStop {
                    position: 0.0,
                    color: Color::from("#0021EB"),
                },
                LinearGradientStop {
                    position: 0.5,
                    color: Color::from("#CE2F24"),
                },
                LinearGradientStop {
                    position: 1.0,
                    color: Color::from("#70EF49"),
                },
            ],
        });
        render_context.fill_rect(x, y, width, height);
        // render_target.draw(render_context.data());
    }
}

#[derive(Default, AsAny)]
pub struct MainViewState {
    cube_spin: f32,
}

impl MainViewState {
    fn spin(&mut self) {
        self.cube_spin += 32.0;
    }
}

impl State for MainViewState {
    fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
        if let Some(cube) = ctx
            .widget()
            .get_mut::<DefaultRenderPipeline>("render_pipeline")
            .0
            .as_any()
            .downcast_ref::<CubePipeline>()
        {
            cube.spin.set(self.cube_spin);
        }
    }
}

widget!(
    MainView<MainViewState> {
         render_pipeline: DefaultRenderPipeline
    }
);

impl Template for MainView {
    fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
        self.name("MainView")
            .render_pipeline(DefaultRenderPipeline(Box::new(CubePipeline::default())))
            .child(
                Grid::new()
                    .rows(Rows::create().push("auto").push("*").push("auto").push("*"))
                    .child(
                        TextBlock::new()
                            .attach(Grid::row(0))
                            .text("Canvas (render with euc crate)")
                            .style("text-block")
                            .style("text_block_header")
                            .margin(4.0)
                            .build(ctx),
                    )
                    .child(
                        Canvas::new()
                            .attach(Grid::row(1))
                            .render_pipeline(id)
                            .build(ctx),
                    )
                    .child(
                        Button::new()
                            .text("spin cube")
                            .v_align("end")
                            .attach(Grid::row(1))
                            .margin(4.0)
                            .on_click(move |states, _| {
                                states.get_mut::<MainViewState>(id).spin();
                                true
                            })
                            .build(ctx),
                    )
                    .child(
                        TextBlock::new()
                            .attach(Grid::row(2))
                            .text("Canvas (render with OrbTk)")
                            .style("text-block")
                            .style("text_block_header")
                            .margin(4.0)
                            .build(ctx),
                    )
                    .child(
                        Canvas::new()
                            .attach(Grid::row(3))
                            .render_pipeline(DefaultRenderPipeline(Box::new(
                                Graphic2DPipeline::default(),
                            )))
                            .build(ctx),
                    )
                    .build(ctx),
            )
    }
}

fn main() {
    // use this only if you want to run it as web application.
    orbtk::initialize();

    Application::new()
        .window(|ctx| {
            Window::new()
                .title("OrbTk - canvas example")
                .position((100.0, 100.0))
                .size(420.0, 730.0)
                .resizeable(true)
                .child(MainView::new().build(ctx))
                .build(ctx)
        })
        .run();
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate tokio_core;
extern crate tokio_signal;

use futures::{Future, Stream};
use tokio_core::reactor::Core;

/// how many signals to handle before exiting
const STOP_AFTER: u64 = 10;

fn main() {
    // set up a Tokio event loop
    let mut core = Core::new().unwrap();

    // tokio_signal provides a convenience builder for Ctrl+C
    // this even works cross-platform: linux and windows!
    //
    // `fn ctrl_c()` produces a `Future` of the actual stream-initialisation
    // the `flatten_stream()` convenience method lazily defers that
    // initialisation, allowing us to use it 'as if' it is already the
    // stream we want, reducing boilerplate Future-handling.
    let endless_stream = tokio_signal::ctrl_c().flatten_stream();
    // don't keep going forever: convert the endless stream to a bounded one.
    let limited_stream = endless_stream.take(STOP_AFTER);

    // how many Ctrl+C have we received so far?
    let mut counter = 0;

    println!(
        "This program is now waiting for you to press Ctrl+C {0} times.
  * If running via `cargo run --example ctrl-c`, Ctrl+C also kills it, \
    due to https://github.com/rust-lang-nursery/rustup.rs/issues/806
  * If running the binary directly, the Ctrl+C is properly trapped.
    Terminate by repeating Ctrl+C {0} times, or ahead of time by \
    opening a second terminal and issuing `pkill -sigkil ctrl-c`",
        STOP_AFTER
    );

    // Stream::for_each is a powerful primitive provided by the Futures crate.
    // It turns a Stream into a Future that completes after all stream-items
    // have been completed, or the first time the closure returns an error
    let future = limited_stream.for_each(|()| {
        // Note how we manipulate the counter without any fancy synchronisation.
        // The borrowchecker realises there can't be any conflicts, so the closure
        // can just capture it.
        counter += 1;
        println!(
            "Ctrl+C received {} times! {} more before exit",
            counter,
            STOP_AFTER - counter
        );

        // return Ok-result to continue handling the stream
        Ok(())
    });

    // Up until now, we haven't really DONE anything, just prepared
    // now it's time to actually schedule, and thus execute, the stream
    // on our event loop
    core.run(future).unwrap();

    println!("Stream ended, quiting the program.");
}

#[cfg(test)]
// `Child::kill` terminates the application instead of sending the equivalent to SIGKILL on windows
#[cfg(unix)]
mod tests {
    use super::*;

    use std::env;
    use std::path::Path;
    use std::process::Command;

    #[test]
    fn ctrl_c() {
        let args = env::args().collect::<Vec<_>>();
        let ctrl_c_child = "ctrl_c_child";
        if args.len() >= 3 && args.last().map(|s| &s[..]) == Some(ctrl_c_child) {
            super::main();
        } else {
            let ctrl_c_path = Path::new("target")
                .join("debug")
                .join("examples")
                .join("ctrl-c");
            let mut child = Command::new(ctrl_c_path)
                .args(&["ctrl_c", "--nocapture", ctrl_c_child])
                .spawn()
                .unwrap();

            for i in 0..STOP_AFTER {
                println!("Kill {}", i);
                child.kill().unwrap();
            }
            child.wait().unwrap();
        }
    }
}
<commit_msg>signal: Remove test that were accidentally included in the ctrl-c example<commit_after>extern crate futures;
extern crate tokio_core;
extern crate tokio_signal;

use futures::{Future, Stream};
use tokio_core::reactor::Core;

/// how many signals to handle before exiting
const STOP_AFTER: u64 = 10;

fn main() {
    // set up a Tokio event loop
    let mut core = Core::new().unwrap();

    // tokio_signal provides a convenience builder for Ctrl+C
    // this even works cross-platform: linux and windows!
    //
    // `fn ctrl_c()` produces a `Future` of the actual stream-initialisation
    // the `flatten_stream()` convenience method lazily defers that
    // initialisation, allowing us to use it 'as if' it is already the
    // stream we want, reducing boilerplate Future-handling.
    let endless_stream = tokio_signal::ctrl_c().flatten_stream();
    // don't keep going forever: convert the endless stream to a bounded one.
    let limited_stream = endless_stream.take(STOP_AFTER);

    // how many Ctrl+C have we received so far?
    let mut counter = 0;

    println!(
        "This program is now waiting for you to press Ctrl+C {0} times.
  * If running via `cargo run --example ctrl-c`, Ctrl+C also kills it, \
    due to https://github.com/rust-lang-nursery/rustup.rs/issues/806
  * If running the binary directly, the Ctrl+C is properly trapped.
    Terminate by repeating Ctrl+C {0} times, or ahead of time by \
    opening a second terminal and issuing `pkill -sigkil ctrl-c`",
        STOP_AFTER
    );

    // Stream::for_each is a powerful primitive provided by the Futures crate.
    // It turns a Stream into a Future that completes after all stream-items
    // have been completed, or the first time the closure returns an error
    let future = limited_stream.for_each(|()| {
        // Note how we manipulate the counter without any fancy synchronisation.
        // The borrowchecker realises there can't be any conflicts, so the closure
        // can just capture it.
        counter += 1;
        println!(
            "Ctrl+C received {} times! {} more before exit",
            counter,
            STOP_AFTER - counter
        );

        // return Ok-result to continue handling the stream
        Ok(())
    });

    // Up until now, we haven't really DONE anything, just prepared
    // now it's time to actually schedule, and thus execute, the stream
    // on our event loop
    core.run(future).unwrap();

    println!("Stream ended, quiting the program.");
}
<|endoftext|>