feat: updated godot version
This commit is contained in:
parent
0c508b0831
commit
42b028dbb5
4694 changed files with 236470 additions and 401376 deletions
|
|
@ -48,6 +48,12 @@ android {
|
|||
buildConfig = true
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
dev {
|
||||
initWith debug
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions = ["products"]
|
||||
productFlavors {
|
||||
editor {}
|
||||
|
|
@ -73,11 +79,13 @@ android {
|
|||
|
||||
sourceSets {
|
||||
debug.jniLibs.srcDirs = ['libs/debug']
|
||||
dev.jniLibs.srcDirs = ['libs/dev']
|
||||
release.jniLibs.srcDirs = ['libs/release']
|
||||
|
||||
// Editor jni library
|
||||
editorRelease.jniLibs.srcDirs = ['libs/tools/release']
|
||||
editorDebug.jniLibs.srcDirs = ['libs/tools/debug']
|
||||
editorDev.jniLibs.srcDirs = ['libs/tools/dev']
|
||||
}
|
||||
|
||||
libraryVariants.all { variant ->
|
||||
|
|
@ -91,9 +99,9 @@ android {
|
|||
throw new GradleException("Invalid build type: $buildType")
|
||||
}
|
||||
|
||||
boolean debugBuild = buildType == "debug"
|
||||
boolean debugSymbols = debugBuild
|
||||
boolean runTests = debugBuild
|
||||
boolean devBuild = buildType == "dev"
|
||||
boolean debugSymbols = devBuild
|
||||
boolean runTests = devBuild
|
||||
boolean storeRelease = buildType == "release"
|
||||
boolean productionBuild = storeRelease
|
||||
|
||||
|
|
@ -101,13 +109,12 @@ android {
|
|||
if (sconsTarget == "template") {
|
||||
// Tests are not supported on template builds
|
||||
runTests = false
|
||||
|
||||
//noinspection GroovyFallthrough
|
||||
switch (buildType) {
|
||||
case "release":
|
||||
sconsTarget += "_release"
|
||||
break
|
||||
case "debug":
|
||||
case "dev":
|
||||
default:
|
||||
sconsTarget += "_debug"
|
||||
break
|
||||
|
|
@ -116,6 +123,9 @@ android {
|
|||
|
||||
// Update the name of the generated library
|
||||
def outputSuffix = "${sconsTarget}"
|
||||
if (devBuild) {
|
||||
outputSuffix = "${outputSuffix}.dev"
|
||||
}
|
||||
variant.outputs.all { output ->
|
||||
output.outputFileName = "godot-lib.${outputSuffix}.aar"
|
||||
}
|
||||
|
|
@ -158,7 +168,7 @@ android {
|
|||
def taskName = getSconsTaskName(flavorName, buildType, selectedAbi)
|
||||
tasks.create(name: taskName, type: Exec) {
|
||||
executable sconsExecutableFile.absolutePath
|
||||
args "--directory=${pathToRootDir}", "platform=android", "store_release=${storeRelease}", "production=${productionBuild}", "dev_mode=${debugBuild}", "dev_build=${debugBuild}", "debug_symbols=${debugSymbols}", "tests=${runTests}", "target=${sconsTarget}", "arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors()
|
||||
args "--directory=${pathToRootDir}", "platform=android", "store_release=${storeRelease}", "production=${productionBuild}", "dev_mode=${devBuild}", "dev_build=${devBuild}", "debug_symbols=${debugSymbols}", "tests=${runTests}", "target=${sconsTarget}", "arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors()
|
||||
}
|
||||
|
||||
// Schedule the tasks so the generated libs are present before the aar file is packaged.
|
||||
|
|
|
|||
|
|
@ -43,7 +43,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
|
||||
|
|
@ -58,7 +57,6 @@ 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
|
||||
|
|
@ -177,6 +175,7 @@ class Godot private constructor(val context: Context) {
|
|||
*/
|
||||
private var renderViewInitialized = false
|
||||
private var primaryHost: GodotHost? = null
|
||||
private var currentConfig = context.resources.configuration
|
||||
|
||||
/**
|
||||
* Tracks whether we're in the RESUMED lifecycle state.
|
||||
|
|
@ -198,7 +197,6 @@ class Godot private constructor(val context: Context) {
|
|||
private var useDebugOpengl = false
|
||||
private var darkMode = false
|
||||
private var backgroundColor: Int = Color.BLACK
|
||||
private var orientation = Configuration.ORIENTATION_UNDEFINED
|
||||
|
||||
internal var containerLayout: FrameLayout? = null
|
||||
var renderView: GodotRenderView? = null
|
||||
|
|
@ -236,9 +234,7 @@ class Godot private constructor(val context: Context) {
|
|||
|
||||
Log.v(TAG, "InitEngine with params: $commandLineParams")
|
||||
|
||||
val config = context.resources.configuration
|
||||
darkMode = (config.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
||||
orientation = config.orientation
|
||||
darkMode = context.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
||||
|
||||
beginBenchmarkMeasure("Startup", "Godot::initEngine")
|
||||
try {
|
||||
|
|
@ -569,14 +565,19 @@ class Godot private constructor(val context: Context) {
|
|||
!isEditorHint() &&
|
||||
java.lang.Boolean.parseBoolean(GodotLib.getGlobal("display/window/per_pixel_transparency/allowed"))
|
||||
Log.d(TAG, "Render view should be transparent: $shouldBeTransparent")
|
||||
renderView = if (usesVulkan()) {
|
||||
if (meetsVulkanRequirements(context.packageManager)) {
|
||||
GodotVulkanRenderView(this, godotInputHandler, shouldBeTransparent)
|
||||
} else if (canFallbackToOpenGL()) {
|
||||
// Fallback to OpenGl.
|
||||
GodotGLRenderView(this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
|
||||
} else {
|
||||
throw IllegalStateException(context.getString(R.string.error_missing_vulkan_requirements_message))
|
||||
}
|
||||
|
||||
val nativeRenderer = getNativeRenderer();
|
||||
if (nativeRenderer == "vulkan") {
|
||||
renderView = GodotVulkanRenderView(this, godotInputHandler, shouldBeTransparent)
|
||||
} else if (nativeRenderer == "opengl3") {
|
||||
renderView = GodotGLRenderView(this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
|
||||
} else {
|
||||
throw IllegalStateException("No native renderer is available.")
|
||||
// Fallback to OpenGl.
|
||||
GodotGLRenderView(this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
|
||||
}
|
||||
|
||||
renderView?.let {
|
||||
|
|
@ -647,6 +648,9 @@ class Godot private constructor(val context: Context) {
|
|||
})
|
||||
|
||||
renderView?.queueOnRenderThread {
|
||||
for (plugin in pluginRegistry.allPlugins) {
|
||||
plugin.onRegisterPluginWithGodotNative()
|
||||
}
|
||||
setKeepScreenOn(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")))
|
||||
}
|
||||
|
||||
|
|
@ -715,13 +719,6 @@ class Godot private constructor(val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
internal fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
|
||||
Log.v(TAG, "onPictureInPictureModeChanged: $isInPictureInPictureMode")
|
||||
runOnRenderThread {
|
||||
GodotLib.onPictureInPictureModeChanged(isInPictureInPictureMode)
|
||||
}
|
||||
}
|
||||
|
||||
fun onPause(host: GodotHost) {
|
||||
Log.v(TAG, "OnPause: $host")
|
||||
resumed = false
|
||||
|
|
@ -778,12 +775,12 @@ class Godot private constructor(val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
if (orientation != newConfig.orientation) {
|
||||
orientation = newConfig.orientation
|
||||
if (currentConfig.orientation != newConfig.orientation) {
|
||||
runOnRenderThread {
|
||||
GodotLib.onOrientationChange(orientation)
|
||||
GodotLib.onScreenRotationChange(newConfig.orientation)
|
||||
}
|
||||
}
|
||||
currentConfig = newConfig
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -847,7 +844,6 @@ class Godot private constructor(val context: Context) {
|
|||
}
|
||||
|
||||
for (plugin in pluginRegistry.allPlugins) {
|
||||
plugin.onRegisterPluginWithGodotNative()
|
||||
plugin.onGodotSetupCompleted()
|
||||
}
|
||||
primaryHost?.onGodotSetupCompleted()
|
||||
|
|
@ -936,25 +932,31 @@ class Godot private constructor(val context: Context) {
|
|||
*/
|
||||
private fun isOnUiThread() = Looper.myLooper() == Looper.getMainLooper()
|
||||
|
||||
/**
|
||||
* Returns the native rendering driver.
|
||||
/**
|
||||
* Returns true if `Vulkan` is used for rendering.
|
||||
*/
|
||||
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]
|
||||
Log.d(TAG, """renderingDevice: ${renderingDriverChosen} (${renderingDriverSource})
|
||||
renderer: ${renderingMethod} (${renderingMethodSource})""")
|
||||
|
||||
if (renderingDriverOriginal == "vulkan" && renderingDriverChosen == "") {
|
||||
// Throw the exception for the case where Vulkan failed to create and no fallback was available.
|
||||
throw IllegalStateException(context.getString(R.string.error_missing_vulkan_requirements_message))
|
||||
private fun usesVulkan(): Boolean {
|
||||
val rendererInfo = GodotLib.getRendererInfo()
|
||||
var renderingDeviceSource = "ProjectSettings"
|
||||
var renderingDevice = rendererInfo[0]
|
||||
var rendererSource = "ProjectSettings"
|
||||
var renderer = rendererInfo[1]
|
||||
val cmdline = commandLine
|
||||
var index = cmdline.indexOf("--rendering-method")
|
||||
if (index > -1 && cmdline.size > index + 1) {
|
||||
rendererSource = "CommandLine"
|
||||
renderer = cmdline.get(index + 1)
|
||||
}
|
||||
|
||||
return renderingDriverChosen;
|
||||
index = cmdline.indexOf("--rendering-driver")
|
||||
if (index > -1 && cmdline.size > index + 1) {
|
||||
renderingDeviceSource = "CommandLine"
|
||||
renderingDevice = cmdline.get(index + 1)
|
||||
}
|
||||
val result = ("forward_plus" == renderer || "mobile" == renderer) && "vulkan" == renderingDevice
|
||||
Log.d(TAG, """usesVulkan(): ${result}
|
||||
renderingDevice: ${renderingDevice} (${renderingDeviceSource})
|
||||
renderer: ${renderer} (${rendererSource})""")
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -976,8 +978,8 @@ class Godot private constructor(val context: Context) {
|
|||
Log.w(TAG, "The vulkan hardware level does not meet the minimum requirement: 1")
|
||||
}
|
||||
|
||||
// Check for api version 1.1
|
||||
return packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000)
|
||||
// Check for api version 1.0
|
||||
return packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x400003)
|
||||
}
|
||||
|
||||
private fun setKeepScreenOn(enabled: Boolean) {
|
||||
|
|
@ -1315,11 +1317,6 @@ class Godot private constructor(val context: Context) {
|
|||
primaryHost?.onEditorWorkspaceSelected(workspace)
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeOnDistractionFreeModeChanged(enabled: Boolean) {
|
||||
primaryHost?.onDistractionFreeModeChanged(enabled)
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvConnect(callback: GodotCallable): Boolean {
|
||||
try {
|
||||
|
|
@ -1379,52 +1376,4 @@ class Godot private constructor(val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
@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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,25 +31,17 @@
|
|||
package org.godotengine.godot
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.PictureInPictureParams
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.util.Rational
|
||||
import android.view.View
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import org.godotengine.godot.feature.PictureInPictureProvider
|
||||
import org.godotengine.godot.utils.CommandLineFileParser
|
||||
import org.godotengine.godot.utils.PermissionsUtil
|
||||
import org.godotengine.godot.utils.ProcessPhoenix
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
/**
|
||||
* Base abstract activity for Android apps intending to use Godot as the primary screen.
|
||||
|
|
@ -57,7 +49,7 @@ import java.util.concurrent.atomic.AtomicReference
|
|||
* Also a reference implementation for how to setup and use the [GodotFragment] fragment
|
||||
* within an Android app.
|
||||
*/
|
||||
abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPictureProvider {
|
||||
abstract class GodotActivity : FragmentActivity(), GodotHost {
|
||||
|
||||
companion object {
|
||||
private val TAG = GodotActivity::class.java.simpleName
|
||||
|
|
@ -73,12 +65,6 @@ abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPicturePr
|
|||
private final val DEFAULT_WINDOW_ID = 664;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if the activity should automatically enter picture-in-picture when put in the background.
|
||||
*/
|
||||
private val pipAspectRatio = AtomicReference<Rational>()
|
||||
private val autoEnterPiP = AtomicBoolean(false)
|
||||
private val gameViewSourceRectHint = Rect()
|
||||
private val commandLineParams = ArrayList<String>()
|
||||
/**
|
||||
* Interaction with the [Godot] object is delegated to the [GodotFragment] class.
|
||||
|
|
@ -153,13 +139,6 @@ abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPicturePr
|
|||
.setPrimaryNavigationFragment(godotFragment)
|
||||
.commitNowAllowingStateLoss()
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val gameView = findViewById<View>(R.id.godot_fragment_container)
|
||||
gameView?.addOnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
|
||||
gameView.getGlobalVisibleRect(gameViewSourceRectHint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewGodotInstanceRequested(args: Array<String>): Int {
|
||||
|
|
@ -170,7 +149,7 @@ abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPicturePr
|
|||
.putExtra(EXTRA_COMMAND_LINE_PARAMS, args)
|
||||
triggerRebirth(null, intent)
|
||||
// fake 'process' id returned by create_instance() etc
|
||||
return DEFAULT_WINDOW_ID
|
||||
return DEFAULT_WINDOW_ID;
|
||||
}
|
||||
|
||||
protected fun triggerRebirth(bundle: Bundle?, intent: Intent) {
|
||||
|
|
@ -188,15 +167,6 @@ abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPicturePr
|
|||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
|
||||
if (isInPictureInPictureMode && !isFinishing) {
|
||||
// We get in this state when PiP is closed, so we terminate the activity.
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onGodotForceQuit(instance: Godot) {
|
||||
runOnUiThread { terminateGodotInstance(instance) }
|
||||
}
|
||||
|
|
@ -226,31 +196,13 @@ abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPicturePr
|
|||
}
|
||||
}
|
||||
|
||||
override fun onGodotSetupCompleted() {
|
||||
super.onGodotSetupCompleted()
|
||||
|
||||
if (isPiPEnabled()) {
|
||||
try {
|
||||
// Update the aspect ratio for picture-in-picture mode.
|
||||
val viewportWidth = Integer.parseInt(GodotLib.getGlobal("display/window/size/viewport_width"))
|
||||
val viewportHeight = Integer.parseInt(GodotLib.getGlobal("display/window/size/viewport_height"))
|
||||
pipAspectRatio.set(Rational(viewportWidth, viewportHeight))
|
||||
} catch (e: NumberFormatException) {
|
||||
Log.w(TAG, "Unable to parse viewport dimensions.", e)
|
||||
}
|
||||
|
||||
runOnHostThread { updatePiPParams() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(newIntent: Intent) {
|
||||
intent = sanitizeLaunchIntent(newIntent)
|
||||
super.onNewIntent(intent)
|
||||
handleStartIntent(intent, false)
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
protected open fun handleStartIntent(intent: Intent, newLaunch: Boolean) {
|
||||
private fun handleStartIntent(intent: Intent, newLaunch: Boolean) {
|
||||
if (!newLaunch) {
|
||||
val newLaunchRequested = intent.getBooleanExtra(EXTRA_NEW_LAUNCH, false)
|
||||
if (newLaunchRequested) {
|
||||
|
|
@ -304,56 +256,4 @@ abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPicturePr
|
|||
|
||||
@CallSuper
|
||||
override fun getCommandLine(): MutableList<String> = commandLineParams
|
||||
|
||||
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
|
||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode)
|
||||
godot?.onPictureInPictureModeChanged(isInPictureInPictureMode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if picture-in-picture (PiP) mode is supported.
|
||||
*/
|
||||
override fun isPiPModeSupported() = isPiPEnabled() && packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
|
||||
|
||||
/**
|
||||
* Returns true if the current activity has enabled picture-in-picture in its manifest declaration using
|
||||
* 'android:supportsPictureInPicture="true"'
|
||||
*/
|
||||
protected open fun isPiPEnabled() = false
|
||||
|
||||
internal fun updatePiPParams(enableAutoEnter: Boolean = autoEnterPiP.get(), aspectRatio: Rational? = pipAspectRatio.get()) {
|
||||
if (isPiPModeSupported()) {
|
||||
autoEnterPiP.set(enableAutoEnter)
|
||||
pipAspectRatio.set(aspectRatio)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val builder = PictureInPictureParams.Builder()
|
||||
.setSourceRectHint(gameViewSourceRectHint)
|
||||
.setAspectRatio(aspectRatio)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
builder.setSeamlessResizeEnabled(false)
|
||||
.setAutoEnterEnabled(enableAutoEnter)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
builder.setExpandedAspectRatio(aspectRatio)
|
||||
}
|
||||
setPictureInPictureParams(builder.build())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun enterPiPMode() {
|
||||
if (isPiPModeSupported()) {
|
||||
updatePiPParams()
|
||||
|
||||
Log.v(TAG, "Entering PiP mode")
|
||||
enterPictureInPictureMode()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUserLeaveHint() {
|
||||
if (autoEnterPiP.get()) {
|
||||
enterPiPMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -496,13 +496,6 @@ public class GodotFragment extends Fragment implements IDownloaderClient, GodotH
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDistractionFreeModeChanged(Boolean enabled) {
|
||||
if (parentHost != null) {
|
||||
parentHost.onDistractionFreeModeChanged(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuildProvider getBuildProvider() {
|
||||
if (parentHost != null) {
|
||||
|
|
|
|||
|
|
@ -153,11 +153,6 @@ public interface GodotHost {
|
|||
*/
|
||||
default void onEditorWorkspaceSelected(String workspace) {}
|
||||
|
||||
/**
|
||||
* Triggered when the editor's distraction-free mode changes.
|
||||
*/
|
||||
default void onDistractionFreeModeChanged(Boolean enabled) {}
|
||||
|
||||
/**
|
||||
* Runs the specified action on a host provided thread.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -192,14 +192,11 @@ public class GodotLib {
|
|||
/**
|
||||
* Used to get info about the current rendering system.
|
||||
*
|
||||
* @return A String array with three elements:
|
||||
* [0] Rendering driver name chosen for rendering.
|
||||
* [1] Rendering driver name chosen before any fallbacks were applied.
|
||||
* [2] Rendering method.
|
||||
* [3] Source where the rendering driver was chosen from.
|
||||
* [4] Source where the rendering method was chosen from.
|
||||
* @return A String array with two elements:
|
||||
* [0] Rendering driver name.
|
||||
* [1] Rendering method.
|
||||
*/
|
||||
public static native String[] getRendererInfo(boolean p_vulkan_requirements_met);
|
||||
public static native String[] getRendererInfo();
|
||||
|
||||
/**
|
||||
* Used to access Godot's editor settings.
|
||||
|
|
@ -302,7 +299,7 @@ public class GodotLib {
|
|||
* Invoked when the screen orientation changes.
|
||||
* @param orientation the new screen orientation
|
||||
*/
|
||||
static native void onOrientationChange(int orientation);
|
||||
static native void onScreenRotationChange(int orientation);
|
||||
|
||||
/**
|
||||
* @return true if input must be dispatched from the render thread. If false, input is
|
||||
|
|
@ -320,6 +317,4 @@ public class GodotLib {
|
|||
static native boolean isProjectManagerHint();
|
||||
|
||||
static native boolean hasFeature(String feature);
|
||||
|
||||
static native void onPictureInPictureModeChanged(boolean isInPictureInPictureMode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,4 @@ package org.godotengine.godot.editor.utils
|
|||
object EditorUtils {
|
||||
@JvmStatic
|
||||
external fun runScene(scene: String, sceneArgs: Array<String>)
|
||||
|
||||
@JvmStatic
|
||||
external fun toggleTitleBar(visible: Boolean)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
/**************************************************************************/
|
||||
/* PictureInPictureProvider.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.feature
|
||||
|
||||
/**
|
||||
* Provides APIs to enable picture-in-picture.
|
||||
*/
|
||||
interface PictureInPictureProvider {
|
||||
|
||||
fun enterPiPMode()
|
||||
|
||||
fun isPiPModeSupported(): Boolean
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ public class GodotEditText extends EditText {
|
|||
private final static int HANDLER_OPEN_IME_KEYBOARD = 2;
|
||||
private final static int HANDLER_CLOSE_IME_KEYBOARD = 3;
|
||||
|
||||
// Enum must be kept up-to-date with DisplayServerEnums::VirtualKeyboardType
|
||||
// Enum must be kept up-to-date with DisplayServer::VirtualKeyboardType
|
||||
public enum VirtualKeyboardType {
|
||||
KEYBOARD_TYPE_DEFAULT,
|
||||
KEYBOARD_TYPE_MULTILINE,
|
||||
|
|
|
|||
|
|
@ -57,11 +57,6 @@ internal class GodotGestureHandler(private val inputHandler: GodotInputHandler)
|
|||
|
||||
var scrollDeadzoneDisabled = false
|
||||
|
||||
/**
|
||||
* Enable haptic feedback on long-press right-click
|
||||
*/
|
||||
var hapticFeedbackEnabled = false
|
||||
|
||||
private var nextDownIsDoubleTap = false
|
||||
private var dragInProgress = false
|
||||
private var scaleInProgress = false
|
||||
|
|
@ -85,9 +80,6 @@ internal class GodotGestureHandler(private val inputHandler: GodotInputHandler)
|
|||
override fun onLongPress(event: MotionEvent) {
|
||||
val toolType = GodotInputHandler.getEventToolType(event)
|
||||
if (toolType != MotionEvent.TOOL_TYPE_MOUSE) {
|
||||
if (hapticFeedbackEnabled) {
|
||||
inputHandler.performHapticFeedback()
|
||||
}
|
||||
contextClickRouter(event)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ import android.util.Log;
|
|||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
|
@ -134,23 +133,6 @@ public class GodotInputHandler implements InputManager.InputDeviceListener, Sens
|
|||
this.godotGestureHandler.setScrollDeadzoneDisabled(disable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable haptic feedback (vibration) when a long-press right-click is triggered.
|
||||
*/
|
||||
public void enableHapticFeedback(boolean enable) {
|
||||
this.godotGestureHandler.setHapticFeedbackEnabled(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform haptic feedback on the render view.
|
||||
*/
|
||||
void performHapticFeedback() {
|
||||
GodotRenderView view = godot.getRenderView();
|
||||
if (view != null) {
|
||||
view.getView().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable multi-fingers pan & scale gestures. This is false by default.
|
||||
* <p>
|
||||
|
|
|
|||
|
|
@ -203,10 +203,8 @@ internal abstract class DataAccess {
|
|||
abstract fun write(buffer: ByteBuffer): Boolean
|
||||
|
||||
fun seekFromEnd(positionFromEnd: Long) {
|
||||
val positionFromBeginning = size() + positionFromEnd
|
||||
if (positionFromBeginning >= 0) {
|
||||
seek(positionFromBeginning)
|
||||
}
|
||||
val positionFromBeginning = max(0, size() - positionFromEnd)
|
||||
seek(positionFromBeginning)
|
||||
}
|
||||
|
||||
abstract class FileChannelDataAccess(private val filePath: String) : DataAccess() {
|
||||
|
|
|
|||
|
|
@ -32,13 +32,10 @@ package org.godotengine.godot.plugin
|
|||
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.annotation.Keep
|
||||
import androidx.core.net.toUri
|
||||
|
||||
import org.godotengine.godot.Godot
|
||||
import org.godotengine.godot.variant.Callable
|
||||
import java.lang.reflect.InvocationHandler
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
/**
|
||||
* Built-in Godot Android plugin used to provide access to the Android runtime capabilities.
|
||||
|
|
@ -46,76 +43,7 @@ import java.lang.reflect.Proxy
|
|||
* @see <a href="https://docs.godotengine.org/en/latest/tutorials/platform/android/javaclasswrapper_and_androidruntimeplugin.html">Integrating with Android APIs</a>
|
||||
*/
|
||||
class AndroidRuntimePlugin(godot: Godot) : GodotPlugin(godot) {
|
||||
|
||||
companion object {
|
||||
private val TAG = AndroidRuntimePlugin::class.java.simpleName
|
||||
|
||||
/**
|
||||
* Helper method used to generate Godot Proxy instances.
|
||||
*/
|
||||
@JvmStatic
|
||||
@Keep
|
||||
private fun generateProxyInstance(interfaces: Array<String>, invocationHandler: InvocationHandler): Any? {
|
||||
try {
|
||||
val interfaceClasses = interfaces.map { Class.forName(it) }.toTypedArray()
|
||||
|
||||
val proxy = Proxy.newProxyInstance(invocationHandler.javaClass.classLoader, interfaceClasses, invocationHandler)
|
||||
return proxy
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Error generating Godot proxy for interfaces ${interfaces.joinToString(",")}", e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method used to create [java.lang.reflect.Proxy] instance wrapping a given Godot [Callable].
|
||||
*
|
||||
* The [Proxy] instance is used to implement one SAM interface with the [Callable] serving as the delegate
|
||||
* implementation for the SAM interface overridden methods.
|
||||
*/
|
||||
@JvmStatic
|
||||
@Keep
|
||||
private fun createProxyFromGodotCallable(interfaceName: String, godotCallable: Callable): Any? {
|
||||
return generateProxyInstance(arrayOf(interfaceName)) { proxy, method, args ->
|
||||
when (method.name) {
|
||||
// We automatically handle 'toString', 'equals' and 'hashCode' to simplify the task of the caller
|
||||
// and provide consistency.
|
||||
"toString" -> "Godot Callable Proxy for $interfaceName"
|
||||
"equals" -> proxy == args[0]
|
||||
"hashCode" -> godotCallable.hashCode()
|
||||
|
||||
// Invocation for the interface single abstract method falls here and is dispatched to the
|
||||
// Godot [Callable].
|
||||
else -> godotCallable.call(*args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method used to create [java.lang.reflect.Proxy] instance wrapping a given Godot Object represented by
|
||||
* its ObjectID.
|
||||
*
|
||||
* The [Proxy] instance is used to implement one or multiple interfaces with the Object represented by
|
||||
* [godotObjectID] serving as the delegate implementation for the interface(s) overridden methods.
|
||||
*/
|
||||
@JvmStatic
|
||||
@Keep
|
||||
private fun createProxyFromGodotObjectID(godotObjectID: Long, interfaces: Array<String>): Any? {
|
||||
return generateProxyInstance(interfaces) { proxy, method, args ->
|
||||
when (val methodName = method.name) {
|
||||
// We automatically handle 'toString', 'equals' and 'hashCode' to simplify the task of the caller
|
||||
// and provide consistency.
|
||||
"toString" -> "Godot Object Proxy for ${interfaces.joinToString(",")}"
|
||||
"equals" -> proxy == args[0]
|
||||
"hashCode" -> godotObjectID
|
||||
|
||||
// Invocation for the remaining interface(s) methods falls here and is dispatched to the
|
||||
// Godot Object.
|
||||
else -> Callable.call(godotObjectID, methodName, *args)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private val TAG = AndroidRuntimePlugin::class.java.simpleName
|
||||
|
||||
override fun getPluginName() = "AndroidRuntime"
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ import java.util.Set;
|
|||
*/
|
||||
@Keep
|
||||
public class GodotTTS extends UtteranceProgressListener implements TextToSpeech.OnInitListener {
|
||||
// Note: These constants must be in sync with DisplayServerEnums::TTSUtteranceEvent enum from "servers/display/display_server.h".
|
||||
// Note: These constants must be in sync with DisplayServer::TTSUtteranceEvent enum from "servers/display/display_server.h".
|
||||
final private static int EVENT_START = 0;
|
||||
final private static int EVENT_END = 1;
|
||||
final private static int EVENT_CANCEL = 2;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ private val benchmarkTracker = Collections.synchronizedMap(LinkedHashMap<Pair<St
|
|||
* Note: Only enabled on 'editorDev' build variant.
|
||||
*/
|
||||
fun beginBenchmarkMeasure(scope: String, label: String) {
|
||||
if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "debug") {
|
||||
if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "dev") {
|
||||
return
|
||||
}
|
||||
val key = Pair(scope, label)
|
||||
|
|
@ -84,7 +84,7 @@ fun beginBenchmarkMeasure(scope: String, label: String) {
|
|||
*/
|
||||
@JvmOverloads
|
||||
fun endBenchmarkMeasure(scope: String, label: String, dumpBenchmark: Boolean = false) {
|
||||
if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "debug") {
|
||||
if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "dev") {
|
||||
return
|
||||
}
|
||||
val key = Pair(scope, label)
|
||||
|
|
@ -109,7 +109,7 @@ fun endBenchmarkMeasure(scope: String, label: String, dumpBenchmark: Boolean = f
|
|||
*/
|
||||
@JvmOverloads
|
||||
fun dumpBenchmark(fileAccessHandler: FileAccessHandler? = null, filepath: String? = benchmarkFile) {
|
||||
if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "debug") {
|
||||
if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "dev") {
|
||||
return
|
||||
}
|
||||
if (!useBenchmark || benchmarkTracker.isEmpty()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue