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

extern crate app_units;
extern crate euclid;
extern crate gleam;
extern crate glutin;
extern crate webrender;
extern crate winit;

use app_units::Au;
use gleam::gl;
use glutin::GlContext;
use std::fs::File;
use std::io::Read;
use webrender::api::*;
use winit::dpi::LogicalSize;

struct Notifier {
    events_proxy: winit::EventsLoopProxy,
}

impl Notifier {
    fn new(events_proxy: winit::EventsLoopProxy) -> Notifier {
        Notifier { events_proxy }
    }
}

impl RenderNotifier for Notifier {
    fn clone(&self) -> Box<RenderNotifier> {
        Box::new(Notifier {
            events_proxy: self.events_proxy.clone(),
        })
    }

    fn wake_up(&self) {
        #[cfg(not(target_os = "android"))]
        let _ = self.events_proxy.wakeup();
    }

    fn new_frame_ready(&self,
                       _: DocumentId,
                       _scrolled: bool,
                       _composite_needed: bool,
                       _render_time: Option<u64>) {
        self.wake_up();
    }
}

struct Window {
    events_loop: winit::EventsLoop, //TODO: share events loop?
    window: glutin::GlWindow,
    renderer: webrender::Renderer,
    name: &'static str,
    pipeline_id: PipelineId,
    document_id: DocumentId,
    epoch: Epoch,
    api: RenderApi,
    font_instance_key: FontInstanceKey,
}

impl Window {
    fn new(name: &'static str, clear_color: ColorF) -> Self {
        let events_loop = winit::EventsLoop::new();
        let context_builder = glutin::ContextBuilder::new()
            .with_gl(glutin::GlRequest::GlThenGles {
                opengl_version: (3, 2),
                opengles_version: (3, 0),
            });
        let window_builder = winit::WindowBuilder::new()
            .with_title(name)
            .with_multitouch()
            .with_dimensions(LogicalSize::new(800., 600.));
        let window = glutin::GlWindow::new(window_builder, context_builder, &events_loop)
            .unwrap();

        unsafe {
            window.make_current().ok();
        }

        let gl = match window.get_api() {
            glutin::Api::OpenGl => unsafe {
                gl::GlFns::load_with(|symbol| window.get_proc_address(symbol) as *const _)
            },
            glutin::Api::OpenGlEs => unsafe {
                gl::GlesFns::load_with(|symbol| window.get_proc_address(symbol) as *const _)
            },
            glutin::Api::WebGl => unimplemented!(),
        };

        let device_pixel_ratio = window.get_hidpi_factor() as f32;

        let opts = webrender::RendererOptions {
            device_pixel_ratio,
            clear_color: Some(clear_color),
            ..webrender::RendererOptions::default()
        };

        let framebuffer_size = {
            let LogicalSize { width, height } = window.get_inner_size().unwrap();
            DeviceUintSize::new(width as u32, height as u32)
        };
        let notifier = Box::new(Notifier::new(events_loop.create_proxy()));
        let (renderer, sender) = webrender::Renderer::new(gl.clone(), notifier, opts).unwrap();
        let api = sender.create_api();
        let document_id = api.add_document(framebuffer_size, 0);

        let epoch = Epoch(0);
        let pipeline_id = PipelineId(0, 0);
        let mut txn = Transaction::new();

        let font_key = api.generate_font_key();
        let font_bytes = load_file("../wrench/reftests/text/FreeSans.ttf");
        txn.add_raw_font(font_key, font_bytes, 0);

        let font_instance_key = api.generate_font_instance_key();
        txn.add_font_instance(font_instance_key, font_key, Au::from_px(32), None, None, Vec::new());

        api.send_transaction(document_id, txn);

        Window {
            events_loop,
            window,
            renderer,
            name,
            epoch,
            pipeline_id,
            document_id,
            api,
            font_instance_key,
        }
    }

    fn tick(&mut self) -> bool {
        unsafe {
            self.window.make_current().ok();
        }
        let mut do_exit = false;
        let my_name = &self.name;
        let renderer = &mut self.renderer;

        self.events_loop.poll_events(|global_event| match global_event {
            winit::Event::WindowEvent { event, .. } => match event {
                winit::WindowEvent::CloseRequested |
                winit::WindowEvent::KeyboardInput {
                    input: winit::KeyboardInput {
                        virtual_keycode: Some(winit::VirtualKeyCode::Escape),
                        ..
                    },
                    ..
                } => {
                    do_exit = true
                }
                winit::WindowEvent::KeyboardInput {
                    input: winit::KeyboardInput {
                        state: winit::ElementState::Pressed,
                        virtual_keycode: Some(winit::VirtualKeyCode::P),
                        ..
                    },
                    ..
                } => {
                    println!("toggle flags {}", my_name);
                    renderer.toggle_debug_flags(webrender::DebugFlags::PROFILER_DBG);
                }
                _ => {}
            }
            _ => {}
        });
        if do_exit {
            return true
        }

        let framebuffer_size = {
            let LogicalSize { width, height } = self.window.get_inner_size().unwrap();
            DeviceUintSize::new(width as u32, height as u32)
        };
        let device_pixel_ratio = self.window.get_hidpi_factor() as f32;
        let layout_size = framebuffer_size.to_f32() / euclid::TypedScale::new(device_pixel_ratio);
        let mut txn = Transaction::new();
        let mut builder = DisplayListBuilder::new(self.pipeline_id, layout_size);

        let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
        let info = LayoutPrimitiveInfo::new(bounds);
        builder.push_stacking_context(
            &info,
            None,
            TransformStyle::Flat,
            MixBlendMode::Normal,
            Vec::new(),
            GlyphRasterSpace::Screen,
        );

        let info = LayoutPrimitiveInfo::new(LayoutRect::new(
            LayoutPoint::new(100.0, 100.0),
            LayoutSize::new(100.0, 200.0)
        ));
        builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));

        let text_bounds = LayoutRect::new(
            LayoutPoint::new(100.0, 50.0),
            LayoutSize::new(700.0, 200.0)
        );
        let glyphs = vec![
            GlyphInstance {
                index: 48,
                point: LayoutPoint::new(100.0, 100.0),
            },
            GlyphInstance {
                index: 68,
                point: LayoutPoint::new(150.0, 100.0),
            },
            GlyphInstance {
                index: 80,
                point: LayoutPoint::new(200.0, 100.0),
            },
            GlyphInstance {
                index: 82,
                point: LayoutPoint::new(250.0, 100.0),
            },
            GlyphInstance {
                index: 81,
                point: LayoutPoint::new(300.0, 100.0),
            },
            GlyphInstance {
                index: 3,
                point: LayoutPoint::new(350.0, 100.0),
            },
            GlyphInstance {
                index: 86,
                point: LayoutPoint::new(400.0, 100.0),
            },
            GlyphInstance {
                index: 79,
                point: LayoutPoint::new(450.0, 100.0),
            },
            GlyphInstance {
                index: 72,
                point: LayoutPoint::new(500.0, 100.0),
            },
            GlyphInstance {
                index: 83,
                point: LayoutPoint::new(550.0, 100.0),
            },
            GlyphInstance {
                index: 87,
                point: LayoutPoint::new(600.0, 100.0),
            },
            GlyphInstance {
                index: 17,
                point: LayoutPoint::new(650.0, 100.0),
            },
        ];

        let info = LayoutPrimitiveInfo::new(text_bounds);
        builder.push_text(
            &info,
            &glyphs,
            self.font_instance_key,
            ColorF::new(1.0, 1.0, 0.0, 1.0),
            None,
        );

        builder.pop_stacking_context();

        txn.set_display_list(
            self.epoch,
            None,
            layout_size,
            builder.finalize(),
            true,
        );
        txn.set_root_pipeline(self.pipeline_id);
        txn.generate_frame();
        self.api.send_transaction(self.document_id, txn);

        renderer.update();
        renderer.render(framebuffer_size).unwrap();
        self.window.swap_buffers().ok();

        false
    }

    fn deinit(self) {
        self.renderer.deinit();
    }
}

fn main() {
    let mut win1 = Window::new("window1", ColorF::new(0.3, 0.0, 0.0, 1.0));
    let mut win2 = Window::new("window2", ColorF::new(0.0, 0.3, 0.0, 1.0));

    loop {
        if win1.tick() {
            break;
        }
        if win2.tick() {
            break;
        }
    }

    win1.deinit();
    win2.deinit();
}

fn load_file(name: &str) -> Vec<u8> {
    let mut file = File::open(name).unwrap();
    let mut buffer = vec![];
    file.read_to_end(&mut buffer).unwrap();
    buffer
}
<commit_msg>Auto merge of #3008 - zakorgy:fix-multiwindow, r=gw3583<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate app_units;
extern crate euclid;
extern crate gleam;
extern crate glutin;
extern crate webrender;
extern crate winit;

use app_units::Au;
use gleam::gl;
use glutin::GlContext;
use std::fs::File;
use std::io::Read;
use webrender::api::*;
use winit::dpi::LogicalSize;

struct Notifier {
    events_proxy: winit::EventsLoopProxy,
}

impl Notifier {
    fn new(events_proxy: winit::EventsLoopProxy) -> Notifier {
        Notifier { events_proxy }
    }
}

impl RenderNotifier for Notifier {
    fn clone(&self) -> Box<RenderNotifier> {
        Box::new(Notifier {
            events_proxy: self.events_proxy.clone(),
        })
    }

    fn wake_up(&self) {
        #[cfg(not(target_os = "android"))]
        let _ = self.events_proxy.wakeup();
    }

    fn new_frame_ready(&self,
                       _: DocumentId,
                       _scrolled: bool,
                       _composite_needed: bool,
                       _render_time: Option<u64>) {
        self.wake_up();
    }
}

struct Window {
    events_loop: winit::EventsLoop, //TODO: share events loop?
    window: glutin::GlWindow,
    renderer: webrender::Renderer,
    name: &'static str,
    pipeline_id: PipelineId,
    document_id: DocumentId,
    epoch: Epoch,
    api: RenderApi,
    font_instance_key: FontInstanceKey,
}

