pub struct FmtJava(std::marker::PhantomData); impl Default for FmtJava { fn default() -> Self { Self(std::marker::PhantomData) } } impl std::fmt::Display for FmtJava { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let java = core::ffi::CStr::from_bytes_with_nul(T::JAVA_PATH).unwrap().to_str().unwrap(); let this_ = java.split("/").last().unwrap(); let path = java.trim_end_matches(this_).trim_end_matches("/").replace("/", "."); f.write_fmt(format_args!( r##" // This file has been automatically generated by `xloop android`. // DO NOT EDIT package {path} import android.annotation.SuppressLint import android.app.Activity import android.content.res.Configuration import android.os.Bundle import android.view.SurfaceHolder class {this_} : Activity(), SurfaceHolder.Callback2 {{ companion object {{ init {{ System.loadLibrary("xloop") }} }} val mNative: Long = 0; @SuppressLint("MissingSuperCall") external override fun onCreate(savedInstanceState: Bundle?) @SuppressLint("MissingSuperCall") external override fun onDestroy() @SuppressLint("MissingSuperCall") external override fun onStart() @SuppressLint("MissingSuperCall") external override fun onStop() @SuppressLint("MissingSuperCall") external override fun onResume() @SuppressLint("MissingSuperCall") external override fun onPause() external override fun surfaceCreated(holder: SurfaceHolder) external override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) external override fun surfaceDestroyed(holder: SurfaceHolder) external override fun surfaceRedrawNeeded(holder: SurfaceHolder) external override fun onConfigurationChanged(newConfig: Configuration) }}"## )) } } #[macro_export] macro_rules! XLoopDefineActivityClass { ( $(#[$META:meta])* #[$JAVA_NAME:literal] $VIS:vis struct $TYPE:ident { $($FIELD:tt)* } impl Native { $( #USE[$JAVA_NAME1:literal,$JAVA_SIGN1:literal] fn $FUN_NAME1:ident; )* $( #DEF[$JAVA_NAME2:literal,$JAVA_SIGN2:literal] fn $FUN_NAME2:ident ($($PARAMS2:tt)*) $(-> $RET2:ty)? $BODY2:block )* $( #SUPER[$JAVA_NAME3:literal,$JAVA_SIGN3:literal] fn $FUN_NAME3:ident ($($PARAMS3:tt)*) $(-> $RET3:ty)? : ($($SUPER_PARAMS3:tt)*) { $($IMPL3:tt)* } )* } impl WinView { $($VIEW_IMPL:tt)* } ) => { $crate::jnim::JnimDefineClass! { $(#[$META])* #2[$JAVA_NAME] $VIS struct $TYPE { __super:$crate::android::view::View, __surface_holder_callback2:$crate::android::view::SurfaceHolderCallback2Object, $($FIELD)* } } impl std::ops::Deref for $TYPE { type Target = $crate::android::view::View; fn deref(&self) -> &Self::Target { &self.__super } } impl AsRef<$crate::android::view::View> for $TYPE { fn as_ref(&self) -> &$crate::android::view::View { &self.__super } } impl AsRef<$crate::android::view::SurfaceHolderCallback2Object> for $TYPE { fn as_ref(&self) -> &$crate::android::view::SurfaceHolderCallback2Object { &self.__surface_holder_callback2 } } impl WinView for $TYPE { fn key(&self, env: &$crate::jnim::JEnv)->$crate::win::Key { $crate::win::Key::from_bits(self.native(env).unwrap() as _).unwrap() } $($VIEW_IMPL)* } impl $TYPE { fn native(&self, env: &$crate::jnim::JEnv) -> Option<$crate::jnim::JLong> { use $crate::jnim::JPlainMarker as _; static CACHE: $crate::jnim::CachedID = $crate::jnim::CachedID::new(); CACHE .get(|| Self::class(Some(env))?.field(env, b"mNative\0", b"J\0"))? .get(env, self.as_ref()) } fn set_native(&self, env: &$crate::jnim::JEnv, value: $crate::jnim::JLong) -> Option<()> { use $crate::jnim::JPlainMarker as _; static CACHE: $crate::jnim::CachedID = $crate::jnim::CachedID::new(); CACHE .get(|| Self::class(Some(env))?.field(env, b"mNative\0", b"J\0"))? .set(env, self.as_ref(), value) } } $crate::jnim::JnimNativeMethods! { impl $TYPE { #USE[b"surfaceCreated\0", b"(Landroid/view/SurfaceHolder;)V\0"] fn surface_created; #USE[b"surfaceChanged\0", b"(Landroid/view/SurfaceHolder;III)V\0"] fn surface_changed; #USE[b"surfaceDestroyed\0", b"(Landroid/view/SurfaceHolder;)V\0"] fn surface_destroyed; #USE[b"surfaceRedrawNeeded\0", b"(Landroid/view/SurfaceHolder;)V\0"] fn surface_redraw_needed; #USE[b"onStart\0", b"()V\0"] fn activity_on_start; #USE[b"onResume\0", b"()V\0"] fn activity_on_resume; #USE[b"onPause\0", b"()V\0"] fn activity_on_pause; #USE[b"onStop\0", b"()V\0"] fn activity_on_stop; #USE[b"onConfigurationChanged\0",b"(Landroid/content/res/Configuration;)V\0"] fn configuration_changed; #USE[b"onTouchNative\0", b"(Landroid/view/MotionEvent;)Z\0"] fn on_touch; #USE[b"onKeyNative\0", b"(Landroid/view/KeyEvent;)Z\0"] fn on_key; #USE[b"onCommitEnd\0", b"(Ljava/lang/String;)V\0"] fn on_commit_end; #USE[b"onCommitBack\0", b"()V\0"] fn on_commit_back; $( #USE[$JAVA_NAME1,$JAVA_SIGN1] fn $FUN_NAME1; )* #DEF[b"onCreate\0", b"(Landroid/os/Bundle;)V\0"] fn on_create(env: &$crate::jnim::JEnv, this: &$TYPE,saved_instance_state: Option<&$crate::android::os::Bundle>) { let native = $crate::win::new_window($TYPE::VIEW_NAME); this.set_native(env, native.to_bits() as _); this.activity_on_create(env, saved_instance_state); } #DEF[b"onDestroy\0", b"()V\0"] fn on_destroy(env: &$crate::jnim::JEnv, this: &$TYPE,) { this.activity_on_destroy(env); $crate::win::del_window(this.key(env)); this.set_native(env,0); } $( #DEF[$JAVA_NAME2,$JAVA_SIGN2] fn $FUN_NAME2 ($($PARAMS2)*) $(-> $RET2)? $BODY2 )* $( #SUPER[$JAVA_NAME3,$JAVA_SIGN3] fn $FUN_NAME3 ($($PARAMS3)*) $(-> $RET3)? : ($($SUPER_PARAMS3)*) { $($IMPL3)* } )* } } }; }