feat(jni): implement ANativeActivity struct and lifecycle callback runner
This commit is contained in:
parent
45c56f342f
commit
8307bee065
3 changed files with 139 additions and 0 deletions
124
crates/molotov-core/src/jni/activity.rs
Normal file
124
crates/molotov-core/src/jni/activity.rs
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#![allow(non_snake_case, dead_code)]
|
||||||
|
use super::env::JNIEnvWrapper;
|
||||||
|
use super::types::{JNIEnvPtr, JavaVMPtr};
|
||||||
|
use super::vm::JavaVMWrapper;
|
||||||
|
use std::ffi::c_void;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ANativeActivityCallbacks {
|
||||||
|
pub onStart: Option<unsafe extern "C" fn(activity: *mut ANativeActivity)>,
|
||||||
|
pub onResume: Option<unsafe extern "C" fn(activity: *mut ANativeActivity)>,
|
||||||
|
pub onSaveInstanceState: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, outSize: *mut usize) -> *mut c_void>,
|
||||||
|
pub onPause: Option<unsafe extern "C" fn(activity: *mut ANativeActivity)>,
|
||||||
|
pub onStop: Option<unsafe extern "C" fn(activity: *mut ANativeActivity)>,
|
||||||
|
pub onDestroy: Option<unsafe extern "C" fn(activity: *mut ANativeActivity)>,
|
||||||
|
pub onWindowFocusChanged: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, hasFocus: i32)>,
|
||||||
|
pub onNativeWindowCreated: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, window: *mut c_void)>,
|
||||||
|
pub onNativeWindowResized: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, window: *mut c_void)>,
|
||||||
|
pub onNativeWindowRedrawNeeded: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, window: *mut c_void)>,
|
||||||
|
pub onNativeWindowDestroyed: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, window: *mut c_void)>,
|
||||||
|
pub onInputQueueCreated: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, queue: *mut c_void)>,
|
||||||
|
pub onInputQueueDestroyed: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, queue: *mut c_void)>,
|
||||||
|
pub onContentRectChanged: Option<unsafe extern "C" fn(activity: *mut ANativeActivity, rect: *const c_void)>,
|
||||||
|
pub onConfigurationChanged: Option<unsafe extern "C" fn(activity: *mut ANativeActivity)>,
|
||||||
|
pub onLowMemory: Option<unsafe extern "C" fn(activity: *mut ANativeActivity)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ANativeActivity {
|
||||||
|
pub callbacks: *mut ANativeActivityCallbacks,
|
||||||
|
pub vm: JavaVMPtr,
|
||||||
|
pub env: JNIEnvPtr,
|
||||||
|
pub clazz: *mut c_void,
|
||||||
|
pub internalDataPath: *const libc::c_char,
|
||||||
|
pub externalDataPath: *const libc::c_char,
|
||||||
|
pub sdkVersion: i32,
|
||||||
|
pub instance: *mut c_void,
|
||||||
|
pub assetManager: *mut c_void,
|
||||||
|
pub obbPath: *const libc::c_char,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ActivityRunner {
|
||||||
|
pub vm: JavaVMWrapper,
|
||||||
|
pub env: JNIEnvWrapper,
|
||||||
|
pub callbacks: Box<ANativeActivityCallbacks>,
|
||||||
|
pub activity: Box<ANativeActivity>,
|
||||||
|
resumed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ActivityRunner {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActivityRunner {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let vm = JavaVMWrapper::new();
|
||||||
|
let env = JNIEnvWrapper::new();
|
||||||
|
|
||||||
|
let mut callbacks = Box::new(ANativeActivityCallbacks {
|
||||||
|
onStart: None,
|
||||||
|
onResume: None,
|
||||||
|
onSaveInstanceState: None,
|
||||||
|
onPause: None,
|
||||||
|
onStop: None,
|
||||||
|
onDestroy: None,
|
||||||
|
onWindowFocusChanged: None,
|
||||||
|
onNativeWindowCreated: None,
|
||||||
|
onNativeWindowResized: None,
|
||||||
|
onNativeWindowRedrawNeeded: None,
|
||||||
|
onNativeWindowDestroyed: None,
|
||||||
|
onInputQueueCreated: None,
|
||||||
|
onInputQueueDestroyed: None,
|
||||||
|
onContentRectChanged: None,
|
||||||
|
onConfigurationChanged: None,
|
||||||
|
onLowMemory: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let activity = Box::new(ANativeActivity {
|
||||||
|
callbacks: &mut *callbacks as *mut ANativeActivityCallbacks,
|
||||||
|
vm: vm.as_raw_ptr(),
|
||||||
|
env: env.as_raw_ptr(),
|
||||||
|
clazz: ptr::null_mut(),
|
||||||
|
internalDataPath: ptr::null(),
|
||||||
|
externalDataPath: ptr::null(),
|
||||||
|
sdkVersion: 33,
|
||||||
|
instance: ptr::null_mut(),
|
||||||
|
assetManager: ptr::null_mut(),
|
||||||
|
obbPath: ptr::null(),
|
||||||
|
});
|
||||||
|
|
||||||
|
Self {
|
||||||
|
vm,
|
||||||
|
env,
|
||||||
|
callbacks,
|
||||||
|
activity,
|
||||||
|
resumed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_resumed(&self) -> bool {
|
||||||
|
self.resumed
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trigger_resume(&mut self) {
|
||||||
|
self.resumed = true;
|
||||||
|
if let Some(cb) = self.callbacks.onResume {
|
||||||
|
unsafe {
|
||||||
|
cb(&mut *self.activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trigger_pause(&mut self) {
|
||||||
|
self.resumed = false;
|
||||||
|
if let Some(cb) = self.callbacks.onPause {
|
||||||
|
unsafe {
|
||||||
|
cb(&mut *self.activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
pub mod activity;
|
||||||
pub mod env;
|
pub mod env;
|
||||||
pub mod framework;
|
pub mod framework;
|
||||||
pub mod objects;
|
pub mod objects;
|
||||||
|
|
|
||||||
14
crates/molotov-core/tests/jni_activity_test.rs
Normal file
14
crates/molotov-core/tests/jni_activity_test.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
use molotov_core::jni::activity::ActivityRunner;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_activity_runner_lifecycle_callbacks() {
|
||||||
|
let mut runner = ActivityRunner::new();
|
||||||
|
assert_eq!(runner.is_resumed(), false);
|
||||||
|
|
||||||
|
runner.trigger_resume();
|
||||||
|
assert_eq!(runner.is_resumed(), true);
|
||||||
|
|
||||||
|
runner.trigger_pause();
|
||||||
|
assert_eq!(runner.is_resumed(), false);
|
||||||
|
}
|
||||||
Reference in a new issue