use std::{cell::RefCell, rc::Rc};
use tairitsu_vdom::Patch;
use crate::WitElement;
#[cfg(feature = "wit-bindings")]
pub fn init_runtime(root_element: WitElement) {
let root_ref: Rc<RefCell<WitElement>> = Rc::new(RefCell::new(root_element));
#[cfg(target_family = "wasm")]
{
tairitsu_vdom::events::register_event_control_functions(
crate::wit_platform::prevent_event_default,
|handle| {
crate::wit_platform::wasm_impl::bindings::tairitsu_browser::full::event_target::stop_propagation(handle);
},
);
}
tairitsu_vdom::runtime::set_schedule_callback({
move |callback: Box<dyn FnOnce()>| {
#[cfg(target_family = "wasm")]
{
let callback_id = crate::wit_platform::wasm_impl::next_callback_id();
crate::wit_platform::wasm_impl::ANIMATION_CALLBACKS.with(|m| {
m.borrow_mut().insert(
callback_id,
Some(Box::new(move |_timestamp| {
callback();
})),
);
});
crate::wit_platform::wasm_impl::bindings::tairitsu_browser::full::platform_helpers::request_animation_frame(callback_id);
}
#[cfg(not(target_family = "wasm"))]
{
let _ = callback;
tracing::error!("request_animation_frame is only available on wasm32 targets");
}
}
});
tairitsu_vdom::runtime::set_apply_patches_callback({
let root_ref_clone: Rc<RefCell<WitElement>> = Rc::clone(&root_ref);
move |component_id: tairitsu_vdom::ComponentId, patches: Vec<Patch>| {
let root = root_ref_clone.borrow();
#[cfg(target_family = "wasm")]
{
if let Ok(platform) = crate::WitPlatform::new() {
crate::wit_platform::wasm_impl::with_render_component(component_id, || {
if let Err(e) = platform.apply_patches(&root, &patches) {
tracing::error!("Failed to apply patches: {:?}", e);
}
});
} else {
tracing::error!("Failed to create platform for patch application");
}
}
#[cfg(not(target_family = "wasm"))]
{
let _ = (root, patches, component_id);
tracing::error!("apply_patches is only available on wasm32 targets");
}
}
});
tracing::info!("Runtime initialized with web platform callbacks");
}
#[cfg(feature = "wit-bindings")]
pub struct ComponentRenderer {
root_element: Rc<RefCell<WitElement>>,
}
#[cfg(feature = "wit-bindings")]
impl ComponentRenderer {
pub fn new(root_element: WitElement) -> Self {
Self {
root_element: Rc::new(RefCell::new(root_element)),
}
}
pub fn init_runtime(&self) {
let root = *self.root_element.borrow();
init_runtime(root);
}
pub fn mount(&self, vnode: tairitsu_vdom::VNode) -> anyhow::Result<()> {
#[cfg(target_family = "wasm")]
{
if let Ok(platform) = crate::WitPlatform::new() {
platform.mount_vnode_to_app(vnode)
} else {
anyhow::bail!("Failed to create platform for mounting")
}
}
#[cfg(not(target_family = "wasm"))]
{
let _ = vnode;
anyhow::bail!("mount is only available on wasm32 targets")
}
}
}
#[cfg(test)]
mod tests {
#[allow(unused_imports)]
use super::*;
#[test]
fn test_init_runtime() {
}
}