@@ -90,7 +90,7 @@ import java.util.concurrent.atomic.AtomicReference
90
90
* Can be hosted by [Activity], [Fragment] or [Service] android components, so long as its
91
91
* lifecycle methods are properly invoked.
92
92
*/
93
- class Godot (private val context : Context ) {
93
+ class Godot (val context : Context ) {
94
94
95
95
internal companion object {
96
96
private val TAG = Godot ::class .java.simpleName
@@ -177,7 +177,7 @@ class Godot(private val context: Context) {
177
177
*/
178
178
private val godotMainLoopStarted = AtomicBoolean (false )
179
179
180
- var io: GodotIO ? = null
180
+ val io = GodotIO ( this )
181
181
182
182
private var commandLine : MutableList <String > = ArrayList <String >()
183
183
private var xrMode = XRMode .REGULAR
@@ -187,7 +187,7 @@ class Godot(private val context: Context) {
187
187
private var useDebugOpengl = false
188
188
private var darkMode = false
189
189
190
- private var containerLayout: FrameLayout ? = null
190
+ internal var containerLayout: FrameLayout ? = null
191
191
var renderView: GodotRenderView ? = null
192
192
193
193
/* *
@@ -198,13 +198,12 @@ class Godot(private val context: Context) {
198
198
/* *
199
199
* Returns true if the engine has been initialized, false otherwise.
200
200
*/
201
- fun isInitialized () = initializationStarted && isNativeInitialized() && renderViewInitialized
201
+ fun isInitialized () = primaryHost != null && initializationStarted && isNativeInitialized() && renderViewInitialized
202
202
203
203
/* *
204
204
* Provides access to the primary host [Activity]
205
205
*/
206
206
fun getActivity () = primaryHost?.activity
207
- private fun requireActivity () = getActivity() ? : throw IllegalStateException (" Host activity must be non-null" )
208
207
209
208
/* *
210
209
* Start initialization of the Godot engine.
@@ -228,17 +227,13 @@ class Godot(private val context: Context) {
228
227
beginBenchmarkMeasure(" Startup" , " Godot::onCreate" )
229
228
try {
230
229
this .primaryHost = primaryHost
231
- val activity = requireActivity()
232
- val window = activity.window
233
- window.addFlags(WindowManager .LayoutParams .FLAG_TURN_SCREEN_ON )
234
230
235
231
Log .v(TAG , " Initializing Godot plugin registry" )
236
232
val runtimePlugins = mutableSetOf<GodotPlugin >(AndroidRuntimePlugin (this ))
237
233
runtimePlugins.addAll(primaryHost.getHostPlugins(this ))
238
234
GodotPluginRegistry .initializePluginRegistry(this , runtimePlugins)
239
- if (io == null ) {
240
- io = GodotIO (activity)
241
- }
235
+
236
+ getActivity()?.window?.addFlags(WindowManager .LayoutParams .FLAG_TURN_SCREEN_ON )
242
237
243
238
// check for apk expansion API
244
239
commandLine = getCommandLine()
@@ -264,7 +259,7 @@ class Godot(private val context: Context) {
264
259
i++
265
260
} else if (hasExtra && commandLine[i] == " --apk_expansion_key" ) {
266
261
mainPackKey = commandLine[i + 1 ]
267
- val prefs = activity .getSharedPreferences(
262
+ val prefs = context .getSharedPreferences(
268
263
" app_data_keys" ,
269
264
Context .MODE_PRIVATE
270
265
)
@@ -294,10 +289,10 @@ class Godot(private val context: Context) {
294
289
// Build the full path to the app's expansion files
295
290
try {
296
291
expansionPackPath = Helpers .getSaveFilePath(context)
297
- expansionPackPath + = " /main." + activity .packageManager.getPackageInfo(
298
- activity .packageName,
292
+ expansionPackPath + = " /main." + context .packageManager.getPackageInfo(
293
+ context .packageName,
299
294
0
300
- ).versionCode + " ." + activity .packageName + " .obb"
295
+ ).versionCode + " ." + context .packageName + " .obb"
301
296
} catch (e: java.lang.Exception ) {
302
297
Log .e(TAG , " Unable to build full path to the app's expansion files" , e)
303
298
}
@@ -408,12 +403,11 @@ class Godot(private val context: Context) {
408
403
commandLine.add(" --main-pack" )
409
404
commandLine.add(expansionPackPath)
410
405
}
411
- val activity = requireActivity()
412
406
if (! nativeLayerInitializeCompleted) {
413
407
nativeLayerInitializeCompleted = GodotLib .initialize(
414
- activity ,
408
+ getActivity() ,
415
409
this ,
416
- activity .assets,
410
+ context .assets,
417
411
io,
418
412
netUtils,
419
413
directoryAccessHandler,
@@ -451,7 +445,7 @@ class Godot(private val context: Context) {
451
445
* @throws IllegalStateException if [onInitNativeLayer] has not been called
452
446
*/
453
447
@JvmOverloads
454
- fun onInitRenderView (host : GodotHost , providedContainerLayout : FrameLayout = FrameLayout (host.activity )): FrameLayout ? {
448
+ fun onInitRenderView (host : GodotHost , providedContainerLayout : FrameLayout = FrameLayout (context )): FrameLayout ? {
455
449
if (! isNativeInitialized()) {
456
450
throw IllegalStateException (" onInitNativeLayer() must be invoked successfully prior to initializing the render view" )
457
451
}
@@ -460,7 +454,6 @@ class Godot(private val context: Context) {
460
454
461
455
beginBenchmarkMeasure(" Startup" , " Godot::onInitRenderView" )
462
456
try {
463
- val activity: Activity = host.activity
464
457
containerLayout = providedContainerLayout
465
458
containerLayout?.removeAllViews()
466
459
containerLayout?.layoutParams = ViewGroup .LayoutParams (
@@ -469,29 +462,29 @@ class Godot(private val context: Context) {
469
462
)
470
463
471
464
// GodotEditText layout
472
- val editText = GodotEditText (activity )
465
+ val editText = GodotEditText (context )
473
466
editText.layoutParams =
474
467
ViewGroup .LayoutParams (
475
468
ViewGroup .LayoutParams .MATCH_PARENT ,
476
- activity .resources.getDimension(R .dimen.text_edit_height).toInt()
469
+ context .resources.getDimension(R .dimen.text_edit_height).toInt()
477
470
)
478
471
// Prevent GodotEditText from showing on splash screen on devices with Android 14 or newer.
479
472
editText.setBackgroundColor(Color .TRANSPARENT )
480
473
// ...add to FrameLayout
481
474
containerLayout?.addView(editText)
482
475
renderView = if (usesVulkan()) {
483
- if (meetsVulkanRequirements(activity .packageManager)) {
484
- GodotVulkanRenderView (host, this , godotInputHandler)
476
+ if (meetsVulkanRequirements(context .packageManager)) {
477
+ GodotVulkanRenderView (this , godotInputHandler)
485
478
} else if (canFallbackToOpenGL()) {
486
479
// Fallback to OpenGl.
487
- GodotGLRenderView (host, this , godotInputHandler, xrMode, useDebugOpengl)
480
+ GodotGLRenderView (this , godotInputHandler, xrMode, useDebugOpengl)
488
481
} else {
489
- throw IllegalStateException (activity .getString(R .string.error_missing_vulkan_requirements_message))
482
+ throw IllegalStateException (context .getString(R .string.error_missing_vulkan_requirements_message))
490
483
}
491
484
492
485
} else {
493
486
// Fallback to OpenGl.
494
- GodotGLRenderView (host, this , godotInputHandler, xrMode, useDebugOpengl)
487
+ GodotGLRenderView (this , godotInputHandler, xrMode, useDebugOpengl)
495
488
}
496
489
497
490
if (host == primaryHost) {
@@ -509,20 +502,21 @@ class Godot(private val context: Context) {
509
502
}
510
503
511
504
editText.setView(renderView)
512
- io? .setEdit(editText)
505
+ io.setEdit(editText)
513
506
507
+ val activity = host.activity
514
508
// Listeners for keyboard height.
515
- val decorView = activity.window.decorView
509
+ val topView = activity? .window? .decorView ? : providedContainerLayout
516
510
// Report the height of virtual keyboard as it changes during the animation.
517
- ViewCompat .setWindowInsetsAnimationCallback(decorView , object : WindowInsetsAnimationCompat .Callback (DISPATCH_MODE_STOP ) {
511
+ ViewCompat .setWindowInsetsAnimationCallback(topView , object : WindowInsetsAnimationCompat .Callback (DISPATCH_MODE_STOP ) {
518
512
var startBottom = 0
519
513
var endBottom = 0
520
514
override fun onPrepare (animation : WindowInsetsAnimationCompat ) {
521
- startBottom = ViewCompat .getRootWindowInsets(decorView )?.getInsets(WindowInsetsCompat .Type .ime())?.bottom ? : 0
515
+ startBottom = ViewCompat .getRootWindowInsets(topView )?.getInsets(WindowInsetsCompat .Type .ime())?.bottom ? : 0
522
516
}
523
517
524
518
override fun onStart (animation : WindowInsetsAnimationCompat , bounds : WindowInsetsAnimationCompat .BoundsCompat ): WindowInsetsAnimationCompat .BoundsCompat {
525
- endBottom = ViewCompat .getRootWindowInsets(decorView )?.getInsets(WindowInsetsCompat .Type .ime())?.bottom ? : 0
519
+ endBottom = ViewCompat .getRootWindowInsets(topView )?.getInsets(WindowInsetsCompat .Type .ime())?.bottom ? : 0
526
520
return bounds
527
521
}
528
522
@@ -648,16 +642,17 @@ class Godot(private val context: Context) {
648
642
}
649
643
650
644
fun onDestroy (primaryHost : GodotHost ) {
651
- Log .v(TAG , " OnDestroy: $primaryHost " )
652
645
if (this .primaryHost != primaryHost) {
653
646
return
654
647
}
648
+ Log .v(TAG , " OnDestroy: $primaryHost " )
655
649
656
650
for (plugin in pluginRegistry.allPlugins) {
657
651
plugin.onMainDestroy()
658
652
}
659
653
660
654
renderView?.onActivityDestroyed()
655
+ this .primaryHost = null
661
656
}
662
657
663
658
/* *
@@ -776,16 +771,16 @@ class Godot(private val context: Context) {
776
771
@StringRes titleResId : Int ,
777
772
okCallback : Runnable ?
778
773
) {
779
- val res: Resources = getActivity()? .resources ? : return
774
+ val res: Resources = context .resources ? : return
780
775
alert(res.getString(messageResId), res.getString(titleResId), okCallback)
781
776
}
782
777
783
778
@JvmOverloads
784
779
@Keep
785
780
fun alert (message : String , title : String , okCallback : Runnable ? = null) {
786
- val activity : Activity = getActivity() ? : return
781
+ val context = getActivity() ? : context
787
782
runOnUiThread {
788
- val builder = AlertDialog .Builder (activity )
783
+ val builder = AlertDialog .Builder (context )
789
784
builder.setMessage(message).setTitle(title)
790
785
builder.setPositiveButton(
791
786
R .string.dialog_ok
@@ -814,8 +809,7 @@ class Godot(private val context: Context) {
814
809
* of the UI thread.
815
810
*/
816
811
fun runOnUiThread (action : Runnable ) {
817
- val activity: Activity = getActivity() ? : return
818
- activity.runOnUiThread(action)
812
+ primaryHost?.runOnHostThread(action)
819
813
}
820
814
821
815
/* *
@@ -968,8 +962,7 @@ class Godot(private val context: Context) {
968
962
@JvmOverloads
969
963
fun destroyAndKillProcess (destroyRunnable : Runnable ? = null) {
970
964
val host = primaryHost
971
- val activity = host?.activity
972
- if (host == null || activity == null ) {
965
+ if (host == null ) {
973
966
// Run the destroyRunnable right away as we are about to force quit.
974
967
destroyRunnable?.run ()
975
968
@@ -1038,7 +1031,7 @@ class Godot(private val context: Context) {
1038
1031
1039
1032
private fun getCommandLine (): MutableList <String > {
1040
1033
val commandLine = try {
1041
- commandLineFileParser.parseCommandLine(requireActivity() .assets.open(" _cl_" ))
1034
+ commandLineFileParser.parseCommandLine(context .assets.open(" _cl_" ))
1042
1035
} catch (ignored: Exception ) {
1043
1036
mutableListOf ()
1044
1037
}
@@ -1070,7 +1063,7 @@ class Godot(private val context: Context) {
1070
1063
}
1071
1064
1072
1065
fun getGrantedPermissions (): Array <String ?>? {
1073
- return PermissionsUtil .getGrantedPermissions(getActivity() )
1066
+ return PermissionsUtil .getGrantedPermissions(context )
1074
1067
}
1075
1068
1076
1069
/* *
0 commit comments