Support multiple panels per script
This commit is contained in:
parent
d54a59b3e8
commit
0ccf787f99
|
@ -26,6 +26,7 @@ fn main() {
|
|||
|
||||
struct App {
|
||||
script: canary::WasmtimeScript<canary::ScriptAbiImpl>,
|
||||
panel: canary::PanelId,
|
||||
last_update: Instant,
|
||||
}
|
||||
|
||||
|
@ -34,10 +35,12 @@ impl App {
|
|||
let runtime = canary::WasmtimeRuntime::new().unwrap();
|
||||
let abi = canary::ScriptAbiImpl::default();
|
||||
let module = std::fs::read(module_path).unwrap();
|
||||
let script = runtime.load_module(abi, &module).unwrap();
|
||||
let mut script = runtime.load_module(abi, &module).unwrap();
|
||||
let panel = script.bind_panel();
|
||||
|
||||
Self {
|
||||
script,
|
||||
panel,
|
||||
last_update: Instant::now(),
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +52,7 @@ impl eframe::App for App {
|
|||
|
||||
let dt = self.last_update.elapsed().as_secs_f32();
|
||||
self.last_update = Instant::now();
|
||||
self.script.update(dt);
|
||||
self.script.update(self.panel, dt);
|
||||
|
||||
egui::Window::new("Panel").show(ctx, |ui| {
|
||||
let size = egui::vec2(800.0, 800.0);
|
||||
|
@ -78,14 +81,14 @@ impl eframe::App for App {
|
|||
CursorEventKind::Hover
|
||||
};
|
||||
|
||||
self.script.on_cursor_event(kind, pos);
|
||||
self.script.on_cursor_event(self.panel, kind, pos);
|
||||
}
|
||||
|
||||
let texture = egui::TextureId::Managed(0);
|
||||
let uv = egui::pos2(0.0, 0.0);
|
||||
let mut mesh = egui::Mesh::with_texture(texture);
|
||||
|
||||
self.script.draw(|commands| {
|
||||
self.script.draw(self.panel, |commands| {
|
||||
for command in commands.iter() {
|
||||
let voff = mesh.vertices.len() as u32;
|
||||
|
||||
|
|
|
@ -11,18 +11,18 @@ macro_rules! export_abi {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn update(dt: f32) {
|
||||
::canary_script::abi::update(dt)
|
||||
pub extern "C" fn update(panel_data: u32, dt: f32) {
|
||||
::canary_script::abi::update(panel_data, dt)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn draw() {
|
||||
::canary_script::abi::draw()
|
||||
pub extern "C" fn draw(panel_data: u32) {
|
||||
::canary_script::abi::draw(panel_data)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn on_cursor_event(kind: u32, x: f32, y: f32) {
|
||||
::canary_script::abi::on_cursor_event(kind, x, y)
|
||||
pub extern "C" fn on_cursor_event(panel_data: u32, kind: u32, x: f32, y: f32) {
|
||||
::canary_script::abi::on_cursor_event(panel_data, kind, x, y)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -43,24 +43,18 @@ pub mod abi {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(dt: f32) {
|
||||
unsafe {
|
||||
for panel in PANEL_IMPLS.iter_mut() {
|
||||
panel.update(dt);
|
||||
}
|
||||
}
|
||||
pub fn update(panel_data: u32, dt: f32) {
|
||||
let panel = unsafe { &mut PANEL_IMPLS[panel_data as usize] };
|
||||
panel.update(dt);
|
||||
}
|
||||
|
||||
pub fn draw() {
|
||||
unsafe {
|
||||
for panel in PANEL_IMPLS.iter_mut() {
|
||||
panel.draw();
|
||||
}
|
||||
}
|
||||
pub fn draw(panel_data: u32) {
|
||||
let panel = unsafe { &mut PANEL_IMPLS[panel_data as usize] };
|
||||
panel.draw();
|
||||
}
|
||||
|
||||
pub fn on_cursor_event(kind: u32, x: f32, y: f32) {
|
||||
let panel = unsafe { &mut PANEL_IMPLS[0] };
|
||||
pub fn on_cursor_event(panel_data: u32, kind: u32, x: f32, y: f32) {
|
||||
let panel = unsafe { &mut PANEL_IMPLS[panel_data as usize] };
|
||||
let at = canary_types::Vec2 { x, y };
|
||||
let kind = CursorEventKind::from_u32(kind).unwrap();
|
||||
panel.on_cursor_event(kind, at);
|
||||
|
|
51
src/lib.rs
51
src/lib.rs
|
@ -23,10 +23,14 @@ pub trait ScriptAbi {
|
|||
fn text_layout_get_bounds(&self, id: u32, rect: &mut Rect);
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct PanelId(pub(crate) usize);
|
||||
|
||||
pub trait ScriptInstance {
|
||||
fn update(&mut self, dt: f32);
|
||||
fn draw(&mut self, f: impl FnOnce(&[DrawCommand]));
|
||||
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2);
|
||||
fn bind_panel(&mut self) -> PanelId;
|
||||
fn update(&mut self, panel: PanelId, dt: f32);
|
||||
fn draw(&mut self, panel: PanelId, f: impl FnOnce(&[DrawCommand]));
|
||||
fn on_cursor_event(&mut self, panel: PanelId, kind: CursorEventKind, at: Vec2);
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
|
@ -60,18 +64,19 @@ impl WasmtimeRuntime {
|
|||
) -> anyhow::Result<WasmtimeScript<T>> {
|
||||
let module = wasmtime::Module::new(&self.engine, module)?;
|
||||
let mut store = wasmtime::Store::new(&self.engine, abi);
|
||||
let panel_datas = Default::default();
|
||||
let mut linker = wasmtime::Linker::new(&self.engine);
|
||||
WasmtimeScript::link(&mut linker)?;
|
||||
let instance = linker.instantiate(&mut store, &module)?;
|
||||
let bind_panel = instance.get_typed_func(&mut store, "bind_panel")?;
|
||||
let update = instance.get_typed_func(&mut store, "update")?;
|
||||
let draw = instance.get_typed_func(&mut store, "draw")?;
|
||||
let on_cursor_event = instance.get_typed_func(&mut store, "on_cursor_event")?;
|
||||
|
||||
let bind_panel = instance.get_typed_func::<u32, u32, _>(&mut store, "bind_panel")?;
|
||||
bind_panel.call(&mut store, 0u32)?;
|
||||
|
||||
Ok(WasmtimeScript {
|
||||
store,
|
||||
panel_datas,
|
||||
bind_panel,
|
||||
update,
|
||||
draw,
|
||||
on_cursor_event,
|
||||
|
@ -81,9 +86,11 @@ impl WasmtimeRuntime {
|
|||
|
||||
pub struct WasmtimeScript<T> {
|
||||
store: wasmtime::Store<T>,
|
||||
update: wasmtime::TypedFunc<f32, ()>,
|
||||
draw: wasmtime::TypedFunc<(), ()>,
|
||||
on_cursor_event: wasmtime::TypedFunc<(u32, f32, f32), ()>,
|
||||
panel_datas: Slab<u32>,
|
||||
bind_panel: wasmtime::TypedFunc<u32, u32>,
|
||||
update: wasmtime::TypedFunc<(u32, f32), ()>,
|
||||
draw: wasmtime::TypedFunc<u32, ()>,
|
||||
on_cursor_event: wasmtime::TypedFunc<(u32, u32, f32, f32), ()>,
|
||||
}
|
||||
|
||||
impl<T: ScriptAbi> WasmtimeScript<T> {
|
||||
|
@ -158,6 +165,10 @@ impl<T: ScriptAbi> WasmtimeScript<T> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn get_panel_data(&self, panel: PanelId) -> u32 {
|
||||
*self.panel_datas.get(panel.0).unwrap()
|
||||
}
|
||||
|
||||
fn get_memory_ref<D: bytemuck::Pod>(
|
||||
caller: &mut wasmtime::Caller<'_, T>,
|
||||
ptr: u32,
|
||||
|
@ -204,19 +215,29 @@ impl<T: ScriptAbi> WasmtimeScript<T> {
|
|||
}
|
||||
|
||||
impl<T: ScriptAbi> ScriptInstance for WasmtimeScript<T> {
|
||||
fn update(&mut self, dt: f32) {
|
||||
self.update.call(&mut self.store, dt).unwrap();
|
||||
fn bind_panel(&mut self) -> PanelId {
|
||||
let id = self.panel_datas.insert(0);
|
||||
let data = self.bind_panel.call(&mut self.store, id as u32).unwrap();
|
||||
*self.panel_datas.get_mut(id).unwrap() = data;
|
||||
PanelId(id)
|
||||
}
|
||||
|
||||
fn draw(&mut self, f: impl FnOnce(&[DrawCommand])) {
|
||||
fn update(&mut self, panel: PanelId, dt: f32) {
|
||||
let data = self.get_panel_data(panel);
|
||||
self.update.call(&mut self.store, (data, dt)).unwrap();
|
||||
}
|
||||
|
||||
fn draw(&mut self, panel: PanelId, f: impl FnOnce(&[DrawCommand])) {
|
||||
let data = self.get_panel_data(panel);
|
||||
self.store.data().start_draw();
|
||||
self.draw.call(&mut self.store, ()).unwrap();
|
||||
self.draw.call(&mut self.store, data).unwrap();
|
||||
self.store.data().with_draw_commands(f);
|
||||
}
|
||||
|
||||
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {
|
||||
fn on_cursor_event(&mut self, panel: PanelId, kind: CursorEventKind, at: Vec2) {
|
||||
let data = self.get_panel_data(panel);
|
||||
self.on_cursor_event
|
||||
.call(&mut self.store, (kind as u32, at.x, at.y))
|
||||
.call(&mut self.store, (data, kind as u32, at.x, at.y))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue