summaryrefslogtreecommitdiff
path: root/core/input/input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/input/input.cpp')
-rw-r--r--core/input/input.cpp34
1 files changed, 31 insertions, 3 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 3cf83fd64b..071d9ba648 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -533,6 +533,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
touch_event->set_pressed(mb->is_pressed());
touch_event->set_position(mb->get_position());
touch_event->set_double_tap(mb->is_double_click());
+ touch_event->set_device(InputEvent::DEVICE_ID_EMULATION);
event_dispatch_function(touch_event);
}
}
@@ -557,6 +558,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
drag_event->set_pen_inverted(mm->get_pen_inverted());
drag_event->set_pressure(mm->get_pressure());
drag_event->set_velocity(get_last_mouse_velocity());
+ drag_event->set_device(InputEvent::DEVICE_ID_EMULATION);
event_dispatch_function(drag_event);
}
@@ -592,7 +594,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
Ref<InputEventMouseButton> button_event;
button_event.instantiate();
- button_event->set_device(InputEvent::DEVICE_ID_TOUCH_MOUSE);
+ button_event->set_device(InputEvent::DEVICE_ID_EMULATION);
button_event->set_position(st->get_position());
button_event->set_global_position(st->get_position());
button_event->set_pressed(st->is_pressed());
@@ -623,7 +625,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
Ref<InputEventMouseMotion> motion_event;
motion_event.instantiate();
- motion_event->set_device(InputEvent::DEVICE_ID_TOUCH_MOUSE);
+ motion_event->set_device(InputEvent::DEVICE_ID_EMULATION);
motion_event->set_tilt(sd->get_tilt());
motion_event->set_pen_inverted(sd->get_pen_inverted());
motion_event->set_pressure(sd->get_pressure());
@@ -832,7 +834,7 @@ void Input::ensure_touch_mouse_raised() {
Ref<InputEventMouseButton> button_event;
button_event.instantiate();
- button_event->set_device(InputEvent::DEVICE_ID_TOUCH_MOUSE);
+ button_event->set_device(InputEvent::DEVICE_ID_EMULATION);
button_event->set_position(mouse_pos);
button_event->set_global_position(mouse_pos);
button_event->set_pressed(false);
@@ -869,6 +871,7 @@ void Input::set_default_cursor_shape(CursorShape p_shape) {
mm.instantiate();
mm->set_position(mouse_pos);
mm->set_global_position(mouse_pos);
+ mm->set_device(InputEvent::DEVICE_ID_INTERNAL);
parse_input_event(mm);
}
@@ -891,6 +894,31 @@ void Input::parse_input_event(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
+#ifdef DEBUG_ENABLED
+ uint64_t curr_frame = Engine::get_singleton()->get_process_frames();
+ if (curr_frame != last_parsed_frame) {
+ frame_parsed_events.clear();
+ last_parsed_frame = curr_frame;
+ frame_parsed_events.insert(p_event);
+ } else if (frame_parsed_events.has(p_event)) {
+ // It would be technically safe to send the same event in cases such as:
+ // - After an explicit flush.
+ // - In platforms using buffering when agile flushing is enabled, after one of the mid-frame flushes.
+ // - If platform doesn't use buffering and event accumulation is disabled.
+ // - If platform doesn't use buffering and the event type is not accumulable.
+ // However, it wouldn't be reasonable to ask users to remember the full ruleset and be aware at all times
+ // of the possibilities of the target platform, project settings and engine internals, which may change
+ // without prior notice.
+ // Therefore, the guideline is, "don't send the same event object more than once per frame".
+ WARN_PRINT_ONCE(
+ "An input event object is being parsed more than once in the same frame, which is unsafe.\n"
+ "If you are generating events in a script, you have to instantiate a new event instead of sending the same one more than once, unless the original one was sent on an earlier frame.\n"
+ "You can call duplicate() on the event to get a new instance with identical values.");
+ } else {
+ frame_parsed_events.insert(p_event);
+ }
+#endif
+
if (use_accumulated_input) {
if (buffered_events.is_empty() || !buffered_events.back()->get()->accumulate(p_event)) {
buffered_events.push_back(p_event);