impl Window {
    fn new(name: &'static str, clear_color: ColorF) -> Self {
        let events_loop = winit::EventsLoop::new();
        let context_builder = glutin::ContextBuilder::new()
            .with_gl(glutin::GlRequest::GlThenGles {
                opengl_version: (3, 2),
                opengles_version: (3, 0),
            });
        let window_builder = winit::WindowBuilder::new()
            .with_title(name)
            .with_multitouch()
            .with_dimensions(LogicalSize::new(800., 600.));
        let window = glutin::GlWindow::new(window_builder, context_builder, &events_loop)
            .unwrap();

        unsafe {
            window.make_current().ok();
        }

        let gl = match window.get_api() {
            glutin::Api::OpenGl => unsafe {
                gl::GlFns::load_with(|symbol| window.get_proc_address(symbol) as *const _)
            },
            glutin::Api::OpenGlEs => unsafe {
                gl::GlesFns::load_with(|symbol| window.get_proc_address(symbol) as *const _)
            },
            glutin::Api::WebGl => unimplemented!(),
        };

        let device_pixel_ratio = window.get_hidpi_factor() as f32;

        let opts = webrender::RendererOptions {
            device_pixel_ratio,
            clear_color: Some(clear_color),
            ..webrender::RendererOptions::default()
        };

        let framebuffer_size = {
            let size = window
                .get_inner_size()
                .unwrap()
                .to_physical(device_pixel_ratio as f64);
            DeviceUintSize::new(size.width as u32, size.height as u32)
        };
        let notifier = Box::new(Notifier::new(events_loop.create_proxy()));
        let (renderer, sender) = webrender::Renderer::new(gl.clone(), notifier, opts).unwrap();
        let api = sender.create_api();
        let document_id = api.add_document(framebuffer_size, 0);

        let epoch = Epoch(0);
        let pipeline_id = PipelineId(0, 0);
        let mut txn = Transaction::new();

        let font_key = api.generate_font_key();
        let font_bytes = load_file("../wrench/reftests/text/FreeSans.ttf");
        txn.add_raw_font(font_key, font_bytes, 0);

        let font_instance_key = api.generate_font_instance_key();
        txn.add_font_instance(font_instance_key, font_key, Au::from_px(32), None, None, Vec::new());

        api.send_transaction(document_id, txn);

        Window {
            events_loop,
            window,
            renderer,
            name,
            epoch,
            pipeline_id,
            document_id,
            api,
            font_instance_key,
        }
    }

    fn tick(&mut self) -> bool {
        unsafe {
            self.window.make_current().ok();
        }
        let mut do_exit = false;
        let my_name = &self.name;
        let renderer = &mut self.renderer;

        self.events_loop.poll_events(|global_event| match global_event {
            winit::Event::WindowEvent { event, .. } => match event {
                winit::WindowEvent::CloseRequested |
                winit::WindowEvent::KeyboardInput {
                    input: winit::KeyboardInput {
                        virtual_keycode: Some(winit::VirtualKeyCode::Escape),
                        ..
                    },
                    ..
                } => {
                    do_exit = true
                }
                winit::WindowEvent::KeyboardInput {
                    input: winit::KeyboardInput {
                        state: winit::ElementState::Pressed,
                        virtual_keycode: Some(winit::VirtualKeyCode::P),
                        ..
                    },
                    ..
                } => {
                    println!("toggle flags {}", my_name);
                    renderer.toggle_debug_flags(webrender::DebugFlags::PROFILER_DBG);
                }
                _ => {}
            }
            _ => {}
        });
        if do_exit {
            return true
        }

        let device_pixel_ratio = self.window.get_hidpi_factor() as f32;
        let framebuffer_size = {
            let size = self.window
                .get_inner_size()
                .unwrap()
                .to_physical(device_pixel_ratio as f64);
            DeviceUintSize::new(size.width as u32, size.height as u32)
        };
        let layout_size = framebuffer_size.to_f32() / euclid::TypedScale::new(device_pixel_ratio);
        let mut txn = Transaction::new();
        let mut builder = DisplayListBuilder::new(self.pipeline_id, layout_size);

        let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
        let info = LayoutPrimitiveInfo::new(bounds);
        builder.push_stacking_context(
            &info,
            None,
            TransformStyle::Flat,
            MixBlendMode::Normal,
            Vec::new(),
            GlyphRasterSpace::Screen,
        );

        let info = LayoutPrimitiveInfo::new(LayoutRect::new(
            LayoutPoint::new(100.0, 100.0),
            LayoutSize::new(100.0, 200.0)
        ));
        builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));

        let text_bounds = LayoutRect::new(
            LayoutPoint::new(100.0, 50.0),
            LayoutSize::new(700.0, 200.0)
        );
        let glyphs = vec![
            GlyphInstance {
                index: 48,
                point: LayoutPoint::new(100.0, 100.0),
            },
            GlyphInstance {
                index: 68,
                point: LayoutPoint::new(150.0, 100.0),
            },
            GlyphInstance {
                index: 80,
                point: LayoutPoint::new(200.0, 100.0),
            },
            GlyphInstance {
                index: 82,
                point: LayoutPoint::new(250.0, 100.0),
            },
            GlyphInstance {
                index: 81,
                point: LayoutPoint::new(300.0, 100.0),
            },
            GlyphInstance {
                index: 3,
                point: LayoutPoint::new(350.0, 100.0),
            },
            GlyphInstance {
                index: 86,
                point: LayoutPoint::new(400.0, 100.0),
            },
            GlyphInstance {
                index: 79,
                point: LayoutPoint::new(450.0, 100.0),
            },
            GlyphInstance {
                index: 72,
                point: LayoutPoint::new(500.0, 100.0),
            },
            GlyphInstance {
                index: 83,
                point: LayoutPoint::new(550.0, 100.0),
            },
            GlyphInstance {
                index: 87,
                point: LayoutPoint::new(600.0, 100.0),
            },
            GlyphInstance {
                index: 17,
                point: LayoutPoint::new(650.0, 100.0),
            },
        ];

        let info = LayoutPrimitiveInfo::new(text_bounds);
        builder.push_text(
            &info,
            &glyphs,
            self.font_instance_key,
            ColorF::new(1.0, 1.0, 0.0, 1.0),
            None,
        );

        builder.pop_stacking_context();

        txn.set_display_list(
            self.epoch,
            None,
            layout_size,
            builder.finalize(),
            true,
        );
        txn.set_root_pipeline(self.pipeline_id);
        txn.generate_frame();
        self.api.send_transaction(self.document_id, txn);

        renderer.update();
        renderer.render(framebuffer_size).unwrap();
        self.window.swap_buffers().ok();

        false
    }

    fn deinit(self) {
        self.renderer.deinit();
    }
}

fn main() {
    let mut win1 = Window::new("window1", ColorF::new(0.3, 0.0, 0.0, 1.0));
    let mut win2 = Window::new("window2", ColorF::new(0.0, 0.3, 0.0, 1.0));

    loop {
        if win1.tick() {
            break;
        }
        if win2.tick() {
            break;
        }
    }

    win1.deinit();
    win2.deinit();
}

fn load_file(name: &str) -> Vec<u8> {
    let mut file = File::open(name).unwrap();
    let mut buffer = vec![];
    file.read_to_end(&mut buffer).unwrap();
    buffer
}
<|endoftext|>


<commit_before>extern crate raindrops;

#[test]
fn test_1() { assert_eq!("1", raindrops::raindrops(1)); }

#[test]
fn test_3() { assert_eq!("Pling", raindrops::raindrops(3)); }

#[test]
fn test_5() { assert_eq!("Plang", raindrops::raindrops(5)); }

#[test]
fn test_7() { assert_eq!("Plong", raindrops::raindrops(7)); }

#[test]
fn test_6() { assert_eq!("Pling", raindrops::raindrops(6)); }

#[test]
fn test_9() { assert_eq!("Pling", raindrops::raindrops(9)); }

#[test]
fn test_10() { assert_eq!("Plang", raindrops::raindrops(10)); }

#[test]
fn test_14() { assert_eq!("Plong", raindrops::raindrops(14)); }

#[test]
fn test_15() { assert_eq!("PlingPlang", raindrops::raindrops(15)); }

#[test]
fn test_21() { assert_eq!("PlingPlong", raindrops::raindrops(21)); }

#[test]
fn test_25() { assert_eq!("Plang", raindrops::raindrops(25)); }

#[test]
fn test_35() { assert_eq!("PlangPlong", raindrops::raindrops(35)); }

#[test]
fn test_49() { assert_eq!("Plong", raindrops::raindrops(49)); }

#[test]
fn test_52() { assert_eq!("52", raindrops::raindrops(52)); }

#[test]
fn test_105() { assert_eq!("PlingPlangPlong", raindrops::raindrops(105)); }

#[test]
fn test_12121() { assert_eq!("12121", raindrops::raindrops(12121)); }
<commit_msg>Ignore all but the first test in raindrops<commit_after>extern crate raindrops;

#[test]
fn test_1() { assert_eq!("1", raindrops::raindrops(1)); }

#[test]
#[ignore]
fn test_3() { assert_eq!("Pling", raindrops::raindrops(3)); }

#[test]
#[ignore]
fn test_5() { assert_eq!("Plang", raindrops::raindrops(5)); }

#[test]
#[ignore]
fn test_7() { assert_eq!("Plong", raindrops::raindrops(7)); }

#[test]
#[ignore]
fn test_6() { assert_eq!("Pling", raindrops::raindrops(6)); }

#[test]
#[ignore]
fn test_9() { assert_eq!("Pling", raindrops::raindrops(9)); }

#[test]
#[ignore]
fn test_10() { assert_eq!("Plang", raindrops::raindrops(10)); }

#[test]
#[ignore]
fn test_14() { assert_eq!("Plong", raindrops::raindrops(14)); }

#[test]
#[ignore]
fn test_15() { assert_eq!("PlingPlang", raindrops::raindrops(15)); }

#[test]
#[ignore]
fn test_21() { assert_eq!("PlingPlong", raindrops::raindrops(21)); }

#[test]
#[ignore]
fn test_25() { assert_eq!("Plang", raindrops::raindrops(25)); }

#[test]
#[ignore]
fn test_35() { assert_eq!("PlangPlong", raindrops::raindrops(35)); }

