|
@@ -63,7 +63,6 @@ import org.godotengine.godot.plugin.AndroidRuntimePlugin
|
|
import org.godotengine.godot.plugin.GodotPlugin
|
|
import org.godotengine.godot.plugin.GodotPlugin
|
|
import org.godotengine.godot.plugin.GodotPluginRegistry
|
|
import org.godotengine.godot.plugin.GodotPluginRegistry
|
|
import org.godotengine.godot.tts.GodotTTS
|
|
import org.godotengine.godot.tts.GodotTTS
|
|
-import org.godotengine.godot.utils.CommandLineFileParser
|
|
|
|
import org.godotengine.godot.utils.DialogUtils
|
|
import org.godotengine.godot.utils.DialogUtils
|
|
import org.godotengine.godot.utils.GodotNetUtils
|
|
import org.godotengine.godot.utils.GodotNetUtils
|
|
import org.godotengine.godot.utils.PermissionsUtil
|
|
import org.godotengine.godot.utils.PermissionsUtil
|
|
@@ -89,54 +88,51 @@ import java.util.concurrent.atomic.AtomicReference
|
|
* Can be hosted by [Activity], [Fragment] or [Service] android components, so long as its
|
|
* Can be hosted by [Activity], [Fragment] or [Service] android components, so long as its
|
|
* lifecycle methods are properly invoked.
|
|
* lifecycle methods are properly invoked.
|
|
*/
|
|
*/
|
|
-class Godot(private val context: Context) {
|
|
|
|
|
|
+class Godot private constructor(val context: Context) {
|
|
|
|
|
|
- internal companion object {
|
|
|
|
|
|
+ companion object {
|
|
private val TAG = Godot::class.java.simpleName
|
|
private val TAG = Godot::class.java.simpleName
|
|
|
|
|
|
|
|
+ @Volatile private var INSTANCE: Godot? = null
|
|
|
|
+
|
|
|
|
+ @JvmStatic
|
|
|
|
+ fun getInstance(context: Context): Godot {
|
|
|
|
+ return INSTANCE ?: synchronized(this) {
|
|
|
|
+ INSTANCE ?: Godot(context.applicationContext).also { INSTANCE = it }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
// Supported build flavors
|
|
// Supported build flavors
|
|
- const val EDITOR_FLAVOR = "editor"
|
|
|
|
- const val TEMPLATE_FLAVOR = "template"
|
|
|
|
|
|
+ private const val EDITOR_FLAVOR = "editor"
|
|
|
|
+ private const val TEMPLATE_FLAVOR = "template"
|
|
|
|
|
|
/**
|
|
/**
|
|
* @return true if this is an editor build, false if this is a template build
|
|
* @return true if this is an editor build, false if this is a template build
|
|
*/
|
|
*/
|
|
- fun isEditorBuild() = BuildConfig.FLAVOR == EDITOR_FLAVOR
|
|
|
|
|
|
+ internal fun isEditorBuild() = BuildConfig.FLAVOR == EDITOR_FLAVOR
|
|
}
|
|
}
|
|
|
|
|
|
- private val mSensorManager: SensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
|
|
|
- private val mClipboard: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
|
|
- private val vibratorService: Vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
|
|
|
-
|
|
|
|
- private val pluginRegistry: GodotPluginRegistry by lazy {
|
|
|
|
- GodotPluginRegistry.getPluginRegistry()
|
|
|
|
- }
|
|
|
|
|
|
+ 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() }
|
|
|
|
|
|
private val accelerometerEnabled = AtomicBoolean(false)
|
|
private val accelerometerEnabled = AtomicBoolean(false)
|
|
- private val mAccelerometer: Sensor? by lazy {
|
|
|
|
- mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
|
|
|
|
- }
|
|
|
|
|
|
+ private val mAccelerometer: Sensor? by lazy { mSensorManager?.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) }
|
|
|
|
|
|
private val gravityEnabled = AtomicBoolean(false)
|
|
private val gravityEnabled = AtomicBoolean(false)
|
|
- private val mGravity: Sensor? by lazy {
|
|
|
|
- mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
|
|
|
|
- }
|
|
|
|
|
|
+ private val mGravity: Sensor? by lazy { mSensorManager?.getDefaultSensor(Sensor.TYPE_GRAVITY) }
|
|
|
|
|
|
private val magnetometerEnabled = AtomicBoolean(false)
|
|
private val magnetometerEnabled = AtomicBoolean(false)
|
|
- private val mMagnetometer: Sensor? by lazy {
|
|
|
|
- mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)
|
|
|
|
- }
|
|
|
|
|
|
+ private val mMagnetometer: Sensor? by lazy { mSensorManager?.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) }
|
|
|
|
|
|
private val gyroscopeEnabled = AtomicBoolean(false)
|
|
private val gyroscopeEnabled = AtomicBoolean(false)
|
|
- private val mGyroscope: Sensor? by lazy {
|
|
|
|
- mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
|
|
|
|
- }
|
|
|
|
|
|
+ private val mGyroscope: Sensor? by lazy { mSensorManager?.getDefaultSensor(Sensor.TYPE_GYROSCOPE) }
|
|
|
|
|
|
val tts = GodotTTS(context)
|
|
val tts = GodotTTS(context)
|
|
val directoryAccessHandler = DirectoryAccessHandler(context)
|
|
val directoryAccessHandler = DirectoryAccessHandler(context)
|
|
val fileAccessHandler = FileAccessHandler(context)
|
|
val fileAccessHandler = FileAccessHandler(context)
|
|
val netUtils = GodotNetUtils(context)
|
|
val netUtils = GodotNetUtils(context)
|
|
- private val commandLineFileParser = CommandLineFileParser()
|
|
|
|
private val godotInputHandler = GodotInputHandler(context, this)
|
|
private val godotInputHandler = GodotInputHandler(context, this)
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -144,11 +140,6 @@ class Godot(private val context: Context) {
|
|
*/
|
|
*/
|
|
private val runOnTerminate = AtomicReference<Runnable>()
|
|
private val runOnTerminate = AtomicReference<Runnable>()
|
|
|
|
|
|
- /**
|
|
|
|
- * Tracks whether [onCreate] was completed successfully.
|
|
|
|
- */
|
|
|
|
- private var initializationStarted = false
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Tracks whether [GodotLib.initialize] was completed successfully.
|
|
* Tracks whether [GodotLib.initialize] was completed successfully.
|
|
*/
|
|
*/
|
|
@@ -176,17 +167,15 @@ class Godot(private val context: Context) {
|
|
*/
|
|
*/
|
|
private val godotMainLoopStarted = AtomicBoolean(false)
|
|
private val godotMainLoopStarted = AtomicBoolean(false)
|
|
|
|
|
|
- var io: GodotIO? = null
|
|
|
|
|
|
+ val io = GodotIO(this)
|
|
|
|
|
|
private var commandLine : MutableList<String> = ArrayList<String>()
|
|
private var commandLine : MutableList<String> = ArrayList<String>()
|
|
private var xrMode = XRMode.REGULAR
|
|
private var xrMode = XRMode.REGULAR
|
|
- private var expansionPackPath: String = ""
|
|
|
|
- private var useApkExpansion = false
|
|
|
|
private val useImmersive = AtomicBoolean(false)
|
|
private val useImmersive = AtomicBoolean(false)
|
|
private var useDebugOpengl = false
|
|
private var useDebugOpengl = false
|
|
private var darkMode = false
|
|
private var darkMode = false
|
|
|
|
|
|
- private var containerLayout: FrameLayout? = null
|
|
|
|
|
|
+ internal var containerLayout: FrameLayout? = null
|
|
var renderView: GodotRenderView? = null
|
|
var renderView: GodotRenderView? = null
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -197,52 +186,45 @@ class Godot(private val context: Context) {
|
|
/**
|
|
/**
|
|
* Returns true if the engine has been initialized, false otherwise.
|
|
* Returns true if the engine has been initialized, false otherwise.
|
|
*/
|
|
*/
|
|
- fun isInitialized() = initializationStarted && isNativeInitialized() && renderViewInitialized
|
|
|
|
|
|
+ fun isInitialized() = primaryHost != null && isNativeInitialized() && renderViewInitialized
|
|
|
|
|
|
/**
|
|
/**
|
|
* Provides access to the primary host [Activity]
|
|
* Provides access to the primary host [Activity]
|
|
*/
|
|
*/
|
|
fun getActivity() = primaryHost?.activity
|
|
fun getActivity() = primaryHost?.activity
|
|
- private fun requireActivity() = getActivity() ?: throw IllegalStateException("Host activity must be non-null")
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* Start initialization of the Godot engine.
|
|
* Start initialization of the Godot engine.
|
|
*
|
|
*
|
|
- * This must be followed by [onInitNativeLayer] and [onInitRenderView] in that order to complete
|
|
|
|
- * initialization of the engine.
|
|
|
|
|
|
+ * This must be followed by [onInitRenderView] to complete initialization of the engine.
|
|
|
|
+ *
|
|
|
|
+ * @return false if initialization of the native layer fails, true otherwise.
|
|
*
|
|
*
|
|
* @throws IllegalArgumentException exception if the specified expansion pack (if any)
|
|
* @throws IllegalArgumentException exception if the specified expansion pack (if any)
|
|
* is invalid.
|
|
* is invalid.
|
|
*/
|
|
*/
|
|
- fun onCreate(primaryHost: GodotHost) {
|
|
|
|
- if (this.primaryHost != null || initializationStarted) {
|
|
|
|
- Log.d(TAG, "OnCreate already invoked")
|
|
|
|
- return
|
|
|
|
|
|
+ fun initEngine(commandLineParams: List<String>, hostPlugins: Set<GodotPlugin>): Boolean {
|
|
|
|
+ if (isNativeInitialized()) {
|
|
|
|
+ Log.d(TAG, "Engine already initialized")
|
|
|
|
+ return true
|
|
}
|
|
}
|
|
|
|
|
|
- Log.v(TAG, "OnCreate: $primaryHost")
|
|
|
|
|
|
+ Log.v(TAG, "InitEngine with params: $commandLineParams")
|
|
|
|
|
|
darkMode = context.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
|
darkMode = context.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
|
|
|
|
|
- beginBenchmarkMeasure("Startup", "Godot::onCreate")
|
|
|
|
|
|
+ beginBenchmarkMeasure("Startup", "Godot::initEngine")
|
|
try {
|
|
try {
|
|
- this.primaryHost = primaryHost
|
|
|
|
- val activity = requireActivity()
|
|
|
|
- val window = activity.window
|
|
|
|
- window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
|
|
|
|
-
|
|
|
|
Log.v(TAG, "Initializing Godot plugin registry")
|
|
Log.v(TAG, "Initializing Godot plugin registry")
|
|
val runtimePlugins = mutableSetOf<GodotPlugin>(AndroidRuntimePlugin(this))
|
|
val runtimePlugins = mutableSetOf<GodotPlugin>(AndroidRuntimePlugin(this))
|
|
- runtimePlugins.addAll(primaryHost.getHostPlugins(this))
|
|
|
|
|
|
+ runtimePlugins.addAll(hostPlugins)
|
|
GodotPluginRegistry.initializePluginRegistry(this, runtimePlugins)
|
|
GodotPluginRegistry.initializePluginRegistry(this, runtimePlugins)
|
|
- if (io == null) {
|
|
|
|
- io = GodotIO(activity)
|
|
|
|
- }
|
|
|
|
|
|
|
|
// check for apk expansion API
|
|
// check for apk expansion API
|
|
- commandLine = getCommandLine()
|
|
|
|
|
|
+ commandLine.addAll(commandLineParams)
|
|
var mainPackMd5: String? = null
|
|
var mainPackMd5: String? = null
|
|
var mainPackKey: String? = null
|
|
var mainPackKey: String? = null
|
|
|
|
+ var useApkExpansion = false
|
|
val newArgs: MutableList<String> = ArrayList()
|
|
val newArgs: MutableList<String> = ArrayList()
|
|
var i = 0
|
|
var i = 0
|
|
while (i < commandLine.size) {
|
|
while (i < commandLine.size) {
|
|
@@ -263,7 +245,7 @@ class Godot(private val context: Context) {
|
|
i++
|
|
i++
|
|
} else if (hasExtra && commandLine[i] == "--apk_expansion_key") {
|
|
} else if (hasExtra && commandLine[i] == "--apk_expansion_key") {
|
|
mainPackKey = commandLine[i + 1]
|
|
mainPackKey = commandLine[i + 1]
|
|
- val prefs = activity.getSharedPreferences(
|
|
|
|
|
|
+ val prefs = context.getSharedPreferences(
|
|
"app_data_keys",
|
|
"app_data_keys",
|
|
Context.MODE_PRIVATE
|
|
Context.MODE_PRIVATE
|
|
)
|
|
)
|
|
@@ -288,15 +270,17 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
i++
|
|
i++
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ var expansionPackPath = ""
|
|
commandLine = if (newArgs.isEmpty()) { mutableListOf() } else { newArgs }
|
|
commandLine = if (newArgs.isEmpty()) { mutableListOf() } else { newArgs }
|
|
if (useApkExpansion && mainPackMd5 != null && mainPackKey != null) {
|
|
if (useApkExpansion && mainPackMd5 != null && mainPackKey != null) {
|
|
// Build the full path to the app's expansion files
|
|
// Build the full path to the app's expansion files
|
|
try {
|
|
try {
|
|
expansionPackPath = Helpers.getSaveFilePath(context)
|
|
expansionPackPath = Helpers.getSaveFilePath(context)
|
|
- expansionPackPath += "/main." + activity.packageManager.getPackageInfo(
|
|
|
|
- activity.packageName,
|
|
|
|
|
|
+ expansionPackPath += "/main." + context.packageManager.getPackageInfo(
|
|
|
|
+ context.packageName,
|
|
0
|
|
0
|
|
- ).versionCode + "." + activity.packageName + ".obb"
|
|
|
|
|
|
+ ).versionCode + "." + context.packageName + ".obb"
|
|
} catch (e: java.lang.Exception) {
|
|
} catch (e: java.lang.Exception) {
|
|
Log.e(TAG, "Unable to build full path to the app's expansion files", e)
|
|
Log.e(TAG, "Unable to build full path to the app's expansion files", e)
|
|
}
|
|
}
|
|
@@ -317,15 +301,35 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- initializationStarted = true
|
|
|
|
- } catch (e: java.lang.Exception) {
|
|
|
|
- // Clear the primary host and rethrow
|
|
|
|
- this.primaryHost = null
|
|
|
|
- initializationStarted = false
|
|
|
|
- throw e
|
|
|
|
|
|
+ if (expansionPackPath.isNotEmpty()) {
|
|
|
|
+ commandLine.add("--main-pack")
|
|
|
|
+ commandLine.add(expansionPackPath)
|
|
|
|
+ }
|
|
|
|
+ if (!nativeLayerInitializeCompleted) {
|
|
|
|
+ nativeLayerInitializeCompleted = GodotLib.initialize(
|
|
|
|
+ this,
|
|
|
|
+ context.assets,
|
|
|
|
+ io,
|
|
|
|
+ netUtils,
|
|
|
|
+ directoryAccessHandler,
|
|
|
|
+ fileAccessHandler,
|
|
|
|
+ useApkExpansion,
|
|
|
|
+ )
|
|
|
|
+ Log.v(TAG, "Godot native layer initialization completed: $nativeLayerInitializeCompleted")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (nativeLayerInitializeCompleted && !nativeLayerSetupCompleted) {
|
|
|
|
+ nativeLayerSetupCompleted = GodotLib.setup(commandLine.toTypedArray(), tts)
|
|
|
|
+ if (!nativeLayerSetupCompleted) {
|
|
|
|
+ throw IllegalStateException("Unable to setup the Godot engine! Aborting...")
|
|
|
|
+ } else {
|
|
|
|
+ Log.v(TAG, "Godot native layer setup completed")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
} finally {
|
|
} finally {
|
|
- endBenchmarkMeasure("Startup", "Godot::onCreate")
|
|
|
|
|
|
+ endBenchmarkMeasure("Startup", "Godot::initEngine")
|
|
}
|
|
}
|
|
|
|
+ return isNativeInitialized()
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -368,7 +372,7 @@ class Godot(private val context: Context) {
|
|
*/
|
|
*/
|
|
@Keep
|
|
@Keep
|
|
private fun nativeEnableImmersiveMode(enabled: Boolean) {
|
|
private fun nativeEnableImmersiveMode(enabled: Boolean) {
|
|
- runOnUiThread {
|
|
|
|
|
|
+ runOnHostThread {
|
|
enableImmersiveMode(enabled)
|
|
enableImmersiveMode(enabled)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -376,103 +380,51 @@ class Godot(private val context: Context) {
|
|
@Keep
|
|
@Keep
|
|
fun isInImmersiveMode() = useImmersive.get()
|
|
fun isInImmersiveMode() = useImmersive.get()
|
|
|
|
|
|
- /**
|
|
|
|
- * Initializes the native layer of the Godot engine.
|
|
|
|
- *
|
|
|
|
- * This must be preceded by [onCreate] and followed by [onInitRenderView] to complete
|
|
|
|
- * initialization of the engine.
|
|
|
|
- *
|
|
|
|
- * @return false if initialization of the native layer fails, true otherwise.
|
|
|
|
- *
|
|
|
|
- * @throws IllegalStateException if [onCreate] has not been called.
|
|
|
|
- */
|
|
|
|
- fun onInitNativeLayer(host: GodotHost): Boolean {
|
|
|
|
- if (!initializationStarted) {
|
|
|
|
- throw IllegalStateException("OnCreate must be invoked successfully prior to initializing the native layer")
|
|
|
|
- }
|
|
|
|
- if (isNativeInitialized()) {
|
|
|
|
- Log.d(TAG, "OnInitNativeLayer already invoked")
|
|
|
|
- return true
|
|
|
|
- }
|
|
|
|
- if (host != primaryHost) {
|
|
|
|
- Log.e(TAG, "Native initialization is only supported for the primary host")
|
|
|
|
- return false
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Log.v(TAG, "OnInitNativeLayer: $host")
|
|
|
|
-
|
|
|
|
- beginBenchmarkMeasure("Startup", "Godot::onInitNativeLayer")
|
|
|
|
- try {
|
|
|
|
- if (expansionPackPath.isNotEmpty()) {
|
|
|
|
- commandLine.add("--main-pack")
|
|
|
|
- commandLine.add(expansionPackPath)
|
|
|
|
- }
|
|
|
|
- val activity = requireActivity()
|
|
|
|
- if (!nativeLayerInitializeCompleted) {
|
|
|
|
- nativeLayerInitializeCompleted = GodotLib.initialize(
|
|
|
|
- activity,
|
|
|
|
- this,
|
|
|
|
- activity.assets,
|
|
|
|
- io,
|
|
|
|
- netUtils,
|
|
|
|
- directoryAccessHandler,
|
|
|
|
- fileAccessHandler,
|
|
|
|
- useApkExpansion,
|
|
|
|
- )
|
|
|
|
- Log.v(TAG, "Godot native layer initialization completed: $nativeLayerInitializeCompleted")
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (nativeLayerInitializeCompleted && !nativeLayerSetupCompleted) {
|
|
|
|
- nativeLayerSetupCompleted = GodotLib.setup(commandLine.toTypedArray(), tts)
|
|
|
|
- if (!nativeLayerSetupCompleted) {
|
|
|
|
- throw IllegalStateException("Unable to setup the Godot engine! Aborting...")
|
|
|
|
- } else {
|
|
|
|
- Log.v(TAG, "Godot native layer setup completed")
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } finally {
|
|
|
|
- endBenchmarkMeasure("Startup", "Godot::onInitNativeLayer")
|
|
|
|
- }
|
|
|
|
- return isNativeInitialized()
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Used to complete initialization of the view used by the engine for rendering.
|
|
* Used to complete initialization of the view used by the engine for rendering.
|
|
*
|
|
*
|
|
- * This must be preceded by [onCreate] and [onInitNativeLayer] in that order to properly
|
|
|
|
- * initialize the engine.
|
|
|
|
|
|
+ * This must be preceded by [initEngine] to properly initialize the engine.
|
|
*
|
|
*
|
|
* @param host The [GodotHost] that's initializing the render views
|
|
* @param host The [GodotHost] that's initializing the render views
|
|
* @param providedContainerLayout Optional argument; if provided, this is reused to host the Godot's render views
|
|
* @param providedContainerLayout Optional argument; if provided, this is reused to host the Godot's render views
|
|
*
|
|
*
|
|
* @return A [FrameLayout] instance containing Godot's render views if initialization is successful, null otherwise.
|
|
* @return A [FrameLayout] instance containing Godot's render views if initialization is successful, null otherwise.
|
|
*
|
|
*
|
|
- * @throws IllegalStateException if [onInitNativeLayer] has not been called
|
|
|
|
|
|
+ * @throws IllegalStateException if [initEngine] has not been called
|
|
*/
|
|
*/
|
|
@JvmOverloads
|
|
@JvmOverloads
|
|
- fun onInitRenderView(host: GodotHost, providedContainerLayout: FrameLayout = FrameLayout(host.activity)): FrameLayout? {
|
|
|
|
|
|
+ fun onInitRenderView(host: GodotHost, providedContainerLayout: FrameLayout = FrameLayout(context)): FrameLayout? {
|
|
if (!isNativeInitialized()) {
|
|
if (!isNativeInitialized()) {
|
|
- throw IllegalStateException("onInitNativeLayer() must be invoked successfully prior to initializing the render view")
|
|
|
|
|
|
+ throw IllegalStateException("initEngine(...) must be invoked successfully prior to initializing the render view")
|
|
}
|
|
}
|
|
|
|
|
|
- Log.v(TAG, "OnInitRenderView: $host")
|
|
|
|
-
|
|
|
|
beginBenchmarkMeasure("Startup", "Godot::onInitRenderView")
|
|
beginBenchmarkMeasure("Startup", "Godot::onInitRenderView")
|
|
|
|
+ Log.v(TAG, "OnInitRenderView: $host")
|
|
try {
|
|
try {
|
|
- val activity: Activity = host.activity
|
|
|
|
|
|
+ this.primaryHost = host
|
|
|
|
+ getActivity()?.window?.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
|
|
|
|
+
|
|
|
|
+ if (containerLayout != null) {
|
|
|
|
+ assert(renderViewInitialized)
|
|
|
|
+ return containerLayout
|
|
|
|
+ }
|
|
|
|
+
|
|
containerLayout = providedContainerLayout
|
|
containerLayout = providedContainerLayout
|
|
containerLayout?.removeAllViews()
|
|
containerLayout?.removeAllViews()
|
|
- containerLayout?.layoutParams = ViewGroup.LayoutParams(
|
|
|
|
|
|
+ val layoutParams = containerLayout?.layoutParams ?: ViewGroup.LayoutParams(
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.MATCH_PARENT
|
|
ViewGroup.LayoutParams.MATCH_PARENT
|
|
)
|
|
)
|
|
|
|
+ layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
|
|
|
+ layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
|
|
|
|
+ containerLayout?.layoutParams = layoutParams
|
|
|
|
|
|
// GodotEditText layout
|
|
// GodotEditText layout
|
|
- val editText = GodotEditText(activity)
|
|
|
|
|
|
+ val editText = GodotEditText(context)
|
|
editText.layoutParams =
|
|
editText.layoutParams =
|
|
ViewGroup.LayoutParams(
|
|
ViewGroup.LayoutParams(
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
- activity.resources.getDimension(R.dimen.text_edit_height).toInt()
|
|
|
|
|
|
+ context.resources.getDimension(R.dimen.text_edit_height).toInt()
|
|
)
|
|
)
|
|
// Prevent GodotEditText from showing on splash screen on devices with Android 14 or newer.
|
|
// Prevent GodotEditText from showing on splash screen on devices with Android 14 or newer.
|
|
editText.setBackgroundColor(Color.TRANSPARENT)
|
|
editText.setBackgroundColor(Color.TRANSPARENT)
|
|
@@ -484,25 +436,22 @@ class Godot(private val context: Context) {
|
|
!isProjectManagerHint() && !isEditorHint() && java.lang.Boolean.parseBoolean(GodotLib.getGlobal("display/window/per_pixel_transparency/allowed"))
|
|
!isProjectManagerHint() && !isEditorHint() && java.lang.Boolean.parseBoolean(GodotLib.getGlobal("display/window/per_pixel_transparency/allowed"))
|
|
Log.d(TAG, "Render view should be transparent: $shouldBeTransparent")
|
|
Log.d(TAG, "Render view should be transparent: $shouldBeTransparent")
|
|
renderView = if (usesVulkan()) {
|
|
renderView = if (usesVulkan()) {
|
|
- if (meetsVulkanRequirements(activity.packageManager)) {
|
|
|
|
- GodotVulkanRenderView(host, this, godotInputHandler, shouldBeTransparent)
|
|
|
|
|
|
+ if (meetsVulkanRequirements(context.packageManager)) {
|
|
|
|
+ GodotVulkanRenderView(this, godotInputHandler, shouldBeTransparent)
|
|
} else if (canFallbackToOpenGL()) {
|
|
} else if (canFallbackToOpenGL()) {
|
|
// Fallback to OpenGl.
|
|
// Fallback to OpenGl.
|
|
- GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
|
|
|
|
|
|
+ GodotGLRenderView(this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
|
|
} else {
|
|
} else {
|
|
- throw IllegalStateException(activity.getString(R.string.error_missing_vulkan_requirements_message))
|
|
|
|
|
|
+ throw IllegalStateException(context.getString(R.string.error_missing_vulkan_requirements_message))
|
|
}
|
|
}
|
|
|
|
|
|
} else {
|
|
} else {
|
|
// Fallback to OpenGl.
|
|
// Fallback to OpenGl.
|
|
- GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (host == primaryHost) {
|
|
|
|
- renderView?.startRenderer()
|
|
|
|
|
|
+ GodotGLRenderView(this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
|
|
}
|
|
}
|
|
|
|
|
|
renderView?.let {
|
|
renderView?.let {
|
|
|
|
+ it.startRenderer()
|
|
containerLayout?.addView(
|
|
containerLayout?.addView(
|
|
it.view,
|
|
it.view,
|
|
ViewGroup.LayoutParams(
|
|
ViewGroup.LayoutParams(
|
|
@@ -513,20 +462,21 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
|
|
|
|
editText.setView(renderView)
|
|
editText.setView(renderView)
|
|
- io?.setEdit(editText)
|
|
|
|
|
|
+ io.setEdit(editText)
|
|
|
|
|
|
|
|
+ val activity = host.activity
|
|
// Listeners for keyboard height.
|
|
// Listeners for keyboard height.
|
|
- val decorView = activity.window.decorView
|
|
|
|
|
|
+ val topView = activity?.window?.decorView ?: providedContainerLayout
|
|
// Report the height of virtual keyboard as it changes during the animation.
|
|
// Report the height of virtual keyboard as it changes during the animation.
|
|
- ViewCompat.setWindowInsetsAnimationCallback(decorView, object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) {
|
|
|
|
|
|
+ ViewCompat.setWindowInsetsAnimationCallback(topView, object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) {
|
|
var startBottom = 0
|
|
var startBottom = 0
|
|
var endBottom = 0
|
|
var endBottom = 0
|
|
override fun onPrepare(animation: WindowInsetsAnimationCompat) {
|
|
override fun onPrepare(animation: WindowInsetsAnimationCompat) {
|
|
- startBottom = ViewCompat.getRootWindowInsets(decorView)?.getInsets(WindowInsetsCompat.Type.ime())?.bottom ?: 0
|
|
|
|
|
|
+ startBottom = ViewCompat.getRootWindowInsets(topView)?.getInsets(WindowInsetsCompat.Type.ime())?.bottom ?: 0
|
|
}
|
|
}
|
|
|
|
|
|
override fun onStart(animation: WindowInsetsAnimationCompat, bounds: WindowInsetsAnimationCompat.BoundsCompat): WindowInsetsAnimationCompat.BoundsCompat {
|
|
override fun onStart(animation: WindowInsetsAnimationCompat, bounds: WindowInsetsAnimationCompat.BoundsCompat): WindowInsetsAnimationCompat.BoundsCompat {
|
|
- endBottom = ViewCompat.getRootWindowInsets(decorView)?.getInsets(WindowInsetsCompat.Type.ime())?.bottom ?: 0
|
|
|
|
|
|
+ endBottom = ViewCompat.getRootWindowInsets(topView)?.getInsets(WindowInsetsCompat.Type.ime())?.bottom ?: 0
|
|
return bounds
|
|
return bounds
|
|
}
|
|
}
|
|
|
|
|
|
@@ -553,23 +503,21 @@ class Godot(private val context: Context) {
|
|
override fun onEnd(animation: WindowInsetsAnimationCompat) {}
|
|
override fun onEnd(animation: WindowInsetsAnimationCompat) {}
|
|
})
|
|
})
|
|
|
|
|
|
- if (host == primaryHost) {
|
|
|
|
- renderView?.queueOnRenderThread {
|
|
|
|
- for (plugin in pluginRegistry.allPlugins) {
|
|
|
|
- plugin.onRegisterPluginWithGodotNative()
|
|
|
|
- }
|
|
|
|
- setKeepScreenOn(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")))
|
|
|
|
|
|
+ renderView?.queueOnRenderThread {
|
|
|
|
+ for (plugin in pluginRegistry.allPlugins) {
|
|
|
|
+ plugin.onRegisterPluginWithGodotNative()
|
|
}
|
|
}
|
|
|
|
+ setKeepScreenOn(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")))
|
|
|
|
+ }
|
|
|
|
|
|
- // Include the returned non-null views in the Godot view hierarchy.
|
|
|
|
- for (plugin in pluginRegistry.allPlugins) {
|
|
|
|
- val pluginView = plugin.onMainCreate(activity)
|
|
|
|
- if (pluginView != null) {
|
|
|
|
- if (plugin.shouldBeOnTop()) {
|
|
|
|
- containerLayout?.addView(pluginView)
|
|
|
|
- } else {
|
|
|
|
- containerLayout?.addView(pluginView, 0)
|
|
|
|
- }
|
|
|
|
|
|
+ // Include the returned non-null views in the Godot view hierarchy.
|
|
|
|
+ for (plugin in pluginRegistry.allPlugins) {
|
|
|
|
+ val pluginView = plugin.onMainCreate(activity)
|
|
|
|
+ if (pluginView != null) {
|
|
|
|
+ if (plugin.shouldBeOnTop()) {
|
|
|
|
+ containerLayout?.addView(pluginView)
|
|
|
|
+ } else {
|
|
|
|
+ containerLayout?.addView(pluginView, 0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -615,16 +563,16 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
|
|
|
|
if (accelerometerEnabled.get() && mAccelerometer != null) {
|
|
if (accelerometerEnabled.get() && mAccelerometer != null) {
|
|
- mSensorManager.registerListener(godotInputHandler, mAccelerometer, SensorManager.SENSOR_DELAY_GAME)
|
|
|
|
|
|
+ mSensorManager?.registerListener(godotInputHandler, mAccelerometer, SensorManager.SENSOR_DELAY_GAME)
|
|
}
|
|
}
|
|
if (gravityEnabled.get() && mGravity != null) {
|
|
if (gravityEnabled.get() && mGravity != null) {
|
|
- mSensorManager.registerListener(godotInputHandler, mGravity, SensorManager.SENSOR_DELAY_GAME)
|
|
|
|
|
|
+ mSensorManager?.registerListener(godotInputHandler, mGravity, SensorManager.SENSOR_DELAY_GAME)
|
|
}
|
|
}
|
|
if (magnetometerEnabled.get() && mMagnetometer != null) {
|
|
if (magnetometerEnabled.get() && mMagnetometer != null) {
|
|
- mSensorManager.registerListener(godotInputHandler, mMagnetometer, SensorManager.SENSOR_DELAY_GAME)
|
|
|
|
|
|
+ mSensorManager?.registerListener(godotInputHandler, mMagnetometer, SensorManager.SENSOR_DELAY_GAME)
|
|
}
|
|
}
|
|
if (gyroscopeEnabled.get() && mGyroscope != null) {
|
|
if (gyroscopeEnabled.get() && mGyroscope != null) {
|
|
- mSensorManager.registerListener(godotInputHandler, mGyroscope, SensorManager.SENSOR_DELAY_GAME)
|
|
|
|
|
|
+ mSensorManager?.registerListener(godotInputHandler, mGyroscope, SensorManager.SENSOR_DELAY_GAME)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -636,7 +584,7 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
|
|
|
|
renderView?.onActivityPaused()
|
|
renderView?.onActivityPaused()
|
|
- mSensorManager.unregisterListener(godotInputHandler)
|
|
|
|
|
|
+ mSensorManager?.unregisterListener(godotInputHandler)
|
|
for (plugin in pluginRegistry.allPlugins) {
|
|
for (plugin in pluginRegistry.allPlugins) {
|
|
plugin.onMainPause()
|
|
plugin.onMainPause()
|
|
}
|
|
}
|
|
@@ -652,16 +600,17 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
|
|
|
|
fun onDestroy(primaryHost: GodotHost) {
|
|
fun onDestroy(primaryHost: GodotHost) {
|
|
- Log.v(TAG, "OnDestroy: $primaryHost")
|
|
|
|
if (this.primaryHost != primaryHost) {
|
|
if (this.primaryHost != primaryHost) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+ Log.v(TAG, "OnDestroy: $primaryHost")
|
|
|
|
|
|
for (plugin in pluginRegistry.allPlugins) {
|
|
for (plugin in pluginRegistry.allPlugins) {
|
|
plugin.onMainDestroy()
|
|
plugin.onMainDestroy()
|
|
}
|
|
}
|
|
|
|
|
|
renderView?.onActivityDestroyed()
|
|
renderView?.onActivityDestroyed()
|
|
|
|
+ this.primaryHost = null
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -721,7 +670,7 @@ class Godot(private val context: Context) {
|
|
val overrideVolumeButtons = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/override_volume_buttons"))
|
|
val overrideVolumeButtons = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/override_volume_buttons"))
|
|
val scrollDeadzoneDisabled = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/disable_scroll_deadzone"))
|
|
val scrollDeadzoneDisabled = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/disable_scroll_deadzone"))
|
|
|
|
|
|
- runOnUiThread {
|
|
|
|
|
|
+ runOnHostThread {
|
|
renderView?.inputHandler?.apply {
|
|
renderView?.inputHandler?.apply {
|
|
enableLongPress(longPressEnabled)
|
|
enableLongPress(longPressEnabled)
|
|
enablePanningAndScalingGestures(panScaleEnabled)
|
|
enablePanningAndScalingGestures(panScaleEnabled)
|
|
@@ -753,7 +702,7 @@ class Godot(private val context: Context) {
|
|
gyroscopeEnabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_gyroscope")))
|
|
gyroscopeEnabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_gyroscope")))
|
|
magnetometerEnabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_magnetometer")))
|
|
magnetometerEnabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_magnetometer")))
|
|
|
|
|
|
- runOnUiThread {
|
|
|
|
|
|
+ runOnHostThread {
|
|
registerSensorsIfNeeded()
|
|
registerSensorsIfNeeded()
|
|
enableImmersiveMode(useImmersive.get(), true)
|
|
enableImmersiveMode(useImmersive.get(), true)
|
|
}
|
|
}
|
|
@@ -782,15 +731,15 @@ class Godot(private val context: Context) {
|
|
@StringRes titleResId: Int,
|
|
@StringRes titleResId: Int,
|
|
okCallback: Runnable?
|
|
okCallback: Runnable?
|
|
) {
|
|
) {
|
|
- val res: Resources = getActivity()?.resources ?: return
|
|
|
|
|
|
+ val res: Resources = context.resources ?: return
|
|
alert(res.getString(messageResId), res.getString(titleResId), okCallback)
|
|
alert(res.getString(messageResId), res.getString(titleResId), okCallback)
|
|
}
|
|
}
|
|
|
|
|
|
@JvmOverloads
|
|
@JvmOverloads
|
|
@Keep
|
|
@Keep
|
|
fun alert(message: String, title: String, okCallback: Runnable? = null) {
|
|
fun alert(message: String, title: String, okCallback: Runnable? = null) {
|
|
- val activity: Activity = getActivity() ?: return
|
|
|
|
- runOnUiThread {
|
|
|
|
|
|
+ val activity = getActivity() ?: return
|
|
|
|
+ runOnHostThread {
|
|
val builder = AlertDialog.Builder(activity)
|
|
val builder = AlertDialog.Builder(activity)
|
|
builder.setMessage(message).setTitle(title)
|
|
builder.setMessage(message).setTitle(title)
|
|
builder.setPositiveButton(
|
|
builder.setPositiveButton(
|
|
@@ -814,14 +763,10 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Runs the specified action on the UI thread.
|
|
|
|
- * If the current thread is the UI thread, then the action is executed immediately.
|
|
|
|
- * If the current thread is not the UI thread, the action is posted to the event queue
|
|
|
|
- * of the UI thread.
|
|
|
|
|
|
+ * Runs the specified action on the host thread.
|
|
*/
|
|
*/
|
|
- fun runOnUiThread(action: Runnable) {
|
|
|
|
- val activity: Activity = getActivity() ?: return
|
|
|
|
- activity.runOnUiThread(action)
|
|
|
|
|
|
+ fun runOnHostThread(action: Runnable) {
|
|
|
|
+ primaryHost?.runOnHostThread(action)
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -838,7 +783,7 @@ class Godot(private val context: Context) {
|
|
var renderingDevice = rendererInfo[0]
|
|
var renderingDevice = rendererInfo[0]
|
|
var rendererSource = "ProjectSettings"
|
|
var rendererSource = "ProjectSettings"
|
|
var renderer = rendererInfo[1]
|
|
var renderer = rendererInfo[1]
|
|
- val cmdline = getCommandLine()
|
|
|
|
|
|
+ val cmdline = commandLine
|
|
var index = cmdline.indexOf("--rendering-method")
|
|
var index = cmdline.indexOf("--rendering-method")
|
|
if (index > -1 && cmdline.size > index + 1) {
|
|
if (index > -1 && cmdline.size > index + 1) {
|
|
rendererSource = "CommandLine"
|
|
rendererSource = "CommandLine"
|
|
@@ -880,7 +825,7 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
|
|
|
|
private fun setKeepScreenOn(enabled: Boolean) {
|
|
private fun setKeepScreenOn(enabled: Boolean) {
|
|
- runOnUiThread {
|
|
|
|
|
|
+ runOnHostThread {
|
|
if (enabled) {
|
|
if (enabled) {
|
|
getActivity()?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
getActivity()?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
} else {
|
|
} else {
|
|
@@ -905,19 +850,21 @@ class Godot(private val context: Context) {
|
|
return darkMode
|
|
return darkMode
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Keep
|
|
fun hasClipboard(): Boolean {
|
|
fun hasClipboard(): Boolean {
|
|
- return mClipboard.hasPrimaryClip()
|
|
|
|
|
|
+ return mClipboard?.hasPrimaryClip() == true
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Keep
|
|
fun getClipboard(): String {
|
|
fun getClipboard(): String {
|
|
- val clipData = mClipboard.primaryClip ?: return ""
|
|
|
|
|
|
+ val clipData = mClipboard?.primaryClip ?: return ""
|
|
val text = clipData.getItemAt(0).text ?: return ""
|
|
val text = clipData.getItemAt(0).text ?: return ""
|
|
return text.toString()
|
|
return text.toString()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Keep
|
|
fun setClipboard(text: String?) {
|
|
fun setClipboard(text: String?) {
|
|
- val clip = ClipData.newPlainText("myLabel", text)
|
|
|
|
- mClipboard.setPrimaryClip(clip)
|
|
|
|
|
|
+ mClipboard?.setPrimaryClip(ClipData.newPlainText("myLabel", text))
|
|
}
|
|
}
|
|
|
|
|
|
@Keep
|
|
@Keep
|
|
@@ -971,8 +918,7 @@ class Godot(private val context: Context) {
|
|
@JvmOverloads
|
|
@JvmOverloads
|
|
fun destroyAndKillProcess(destroyRunnable: Runnable? = null) {
|
|
fun destroyAndKillProcess(destroyRunnable: Runnable? = null) {
|
|
val host = primaryHost
|
|
val host = primaryHost
|
|
- val activity = host?.activity
|
|
|
|
- if (host == null || activity == null) {
|
|
|
|
|
|
+ if (host == null) {
|
|
// Run the destroyRunnable right away as we are about to force quit.
|
|
// Run the destroyRunnable right away as we are about to force quit.
|
|
destroyRunnable?.run()
|
|
destroyRunnable?.run()
|
|
|
|
|
|
@@ -984,7 +930,7 @@ class Godot(private val context: Context) {
|
|
// Store the destroyRunnable so it can be run when the engine is terminating
|
|
// Store the destroyRunnable so it can be run when the engine is terminating
|
|
runOnTerminate.set(destroyRunnable)
|
|
runOnTerminate.set(destroyRunnable)
|
|
|
|
|
|
- runOnUiThread {
|
|
|
|
|
|
+ runOnHostThread {
|
|
onDestroy(host)
|
|
onDestroy(host)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1019,14 +965,14 @@ class Godot(private val context: Context) {
|
|
try {
|
|
try {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
if (amplitude <= -1) {
|
|
if (amplitude <= -1) {
|
|
- vibratorService.vibrate(
|
|
|
|
|
|
+ vibratorService?.vibrate(
|
|
VibrationEffect.createOneShot(
|
|
VibrationEffect.createOneShot(
|
|
durationMs.toLong(),
|
|
durationMs.toLong(),
|
|
VibrationEffect.DEFAULT_AMPLITUDE
|
|
VibrationEffect.DEFAULT_AMPLITUDE
|
|
)
|
|
)
|
|
)
|
|
)
|
|
} else {
|
|
} else {
|
|
- vibratorService.vibrate(
|
|
|
|
|
|
+ vibratorService?.vibrate(
|
|
VibrationEffect.createOneShot(
|
|
VibrationEffect.createOneShot(
|
|
durationMs.toLong(),
|
|
durationMs.toLong(),
|
|
amplitude
|
|
amplitude
|
|
@@ -1035,7 +981,7 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
// deprecated in API 26
|
|
// deprecated in API 26
|
|
- vibratorService.vibrate(durationMs.toLong())
|
|
|
|
|
|
+ vibratorService?.vibrate(durationMs.toLong())
|
|
}
|
|
}
|
|
} catch (e: SecurityException) {
|
|
} 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.")
|
|
Log.w(TAG, "SecurityException: VIBRATE permission not found. Make sure it is declared in the manifest or enabled in the export preset.")
|
|
@@ -1043,21 +989,6 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private fun getCommandLine(): MutableList<String> {
|
|
|
|
- val commandLine = try {
|
|
|
|
- commandLineFileParser.parseCommandLine(requireActivity().assets.open("_cl_"))
|
|
|
|
- } catch (ignored: Exception) {
|
|
|
|
- mutableListOf()
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- val hostCommandLine = primaryHost?.commandLine
|
|
|
|
- if (!hostCommandLine.isNullOrEmpty()) {
|
|
|
|
- commandLine.addAll(hostCommandLine)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return commandLine
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Used by the native code (java_godot_wrapper.h) to access the input fallback mapping.
|
|
* 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.
|
|
* @return The input fallback mapping for the current XR mode.
|
|
@@ -1077,7 +1008,7 @@ class Godot(private val context: Context) {
|
|
}
|
|
}
|
|
|
|
|
|
fun getGrantedPermissions(): Array<String?>? {
|
|
fun getGrantedPermissions(): Array<String?>? {
|
|
- return PermissionsUtil.getGrantedPermissions(getActivity())
|
|
|
|
|
|
+ return PermissionsUtil.getGrantedPermissions(context)
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|