diff options
| author | JosJuice <josjuice@gmail.com> | 2025-05-13 16:55:48 +0200 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2025-06-07 10:20:18 +0200 |
| commit | 4214cb6eb8828e319b90cfde6604cc36eb236f19 (patch) | |
| tree | 3f7d4c11764644351864b2e5ee772c295a7fffe8 /Source/Android/app/src/main/java | |
| parent | 903eafcf6521601c0a2dc882c3d37d0e5a32ccd6 (diff) | |
Android: Make input state changes observable
Diffstat (limited to 'Source/Android/app/src/main/java')
| -rw-r--r-- | Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt index 3bca59f7b7..d5945f2784 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt @@ -6,6 +6,7 @@ import android.content.Context import android.hardware.input.InputManager import android.os.Build import android.os.Handler +import android.os.Looper import android.os.VibrationEffect import android.os.Vibrator import android.os.VibratorManager @@ -13,8 +14,11 @@ import android.view.InputDevice import android.view.KeyEvent import android.view.MotionEvent import androidx.annotation.Keep +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import org.dolphinemu.dolphinemu.DolphinApplication import org.dolphinemu.dolphinemu.utils.LooperThread +import java.util.concurrent.atomic.AtomicBoolean /** * This class interfaces with the native ControllerInterface, @@ -24,6 +28,12 @@ object ControllerInterface { private var inputDeviceListener: InputDeviceListener? = null private lateinit var looperThread: LooperThread + private var inputStateUpdatePending = AtomicBoolean(false) + private val inputStateVersion = MutableLiveData(0) + + val inputStateChanged: LiveData<Int> + get() = inputStateVersion + /** * Activities which want to pass on inputs to native code * should call this in their own dispatchKeyEvent method. @@ -31,7 +41,13 @@ object ControllerInterface { * @return true if the emulator core seems to be interested in this event. * false if the event should be passed on to the default dispatchKeyEvent. */ - external fun dispatchKeyEvent(event: KeyEvent): Boolean + fun dispatchKeyEvent(event: KeyEvent): Boolean { + val result = dispatchKeyEventNative(event) + onInputStateChanged() + return result + } + + private external fun dispatchKeyEventNative(event: KeyEvent): Boolean /** * Activities which want to pass on inputs to native code @@ -40,7 +56,13 @@ object ControllerInterface { * @return true if the emulator core seems to be interested in this event. * false if the event should be passed on to the default dispatchGenericMotionEvent. */ - external fun dispatchGenericMotionEvent(event: MotionEvent): Boolean + fun dispatchGenericMotionEvent(event: MotionEvent): Boolean { + val result = dispatchGenericMotionEventNative(event) + onInputStateChanged() + return result + } + + private external fun dispatchGenericMotionEventNative(event: MotionEvent): Boolean /** * [DolphinSensorEventListener] calls this for each axis of a received SensorEvent. @@ -48,7 +70,13 @@ object ControllerInterface { * @return true if the emulator core seems to be interested in this event. * false if the sensor can be suspended to save battery. */ - external fun dispatchSensorEvent( + fun dispatchSensorEvent(deviceQualifier: String, axisName: String, value: Float): Boolean { + val result = dispatchSensorEventNative(deviceQualifier, axisName, value) + onInputStateChanged() + return result + } + + private external fun dispatchSensorEventNative( deviceQualifier: String, axisName: String, value: Float @@ -76,6 +104,19 @@ object ControllerInterface { external fun getDevice(deviceString: String): CoreDevice? + private fun onInputStateChanged() { + // When a single SensorEvent is dispatched, this method is likely to get called many times. + // For the sake of performance, let's batch input state updates so that observers only have + // to process one update. + if (!inputStateUpdatePending.getAndSet(true)) { + Handler(Looper.getMainLooper()).post { + if (inputStateUpdatePending.getAndSet(false)) { + inputStateVersion.value = inputStateVersion.value?.plus(1) + } + } + } + } + @Keep @JvmStatic private fun registerInputDeviceListener() { |