#[test]
#[ignore]
fn test_49() { assert_eq!("Plong", raindrops::raindrops(49)); }

#[test]
#[ignore]
fn test_52() { assert_eq!("52", raindrops::raindrops(52)); }

#[test]
#[ignore]
fn test_105() { assert_eq!("PlingPlangPlong", raindrops::raindrops(105)); }

#[test]
#[ignore]
fn test_12121() { assert_eq!("12121", raindrops::raindrops(12121)); }
<|endoftext|>


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

use generate_format::Corpus;
use std::{fs::File, io::Write};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(
    name = "Diem format generator",
    about = "Trace serde (de)serialization to generate format descriptions for Diem types"
)]
struct Options {
    #[structopt(long, possible_values = &Corpus::variants(), default_value = "Diem", case_insensitive = true)]
    corpus: Corpus,

    #[structopt(long)]
    record: bool,
}

fn main() {
    let options = Options::from_args();

    let registry = options.corpus.get_registry();
    let output_file = options.corpus.output_file();

    let content = serde_yaml::to_string(&registry).unwrap();
    if options.record {
        match output_file {
            Some(path) => {
                let mut f = File::create("testsuite/generate-format/".to_string() + path).unwrap();
                writeln!(f, "{}", content).unwrap();
            }
            None => panic!("Corpus {:?} doesn't record formats on disk", options.corpus),
        }
    } else {
        println!("{}", content);
    }
}
<commit_msg>[generate-format] Remove the extra empty line at EOF<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use generate_format::Corpus;
use std::{fs::File, io::Write};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(
    name = "Diem format generator",
    about = "Trace serde (de)serialization to generate format descriptions for Diem types"
)]
struct Options {
    #[structopt(long, possible_values = &Corpus::variants(), default_value = "Diem", case_insensitive = true)]
    corpus: Corpus,

    #[structopt(long)]
    record: bool,
}

fn main() {
    let options = Options::from_args();

    let registry = options.corpus.get_registry();
    let output_file = options.corpus.output_file();

    let content = serde_yaml::to_string(&registry).unwrap();
    if options.record {
        match output_file {
            Some(path) => {
                let mut f = File::create("testsuite/generate-format/".to_string() + path).unwrap();
                write!(f, "{}", content).unwrap();
            }
            None => panic!("Corpus {:?} doesn't record formats on disk", options.corpus),
        }
    } else {
        println!("{}", content);
    }
}
<|endoftext|>


<commit_before>use descartes::{P2, V2, Path, Segment, Band, Curve, FiniteCurve, N, RoughlyComparable};
use kay::{ID, CVec, Swarm, CreateWith};
use monet::{Thing};
use core::geometry::{CPath, band_to_thing};
use super::materialized_reality::BuildableRef;
use super::super::{Lane, TransferLane, AdvertiseToTransferAndReport};

#[derive(Compact, Clone)]
pub struct LaneStroke{
    nodes: CVec<LaneStrokeNode>,
    _memoized_path: CPath
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct LaneStrokeNodeRef(pub usize, pub usize);

pub const MIN_NODE_DISTANCE : f32 = 1.0;

#[derive(Debug)]
pub enum LaneStrokeError{
    NodesTooClose,
    LessThanTwoNodes
}

impl LaneStroke {
    pub fn new(nodes: CVec<LaneStrokeNode>) -> Result<Self, LaneStrokeError> {
        if nodes.windows(2).any(|window|
            if window[0].position.is_roughly_within(window[1].position, MIN_NODE_DISTANCE) {
                ::core::geometry::add_debug_point(window[0].position, [1.0, 0.0, 1.0], 0.5);
                ::core::geometry::add_debug_point(window[1].position, [1.0, 0.0, 1.0], 0.5);
                true
            } else {false}
        ) {
            Result::Err(LaneStrokeError::NodesTooClose)
        } else if nodes.len() <= 1 {
            Result::Err(LaneStrokeError::LessThanTwoNodes)
        } else {
            Result::Ok(LaneStroke{nodes: nodes, _memoized_path: CPath::new(vec![])})
        }
    }

    pub fn nodes(&self) -> &CVec<LaneStrokeNode> {
        &self.nodes
    }

    pub fn nodes_mut(&mut self) -> &mut CVec<LaneStrokeNode> {
        self._memoized_path = CPath::new(vec![]);
        &mut self.nodes
    }

    pub fn path(&self) -> &CPath {
        // TODO: replace by proper Option
        if self._memoized_path.segments().len() == 0 {
            // TODO: maybe there is something less damn dangerous
            #[allow(mutable_transmutes)]
            let unsafe_memoized_path : &mut CPath = unsafe{::std::mem::transmute(&self._memoized_path)};
            *unsafe_memoized_path = Path::new(self.nodes.windows(2).flat_map(|window|
                Segment::biarc(window[0].position, window[0].direction, window[1].position, window[1].direction)
            ).collect::<Vec<_>>())
        }
        &self._memoized_path
    }

    pub fn preview_thing(&self) -> Thing {
        band_to_thing(&Band::new(Band::new(self.path().clone(), 4.85).outline(), 0.6), 0.0)
    }

    // TODO: this is slightly ugly
    pub fn subsection(&self, start: N, end: N) -> Option<Self> {
        let path = self.path();
        if let Some(cut_path) = path.subsection(start, end) {
            let nodes = cut_path.segments().iter().map(|segment|
                LaneStrokeNode{
                    position: segment.start(),
                    direction: segment.start_direction()
                }
            ).chain(cut_path.segments().last().map(|last_segment|
                LaneStrokeNode{
                    position: last_segment.end(),
                    direction: last_segment.end_direction()
                }
            ).into_iter()).collect();
            LaneStroke::new(nodes).ok()
        } else {None}
    }

    pub fn with_subsection_moved(&self, start: N, end: N, delta: V2) -> MovedSubsectionInfo {
        let nodes_before = self.nodes.iter().take_while(|node|
            self.path().project(node.position).unwrap() < start - 5.0
        ).cloned().collect::<Vec<_>>();

        let new_subsection = self.subsection(start, end).into_iter()
            .flat_map(|subsection| subsection.nodes)
            .map(|node| LaneStrokeNode{
                position: node.position + delta,
                direction: node.direction
            }).collect::<Vec<_>>();

        let nodes_after = self.nodes.iter().skip_while(|node|
            self.path().project(node.position).unwrap() < end + 5.0
        ).cloned().collect::<Vec<_>>();

        let mut maybe_before_connector = None;
        let mut maybe_after_connector = None;

        if let (Some(&last_node_before), Some(&first_moved_node)) = (nodes_before.last(), new_subsection.get(0)) {
            maybe_before_connector = biarc_connection_node(last_node_before, first_moved_node);
        }

        if let (Some(&last_moved_node), Some(&first_node_after)) = (new_subsection.last(), nodes_after.get(0)) {
            maybe_after_connector = biarc_connection_node(last_moved_node, first_node_after);
        }

        (nodes_before, maybe_before_connector, new_subsection, maybe_after_connector, nodes_after)
     }

    pub fn build(&self, report_to: ID, report_as: BuildableRef) {
        Swarm::<Lane>::all() << CreateWith(
            Lane::new(self.path().clone(), false, CVec::new()),
            AdvertiseToTransferAndReport(report_to, report_as)
        );
    }

    pub fn build_intersection(&self, report_to: ID, report_as: BuildableRef, timings: CVec<bool>) {
        Swarm::<Lane>::all() << CreateWith(
            Lane::new(self.path().clone(), true, timings),
            AdvertiseToTransferAndReport(report_to, report_as)
        );
    }

    pub fn build_transfer(&self, report_to: ID, report_as: BuildableRef) {
        Swarm::<TransferLane>::all() << CreateWith(
            TransferLane::new(self.path().clone()),
            AdvertiseToTransferAndReport(report_to, report_as)
        );
    }
}

pub type MovedSubsectionInfo = (
    Vec<LaneStrokeNode>,
    Option<LaneStrokeNode>,
    Vec<LaneStrokeNode>,
    Option<LaneStrokeNode>,
    Vec<LaneStrokeNode>
);

fn biarc_connection_node(start_node: LaneStrokeNode, end_node: LaneStrokeNode) -> Option<LaneStrokeNode> {
    let connection_segments = Segment::biarc(
        start_node.position, start_node.direction,
        end_node.position, end_node.direction
    );

    if connection_segments.len() > 1 {
        let connection_node = LaneStrokeNode{
            position: connection_segments[0].end(),
            direction: connection_segments[0].end_direction()
        };
        if !connection_node.position.is_roughly_within(start_node.position, MIN_NODE_DISTANCE)
        && !connection_node.position.is_roughly_within(end_node.position, MIN_NODE_DISTANCE) {
            Some(connection_node)
        } else {None}
    } else {None}
}

impl<'a> RoughlyComparable for &'a LaneStroke {
    fn is_roughly_within(&self, other: &LaneStroke, tolerance: N) -> bool {
        self.nodes.len() == other.nodes.len()
        && self.nodes.iter().zip(other.nodes.iter()).all(|(n1, n2)|
            n1.is_roughly_within(n2, tolerance)
        )
    }
}

#[derive(Copy, Clone)]
pub struct LaneStrokeNode {
    pub position: P2,
    pub direction: V2
}

impl<'a> RoughlyComparable for &'a LaneStrokeNode {
    fn is_roughly_within(&self, other: &LaneStrokeNode, tolerance: N) -> bool {
        self.position.is_roughly_within(other.position, tolerance)
        // && (
        //     (self.direction.is_none() && other.direction.is_none())
        //     || (self.direction.is_some() && other.direction.is_some()
        //         && self.direction.unwrap().is_roughly_within(other.direction.unwrap(), tolerance)))
    }
}<commit_msg>Disabled close lane stroke debug points<commit_after>use descartes::{P2, V2, Path, Segment, Band, Curve, FiniteCurve, N, RoughlyComparable};
use kay::{ID, CVec, Swarm, CreateWith};
use monet::{Thing};
use core::geometry::{CPath, band_to_thing};
use super::materialized_reality::BuildableRef;
use super::super::{Lane, TransferLane, AdvertiseToTransferAndReport};

#[derive(Compact, Clone)]
pub struct LaneStroke{
    nodes: CVec<LaneStrokeNode>,
    _memoized_path: CPath
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct LaneStrokeNodeRef(pub usize, pub usize);

pub const MIN_NODE_DISTANCE : f32 = 1.0;

#[derive(Debug)]
pub enum LaneStrokeError{
    NodesTooClose,
    LessThanTwoNodes
}

impl LaneStroke {
    pub fn new(nodes: CVec<LaneStrokeNode>) -> Result<Self, LaneStrokeError> {
        if nodes.windows(2).any(|window|
            window[0].position.is_roughly_within(window[1].position, MIN_NODE_DISTANCE)
            //::core::geometry::add_debug_point(window[0].position, [1.0, 0.0, 1.0], 0.5);
            //::core::geometry::add_debug_point(window[1].position, [1.0, 0.0, 1.0], 0.5);
        ) {
            Result::Err(LaneStrokeError::NodesTooClose)
        } else if nodes.len() <= 1 {
            Result::Err(LaneStrokeError::LessThanTwoNodes)
        } else {
            Result::Ok(LaneStroke{nodes: nodes, _memoized_path: CPath::new(vec![])})
        }
    }

