Skip to content

Commit

Permalink
feat: switch android_fn! to a proc_macro (#654)
Browse files Browse the repository at this point in the history
* feat: switch android_fn! to a proc_macro

* document the macros

* add to CI

* fix ci

* again

* one more
  • Loading branch information
amrbashir authored Dec 26, 2022
1 parent 77569c8 commit b3aa398
Show file tree
Hide file tree
Showing 12 changed files with 374 additions and 50 deletions.
4 changes: 4 additions & 0 deletions .changes/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
"tao": {
"path": "./",
"manager": "rust"
},
"tao-macros": {
"path": "./tao-macros",
"manager": "rust"
}
}
}
4 changes: 2 additions & 2 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ on:
- cron: '0 0 * * *'
push:
paths:
- "Cargo.lock"
- "Cargo.toml"
- "**/Cargo.lock"
- "**/Cargo.toml"

jobs:
audit-rust:
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,25 @@ jobs:
!contains(matrix.platform.target, 'ios'))
run: cargo $CMD test --verbose --target ${{ matrix.platform.target }} $OPTIONS --features serde,tray,$FEATURES

test_tao_macros:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Cache cargo folder
uses: actions/cache@v1
with:
path: ~/.cargo
key: ${{ matrix.platform.target }}-cargo-${{ matrix.rust_version }}

- uses: actions-rs/toolchain@v1
with:
toolchain: stable

- name: Run tests
shell: bash
run: cargo test --package tao-macros

fmt:
name: fmt check
runs-on: ubuntu-latest
Expand Down
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ repository = "https://github.com/tauri-apps/tao"
documentation = "https://docs.rs/tao"
categories = [ "gui" ]

[workspace]
members = [ "tao-macros" ]

[package.metadata.docs.rs]
features = [ "serde", "tray", "dox" ]
default-target = "x86_64-unknown-linux-gnu"
Expand Down Expand Up @@ -54,7 +57,7 @@ ndk = "0.6"
ndk-sys = "0.3"
ndk-context = "0.1"
once_cell = "1"
paste = "1.0"
tao-macros = { version = "0.0.0", path = "./tao-macros" }

[target."cfg(any(target_os = \"ios\", target_os = \"macos\"))".dependencies]
objc = "0.2"
Expand Down
2 changes: 1 addition & 1 deletion examples/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn main() {
}
Event::MainEventsCleared => {
if let Some(w) = &window {
// w.request_redraw();
w.request_redraw();
}
}
_ => (),
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@
)]
#![deny(rustdoc::broken_intra_doc_links)]

#[cfg(target_os = "android")]
pub use tao_macros::{android_fn, generate_package_name};

use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ impl<T: 'static> EventLoopWindowTarget<T> {
}

