diff --git a/docker/devenv/Dockerfile b/docker/devenv/Dockerfile index 4aeb64289..530a381d9 100644 --- a/docker/devenv/Dockerfile +++ b/docker/devenv/Dockerfile @@ -264,7 +264,8 @@ RUN set -eux; \ ./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION --default-host ${rustArch}; \ rm rustup-init; \ chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \ - rustup component add rustfmt; + rustup component add rustfmt; \ + rustup component add clippy; WORKDIR /usr/local diff --git a/render-wasm/lint b/render-wasm/lint new file mode 100755 index 000000000..53d695c3e --- /dev/null +++ b/render-wasm/lint @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# Enable debugging if the script is run with --debug +if [[ "$1" == "--debug" ]]; then + set -x +fi + +. ./_build_env + +ALLOWED_RULES=" + -A clippy::box_collection \ + -A clippy::clone_on_copy \ + -A clippy::derivable_impls \ + -A clippy::enum_variant_names \ + -A clippy::field_reassign_with_default \ + -A clippy::from_over_into \ + -A clippy::len_zero \ + -A clippy::manual_map \ + -A clippy::map_entry \ + -A clippy::missing_safety_doc \ + -A clippy::missing_transmute_annotations \ + -A clippy::needless_borrow \ + -A clippy::needless_borrows_for_generic_args \ + -A clippy::needless_range_loop \ + -A clippy::needless_return \ + -A clippy::redundant_closure \ + -A clippy::redundant_field_names \ + -A clippy::single_match \ + -A clippy::slow_vector_initialization \ + -A clippy::too_many_arguments \ + -A clippy::unnecessary_to_owned \ + -A clippy::unused_unit \ + -A clippy::unwrap_or_default \ + -A clippy::useless_format \ + -A clippy::wrong_self_convention \ + -A dead_code" + +# ./lint --fix +if [[ "$1" == "--fix" ]]; then + cargo clippy \ + --fix --allow-dirty \ + --target=wasm32-unknown-emscripten \ + -- -D warnings \ + $ALLOWED_RULES +else + cargo clippy \ + --target=wasm32-unknown-emscripten \ + -- -D warnings \ + $ALLOWED_RULES +fi diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs index 6a427d7ef..781141719 100644 --- a/render-wasm/src/main.rs +++ b/render-wasm/src/main.rs @@ -24,6 +24,22 @@ extern "C" { ) -> *const ::std::os::raw::c_void; } +macro_rules! with_state { + ($state:ident, $block:block) => { + let $state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); + $block + }; +} + +macro_rules! with_current_shape { + ($state:ident, |$shape:ident: &mut Shape| $block:block) => { + let $state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); + if let Some($shape) = $state.current_shape() { + $block + } + }; +} + fn init_gl() { unsafe { gl::load_with(|addr| { @@ -50,167 +66,167 @@ pub extern "C" fn clean_up() { #[no_mangle] pub extern "C" fn clear_cache() { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - let render_state = state.render_state(); - render_state.clear_cache(); + with_state!(state, { + let render_state = state.render_state(); + render_state.clear_cache(); + }); } #[no_mangle] pub extern "C" fn set_render_options(debug: u32, dpr: f32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - let render_state = state.render_state(); - - render_state.set_debug_flags(debug); - render_state.set_dpr(dpr); + with_state!(state, { + let render_state = state.render_state(); + render_state.set_debug_flags(debug); + render_state.set_dpr(dpr); + }); } #[no_mangle] pub extern "C" fn set_canvas_background(raw_color: u32) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - let color = skia::Color::new(raw_color); - state.set_background_color(color); + with_state!(state, { + let color = skia::Color::new(raw_color); + state.set_background_color(color); + }); } #[no_mangle] pub extern "C" fn render(timestamp: i32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - state.start_render_loop(timestamp).expect("Error rendering"); + with_state!(state, { + state.start_render_loop(timestamp).expect("Error rendering"); + }); } #[no_mangle] pub extern "C" fn render_from_cache() { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - state.render_from_cache(); + with_state!(state, { + state.render_from_cache(); + }); } #[no_mangle] pub extern "C" fn process_animation_frame(timestamp: i32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - state - .process_animation_frame(timestamp) - .expect("Error processing animation frame"); + with_state!(state, { + state + .process_animation_frame(timestamp) + .expect("Error processing animation frame"); + }); } #[no_mangle] pub extern "C" fn reset_canvas() { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - state.render_state().reset_canvas(); + with_state!(state, { + state.render_state().reset_canvas(); + }); } #[no_mangle] pub extern "C" fn resize_viewbox(width: i32, height: i32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - state.resize(width, height); + with_state!(state, { + state.resize(width, height); + }); } #[no_mangle] pub extern "C" fn set_view(zoom: f32, x: f32, y: f32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - let render_state = state.render_state(); - render_state.invalidate_cache_if_needed(); - render_state.viewbox.set_all(zoom, x, y); + with_state!(state, { + let render_state = state.render_state(); + render_state.invalidate_cache_if_needed(); + render_state.viewbox.set_all(zoom, x, y); + }); } #[no_mangle] pub extern "C" fn set_view_zoom(zoom: f32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - state.render_state().viewbox.set_zoom(zoom); + with_state!(state, { + state.render_state().viewbox.set_zoom(zoom); + }); } #[no_mangle] pub extern "C" fn set_view_xy(x: f32, y: f32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - state.render_state().viewbox.set_pan_xy(x, y); + with_state!(state, { + state.render_state().viewbox.set_pan_xy(x, y); + }); } #[no_mangle] pub extern "C" fn use_shape(a: u32, b: u32, c: u32, d: u32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - let id = uuid_from_u32_quartet(a, b, c, d); - state.use_shape(id); + with_state!(state, { + let id = uuid_from_u32_quartet(a, b, c, d); + state.use_shape(id); + }); } #[no_mangle] pub extern "C" fn set_shape_masked_group(masked: bool) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_masked(masked); - } + }); } #[no_mangle] pub extern "C" fn set_shape_bool_type(raw_bool_type: u8) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { - shape.set_bool_type(BoolType::from(raw_bool_type)) - } + with_current_shape!(state, |shape: &mut Shape| { + shape.set_bool_type(BoolType::from(raw_bool_type)); + }); } #[no_mangle] pub unsafe extern "C" fn set_shape_type(shape_type: u8) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_shape_type(Type::from(shape_type)); - } + }); } #[no_mangle] pub extern "C" fn set_shape_selrect(left: f32, top: f32, right: f32, bottom: f32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_selrect(left, top, right, bottom); - } + }); } #[no_mangle] pub extern "C" fn set_shape_clip_content(clip_content: bool) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_clip(clip_content); - } + }); } #[no_mangle] pub extern "C" fn set_shape_rotation(rotation: f32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_rotation(rotation); - } + }); } #[no_mangle] pub extern "C" fn set_shape_transform(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_transform(a, b, c, d, e, f); - } + }); } #[no_mangle] pub extern "C" fn add_shape_child(a: u32, b: u32, c: u32, d: u32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - let id = uuid_from_u32_quartet(a, b, c, d); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { + let id = uuid_from_u32_quartet(a, b, c, d); shape.add_child(id); - } + }); } #[no_mangle] pub extern "C" fn clear_shape_children() { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.clear_children(); - } + }); } #[no_mangle] pub extern "C" fn add_shape_solid_fill(raw_color: u32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { let color = skia::Color::new(raw_color); shape.add_fill(shapes::Fill::Solid(color)); - } + }); } #[no_mangle] @@ -221,14 +237,13 @@ pub extern "C" fn add_shape_linear_fill( end_y: f32, opacity: f32, ) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.add_fill(shapes::Fill::new_linear_gradient( (start_x, start_y), (end_x, end_y), opacity, - )) - } + )); + }); } #[no_mangle] @@ -240,15 +255,14 @@ pub extern "C" fn add_shape_radial_fill( opacity: f32, width: f32, ) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.add_fill(shapes::Fill::new_radial_gradient( (start_x, start_y), (end_x, end_y), opacity, width, - )) - } + )); + }); } #[no_mangle] @@ -260,58 +274,63 @@ pub extern "C" fn add_shape_fill_stops() { .map(|data| shapes::RawStopData::from_bytes(data.try_into().unwrap())) .collect(); - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape .add_fill_gradient_stops(entries) .expect("could not add gradient stops"); - } + }); + mem::free_bytes(); } #[no_mangle] pub extern "C" fn store_font(family_name_size: u32, font_size: u32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - unsafe { - let font_bytes = - Vec::::from_raw_parts(mem::buffer_ptr(), font_size as usize, font_size as usize); - let family_name = String::from_raw_parts( - mem::buffer_ptr().add(font_size as usize), - family_name_size as usize, - family_name_size as usize, - ); - match state.render_state().add_font(family_name, &font_bytes) { + with_state!(state, { + unsafe { + let font_bytes = Vec::::from_raw_parts( + mem::buffer_ptr(), + font_size as usize, + font_size as usize, + ); + let family_name = String::from_raw_parts( + mem::buffer_ptr().add(font_size as usize), + family_name_size as usize, + family_name_size as usize, + ); + match state.render_state().add_font(family_name, &font_bytes) { + Err(msg) => { + eprintln!("{}", msg); + } + _ => {} + } + mem::free_bytes(); + } + }); +} + +#[no_mangle] +pub extern "C" fn store_image(a: u32, b: u32, c: u32, d: u32) { + with_state!(state, { + let id = uuid_from_u32_quartet(a, b, c, d); + let image_bytes = mem::bytes(); + + match state.render_state().add_image(id, &image_bytes) { Err(msg) => { eprintln!("{}", msg); } _ => {} } + mem::free_bytes(); - } -} - -#[no_mangle] -pub extern "C" fn store_image(a: u32, b: u32, c: u32, d: u32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - let id = uuid_from_u32_quartet(a, b, c, d); - let image_bytes = mem::bytes(); - - match state.render_state().add_image(id, &image_bytes) { - Err(msg) => { - eprintln!("{}", msg); - } - _ => {} - } - - mem::free_bytes(); + }); } #[no_mangle] pub extern "C" fn is_image_cached(a: u32, b: u32, c: u32, d: u32) -> bool { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - let id = uuid_from_u32_quartet(a, b, c, d); - state.render_state().has_image(&id) + with_state!(state, { + let id = uuid_from_u32_quartet(a, b, c, d); + return state.render_state().has_image(&id); + }); } #[no_mangle] @@ -324,29 +343,26 @@ pub extern "C" fn add_shape_image_fill( width: i32, height: i32, ) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - let id = uuid_from_u32_quartet(a, b, c, d); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { + let id = uuid_from_u32_quartet(a, b, c, d); shape.add_fill(shapes::Fill::new_image_fill( id, (alpha * 0xff as f32).floor() as u8, (width, height), )); - } + }); } #[no_mangle] pub extern "C" fn clear_shape_fills() { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.clear_fills(); - } + }); } #[no_mangle] pub extern "C" fn set_shape_svg_raw_content() { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { let bytes = mem::bytes(); let svg_raw_content = String::from_utf8(bytes) .unwrap() @@ -355,62 +371,54 @@ pub extern "C" fn set_shape_svg_raw_content() { shape .set_svg_raw_content(svg_raw_content) .expect("Failed to set svg raw content"); - } + }); } #[no_mangle] pub extern "C" fn set_shape_blend_mode(mode: i32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_blend_mode(render::BlendMode::from(mode)); - } + }); } #[no_mangle] pub extern "C" fn set_shape_opacity(opacity: f32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_opacity(opacity); - } + }); } #[no_mangle] pub extern "C" fn set_shape_constraint_h(constraint: u8) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { - shape.set_constraint_h(ConstraintH::from(constraint)) - } + with_current_shape!(state, |shape: &mut Shape| { + shape.set_constraint_h(ConstraintH::from(constraint)); + }); } #[no_mangle] pub extern "C" fn set_shape_constraint_v(constraint: u8) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { - shape.set_constraint_v(ConstraintV::from(constraint)) - } + with_current_shape!(state, |shape: &mut Shape| { + shape.set_constraint_v(ConstraintV::from(constraint)); + }); } #[no_mangle] pub extern "C" fn set_shape_hidden(hidden: bool) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_hidden(hidden); - } + }); } #[no_mangle] pub extern "C" fn set_shape_blur(blur_type: u8, hidden: bool, value: f32) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_blur(blur_type, hidden, value); - } + }); } #[no_mangle] pub extern "C" fn set_shape_path_content() { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { let bytes = mem::bytes(); let raw_segments = bytes .chunks(size_of::()) @@ -419,48 +427,44 @@ pub extern "C" fn set_shape_path_content() { }) .collect(); shape.set_path_segments(raw_segments).unwrap(); - } + }); } #[no_mangle] pub extern "C" fn add_shape_center_stroke(width: f32, style: u8, cap_start: u8, cap_end: u8) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.add_stroke(shapes::Stroke::new_center_stroke( width, style, cap_start, cap_end, )); - } + }); } #[no_mangle] pub extern "C" fn add_shape_inner_stroke(width: f32, style: u8, cap_start: u8, cap_end: u8) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.add_stroke(shapes::Stroke::new_inner_stroke( width, style, cap_start, cap_end, - )) - } + )); + }); } #[no_mangle] pub extern "C" fn add_shape_outer_stroke(width: f32, style: u8, cap_start: u8, cap_end: u8) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.add_stroke(shapes::Stroke::new_outer_stroke( width, style, cap_start, cap_end, - )) - } + )); + }); } #[no_mangle] pub extern "C" fn add_shape_stroke_solid_fill(raw_color: u32) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { let color = skia::Color::new(raw_color); shape .set_stroke_fill(shapes::Fill::Solid(color)) .expect("could not add stroke solid fill"); - } + }); } #[no_mangle] @@ -471,8 +475,7 @@ pub extern "C" fn add_shape_stroke_linear_fill( end_y: f32, opacity: f32, ) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape .set_stroke_fill(shapes::Fill::new_linear_gradient( (start_x, start_y), @@ -480,7 +483,7 @@ pub extern "C" fn add_shape_stroke_linear_fill( opacity, )) .expect("could not add stroke linear fill"); - } + }); } #[no_mangle] @@ -492,8 +495,7 @@ pub extern "C" fn add_shape_stroke_radial_fill( opacity: f32, width: f32, ) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape .set_stroke_fill(shapes::Fill::new_radial_gradient( (start_x, start_y), @@ -502,7 +504,7 @@ pub extern "C" fn add_shape_stroke_radial_fill( width, )) .expect("could not add stroke radial fill"); - } + }); } #[no_mangle] @@ -514,13 +516,12 @@ pub extern "C" fn add_shape_stroke_stops() { .map(|data| shapes::RawStopData::from_bytes(data.try_into().unwrap())) .collect(); - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape .add_stroke_gradient_stops(entries) .expect("could not add gradient stops"); - } + }); + mem::free_bytes(); } @@ -552,9 +553,8 @@ pub extern "C" fn add_shape_image_stroke( width: i32, height: i32, ) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - let id = uuid_from_u32_quartet(a, b, c, d); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { + let id = uuid_from_u32_quartet(a, b, c, d); shape .set_stroke_fill(shapes::Fill::new_image_fill( id, @@ -562,30 +562,26 @@ pub extern "C" fn add_shape_image_stroke( (width, height), )) .expect("could not add stroke image fill"); - } + }); } #[no_mangle] pub extern "C" fn clear_shape_strokes() { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.clear_strokes(); - } + }); } #[no_mangle] pub extern "C" fn set_shape_corners(r1: f32, r2: f32, r3: f32, r4: f32) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_corners((r1, r2, r3, r4)); - } + }); } #[no_mangle] pub extern "C" fn set_shape_path_attrs(num_attrs: u32) { - let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer"); - - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { let bytes = mem::bytes(); let mut start = 0; for _ in 0..num_attrs { @@ -593,7 +589,7 @@ pub extern "C" fn set_shape_path_attrs(num_attrs: u32) { let value = extract_string(&mut start, &bytes); shape.set_path_attr(name, value); } - } + }); } #[no_mangle] @@ -632,7 +628,7 @@ pub extern "C" fn set_modifiers() { for entry in entries { state.modifiers.insert(entry.id, entry.transform); } - state.render_state.clear_cache(); + state.render_state().clear_cache(); } #[no_mangle] @@ -645,21 +641,19 @@ pub extern "C" fn add_shape_shadow( raw_style: u8, hidden: bool, ) { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { let color = skia::Color::new(raw_color); let style = shapes::ShadowStyle::from(raw_style); let shadow = shapes::Shadow::new(color, blur, spread, (x, y), style, hidden); shape.add_shadow(shadow); - } + }); } #[no_mangle] pub extern "C" fn clear_shape_shadows() { - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.clear_shadows(); - } + }); } #[no_mangle] @@ -684,8 +678,7 @@ pub extern "C" fn set_flex_layout_data( let justify_content = shapes::JustifyContent::from_u8(justify_content); let wrap_type = shapes::WrapType::from_u8(wrap_type); - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_flex_layout_data( dir, row_gap, @@ -700,7 +693,7 @@ pub extern "C" fn set_flex_layout_data( padding_bottom, padding_left, ); - } + }); } #[no_mangle] @@ -729,8 +722,7 @@ pub extern "C" fn set_layout_child_data( let max_w = if has_max_w { Some(max_w) } else { None }; let min_w = if has_min_w { Some(min_w) } else { None }; - let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); - if let Some(shape) = state.current_shape() { + with_current_shape!(state, |shape: &mut Shape| { shape.set_flex_layout_child_data( margin_top, margin_right, @@ -745,7 +737,7 @@ pub extern "C" fn set_layout_child_data( is_absolute, z_index, ); - } + }); } #[no_mangle] diff --git a/render-wasm/src/mem.rs b/render-wasm/src/mem.rs index 20e44ef3e..cd1ddea53 100644 --- a/render-wasm/src/mem.rs +++ b/render-wasm/src/mem.rs @@ -1,47 +1,57 @@ -static mut BUFFERU8: Option>> = None; +use std::sync::Mutex; + +static BUFFERU8: Mutex>>> = Mutex::new(None); #[no_mangle] pub extern "C" fn alloc_bytes(len: usize) -> *mut u8 { - // TODO: Figure out how to deal with Result from Emscripten - if unsafe { BUFFERU8.is_some() } { + let mut guard = BUFFERU8.lock().unwrap(); + + if guard.is_some() { panic!("Bytes already allocated"); } - let mut buffer = Box::new(vec![0u8; len]); - let ptr = buffer.as_mut_ptr(); + let mut new_buffer = Box::new(vec![0u8; len]); + let ptr = new_buffer.as_mut_ptr(); - unsafe { BUFFERU8 = Some(buffer) }; - return ptr; + *guard = Some(new_buffer); + ptr } pub fn write_bytes(bytes: Vec) -> *mut u8 { - if unsafe { BUFFERU8.is_some() } { + let mut guard = BUFFERU8.lock().unwrap(); + + if guard.is_some() { panic!("Bytes already allocated"); } - let mut buffer = Box::new(bytes); - let ptr = buffer.as_mut_ptr(); + let mut new_buffer = Box::new(bytes); + let ptr = new_buffer.as_mut_ptr(); - unsafe { BUFFERU8 = Some(buffer) }; - return ptr; + *guard = Some(new_buffer); + ptr } #[no_mangle] pub extern "C" fn free_bytes() { - if unsafe { BUFFERU8.is_some() } { - let buffer = unsafe { BUFFERU8.take() }.expect("uninitialized buffer"); - std::mem::drop(buffer); - } + let mut guard = BUFFERU8.lock().unwrap(); + *guard = None; + std::mem::drop(guard); } pub fn buffer_ptr() -> *mut u8 { - let buffer = unsafe { BUFFERU8.as_mut() }.expect("uninitializied buffer"); - buffer.as_mut_ptr() + let guard = BUFFERU8.lock().unwrap(); + + guard + .as_ref() + .map_or(std::ptr::null_mut(), |buffer| buffer.as_ptr() as *mut u8) } pub fn bytes() -> Vec { - let buffer = unsafe { BUFFERU8.take() }.expect("uninitialized buffer"); - *buffer + let mut guard = BUFFERU8.lock().unwrap(); + + guard + .take() + .map_or_else(|| panic!("Buffer is not initialized"), |buffer| *buffer) } pub trait SerializableResult { diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index 9c5e69611..6fac18351 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -458,7 +458,7 @@ impl RenderState { if self .cached_surface_image .as_ref() - .map_or(true, |img| img.invalid) + .is_none_or(|img| img.invalid) { self.cached_surface_image = Some(CachedSurfaceImage { image: self.surfaces.snapshot(SurfaceId::Current), diff --git a/render-wasm/src/state.rs b/render-wasm/src/state.rs index aa760caea..2f440ef78 100644 --- a/render-wasm/src/state.rs +++ b/render-wasm/src/state.rs @@ -59,12 +59,11 @@ impl<'a> State<'a> { let new_shape = Shape::new(id); self.shapes.insert(id, new_shape); } - self.current_id = Some(id); self.current_shape = self.shapes.get_mut(&id); } - pub fn current_shape(&'a mut self) -> Option<&'a mut Shape> { + pub fn current_shape(&mut self) -> Option<&mut Shape> { self.current_shape.as_deref_mut() }