    pub fn nodes(&self) -> &CVec<LaneStrokeNode> {
        &self.nodes
    }

    pub fn nodes_mut(&mut self) -> &mut CVec<LaneStrokeNode> {
        self._memoized_path = CPath::new(vec![]);
        &mut self.nodes
    }

    pub fn path(&self) -> &CPath {
        // TODO: replace by proper Option
        if self._memoized_path.segments().len() == 0 {
            // TODO: maybe there is something less damn dangerous
            #[allow(mutable_transmutes)]
            let unsafe_memoized_path : &mut CPath = unsafe{::std::mem::transmute(&self._memoized_path)};
            *unsafe_memoized_path = Path::new(self.nodes.windows(2).flat_map(|window|
                Segment::biarc(window[0].position, window[0].direction, window[1].position, window[1].direction)
            ).collect::<Vec<_>>())
        }
        &self._memoized_path
    }

    pub fn preview_thing(&self) -> Thing {
        band_to_thing(&Band::new(Band::new(self.path().clone(), 4.85).outline(), 0.6), 0.0)
    }

    // TODO: this is slightly ugly
    pub fn subsection(&self, start: N, end: N) -> Option<Self> {
        let path = self.path();
        if let Some(cut_path) = path.subsection(start, end) {
            let nodes = cut_path.segments().iter().map(|segment|
                LaneStrokeNode{
                    position: segment.start(),
                    direction: segment.start_direction()
                }
            ).chain(cut_path.segments().last().map(|last_segment|
                LaneStrokeNode{
                    position: last_segment.end(),
                    direction: last_segment.end_direction()
                }
            ).into_iter()).collect();
            LaneStroke::new(nodes).ok()
        } else {None}
    }

    pub fn with_subsection_moved(&self, start: N, end: N, delta: V2) -> MovedSubsectionInfo {
        let nodes_before = self.nodes.iter().take_while(|node|
            self.path().project(node.position).unwrap() < start - 5.0
        ).cloned().collect::<Vec<_>>();

        let new_subsection = self.subsection(start, end).into_iter()
            .flat_map(|subsection| subsection.nodes)
            .map(|node| LaneStrokeNode{
                position: node.position + delta,
                direction: node.direction
            }).collect::<Vec<_>>();

        let nodes_after = self.nodes.iter().skip_while(|node|
            self.path().project(node.position).unwrap() < end + 5.0
        ).cloned().collect::<Vec<_>>();

        let mut maybe_before_connector = None;
        let mut maybe_after_connector = None;

        if let (Some(&last_node_before), Some(&first_moved_node)) = (nodes_before.last(), new_subsection.get(0)) {
            maybe_before_connector = biarc_connection_node(last_node_before, first_moved_node);
        }

        if let (Some(&last_moved_node), Some(&first_node_after)) = (new_subsection.last(), nodes_after.get(0)) {
            maybe_after_connector = biarc_connection_node(last_moved_node, first_node_after);
        }

        (nodes_before, maybe_before_connector, new_subsection, maybe_after_connector, nodes_after)
     }

    pub fn build(&self, report_to: ID, report_as: BuildableRef) {
        Swarm::<Lane>::all() << CreateWith(
            Lane::new(self.path().clone(), false, CVec::new()),
            AdvertiseToTransferAndReport(report_to, report_as)
        );
    }

    pub fn build_intersection(&self, report_to: ID, report_as: BuildableRef, timings: CVec<bool>) {
        Swarm::<Lane>::all() << CreateWith(
            Lane::new(self.path().clone(), true, timings),
            AdvertiseToTransferAndReport(report_to, report_as)
        );
    }

    pub fn build_transfer(&self, report_to: ID, report_as: BuildableRef) {
        Swarm::<TransferLane>::all() << CreateWith(
            TransferLane::new(self.path().clone()),
            AdvertiseToTransferAndReport(report_to, report_as)
        );
    }
}

pub type MovedSubsectionInfo = (
    Vec<LaneStrokeNode>,
    Option<LaneStrokeNode>,
    Vec<LaneStrokeNode>,
    Option<LaneStrokeNode>,
    Vec<LaneStrokeNode>
);

fn biarc_connection_node(start_node: LaneStrokeNode, end_node: LaneStrokeNode) -> Option<LaneStrokeNode> {
    let connection_segments = Segment::biarc(
        start_node.position, start_node.direction,
        end_node.position, end_node.direction
    );

    if connection_segments.len() > 1 {
        let connection_node = LaneStrokeNode{
            position: connection_segments[0].end(),
            direction: connection_segments[0].end_direction()
        };
        if !connection_node.position.is_roughly_within(start_node.position, MIN_NODE_DISTANCE)
        && !connection_node.position.is_roughly_within(end_node.position, MIN_NODE_DISTANCE) {
            Some(connection_node)
        } else {None}
    } else {None}
}

impl<'a> RoughlyComparable for &'a LaneStroke {
    fn is_roughly_within(&self, other: &LaneStroke, tolerance: N) -> bool {
        self.nodes.len() == other.nodes.len()
        && self.nodes.iter().zip(other.nodes.iter()).all(|(n1, n2)|
            n1.is_roughly_within(n2, tolerance)
        )
    }
}

#[derive(Copy, Clone)]
pub struct LaneStrokeNode {
    pub position: P2,
    pub direction: V2
}

impl<'a> RoughlyComparable for &'a LaneStrokeNode {
    fn is_roughly_within(&self, other: &LaneStrokeNode, tolerance: N) -> bool {
        self.position.is_roughly_within(other.position, tolerance)
        // && (
        //     (self.direction.is_none() && other.direction.is_none())
        //     || (self.direction.is_some() && other.direction.is_some()
        //         && self.direction.unwrap().is_roughly_within(other.direction.unwrap(), tolerance)))
    }
}<|endoftext|>


<commit_before>use std::collections::hash_map::{self, HashMap};
use utils::address::Address;
use utils::bigint::{M256, U256};

use vm::Storage;
use vm::errors::{RequireError, CommitError};

#[derive(Debug, Clone)]
pub enum AccountCommitment<S> {
    Full {
        nonce: M256,
        address: Address,
        balance: U256,
        storage: S,
        code: Vec<u8>,
    },
    Code {
        address: Address,
        code: Vec<u8>,
    },
}

impl<S: Storage> AccountCommitment<S> {
    pub fn address(&self) -> Address {
        match self {
            &AccountCommitment::Full {
                address,
                ..
            } => address,
            &AccountCommitment::Code {
                address,
                ..
            } => address,
        }
    }
}

#[derive(Debug, Clone)]
pub enum Account<S> {
    Full {
        nonce: M256,
        address: Address,
        balance: U256,
        storage: S,
        code: Vec<u8>,
    },
    IncreaseBalance(Address, U256),
    DecreaseBalance(Address, U256),
}

impl<S: Storage> Account<S> {
    pub fn address(&self) -> Address {
        match self {
            &Account::Full {
                address,
                ..
            } => address,
            &Account::IncreaseBalance(address, _) => address,
            &Account::DecreaseBalance(address, _) => address,
        }
    }
}

#[derive(Debug, Clone)]
pub struct AccountState<S> {
    accounts: HashMap<Address, Account<S>>,
    codes: HashMap<Address, Vec<u8>>,
}

impl<S: Storage> Default for AccountState<S> {
    fn default() -> Self {
        Self {
            accounts: HashMap::new(),
            codes: HashMap::new(),
        }
    }
}

impl<S: Storage + Default + Clone> AccountState<S> {
    pub fn accounts(&self) -> hash_map::Values<Address, Account<S>> {
        self.accounts.values()
    }

    pub fn require(&self, address: Address) -> Result<(), RequireError> {
        match self.accounts.get(&address) {
            Some(&Account::Full { .. }) => return Ok(()),
            _ => return Err(RequireError::Account(address)),
        }
    }

    pub fn require_code(&self, address: Address) -> Result<(), RequireError> {
        if self.codes.contains_key(&address) {
            return Ok(());
        }
        match self.accounts.get(&address) {
            Some(&Account::Full { .. }) => return Ok(()),
            _ => return Err(RequireError::AccountCode(address)),
        }
    }

    pub fn commit(&mut self, commitment: AccountCommitment<S>) -> Result<(), CommitError> {
        match commitment {
            AccountCommitment::Full {
                nonce,
                address,
                balance,
                storage,
                code
            } => {
                if self.accounts.contains_key(&address) {
                    return Err(CommitError::AlreadyCommitted);
                }

                self.accounts.insert(address, Account::Full {
                    nonce,
                    address,
                    balance,
                    storage,
                    code,
                });
            },
            AccountCommitment::Code {
                address,
                code,
            } => {
                if self.accounts.contains_key(&address) || self.codes.contains_key(&address) {
                    return Err(CommitError::AlreadyCommitted);
                }

                self.codes.insert(address, code);
            }
        }
        Ok(())
    }

