You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-11 13:10:58 +00:00
Use ?. (and ?.let) safe operators instead of !!
This PR prevents potential NPEs, and follows Kotlin conventions more closely by replacing the unsafe !! operator with safe ?. (or ?.let) (usually !! would only be used very rarely, and with a good reason - there is one place left in this PR where !! makes sense), and by replacing Java style 'if (x != null)' with Kotlin's '?.'
This commit is contained in:
@@ -396,16 +396,19 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (host == primaryHost) {
|
if (host == primaryHost) {
|
||||||
renderView!!.startRenderer()
|
renderView?.startRenderer()
|
||||||
}
|
}
|
||||||
val view: View = renderView!!.view
|
|
||||||
|
renderView?.let {
|
||||||
containerLayout?.addView(
|
containerLayout?.addView(
|
||||||
view,
|
it.view,
|
||||||
ViewGroup.LayoutParams(
|
ViewGroup.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
editText.setView(renderView)
|
editText.setView(renderView)
|
||||||
io?.setEdit(editText)
|
io?.setEdit(editText)
|
||||||
|
|
||||||
@@ -448,20 +451,23 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Infer the virtual keyboard height using visible area.
|
// Infer the virtual keyboard height using visible area.
|
||||||
view.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
|
renderView?.view?.viewTreeObserver?.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
|
||||||
// Don't allocate a new Rect every time the callback is called.
|
// Don't allocate a new Rect every time the callback is called.
|
||||||
val visibleSize = Rect()
|
val visibleSize = Rect()
|
||||||
override fun onGlobalLayout() {
|
override fun onGlobalLayout() {
|
||||||
val surfaceView = renderView!!.view
|
renderView?.let {
|
||||||
|
val surfaceView = it.view
|
||||||
|
|
||||||
surfaceView.getWindowVisibleDisplayFrame(visibleSize)
|
surfaceView.getWindowVisibleDisplayFrame(visibleSize)
|
||||||
val keyboardHeight = surfaceView.height - visibleSize.bottom
|
val keyboardHeight = surfaceView.height - visibleSize.bottom
|
||||||
GodotLib.setVirtualKeyboardHeight(keyboardHeight)
|
GodotLib.setVirtualKeyboardHeight(keyboardHeight)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host == primaryHost) {
|
if (host == primaryHost) {
|
||||||
renderView!!.queueOnRenderThread {
|
renderView?.queueOnRenderThread {
|
||||||
for (plugin in pluginRegistry.allPlugins) {
|
for (plugin in pluginRegistry.allPlugins) {
|
||||||
plugin.onRegisterPluginWithGodotNative()
|
plugin.onRegisterPluginWithGodotNative()
|
||||||
}
|
}
|
||||||
@@ -495,7 +501,7 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
renderView!!.onActivityStarted()
|
renderView?.onActivityStarted()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onResume(host: GodotHost) {
|
fun onResume(host: GodotHost) {
|
||||||
@@ -503,7 +509,7 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
renderView!!.onActivityResumed()
|
renderView?.onActivityResumed()
|
||||||
if (mAccelerometer != null) {
|
if (mAccelerometer != null) {
|
||||||
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME)
|
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME)
|
||||||
}
|
}
|
||||||
@@ -535,7 +541,7 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
renderView!!.onActivityPaused()
|
renderView?.onActivityPaused()
|
||||||
mSensorManager.unregisterListener(this)
|
mSensorManager.unregisterListener(this)
|
||||||
for (plugin in pluginRegistry.allPlugins) {
|
for (plugin in pluginRegistry.allPlugins) {
|
||||||
plugin.onMainPause()
|
plugin.onMainPause()
|
||||||
@@ -547,7 +553,7 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
renderView!!.onActivityStopped()
|
renderView?.onActivityStopped()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onDestroy(primaryHost: GodotHost) {
|
fun onDestroy(primaryHost: GodotHost) {
|
||||||
@@ -569,7 +575,7 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
* Configuration change callback
|
* Configuration change callback
|
||||||
*/
|
*/
|
||||||
fun onConfigurationChanged(newConfig: Configuration) {
|
fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
var newDarkMode = newConfig.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
val newDarkMode = newConfig.uiMode.and(Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
||||||
if (darkMode != newDarkMode) {
|
if (darkMode != newDarkMode) {
|
||||||
darkMode = newDarkMode
|
darkMode = newDarkMode
|
||||||
GodotLib.onNightModeChanged()
|
GodotLib.onNightModeChanged()
|
||||||
@@ -686,9 +692,7 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
* This must be called after the render thread has started.
|
* This must be called after the render thread has started.
|
||||||
*/
|
*/
|
||||||
fun runOnRenderThread(action: Runnable) {
|
fun runOnRenderThread(action: Runnable) {
|
||||||
if (renderView != null) {
|
renderView?.queueOnRenderThread(action)
|
||||||
renderView!!.queueOnRenderThread(action)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -765,7 +769,7 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
return mClipboard.hasPrimaryClip()
|
return mClipboard.hasPrimaryClip()
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
@@ -782,15 +786,14 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
private fun forceQuit(instanceId: Int): Boolean {
|
private fun forceQuit(instanceId: Int): Boolean {
|
||||||
if (primaryHost == null) {
|
primaryHost?.let {
|
||||||
return false
|
if (instanceId == 0) {
|
||||||
}
|
it.onGodotForceQuit(this)
|
||||||
return if (instanceId == 0) {
|
return true
|
||||||
primaryHost!!.onGodotForceQuit(this)
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
primaryHost!!.onGodotForceQuit(instanceId)
|
return it.onGodotForceQuit(instanceId)
|
||||||
}
|
}
|
||||||
|
} ?: return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onBackPressed(host: GodotHost) {
|
fun onBackPressed(host: GodotHost) {
|
||||||
@@ -804,14 +807,14 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
shouldQuit = false
|
shouldQuit = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shouldQuit && renderView != null) {
|
if (shouldQuit) {
|
||||||
renderView!!.queueOnRenderThread { GodotLib.back() }
|
renderView?.queueOnRenderThread { GodotLib.back() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRotatedValues(values: FloatArray?): FloatArray? {
|
private fun getRotatedValues(values: FloatArray?): FloatArray? {
|
||||||
if (values == null || values.size != 3) {
|
if (values == null || values.size != 3) {
|
||||||
return values
|
return null
|
||||||
}
|
}
|
||||||
val display =
|
val display =
|
||||||
(requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
|
(requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
|
||||||
@@ -848,39 +851,43 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
}
|
}
|
||||||
when (event.sensor.type) {
|
when (event.sensor.type) {
|
||||||
Sensor.TYPE_ACCELEROMETER -> {
|
Sensor.TYPE_ACCELEROMETER -> {
|
||||||
val rotatedValues = getRotatedValues(event.values)
|
getRotatedValues(event.values)?.let { rotatedValues ->
|
||||||
renderView!!.queueOnRenderThread {
|
renderView?.queueOnRenderThread {
|
||||||
GodotLib.accelerometer(
|
GodotLib.accelerometer(
|
||||||
-rotatedValues!![0], -rotatedValues[1], -rotatedValues[2]
|
-rotatedValues[0], -rotatedValues[1], -rotatedValues[2]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Sensor.TYPE_GRAVITY -> {
|
Sensor.TYPE_GRAVITY -> {
|
||||||
val rotatedValues = getRotatedValues(event.values)
|
getRotatedValues(event.values)?.let { rotatedValues ->
|
||||||
renderView!!.queueOnRenderThread {
|
renderView?.queueOnRenderThread {
|
||||||
GodotLib.gravity(
|
GodotLib.gravity(
|
||||||
-rotatedValues!![0], -rotatedValues[1], -rotatedValues[2]
|
-rotatedValues[0], -rotatedValues[1], -rotatedValues[2]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Sensor.TYPE_MAGNETIC_FIELD -> {
|
Sensor.TYPE_MAGNETIC_FIELD -> {
|
||||||
val rotatedValues = getRotatedValues(event.values)
|
getRotatedValues(event.values)?.let { rotatedValues ->
|
||||||
renderView!!.queueOnRenderThread {
|
renderView?.queueOnRenderThread {
|
||||||
GodotLib.magnetometer(
|
GodotLib.magnetometer(
|
||||||
-rotatedValues!![0], -rotatedValues[1], -rotatedValues[2]
|
-rotatedValues[0], -rotatedValues[1], -rotatedValues[2]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Sensor.TYPE_GYROSCOPE -> {
|
Sensor.TYPE_GYROSCOPE -> {
|
||||||
val rotatedValues = getRotatedValues(event.values)
|
getRotatedValues(event.values)?.let { rotatedValues ->
|
||||||
renderView!!.queueOnRenderThread {
|
renderView?.queueOnRenderThread {
|
||||||
GodotLib.gyroscope(
|
GodotLib.gyroscope(
|
||||||
rotatedValues!![0], rotatedValues[1], rotatedValues[2]
|
rotatedValues[0], rotatedValues[1], rotatedValues[2]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
|
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
|
||||||
|
|
||||||
@@ -1039,7 +1046,7 @@ class Godot(private val context: Context) : SensorEventListener {
|
|||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
private fun initInputDevices() {
|
private fun initInputDevices() {
|
||||||
renderView!!.initInputDevices()
|
renderView?.initInputDevices()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
|
|||||||
@@ -83,8 +83,9 @@ abstract class GodotActivity : FragmentActivity(), GodotHost {
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
Log.v(TAG, "Destroying Godot app...")
|
Log.v(TAG, "Destroying Godot app...")
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
if (godotFragment != null) {
|
|
||||||
terminateGodotInstance(godotFragment!!.godot)
|
godotFragment?.let {
|
||||||
|
terminateGodotInstance(it.godot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,15 +94,18 @@ abstract class GodotActivity : FragmentActivity(), GodotHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun terminateGodotInstance(instance: Godot) {
|
private fun terminateGodotInstance(instance: Godot) {
|
||||||
if (godotFragment != null && instance === godotFragment!!.godot) {
|
godotFragment?.let {
|
||||||
|
if (instance === it.godot) {
|
||||||
Log.v(TAG, "Force quitting Godot instance")
|
Log.v(TAG, "Force quitting Godot instance")
|
||||||
ProcessPhoenix.forceQuit(this)
|
ProcessPhoenix.forceQuit(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onGodotRestartRequested(instance: Godot) {
|
override fun onGodotRestartRequested(instance: Godot) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
if (godotFragment != null && instance === godotFragment!!.godot) {
|
godotFragment?.let {
|
||||||
|
if (instance === it.godot) {
|
||||||
// It's very hard to properly de-initialize Godot on Android to restart the game
|
// It's very hard to properly de-initialize Godot on Android to restart the game
|
||||||
// from scratch. Therefore, we need to kill the whole app process and relaunch it.
|
// from scratch. Therefore, we need to kill the whole app process and relaunch it.
|
||||||
//
|
//
|
||||||
@@ -112,6 +116,7 @@ abstract class GodotActivity : FragmentActivity(), GodotHost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onNewIntent(newIntent: Intent) {
|
override fun onNewIntent(newIntent: Intent) {
|
||||||
super.onNewIntent(newIntent)
|
super.onNewIntent(newIntent)
|
||||||
|
|||||||
@@ -56,7 +56,9 @@ class FileAccessHandler(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
DataAccess.fileExists(storageScope, context, path!!)
|
path?.let {
|
||||||
|
DataAccess.fileExists(storageScope, context, it)
|
||||||
|
} ?: false
|
||||||
} catch (e: SecurityException) {
|
} catch (e: SecurityException) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -69,20 +71,22 @@ class FileAccessHandler(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
DataAccess.removeFile(storageScope, context, path!!)
|
path?.let {
|
||||||
|
DataAccess.removeFile(storageScope, context, it)
|
||||||
|
} ?: false
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun renameFile(context: Context, storageScopeIdentifier: StorageScope.Identifier, from: String?, to: String?): Boolean {
|
internal fun renameFile(context: Context, storageScopeIdentifier: StorageScope.Identifier, from: String, to: String): Boolean {
|
||||||
val storageScope = storageScopeIdentifier.identifyStorageScope(from)
|
val storageScope = storageScopeIdentifier.identifyStorageScope(from)
|
||||||
if (storageScope == StorageScope.UNKNOWN) {
|
if (storageScope == StorageScope.UNKNOWN) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
DataAccess.renameFile(storageScope, context, from!!, to!!)
|
DataAccess.renameFile(storageScope, context, from, to)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -106,16 +110,18 @@ class FileAccessHandler(val context: Context) {
|
|||||||
return INVALID_FILE_ID
|
return INVALID_FILE_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return try {
|
||||||
val dataAccess = DataAccess.generateDataAccess(storageScope, context, path!!, accessFlag) ?: return INVALID_FILE_ID
|
path?.let {
|
||||||
|
val dataAccess = DataAccess.generateDataAccess(storageScope, context, it, accessFlag) ?: return INVALID_FILE_ID
|
||||||
|
|
||||||
files.put(++lastFileId, dataAccess)
|
files.put(++lastFileId, dataAccess)
|
||||||
return lastFileId
|
lastFileId
|
||||||
|
} ?: INVALID_FILE_ID
|
||||||
} catch (e: FileNotFoundException) {
|
} catch (e: FileNotFoundException) {
|
||||||
return FILE_NOT_FOUND_ERROR_ID
|
FILE_NOT_FOUND_ERROR_ID
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Error while opening $path", e)
|
Log.w(TAG, "Error while opening $path", e)
|
||||||
return INVALID_FILE_ID
|
INVALID_FILE_ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +182,9 @@ class FileAccessHandler(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
DataAccess.fileLastModified(storageScope, context, filepath!!)
|
filepath?.let {
|
||||||
|
DataAccess.fileLastModified(storageScope, context, it)
|
||||||
|
} ?: 0L
|
||||||
} catch (e: SecurityException) {
|
} catch (e: SecurityException) {
|
||||||
0L
|
0L
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user