♻️ Clean unnecessary methods (#11472)

* ♻️ Remove duplicated/unused set-children code

* ♻️ Remove unused methods
This commit is contained in:
Elena Torró 2026-09-02 12:58:52 +02:00 committed by GitHub
parent b9ddfc1596
commit 03e6f119e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 5 additions and 536 deletions

View File

@ -17,7 +17,6 @@
[app.common.math :as mth]
[app.common.render-wasm.helpers :as h]
[app.common.render-wasm.mem :as mem]
[app.common.render-wasm.mem.heap32 :as mem.h32]
[app.common.render-wasm.serializers :as sr]
[app.common.render-wasm.serializers.color :as sr-clr]
[app.common.render-wasm.wasm :as wasm]
@ -27,22 +26,6 @@
(def ^:const MAX_BUFFER_CHUNK_SIZE (* 256 1024))
(def ^:const UUID-U8-SIZE 16)
(defn set-shape-children
"Uploads the child id list via the dynamic `_set_children` path (handles any
count). The browser also has fixed-arity fast paths for the incremental edit
path; this dynamic one is the shared/batch version."
[children]
(let [children (into [] (filter uuid?) children)]
(if (empty? children)
(h/call wasm/internal-module "_set_children_0")
(let [heap (mem/get-heap-u32)
size (mem/get-alloc-size children UUID-U8-SIZE)
offset (mem/alloc->offset-32 size)]
(reduce (fn [o id] (mem.h32/write-uuid o heap id)) offset children)
(h/call wasm/internal-module "_set_children")))))
(defn set-shape-bool-type
[bool-type]
(h/call wasm/internal-module "_set_shape_bool_type" (sr/translate-bool-type bool-type)))

View File