    pub fn code(&self, address: Address) -> Result<&[u8], RequireError> {
        if self.codes.contains_key(&address) {
            return Ok(self.codes.get(&address).unwrap().as_slice());
        }

        if self.accounts.contains_key(&address) {
            match self.accounts.get(&address).unwrap() {
                &Account::Full {
                    ref code,
                    ..
                } => return Ok(code.as_slice()),
                _ => (),
            }
        }

        return Err(RequireError::AccountCode(address));
    }

    pub fn nonce(&self, address: Address) -> Result<M256, RequireError> {
        if self.accounts.contains_key(&address) {
            match self.accounts.get(&address).unwrap() {
                &Account::Full {
                    nonce,
                    ..
                } => return Ok(nonce),
                _ => (),
            }
        }

        return Err(RequireError::Account(address));
    }

    pub fn balance(&self, address: Address) -> Result<U256, RequireError> {
        if self.accounts.contains_key(&address) {
            match self.accounts.get(&address).unwrap() {
                &Account::Full {
                    balance,
                    ..
                } => return Ok(balance),
                _ => (),
            }
        }

        return Err(RequireError::Account(address));
    }

    pub fn storage(&self, address: Address) -> Result<&S, RequireError> {
        if self.accounts.contains_key(&address) {
            match self.accounts.get(&address).unwrap() {
                &Account::Full {
                    ref storage,
                    ..
                } => return Ok(storage),
                _ => (),
            }
        }

        return Err(RequireError::Account(address));
    }

    pub fn storage_mut(&mut self, address: Address) -> Result<&mut S, RequireError> {
        if self.accounts.contains_key(&address) {
            match self.accounts.get_mut(&address).unwrap() {
                &mut Account::Full {
                    ref mut storage,
                    ..
                } => return Ok(storage),
                _ => (),
            }
        }

        return Err(RequireError::Account(address));
    }

    pub fn create(&mut self, address: Address, balance: U256, code: &[u8]) {
        self.accounts.insert(address, Account::Full {
            address, balance, storage: S::default(), code: code.into(), nonce: M256::zero(),
        });
    }

    pub fn increase_balance(&mut self, address: Address, topup: U256) {
        assert!(topup != U256::zero());
        let account = match self.accounts.remove(&address) {
            Some(Account::Full {
                address,
                balance,
                storage,
                code,
                nonce,
            }) => {
                Some(Account::Full {
                    address,
                    balance: balance + topup,
                    storage,
                    code,
                    nonce,
                })
            },
            Some(Account::IncreaseBalance(address, balance)) => {
                Some(Account::IncreaseBalance(address, balance + topup))
            },
            Some(Account::DecreaseBalance(address, balance)) => {
                if balance == topup {
                    None
                } else if balance > topup {
                    Some(Account::DecreaseBalance(address, balance - topup))
                } else {
                    Some(Account::IncreaseBalance(address, topup - balance))
                }
            },
            None => {
                Some(Account::IncreaseBalance(address, topup))
            },
        };
        if account.is_some() {
            self.accounts.insert(address, account.unwrap());
        }
    }

    pub fn decrease_balance(&mut self, address: Address, withdraw: U256) {
        assert!(withdraw != U256::zero());
        let account = match self.accounts.remove(&address) {
            Some(Account::Full {
                address,
                balance,
                storage,
                code,
                nonce,
            }) => {
                Some(Account::Full {
                    address,
                    balance: balance - withdraw,
                    storage,
                    code,
                    nonce,
                })
            },
            Some(Account::DecreaseBalance(address, balance)) => {
                Some(Account::DecreaseBalance(address, balance - withdraw))
            },
            Some(Account::IncreaseBalance(address, balance)) => {
                if balance == withdraw {
                    None
                } else if balance > withdraw {
                    Some(Account::IncreaseBalance(address, balance - withdraw))
                } else {
                    Some(Account::DecreaseBalance(address, withdraw - balance))
                }
            },
            None => {
                Some(Account::DecreaseBalance(address, withdraw))
            },
        };
        if account.is_some() {
            self.accounts.insert(address, account.unwrap());
        }
    }

    pub fn set_nonce(&mut self, address: Address, new_nonce: M256) -> Result<(), RequireError> {
        match self.accounts.get_mut(&address) {
            Some(&mut Account::Full {
                ref mut nonce,
                ..
            }) => {
                *nonce = new_nonce;
                Ok(())
            },
            _ => {
                Err(RequireError::Account(address))
            },
        }
    }

    pub fn remove(&mut self, address: Address) -> Result<(), RequireError> {
        let account = match self.accounts.remove(&address) {
            Some(Account::Full {
                address,
                ..
            }) => {
                Account::Full {
                    address,
                    balance: U256::zero(),
                    storage: S::default(),
                    code: Vec::new(),
                    nonce: M256::zero(),
                }
            },
            Some(Account::DecreaseBalance(address, _)) => {
                return Err(RequireError::Account(address));
            },
            Some(Account::IncreaseBalance(address, _)) => {
                return Err(RequireError::Account(address));
            },
            None => {
                return Err(RequireError::Account(address));
            },
        };
        self.accounts.insert(address, account);
        Ok(())
    }
}
<commit_msg>Problem: zero topup and withdraw fails Solution: remove the assert!<commit_after>use std::collections::hash_map::{self, HashMap};
use utils::address::Address;
use utils::bigint::{M256, U256};

use vm::Storage;
use vm::errors::{RequireError, CommitError};

#[derive(Debug, Clone)]
pub enum AccountCommitment<S> {
    Full {
        nonce: M256,
        address: Address,
        balance: U256,
        storage: S,
        code: Vec<u8>,
    },
    Code {
        address: Address,
        code: Vec<u8>,
    },
}

impl<S: Storage> AccountCommitment<S> {
    pub fn address(&self) -> Address {
        match self {
            &AccountCommitment::Full {
                address,
                ..
            } => address,
            &AccountCommitment::Code {
                address,
                ..
            } => address,
        }
    }
}

#[derive(Debug, Clone)]
pub enum Account<S> {
    Full {
        nonce: M256,
        address: Address,
        balance: U256,
        storage: S,
        code: Vec<u8>,
    },
    IncreaseBalance(Address, U256),
    DecreaseBalance(Address, U256),
}

impl<S: Storage> Account<S> {
    pub fn address(&self) -> Address {
        match self {
            &Account::Full {
                address,
                ..
            } => address,
            &Account::IncreaseBalance(address, _) => address,
            &Account::DecreaseBalance(address, _) => address,
        }
    }
}

#[derive(Debug, Clone)]
pub struct AccountState<S> {
    accounts: HashMap<Address, Account<S>>,
    codes: HashMap<Address, Vec<u8>>,
}

impl<S: Storage> Default for AccountState<S> {
    fn default() -> Self {
        Self {
            accounts: HashMap::new(),
            codes: HashMap::new(),
        }
    }
}

impl<S: Storage + Default + Clone> AccountState<S> {
    pub fn accounts(&self) -> hash_map::Values<Address, Account<S>> {
        self.accounts.values()
    }

    pub fn require(&self, address: Address) -> Result<(), RequireError> {
        match self.accounts.get(&address) {
            Some(&Account::Full { .. }) => return Ok(()),
            _ => return Err(RequireError::Account(address)),
        }
    }

    pub fn require_code(&self, address: Address) -> Result<(), RequireError> {
        if self.codes.contains_key(&address) {
            return Ok(());
        }
        match self.accounts.get(&address) {
            Some(&Account::Full { .. }) => return Ok(()),
            _ => return Err(RequireError::AccountCode(address)),
        }
    }

    pub fn commit(&mut self, commitment: AccountCommitment<S>) -> Result<(), CommitError> {
        match commitment {
            AccountCommitment::Full {
                nonce,
                address,
                balance,
                storage,
                code
            } => {
                if self.accounts.contains_key(&address) {
                    return Err(CommitError::AlreadyCommitted);
                }

                self.accounts.insert(address, Account::Full {
                    nonce,
                    address,
                    balance,
                    storage,
                    code,
                });
            },
            AccountCommitment::Code {
                address,
                code,
            } => {
                if self.accounts.contains_key(&address) || self.codes.contains_key(&address) {
                    return Err(CommitError::AlreadyCommitted);
                }

                self.codes.insert(address, code);
            }
        }
        Ok(())
    }

    pub fn code(&self, address: Address) -> Result<&[u8], RequireError> {
        if self.codes.contains_key(&address) {
            return Ok(self.codes.get(&address).unwrap().as_slice());
        }

        if self.accounts.contains_key(&address) {
            match self.accounts.get(&address).unwrap() {
                &Account::Full {
                    ref code,
                    ..
                } => return Ok(code.as_slice()),
                _ => (),
            }
        }

        return Err(RequireError::AccountCode(address));
    }

    pub fn nonce(&self, address: Address) -> Result<M256, RequireError> {
        if self.accounts.contains_key(&address) {
            match self.accounts.get(&address).unwrap() {
                &Account::Full {
                    nonce,
                    ..
                } => return Ok(nonce),
                _ => (),
            }
        }

        return Err(RequireError::Account(address));
    }

    pub fn balance(&self, address: Address) -> Result<U256, RequireError> {
        if self.accounts.contains_key(&address) {
            match self.accounts.get(&address).unwrap() {
                &Account::Full {
                    balance,
                    ..
                } => return Ok(balance),
                _ => (),
            }
        }

        return Err(RequireError::Account(address));
    }

    pub fn storage(&self, address: Address) -> Result<&S, RequireError> {
        if self.accounts.contains_key(&address) {
            match self.accounts.get(&address).unwrap() {
                &Account::Full {
                    ref storage,
                    ..
                } => return Ok(storage),
                _ => (),
            }
        }

        return Err(RequireError::Account(address));
    }

    pub fn storage_mut(&mut self, address: Address) -> Result<&mut S, RequireError> {
        if self.accounts.contains_key(&address) {
            match self.accounts.get_mut(&address).unwrap() {
                &mut Account::Full {
                    ref mut storage,
                    ..
                } => return Ok(storage),
                _ => (),
            }
        }

        return Err(RequireError::Account(address));
    }

    pub fn create(&mut self, address: Address, balance: U256, code: &[u8]) {
        self.accounts.insert(address, Account::Full {
            address, balance, storage: S::default(), code: code.into(), nonce: M256::zero(),
        });
    }

