Add input buffering framework

Input buffering is implicitly used by event accumulation, but this commit makes it more generic so it can be enabled for other uses.

For desktop OSs it's currently not feasible given main and UI threads are the same).
This commit is contained in:
Pedro J. Estébanez 2021-08-03 18:59:20 +02:00
parent 58a54f534e
commit 7be9c26e20
7 changed files with 37 additions and 18 deletions

View file

@ -136,7 +136,9 @@ public:
virtual int get_joy_axis_index_from_string(String p_axis) = 0;
virtual void parse_input_event(const Ref<InputEvent> &p_event) = 0;
virtual void flush_accumulated_events() = 0;
virtual void flush_buffered_events() = 0;
virtual bool is_using_input_buffering() = 0;
virtual void set_use_input_buffering(bool p_enable) = 0;
virtual void set_use_accumulated_input(bool p_enable) = 0;
Input();

View file

@ -696,31 +696,39 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!use_accumulated_input) {
if (use_accumulated_input) {
if (buffered_events.empty() || !buffered_events.back()->get()->accumulate(p_event)) {
buffered_events.push_back(p_event);
}
} else if (use_input_buffering) {
buffered_events.push_back(p_event);
} else {
_parse_input_event_impl(p_event, false);
return;
}
if (!accumulated_events.empty() && accumulated_events.back()->get()->accumulate(p_event)) {
return; //event was accumulated, exit
}
accumulated_events.push_back(p_event);
}
void InputDefault::flush_accumulated_events() {
void InputDefault::flush_buffered_events() {
_THREAD_SAFE_METHOD_
while (accumulated_events.front()) {
_parse_input_event_impl(accumulated_events.front()->get(), false);
accumulated_events.pop_front();
while (buffered_events.front()) {
_parse_input_event_impl(buffered_events.front()->get(), false);
buffered_events.pop_front();
}
}
bool InputDefault::is_using_input_buffering() {
return use_input_buffering;
}
void InputDefault::set_use_input_buffering(bool p_enable) {
use_input_buffering = p_enable;
}
void InputDefault::set_use_accumulated_input(bool p_enable) {
use_accumulated_input = p_enable;
}
void InputDefault::release_pressed_events() {
flush_accumulated_events(); // this is needed to release actions strengths
flush_buffered_events(); // this is needed to release actions strengths
keys_pressed.clear();
joy_buttons_pressed.clear();
@ -734,6 +742,7 @@ void InputDefault::release_pressed_events() {
}
InputDefault::InputDefault() {
use_input_buffering = false;
use_accumulated_input = false;
mouse_button_mask = 0;
emulate_touch_from_mouse = false;

View file

@ -205,7 +205,8 @@ private:
void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
List<Ref<InputEvent>> accumulated_events;
List<Ref<InputEvent>> buffered_events;
bool use_input_buffering;
bool use_accumulated_input;
protected:
@ -302,7 +303,9 @@ public:
String get_joy_guid_remapped(int p_device) const;
void set_fallback_mapping(String p_guid);
virtual void flush_accumulated_events();
virtual void flush_buffered_events();
virtual bool is_using_input_buffering();
virtual void set_use_input_buffering(bool p_enable);
virtual void set_use_accumulated_input(bool p_enable);
virtual void release_pressed_events();

View file

@ -2217,6 +2217,11 @@ bool Main::iteration() {
iterating--;
// Needed for OSs using input buffering regardless accumulation (like Android)
if (InputDefault::get_singleton()->is_using_input_buffering()) {
InputDefault::get_singleton()->flush_buffered_events();
}
if (fixed_fps != -1) {
return exit;
}

View file

@ -3159,7 +3159,7 @@ void OS_OSX::process_events() {
[autoreleasePool drain];
autoreleasePool = [[NSAutoreleasePool alloc] init];
input->flush_accumulated_events();
input->flush_buffered_events();
}
void OS_OSX::process_key_events() {

View file

@ -2529,7 +2529,7 @@ void OS_Windows::process_events() {
if (!drop_events) {
process_key_events();
input->flush_accumulated_events();
input->flush_buffered_events();
}
}

View file

@ -2904,7 +2904,7 @@ void OS_X11::process_xevents() {
*/
}
input->flush_accumulated_events();
input->flush_buffered_events();
}
MainLoop *OS_X11::get_main_loop() const {