use jni::JNIEnv;
use jni::objects::{JClass, JString};
use jni::sys::{jstring, jboolean, jint, JNI_TRUE, JNI_FALSE};
use jni::JavaVM;
use std::sync::OnceLock;
use crate::runtime::{dispatch_event, did_navigate, render_current_to_json};
use crate::navigation::navigate_back;
static JVM: OnceLock<JavaVM> = OnceLock::new();
#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeInit(
mut env: JNIEnv,
_class: JClass,
) {
env_logger::try_init().ok();
log::info!("[Bubba] nativeInit called");
if let Ok(vm) = env.get_java_vm() {
JVM.set(vm).ok();
}
}
#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeOnLifecycle(
mut env: JNIEnv,
_class: JClass,
event: JString,
) {
let event_str: String = env.get_string(&event)
.map(|s| s.into())
.unwrap_or_default();
log::info!("[Bubba] Lifecycle: {}", event_str);
}
#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeRender(
mut env: JNIEnv,
_class: JClass,
) -> jstring {
let json = render_current_to_json();
log::debug!("[Bubba] nativeRender {} bytes", json.len());
env.new_string(json)
.map(|s| s.into_raw())
.unwrap_or(std::ptr::null_mut())
}
#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeOnEvent(
mut env: JNIEnv,
_class: JClass,
element_id: jint,
event_kind: JString,
value: JString,
) {
let kind: String = env.get_string(&event_kind)
.map(|s| s.into())
.unwrap_or_default();
let val: String = env.get_string(&value)
.map(|s| s.into())
.unwrap_or_default();
log::debug!("[Bubba] nativeOnEvent: {} on #{}", kind, element_id);
dispatch_event(element_id as u32, &kind, &val);
}
#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeDidNavigate(
_env: JNIEnv,
_class: JClass,
) -> jboolean {
if did_navigate() { JNI_TRUE } else { JNI_FALSE }
}
#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeOnBack(
_env: JNIEnv,
_class: JClass,
) -> jboolean {
if navigate_back() { JNI_TRUE } else { JNI_FALSE }
}