    pub fn increase_balance(&mut self, address: Address, topup: U256) {
        if topup == U256::zero() { return; }
        let account = match self.accounts.remove(&address) {
            Some(Account::Full {
                address,
                balance,
                storage,
                code,
                nonce,
            }) => {
                Some(Account::Full {
                    address,
                    balance: balance + topup,
                    storage,
                    code,
                    nonce,
                })
            },
            Some(Account::IncreaseBalance(address, balance)) => {
                Some(Account::IncreaseBalance(address, balance + topup))
            },
            Some(Account::DecreaseBalance(address, balance)) => {
                if balance == topup {
                    None
                } else if balance > topup {
                    Some(Account::DecreaseBalance(address, balance - topup))
                } else {
                    Some(Account::IncreaseBalance(address, topup - balance))
                }
            },
            None => {
                Some(Account::IncreaseBalance(address, topup))
            },
        };
        if account.is_some() {
            self.accounts.insert(address, account.unwrap());
        }
    }

    pub fn decrease_balance(&mut self, address: Address, withdraw: U256) {
        if withdraw == U256::zero() { return; }
        let account = match self.accounts.remove(&address) {
            Some(Account::Full {
                address,
                balance,
                storage,
                code,
                nonce,
            }) => {
                Some(Account::Full {
                    address,
                    balance: balance - withdraw,
                    storage,
                    code,
                    nonce,
                })
            },
            Some(Account::DecreaseBalance(address, balance)) => {
                Some(Account::DecreaseBalance(address, balance - withdraw))
            },
            Some(Account::IncreaseBalance(address, balance)) => {
                if balance == withdraw {
                    None
                } else if balance > withdraw {
                    Some(Account::IncreaseBalance(address, balance - withdraw))
                } else {
                    Some(Account::DecreaseBalance(address, withdraw - balance))
                }
            },
            None => {
                Some(Account::DecreaseBalance(address, withdraw))
            },
        };
        if account.is_some() {
            self.accounts.insert(address, account.unwrap());
        }
    }

    pub fn set_nonce(&mut self, address: Address, new_nonce: M256) -> Result<(), RequireError> {
        match self.accounts.get_mut(&address) {
            Some(&mut Account::Full {
                ref mut nonce,
                ..
            }) => {
                *nonce = new_nonce;
                Ok(())
            },
            _ => {
                Err(RequireError::Account(address))
            },
        }
    }

