diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index e382f15b435..d626e209c20 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -583,6 +583,12 @@
Default [InputEventAction] to move up in the UI.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
+
+ If [code]true[/code], key/touch/joystick events will be flushed just before every idle and physics frame.
+ If [code]false[/code], such events will be flushed only once per idle frame, between iterations of the engine.
+ Enabling this can greatly improve the responsiveness to input, specially in devices that need to run multiple physics frames per visible (idle) frame, because they can't run at the target frame rate.
+ [b]Note:[/b] Currently implemented only in Android.
+
If [code]true[/code], sends mouse input events when tapping or swiping on the touchscreen.
diff --git a/main/main.cpp b/main/main.cpp
index 5f6605f201c..0be70e53af4 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1413,6 +1413,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
InputDefault *id = Object::cast_to(Input::get_singleton());
if (id) {
+ agile_input_event_flushing = GLOBAL_DEF("input_devices/buffering/agile_event_flushing", false);
+
if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
if (!OS::get_singleton()->has_touchscreen_ui_hint()) {
//only if no touchscreen ui hint, set emulation
@@ -2045,6 +2047,8 @@ uint32_t Main::frames = 0;
uint32_t Main::frame = 0;
bool Main::force_redraw_requested = false;
int Main::iterating = 0;
+bool Main::agile_input_event_flushing = false;
+
bool Main::is_iterating() {
return iterating > 0;
}
@@ -2114,9 +2118,13 @@ bool Main::iteration() {
bool exit = false;
- Engine::get_singleton()->_in_physics = true;
-
for (int iters = 0; iters < advance.physics_steps; ++iters) {
+ if (InputDefault::get_singleton()->is_using_input_buffering() && agile_input_event_flushing) {
+ InputDefault::get_singleton()->flush_buffered_events();
+ }
+
+ Engine::get_singleton()->_in_physics = true;
+
uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();
PhysicsServer::get_singleton()->flush_queries();
@@ -2141,9 +2149,13 @@ bool Main::iteration() {
physics_process_ticks = MAX(physics_process_ticks, OS::get_singleton()->get_ticks_usec() - physics_begin); // keep the largest one for reference
physics_process_max = MAX(OS::get_singleton()->get_ticks_usec() - physics_begin, physics_process_max);
Engine::get_singleton()->_physics_frames++;
+
+ Engine::get_singleton()->_in_physics = false;
}
- Engine::get_singleton()->_in_physics = false;
+ if (InputDefault::get_singleton()->is_using_input_buffering() && agile_input_event_flushing) {
+ InputDefault::get_singleton()->flush_buffered_events();
+ }
uint64_t idle_begin = OS::get_singleton()->get_ticks_usec();
@@ -2218,7 +2230,7 @@ bool Main::iteration() {
iterating--;
// Needed for OSs using input buffering regardless accumulation (like Android)
- if (InputDefault::get_singleton()->is_using_input_buffering()) {
+ if (InputDefault::get_singleton()->is_using_input_buffering() && !agile_input_event_flushing) {
InputDefault::get_singleton()->flush_buffered_events();
}
diff --git a/main/main.h b/main/main.h
index 96b845bd7ec..14e15746317 100644
--- a/main/main.h
+++ b/main/main.h
@@ -42,6 +42,7 @@ class Main {
static uint32_t frame;
static bool force_redraw_requested;
static int iterating;
+ static bool agile_input_event_flushing;
public:
static bool is_project_manager();