@ -844,61 +844,8 @@
[children]
(perf/begin-measure "set-shape-children")
(let [children (into [] (filter uuid?) children)]
(case (count children)
0
(if (empty? children)
(h/call wasm/internal-module "_set_children_0")
1
(let [[c1] children
c1 (uuid/get-u32 c1)]
(h/call wasm/internal-module "_set_children_1"
(aget c1 0) (aget c1 1) (aget c1 2) (aget c1 3)))
2
(let [[c1 c2] children
c1 (uuid/get-u32 c1)
c2 (uuid/get-u32 c2)]
(h/call wasm/internal-module "_set_children_2"
(aget c1 0) (aget c1 1) (aget c1 2) (aget c1 3)
(aget c2 0) (aget c2 1) (aget c2 2) (aget c2 3)))
3
(let [[c1 c2 c3] children
c1 (uuid/get-u32 c1)
c2 (uuid/get-u32 c2)
c3 (uuid/get-u32 c3)]
(h/call wasm/internal-module "_set_children_3"
(aget c1 0) (aget c1 1) (aget c1 2) (aget c1 3)
(aget c2 0) (aget c2 1) (aget c2 2) (aget c2 3)
(aget c3 0) (aget c3 1) (aget c3 2) (aget c3 3)))
4
(let [[c1 c2 c3 c4] children
c1 (uuid/get-u32 c1)
c2 (uuid/get-u32 c2)
c3 (uuid/get-u32 c3)
c4 (uuid/get-u32 c4)]
(h/call wasm/internal-module "_set_children_4"
(aget c1 0) (aget c1 1) (aget c1 2) (aget c1 3)
(aget c2 0) (aget c2 1) (aget c2 2) (aget c2 3)
(aget c3 0) (aget c3 1) (aget c3 2) (aget c3 3)
(aget c4 0) (aget c4 1) (aget c4 2) (aget c4 3)))
5
(let [[c1 c2 c3 c4 c5] children
c1 (uuid/get-u32 c1)
c2 (uuid/get-u32 c2)
c3 (uuid/get-u32 c3)
c4 (uuid/get-u32 c4)
c5 (uuid/get-u32 c5)]
(h/call wasm/internal-module "_set_children_5"
(aget c1 0) (aget c1 1) (aget c1 2) (aget c1 3)
(aget c2 0) (aget c2 1) (aget c2 2) (aget c2 3)
(aget c3 0) (aget c3 1) (aget c3 2) (aget c3 3)
(aget c4 0) (aget c4 1) (aget c4 2) (aget c4 3)
(aget c5 0) (aget c5 1) (aget c5 2) (aget c5 3)))
;; Dynamic call for children > 5
(let [heap (mem/get-heap-u32)
size (mem/get-alloc-size children UUID-U8-SIZE)
offset (mem/alloc->offset-32 size)]

View File

@ -51,47 +51,6 @@ pub extern "C" fn set_render_options(debug: u32, dpr: f32) -> Result<()> {
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_viewport_interest_area_threshold(
viewport_interest_area_threshold: i32,
) -> Result<()> {
let render_state = get_render_state();
render_state.set_viewport_interest_area_threshold(viewport_interest_area_threshold)?;
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_max_blocking_time_ms(max_blocking_time_ms: i32) -> Result<()> {
let render_state = get_render_state();
render_state.set_max_blocking_time_ms(max_blocking_time_ms);
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_node_batch_threshold(node_batch_threshold: i32) -> Result<()> {
let render_state = get_render_state();
render_state.set_node_batch_threshold(node_batch_threshold);
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_blur_downscale_threshold(blur_downscale_threshold: f32) -> Result<()> {
let render_state = get_render_state();
render_state.set_blur_downscale_threshold(blur_downscale_threshold);
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_antialias_threshold(threshold: f32) -> Result<()> {
get_render_state().set_antialias_threshold(threshold);
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_canvas_background(raw_color: u32) -> Result<()> {
@ -469,16 +428,6 @@ pub extern "C" fn has_shape(a: u32, b: u32, c: u32, d: u32) -> Result<bool> {
});
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn touch_shape(a: u32, b: u32, c: u32, d: u32) -> Result<()> {
with_state!(state, {
let shape_id = uuid_from_u32_quartet(a, b, c, d);
state.touch_shape(shape_id);
});
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_parent(a: u32, b: u32, c: u32, d: u32) -> Result<()> {
@ -541,16 +490,6 @@ pub extern "C" fn set_shape_transform(
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn add_shape_child(a: u32, b: u32, c: u32, d: u32) -> Result<()> {
with_current_shape_mut!(state, |shape: &mut Shape| {
let id = uuid_from_u32_quartet(a, b, c, d);
shape.add_child(id);
});
Ok(())
}
fn set_children_set(entries: Vec<Uuid>) -> Result<()> {
with_state!(state, {
state.set_current_shape_children(entries)?;
@ -566,124 +505,6 @@ pub extern "C" fn set_children_0() -> Result<()> {
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_children_1(a1: u32, b1: u32, c1: u32, d1: u32) -> Result<()> {
let entries = vec![uuid_from_u32_quartet(a1, b1, c1, d1)];
set_children_set(entries)?;
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_children_2(
a1: u32,
b1: u32,
c1: u32,
d1: u32,
a2: u32,
b2: u32,
c2: u32,
d2: u32,
) -> Result<()> {
let entries = vec![
uuid_from_u32_quartet(a1, b1, c1, d1),
uuid_from_u32_quartet(a2, b2, c2, d2),
];
set_children_set(entries)?;
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_children_3(
a1: u32,
b1: u32,
c1: u32,
d1: u32,
a2: u32,
b2: u32,
c2: u32,
d2: u32,
a3: u32,
b3: u32,
c3: u32,
d3: u32,
) -> Result<()> {
let entries = vec![
uuid_from_u32_quartet(a1, b1, c1, d1),
uuid_from_u32_quartet(a2, b2, c2, d2),
uuid_from_u32_quartet(a3, b3, c3, d3),
];
set_children_set(entries)?;
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_children_4(
a1: u32,
b1: u32,
c1: u32,
d1: u32,
a2: u32,
b2: u32,
c2: u32,
d2: u32,
a3: u32,
b3: u32,
c3: u32,
d3: u32,
a4: u32,
b4: u32,
c4: u32,
d4: u32,
) -> Result<()> {
let entries = vec![
uuid_from_u32_quartet(a1, b1, c1, d1),
uuid_from_u32_quartet(a2, b2, c2, d2),
uuid_from_u32_quartet(a3, b3, c3, d3),
uuid_from_u32_quartet(a4, b4, c4, d4),
];
set_children_set(entries)?;
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_children_5(
a1: u32,
b1: u32,
c1: u32,
d1: u32,
a2: u32,
b2: u32,
c2: u32,
d2: u32,
a3: u32,
b3: u32,
c3: u32,
d3: u32,
a4: u32,
b4: u32,
c4: u32,
d4: u32,
a5: u32,
b5: u32,
c5: u32,
d5: u32,
) -> Result<()> {
let entries = vec![
uuid_from_u32_quartet(a1, b1, c1, d1),
uuid_from_u32_quartet(a2, b2, c2, d2),
uuid_from_u32_quartet(a3, b3, c3, d3),
uuid_from_u32_quartet(a4, b4, c4, d4),
uuid_from_u32_quartet(a5, b5, c5, d5),
];
set_children_set(entries)?;
Ok(())
}
#[no_mangle]
#[wasm_error]
pub extern "C" fn set_children() -> Result<()> {

View File

@ -911,37 +911,6 @@ impl RenderState {
.ensure_tile_atlas_layout(self.tile_viewbox.interest_rect.len().max(1) as usize);
}
pub fn set_antialias_threshold(&mut self, value: f32) {
self.options.set_antialias_threshold(value);
}
pub fn set_viewport_interest_area_threshold(&mut self, value: i32) -> Result<()> {
// Only when this function returns true (it means the value
// was changed properly) the tile_viewbox.set_interest is called.
if self.options.set_viewport_interest_area_threshold(value) {
// The TileViewbox stores its own copy of `interest` (set at
// construction). Without propagating, options change wouldn't
// affect pending_tiles generation.
self.tile_viewbox
.set_interest(self.options.dpr_viewport_interest_area_threshold);
self.tile_viewbox.update(&self.viewbox);
self.ensure_tile_atlas_layout();
}
Ok(())
}
pub fn set_node_batch_threshold(&mut self, value: i32) {
self.options.set_node_batch_threshold(value);
}
pub fn set_max_blocking_time_ms(&mut self, value: i32) {
self.options.set_max_blocking_time_ms(value);
}
pub fn set_blur_downscale_threshold(&mut self, value: f32) {
self.options.set_blur_downscale_threshold(value);
}
pub fn set_background_color(&mut self, color: skia::Color) {
self.background_color = color;
}

View File

@ -121,45 +121,4 @@ impl RenderOptions {
pub fn show_wasm_info(&self) -> bool {
self.flags & SHOW_WASM_INFO == SHOW_WASM_INFO
}
pub fn set_antialias_threshold(&mut self, value: f32) -> bool {
if value.is_finite() && value > 0.0 {
self.antialias_threshold = value;
return true;
}
false
}
pub fn set_blur_downscale_threshold(&mut self, value: f32) -> bool {
if value.is_finite() && value > 0.0 {
self.blur_downscale_threshold = value;
return true;
}
false
}
pub fn set_viewport_interest_area_threshold(&mut self, value: i32) -> bool {
if value >= 0 && self.viewport_interest_area_threshold != value {
self.viewport_interest_area_threshold = value;
self.update_dpr_viewport_interest_area_threshold();
return true;
}
false
}
pub fn set_node_batch_threshold(&mut self, value: i32) -> bool {
if value > 0 {
self.node_batch_threshold = value;
return true;
}
false
}
pub fn set_max_blocking_time_ms(&mut self, value: i32) -> bool {
if value > 0 {
self.max_blocking_time_ms = value;
return true;
}
false
}
}

View File

@ -652,6 +652,7 @@ impl Shape {
self.background_blur.filter(|blur| !blur.hidden)
}
#[cfg(test)]
pub fn add_child(&mut self, id: Uuid) {
self.children.push(id);
}

View File

@ -1,12 +1,12 @@
use macros::{wasm_error, ToJs};
use crate::globals::{get_render_state, get_text_editor_state};
use crate::math::{Matrix, Point, Rect};
use crate::math::{Matrix, Point};
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};
use crate::state::{State, TextEditorEvent, TextSelection};
use crate::shapes::{TextAlign, TextPositionWithAffinity, Type, VerticalAlign};
use crate::state::{State, TextEditorEvent};
use crate::utils::uuid_from_u32_quartet;
use crate::utils::uuid_to_u32_quartet;
use crate::uuid::Uuid;
@ -643,40 +643,6 @@ pub extern "C" fn text_editor_move_cursor(
// RENDERING & EXPORT
// ============================================================================
#[no_mangle]
pub extern "C" fn text_editor_get_cursor_rect() -> *mut u8 {
with_state!(state, {
if !get_text_editor_state().has_focus || !get_text_editor_state().cursor_visible {
return std::ptr::null_mut();
}
let Some(shape_id) = get_text_editor_state().active_shape_id else {
return std::ptr::null_mut();
};
let Some(shape) = state.shapes.get(&shape_id) else {
return std::ptr::null_mut();
};
let Type::Text(text_content) = &shape.shape_type else {
return std::ptr::null_mut();
};
let cursor = &get_text_editor_state().selection.focus;
if let Some(rect) = get_cursor_rect(text_content, cursor, shape) {
let mut bytes = vec![0u8; 16];
bytes[0..4].copy_from_slice(&rect.left().to_le_bytes());
bytes[4..8].copy_from_slice(&rect.top().to_le_bytes());
bytes[8..12].copy_from_slice(&rect.width().to_le_bytes());
bytes[12..16].copy_from_slice(&rect.height().to_le_bytes());
return mem::write_bytes(bytes);
}
std::ptr::null_mut()
})
}
#[no_mangle]
pub extern "C" fn text_editor_get_current_styles() -> *mut u8 {
with_state!(state, {
@ -838,47 +804,6 @@ 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!(state, {
if !get_text_editor_state().has_focus {
return std::ptr::null_mut();
}
if get_text_editor_state().selection.is_collapsed() {
return std::ptr::null_mut();
}
let Some(shape_id) = get_text_editor_state().active_shape_id else {
return std::ptr::null_mut();
};
let Some(shape) = state.shapes.get(&shape_id) else {
return std::ptr::null_mut();
};
let Type::Text(text_content) = &shape.shape_type else {
return std::ptr::null_mut();
};
let selection = &get_text_editor_state().selection;
let rects = get_selection_rects(text_content, selection, shape);
if rects.is_empty() {
return std::ptr::null_mut();
}
let mut bytes = Vec::with_capacity(4 + rects.len() * 16);
bytes.extend_from_slice(&(rects.len() as u32).to_le_bytes());
for rect in rects {
bytes.extend_from_slice(&rect.left().to_le_bytes());
bytes.extend_from_slice(&rect.top().to_le_bytes());
bytes.extend_from_slice(&rect.width().to_le_bytes());
bytes.extend_from_slice(&rect.height().to_le_bytes());
}
mem::write_bytes(bytes)
})
}
#[no_mangle]
pub extern "C" fn text_editor_update_blink(timestamp_ms: f32) {
get_text_editor_state().update_blink(timestamp_ms);
@ -1124,139 +1049,3 @@ pub extern "C" fn text_editor_get_selection(buffer_ptr: *mut u32) -> bool {
true
})
}
// ============================================================================
// HELPERS: Cursor & Selection
// ============================================================================
fn get_cursor_rect(
text_content: &TextContent,
cursor: &TextPositionWithAffinity,
shape: &Shape,
) -> Option<Rect> {
let paragraphs = text_content.paragraphs();
if cursor.paragraph >= paragraphs.len() {
return None;
}
let layout_paragraphs: Vec<_> = text_content.layout.paragraphs.iter().flatten().collect();
let total_height: f32 = layout_paragraphs.iter().map(|p| p.height()).sum();
let valign_offset = match shape.vertical_align() {
VerticalAlign::Center => (shape.selrect().height() - total_height) / 2.0,
VerticalAlign::Bottom => shape.selrect().height() - total_height,
_ => 0.0,
};
let mut y_offset = valign_offset;
for (idx, laid_out_para) in layout_paragraphs.iter().enumerate() {
if idx == cursor.paragraph {
let utf16_pos = paragraphs[cursor.paragraph].char_offset_to_utf16(cursor.offset);
use skia_safe::textlayout::{RectHeightStyle, RectWidthStyle};
let rects = laid_out_para.get_rects_for_range(
utf16_pos..utf16_pos,
RectHeightStyle::Tight,
RectWidthStyle::Tight,
);
let (x, height) = if !rects.is_empty() {
(rects[0].rect.left(), rects[0].rect.height())
} else {
let pos = laid_out_para.get_glyph_position_at_coordinate((0.0, 0.0));
let height = laid_out_para.height();
(pos.position as f32, height)
};
let selrect = shape.selrect();
let base_x = selrect.x();
let base_y = selrect.y() + y_offset;
return Some(Rect::from_xywh(base_x + x, base_y, 1.0, height));
}
y_offset += laid_out_para.height();
}
None
}
/// Get selection rectangles for a given selection.
fn get_selection_rects(
text_content: &TextContent,
selection: &TextSelection,
shape: &Shape,
) -> Vec<Rect> {
let mut rects = Vec::new();
let start = selection.start();
let end = selection.end();
let paragraphs = text_content.paragraphs();
let layout_paragraphs: Vec<_> = text_content.layout.paragraphs.iter().flatten().collect();
let selrect = shape.selrect();
let total_height: f32 = layout_paragraphs.iter().map(|p| p.height()).sum();
let valign_offset = match shape.vertical_align() {
VerticalAlign::Center => (selrect.height() - total_height) / 2.0,
VerticalAlign::Bottom => selrect.height() - total_height,
_ => 0.0,
};
let mut y_offset = valign_offset;
for (para_idx, laid_out_para) in layout_paragraphs.iter().enumerate() {
let para_height = laid_out_para.height();
if para_idx < start.paragraph || para_idx > end.paragraph {
y_offset += para_height;
continue;
}
if para_idx >= paragraphs.len() {
y_offset += para_height;
continue;
}
let para = &paragraphs[para_idx];
let para_char_count: usize = para
.children()
.iter()
.map(|span| span.text.chars().count())
.sum();
let range_start = if para_idx == start.paragraph {
start.offset
} else {
0
};
let range_end = if para_idx == end.paragraph {
end.offset
} else {
para_char_count
};
if range_start < range_end {
use skia_safe::textlayout::{RectHeightStyle, RectWidthStyle};
let text_boxes = laid_out_para.get_rects_for_range(
para.char_offset_to_utf16(range_start)..para.char_offset_to_utf16(range_end),
RectHeightStyle::Tight,
RectWidthStyle::Tight,
);
for text_box in text_boxes {
let r = text_box.rect;
rects.push(Rect::from_xywh(
selrect.x() + r.left(),
selrect.y() + y_offset + r.top(),
r.width(),
r.height(),
));
}
}
y_offset += para_height;
}
rects
}