xloop_android 0.1.0

android impl for xloop.
Documentation
pub struct FmtJava<T>(std::marker::PhantomData<T>);
impl<T> Default for FmtJava<T> {
	fn default() -> Self {
		Self(std::marker::PhantomData)
	}
}
impl<T: crate::win::WinActivity> std::fmt::Display for FmtJava<T> {
	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! XLoopDumpActivityClass {
	($TYPE:ident) => {
		assert_eq!(0, std::mem::size_of::<$TYPE>());
		#[allow(deref_nullptr)]
		let value = unsafe { &*(core::ptr::null() as *const $TYPE) };
		log::debug!("{value}");
	};
}

#[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 WinActivity {
			$($ACTIVITY_IMPL:tt)*
		}
	) => {
		$crate::jnim::JnimDefineClass! {
			$(#[$META])*
			#2[$JAVA_NAME]
			$VIS struct $TYPE  {
				__activity:$crate::android::app::Activity,
				__surface_holder_callback2:$crate::android::view::SurfaceHolderCallback2Object,
				$($FIELD)*
			}
		}
		impl std::ops::Deref for $TYPE {
			type Target = $crate::android::app::Activity;
			fn deref(&self) -> &Self::Target {
				&self.__activity
			}
		}
		impl AsRef<$crate::android::app::Activity> for $TYPE {
			fn as_ref(&self) -> &$crate::android::app::Activity {
				&self.__activity
			}
		}
		impl AsRef<$crate::android::view::SurfaceHolderCallback2Object> for $TYPE {
			fn as_ref(&self) -> &$crate::android::view::SurfaceHolderCallback2Object {
				&self.__surface_holder_callback2
			}
		}
		impl WinActivity for $TYPE {
			fn key(&self, env: &$crate::jnim::JEnv)->$crate::win::Key {
				$crate::win::Key::from_bits(self.native(env).unwrap() as _).unwrap()
			}
			$($ACTIVITY_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[$JAVA_NAME1,$JAVA_SIGN1]
					fn $FUN_NAME1;
				)*
				#DEF[b"onDestroy\0", b"()V\0"]
				fn on_destroy(env: &$crate::jnim::JEnv, this: &$TYPE,) {
					this.activity_on_destroy(env);
					let _: () = $crate::jnim::JSuperCall!(this, env, b"onDestroy\0", b"()V\0",).unwrap();
					$crate::win::del_window(this.key(env));
					this.set_native(env,0);
				}
				$(
					#DEF[$JAVA_NAME2,$JAVA_SIGN2]
					fn $FUN_NAME2 ($($PARAMS2)*) $(-> $RET2)? $BODY2
				)*
				#SUPER[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>)
					: (this, env, b"onCreate\0", b"(Landroid/os/Bundle;)V\0", saved_instance_state,) {
					let native = $crate::win::new_window($TYPE::ACTIVITY_NAME);
					this.set_native(env, native.to_bits() as _);
					this.activity_on_create(env, saved_instance_state);
				}
				#SUPER[b"onStart\0", b"()V\0"]
				fn on_start(env: &$crate::jnim::JEnv, this: &$TYPE,)
					: (this, env, b"onStart\0", b"()V\0",) {
					this.activity_on_start(env);
				}
				#SUPER[b"onResume\0", b"()V\0"]
				fn on_resume(env: &$crate::jnim::JEnv, this: &$TYPE,)
					:(this, env, b"onResume\0", b"()V\0",) {
					this.activity_on_resume(env);
				}
				#SUPER[b"onPause\0", b"()V\0"]
				fn on_pause(env: &$crate::jnim::JEnv, this: &$TYPE,)
					:(this, env, b"onPause\0", b"()V\0",) {
					this.activity_on_pause(env);
				}
				#SUPER[b"onStop\0", b"()V\0"]
				fn on_stop(env: &$crate::jnim::JEnv, this: &$TYPE,)
					:(this, env, b"onStop\0", b"()V\0",) {
					this.activity_on_stop(env);
				}
				#SUPER[b"onConfigurationChanged\0",b"(Landroid/content/res/Configuration;)V\0"]
				fn configuration_changed(env: &$crate::jnim::JEnv, this: &$TYPE, arg0: &$crate::android::content::res::Configuration)
					:(this,env,b"onConfigurationChanged\0",b"(Landroid/content/res/Configuration;)V\0", arg0.as_sys(),) {
					this.configuration_changed(env, arg0);
				}
				$(
					#SUPER[$JAVA_NAME3,$JAVA_SIGN3]
					fn $FUN_NAME3 ($($PARAMS3)*) $(-> $RET3)? : ($($SUPER_PARAMS3)*) { $($IMPL3)* }
				)*
			}
		}
	};
}