🎉 Tile rendering system

This commit is contained in:
Aitor Moreno 2025-02-17 12:54:51 +01:00 committed by Alejandro Alonso
parent b727f2fe1f
commit 084816fb9f
17 changed files with 956 additions and 408 deletions

View file

@ -1,6 +1,7 @@
use skia_safe as skia;
mod debug;
mod emscripten;
mod math;
mod mem;
mod render;
@ -18,12 +19,6 @@ use state::State;
pub(crate) static mut STATE: Option<Box<State>> = None;
extern "C" {
fn emscripten_GetProcAddress(
name: *const ::std::os::raw::c_char,
) -> *const ::std::os::raw::c_void;
}
#[macro_export]
macro_rules! with_state {
($state:ident, $block:block) => {
@ -50,15 +45,6 @@ macro_rules! with_current_shape {
};
}
fn init_gl() {
unsafe {
gl::load_with(|addr| {
let addr = std::ffi::CString::new(addr).unwrap();
emscripten_GetProcAddress(addr.into_raw() as *const _) as *const _
});
}
}
/// This is called from JS after the WebGL context has been created.
#[no_mangle]
pub extern "C" fn init(width: i32, height: i32) {
@ -77,8 +63,7 @@ pub extern "C" fn clean_up() {
#[no_mangle]
pub extern "C" fn clear_cache() {
with_state!(state, {
let render_state = state.render_state();
render_state.clear_cache();
state.rebuild_tiles();
});
}
@ -106,13 +91,6 @@ pub extern "C" fn render(timestamp: i32) {
});
}
#[no_mangle]
pub extern "C" fn render_from_cache() {
with_state!(state, {
state.render_from_cache();
});
}
#[no_mangle]
pub extern "C" fn process_animation_frame(timestamp: i32) {
with_state!(state, {
@ -140,22 +118,13 @@ pub extern "C" fn resize_viewbox(width: i32, height: i32) {
pub extern "C" fn set_view(zoom: f32, x: f32, y: f32) {
with_state!(state, {
let render_state = state.render_state();
render_state.invalidate_cache_if_needed();
let zoom_changed = zoom != render_state.viewbox.zoom;
render_state.viewbox.set_all(zoom, x, y);
});
}
#[no_mangle]
pub extern "C" fn set_view_zoom(zoom: f32) {
with_state!(state, {
state.render_state().viewbox.set_zoom(zoom);
});
}
#[no_mangle]
pub extern "C" fn set_view_xy(x: f32, y: f32) {
with_state!(state, {
state.render_state().viewbox.set_pan_xy(x, y);
if zoom_changed {
with_state!(state, {
state.rebuild_tiles();
});
}
});
}
@ -169,11 +138,12 @@ pub extern "C" fn use_shape(a: u32, b: u32, c: u32, d: u32) {
#[no_mangle]
pub unsafe extern "C" fn set_parent(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() {
shape.set_parent(id);
}
with_state!(state, {
let id = uuid_from_u32_quartet(a, b, c, d);
with_current_shape!(state, |shape: &mut Shape| {
shape.set_parent(id);
});
});
}
#[no_mangle]
@ -199,8 +169,8 @@ pub unsafe extern "C" fn set_shape_type(shape_type: u8) {
#[no_mangle]
pub extern "C" fn set_shape_selrect(left: f32, top: f32, right: f32, bottom: f32) {
with_current_shape!(state, |shape: &mut Shape| {
shape.set_selrect(left, top, right, bottom);
with_state!(state, {
state.set_selrect_for_current_shape(left, top, right, bottom);
});
}
@ -621,7 +591,10 @@ pub extern "C" fn set_modifiers() {
for entry in entries {
state.modifiers.insert(entry.id, entry.transform);
}
state.render_state().clear_cache();
// TODO: Do a more specific rebuild of tiles. For
// example: using only the selected shapes to rebuild
// the tiles affected by the selected shapes.
state.rebuild_tiles();
});
}
@ -752,5 +725,5 @@ pub extern "C" fn add_grid_track() {}
pub extern "C" fn set_grid_cell() {}
fn main() {
init_gl();
init_gl!();
}