mirror of
https://github.com/tauri-apps/tao.git
synced 2026-01-31 00:35:16 +01:00
refactor: improve android_fn! lifetime support (#780)
* refactor: improve android_fn! lifetime support * take ownership in setup function * Update tao-macros/src/lib.rs Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.studio> --------- Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.studio>
This commit is contained in:
@@ -749,7 +749,7 @@ impl MonitorHandle {
|
||||
.l()
|
||||
.unwrap();
|
||||
let rect = env
|
||||
.call_method(metrics, "getBounds", "()Landroid/graphics/Rect;", &[])
|
||||
.call_method(&metrics, "getBounds", "()Landroid/graphics/Rect;", &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
@@ -759,7 +759,7 @@ impl MonitorHandle {
|
||||
.i()
|
||||
.unwrap();
|
||||
let height = env
|
||||
.call_method(rect, "height", "()I", &[])
|
||||
.call_method(&rect, "height", "()I", &[])
|
||||
.unwrap()
|
||||
.i()
|
||||
.unwrap();
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use tao_macros::android_fn;
|
||||
|
||||
struct JNIEnv;
|
||||
struct JClass;
|
||||
struct JNIEnv<'a> {
|
||||
_marker: &'a PhantomData<()>,
|
||||
}
|
||||
#[repr(C)]
|
||||
struct JClass<'a> {
|
||||
_marker: &'a PhantomData<()>,
|
||||
}
|
||||
|
||||
android_fn![com_example, tao_app, SomeClass, add, []];
|
||||
unsafe fn add(_env: JNIEnv, _class: JClass) {}
|
||||
@@ -53,15 +60,21 @@ unsafe fn add8(_env: JNIEnv, _class: JClass, _a: i32, _b: i32) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
android_fn!(
|
||||
android_fn![
|
||||
com_example,
|
||||
tao_app,
|
||||
SomeClass,
|
||||
add9,
|
||||
[i32, i32],
|
||||
__VOID__,
|
||||
[],
|
||||
);
|
||||
unsafe fn add9(_env: JNIEnv, _class: JClass, _a: i32, _b: i32) {}
|
||||
add10,
|
||||
[JClass<'local>, i32],
|
||||
JClass<'local>
|
||||
];
|
||||
unsafe fn add10<'local>(
|
||||
_env: JNIEnv<'local>,
|
||||
_class: JClass<'local>,
|
||||
a: JClass<'local>,
|
||||
_b: i32,
|
||||
) -> JClass<'local> {
|
||||
a
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -99,19 +99,24 @@ impl Parse for AndroidFnInput {
|
||||
/// 3. Java/Kotlin class name.
|
||||
/// 4. Rust function name (`ident`).
|
||||
/// 5. List of extra types your Rust function expects. Pass empty array if the function doesn't need any arugments.
|
||||
/// - If your function takes an arguments as reference with a lifetime tied to the [`JNIEnv`], it should use `'local` as the lifetime name as it is the
|
||||
/// lifetime name generated by the macro.
|
||||
/// Note that all rust functions should expect the first two parameters to be [`JNIEnv`] and [`JClass`] so make sure they are imported into scope).
|
||||
/// 6. (Optional) Return type of your rust function.
|
||||
/// if you want to use the next parameter you need to provide a type or just pass `__VOID__` if the function doesn't return anything.
|
||||
/// 7. (Optional) List of `ident`s to pass to the rust function when invoked (This mostly exists for internal usages).
|
||||
/// 8. (Optional) Function to be invoked right before invoking the rust function (This mostly exists for internal usages).
|
||||
/// - If your function returns a reference with a lifetime tied to the [`JNIEnv`], it should use `'local` as the lifetime name as it is the
|
||||
/// lifetime name generated by the macro.
|
||||
/// - if you want to use the next macro parameter you need to provide a type or just pass `__VOID__` if the function doesn't return anything.
|
||||
/// 7. (Optional) List of `ident`s to pass to the rust function when invoked (This mostly exists for internal usage by `tao` crate).
|
||||
/// 8. (Optional) Function to be invoked right before invoking the rust function (This mostly exists for internal usage by `tao` crate).
|
||||
///
|
||||
/// ## Example
|
||||
/// ## Example 1: Basic
|
||||
///
|
||||
/// ```
|
||||
/// # use tao_macros::android_fn;
|
||||
/// # struct JNIEnv;
|
||||
/// # struct JClass;
|
||||
///
|
||||
/// # struct JNIEnv<'a> {
|
||||
/// # _marker: &'a std::marker::PhantomData<()>,
|
||||
/// # }
|
||||
/// # type JClass<'a> = JNIEnv<'a>;
|
||||
/// android_fn![com_example, tao, OperationsClass, add, [i32, i32], i32];
|
||||
/// unsafe fn add(_env: JNIEnv, _class: JClass, a: i32, b: i32) -> i32 {
|
||||
/// a + b
|
||||
@@ -119,19 +124,21 @@ impl Parse for AndroidFnInput {
|
||||
/// ```
|
||||
/// which will expand into:
|
||||
/// ```
|
||||
/// # struct JNIEnv;
|
||||
/// # struct JClass;
|
||||
/// # struct JNIEnv<'a> {
|
||||
/// # _marker: &'a std::marker::PhantomData<()>,
|
||||
/// # }
|
||||
/// # type JClass<'a> = JNIEnv<'a>;
|
||||
/// #[no_mangle]
|
||||
/// unsafe extern "C" fn Java_com_example_tao_OperationsClass_add(
|
||||
/// env: JNIEnv,
|
||||
/// class: JClass,
|
||||
/// unsafe extern "C" fn Java_com_example_tao_OperationsClass_add<'local>(
|
||||
/// env: JNIEnv<'local>,
|
||||
/// class: JClass<'local>,
|
||||
/// a_1: i32,
|
||||
/// a_2: i32
|
||||
/// ) -> i32 {
|
||||
/// add(env, class, a_1, a_2)
|
||||
/// }
|
||||
///
|
||||
/// unsafe fn add(_env: JNIEnv, _class: JClass, a: i32, b: i32) -> i32 {
|
||||
/// unsafe fn add<'local>(_env: JNIEnv<'local>, _class: JClass<'local>, a: i32, b: i32) -> i32 {
|
||||
/// a + b
|
||||
/// }
|
||||
/// ```
|
||||
@@ -143,6 +150,41 @@ impl Parse for AndroidFnInput {
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Example 2: Return a reference with a lifetime
|
||||
///
|
||||
/// ```
|
||||
/// # use tao_macros::android_fn;
|
||||
/// # struct JNIEnv<'a> {
|
||||
/// # _marker: &'a std::marker::PhantomData<()>,
|
||||
/// # }
|
||||
/// # type JClass<'a> = JNIEnv<'a>;
|
||||
/// # type JObject<'a> = JNIEnv<'a>;
|
||||
/// android_fn![com_example, tao, OperationsClass, add, [JObject<'local>], JClass<'local>];
|
||||
/// unsafe fn add<'local>(mut _env: JNIEnv<'local>, class: JClass<'local>, obj: JObject<'local>) -> JClass<'local> {
|
||||
/// class
|
||||
/// }
|
||||
/// ```
|
||||
/// which will expand into:
|
||||
/// ```
|
||||
/// # struct JNIEnv<'a> {
|
||||
/// # _marker: &'a std::marker::PhantomData<()>,
|
||||
/// # }
|
||||
/// # type JClass<'a> = JNIEnv<'a>;
|
||||
/// # type JObject<'a> = JNIEnv<'a>;
|
||||
/// #[no_mangle]
|
||||
/// unsafe extern "C" fn Java_com_example_tao_OperationsClass_add<'local>(
|
||||
/// env: JNIEnv<'local>,
|
||||
/// class: JClass<'local>,
|
||||
/// a_1: JObject<'local>,
|
||||
/// ) -> JClass<'local> {
|
||||
/// add(env, class, a_1)
|
||||
/// }
|
||||
///
|
||||
/// unsafe fn add<'local>(mut _env: JNIEnv<'local>, class: JClass<'local>, obj: JObject<'local>) -> JClass<'local> {
|
||||
/// class
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// - [`JNIEnv`]: https://docs.rs/jni/latest/jni/struct.JNIEnv.html
|
||||
/// - [`JClass`]: https://docs.rs/jni/latest/jni/objects/struct.JClass.html
|
||||
#[proc_macro]
|
||||
@@ -160,7 +202,7 @@ pub fn android_fn(tokens: TokenStream) -> TokenStream {
|
||||
} = tokens;
|
||||
|
||||
let domain = domain.to_string();
|
||||
let package = package.to_string().replace("_", "_1").replace("-", "_1");
|
||||
let package = package.to_string().replace('_', "_1").replace('-', "_1");
|
||||
let class = class.to_string();
|
||||
let args = args
|
||||
.into_iter()
|
||||
@@ -196,9 +238,9 @@ pub fn android_fn(tokens: TokenStream) -> TokenStream {
|
||||
|
||||
quote! {
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn #java_fn_name(
|
||||
env: JNIEnv,
|
||||
class: JClass,
|
||||
unsafe extern "C" fn #java_fn_name<'local>(
|
||||
env: JNIEnv<'local>,
|
||||
class: JClass<'local>,
|
||||
#(#args),*
|
||||
) #ret {
|
||||
#function_before();
|
||||
@@ -253,8 +295,8 @@ pub fn generate_package_name(tokens: TokenStream) -> TokenStream {
|
||||
let tokens = parse_macro_input!(tokens as GeneratePackageNameInput);
|
||||
let GeneratePackageNameInput { domain, package } = tokens;
|
||||
|
||||
let domain = domain.to_string().replace("_", "/");
|
||||
let package = package.to_string().replace("-", "_");
|
||||
let domain = domain.to_string().replace('_', "/");
|
||||
let package = package.to_string().replace('-', "_");
|
||||
|
||||
let path = format!("{}/{}", domain, package);
|
||||
let litstr = LitStr::new(&path, proc_macro2::Span::call_site());
|
||||
|
||||
Reference in New Issue
Block a user