diff --git a/render-wasm/src/globals.rs b/render-wasm/src/globals.rs new file mode 100644 index 0000000000..d2ed2196f6 --- /dev/null +++ b/render-wasm/src/globals.rs @@ -0,0 +1,138 @@ +use macros::wasm_error; + +use crate::mem; +use crate::render::{gpu_state::GpuState, RenderState}; +use crate::state::{State, TextEditorState}; + +static mut DESIGN_STATE: *mut State = std::ptr::null_mut(); + +/// Design State. +pub(crate) fn get_design_state() -> &'static mut State { + unsafe { + debug_assert!(!DESIGN_STATE.is_null(), "Design State is null"); + &mut *DESIGN_STATE + } +} + +/// GPU State. +static mut GPU_STATE: *mut GpuState = std::ptr::null_mut(); + +#[inline(always)] +pub(crate) fn get_gpu_state() -> &'static mut GpuState { + unsafe { + debug_assert!(!GPU_STATE.is_null(), "GPU State is null"); + &mut *GPU_STATE + } +} + +/// Render State. +static mut RENDER_STATE: *mut RenderState = std::ptr::null_mut(); + +#[inline(always)] +pub(crate) fn get_render_state() -> &'static mut RenderState { + unsafe { + debug_assert!(!RENDER_STATE.is_null(), "Render State is null"); + &mut *RENDER_STATE + } +} + +/// Text Editor State +static mut TEXT_EDITOR_STATE: *mut TextEditorState = std::ptr::null_mut(); + +#[inline(always)] +pub(crate) fn get_text_editor_state() -> &'static mut TextEditorState { + unsafe { + debug_assert!(!TEXT_EDITOR_STATE.is_null(), "Text Editor state is null"); + &mut *TEXT_EDITOR_STATE + } +} + +// FIXME: These with_state* macros should be using our CriticalError instead of expect. +// But to do that, we need to not use them at domain-level (i.e. in business logic), just +// in the context of the wasm call. +#[macro_export] +macro_rules! with_state { + ($state:ident, $block:block) => {{ + use $crate::globals::get_design_state; + let $state = get_design_state(); + $block + }}; +} + +#[macro_export] +macro_rules! with_current_shape_mut { + ($state:ident, |$shape:ident: &mut Shape| $block:block) => { + use $crate::globals::get_design_state; + let $state = get_design_state(); + $state.touch_current(); + if let Some($shape) = $state.current_shape_mut() { + $block + } + }; +} + +#[macro_export] +macro_rules! with_current_shape { + ($state:ident, |$shape:ident: &Shape| $block:block) => { + use $crate::globals::get_design_state; + let $state = get_design_state(); + if let Some($shape) = $state.current_shape() { + $block + } + }; +} + +/// Initializes GPUState. +fn gpu_init() { + unsafe { + let gpu_state = GpuState::try_new().expect("Cannot initialize GPU State"); + GPU_STATE = Box::into_raw(Box::new(gpu_state)); + } +} + +/// Initializes RenderState. +fn render_init(width: i32, height: i32) { + unsafe { + let render_state = + RenderState::try_new(width, height).expect("Cannot intialize RenderState"); + RENDER_STATE = Box::into_raw(Box::new(render_state)); + } +} + +/// Initializes DesignState. +fn design_init() { + unsafe { + let design_state = State::new(); + DESIGN_STATE = Box::into_raw(Box::new(design_state)); + } +} + +fn text_editor_init() { + unsafe { + let text_editor_state = TextEditorState::new(); + TEXT_EDITOR_STATE = Box::into_raw(Box::new(text_editor_state)); + } +} + +#[no_mangle] +#[wasm_error] +pub extern "C" fn init(width: i32, height: i32) -> Result<()> { + gpu_init(); + render_init(width, height); + text_editor_init(); + design_init(); + Ok(()) +} + +#[no_mangle] +#[wasm_error] +pub extern "C" fn clean_up() -> Result<()> { + // Cancel the current animation frame if it exists so + // it won't try to render without context + let render_state = get_render_state(); + render_state.cancel_animation_frame(); + render_state.prepare_context_loss_cleanup(); + unsafe { DESIGN_STATE = std::ptr::null_mut() } + mem::free_bytes()?; + Ok(()) +} diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs index f6a1f74f3c..bbec95e81f 100644 --- a/render-wasm/src/main.rs +++ b/render-wasm/src/main.rs @@ -1,6 +1,7 @@ #[cfg(target_arch = "wasm32")] mod emscripten; mod error; +mod globals; mod math; mod mem; mod performance; @@ -18,181 +19,26 @@ use std::collections::HashMap; #[allow(unused_imports)] use crate::error::{Error, Result}; -use crate::state::TextEditorState; + +use globals::{get_design_state, get_gpu_state, get_render_state}; + use macros::wasm_error; use math::{Bounds, Matrix}; use mem::SerializableResult; -use render::{gpu_state::GpuState, RenderState}; use shapes::{StructureEntry, StructureEntryType, TransformEntry}; use skia_safe as skia; -use state::State; use utils::uuid_from_u32_quartet; use uuid::Uuid; -pub(crate) static mut STATE: Option> = None; -pub(crate) static mut TEXT_EDITOR_STATE: *mut TextEditorState = std::ptr::null_mut(); - -#[inline(always)] -pub fn get_text_editor_state() -> &'static mut TextEditorState { - unsafe { - debug_assert!(!TEXT_EDITOR_STATE.is_null(), "Text Editor state is null"); - &mut *TEXT_EDITOR_STATE - } -} - -/// GPU State. -static mut GPU_STATE: *mut GpuState = std::ptr::null_mut(); - -#[inline(always)] -pub(crate) fn get_gpu_state() -> &'static mut GpuState { - unsafe { - debug_assert!(!GPU_STATE.is_null(), "GPU State is null"); - &mut *GPU_STATE - } -} - -/// Render State. -static mut RENDER_STATE: *mut RenderState = std::ptr::null_mut(); - -#[inline(always)] -pub(crate) fn get_render_state() -> &'static mut RenderState { - unsafe { - debug_assert!(!RENDER_STATE.is_null(), "Render State is null"); - &mut *RENDER_STATE - } -} - -// FIXME: These with_state* macros should be using our CriticalError instead of expect. -// But to do that, we need to not use them at domain-level (i.e. in business logic), just -// in the context of the wasm call. -#[macro_export] -macro_rules! with_state_mut { - ($state:ident, $block:block) => {{ - let $state = unsafe { - #[allow(static_mut_refs)] - STATE.as_mut() - } - .expect("Got an invalid state pointer"); - $block - }}; -} - -#[macro_export] -macro_rules! with_state { - ($state:ident, $block:block) => {{ - let $state = unsafe { - #[allow(static_mut_refs)] - STATE.as_ref() - } - .expect("Got an invalid state pointer"); - $block - }}; -} - -#[macro_export] -macro_rules! with_current_shape_mut { - ($state:ident, |$shape:ident: &mut Shape| $block:block) => { - let $state = unsafe { - #[allow(static_mut_refs)] - STATE.as_mut() - } - .expect("Got an invalid state pointer"); - - $state.touch_current(); - - if let Some($shape) = $state.current_shape_mut() { - $block - } - }; -} - -#[macro_export] -macro_rules! with_current_shape { - ($state:ident, |$shape:ident: &Shape| $block:block) => { - let $state = unsafe { - #[allow(static_mut_refs)] - STATE.as_ref() - } - .expect("Got an invalid state pointer"); - if let Some($shape) = $state.current_shape() { - $block - } - }; -} - -#[macro_export] -macro_rules! with_state_mut_current_shape { - ($state:ident, |$shape:ident: &Shape| $block:block) => { - let $state = unsafe { - #[allow(static_mut_refs)] - STATE.as_mut() - } - .expect("Got an invalid state pointer"); - if let Some($shape) = $state.current_shape() { - $block - } - }; -} - -/// Initializes GPU. -fn gpu_init() { - unsafe { - let gpu_state = GpuState::try_new().expect("Cannot initialize GPU State"); - GPU_STATE = Box::into_raw(Box::new(gpu_state)); - } -} - -/// Initializes RenderState. -fn render_init(width: i32, height: i32) { - unsafe { - let render_state = - RenderState::try_new(width, height).expect("Cannot intialize RenderState"); - RENDER_STATE = Box::into_raw(Box::new(render_state)); - } -} - -#[no_mangle] -#[wasm_error] -pub extern "C" fn init(width: i32, height: i32) -> Result<()> { - gpu_init(); - render_init(width, height); - unsafe { - let state_box = Box::new(State::new()); - STATE = Some(state_box); - TEXT_EDITOR_STATE = Box::into_raw(Box::new(TextEditorState::new())); - } - Ok(()) -} - #[no_mangle] #[wasm_error] pub extern "C" fn set_browser(browser: u8) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { state.set_browser(browser); }); Ok(()) } -#[no_mangle] -#[wasm_error] -pub extern "C" fn clean_up() -> Result<()> { - // Cancel the current animation frame if it exists so - // it won't try to render without context - unsafe { - #[allow(static_mut_refs)] - if STATE.is_some() { - // Cancel the current animation frame if it exists so - // it won't try to render without context. - let render_state = get_render_state(); - render_state.cancel_animation_frame(); - render_state.prepare_context_loss_cleanup(); - } - STATE = None; - } - mem::free_bytes()?; - Ok(()) -} - #[no_mangle] #[wasm_error] pub extern "C" fn set_render_options(debug: u32, dpr: f32) -> Result<()> { @@ -255,7 +101,7 @@ pub extern "C" fn set_max_atlas_texture_size(max_px: i32) -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn set_canvas_background(raw_color: u32) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { let color = skia::Color::new(raw_color); state.set_background_color(color); state.rebuild_tiles_shallow(); @@ -267,7 +113,7 @@ pub extern "C" fn set_canvas_background(raw_color: u32) -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn render(timestamp: i32) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { state.rebuild_touched_tiles(); // Drain the throttled modifier-tile invalidation accumulated // since the previous rAF. set_modifiers skips this work during @@ -290,7 +136,7 @@ pub extern "C" fn render(timestamp: i32) -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn render_sync() -> Result<()> { - with_state_mut!(state, { + with_state!(state, { state.rebuild_tiles(); state .render_sync(0) @@ -302,7 +148,7 @@ pub extern "C" fn render_sync() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn render_sync_shape(a: u32, b: u32, c: u32, d: u32) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { let id = uuid_from_u32_quartet(a, b, c, d); state.use_shape(id); @@ -328,7 +174,7 @@ pub extern "C" fn render_sync_shape(a: u32, b: u32, c: u32, d: u32) -> Result<() #[no_mangle] #[wasm_error] pub extern "C" fn render_from_cache(_: i32) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { // Don't cancel the animation frame — let the async render // continue populating the tile HashMap in the background. // process_animation_frame skips flush_and_submit in fast @@ -351,7 +197,7 @@ pub extern "C" fn set_preview_mode(enabled: bool) -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn render_preview() -> Result<()> { - with_state_mut!(state, { + with_state!(state, { state.render_preview(performance::get_time()); }); Ok(()) @@ -361,7 +207,7 @@ pub extern "C" fn render_preview() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn begin_loading() -> Result<()> { - with_state_mut!(state, { + with_state!(state, { state.loading = true; }); Ok(()) @@ -372,7 +218,7 @@ pub extern "C" fn begin_loading() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn end_loading() -> Result<()> { - with_state_mut!(state, { + with_state!(state, { state.loading = false; }); Ok(()) @@ -394,7 +240,7 @@ pub extern "C" fn render_loading_overlay() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn process_animation_frame(timestamp: i32) -> Result<()> { - let result = with_state_mut!(state, { state.process_animation_frame(timestamp) }); + let result = with_state!(state, { state.process_animation_frame(timestamp) }); if let Err(err) = result { eprintln!("process_animation_frame error: {}", err); } @@ -449,7 +295,7 @@ pub extern "C" fn set_view_start() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn set_view_end() -> Result<()> { - with_state_mut!(state, { + with_state!(state, { performance::begin_measure!("set_view_end"); let render_state = get_render_state(); render_state.options.set_fast_mode(false); @@ -518,7 +364,7 @@ pub extern "C" fn set_modifiers_end() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn clear_focus_mode() -> Result<()> { - with_state_mut!(state, { + with_state!(state, { state.clear_focus_mode(); }); Ok(()) @@ -534,7 +380,7 @@ pub extern "C" fn set_focus_mode() -> Result<()> { .map(|data| Uuid::try_from(data).map_err(|e| Error::RecoverableError(e.to_string()))) .collect::>>()?; - with_state_mut!(state, { + with_state!(state, { state.set_focus_mode(entries); }); Ok(()) @@ -543,7 +389,7 @@ pub extern "C" fn set_focus_mode() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn init_shapes_pool(capacity: usize) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { state.init_shapes_pool(capacity); }); Ok(()) @@ -552,7 +398,7 @@ pub extern "C" fn init_shapes_pool(capacity: usize) -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn use_shape(a: u32, b: u32, c: u32, d: u32) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { let id = uuid_from_u32_quartet(a, b, c, d); state.use_shape(id); }); @@ -562,7 +408,7 @@ pub extern "C" fn use_shape(a: u32, b: u32, c: u32, d: u32) -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn touch_shape(a: u32, b: u32, c: u32, d: u32) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { let shape_id = uuid_from_u32_quartet(a, b, c, d); state.touch_shape(shape_id); }); @@ -572,7 +418,7 @@ pub extern "C" fn touch_shape(a: u32, b: u32, c: u32, d: u32) -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn set_parent(a: u32, b: u32, c: u32, d: u32) -> Result<()> { - with_state_mut!(state, { + with_state!(state, { let id = uuid_from_u32_quartet(a, b, c, d); state.set_parent_for_current_shape(id); }); @@ -658,7 +504,7 @@ fn set_children_set(entries: Vec) -> Result<()> { } }); - with_state_mut!(state, { + with_state!(state, { let Some(parent_id) = parent_id else { return Err(Error::RecoverableError( "set_children_set: Parent ID not found".to_string(), @@ -891,7 +737,7 @@ pub extern "C" fn get_selection_rect() -> Result<*mut u8> { }) .collect(); - let result_bound = with_state_mut!(state, { + let result_bound = with_state!(state, { let bbs: Vec<_> = entries .iter() .flat_map(|id| state.shapes.get(id).map(|b| b.bounds())) @@ -938,7 +784,7 @@ pub extern "C" fn set_structure_modifiers() -> Result<()> { }) .collect::>>()?; - with_state_mut!(state, { + with_state!(state, { let mut structure = HashMap::new(); let mut scale_content = HashMap::new(); for entry in entries { @@ -977,7 +823,7 @@ pub extern "C" fn set_structure_modifiers() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn clean_modifiers() -> Result<()> { - with_state_mut!(state, { + with_state!(state, { let render_state = get_render_state(); let prev_modifier_ids = state.shapes.clean_all(); // Skip the tile-cache cleanup during interactive transform: the @@ -1008,7 +854,7 @@ pub extern "C" fn set_modifiers() -> Result<()> { ids.push(entry.id); } - with_state_mut!(state, { + with_state!(state, { state.set_modifiers(modifiers); // TO CHECK if !get_render_state().options.is_interactive_transform() { @@ -1021,28 +867,14 @@ pub extern "C" fn set_modifiers() -> Result<()> { #[no_mangle] #[wasm_error] pub extern "C" fn start_temp_objects() -> Result<()> { - unsafe { - #[allow(static_mut_refs)] - let mut state = STATE.take().ok_or(Error::CriticalError( - "Got an invalid state pointer".to_string(), - ))?; - state = Box::new(state.start_temp_objects()?); - STATE = Some(state); - } + get_design_state().start_temp_objects()?; Ok(()) } #[no_mangle] #[wasm_error] pub extern "C" fn end_temp_objects() -> Result<()> { - unsafe { - #[allow(static_mut_refs)] - let mut state = STATE.take().ok_or(Error::CriticalError( - "Got an invalid state pointer".to_string(), - ))?; - state = Box::new(state.end_temp_objects()?); - STATE = Some(state); - } + get_design_state().end_temp_objects()?; Ok(()) } @@ -1061,7 +893,7 @@ pub extern "C" fn render_shape_pixels( return Err(Error::CriticalError("Scale is not finite".to_string())); } - with_state_mut!(state, { + with_state!(state, { let (data, width, height) = state.render_shape_pixels(&id, scale, performance::get_time())?; diff --git a/render-wasm/src/shapes/text.rs b/render-wasm/src/shapes/text.rs index fcc9066777..98e0a4e6c9 100644 --- a/render-wasm/src/shapes/text.rs +++ b/render-wasm/src/shapes/text.rs @@ -26,7 +26,6 @@ use crate::math::Point; use crate::shapes::{self, merge_fills, Shape, VerticalAlign}; use crate::utils::{get_fallback_fonts, get_font_collection}; use crate::Uuid; -use crate::STATE; // TODO: maybe move this to the wasm module? pub type ParagraphBuilderGroup = Vec; diff --git a/render-wasm/src/state.rs b/render-wasm/src/state.rs index 9591294abf..5eed9d66fb 100644 --- a/render-wasm/src/state.rs +++ b/render-wasm/src/state.rs @@ -38,26 +38,26 @@ impl State { // Creates a new temporary shapes pool. // Will panic if a previous temporary pool exists. - pub fn start_temp_objects(mut self) -> Result { + pub fn start_temp_objects(&mut self) -> Result<()> { if self.saved_shapes.is_some() { return Err(Error::CriticalError( "Tried to start a temp objects while the previous have not been restored" .to_string(), )); } - self.saved_shapes = Some(self.shapes); + self.saved_shapes = Some(self.shapes.clone()); self.shapes = ShapesPool::new(); - Ok(self) + Ok(()) } // Disposes of the temporary shapes pool restoring the normal pool // Will panic if a there is no temporary pool. - pub fn end_temp_objects(mut self) -> Result { - self.shapes = self.saved_shapes.ok_or(Error::CriticalError( + pub fn end_temp_objects(&mut self) -> Result<()> { + self.shapes = self.saved_shapes.clone().ok_or(Error::CriticalError( "Tried to end temp objects but not content to be restored is present".to_string(), ))?; self.saved_shapes = None; - Ok(self) + Ok(()) } pub fn render_from_cache(&mut self) { diff --git a/render-wasm/src/state/shapes_pool.rs b/render-wasm/src/state/shapes_pool.rs index 32d95f8a3a..9f19dbc50a 100644 --- a/render-wasm/src/state/shapes_pool.rs +++ b/render-wasm/src/state/shapes_pool.rs @@ -398,3 +398,19 @@ impl Default for ShapesPoolImpl { Self::new() } } + +impl Clone for ShapesPoolImpl { + fn clone(&self) -> Self { + ShapesPoolImpl { + shapes: self.shapes.clone(), + counter: self.counter, + uuid_to_idx: self.uuid_to_idx.clone(), + // The modified_shape_cache is a derived/computed cache; reset it on clone + // so it gets lazily rebuilt on demand rather than cloning OnceCell state. + modified_shape_cache: HashMap::default(), + modifiers: self.modifiers.clone(), + structure: self.structure.clone(), + scale_content: self.scale_content.clone(), + } + } +} diff --git a/render-wasm/src/utils.rs b/render-wasm/src/utils.rs index 5d5c9a4c10..206b91dbb0 100644 --- a/render-wasm/src/utils.rs +++ b/render-wasm/src/utils.rs @@ -2,8 +2,7 @@ use crate::get_render_state; use crate::skia::textlayout::FontCollection; use crate::skia::Image; use crate::uuid::Uuid; -use crate::with_state_mut; -use crate::STATE; +use crate::with_state; use std::collections::HashSet; pub fn uuid_from_u32_quartet(a: u32, b: u32, c: u32, d: u32) -> Uuid { @@ -35,7 +34,7 @@ pub fn get_fallback_fonts() -> &'static HashSet { } pub fn get_font_collection() -> &'static FontCollection { - with_state_mut!(state, { state.font_collection() }) + with_state!(state, { state.font_collection() }) } #[derive(Debug, Clone, Copy)] diff --git a/render-wasm/src/wasm/blend.rs b/render-wasm/src/wasm/blend.rs index d0dcbad118..832547cecb 100644 --- a/render-wasm/src/wasm/blend.rs +++ b/render-wasm/src/wasm/blend.rs @@ -2,7 +2,7 @@ use macros::ToJs; use skia_safe as skia; use crate::shapes::BlendMode; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; #[derive(Debug, PartialEq, Clone, Copy, ToJs)] #[repr(u8)] diff --git a/render-wasm/src/wasm/blurs.rs b/render-wasm/src/wasm/blurs.rs index e8e1a4242c..022439ab44 100644 --- a/render-wasm/src/wasm/blurs.rs +++ b/render-wasm/src/wasm/blurs.rs @@ -1,7 +1,7 @@ use macros::ToJs; use crate::shapes::{Blur, BlurType}; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; #[derive(Debug, Clone, Copy, PartialEq, ToJs)] #[repr(u8)] diff --git a/render-wasm/src/wasm/fills.rs b/render-wasm/src/wasm/fills.rs index 19fc49e575..2e652b11b1 100644 --- a/render-wasm/src/wasm/fills.rs +++ b/render-wasm/src/wasm/fills.rs @@ -3,7 +3,6 @@ use macros::{wasm_error, ToJs}; use crate::mem; use crate::shapes; use crate::with_current_shape_mut; -use crate::STATE; mod gradient; mod image; diff --git a/render-wasm/src/wasm/fills/image.rs b/render-wasm/src/wasm/fills/image.rs index 5d4db56a71..ce245055fb 100644 --- a/render-wasm/src/wasm/fills/image.rs +++ b/render-wasm/src/wasm/fills/image.rs @@ -4,8 +4,7 @@ use crate::mem; use crate::shapes::Fill; use crate::state::State; use crate::uuid::Uuid; -use crate::with_state_mut; -use crate::STATE; +use crate::with_state; use crate::{shapes::ImageFill, utils::uuid_from_u32_quartet}; use macros::wasm_error; @@ -106,7 +105,7 @@ pub extern "C" fn store_image() -> Result<()> { let image_bytes = &bytes[IMAGE_HEADER_SIZE..]; - with_state_mut!(state, { + with_state!(state, { if let Err(msg) = get_render_state().add_image(ids.image_id, is_thumbnail, image_bytes) { eprintln!("{}", msg); } @@ -176,7 +175,7 @@ pub extern "C" fn store_image_from_texture() -> Result<()> { .map_err(|_| Error::CriticalError("Invalid bytes for height".to_string()))?, ); - with_state_mut!(state, { + with_state!(state, { if let Err(msg) = get_render_state().add_image_from_gl_texture( ids.image_id, is_thumbnail, diff --git a/render-wasm/src/wasm/layouts.rs b/render-wasm/src/wasm/layouts.rs index 81ea59240d..d179188e51 100644 --- a/render-wasm/src/wasm/layouts.rs +++ b/render-wasm/src/wasm/layouts.rs @@ -1,5 +1,5 @@ use crate::shapes::Sizing; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; use macros::ToJs; mod align; diff --git a/render-wasm/src/wasm/layouts/align.rs b/render-wasm/src/wasm/layouts/align.rs index 42810588d9..75ce0816cb 100644 --- a/render-wasm/src/wasm/layouts/align.rs +++ b/render-wasm/src/wasm/layouts/align.rs @@ -3,7 +3,7 @@ use macros::ToJs; use crate::shapes::{ AlignContent, AlignItems, AlignSelf, JustifyContent, JustifyItems, JustifySelf, VerticalAlign, }; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; #[derive(Debug, Clone, PartialEq, Copy, ToJs)] #[repr(u8)] diff --git a/render-wasm/src/wasm/layouts/constraints.rs b/render-wasm/src/wasm/layouts/constraints.rs index 057e739241..8760ed5592 100644 --- a/render-wasm/src/wasm/layouts/constraints.rs +++ b/render-wasm/src/wasm/layouts/constraints.rs @@ -1,7 +1,7 @@ use macros::ToJs; use crate::shapes::{ConstraintH, ConstraintV}; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; #[derive(Debug, Clone, PartialEq, Copy, ToJs)] #[repr(u8)] diff --git a/render-wasm/src/wasm/layouts/flex.rs b/render-wasm/src/wasm/layouts/flex.rs index 10d1f991e8..2935165fcf 100644 --- a/render-wasm/src/wasm/layouts/flex.rs +++ b/render-wasm/src/wasm/layouts/flex.rs @@ -1,5 +1,5 @@ use crate::shapes::{FlexDirection, WrapType}; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; use macros::ToJs; use super::align; diff --git a/render-wasm/src/wasm/layouts/grid.rs b/render-wasm/src/wasm/layouts/grid.rs index 87a7e45f28..15284250c2 100644 --- a/render-wasm/src/wasm/layouts/grid.rs +++ b/render-wasm/src/wasm/layouts/grid.rs @@ -4,7 +4,7 @@ use crate::get_render_state; use crate::mem; use crate::shapes::{GridCell, GridDirection, GridTrack, GridTrackType}; use crate::uuid::Uuid; -use crate::{uuid_from_u32_quartet, with_current_shape_mut, with_state, STATE}; +use crate::{uuid_from_u32_quartet, with_current_shape_mut, with_state}; use super::align; diff --git a/render-wasm/src/wasm/paths.rs b/render-wasm/src/wasm/paths.rs index 7690a9001f..730bb6fe85 100644 --- a/render-wasm/src/wasm/paths.rs +++ b/render-wasm/src/wasm/paths.rs @@ -6,7 +6,7 @@ use std::sync::{Mutex, OnceLock}; use crate::error::{Error, Result}; use crate::shapes::{stroke_to_path, Path, Segment, ToPath}; -use crate::{mem, with_current_shape, with_current_shape_mut, STATE}; +use crate::{mem, with_current_shape, with_current_shape_mut}; const RAW_SEGMENT_DATA_SIZE: usize = size_of::(); diff --git a/render-wasm/src/wasm/paths/bools.rs b/render-wasm/src/wasm/paths/bools.rs index 0e6636e2f2..3858641f0a 100644 --- a/render-wasm/src/wasm/paths/bools.rs +++ b/render-wasm/src/wasm/paths/bools.rs @@ -5,7 +5,7 @@ use crate::math; use crate::shapes::BoolType; use crate::uuid::Uuid; use crate::{mem, SerializableResult}; -use crate::{with_current_shape_mut, with_state, STATE}; +use crate::{with_current_shape_mut, with_state}; use std::mem::size_of; #[allow(unused_imports)] diff --git a/render-wasm/src/wasm/shadows.rs b/render-wasm/src/wasm/shadows.rs index c7a95aacfe..57ecae2613 100644 --- a/render-wasm/src/wasm/shadows.rs +++ b/render-wasm/src/wasm/shadows.rs @@ -2,7 +2,7 @@ use macros::ToJs; use skia_safe as skia; use crate::shapes::{Shadow, ShadowStyle}; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; #[derive(Debug, Clone, Copy, PartialEq, ToJs)] #[repr(u8)] diff --git a/render-wasm/src/wasm/shapes/base_props.rs b/render-wasm/src/wasm/shapes/base_props.rs index 5e0146f276..e9b6a6e7b0 100644 --- a/render-wasm/src/wasm/shapes/base_props.rs +++ b/render-wasm/src/wasm/shapes/base_props.rs @@ -4,7 +4,7 @@ use crate::utils::uuid_from_u32_quartet; use crate::uuid::Uuid; use crate::wasm::blend::RawBlendMode; use crate::wasm::layouts::constraints::{RawConstraintH, RawConstraintV}; -use crate::{with_state_mut, STATE}; +use crate::with_state; #[allow(unused_imports)] use crate::error::{Error, Result}; @@ -128,7 +128,7 @@ pub extern "C" fn set_shape_base_props() -> Result<()> { let parent_id = raw.parent_id(); let shape_type = RawShapeType::from(raw.shape_type); - with_state_mut!(state, { + with_state!(state, { state.use_shape(id); state.set_parent_for_current_shape(parent_id); state.touch_current(); diff --git a/render-wasm/src/wasm/shapes/mod.rs b/render-wasm/src/wasm/shapes/mod.rs index 3f32e824c3..901feb57f8 100644 --- a/render-wasm/src/wasm/shapes/mod.rs +++ b/render-wasm/src/wasm/shapes/mod.rs @@ -3,7 +3,7 @@ mod base_props; use macros::ToJs; use crate::shapes::{Bool, Frame, Group, Path, Rect, SVGRaw, TextContent, Type}; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; #[derive(Debug, Clone, PartialEq, ToJs)] #[repr(u8)] diff --git a/render-wasm/src/wasm/strokes.rs b/render-wasm/src/wasm/strokes.rs index 21a7e321ff..452eb4ee2a 100644 --- a/render-wasm/src/wasm/strokes.rs +++ b/render-wasm/src/wasm/strokes.rs @@ -3,7 +3,6 @@ use macros::ToJs; use crate::mem; use crate::shapes::{self, StrokeCap, StrokeStyle}; use crate::with_current_shape_mut; -use crate::STATE; #[derive(Debug, Clone, PartialEq, Copy, ToJs)] #[repr(u8)] diff --git a/render-wasm/src/wasm/svg_attrs.rs b/render-wasm/src/wasm/svg_attrs.rs index 73c146eb2c..ac4e7c376a 100644 --- a/render-wasm/src/wasm/svg_attrs.rs +++ b/render-wasm/src/wasm/svg_attrs.rs @@ -1,7 +1,7 @@ use macros::ToJs; use crate::shapes::{FillRule, StrokeLineCap, StrokeLineJoin, SvgAttrs}; -use crate::{with_current_shape_mut, STATE}; +use crate::with_current_shape_mut; #[derive(PartialEq, ToJs)] #[repr(u8)] diff --git a/render-wasm/src/wasm/text.rs b/render-wasm/src/wasm/text.rs index 88726de91e..c97ec81276 100644 --- a/render-wasm/src/wasm/text.rs +++ b/render-wasm/src/wasm/text.rs @@ -7,7 +7,7 @@ use crate::shapes::{ self, GrowType, Shape, TextAlign, TextDecoration, TextDirection, TextTransform, Type, }; use crate::utils::{uuid_from_u32, uuid_from_u32_quartet}; -use crate::{with_current_shape, with_current_shape_mut, with_state, with_state_mut, STATE}; +use crate::{with_current_shape, with_current_shape_mut, with_state}; use crate::error::Error; @@ -386,7 +386,7 @@ pub extern "C" fn update_shape_text_layout() { #[no_mangle] pub extern "C" fn update_shape_text_layout_for(a: u32, b: u32, c: u32, d: u32) { - with_state_mut!(state, { + with_state!(state, { let shape_id = uuid_from_u32_quartet(a, b, c, d); if let Some(shape) = state.shapes.get_mut(&shape_id) { update_text_layout(shape); diff --git a/render-wasm/src/wasm/text_editor.rs b/render-wasm/src/wasm/text_editor.rs index 10853c98e5..6fc4a3e20a 100644 --- a/render-wasm/src/wasm/text_editor.rs +++ b/render-wasm/src/wasm/text_editor.rs @@ -1,7 +1,8 @@ use macros::{wasm_error, ToJs}; -use crate::get_text_editor_state; +use crate::globals::{get_render_state, get_text_editor_state}; use crate::math::{Matrix, Point, Rect}; +use crate::mem; use crate::render::text_editor as text_editor_render; use crate::render::SurfaceId; use crate::shapes::{Shape, TextAlign, TextContent, TextPositionWithAffinity, Type, VerticalAlign}; @@ -12,8 +13,7 @@ use crate::wasm::fills::RawFillData; use crate::wasm::text::{ helpers as text_helpers, RawTextAlign, RawTextDecoration, RawTextDirection, RawTextTransform, }; -use crate::{get_render_state, mem}; -use crate::{with_state, with_state_mut, STATE}; +use crate::with_state; use skia_safe::Color; #[derive(PartialEq, ToJs)] @@ -42,7 +42,7 @@ pub extern "C" fn text_editor_apply_theme(selection_color: u32, cursor_color: u3 #[no_mangle] pub extern "C" fn text_editor_focus(a: u32, b: u32, c: u32, d: u32) -> bool { - with_state_mut!(state, { + with_state!(state, { let shape_id = uuid_from_u32_quartet(a, b, c, d); let Some(shape) = state.shapes.get(&shape_id) else { @@ -107,7 +107,7 @@ pub extern "C" fn text_editor_get_active_shape_id(buffer_ptr: *mut u32) { #[no_mangle] pub extern "C" fn text_editor_select_all() -> bool { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return false; } @@ -129,7 +129,7 @@ pub extern "C" fn text_editor_select_all() -> bool { #[no_mangle] pub extern "C" fn text_editor_select_word_boundary(x: f32, y: f32) { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -164,7 +164,7 @@ pub extern "C" fn text_editor_poll_event() -> u8 { #[no_mangle] pub extern "C" fn text_editor_pointer_down(x: f32, y: f32) { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -188,7 +188,7 @@ pub extern "C" fn text_editor_pointer_down(x: f32, y: f32) { #[no_mangle] pub extern "C" fn text_editor_pointer_move(x: f32, y: f32) { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -222,7 +222,7 @@ pub extern "C" fn text_editor_pointer_move(x: f32, y: f32) { #[no_mangle] pub extern "C" fn text_editor_pointer_up(x: f32, y: f32) { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -249,7 +249,7 @@ pub extern "C" fn text_editor_pointer_up(x: f32, y: f32) { #[no_mangle] pub extern "C" fn text_editor_set_cursor_from_offset(x: f32, y: f32) { - with_state_mut!(state, { + with_state!(state, { // We need this flag to prevent handling the click behavior // just after a pointerup event. if get_text_editor_state().is_click_event_skipped { @@ -282,7 +282,7 @@ pub extern "C" fn text_editor_set_cursor_from_offset(x: f32, y: f32) { #[no_mangle] pub extern "C" fn text_editor_set_cursor_from_point(x: f32, y: f32) { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -330,7 +330,7 @@ pub extern "C" fn text_editor_composition_end() -> Result<()> { Err(_) => return Ok(()), }; - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return Ok(()); } @@ -386,7 +386,7 @@ pub extern "C" fn text_editor_composition_update() -> Result<()> { Err(_) => return Ok(()), }; - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return Ok(()); } @@ -444,7 +444,7 @@ pub extern "C" fn text_editor_insert_text() -> Result<()> { Err(_) => return Ok(()), }; - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return Ok(()); } @@ -498,7 +498,7 @@ pub extern "C" fn text_editor_insert_text() -> Result<()> { #[no_mangle] pub extern "C" fn text_editor_delete_backward(word_boundary: bool) { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -522,7 +522,7 @@ pub extern "C" fn text_editor_delete_backward(word_boundary: bool) { #[no_mangle] pub extern "C" fn text_editor_delete_forward(word_boundary: bool) { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -546,7 +546,7 @@ pub extern "C" fn text_editor_delete_forward(word_boundary: bool) { #[no_mangle] pub extern "C" fn text_editor_insert_paragraph() { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -578,7 +578,7 @@ pub extern "C" fn text_editor_move_cursor( word_boundary: bool, extend_selection: bool, ) { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return; } @@ -610,7 +610,7 @@ pub extern "C" fn text_editor_move_cursor( #[no_mangle] pub extern "C" fn text_editor_get_cursor_rect() -> *mut u8 { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus || !get_text_editor_state().cursor_visible { return std::ptr::null_mut(); } @@ -644,7 +644,7 @@ pub extern "C" fn text_editor_get_cursor_rect() -> *mut u8 { #[no_mangle] pub extern "C" fn text_editor_get_current_styles() -> *mut u8 { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return std::ptr::null_mut(); } @@ -812,7 +812,7 @@ pub extern "C" fn text_editor_get_current_styles() -> *mut u8 { #[no_mangle] pub extern "C" fn text_editor_get_selection_rects() -> *mut u8 { - with_state_mut!(state, { + with_state!(state, { if !get_text_editor_state().has_focus { return std::ptr::null_mut(); } @@ -858,7 +858,7 @@ pub extern "C" fn text_editor_update_blink(timestamp_ms: f32) { #[no_mangle] pub extern "C" fn text_editor_render_overlay() { - with_state_mut!(state, { + with_state!(state, { let Some(shape_id) = get_text_editor_state().active_shape_id else { return; }; diff --git a/render-wasm/src/wasm/transforms.rs b/render-wasm/src/wasm/transforms.rs index b0e0a2d84d..87989c545b 100644 --- a/render-wasm/src/wasm/transforms.rs +++ b/render-wasm/src/wasm/transforms.rs @@ -7,7 +7,7 @@ use skia_safe as skia; use crate::mem; use crate::shapes::{self, TransformEntry, TransformEntrySource}; use crate::utils::uuid_from_u32_quartet; -use crate::{with_state, STATE}; +use crate::with_state; #[derive(Debug, PartialEq, Clone, Copy, ToJs)] #[repr(u8)]