Skip to content

Commit 605b970

Browse files
committed
Fix create_instance in android GodotApp so non-editor apps can restart
Enables OS.create_instance(args) and OS.set_restart_on_exit(true, args) on android. Borrowed the logic from the editor, so it completely restarts the process so you can pass --rendering-method, --rendering-driver to switch between forward_plus, mobile, gl_compatibility etc on an exported app. Related: godotengine/godot-proposals#6423
1 parent 7b1ed52 commit 605b970

File tree

4 files changed

+79
-31
lines changed

4 files changed

+79
-31
lines changed

platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt

+8-26
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ abstract class BaseGodotEditor : GodotActivity() {
7171

7272
private const val WAIT_FOR_DEBUGGER = false
7373

74-
@JvmStatic
75-
protected val EXTRA_COMMAND_LINE_PARAMS = "command_line_params"
7674
@JvmStatic
7775
protected val EXTRA_PIP_AVAILABLE = "pip_available"
7876
@JvmStatic
@@ -130,7 +128,6 @@ abstract class BaseGodotEditor : GodotActivity() {
130128
}
131129

132130
private val editorMessageDispatcher = EditorMessageDispatcher(this)
133-
private val commandLineParams = ArrayList<String>()
134131
private val editorLoadingIndicator: View? by lazy { findViewById(R.id.editor_loading_indicator) }
135132

136133
override fun getGodotAppLayout() = R.layout.godot_editor_layout
@@ -183,10 +180,6 @@ abstract class BaseGodotEditor : GodotActivity() {
183180
// requested on demand based on use cases.
184181
PermissionsUtil.requestManifestPermissions(this, getExcludedPermissions())
185182

186-
val params = intent.getStringArrayExtra(EXTRA_COMMAND_LINE_PARAMS)
187-
Log.d(TAG, "Starting intent $intent with parameters ${params.contentToString()}")
188-
updateCommandLineParams(params?.asList() ?: emptyList())
189-
190183
editorMessageDispatcher.parseStartIntent(packageManager, intent)
191184

192185
if (BuildConfig.BUILD_TYPE == "dev" && WAIT_FOR_DEBUGGER) {
@@ -219,20 +212,16 @@ abstract class BaseGodotEditor : GodotActivity() {
219212
}
220213

221214
@CallSuper
222-
protected open fun updateCommandLineParams(args: List<String>) {
223-
// Update the list of command line params with the new args
224-
commandLineParams.clear()
225-
if (args.isNotEmpty()) {
226-
commandLineParams.addAll(args)
227-
}
228-
if (BuildConfig.BUILD_TYPE == "dev") {
229-
commandLineParams.add("--benchmark")
215+
protected override fun updateCommandLineParams(args: Array<String>) {
216+
val args = if (BuildConfig.BUILD_TYPE == "dev") {
217+
args + "--benchmark"
218+
} else {
219+
args
230220
}
221+
super.updateCommandLineParams(args);
231222
}
232223

233-
final override fun getCommandLine() = commandLineParams
234-
235-
protected fun retrieveEditorWindowInfo(args: Array<String>): EditorWindowInfo {
224+
protected open fun retrieveEditorWindowInfo(args: Array<String>): EditorWindowInfo {
236225
var hasEditor = false
237226
var xrMode = XR_MODE_DEFAULT
238227

@@ -335,14 +324,7 @@ abstract class BaseGodotEditor : GodotActivity() {
335324
val newInstance = getNewGodotInstanceIntent(editorWindowInfo, args)
336325
if (editorWindowInfo.windowClassName == javaClass.name) {
337326
Log.d(TAG, "Restarting ${editorWindowInfo.windowClassName} with parameters ${args.contentToString()}")
338-
val godot = godot
339-
if (godot != null) {
340-
godot.destroyAndKillProcess {
341-
ProcessPhoenix.triggerRebirth(this, activityOptions?.toBundle(), newInstance)
342-
}
343-
} else {
344-
ProcessPhoenix.triggerRebirth(this, activityOptions?.toBundle(), newInstance)
345-
}
327+
triggerRebirth(activityOptions?.toBundle(), newInstance)
346328
} else {
347329
Log.d(TAG, "Starting ${editorWindowInfo.windowClassName} with parameters ${args.contentToString()}")
348330
newInstance.putExtra(EXTRA_NEW_LAUNCH, true)

platform/android/java/editor/src/main/java/org/godotengine/editor/GodotXRGame.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ open class GodotXRGame: GodotGame() {
4040

4141
override fun overrideOrientationRequest() = true
4242

43-
override fun updateCommandLineParams(args: List<String>) {
43+
override fun updateCommandLineParams(args: Array<String>) {
4444
val updatedArgs = ArrayList<String>()
4545
if (!args.contains(XRMode.OPENXR.cmdLineArg)) {
4646
updatedArgs.add(XRMode.OPENXR.cmdLineArg)
@@ -51,7 +51,7 @@ open class GodotXRGame: GodotGame() {
5151
}
5252
updatedArgs.addAll(args)
5353

54-
super.updateCommandLineParams(updatedArgs)
54+
super.updateCommandLineParams(updatedArgs.toTypedArray())
5555
}
5656

5757
override fun getEditorWindowInfo() = XR_RUN_GAME_INFO

platform/android/java/lib/src/org/godotengine/godot/Godot.kt

+20-3
Original file line numberDiff line numberDiff line change
@@ -823,9 +823,26 @@ class Godot(private val context: Context) {
823823
* Returns true if `Vulkan` is used for rendering.
824824
*/
825825
private fun usesVulkan(): Boolean {
826-
val renderer = GodotLib.getGlobal("rendering/renderer/rendering_method")
827-
val renderingDevice = GodotLib.getGlobal("rendering/rendering_device/driver")
828-
return ("forward_plus" == renderer || "mobile" == renderer) && "vulkan" == renderingDevice
826+
var rendererSource = "ProjectSettings"
827+
var renderer = GodotLib.getGlobal("rendering/renderer/rendering_method")
828+
var renderingDeviceSource = "ProjectSettings"
829+
var renderingDevice = GodotLib.getGlobal("rendering/rendering_device/driver")
830+
val cmdline = getCommandLine()
831+
var index = cmdline.indexOf("--rendering-method")
832+
if (index > -1 && cmdline.size > index + 1) {
833+
rendererSource = "CommandLine"
834+
renderer = cmdline.get(index + 1)
835+
}
836+
index = cmdline.indexOf("--rendering-driver")
837+
if (index > -1 && cmdline.size > index + 1) {
838+
renderingDeviceSource = "CommandLine"
839+
renderingDevice = cmdline.get(index + 1)
840+
}
841+
val result = ("forward_plus" == renderer || "mobile" == renderer) && "vulkan" == renderingDevice
842+
Log.d(TAG, """usesVulkan(): ${result}
843+
renderingDevice: ${renderingDevice} (${renderingDeviceSource})
844+
renderer: ${renderer} (${rendererSource})""")
845+
return result
829846
}
830847

831848
/**

platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt

+49
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
package org.godotengine.godot
3232

3333
import android.app.Activity
34+
import android.content.ComponentName
3435
import android.content.Intent
3536
import android.content.pm.PackageManager
3637
import android.os.Bundle
@@ -52,18 +53,32 @@ abstract class GodotActivity : FragmentActivity(), GodotHost {
5253
companion object {
5354
private val TAG = GodotActivity::class.java.simpleName
5455

56+
@JvmStatic
57+
protected val EXTRA_COMMAND_LINE_PARAMS = "command_line_params"
58+
5559
@JvmStatic
5660
protected val EXTRA_NEW_LAUNCH = "new_launch_requested"
61+
62+
// This window must not match those in BaseGodotEditor.RUN_GAME_INFO etc
63+
@JvmStatic
64+
private final val DEFAULT_WINDOW_ID = 664;
5765
}
5866

67+
private val commandLineParams = ArrayList<String>()
5968
/**
6069
* Interaction with the [Godot] object is delegated to the [GodotFragment] class.
6170
*/
6271
protected var godotFragment: GodotFragment? = null
6372
private set
6473

74+
@CallSuper
6575
override fun onCreate(savedInstanceState: Bundle?) {
76+
val params = intent.getStringArrayExtra(EXTRA_COMMAND_LINE_PARAMS)
77+
Log.d(TAG, "Starting intent $intent with parameters ${params.contentToString()}")
78+
updateCommandLineParams(params ?: emptyArray())
79+
6680
super.onCreate(savedInstanceState)
81+
6782
setContentView(getGodotAppLayout())
6883

6984
handleStartIntent(intent, true)
@@ -79,6 +94,29 @@ abstract class GodotActivity : FragmentActivity(), GodotHost {
7994
}
8095
}
8196

97+
override fun onNewGodotInstanceRequested(args: Array<String>): Int {
98+
Log.d(TAG, "Restarting with parameters ${args.contentToString()}")
99+
val intent = Intent()
100+
.setComponent(ComponentName(this, javaClass.name))
101+
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
102+
.putExtra(EXTRA_COMMAND_LINE_PARAMS, args)
103+
triggerRebirth(null, intent)
104+
// fake 'process' id returned by create_instance() etc
105+
return DEFAULT_WINDOW_ID;
106+
}
107+
108+
protected fun triggerRebirth(bundle: Bundle?, intent: Intent) {
109+
// Launch a new activity
110+
val godot = godot
111+
if (godot != null) {
112+
godot.destroyAndKillProcess {
113+
ProcessPhoenix.triggerRebirth(this, bundle, intent)
114+
}
115+
} else {
116+
ProcessPhoenix.triggerRebirth(this, bundle, intent)
117+
}
118+
}
119+
82120
@LayoutRes
83121
protected open fun getGodotAppLayout() = R.layout.godot_app_layout
84122

@@ -176,4 +214,15 @@ abstract class GodotActivity : FragmentActivity(), GodotHost {
176214
protected open fun initGodotInstance(): GodotFragment {
177215
return GodotFragment()
178216
}
217+
218+
@CallSuper
219+
protected open fun updateCommandLineParams(args: Array<String>) {
220+
// Update the list of command line params with the new args
221+
commandLineParams.clear()
222+
if (args.isNotEmpty()) {
223+
commandLineParams.addAll(args)
224+
}
225+
}
226+
227+
final override fun getCommandLine() = commandLineParams
179228
}

0 commit comments

Comments
 (0)