#[inline]
pub fn monitor_from_point(&self, x: f64, y: f64) -> Option<MonitorHandle> {
pub fn monitor_from_point(&self, _x: f64, _y: f64) -> Option<MonitorHandle> {
warn!("`Window::monitor_from_point` is ignored on Android");
return None;
}
Expand Down Expand Up @@ -553,7 +553,7 @@ impl Window {
}

#[inline]
pub fn monitor_from_point(&self, x: f64, y: f64) -> Option<monitor::MonitorHandle> {
pub fn monitor_from_point(&self, _x: f64, _y: f64) -> Option<monitor::MonitorHandle> {
warn!("`Window::monitor_from_point` is ignored on Android");
None
}
Expand Down
67 changes: 23 additions & 44 deletions src/platform_impl/android/ndk_glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,58 +24,37 @@ use std::{
thread,
};

// pub static PACKAGE: OnceCell<&str> = OnceCell::new();
pub static PACKAGE: OnceCell<&str> = OnceCell::new();

#[macro_export]
macro_rules! android_binding {
($domain:ident, $package:ident, $setup: ident, $main: ident) => {
paste::paste! {
#[no_mangle]
unsafe extern "C" fn [< Java_ $domain _ $package _ TauriActivity_create >](
env: JNIEnv,
class: JClass,
object: JObject,
) {
let domain = stringify!($domain).replace("_", "/");
let package = format!("{}/{}", domain, stringify!($package).replace("_1","_"));
PACKAGE.get_or_init(move || package);
create(env, class, object, $setup, $main)
}

android_fn!($domain, $package, TauriActivity, start);
android_fn!($domain, $package, TauriActivity, stop);
android_fn!($domain, $package, TauriActivity, resume);
android_fn!($domain, $package, TauriActivity, pause);
android_fn!($domain, $package, TauriActivity, save);
android_fn!($domain, $package, TauriActivity, destroy);
android_fn!($domain, $package, TauriActivity, memory);
android_fn!($domain, $package, TauriActivity, focus, i32);
fn __store_package_name__() {
PACKAGE.get_or_init(move || generate_package_name!($domain, $package));
}
};
}

#[macro_export]
macro_rules! android_fn {
($domain:ident, $package:ident, $class:ident, $function:ident) => {
android_fn!($domain, $package, $class, $function, JObject)
};
($domain:ident, $package:ident, $class:ident, $function:ident, $arg:ty) => {
android_fn!($domain, $package, $class, $function, $arg, ())
};
($domain:ident, $package:ident, $class:ident, $function:ident, $arg:ty, $ret: ty) => {
paste::paste! {
#[no_mangle]
unsafe extern "C" fn [< Java_ $domain _ $package _ $class _ $function >](
env: JNIEnv,
class: JClass,
object: $arg,
) -> $ret {
$function(env, class, object)
}
}
android_fn!(
$domain,
$package,
TauriActivity,
create,
[JObject],
__VOID__,
[$setup, $main],
__store_package_name__,
);
android_fn!($domain, $package, TauriActivity, start, [JObject]);
android_fn!($domain, $package, TauriActivity, stop, [JObject]);
android_fn!($domain, $package, TauriActivity, resume, [JObject]);
android_fn!($domain, $package, TauriActivity, pause, [JObject]);
android_fn!($domain, $package, TauriActivity, save, [JObject]);
android_fn!($domain, $package, TauriActivity, destroy, [JObject]);
android_fn!($domain, $package, TauriActivity, memory, [JObject]);
android_fn!($domain, $package, TauriActivity, focus, [i32]);
};
}

pub static PACKAGE: OnceCell<String> = OnceCell::new();

/// `ndk-glue` macros register the reading end of an event pipe with the
/// main [`ThreadLooper`] under this `ident`.
/// When returned from [`ThreadLooper::poll_*`](ThreadLooper::poll_once)
Expand Down
19 changes: 19 additions & 0 deletions tao-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "tao-macros"
description = "Proc macros for tao"
version = "0.0.0"
edition = "2021"
authors = ["Tauri Programme within The Commons Conservancy"]
rust-version = "1.56"
license = "MIT OR Apache-2.0"
readme = "../README.md"
repository = "https://github.com/tauri-apps/tao"
documentation = "https://docs.rs/tao-macros"

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["full"] }
33 changes: 33 additions & 0 deletions tao-macros/examples/android_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use tao_macros::android_fn;

struct JNIEnv;
struct JClass;

android_fn![com_example, tao_app, SomeClass, add, [i32, i32], i32];
unsafe fn add(_env: JNIEnv, _class: JClass, a: i32, b: i32) -> i32 {
a + b
}

android_fn!(com_example, tao_app, SomeClass, add2, [i32, i32]);
unsafe fn add2(_env: JNIEnv, _class: JClass, a: i32, b: i32) {
let _ = a + b;
}

fn __store_package_name__() {}

android_fn!(
com_example,
tao_app,
SomeClass,
add3,
[i32, i32],
__VOID__,
[setup, main],
__store_package_name__,
);
unsafe fn add3(_env: JNIEnv, _class: JClass, a: i32, b: i32, _setup: fn(), _main: fn()) {
let _ = a + b;
}

fn setup() {}
fn main() {}
5 changes: 5 additions & 0 deletions tao-macros/examples/generate_package_name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use tao_macros::generate_package_name;

pub const PACKAGE: &str = generate_package_name!(com_example, tao_app);

fn main() {}
Loading

0 comments on commit b3aa398

Please sign in to comment.