ffi 2D: migrate android.sx safe-insets to declarative #jni_class blocks
`sx_query_safe_insets_jni`'s body — previously seven hand-rolled
`#jni_call` sites with verbose JNI descriptor literals — now uses
four `#jni_class` declarations and the DSL method-call form inside
a `#jni_env(env) { ... }` scope. The new shape:
```
WindowInsets :: #jni_class("android/view/WindowInsets") {
getSystemWindowInsetTop :: (self: *Self) -> s32;
...
}
... Activity / Window / View ...
#jni_env(env) {
window := activity.getWindow();
decor := window.getDecorView();
insets := decor.getRootWindowInsets();
top.* = insets.getSystemWindowInsetTop();
...
}
```
Descriptor derivation happens at lower time (jni_descriptor.zig);
slot interning + vtable dispatch shape match the Phase 1C hand-rolled
form byte-for-byte. The function param signature changes from
`activity: *void` to `activity: *Activity` so the DSL can resolve
method names through `foreign_class_map`; the AndroidPlatform.safe_insets
caller adds an `xx` cast at the call site.
Net body shrinks from 14 dispatch lines to 12 (slightly shorter but
the win is type safety + readability — the foreign descriptor
strings are gone). On-device chess regression is the remaining
verification step (Pixel device with safe-area-driven board layout).
Verified locally: zig build, run_examples (129/129), cross_compile
(3/3 — incl. examples/99-android-egl-clear.sx cross-compile to
android target succeeds and produces a valid .o).
Naming caveat: `Activity` / `Window` / `View` / `WindowInsets` are
now top-level names exported by `modules/platform/android.sx`. User
code that imports this module shouldn't redefine these aliases.
This commit is contained in:
@@ -134,31 +134,56 @@ sx_android_activity_clazz :: (activity: *void) -> *void {
|
|||||||
sx_load_ptr_at(activity, ANATIVEACTIVITY_CLAZZ_OFFSET);
|
sx_load_ptr_at(activity, ANATIVEACTIVITY_CLAZZ_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sx-side reimplementation of the JNI dispatch chain inside
|
// Declarative JNI class bindings for the safe-insets dispatch chain
|
||||||
// `sx_android_query_safe_insets`. Caller provides an already-attached
|
// (Phase 2D migration). Each `#jni_class` declares the sx-side alias,
|
||||||
// `JNIEnv*` and the activity's `clazz` jobject. Outputs physical-pixel
|
// the JNI class path, and the methods we use — `inst.method(args)`
|
||||||
// insets just like the C foreign helper above. Eventually replaces
|
// inside a `#jni_env(env) { ... }` scope lowers to the same JNI vtable
|
||||||
// the foreign call once the JavaVM env-attach plumbing has a sx
|
// indirection as the hand-rolled `#jni_call` form, with the descriptor
|
||||||
// equivalent or a thinner C shim.
|
// auto-derived from the sx signature (see [src/ir/jni_descriptor.zig]).
|
||||||
sx_query_safe_insets_jni :: (env: *void, activity: *void, top: *s32, left: *s32, bottom: *s32, right: *s32) -> void {
|
WindowInsets :: #jni_class("android/view/WindowInsets") {
|
||||||
|
getSystemWindowInsetTop :: (self: *Self) -> s32;
|
||||||
|
getSystemWindowInsetLeft :: (self: *Self) -> s32;
|
||||||
|
getSystemWindowInsetBottom :: (self: *Self) -> s32;
|
||||||
|
getSystemWindowInsetRight :: (self: *Self) -> s32;
|
||||||
|
}
|
||||||
|
|
||||||
|
View :: #jni_class("android/view/View") {
|
||||||
|
getRootWindowInsets :: (self: *Self) -> *WindowInsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window :: #jni_class("android/view/Window") {
|
||||||
|
getDecorView :: (self: *Self) -> *View;
|
||||||
|
}
|
||||||
|
|
||||||
|
Activity :: #jni_class("android/app/Activity") {
|
||||||
|
getWindow :: (self: *Self) -> *Window;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sx-side reimplementation of the JNI dispatch chain. Caller provides
|
||||||
|
// an already-attached `JNIEnv*` and the activity's `clazz` jobject
|
||||||
|
// (cast to `*Activity` so the method-call DSL can find it in the
|
||||||
|
// foreign-class registry). Outputs physical-pixel insets.
|
||||||
|
sx_query_safe_insets_jni :: (env: *void, activity: *Activity, top: *s32, left: *s32, bottom: *s32, right: *s32) -> void {
|
||||||
inline if OS != .android { return; }
|
inline if OS != .android { return; }
|
||||||
|
|
||||||
top.* = 0; left.* = 0; bottom.* = 0; right.* = 0;
|
top.* = 0; left.* = 0; bottom.* = 0; right.* = 0;
|
||||||
if activity == null { return; }
|
if activity == null { return; }
|
||||||
|
|
||||||
window := #jni_call(*void)(env, activity, "getWindow", "()Landroid/view/Window;");
|
#jni_env(env) {
|
||||||
if window == null { return; }
|
window := activity.getWindow();
|
||||||
|
if window == null { return; }
|
||||||
|
|
||||||
decor := #jni_call(*void)(env, window, "getDecorView", "()Landroid/view/View;");
|
decor := window.getDecorView();
|
||||||
if decor == null { return; }
|
if decor == null { return; }
|
||||||
|
|
||||||
insets := #jni_call(*void)(env, decor, "getRootWindowInsets", "()Landroid/view/WindowInsets;");
|
insets := decor.getRootWindowInsets();
|
||||||
if insets == null { return; }
|
if insets == null { return; }
|
||||||
|
|
||||||
top.* = #jni_call(s32)(env, insets, "getSystemWindowInsetTop", "()I");
|
top.* = insets.getSystemWindowInsetTop();
|
||||||
left.* = #jni_call(s32)(env, insets, "getSystemWindowInsetLeft", "()I");
|
left.* = insets.getSystemWindowInsetLeft();
|
||||||
bottom.* = #jni_call(s32)(env, insets, "getSystemWindowInsetBottom", "()I");
|
bottom.* = insets.getSystemWindowInsetBottom();
|
||||||
right.* = #jni_call(s32)(env, insets, "getSystemWindowInsetRight", "()I");
|
right.* = insets.getSystemWindowInsetRight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EGL — display/surface/context/config are opaque to us.
|
// EGL — display/surface/context/config are opaque to us.
|
||||||
@@ -396,7 +421,7 @@ impl Platform for AndroidPlatform {
|
|||||||
attached : bool = false;
|
attached : bool = false;
|
||||||
env := sx_android_get_env(g_android_activity, @attached);
|
env := sx_android_get_env(g_android_activity, @attached);
|
||||||
if env != null {
|
if env != null {
|
||||||
clazz := sx_android_activity_clazz(g_android_activity);
|
clazz : *Activity = xx sx_android_activity_clazz(g_android_activity);
|
||||||
sx_query_safe_insets_jni(env, clazz, @t, @l, @b, @r);
|
sx_query_safe_insets_jni(env, clazz, @t, @l, @b, @r);
|
||||||
if attached { sx_android_detach_env(g_android_activity); }
|
if attached { sx_android_detach_env(g_android_activity); }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user