Merge pull request #117687 from m4gr3d/cleanup_godot_kt
[Android] Clean up `Godot.kt`
This commit is contained in:
@@ -30,7 +30,6 @@
|
||||
|
||||
package org.godotengine.godot
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.*
|
||||
@@ -43,7 +42,6 @@ import android.hardware.Sensor
|
||||
import android.hardware.SensorManager
|
||||
import android.os.*
|
||||
import android.util.Log
|
||||
import android.util.Rational
|
||||
import android.util.TypedValue
|
||||
import android.view.*
|
||||
import android.widget.FrameLayout
|
||||
@@ -57,27 +55,23 @@ import androidx.core.view.WindowInsetsAnimationCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import com.google.android.vending.expansion.downloader.*
|
||||
import org.godotengine.godot.error.Error
|
||||
import org.godotengine.godot.feature.PictureInPictureProvider
|
||||
import org.godotengine.godot.input.GodotEditText
|
||||
import org.godotengine.godot.input.GodotInputHandler
|
||||
import org.godotengine.godot.io.FilePicker
|
||||
import org.godotengine.godot.io.directory.DirectoryAccessHandler
|
||||
import org.godotengine.godot.io.file.FileAccessHandler
|
||||
import org.godotengine.godot.nativeapi.GodotNativeBridge
|
||||
import org.godotengine.godot.plugin.AndroidRuntimePlugin
|
||||
import org.godotengine.godot.plugin.GodotPlugin
|
||||
import org.godotengine.godot.plugin.GodotPluginRegistry
|
||||
import org.godotengine.godot.tts.GodotTTS
|
||||
import org.godotengine.godot.utils.DialogUtils
|
||||
import org.godotengine.godot.utils.GodotNetUtils
|
||||
import org.godotengine.godot.utils.PermissionsUtil
|
||||
import org.godotengine.godot.utils.PermissionsUtil.requestPermission
|
||||
import org.godotengine.godot.utils.beginBenchmarkMeasure
|
||||
import org.godotengine.godot.utils.benchmarkFile
|
||||
import org.godotengine.godot.utils.dumpBenchmark
|
||||
import org.godotengine.godot.utils.endBenchmarkMeasure
|
||||
import org.godotengine.godot.utils.useBenchmark
|
||||
import org.godotengine.godot.variant.Callable as GodotCallable
|
||||
import org.godotengine.godot.xr.XRMode
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
@@ -89,7 +83,6 @@ import java.util.concurrent.FutureTask
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
|
||||
/**
|
||||
* Core component used to interface with the native layer of the engine.
|
||||
*
|
||||
@@ -131,10 +124,11 @@ class Godot private constructor(val context: Context) {
|
||||
TERMINATING
|
||||
}
|
||||
|
||||
private val godotNativeBridge = GodotNativeBridge(this)
|
||||
|
||||
private val mSensorManager: SensorManager? by lazy { context.getSystemService(Context.SENSOR_SERVICE) as? SensorManager }
|
||||
private val mClipboard: ClipboardManager? by lazy { context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager }
|
||||
private val vibratorService: Vibrator? by lazy { context.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator }
|
||||
private val pluginRegistry: GodotPluginRegistry by lazy { GodotPluginRegistry.getPluginRegistry() }
|
||||
internal val pluginRegistry: GodotPluginRegistry by lazy { GodotPluginRegistry.getPluginRegistry() }
|
||||
|
||||
private val accelerometerEnabled = AtomicBoolean(false)
|
||||
private val mAccelerometer: Sensor? by lazy { mSensorManager?.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) }
|
||||
@@ -154,7 +148,7 @@ class Godot private constructor(val context: Context) {
|
||||
val directoryAccessHandler = DirectoryAccessHandler(context)
|
||||
val fileAccessHandler = FileAccessHandler(context)
|
||||
val netUtils = GodotNetUtils(context)
|
||||
private val godotInputHandler = GodotInputHandler(context, this)
|
||||
val godotInputHandler = GodotInputHandler(context, this)
|
||||
|
||||
private val hasClipboardCallable = Callable {
|
||||
mClipboard?.hasPrimaryClip() == true
|
||||
@@ -185,7 +179,7 @@ class Godot private constructor(val context: Context) {
|
||||
* Tracks whether [onInitRenderView] was completed successfully.
|
||||
*/
|
||||
private var renderViewInitialized = false
|
||||
private var primaryHost: GodotHost? = null
|
||||
internal var primaryHost: GodotHost? = null
|
||||
|
||||
/**
|
||||
* Tracks whether we're in the RESUMED lifecycle state.
|
||||
@@ -203,11 +197,11 @@ class Godot private constructor(val context: Context) {
|
||||
val io = GodotIO(this)
|
||||
|
||||
private var commandLine : MutableList<String> = ArrayList<String>()
|
||||
private var xrMode = XRMode.REGULAR
|
||||
internal var xrMode = XRMode.REGULAR
|
||||
private val useImmersive = AtomicBoolean(false)
|
||||
private val isEdgeToEdge = AtomicBoolean(false)
|
||||
private var useDebugOpengl = false
|
||||
private var darkMode = false
|
||||
internal var darkMode = false
|
||||
private var backgroundColor: Int = Color.BLACK
|
||||
private var orientation = Configuration.ORIENTATION_UNDEFINED
|
||||
|
||||
@@ -351,7 +345,7 @@ class Godot private constructor(val context: Context) {
|
||||
}
|
||||
if (!nativeLayerInitializeCompleted) {
|
||||
nativeLayerInitializeCompleted = GodotLib.initialize(
|
||||
this,
|
||||
godotNativeBridge,
|
||||
context.assets,
|
||||
io,
|
||||
netUtils,
|
||||
@@ -474,20 +468,8 @@ class Godot private constructor(val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked from the render thread to toggle the immersive mode.
|
||||
*/
|
||||
@Keep
|
||||
private fun nativeEnableImmersiveMode(enabled: Boolean) {
|
||||
runOnHostThread {
|
||||
enableImmersiveMode(enabled)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun isInImmersiveMode() = useImmersive.get()
|
||||
|
||||
@Keep
|
||||
fun isInEdgeToEdgeMode() = isEdgeToEdge.get()
|
||||
|
||||
fun setSystemBarsAppearance() {
|
||||
@@ -833,7 +815,7 @@ class Godot private constructor(val context: Context) {
|
||||
/**
|
||||
* Invoked on the render thread when the Godot setup is complete.
|
||||
*/
|
||||
private fun onGodotSetupCompleted() {
|
||||
internal fun onGodotSetupCompleted() {
|
||||
Log.v(TAG, "OnGodotSetupCompleted")
|
||||
|
||||
// These properties are defined after Godot setup completion, so we retrieve them here.
|
||||
@@ -844,7 +826,7 @@ class Godot private constructor(val context: Context) {
|
||||
val scrollDeadzoneDisabled = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/disable_scroll_deadzone"))
|
||||
|
||||
runOnHostThread {
|
||||
renderView?.inputHandler?.apply {
|
||||
godotInputHandler.apply {
|
||||
enableLongPress(longPressEnabled)
|
||||
enablePanningAndScalingGestures(panScaleEnabled)
|
||||
setOverrideVolumeButtons(overrideVolumeButtons)
|
||||
@@ -867,7 +849,7 @@ class Godot private constructor(val context: Context) {
|
||||
/**
|
||||
* Invoked on the render thread when the Godot main loop has started.
|
||||
*/
|
||||
private fun onGodotMainLoopStarted() {
|
||||
internal fun onGodotMainLoopStarted() {
|
||||
Log.v(TAG, "OnGodotMainLoopStarted")
|
||||
_runStatus.set(RunStatus.STARTED)
|
||||
|
||||
@@ -889,8 +871,7 @@ class Godot private constructor(val context: Context) {
|
||||
/**
|
||||
* Invoked on the render thread when the engine is about to terminate.
|
||||
*/
|
||||
@Keep
|
||||
private fun onGodotTerminating() {
|
||||
internal fun onGodotTerminating() {
|
||||
Log.v(TAG, "OnGodotTerminating")
|
||||
_runStatus.set(RunStatus.TERMINATING)
|
||||
|
||||
@@ -900,9 +881,6 @@ class Godot private constructor(val context: Context) {
|
||||
runOnTerminate.get()?.run()
|
||||
}
|
||||
|
||||
private fun restart() {
|
||||
primaryHost?.onGodotRestartRequested(this)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes messageResId: Int,
|
||||
@@ -914,7 +892,6 @@ class Godot private constructor(val context: Context) {
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
@Keep
|
||||
fun alert(message: String, title: String, okCallback: Runnable? = null) {
|
||||
val activity = getActivity() ?: return
|
||||
runOnHostThread {
|
||||
@@ -947,21 +924,16 @@ class Godot private constructor(val context: Context) {
|
||||
primaryHost?.runOnHostThread(action)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the call is being made on the Ui thread.
|
||||
*/
|
||||
private fun isOnUiThread() = Looper.myLooper() == Looper.getMainLooper()
|
||||
|
||||
/**
|
||||
* Returns the native rendering driver.
|
||||
*/
|
||||
private fun getNativeRenderer(): String {
|
||||
val rendererInfo = GodotLib.getRendererInfo(meetsVulkanRequirements(context.packageManager))
|
||||
var renderingDriverChosen = rendererInfo[0]
|
||||
var renderingDriverOriginal = rendererInfo[1]
|
||||
var renderingMethod = rendererInfo[2]
|
||||
var renderingDriverSource = rendererInfo[3]
|
||||
var renderingMethodSource = rendererInfo[4]
|
||||
val renderingDriverChosen = rendererInfo[0]
|
||||
val renderingDriverOriginal = rendererInfo[1]
|
||||
val renderingMethod = rendererInfo[2]
|
||||
val renderingDriverSource = rendererInfo[3]
|
||||
val renderingMethodSource = rendererInfo[4]
|
||||
Log.d(TAG, """renderingDevice: ${renderingDriverChosen} (${renderingDriverSource})
|
||||
renderer: ${renderingMethod} (${renderingMethodSource})""")
|
||||
|
||||
@@ -973,13 +945,6 @@ class Godot private constructor(val context: Context) {
|
||||
return renderingDriverChosen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if can fallback to OpenGL.
|
||||
*/
|
||||
private fun canFallbackToOpenGL(): Boolean {
|
||||
return java.lang.Boolean.parseBoolean(GodotLib.getGlobal("rendering/rendering_device/fallback_to_opengl3"))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the device meets the base requirements for Vulkan support, false otherwise.
|
||||
*/
|
||||
@@ -996,7 +961,7 @@ class Godot private constructor(val context: Context) {
|
||||
return packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000)
|
||||
}
|
||||
|
||||
private fun setKeepScreenOn(enabled: Boolean) {
|
||||
internal fun setKeepScreenOn(enabled: Boolean) {
|
||||
runOnHostThread {
|
||||
if (enabled) {
|
||||
getActivity()?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
@@ -1006,22 +971,6 @@ class Godot private constructor(val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if dark mode is supported, false otherwise.
|
||||
*/
|
||||
@Keep
|
||||
private fun isDarkModeSupported(): Boolean {
|
||||
return context.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_UNDEFINED
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if dark mode is supported and enabled, false otherwise.
|
||||
*/
|
||||
@Keep
|
||||
private fun isDarkMode(): Boolean {
|
||||
return darkMode
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun hasClipboard(): Boolean {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P || Looper.getMainLooper().thread == Thread.currentThread()) {
|
||||
@@ -1051,49 +1000,6 @@ class Godot private constructor(val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun showFilePicker(currentDirectory: String, filename: String, fileMode: Int, filters: Array<String>) {
|
||||
FilePicker.showFilePicker(context, getActivity(), currentDirectory, filename, fileMode, filters)
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shows a dialog with multiple buttons.
|
||||
*
|
||||
* @param title The title of the dialog.
|
||||
* @param message The message displayed in the dialog.
|
||||
* @param buttons An array of button labels to display.
|
||||
*/
|
||||
@Keep
|
||||
private fun showDialog(title: String, message: String, buttons: Array<String>) {
|
||||
getActivity()?.let { DialogUtils.showDialog(it, title, message, buttons) }
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shows a dialog with a text input field, allowing the user to input text.
|
||||
*
|
||||
* @param title The title of the input dialog.
|
||||
* @param message The message displayed in the input dialog.
|
||||
* @param existingText The existing text that will be pre-filled in the input field.
|
||||
*/
|
||||
@Keep
|
||||
private fun showInputDialog(title: String, message: String, existingText: String) {
|
||||
getActivity()?.let { DialogUtils.showInputDialog(it, title, message, existingText) }
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun getAccentColor(): Int {
|
||||
val value = TypedValue()
|
||||
context.theme.resolveAttribute(android.R.attr.colorAccent, value, true)
|
||||
return value.data
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun getBaseColor(): Int {
|
||||
val value = TypedValue()
|
||||
context.theme.resolveAttribute(android.R.attr.colorBackground, value, true)
|
||||
return value.data
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the Godot Engine and kill the process it's running in.
|
||||
*/
|
||||
@@ -1117,8 +1023,7 @@ class Godot private constructor(val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun forceQuit(instanceId: Int): Boolean {
|
||||
internal fun forceQuit(instanceId: Int): Boolean {
|
||||
primaryHost?.let {
|
||||
if (instanceId == 0) {
|
||||
it.onGodotForceQuit(this)
|
||||
@@ -1136,50 +1041,6 @@ class Godot private constructor(val context: Context) {
|
||||
runOnRenderThread { GodotLib.back() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the native code (java_godot_wrapper.h) to vibrate the device.
|
||||
* @param durationMs
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
@Keep
|
||||
private fun vibrate(durationMs: Int, amplitude: Int) {
|
||||
if (durationMs > 0 && requestPermission("VIBRATE")) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (amplitude <= -1) {
|
||||
vibratorService?.vibrate(
|
||||
VibrationEffect.createOneShot(
|
||||
durationMs.toLong(),
|
||||
VibrationEffect.DEFAULT_AMPLITUDE
|
||||
)
|
||||
)
|
||||
} else {
|
||||
vibratorService?.vibrate(
|
||||
VibrationEffect.createOneShot(
|
||||
durationMs.toLong(),
|
||||
amplitude
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// deprecated in API 26
|
||||
vibratorService?.vibrate(durationMs.toLong())
|
||||
}
|
||||
} catch (e: SecurityException) {
|
||||
Log.w(TAG, "SecurityException: VIBRATE permission not found. Make sure it is declared in the manifest or enabled in the export preset.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the native code (java_godot_wrapper.h) to access the input fallback mapping.
|
||||
* @return The input fallback mapping for the current XR mode.
|
||||
*/
|
||||
@Keep
|
||||
private fun getInputFallbackMapping(): String? {
|
||||
return xrMode.inputFallbackMapping
|
||||
}
|
||||
|
||||
fun requestPermission(name: String?): Boolean {
|
||||
val activity = getActivity() ?: return false
|
||||
return requestPermission(name, activity)
|
||||
@@ -1213,44 +1074,6 @@ class Godot private constructor(val context: Context) {
|
||||
return GodotLib.hasFeature(feature)
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used to query whether the host or the registered plugins supports a given feature.
|
||||
*
|
||||
* This is invoked by the native code, and should not be confused with [hasFeature] which is the Android version of
|
||||
* https://docs.godotengine.org/en/stable/classes/class_os.html#class-os-method-has-feature
|
||||
*/
|
||||
@Keep
|
||||
private fun checkInternalFeatureSupport(feature: String): Boolean {
|
||||
if (primaryHost?.supportsFeature(feature) == true) {
|
||||
return true
|
||||
}
|
||||
|
||||
for (plugin in pluginRegistry.allPlugins) {
|
||||
if (plugin.supportsFeature(feature)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of gdextension modules to register.
|
||||
*/
|
||||
@Keep
|
||||
private fun getGDExtensionConfigFiles(): Array<String> {
|
||||
val configFiles = mutableSetOf<String>()
|
||||
for (plugin in pluginRegistry.allPlugins) {
|
||||
configFiles.addAll(plugin.pluginGDExtensionLibrariesPaths)
|
||||
}
|
||||
|
||||
return configFiles.toTypedArray()
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun getCACertificates(): String {
|
||||
return GodotNetUtils.getCACertificates()
|
||||
}
|
||||
|
||||
private fun obbIsCorrupted(f: String, mainPackMd5: String): Boolean {
|
||||
return try {
|
||||
val fis: InputStream = FileInputStream(f)
|
||||
@@ -1284,163 +1107,4 @@ class Godot private constructor(val context: Context) {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun initInputDevices() {
|
||||
godotInputHandler.initInputDevices()
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun createNewGodotInstance(args: Array<String>): Int {
|
||||
return primaryHost?.onNewGodotInstanceRequested(args) ?: -1
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBeginBenchmarkMeasure(scope: String, label: String) {
|
||||
beginBenchmarkMeasure(scope, label)
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeEndBenchmarkMeasure(scope: String, label: String) {
|
||||
endBenchmarkMeasure(scope, label)
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeDumpBenchmark(benchmarkFile: String) {
|
||||
dumpBenchmark(fileAccessHandler, benchmarkFile)
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeSignApk(inputPath: String,
|
||||
outputPath: String,
|
||||
keystorePath: String,
|
||||
keystoreUser: String,
|
||||
keystorePassword: String): Int {
|
||||
val signResult = primaryHost?.signApk(inputPath, outputPath, keystorePath, keystoreUser, keystorePassword) ?: Error.ERR_UNAVAILABLE
|
||||
return signResult.toNativeValue()
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeVerifyApk(apkPath: String): Int {
|
||||
val verifyResult = primaryHost?.verifyApk(apkPath) ?: Error.ERR_UNAVAILABLE
|
||||
return verifyResult.toNativeValue()
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeOnEditorWorkspaceSelected(workspace: String) {
|
||||
primaryHost?.onEditorWorkspaceSelected(workspace)
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeOnDistractionFreeModeChanged(enabled: Boolean) {
|
||||
primaryHost?.onDistractionFreeModeChanged(enabled)
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvConnect(callback: GodotCallable): Boolean {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
return buildProvider?.buildEnvConnect(callback) ?: false
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to connect to build environment", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvDisconnect() {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvDisconnect()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to disconnect from build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvExecute(buildTool: String, arguments: Array<String>, projectPath: String, buildDir: String, outputCallback: GodotCallable, resultCallback: GodotCallable): Int {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
return buildProvider?.buildEnvExecute(
|
||||
buildTool,
|
||||
arguments,
|
||||
projectPath,
|
||||
buildDir,
|
||||
outputCallback,
|
||||
resultCallback
|
||||
) ?: -1
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to execute Gradle command in build environment", e);
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvCancel(jobId: Int) {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvCancel(jobId)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to cancel command in build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvCleanProject(projectPath: String, buildDir: String, callback: GodotCallable) {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvCleanProject(projectPath, buildDir, callback)
|
||||
} catch(e: Exception) {
|
||||
Log.e(TAG, "Unable to clean project in build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeIsPiPModeSupported(): Boolean {
|
||||
val hostActivity = getActivity()
|
||||
if (hostActivity is PictureInPictureProvider) {
|
||||
return hostActivity.isPiPModeSupported()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeIsInPiPMode(): Boolean {
|
||||
val hostActivity = getActivity()
|
||||
if (hostActivity is GodotActivity) {
|
||||
return hostActivity.isInPictureInPictureMode
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeEnterPiPMode() {
|
||||
val hostActivity = getActivity()
|
||||
if (hostActivity is PictureInPictureProvider) {
|
||||
runOnHostThread {
|
||||
hostActivity.enterPiPMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeSetPiPModeAspectRatio(numerator: Int, denominator: Int) {
|
||||
val hostActivity = getActivity()
|
||||
if (hostActivity is GodotActivity) {
|
||||
runOnHostThread {
|
||||
hostActivity.updatePiPParams(aspectRatio = Rational(numerator, denominator))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeSetAutoEnterPiPModeOnBackground(autoEnterPiPOnBackground: Boolean) {
|
||||
val hostActivity = getActivity()
|
||||
if (hostActivity is GodotActivity) {
|
||||
runOnHostThread {
|
||||
hostActivity.updatePiPParams(enableAutoEnter = autoEnterPiPOnBackground)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ package org.godotengine.godot;
|
||||
import org.godotengine.godot.gl.GodotRenderer;
|
||||
import org.godotengine.godot.io.directory.DirectoryAccessHandler;
|
||||
import org.godotengine.godot.io.file.FileAccessHandler;
|
||||
import org.godotengine.godot.nativeapi.GodotNativeBridge;
|
||||
import org.godotengine.godot.tts.GodotTTS;
|
||||
import org.godotengine.godot.utils.GodotNetUtils;
|
||||
import org.godotengine.godot.variant.Callable;
|
||||
@@ -56,13 +57,13 @@ public class GodotLib {
|
||||
* Invoked on the main thread to initialize Godot native layer.
|
||||
*/
|
||||
public static native boolean initialize(
|
||||
Godot p_instance,
|
||||
AssetManager p_asset_manager,
|
||||
GodotNativeBridge nativeBridge,
|
||||
AssetManager assetManager,
|
||||
GodotIO godotIO,
|
||||
GodotNetUtils netUtils,
|
||||
DirectoryAccessHandler directoryAccessHandler,
|
||||
FileAccessHandler fileAccessHandler,
|
||||
boolean use_apk_expansion);
|
||||
boolean useApkExpansion);
|
||||
|
||||
/**
|
||||
* Invoked on the main thread to clean up Godot native layer.
|
||||
|
||||
+410
@@ -0,0 +1,410 @@
|
||||
/**************************************************************************/
|
||||
/* GodotNativeBridge.kt */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
package org.godotengine.godot.nativeapi
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import android.util.Log
|
||||
import android.util.Rational
|
||||
import android.util.TypedValue
|
||||
import androidx.annotation.Keep
|
||||
import org.godotengine.godot.Godot
|
||||
import org.godotengine.godot.GodotActivity
|
||||
import org.godotengine.godot.GodotLib
|
||||
import org.godotengine.godot.error.Error
|
||||
import org.godotengine.godot.feature.PictureInPictureProvider
|
||||
import org.godotengine.godot.io.FilePicker
|
||||
import org.godotengine.godot.utils.DialogUtils
|
||||
import org.godotengine.godot.utils.GodotNetUtils
|
||||
import org.godotengine.godot.utils.beginBenchmarkMeasure
|
||||
import org.godotengine.godot.utils.dumpBenchmark
|
||||
import org.godotengine.godot.utils.endBenchmarkMeasure
|
||||
import org.godotengine.godot.variant.Callable as GodotCallable
|
||||
|
||||
/**
|
||||
* Holds and expose Godot apis to the native layer.
|
||||
*
|
||||
* All the methods in this class are accessed by the native code (java_godot_wrapper.h) and as such are kept private to
|
||||
* not be accessible by the rest of the java/kotlin code.
|
||||
*/
|
||||
@Keep
|
||||
internal class GodotNativeBridge(private val godot: Godot) {
|
||||
|
||||
companion object {
|
||||
private val TAG = GodotNativeBridge::class.java.simpleName
|
||||
|
||||
}
|
||||
|
||||
private val vibratorService: Vibrator? by lazy { godot.context.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator }
|
||||
|
||||
/**
|
||||
* Invoked on the render thread when the Godot setup is complete.
|
||||
*/
|
||||
private fun onGodotSetupCompleted() {
|
||||
godot.onGodotSetupCompleted()
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked on the render thread when the Godot main loop has started.
|
||||
*/
|
||||
private fun onGodotMainLoopStarted() {
|
||||
godot.onGodotMainLoopStarted()
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked on the render thread when the engine is about to terminate.
|
||||
*/
|
||||
private fun onGodotTerminating() = godot.onGodotTerminating()
|
||||
|
||||
/**
|
||||
* Invoked from the render thread to toggle the immersive mode.
|
||||
*/
|
||||
private fun nativeEnableImmersiveMode(enabled: Boolean) {
|
||||
godot.runOnHostThread {
|
||||
godot.enableImmersiveMode(enabled)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isInImmersiveMode() = godot.isInImmersiveMode()
|
||||
|
||||
private fun isInEdgeToEdgeMode() = godot.isInEdgeToEdgeMode()
|
||||
|
||||
private fun setKeepScreenOn(enabled: Boolean) = godot.setKeepScreenOn(enabled)
|
||||
|
||||
private fun restart() { godot.primaryHost?.onGodotRestartRequested(godot) }
|
||||
|
||||
private fun alert(message: String, title: String) {
|
||||
godot.alert(message, title)
|
||||
}
|
||||
|
||||
private fun forceQuit(instanceId: Int) = godot.forceQuit(instanceId)
|
||||
|
||||
/**
|
||||
* Returns true if dark mode is supported, false otherwise.
|
||||
*/
|
||||
private fun isDarkModeSupported(): Boolean {
|
||||
return godot.context.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_UNDEFINED
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if dark mode is supported and enabled, false otherwise.
|
||||
*/
|
||||
private fun isDarkMode() = godot.darkMode
|
||||
|
||||
private fun showFilePicker(currentDirectory: String, filename: String, fileMode: Int, filters: Array<String>) {
|
||||
FilePicker.showFilePicker(godot.context, godot.getActivity(), currentDirectory, filename, fileMode, filters)
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shows a dialog with multiple buttons.
|
||||
*
|
||||
* @param title The title of the dialog.
|
||||
* @param message The message displayed in the dialog.
|
||||
* @param buttons An array of button labels to display.
|
||||
*/
|
||||
private fun showDialog(title: String, message: String, buttons: Array<String>) {
|
||||
godot.getActivity()?.let { DialogUtils.showDialog(it, title, message, buttons) }
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shows a dialog with a text input field, allowing the user to input text.
|
||||
*
|
||||
* @param title The title of the input dialog.
|
||||
* @param message The message displayed in the input dialog.
|
||||
* @param existingText The existing text that will be pre-filled in the input field.
|
||||
*/
|
||||
private fun showInputDialog(title: String, message: String, existingText: String) {
|
||||
godot.getActivity()?.let { DialogUtils.showInputDialog(it, title, message, existingText) }
|
||||
}
|
||||
|
||||
private fun getAccentColor(): Int {
|
||||
val value = TypedValue()
|
||||
godot.context.theme.resolveAttribute(android.R.attr.colorAccent, value, true)
|
||||
return value.data
|
||||
}
|
||||
|
||||
private fun getBaseColor(): Int {
|
||||
val value = TypedValue()
|
||||
godot.context.theme.resolveAttribute(android.R.attr.colorBackground, value, true)
|
||||
return value.data
|
||||
}
|
||||
|
||||
private fun requestPermission(name: String?) = godot.requestPermission(name)
|
||||
|
||||
private fun requestPermissions() = godot.requestPermissions()
|
||||
|
||||
private fun getGrantedPermissions() = godot.getGrantedPermissions()
|
||||
|
||||
/**
|
||||
* Used by the native code (java_godot_wrapper.h) to vibrate the device.
|
||||
* @param durationMs
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun vibrate(durationMs: Int, amplitude: Int) {
|
||||
if (durationMs > 0 && godot.requestPermission("VIBRATE")) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (amplitude <= -1) {
|
||||
vibratorService?.vibrate(
|
||||
VibrationEffect.createOneShot(
|
||||
durationMs.toLong(),
|
||||
VibrationEffect.DEFAULT_AMPLITUDE
|
||||
)
|
||||
)
|
||||
} else {
|
||||
vibratorService?.vibrate(
|
||||
VibrationEffect.createOneShot(
|
||||
durationMs.toLong(),
|
||||
amplitude
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// deprecated in API 26
|
||||
vibratorService?.vibrate(durationMs.toLong())
|
||||
}
|
||||
} catch (e: SecurityException) {
|
||||
Log.w(
|
||||
TAG,
|
||||
"SecurityException: VIBRATE permission not found. Make sure it is declared in the manifest or enabled in the export preset."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used to query whether the host or the registered plugins supports a given feature.
|
||||
*
|
||||
* This is invoked by the native code, and should not be confused with [hasFeature] which is the Android version of
|
||||
* https://docs.godotengine.org/en/stable/classes/class_os.html#class-os-method-has-feature
|
||||
*/
|
||||
private fun checkInternalFeatureSupport(feature: String): Boolean {
|
||||
if (godot.primaryHost?.supportsFeature(feature) == true) {
|
||||
return true
|
||||
}
|
||||
|
||||
for (plugin in godot.pluginRegistry.allPlugins) {
|
||||
if (plugin.supportsFeature(feature)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of gdextension modules to register.
|
||||
*/
|
||||
private fun getGDExtensionConfigFiles(): Array<String> {
|
||||
val configFiles = mutableSetOf<String>()
|
||||
for (plugin in godot.pluginRegistry.allPlugins) {
|
||||
configFiles.addAll(plugin.pluginGDExtensionLibrariesPaths)
|
||||
}
|
||||
|
||||
return configFiles.toTypedArray()
|
||||
}
|
||||
|
||||
private fun getCACertificates(): String {
|
||||
return GodotNetUtils.getCACertificates()
|
||||
}
|
||||
|
||||
private fun getActivity() = godot.getActivity()
|
||||
|
||||
private fun getRenderView() = godot.renderView
|
||||
|
||||
private fun getClipboard() = godot.getClipboard()
|
||||
|
||||
private fun setClipboard(text: String) = godot.setClipboard(text)
|
||||
|
||||
private fun hasClipboard() = godot.hasClipboard()
|
||||
|
||||
private fun setWindowColor(color: String) = godot.setWindowColor(color)
|
||||
|
||||
/**
|
||||
* Used by the native code (java_godot_wrapper.h) to access the input fallback mapping.
|
||||
* @return The input fallback mapping for the current XR mode.
|
||||
*/
|
||||
private fun getInputFallbackMapping(): String? {
|
||||
return godot.xrMode.inputFallbackMapping
|
||||
}
|
||||
|
||||
private fun initInputDevices() {
|
||||
godot.godotInputHandler.initInputDevices()
|
||||
}
|
||||
|
||||
private fun createNewGodotInstance(args: Array<String>): Int {
|
||||
return godot.primaryHost?.onNewGodotInstanceRequested(args) ?: -1
|
||||
}
|
||||
|
||||
private fun nativeBeginBenchmarkMeasure(scope: String, label: String) {
|
||||
beginBenchmarkMeasure(scope, label)
|
||||
}
|
||||
|
||||
private fun nativeEndBenchmarkMeasure(scope: String, label: String) {
|
||||
endBenchmarkMeasure(scope, label)
|
||||
}
|
||||
|
||||
private fun nativeDumpBenchmark(benchmarkFile: String) {
|
||||
dumpBenchmark(godot.fileAccessHandler, benchmarkFile)
|
||||
}
|
||||
|
||||
private fun nativeSignApk(
|
||||
inputPath: String,
|
||||
outputPath: String,
|
||||
keystorePath: String,
|
||||
keystoreUser: String,
|
||||
keystorePassword: String
|
||||
): Int {
|
||||
val signResult = godot.primaryHost?.signApk(inputPath, outputPath, keystorePath, keystoreUser, keystorePassword)
|
||||
?: org.godotengine.godot.error.Error.ERR_UNAVAILABLE
|
||||
return signResult.toNativeValue()
|
||||
}
|
||||
|
||||
private fun nativeVerifyApk(apkPath: String): Int {
|
||||
val verifyResult = godot.primaryHost?.verifyApk(apkPath) ?: Error.ERR_UNAVAILABLE
|
||||
return verifyResult.toNativeValue()
|
||||
}
|
||||
|
||||
private fun nativeOnEditorWorkspaceSelected(workspace: String) {
|
||||
godot.primaryHost?.onEditorWorkspaceSelected(workspace)
|
||||
}
|
||||
|
||||
private fun nativeOnDistractionFreeModeChanged(enabled: Boolean) {
|
||||
godot.primaryHost?.onDistractionFreeModeChanged(enabled)
|
||||
}
|
||||
|
||||
private fun nativeBuildEnvConnect(callback: GodotCallable): Boolean {
|
||||
try {
|
||||
val buildProvider = godot.primaryHost?.getBuildProvider()
|
||||
return buildProvider?.buildEnvConnect(callback) ?: false
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to connect to build environment", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private fun nativeBuildEnvDisconnect() {
|
||||
try {
|
||||
val buildProvider = godot.primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvDisconnect()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to disconnect from build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun nativeBuildEnvExecute(
|
||||
buildTool: String,
|
||||
arguments: Array<String>,
|
||||
projectPath: String,
|
||||
buildDir: String,
|
||||
outputCallback: GodotCallable,
|
||||
resultCallback: GodotCallable
|
||||
): Int {
|
||||
try {
|
||||
val buildProvider = godot.primaryHost?.getBuildProvider()
|
||||
return buildProvider?.buildEnvExecute(
|
||||
buildTool,
|
||||
arguments,
|
||||
projectPath,
|
||||
buildDir,
|
||||
outputCallback,
|
||||
resultCallback
|
||||
) ?: -1
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to execute Gradle command in build environment", e);
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
private fun nativeBuildEnvCancel(jobId: Int) {
|
||||
try {
|
||||
val buildProvider = godot.primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvCancel(jobId)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to cancel command in build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun nativeBuildEnvCleanProject(projectPath: String, buildDir: String, callback: GodotCallable) {
|
||||
try {
|
||||
val buildProvider = godot.primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvCleanProject(projectPath, buildDir, callback)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to clean project in build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun nativeIsPiPModeSupported(): Boolean {
|
||||
val hostActivity = godot.getActivity()
|
||||
if (hostActivity is PictureInPictureProvider) {
|
||||
return hostActivity.isPiPModeSupported()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun nativeIsInPiPMode(): Boolean {
|
||||
val hostActivity = godot.getActivity()
|
||||
if (hostActivity is GodotActivity) {
|
||||
return hostActivity.isInPictureInPictureMode
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun nativeEnterPiPMode() {
|
||||
val hostActivity = godot.getActivity()
|
||||
if (hostActivity is PictureInPictureProvider) {
|
||||
godot.runOnHostThread {
|
||||
hostActivity.enterPiPMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun nativeSetPiPModeAspectRatio(numerator: Int, denominator: Int) {
|
||||
val hostActivity = godot.getActivity()
|
||||
if (hostActivity is GodotActivity) {
|
||||
godot.runOnHostThread {
|
||||
hostActivity.updatePiPParams(aspectRatio = Rational(numerator, denominator))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun nativeSetAutoEnterPiPModeOnBackground(autoEnterPiPOnBackground: Boolean) {
|
||||
val hostActivity = godot.getActivity()
|
||||
if (hostActivity is GodotActivity) {
|
||||
godot.runOnHostThread {
|
||||
hostActivity.updatePiPParams(enableAutoEnter = autoEnterPiPOnBackground)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion) {
|
||||
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_godot_native_bridge, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion) {
|
||||
godot_init_profiler();
|
||||
|
||||
JavaVM *jvm;
|
||||
@@ -172,7 +172,7 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv
|
||||
setup_android_class_loader();
|
||||
|
||||
// create our wrapper classes
|
||||
godot_java = new GodotJavaWrapper(env, p_godot_instance);
|
||||
godot_java = new GodotJavaWrapper(env, p_godot_native_bridge);
|
||||
godot_io_java = new GodotIOJavaWrapper(env, p_godot_io);
|
||||
|
||||
FileAccessAndroid::setup(p_asset_manager);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
|
||||
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
|
||||
extern "C" {
|
||||
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion);
|
||||
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_godot_native_bridge, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
|
||||
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline, jobject p_godot_tts);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jobject p_surface, jint p_width, jint p_height);
|
||||
|
||||
@@ -39,70 +39,70 @@
|
||||
|
||||
// TODO we could probably create a base class for this...
|
||||
|
||||
GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
|
||||
godot_instance = p_env->NewGlobalRef(p_godot_instance);
|
||||
GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_native_bridge) {
|
||||
godot_native_bridge = p_env->NewGlobalRef(p_godot_native_bridge);
|
||||
|
||||
// get info about our Godot class so we can get pointers and stuff...
|
||||
godot_class = jni_find_class(p_env, "org/godotengine/godot/Godot");
|
||||
if (godot_class) {
|
||||
godot_class = (jclass)p_env->NewGlobalRef(godot_class);
|
||||
godot_native_bridge_class = jni_find_class(p_env, "org/godotengine/godot/nativeapi/GodotNativeBridge");
|
||||
if (godot_native_bridge_class) {
|
||||
godot_native_bridge_class = (jclass)p_env->NewGlobalRef(godot_native_bridge_class);
|
||||
} else {
|
||||
// this is a pretty serious fail.. bail... pointers will stay 0
|
||||
return;
|
||||
}
|
||||
|
||||
// get some Godot method pointers...
|
||||
_restart = p_env->GetMethodID(godot_class, "restart", "()V");
|
||||
_finish = p_env->GetMethodID(godot_class, "forceQuit", "(I)Z");
|
||||
_set_keep_screen_on = p_env->GetMethodID(godot_class, "setKeepScreenOn", "(Z)V");
|
||||
_alert = p_env->GetMethodID(godot_class, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
_is_dark_mode_supported = p_env->GetMethodID(godot_class, "isDarkModeSupported", "()Z");
|
||||
_is_dark_mode = p_env->GetMethodID(godot_class, "isDarkMode", "()Z");
|
||||
_get_accent_color = p_env->GetMethodID(godot_class, "getAccentColor", "()I");
|
||||
_get_base_color = p_env->GetMethodID(godot_class, "getBaseColor", "()I");
|
||||
_get_clipboard = p_env->GetMethodID(godot_class, "getClipboard", "()Ljava/lang/String;");
|
||||
_set_clipboard = p_env->GetMethodID(godot_class, "setClipboard", "(Ljava/lang/String;)V");
|
||||
_has_clipboard = p_env->GetMethodID(godot_class, "hasClipboard", "()Z");
|
||||
_show_dialog = p_env->GetMethodID(godot_class, "showDialog", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");
|
||||
_show_input_dialog = p_env->GetMethodID(godot_class, "showInputDialog", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
_show_file_picker = p_env->GetMethodID(godot_class, "showFilePicker", "(Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;)V");
|
||||
_request_permission = p_env->GetMethodID(godot_class, "requestPermission", "(Ljava/lang/String;)Z");
|
||||
_request_permissions = p_env->GetMethodID(godot_class, "requestPermissions", "()Z");
|
||||
_get_granted_permissions = p_env->GetMethodID(godot_class, "getGrantedPermissions", "()[Ljava/lang/String;");
|
||||
_get_ca_certificates = p_env->GetMethodID(godot_class, "getCACertificates", "()Ljava/lang/String;");
|
||||
_init_input_devices = p_env->GetMethodID(godot_class, "initInputDevices", "()V");
|
||||
_vibrate = p_env->GetMethodID(godot_class, "vibrate", "(II)V");
|
||||
_get_input_fallback_mapping = p_env->GetMethodID(godot_class, "getInputFallbackMapping", "()Ljava/lang/String;");
|
||||
_on_godot_setup_completed = p_env->GetMethodID(godot_class, "onGodotSetupCompleted", "()V");
|
||||
_on_godot_main_loop_started = p_env->GetMethodID(godot_class, "onGodotMainLoopStarted", "()V");
|
||||
_on_godot_terminating = p_env->GetMethodID(godot_class, "onGodotTerminating", "()V");
|
||||
_create_new_godot_instance = p_env->GetMethodID(godot_class, "createNewGodotInstance", "([Ljava/lang/String;)I");
|
||||
_get_render_view = p_env->GetMethodID(godot_class, "getRenderView", "()Lorg/godotengine/godot/GodotRenderView;");
|
||||
_begin_benchmark_measure = p_env->GetMethodID(godot_class, "nativeBeginBenchmarkMeasure", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
_end_benchmark_measure = p_env->GetMethodID(godot_class, "nativeEndBenchmarkMeasure", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
_dump_benchmark = p_env->GetMethodID(godot_class, "nativeDumpBenchmark", "(Ljava/lang/String;)V");
|
||||
_get_gdextension_list_config_file = p_env->GetMethodID(godot_class, "getGDExtensionConfigFiles", "()[Ljava/lang/String;");
|
||||
_check_internal_feature_support = p_env->GetMethodID(godot_class, "checkInternalFeatureSupport", "(Ljava/lang/String;)Z");
|
||||
_sign_apk = p_env->GetMethodID(godot_class, "nativeSignApk", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I");
|
||||
_verify_apk = p_env->GetMethodID(godot_class, "nativeVerifyApk", "(Ljava/lang/String;)I");
|
||||
_enable_immersive_mode = p_env->GetMethodID(godot_class, "nativeEnableImmersiveMode", "(Z)V");
|
||||
_is_in_immersive_mode = p_env->GetMethodID(godot_class, "isInImmersiveMode", "()Z");
|
||||
_set_window_color = p_env->GetMethodID(godot_class, "setWindowColor", "(Ljava/lang/String;)V");
|
||||
_on_editor_workspace_selected = p_env->GetMethodID(godot_class, "nativeOnEditorWorkspaceSelected", "(Ljava/lang/String;)V");
|
||||
_on_distraction_free_mode_changed = p_env->GetMethodID(godot_class, "nativeOnDistractionFreeModeChanged", "(Z)V");
|
||||
_get_activity = p_env->GetMethodID(godot_class, "getActivity", "()Landroid/app/Activity;");
|
||||
_build_env_connect = p_env->GetMethodID(godot_class, "nativeBuildEnvConnect", "(Lorg/godotengine/godot/variant/Callable;)Z");
|
||||
_build_env_disconnect = p_env->GetMethodID(godot_class, "nativeBuildEnvDisconnect", "()V");
|
||||
_build_env_execute = p_env->GetMethodID(godot_class, "nativeBuildEnvExecute", "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/godotengine/godot/variant/Callable;Lorg/godotengine/godot/variant/Callable;)I");
|
||||
_build_env_cancel = p_env->GetMethodID(godot_class, "nativeBuildEnvCancel", "(I)V");
|
||||
_build_env_clean_project = p_env->GetMethodID(godot_class, "nativeBuildEnvCleanProject", "(Ljava/lang/String;Ljava/lang/String;Lorg/godotengine/godot/variant/Callable;)V");
|
||||
_restart = p_env->GetMethodID(godot_native_bridge_class, "restart", "()V");
|
||||
_finish = p_env->GetMethodID(godot_native_bridge_class, "forceQuit", "(I)Z");
|
||||
_set_keep_screen_on = p_env->GetMethodID(godot_native_bridge_class, "setKeepScreenOn", "(Z)V");
|
||||
_alert = p_env->GetMethodID(godot_native_bridge_class, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
_is_dark_mode_supported = p_env->GetMethodID(godot_native_bridge_class, "isDarkModeSupported", "()Z");
|
||||
_is_dark_mode = p_env->GetMethodID(godot_native_bridge_class, "isDarkMode", "()Z");
|
||||
_get_accent_color = p_env->GetMethodID(godot_native_bridge_class, "getAccentColor", "()I");
|
||||
_get_base_color = p_env->GetMethodID(godot_native_bridge_class, "getBaseColor", "()I");
|
||||
_get_clipboard = p_env->GetMethodID(godot_native_bridge_class, "getClipboard", "()Ljava/lang/String;");
|
||||
_set_clipboard = p_env->GetMethodID(godot_native_bridge_class, "setClipboard", "(Ljava/lang/String;)V");
|
||||
_has_clipboard = p_env->GetMethodID(godot_native_bridge_class, "hasClipboard", "()Z");
|
||||
_show_dialog = p_env->GetMethodID(godot_native_bridge_class, "showDialog", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");
|
||||
_show_input_dialog = p_env->GetMethodID(godot_native_bridge_class, "showInputDialog", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
_show_file_picker = p_env->GetMethodID(godot_native_bridge_class, "showFilePicker", "(Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;)V");
|
||||
_request_permission = p_env->GetMethodID(godot_native_bridge_class, "requestPermission", "(Ljava/lang/String;)Z");
|
||||
_request_permissions = p_env->GetMethodID(godot_native_bridge_class, "requestPermissions", "()Z");
|
||||
_get_granted_permissions = p_env->GetMethodID(godot_native_bridge_class, "getGrantedPermissions", "()[Ljava/lang/String;");
|
||||
_get_ca_certificates = p_env->GetMethodID(godot_native_bridge_class, "getCACertificates", "()Ljava/lang/String;");
|
||||
_init_input_devices = p_env->GetMethodID(godot_native_bridge_class, "initInputDevices", "()V");
|
||||
_vibrate = p_env->GetMethodID(godot_native_bridge_class, "vibrate", "(II)V");
|
||||
_get_input_fallback_mapping = p_env->GetMethodID(godot_native_bridge_class, "getInputFallbackMapping", "()Ljava/lang/String;");
|
||||
_on_godot_setup_completed = p_env->GetMethodID(godot_native_bridge_class, "onGodotSetupCompleted", "()V");
|
||||
_on_godot_main_loop_started = p_env->GetMethodID(godot_native_bridge_class, "onGodotMainLoopStarted", "()V");
|
||||
_on_godot_terminating = p_env->GetMethodID(godot_native_bridge_class, "onGodotTerminating", "()V");
|
||||
_create_new_godot_instance = p_env->GetMethodID(godot_native_bridge_class, "createNewGodotInstance", "([Ljava/lang/String;)I");
|
||||
_get_render_view = p_env->GetMethodID(godot_native_bridge_class, "getRenderView", "()Lorg/godotengine/godot/GodotRenderView;");
|
||||
_begin_benchmark_measure = p_env->GetMethodID(godot_native_bridge_class, "nativeBeginBenchmarkMeasure", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
_end_benchmark_measure = p_env->GetMethodID(godot_native_bridge_class, "nativeEndBenchmarkMeasure", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
_dump_benchmark = p_env->GetMethodID(godot_native_bridge_class, "nativeDumpBenchmark", "(Ljava/lang/String;)V");
|
||||
_get_gdextension_list_config_file = p_env->GetMethodID(godot_native_bridge_class, "getGDExtensionConfigFiles", "()[Ljava/lang/String;");
|
||||
_check_internal_feature_support = p_env->GetMethodID(godot_native_bridge_class, "checkInternalFeatureSupport", "(Ljava/lang/String;)Z");
|
||||
_sign_apk = p_env->GetMethodID(godot_native_bridge_class, "nativeSignApk", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I");
|
||||
_verify_apk = p_env->GetMethodID(godot_native_bridge_class, "nativeVerifyApk", "(Ljava/lang/String;)I");
|
||||
_enable_immersive_mode = p_env->GetMethodID(godot_native_bridge_class, "nativeEnableImmersiveMode", "(Z)V");
|
||||
_is_in_immersive_mode = p_env->GetMethodID(godot_native_bridge_class, "isInImmersiveMode", "()Z");
|
||||
_set_window_color = p_env->GetMethodID(godot_native_bridge_class, "setWindowColor", "(Ljava/lang/String;)V");
|
||||
_on_editor_workspace_selected = p_env->GetMethodID(godot_native_bridge_class, "nativeOnEditorWorkspaceSelected", "(Ljava/lang/String;)V");
|
||||
_on_distraction_free_mode_changed = p_env->GetMethodID(godot_native_bridge_class, "nativeOnDistractionFreeModeChanged", "(Z)V");
|
||||
_get_activity = p_env->GetMethodID(godot_native_bridge_class, "getActivity", "()Landroid/app/Activity;");
|
||||
_build_env_connect = p_env->GetMethodID(godot_native_bridge_class, "nativeBuildEnvConnect", "(Lorg/godotengine/godot/variant/Callable;)Z");
|
||||
_build_env_disconnect = p_env->GetMethodID(godot_native_bridge_class, "nativeBuildEnvDisconnect", "()V");
|
||||
_build_env_execute = p_env->GetMethodID(godot_native_bridge_class, "nativeBuildEnvExecute", "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/godotengine/godot/variant/Callable;Lorg/godotengine/godot/variant/Callable;)I");
|
||||
_build_env_cancel = p_env->GetMethodID(godot_native_bridge_class, "nativeBuildEnvCancel", "(I)V");
|
||||
_build_env_clean_project = p_env->GetMethodID(godot_native_bridge_class, "nativeBuildEnvCleanProject", "(Ljava/lang/String;Ljava/lang/String;Lorg/godotengine/godot/variant/Callable;)V");
|
||||
|
||||
// PiP mode method ids.
|
||||
_is_pip_mode_supported = p_env->GetMethodID(godot_class, "nativeIsPiPModeSupported", "()Z");
|
||||
_is_in_pip_mode = p_env->GetMethodID(godot_class, "nativeIsInPiPMode", "()Z");
|
||||
_enter_pip_mode = p_env->GetMethodID(godot_class, "nativeEnterPiPMode", "()V");
|
||||
_set_pip_mode_aspect_ratio = p_env->GetMethodID(godot_class, "nativeSetPiPModeAspectRatio", "(II)V");
|
||||
_set_auto_enter_pip_mode_on_background = p_env->GetMethodID(godot_class, "nativeSetAutoEnterPiPModeOnBackground", "(Z)V");
|
||||
_is_pip_mode_supported = p_env->GetMethodID(godot_native_bridge_class, "nativeIsPiPModeSupported", "()Z");
|
||||
_is_in_pip_mode = p_env->GetMethodID(godot_native_bridge_class, "nativeIsInPiPMode", "()Z");
|
||||
_enter_pip_mode = p_env->GetMethodID(godot_native_bridge_class, "nativeEnterPiPMode", "()V");
|
||||
_set_pip_mode_aspect_ratio = p_env->GetMethodID(godot_native_bridge_class, "nativeSetPiPModeAspectRatio", "(II)V");
|
||||
_set_auto_enter_pip_mode_on_background = p_env->GetMethodID(godot_native_bridge_class, "nativeSetAutoEnterPiPModeOnBackground", "(Z)V");
|
||||
}
|
||||
|
||||
GodotJavaWrapper::~GodotJavaWrapper() {
|
||||
@@ -112,15 +112,15 @@ GodotJavaWrapper::~GodotJavaWrapper() {
|
||||
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
env->DeleteGlobalRef(godot_instance);
|
||||
env->DeleteGlobalRef(godot_class);
|
||||
env->DeleteGlobalRef(godot_native_bridge);
|
||||
env->DeleteGlobalRef(godot_native_bridge_class);
|
||||
}
|
||||
|
||||
jobject GodotJavaWrapper::get_activity() {
|
||||
if (_get_activity) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, nullptr);
|
||||
jobject activity = env->CallObjectMethod(godot_instance, _get_activity);
|
||||
jobject activity = env->CallObjectMethod(godot_native_bridge, _get_activity);
|
||||
return activity;
|
||||
}
|
||||
return nullptr;
|
||||
@@ -133,7 +133,7 @@ GodotJavaViewWrapper *GodotJavaWrapper::get_godot_view() {
|
||||
if (_get_render_view) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, nullptr);
|
||||
jobject godot_render_view = env->CallObjectMethod(godot_instance, _get_render_view);
|
||||
jobject godot_render_view = env->CallObjectMethod(godot_native_bridge, _get_render_view);
|
||||
if (!env->IsSameObject(godot_render_view, nullptr)) {
|
||||
godot_view = new GodotJavaViewWrapper(godot_render_view);
|
||||
}
|
||||
@@ -146,7 +146,7 @@ void GodotJavaWrapper::on_godot_setup_completed(JNIEnv *p_env) {
|
||||
if (p_env == nullptr) {
|
||||
p_env = get_jni_env();
|
||||
}
|
||||
p_env->CallVoidMethod(godot_instance, _on_godot_setup_completed);
|
||||
p_env->CallVoidMethod(godot_native_bridge, _on_godot_setup_completed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ void GodotJavaWrapper::on_godot_main_loop_started(JNIEnv *p_env) {
|
||||
p_env = get_jni_env();
|
||||
}
|
||||
ERR_FAIL_NULL(p_env);
|
||||
p_env->CallVoidMethod(godot_instance, _on_godot_main_loop_started);
|
||||
p_env->CallVoidMethod(godot_native_bridge, _on_godot_main_loop_started);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ void GodotJavaWrapper::on_godot_terminating(JNIEnv *p_env) {
|
||||
p_env = get_jni_env();
|
||||
}
|
||||
ERR_FAIL_NULL(p_env);
|
||||
p_env->CallVoidMethod(godot_instance, _on_godot_terminating);
|
||||
p_env->CallVoidMethod(godot_native_bridge, _on_godot_terminating);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ void GodotJavaWrapper::restart(JNIEnv *p_env) {
|
||||
p_env = get_jni_env();
|
||||
}
|
||||
ERR_FAIL_NULL(p_env);
|
||||
p_env->CallVoidMethod(godot_instance, _restart);
|
||||
p_env->CallVoidMethod(godot_native_bridge, _restart);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ bool GodotJavaWrapper::force_quit(JNIEnv *p_env, int p_instance_id) {
|
||||
p_env = get_jni_env();
|
||||
}
|
||||
ERR_FAIL_NULL_V(p_env, false);
|
||||
return p_env->CallBooleanMethod(godot_instance, _finish, p_instance_id);
|
||||
return p_env->CallBooleanMethod(godot_native_bridge, _finish, p_instance_id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -195,7 +195,7 @@ void GodotJavaWrapper::set_keep_screen_on(bool p_enabled) {
|
||||
if (_set_keep_screen_on) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
env->CallVoidMethod(godot_instance, _set_keep_screen_on, p_enabled);
|
||||
env->CallVoidMethod(godot_native_bridge, _set_keep_screen_on, p_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ void GodotJavaWrapper::alert(const String &p_message, const String &p_title) {
|
||||
ERR_FAIL_NULL(env);
|
||||
jstring jStrMessage = env->NewStringUTF(p_message.utf8().get_data());
|
||||
jstring jStrTitle = env->NewStringUTF(p_title.utf8().get_data());
|
||||
env->CallVoidMethod(godot_instance, _alert, jStrMessage, jStrTitle);
|
||||
env->CallVoidMethod(godot_native_bridge, _alert, jStrMessage, jStrTitle);
|
||||
env->DeleteLocalRef(jStrMessage);
|
||||
env->DeleteLocalRef(jStrTitle);
|
||||
}
|
||||
@@ -215,7 +215,7 @@ bool GodotJavaWrapper::is_dark_mode_supported() {
|
||||
if (_is_dark_mode_supported) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
return env->CallBooleanMethod(godot_instance, _is_dark_mode_supported);
|
||||
return env->CallBooleanMethod(godot_native_bridge, _is_dark_mode_supported);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -225,7 +225,7 @@ bool GodotJavaWrapper::is_dark_mode() {
|
||||
if (_is_dark_mode) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
return env->CallBooleanMethod(godot_instance, _is_dark_mode);
|
||||
return env->CallBooleanMethod(godot_native_bridge, _is_dark_mode);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -244,7 +244,7 @@ Color GodotJavaWrapper::get_accent_color() {
|
||||
if (_get_accent_color) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, Color(0, 0, 0, 0));
|
||||
int accent_color = env->CallIntMethod(godot_instance, _get_accent_color);
|
||||
int accent_color = env->CallIntMethod(godot_native_bridge, _get_accent_color);
|
||||
return _argb_to_rgba(accent_color);
|
||||
} else {
|
||||
return Color(0, 0, 0, 0);
|
||||
@@ -255,7 +255,7 @@ Color GodotJavaWrapper::get_base_color() {
|
||||
if (_get_base_color) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, Color(0, 0, 0, 0));
|
||||
int base_color = env->CallIntMethod(godot_instance, _get_base_color);
|
||||
int base_color = env->CallIntMethod(godot_native_bridge, _get_base_color);
|
||||
return _argb_to_rgba(base_color);
|
||||
} else {
|
||||
return Color(0, 0, 0, 0);
|
||||
@@ -271,7 +271,7 @@ String GodotJavaWrapper::get_clipboard() {
|
||||
if (_get_clipboard) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, String());
|
||||
jstring s = (jstring)env->CallObjectMethod(godot_instance, _get_clipboard);
|
||||
jstring s = (jstring)env->CallObjectMethod(godot_native_bridge, _get_clipboard);
|
||||
clipboard = jstring_to_string(s, env);
|
||||
env->DeleteLocalRef(s);
|
||||
}
|
||||
@@ -283,7 +283,7 @@ String GodotJavaWrapper::get_input_fallback_mapping() {
|
||||
if (_get_input_fallback_mapping) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, String());
|
||||
jstring fallback_mapping = (jstring)env->CallObjectMethod(godot_instance, _get_input_fallback_mapping);
|
||||
jstring fallback_mapping = (jstring)env->CallObjectMethod(godot_native_bridge, _get_input_fallback_mapping);
|
||||
input_fallback_mapping = jstring_to_string(fallback_mapping, env);
|
||||
env->DeleteLocalRef(fallback_mapping);
|
||||
}
|
||||
@@ -299,7 +299,7 @@ void GodotJavaWrapper::set_clipboard(const String &p_text) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
jstring jStr = env->NewStringUTF(p_text.utf8().get_data());
|
||||
env->CallVoidMethod(godot_instance, _set_clipboard, jStr);
|
||||
env->CallVoidMethod(godot_native_bridge, _set_clipboard, jStr);
|
||||
env->DeleteLocalRef(jStr);
|
||||
}
|
||||
}
|
||||
@@ -312,7 +312,7 @@ bool GodotJavaWrapper::has_clipboard() {
|
||||
if (_has_clipboard) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
return env->CallBooleanMethod(godot_instance, _has_clipboard);
|
||||
return env->CallBooleanMethod(godot_native_bridge, _has_clipboard);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -330,7 +330,7 @@ Error GodotJavaWrapper::show_dialog(const String &p_title, const String &p_descr
|
||||
env->SetObjectArrayElement(j_buttons, i, j_button);
|
||||
env->DeleteLocalRef(j_button);
|
||||
}
|
||||
env->CallVoidMethod(godot_instance, _show_dialog, j_title, j_description, j_buttons);
|
||||
env->CallVoidMethod(godot_native_bridge, _show_dialog, j_title, j_description, j_buttons);
|
||||
env->DeleteLocalRef(j_title);
|
||||
env->DeleteLocalRef(j_description);
|
||||
env->DeleteLocalRef(j_buttons);
|
||||
@@ -347,7 +347,7 @@ Error GodotJavaWrapper::show_input_dialog(const String &p_title, const String &p
|
||||
jstring jStrTitle = env->NewStringUTF(p_title.utf8().get_data());
|
||||
jstring jStrMessage = env->NewStringUTF(p_message.utf8().get_data());
|
||||
jstring jStrExistingText = env->NewStringUTF(p_existing_text.utf8().get_data());
|
||||
env->CallVoidMethod(godot_instance, _show_input_dialog, jStrTitle, jStrMessage, jStrExistingText);
|
||||
env->CallVoidMethod(godot_native_bridge, _show_input_dialog, jStrTitle, jStrMessage, jStrExistingText);
|
||||
env->DeleteLocalRef(jStrTitle);
|
||||
env->DeleteLocalRef(jStrMessage);
|
||||
env->DeleteLocalRef(jStrExistingText);
|
||||
@@ -375,7 +375,7 @@ Error GodotJavaWrapper::show_file_picker(const String &p_current_directory, cons
|
||||
env->SetObjectArrayElement(j_filters, i, j_filter);
|
||||
env->DeleteLocalRef(j_filter);
|
||||
}
|
||||
env->CallVoidMethod(godot_instance, _show_file_picker, j_current_directory, j_filename, j_mode, j_filters);
|
||||
env->CallVoidMethod(godot_native_bridge, _show_file_picker, j_current_directory, j_filename, j_mode, j_filters);
|
||||
env->DeleteLocalRef(j_current_directory);
|
||||
env->DeleteLocalRef(j_filename);
|
||||
env->DeleteLocalRef(j_filters);
|
||||
@@ -390,7 +390,7 @@ bool GodotJavaWrapper::request_permission(const String &p_name) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
jstring jStrName = env->NewStringUTF(p_name.utf8().get_data());
|
||||
bool result = env->CallBooleanMethod(godot_instance, _request_permission, jStrName);
|
||||
bool result = env->CallBooleanMethod(godot_native_bridge, _request_permission, jStrName);
|
||||
env->DeleteLocalRef(jStrName);
|
||||
return result;
|
||||
} else {
|
||||
@@ -402,7 +402,7 @@ bool GodotJavaWrapper::request_permissions() {
|
||||
if (_request_permissions) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
return env->CallBooleanMethod(godot_instance, _request_permissions);
|
||||
return env->CallBooleanMethod(godot_native_bridge, _request_permissions);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -413,7 +413,7 @@ Vector<String> GodotJavaWrapper::get_granted_permissions() const {
|
||||
if (_get_granted_permissions) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, permissions_list);
|
||||
jobject permissions_object = env->CallObjectMethod(godot_instance, _get_granted_permissions);
|
||||
jobject permissions_object = env->CallObjectMethod(godot_native_bridge, _get_granted_permissions);
|
||||
jobjectArray *arr = reinterpret_cast<jobjectArray *>(&permissions_object);
|
||||
|
||||
jsize len = env->GetArrayLength(*arr);
|
||||
@@ -432,7 +432,7 @@ Vector<String> GodotJavaWrapper::get_gdextension_list_config_file() const {
|
||||
if (_get_gdextension_list_config_file) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, config_file_list);
|
||||
jobject config_file_list_object = env->CallObjectMethod(godot_instance, _get_gdextension_list_config_file);
|
||||
jobject config_file_list_object = env->CallObjectMethod(godot_native_bridge, _get_gdextension_list_config_file);
|
||||
jobjectArray *arr = reinterpret_cast<jobjectArray *>(&config_file_list_object);
|
||||
|
||||
jsize len = env->GetArrayLength(*arr);
|
||||
@@ -451,7 +451,7 @@ String GodotJavaWrapper::get_ca_certificates() const {
|
||||
if (_get_ca_certificates) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, String());
|
||||
jstring s = (jstring)env->CallObjectMethod(godot_instance, _get_ca_certificates);
|
||||
jstring s = (jstring)env->CallObjectMethod(godot_native_bridge, _get_ca_certificates);
|
||||
ca_certificates = jstring_to_string(s, env);
|
||||
env->DeleteLocalRef(s);
|
||||
}
|
||||
@@ -462,7 +462,7 @@ void GodotJavaWrapper::init_input_devices() {
|
||||
if (_init_input_devices) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
env->CallVoidMethod(godot_instance, _init_input_devices);
|
||||
env->CallVoidMethod(godot_native_bridge, _init_input_devices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ void GodotJavaWrapper::vibrate(int p_duration_ms, float p_amplitude) {
|
||||
j_amplitude = CLAMP(int(p_amplitude * 255), 1, 255);
|
||||
}
|
||||
|
||||
env->CallVoidMethod(godot_instance, _vibrate, p_duration_ms, j_amplitude);
|
||||
env->CallVoidMethod(godot_native_bridge, _vibrate, p_duration_ms, j_amplitude);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,7 +492,7 @@ int GodotJavaWrapper::create_new_godot_instance(const List<String> &args) {
|
||||
env->SetObjectArrayElement(jargs, i, j_arg);
|
||||
env->DeleteLocalRef(j_arg);
|
||||
}
|
||||
return env->CallIntMethod(godot_instance, _create_new_godot_instance, jargs);
|
||||
return env->CallIntMethod(godot_native_bridge, _create_new_godot_instance, jargs);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -504,7 +504,7 @@ void GodotJavaWrapper::begin_benchmark_measure(const String &p_context, const St
|
||||
ERR_FAIL_NULL(env);
|
||||
jstring j_context = env->NewStringUTF(p_context.utf8().get_data());
|
||||
jstring j_label = env->NewStringUTF(p_label.utf8().get_data());
|
||||
env->CallVoidMethod(godot_instance, _begin_benchmark_measure, j_context, j_label);
|
||||
env->CallVoidMethod(godot_native_bridge, _begin_benchmark_measure, j_context, j_label);
|
||||
env->DeleteLocalRef(j_context);
|
||||
env->DeleteLocalRef(j_label);
|
||||
}
|
||||
@@ -516,7 +516,7 @@ void GodotJavaWrapper::end_benchmark_measure(const String &p_context, const Stri
|
||||
ERR_FAIL_NULL(env);
|
||||
jstring j_context = env->NewStringUTF(p_context.utf8().get_data());
|
||||
jstring j_label = env->NewStringUTF(p_label.utf8().get_data());
|
||||
env->CallVoidMethod(godot_instance, _end_benchmark_measure, j_context, j_label);
|
||||
env->CallVoidMethod(godot_native_bridge, _end_benchmark_measure, j_context, j_label);
|
||||
env->DeleteLocalRef(j_context);
|
||||
env->DeleteLocalRef(j_label);
|
||||
}
|
||||
@@ -527,7 +527,7 @@ void GodotJavaWrapper::dump_benchmark(const String &benchmark_file) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
jstring j_benchmark_file = env->NewStringUTF(benchmark_file.utf8().get_data());
|
||||
env->CallVoidMethod(godot_instance, _dump_benchmark, j_benchmark_file);
|
||||
env->CallVoidMethod(godot_native_bridge, _dump_benchmark, j_benchmark_file);
|
||||
env->DeleteLocalRef(j_benchmark_file);
|
||||
}
|
||||
}
|
||||
@@ -538,7 +538,7 @@ bool GodotJavaWrapper::check_internal_feature_support(const String &p_feature) c
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
|
||||
jstring j_feature = env->NewStringUTF(p_feature.utf8().get_data());
|
||||
bool result = env->CallBooleanMethod(godot_instance, _check_internal_feature_support, j_feature);
|
||||
bool result = env->CallBooleanMethod(godot_native_bridge, _check_internal_feature_support, j_feature);
|
||||
env->DeleteLocalRef(j_feature);
|
||||
return result;
|
||||
} else {
|
||||
@@ -557,7 +557,7 @@ Error GodotJavaWrapper::sign_apk(const String &p_input_path, const String &p_out
|
||||
jstring j_keystore_user = env->NewStringUTF(p_keystore_user.utf8().get_data());
|
||||
jstring j_keystore_password = env->NewStringUTF(p_keystore_password.utf8().get_data());
|
||||
|
||||
int result = env->CallIntMethod(godot_instance, _sign_apk, j_input_path, j_output_path, j_keystore_path, j_keystore_user, j_keystore_password);
|
||||
int result = env->CallIntMethod(godot_native_bridge, _sign_apk, j_input_path, j_output_path, j_keystore_path, j_keystore_user, j_keystore_password);
|
||||
|
||||
env->DeleteLocalRef(j_input_path);
|
||||
env->DeleteLocalRef(j_output_path);
|
||||
@@ -577,7 +577,7 @@ Error GodotJavaWrapper::verify_apk(const String &p_apk_path) {
|
||||
ERR_FAIL_NULL_V(env, ERR_UNCONFIGURED);
|
||||
|
||||
jstring j_apk_path = env->NewStringUTF(p_apk_path.utf8().get_data());
|
||||
int result = env->CallIntMethod(godot_instance, _verify_apk, j_apk_path);
|
||||
int result = env->CallIntMethod(godot_native_bridge, _verify_apk, j_apk_path);
|
||||
env->DeleteLocalRef(j_apk_path);
|
||||
return static_cast<Error>(result);
|
||||
} else {
|
||||
@@ -589,7 +589,7 @@ void GodotJavaWrapper::enable_immersive_mode(bool p_enabled) {
|
||||
if (_enable_immersive_mode) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
env->CallVoidMethod(godot_instance, _enable_immersive_mode, p_enabled);
|
||||
env->CallVoidMethod(godot_native_bridge, _enable_immersive_mode, p_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ bool GodotJavaWrapper::is_in_immersive_mode() {
|
||||
if (_is_in_immersive_mode) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
return env->CallBooleanMethod(godot_instance, _is_in_immersive_mode);
|
||||
return env->CallBooleanMethod(godot_native_bridge, _is_in_immersive_mode);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -609,7 +609,7 @@ void GodotJavaWrapper::set_window_color(const Color &p_color) {
|
||||
ERR_FAIL_NULL(env);
|
||||
String color = "#" + p_color.to_html(false);
|
||||
jstring jStrColor = env->NewStringUTF(color.utf8().get_data());
|
||||
env->CallVoidMethod(godot_instance, _set_window_color, jStrColor);
|
||||
env->CallVoidMethod(godot_native_bridge, _set_window_color, jStrColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,7 +619,7 @@ void GodotJavaWrapper::on_editor_workspace_selected(const String &p_workspace) {
|
||||
ERR_FAIL_NULL(env);
|
||||
|
||||
jstring j_workspace = env->NewStringUTF(p_workspace.utf8().get_data());
|
||||
env->CallVoidMethod(godot_instance, _on_editor_workspace_selected, j_workspace);
|
||||
env->CallVoidMethod(godot_native_bridge, _on_editor_workspace_selected, j_workspace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,7 +628,7 @@ void GodotJavaWrapper::on_distraction_free_mode_changed(bool p_enabled) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
|
||||
env->CallVoidMethod(godot_instance, _on_distraction_free_mode_changed, p_enabled);
|
||||
env->CallVoidMethod(godot_native_bridge, _on_distraction_free_mode_changed, p_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ bool GodotJavaWrapper::build_env_connect(const Callable &p_callback) {
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
|
||||
jobject j_callback = callable_to_jcallable(env, p_callback);
|
||||
jboolean result = env->CallBooleanMethod(godot_instance, _build_env_connect, j_callback);
|
||||
jboolean result = env->CallBooleanMethod(godot_native_bridge, _build_env_connect, j_callback);
|
||||
env->DeleteLocalRef(j_callback);
|
||||
|
||||
return result;
|
||||
@@ -652,7 +652,7 @@ void GodotJavaWrapper::build_env_disconnect() {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
|
||||
env->CallVoidMethod(godot_instance, _build_env_disconnect);
|
||||
env->CallVoidMethod(godot_native_bridge, _build_env_disconnect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,7 +673,7 @@ int GodotJavaWrapper::build_env_execute(const String &p_build_tool, const List<S
|
||||
jobject j_output_callback = callable_to_jcallable(env, p_output_callback);
|
||||
jobject j_result_callback = callable_to_jcallable(env, p_result_callback);
|
||||
|
||||
jint result = env->CallIntMethod(godot_instance, _build_env_execute, j_build_tool, j_args, j_project_path, j_gradle_build_directory, j_output_callback, j_result_callback);
|
||||
jint result = env->CallIntMethod(godot_native_bridge, _build_env_execute, j_build_tool, j_args, j_project_path, j_gradle_build_directory, j_output_callback, j_result_callback);
|
||||
|
||||
env->DeleteLocalRef(j_build_tool);
|
||||
env->DeleteLocalRef(j_args);
|
||||
@@ -692,7 +692,7 @@ void GodotJavaWrapper::build_env_cancel(int p_job_id) {
|
||||
if (_build_env_cancel) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
env->CallVoidMethod(godot_instance, _build_env_cancel, p_job_id);
|
||||
env->CallVoidMethod(godot_native_bridge, _build_env_cancel, p_job_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,7 +705,7 @@ void GodotJavaWrapper::build_env_clean_project(const String &p_project_path, con
|
||||
jstring j_gradle_build_directory = env->NewStringUTF(p_gradle_build_directory.utf8().get_data());
|
||||
jobject j_callback = callable_to_jcallable(env, p_callback);
|
||||
|
||||
env->CallVoidMethod(godot_instance, _build_env_clean_project, j_project_path, j_gradle_build_directory, j_callback);
|
||||
env->CallVoidMethod(godot_native_bridge, _build_env_clean_project, j_project_path, j_gradle_build_directory, j_callback);
|
||||
|
||||
env->DeleteLocalRef(j_project_path);
|
||||
env->DeleteLocalRef(j_gradle_build_directory);
|
||||
@@ -717,7 +717,7 @@ bool GodotJavaWrapper::is_pip_mode_supported() {
|
||||
if (_is_pip_mode_supported) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
return env->CallBooleanMethod(godot_instance, _is_pip_mode_supported);
|
||||
return env->CallBooleanMethod(godot_native_bridge, _is_pip_mode_supported);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -727,7 +727,7 @@ bool GodotJavaWrapper::is_in_pip_mode() {
|
||||
if (_is_in_pip_mode) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
return env->CallBooleanMethod(godot_instance, _is_in_pip_mode);
|
||||
return env->CallBooleanMethod(godot_native_bridge, _is_in_pip_mode);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -737,7 +737,7 @@ void GodotJavaWrapper::enter_pip_mode() {
|
||||
if (_enter_pip_mode) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
env->CallVoidMethod(godot_instance, _enter_pip_mode);
|
||||
env->CallVoidMethod(godot_native_bridge, _enter_pip_mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,7 +745,7 @@ void GodotJavaWrapper::set_pip_mode_aspect_ratio(int p_numerator, int p_denomina
|
||||
if (_set_pip_mode_aspect_ratio) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
env->CallVoidMethod(godot_instance, _set_pip_mode_aspect_ratio, p_numerator, p_denominator);
|
||||
env->CallVoidMethod(godot_native_bridge, _set_pip_mode_aspect_ratio, p_numerator, p_denominator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,6 +753,6 @@ void GodotJavaWrapper::set_auto_enter_pip_mode_on_background(bool p_auto_enter_o
|
||||
if (_set_auto_enter_pip_mode_on_background) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL(env);
|
||||
env->CallVoidMethod(godot_instance, _set_auto_enter_pip_mode_on_background, p_auto_enter_on_background);
|
||||
env->CallVoidMethod(godot_native_bridge, _set_auto_enter_pip_mode_on_background, p_auto_enter_on_background);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
// Class that makes functions in java/src/org/godotengine/godot/Godot.kt callable from C++
|
||||
class GodotJavaWrapper {
|
||||
private:
|
||||
jobject godot_instance;
|
||||
jclass godot_class;
|
||||
jobject godot_native_bridge;
|
||||
jclass godot_native_bridge_class;
|
||||
|
||||
GodotJavaViewWrapper *godot_view = nullptr;
|
||||
|
||||
@@ -98,7 +98,7 @@ private:
|
||||
jmethodID _set_auto_enter_pip_mode_on_background = nullptr;
|
||||
|
||||
public:
|
||||
GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance);
|
||||
GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_native_bridge);
|
||||
~GodotJavaWrapper();
|
||||
|
||||
jobject get_activity();
|
||||
|
||||
Reference in New Issue
Block a user