    pub fn remove(&mut self, address: Address) -> Result<(), RequireError> {
        let account = match self.accounts.remove(&address) {
            Some(Account::Full {
                address,
                ..
            }) => {
                Account::Full {
                    address,
                    balance: U256::zero(),
                    storage: S::default(),
                    code: Vec::new(),
                    nonce: M256::zero(),
                }
            },
            Some(Account::DecreaseBalance(address, _)) => {
                return Err(RequireError::Account(address));
            },
            Some(Account::IncreaseBalance(address, _)) => {
                return Err(RequireError::Account(address));
            },
            None => {
                return Err(RequireError::Account(address));
            },
        };
        self.accounts.insert(address, account);
        Ok(())
    }
}
<|endoftext|>


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

// #[warn(deprecated_mode)];

use middle::ty;

use middle::typeck::isr_alist;
use util::common::indenter;
use util::ppaux::region_to_str;
use util::ppaux;

use extra::list::Cons;

// Helper functions related to manipulating region types.

pub fn replace_bound_regions_in_fn_sig(
    tcx: ty::ctxt,
    isr: isr_alist,
    opt_self_ty: Option<ty::t>,
    fn_sig: &ty::FnSig,
    mapf: &fn(ty::bound_region) -> ty::Region)
    -> (isr_alist, Option<ty::t>, ty::FnSig)
{
    let mut all_tys = ty::tys_in_fn_sig(fn_sig);

    for &self_ty in opt_self_ty.iter() {
        all_tys.push(self_ty);
    }

    for &t in opt_self_ty.iter() { all_tys.push(t) }

    debug2!("replace_bound_regions_in_fn_sig(self_ty={:?}, fn_sig={}, \
            all_tys={:?})",
           opt_self_ty.map(|t| ppaux::ty_to_str(tcx, *t)),
           ppaux::fn_sig_to_str(tcx, fn_sig),
           all_tys.map(|t| ppaux::ty_to_str(tcx, *t)));
    let _i = indenter();

    let isr = do create_bound_region_mapping(tcx, isr, all_tys) |br| {
        debug2!("br={:?}", br);
        mapf(br)
    };
    let new_fn_sig = ty::fold_sig(fn_sig, |t| {
        replace_bound_regions(tcx, isr, t)
    });
    let new_self_ty = opt_self_ty.map(|t| replace_bound_regions(tcx, isr, *t));

    debug2!("result of replace_bound_regions_in_fn_sig: \
            new_self_ty={:?}, \
            fn_sig={}",
           new_self_ty.map(|t| ppaux::ty_to_str(tcx, *t)),
           ppaux::fn_sig_to_str(tcx, &new_fn_sig));

    return (isr, new_self_ty, new_fn_sig);

    // Takes `isr`, a (possibly empty) mapping from in-scope region
    // names ("isr"s) to their corresponding regions; `tys`, a list of
    // types, and `to_r`, a closure that takes a bound_region and
    // returns a region.  Returns an updated version of `isr`,
    // extended with the in-scope region names from all of the bound
    // regions appearing in the types in the `tys` list (if they're
    // not in `isr` already), with each of those in-scope region names
    // mapped to a region that's the result of applying `to_r` to
    // itself.
    fn create_bound_region_mapping(
        tcx: ty::ctxt,
        isr: isr_alist,
        tys: ~[ty::t],
        to_r: &fn(ty::bound_region) -> ty::Region) -> isr_alist {

        // Takes `isr` (described above), `to_r` (described above),
        // and `r`, a region.  If `r` is anything other than a bound
        // region, or if it's a bound region that already appears in
        // `isr`, then we return `isr` unchanged.  If `r` is a bound
        // region that doesn't already appear in `isr`, we return an
        // updated isr_alist that now contains a mapping from `r` to
        // the result of calling `to_r` on it.
        fn append_isr(isr: isr_alist,
                      to_r: &fn(ty::bound_region) -> ty::Region,
                      r: ty::Region) -> isr_alist {
            match r {
              ty::re_empty | ty::re_free(*) | ty::re_static | ty::re_scope(_) |
              ty::re_infer(_) => {
                isr
              }
              ty::re_bound(br) => {
                match isr.find(br) {
                  Some(_) => isr,
                  None => @Cons((br, to_r(br)), isr)
                }
              }
            }
        }

        // For each type `ty` in `tys`...
        do tys.iter().fold(isr) |isr, ty| {
            let mut isr = isr;

            // Using fold_regions is inefficient, because it
            // constructs new types, but it avoids code duplication in
            // terms of locating all the regions within the various
            // kinds of types.  This had already caused me several
            // bugs so I decided to switch over.
            do ty::fold_regions(tcx, *ty) |r, in_fn| {
                if !in_fn { isr = append_isr(isr, |br| to_r(br), r); }
                r
            };

            isr
        }
    }

    // Takes `isr`, a mapping from in-scope region names ("isr"s) to
    // their corresponding regions; and `ty`, a type.  Returns an
    // updated version of `ty`, in which bound regions in `ty` have
    // been replaced with the corresponding bindings in `isr`.
    fn replace_bound_regions(
        tcx: ty::ctxt,
        isr: isr_alist,
        ty: ty::t) -> ty::t {

        do ty::fold_regions(tcx, ty) |r, in_fn| {
            let r1 = match r {
              // As long as we are not within a fn() type, `&T` is
              // mapped to the free region anon_r.  But within a fn
              // type, it remains bound.
              ty::re_bound(ty::br_anon(_)) if in_fn => r,

              ty::re_bound(br) => {
                match isr.find(br) {
                  // In most cases, all named, bound regions will be
                  // mapped to some free region.
                  Some(fr) => fr,

                  // But in the case of a fn() type, there may be
                  // named regions within that remain bound:
                  None if in_fn => r,
                  None => {
                    tcx.sess.bug(
                        format!("Bound region not found in \
                              in_scope_regions list: {}",
                             region_to_str(tcx, "", false, r)));
                  }
                }
              }

              // Free regions like these just stay the same:
              ty::re_empty |
              ty::re_static |
              ty::re_scope(_) |
              ty::re_free(*) |
              ty::re_infer(_) => r
            };
            r1
        }
    }
}

pub fn relate_nested_regions(
    tcx: ty::ctxt,
    opt_region: Option<ty::Region>,
    ty: ty::t,
    relate_op: &fn(ty::Region, ty::Region))
{
    /*!
     *
     * This rather specialized function walks each region `r` that appear
     * in `ty` and invokes `relate_op(r_encl, r)` for each one.  `r_encl`
     * here is the region of any enclosing `&'r T` pointer.  If there is
     * no enclosing pointer, and `opt_region` is Some, then `opt_region.get()`
     * is used instead.  Otherwise, no callback occurs at all).
     *
     * Here are some examples to give you an intution:
     *
     * - `relate_nested_regions(Some('r1), &'r2 uint)` invokes
     *   - `relate_op('r1, 'r2)`
     * - `relate_nested_regions(Some('r1), &'r2 &'r3 uint)` invokes
     *   - `relate_op('r1, 'r2)`
     *   - `relate_op('r2, 'r3)`
     * - `relate_nested_regions(None, &'r2 &'r3 uint)` invokes
     *   - `relate_op('r2, 'r3)`
     * - `relate_nested_regions(None, &'r2 &'r3 &'r4 uint)` invokes
     *   - `relate_op('r2, 'r3)`
     *   - `relate_op('r2, 'r4)`
     *   - `relate_op('r3, 'r4)`
     *
     * This function is used in various pieces of code because we enforce the
     * constraint that a region pointer cannot outlive the things it points at.
     * Hence, in the second example above, `'r2` must be a subregion of `'r3`.
     */

    let mut the_stack = ~[];
    for &r in opt_region.iter() { the_stack.push(r); }
    walk_ty(tcx, &mut the_stack, ty, relate_op);

    fn walk_ty(tcx: ty::ctxt,
               the_stack: &mut ~[ty::Region],
               ty: ty::t,
               relate_op: &fn(ty::Region, ty::Region))
    {
        match ty::get(ty).sty {
            ty::ty_rptr(r, ref mt) |
            ty::ty_evec(ref mt, ty::vstore_slice(r)) => {
                relate(*the_stack, r, |x,y| relate_op(x,y));
                the_stack.push(r);
                walk_ty(tcx, the_stack, mt.ty, |x,y| relate_op(x,y));
                the_stack.pop();
            }
            _ => {
                ty::fold_regions_and_ty(
                    tcx,
                    ty,
                    |r| { relate(     *the_stack, r, |x,y| relate_op(x,y)); r },
                    |t| { walk_ty(tcx, the_stack, t, |x,y| relate_op(x,y)); t },
                    |t| { walk_ty(tcx, the_stack, t, |x,y| relate_op(x,y)); t });
            }
        }
    }

    fn relate(the_stack: &[ty::Region],
              r_sub: ty::Region,
              relate_op: &fn(ty::Region, ty::Region))
    {
        for &r in the_stack.iter() {
            if !r.is_bound() && !r_sub.is_bound() {
                relate_op(r, r_sub);
            }
        }
    }
}

pub fn relate_free_regions(
    tcx: ty::ctxt,
    self_ty: Option<ty::t>,
    fn_sig: &ty::FnSig)
{
    /*!
     * This function populates the region map's `free_region_map`.
     * It walks over the transformed self type and argument types
     * for each function just before we check the body of that
     * function, looking for types where you have a borrowed
     * pointer to other borrowed data (e.g., `&'a &'b [uint]`.
     * We do not allow borrowed pointers to outlive the things they
     * point at, so we can assume that `'a <= 'b`.
     *
     * Tests: `src/test/compile-fail/regions-free-region-ordering-*.rs`
     */

    debug2!("relate_free_regions >>");

    let mut all_tys = ~[];
    for arg in fn_sig.inputs.iter() {
        all_tys.push(*arg);
    }
    for &t in self_ty.iter() {
        all_tys.push(t);
    }

    for &t in all_tys.iter() {
        debug2!("relate_free_regions(t={})", ppaux::ty_to_str(tcx, t));
        relate_nested_regions(tcx, None, t, |a, b| {
            match (&a, &b) {
                (&ty::re_free(free_a), &ty::re_free(free_b)) => {
                    tcx.region_maps.relate_free_regions(free_a, free_b);
                }
                _ => {}
            }
        })
    }

    debug2!("<< relate_free_regions");
}
<commit_msg>auto merge of #9729 : dwrensha/rust/regionmanip-cleanup, r=catamorphism<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// #[warn(deprecated_mode)];

use middle::ty;

use middle::typeck::isr_alist;
use util::common::indenter;
use util::ppaux::region_to_str;
use util::ppaux;

use extra::list::Cons;

// Helper functions related to manipulating region types.

pub fn replace_bound_regions_in_fn_sig(
    tcx: ty::ctxt,
    isr: isr_alist,
    opt_self_ty: Option<ty::t>,
    fn_sig: &ty::FnSig,
    mapf: &fn(ty::bound_region) -> ty::Region)
    -> (isr_alist, Option<ty::t>, ty::FnSig)
{
    let mut all_tys = ty::tys_in_fn_sig(fn_sig);

    for &t in opt_self_ty.iter() { all_tys.push(t) }

    debug2!("replace_bound_regions_in_fn_sig(self_ty={:?}, fn_sig={}, \
            all_tys={:?})",
           opt_self_ty.map(|t| ppaux::ty_to_str(tcx, *t)),
           ppaux::fn_sig_to_str(tcx, fn_sig),
           all_tys.map(|t| ppaux::ty_to_str(tcx, *t)));
    let _i = indenter();

    let isr = do create_bound_region_mapping(tcx, isr, all_tys) |br| {
        debug2!("br={:?}", br);
        mapf(br)
    };
    let new_fn_sig = ty::fold_sig(fn_sig, |t| {
        replace_bound_regions(tcx, isr, t)
    });
    let new_self_ty = opt_self_ty.map(|t| replace_bound_regions(tcx, isr, *t));

    debug2!("result of replace_bound_regions_in_fn_sig: \
            new_self_ty={:?}, \
            fn_sig={}",
           new_self_ty.map(|t| ppaux::ty_to_str(tcx, *t)),
           ppaux::fn_sig_to_str(tcx, &new_fn_sig));

    return (isr, new_self_ty, new_fn_sig);

    // Takes `isr`, a (possibly empty) mapping from in-scope region
    // names ("isr"s) to their corresponding regions; `tys`, a list of
    // types, and `to_r`, a closure that takes a bound_region and
    // returns a region.  Returns an updated version of `isr`,
    // extended with the in-scope region names from all of the bound
    // regions appearing in the types in the `tys` list (if they're
    // not in `isr` already), with each of those in-scope region names
    // mapped to a region that's the result of applying `to_r` to
    // itself.
    fn create_bound_region_mapping(
        tcx: ty::ctxt,
        isr: isr_alist,
        tys: ~[ty::t],
        to_r: &fn(ty::bound_region) -> ty::Region) -> isr_alist {

        // Takes `isr` (described above), `to_r` (described above),
        // and `r`, a region.  If `r` is anything other than a bound
        // region, or if it's a bound region that already appears in
        // `isr`, then we return `isr` unchanged.  If `r` is a bound
        // region that doesn't already appear in `isr`, we return an
        // updated isr_alist that now contains a mapping from `r` to
        // the result of calling `to_r` on it.
        fn append_isr(isr: isr_alist,
                      to_r: &fn(ty::bound_region) -> ty::Region,
                      r: ty::Region) -> isr_alist {
            match r {
              ty::re_empty | ty::re_free(*) | ty::re_static | ty::re_scope(_) |
              ty::re_infer(_) => {
                isr
              }
              ty::re_bound(br) => {
                match isr.find(br) {
                  Some(_) => isr,
                  None => @Cons((br, to_r(br)), isr)
                }
              }
            }
        }

        // For each type `ty` in `tys`...
        do tys.iter().fold(isr) |isr, ty| {
            let mut isr = isr;

            // Using fold_regions is inefficient, because it
            // constructs new types, but it avoids code duplication in
            // terms of locating all the regions within the various
            // kinds of types.  This had already caused me several
            // bugs so I decided to switch over.
            do ty::fold_regions(tcx, *ty) |r, in_fn| {
                if !in_fn { isr = append_isr(isr, |br| to_r(br), r); }
                r
            };

            isr
        }
    }

    // Takes `isr`, a mapping from in-scope region names ("isr"s) to
    // their corresponding regions; and `ty`, a type.  Returns an
    // updated version of `ty`, in which bound regions in `ty` have
    // been replaced with the corresponding bindings in `isr`.
    fn replace_bound_regions(
        tcx: ty::ctxt,
        isr: isr_alist,
        ty: ty::t) -> ty::t {

        do ty::fold_regions(tcx, ty) |r, in_fn| {
            let r1 = match r {
              // As long as we are not within a fn() type, `&T` is
              // mapped to the free region anon_r.  But within a fn
              // type, it remains bound.
              ty::re_bound(ty::br_anon(_)) if in_fn => r,

              ty::re_bound(br) => {
                match isr.find(br) {
                  // In most cases, all named, bound regions will be
                  // mapped to some free region.
                  Some(fr) => fr,

                  // But in the case of a fn() type, there may be
                  // named regions within that remain bound:
                  None if in_fn => r,
                  None => {
                    tcx.sess.bug(
                        format!("Bound region not found in \
                              in_scope_regions list: {}",
                             region_to_str(tcx, "", false, r)));
                  }
                }
              }

              // Free regions like these just stay the same:
              ty::re_empty |
              ty::re_static |
              ty::re_scope(_) |
              ty::re_free(*) |
              ty::re_infer(_) => r
            };
            r1
        }
    }
}

pub fn relate_nested_regions(
    tcx: ty::ctxt,
    opt_region: Option<ty::Region>,
    ty: ty::t,
    relate_op: &fn(ty::Region, ty::Region))
{
    /*!
     *
     * This rather specialized function walks each region `r` that appear
     * in `ty` and invokes `relate_op(r_encl, r)` for each one.  `r_encl`
     * here is the region of any enclosing `&'r T` pointer.  If there is
     * no enclosing pointer, and `opt_region` is Some, then `opt_region.get()`
     * is used instead.  Otherwise, no callback occurs at all).
     *
     * Here are some examples to give you an intution:
     *
     * - `relate_nested_regions(Some('r1), &'r2 uint)` invokes
     *   - `relate_op('r1, 'r2)`
     * - `relate_nested_regions(Some('r1), &'r2 &'r3 uint)` invokes
     *   - `relate_op('r1, 'r2)`
     *   - `relate_op('r2, 'r3)`
     * - `relate_nested_regions(None, &'r2 &'r3 uint)` invokes
     *   - `relate_op('r2, 'r3)`
     * - `relate_nested_regions(None, &'r2 &'r3 &'r4 uint)` invokes
     *   - `relate_op('r2, 'r3)`
     *   - `relate_op('r2, 'r4)`
     *   - `relate_op('r3, 'r4)`
     *
     * This function is used in various pieces of code because we enforce the
     * constraint that a region pointer cannot outlive the things it points at.
     * Hence, in the second example above, `'r2` must be a subregion of `'r3`.
     */

    let mut the_stack = ~[];
    for &r in opt_region.iter() { the_stack.push(r); }
    walk_ty(tcx, &mut the_stack, ty, relate_op);

    fn walk_ty(tcx: ty::ctxt,
               the_stack: &mut ~[ty::Region],
               ty: ty::t,
               relate_op: &fn(ty::Region, ty::Region))
    {
        match ty::get(ty).sty {
            ty::ty_rptr(r, ref mt) |
            ty::ty_evec(ref mt, ty::vstore_slice(r)) => {
                relate(*the_stack, r, |x,y| relate_op(x,y));
                the_stack.push(r);
                walk_ty(tcx, the_stack, mt.ty, |x,y| relate_op(x,y));
                the_stack.pop();
            }
            _ => {
                ty::fold_regions_and_ty(
                    tcx,
                    ty,
                    |r| { relate(     *the_stack, r, |x,y| relate_op(x,y)); r },
                    |t| { walk_ty(tcx, the_stack, t, |x,y| relate_op(x,y)); t },
                    |t| { walk_ty(tcx, the_stack, t, |x,y| relate_op(x,y)); t });
            }
        }
    }

    fn relate(the_stack: &[ty::Region],
              r_sub: ty::Region,
              relate_op: &fn(ty::Region, ty::Region))
    {
        for &r in the_stack.iter() {
            if !r.is_bound() && !r_sub.is_bound() {
                relate_op(r, r_sub);
            }
        }
    }
}

pub fn relate_free_regions(
    tcx: ty::ctxt,
    self_ty: Option<ty::t>,
    fn_sig: &ty::FnSig)
{
    /*!
     * This function populates the region map's `free_region_map`.
     * It walks over the transformed self type and argument types
     * for each function just before we check the body of that
     * function, looking for types where you have a borrowed
     * pointer to other borrowed data (e.g., `&'a &'b [uint]`.
     * We do not allow borrowed pointers to outlive the things they
     * point at, so we can assume that `'a <= 'b`.
     *
     * Tests: `src/test/compile-fail/regions-free-region-ordering-*.rs`
     */

    debug2!("relate_free_regions >>");

    let mut all_tys = ~[];
    for arg in fn_sig.inputs.iter() {
        all_tys.push(*arg);
    }
    for &t in self_ty.iter() {
        all_tys.push(t);
    }

    for &t in all_tys.iter() {
        debug2!("relate_free_regions(t={})", ppaux::ty_to_str(tcx, t));
        relate_nested_regions(tcx, None, t, |a, b| {
            match (&a, &b) {
                (&ty::re_free(free_a), &ty::re_free(free_b)) => {
                    tcx.region_maps.relate_free_regions(free_a, free_b);
                }
                _ => {}
            }
        })
    }

    debug2!("<< relate_free_regions");
}
<|endoftext|>


<commit_before>extern crate lcm;

mod exlcm {
    include!(concat!(env!("OUT_DIR"), "/exlcm/example_t.rs"));
}

fn main() {
    let mut lcm = lcm::Lcm::new();

    let mut my_data = exlcm::ExampleT::new();
    // let mut my_data = exlcm::Example::new();
    my_data.timestamp = 0;

    my_data.position[0] = 1.0;
    my_data.position[1] = 2.0;
    my_data.position[2] = 3.0;

    my_data.orientation[0] = 1.0;
    my_data.orientation[1] = 0.0;
    my_data.orientation[2] = 0.0;
    my_data.orientation[3] = 0.0;

    my_data.num_ranges = 15;
    my_data.ranges = (0..15).collect();

    my_data.name = "example string".to_string();
    my_data.enabled = true;

    match lcm.publish("EXAMPLE", &my_data) {
        Ok(()) => println!("Sent message."),
        Err(e) => println!("Failed to send message: {}", e)
    }
}
<commit_msg>Fix example to hnadle result.<commit_after>extern crate lcm;

mod exlcm {
    include!(concat!(env!("OUT_DIR"), "/exlcm/example_t.rs"));
}

fn main() {
    let mut lcm = lcm::Lcm::new().unwrap();

    let mut my_data = exlcm::ExampleT::new();
    // let mut my_data = exlcm::Example::new();
    my_data.timestamp = 0;

    my_data.position[0] = 1.0;
    my_data.position[1] = 2.0;
    my_data.position[2] = 3.0;

    my_data.orientation[0] = 1.0;
    my_data.orientation[1] = 0.0;
    my_data.orientation[2] = 0.0;
    my_data.orientation[3] = 0.0;

    my_data.num_ranges = 15;
    my_data.ranges = (0..15).collect();

    my_data.name = "example string".to_string();
    my_data.enabled = true;

    match lcm.publish("EXAMPLE", &my_data) {
        Ok(()) => println!("Sent message."),
        Err(e) => println!("Failed to send message: {}", e)
    }
}
<|endoftext|>


<commit_before>#![allow(unused_mut)]

pub use algorithms::percolation::Percolation;

pub use expectest::prelude::{be_true, be_false};

describe! percolation_tests {

    before_each {
        const SIDE_SIZE: usize = 4;
        let mut percolation = Percolation::new(SIDE_SIZE);
    }

    it "should open a cell" {
        percolation.open(1, 1);

        expect!(percolation.is_open(1, 1)).to(be_true());
    }

    it "should not be open cell which was not opened" {
        expect!(percolation.is_open(1, 1)).to(be_false());
    }

    it "should be full when opened cell is on the top" {
        percolation.open(1, 1);

        expect!(percolation.is_full(1, 1)).to(be_true());
    }

    it "should not be full cell which was not opened and locates on the top" {
        expect!(percolation.is_full(1, 1)).to(be_false());
    }

    it "should not be full when opened cell is not on the top" {
        percolation.open(2, 1);

        expect!(percolation.is_full(2, 1)).to(be_false());
    }

    it "should be full if a cell connects with cells on the top" {
        open_column_till_row(&mut percolation, 2, 1);

        expect!(percolation.is_full(2, 1)).to(be_true());
    }

    it "should not be full if a cell doesn't connect to a full cell on the top" {
        percolation.open(1, 1);
        percolation.open(2, 2);

        expect!(percolation.is_full(2, 2)).to(be_false());
    }

    it "should be full if a cell connects to a full cell on the left" {
        open_column_till_row(&mut percolation, 3, 1);
        percolation.open(3, 2);

        expect!(percolation.is_full(3, 2)).to(be_true());
    }

    it "should be full if a cell connects to a full cell on the right" {
        open_column_till_row(&mut percolation, 3, 3);
        percolation.open(3, 2);

        expect!(percolation.is_full(3, 2)).to(be_true());
    }

    it "should be full if a cell connects to a full cell on the bottom" {
        open_column_till_row(&mut percolation, SIDE_SIZE, 1);
        percolation.open(4, 2);
        percolation.open(4, 3);
        percolation.open(3, 3);

        expect!(percolation.is_full(3, 3)).to(be_true());
    }

    it "should percolate if one of bottom cells is full" {
        open_column_till_row(&mut percolation, SIDE_SIZE, 1);

        expect!(percolation.percolates()).to(be_true());
    }

    it "should not percolate when none of bottom cells is full" {
        expect!(percolation.percolates()).to(be_false());
    }

    it "should be full without matter on order of cell open operations" {
        percolation.open(SIDE_SIZE, 1);
        open_column_till_row(&mut percolation, SIDE_SIZE - 1, 1);

        expect!(percolation.is_full(SIDE_SIZE, 1)).to(be_true());
    }

    it "should not contain backwash" {
        open_column_till_row(&mut percolation, SIDE_SIZE, 1);
        percolation.open(SIDE_SIZE, SIDE_SIZE);

        expect!(percolation.is_full(SIDE_SIZE, SIDE_SIZE)).to(be_false());
    }
}

pub fn open_column_till_row(percolation: &mut Percolation, row: usize, col: usize) {
    for r in 1..row + 1 {
        percolation.open(r, col);
    }
}
<commit_msg>rewrite tests for better coverage<commit_after>#![allow(unused_mut)]

pub use algorithms::percolation::Percolation;

pub use expectest::prelude::{be_true, be_false};

describe! percolation_tests {

    before_each {
        const SIDE_SIZE: usize = 4;
        let mut percolation = Percolation::new(SIDE_SIZE);
    }

    it "should open a cell" {
        percolation.open(1, 1);

        expect!(percolation.is_open(1, 1)).to(be_true());
    }

    it "should not be open cell which was not opened" {
        expect!(percolation.is_open(1, 1)).to(be_false());
    }

    it "should be full when opened cell is on the top" {
        percolation.open(1, 1);

        expect!(percolation.is_full(1, 1)).to(be_true());
    }

    it "should not be full cell which was not opened and locates on the top" {
        expect!(percolation.is_full(1, 1)).to(be_false());
    }

    it "should not be full when opened cell is not on the top" {
        percolation.open(2, 1);

        expect!(percolation.is_full(2, 1)).to(be_false());
    }

    it "should be full if a cell connects with cells on the top" {
        percolation.open(2, 1);
        percolation.open(1, 1);

        expect!(percolation.is_full(2, 1)).to(be_true());
    }

    it "should not be full if a cell doesn't connect to a full cell on the top" {
        percolation.open(1, 1);
        percolation.open(2, 2);

        expect!(percolation.is_full(2, 2)).to(be_false());
    }

    it "should be full if a cell connects to a full cell on the left" {
        percolation.open(3, 2);
        open_column_till_row(&mut percolation, 3, 1);

        expect!(percolation.is_full(3, 2)).to(be_true());
    }

    it "should be full if a cell connects to a full cell on the right" {
        percolation.open(3, 2);
        open_column_till_row(&mut percolation, 3, 3);

        expect!(percolation.is_full(3, 2)).to(be_true());
    }

    it "should be full if a cell connects to a full cell on the bottom" {
        percolation.open(3, 3);
        open_column_till_row(&mut percolation, SIDE_SIZE, 1);
        percolation.open(4, 2);
        percolation.open(4, 3);

        expect!(percolation.is_full(3, 3)).to(be_true());
    }

    it "should percolate if one of bottom cells is full" {
        open_column_till_row(&mut percolation, SIDE_SIZE, 1);

        expect!(percolation.percolates()).to(be_true());
    }

    it "should not percolate when none of bottom cells is full" {
        expect!(percolation.percolates()).to(be_false());
    }

    it "should not contain backwash" {
        open_column_till_row(&mut percolation, SIDE_SIZE, 1);
        percolation.open(SIDE_SIZE, SIDE_SIZE);

        expect!(percolation.is_full(SIDE_SIZE, SIDE_SIZE)).to(be_false());
    }
}

pub fn open_column_till_row(percolation: &mut Percolation, row: usize, col: usize) {
    for r in 1..row + 1 {
        percolation.open(r, col);
    }
}
<|endoftext|>