mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Android: Update advanced mapping dialog when devices change
Without this, there was a bug where if you turned the device's screen off and on again while in the advanced mapping dialog, the input indicators would stop updating. This is because turning the screen on again causes devices to refresh, which causes all devices to be recreated, leaving the AdvancedMappingControlViewHolders stuck referencing controls belonging to devices that are no longer being updated.
This commit is contained in:
@ -30,10 +30,14 @@ object ControllerInterface {
|
|||||||
|
|
||||||
private var inputStateUpdatePending = AtomicBoolean(false)
|
private var inputStateUpdatePending = AtomicBoolean(false)
|
||||||
private val inputStateVersion = MutableLiveData(0)
|
private val inputStateVersion = MutableLiveData(0)
|
||||||
|
private val devicesVersion = MutableLiveData(0)
|
||||||
|
|
||||||
val inputStateChanged: LiveData<Int>
|
val inputStateChanged: LiveData<Int>
|
||||||
get() = inputStateVersion
|
get() = inputStateVersion
|
||||||
|
|
||||||
|
val devicesChanged: LiveData<Int>
|
||||||
|
get() = devicesVersion
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activities which want to pass on inputs to native code
|
* Activities which want to pass on inputs to native code
|
||||||
* should call this in their own dispatchKeyEvent method.
|
* should call this in their own dispatchKeyEvent method.
|
||||||
@ -117,6 +121,14 @@ object ControllerInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
@JvmStatic
|
||||||
|
private fun onDevicesChanged() {
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
devicesVersion.value = devicesVersion.value?.plus(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
private fun registerInputDeviceListener() {
|
private fun registerInputDeviceListener() {
|
||||||
|
@ -25,7 +25,7 @@ class AdvancedMappingDialog(
|
|||||||
private val controlReference: ControlReference,
|
private val controlReference: ControlReference,
|
||||||
private val controller: EmulatedController
|
private val controller: EmulatedController
|
||||||
) : AlertDialog(context), OnItemClickListener {
|
) : AlertDialog(context), OnItemClickListener {
|
||||||
private val devices: Array<String> = ControllerInterface.getAllDeviceStrings()
|
private lateinit var devices: Array<String>
|
||||||
private val controlAdapter: AdvancedMappingControlAdapter
|
private val controlAdapter: AdvancedMappingControlAdapter
|
||||||
private lateinit var selectedDevice: String
|
private lateinit var selectedDevice: String
|
||||||
|
|
||||||
@ -36,10 +36,6 @@ class AdvancedMappingDialog(
|
|||||||
|
|
||||||
binding.dropdownDevice.onItemClickListener = this
|
binding.dropdownDevice.onItemClickListener = this
|
||||||
|
|
||||||
val deviceAdapter =
|
|
||||||
ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, devices)
|
|
||||||
binding.dropdownDevice.setAdapter(deviceAdapter)
|
|
||||||
|
|
||||||
controlAdapter = AdvancedMappingControlAdapter(lifecycle, controlReference.isInput()) {
|
controlAdapter = AdvancedMappingControlAdapter(lifecycle, controlReference.isInput()) {
|
||||||
control: String -> onControlClicked(control)
|
control: String -> onControlClicked(control)
|
||||||
}
|
}
|
||||||
@ -52,6 +48,12 @@ class AdvancedMappingDialog(
|
|||||||
|
|
||||||
binding.editExpression.setText(controlReference.getExpression())
|
binding.editExpression.setText(controlReference.getExpression())
|
||||||
|
|
||||||
|
ControllerInterface.devicesChanged.observe(this) {
|
||||||
|
onDevicesChanged()
|
||||||
|
setSelectedDevice(selectedDevice)
|
||||||
|
}
|
||||||
|
|
||||||
|
onDevicesChanged()
|
||||||
selectDefaultDevice()
|
selectDefaultDevice()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +74,13 @@ class AdvancedMappingDialog(
|
|||||||
return super.dispatchGenericMotionEvent(event)
|
return super.dispatchGenericMotionEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onDevicesChanged() {
|
||||||
|
devices = ControllerInterface.getAllDeviceStrings()
|
||||||
|
binding.dropdownDevice.setAdapter(
|
||||||
|
ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, devices)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setSelectedDevice(deviceString: String) {
|
private fun setSelectedDevice(deviceString: String) {
|
||||||
selectedDevice = deviceString
|
selectedDevice = deviceString
|
||||||
|
|
||||||
|
@ -442,6 +442,25 @@ std::shared_ptr<ciface::Core::Device> FindDevice(jint device_id)
|
|||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterDevicesChangedCallbackIfNeeded(JNIEnv* env, jclass controller_interface_class)
|
||||||
|
{
|
||||||
|
static bool registered = false;
|
||||||
|
if (registered)
|
||||||
|
return;
|
||||||
|
registered = true;
|
||||||
|
|
||||||
|
const jclass global_controller_interface_class =
|
||||||
|
reinterpret_cast<jclass>(env->NewGlobalRef(controller_interface_class));
|
||||||
|
const jmethodID controller_interface_on_devices_changed =
|
||||||
|
env->GetStaticMethodID(global_controller_interface_class, "onDevicesChanged", "()V");
|
||||||
|
|
||||||
|
g_controller_interface.RegisterDevicesChangedCallback(
|
||||||
|
[global_controller_interface_class, controller_interface_on_devices_changed] {
|
||||||
|
IDCache::GetEnvForThread()->CallStaticVoidMethod(global_controller_interface_class,
|
||||||
|
controller_interface_on_devices_changed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace ciface::Android
|
namespace ciface::Android
|
||||||
@ -903,6 +922,8 @@ InputBackend::InputBackend(ControllerInterface* controller_interface)
|
|||||||
|
|
||||||
env->CallStaticVoidMethod(s_controller_interface_class,
|
env->CallStaticVoidMethod(s_controller_interface_class,
|
||||||
s_controller_interface_register_input_device_listener);
|
s_controller_interface_register_input_device_listener);
|
||||||
|
|
||||||
|
RegisterDevicesChangedCallbackIfNeeded(env, s_controller_interface_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
InputBackend::~InputBackend()
|
InputBackend::~InputBackend()
|
||||||
|
Reference in New Issue
Block a user