2
0
Эх сурвалжийг харах

Merge pull request #81006 from KurtBliss/Chance-of-crash-when-Control-overrides-mouse-input-on-Area2D-#79371

Fix possible crash when Control overrides mouse input on Area2D
Rémi Verschelde 2 жил өмнө
parent
commit
8b8b6d1e87

+ 19 - 2
scene/main/viewport.cpp

@@ -2524,6 +2524,7 @@ void Viewport::_drop_physics_mouseover(bool p_paused_only) {
 
 
 void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference) {
 void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference) {
 	List<ObjectID> to_erase;
 	List<ObjectID> to_erase;
+	List<ObjectID> to_mouse_exit;
 
 
 	for (const KeyValue<ObjectID, uint64_t> &E : physics_2d_mouseover) {
 	for (const KeyValue<ObjectID, uint64_t> &E : physics_2d_mouseover) {
 		if (!p_clean_all_frames && E.value == p_frame_reference) {
 		if (!p_clean_all_frames && E.value == p_frame_reference) {
@@ -2537,7 +2538,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
 				if (p_clean_all_frames && p_paused_only && co->can_process()) {
 				if (p_clean_all_frames && p_paused_only && co->can_process()) {
 					continue;
 					continue;
 				}
 				}
-				co->_mouse_exit();
+				to_mouse_exit.push_back(E.key);
 			}
 			}
 		}
 		}
 		to_erase.push_back(E.key);
 		to_erase.push_back(E.key);
@@ -2550,6 +2551,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
 
 
 	// Per-shape.
 	// Per-shape.
 	List<Pair<ObjectID, int>> shapes_to_erase;
 	List<Pair<ObjectID, int>> shapes_to_erase;
+	List<Pair<ObjectID, int>> shapes_to_mouse_exit;
 
 
 	for (KeyValue<Pair<ObjectID, int>, uint64_t> &E : physics_2d_shape_mouseover) {
 	for (KeyValue<Pair<ObjectID, int>, uint64_t> &E : physics_2d_shape_mouseover) {
 		if (!p_clean_all_frames && E.value == p_frame_reference) {
 		if (!p_clean_all_frames && E.value == p_frame_reference) {
@@ -2563,7 +2565,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
 				if (p_clean_all_frames && p_paused_only && co->can_process()) {
 				if (p_clean_all_frames && p_paused_only && co->can_process()) {
 					continue;
 					continue;
 				}
 				}
-				co->_mouse_shape_exit(E.key.second);
+				shapes_to_mouse_exit.push_back(E.key);
 			}
 			}
 		}
 		}
 		shapes_to_erase.push_back(E.key);
 		shapes_to_erase.push_back(E.key);
@@ -2573,6 +2575,21 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
 		physics_2d_shape_mouseover.erase(shapes_to_erase.front()->get());
 		physics_2d_shape_mouseover.erase(shapes_to_erase.front()->get());
 		shapes_to_erase.pop_front();
 		shapes_to_erase.pop_front();
 	}
 	}
+
+	while (to_mouse_exit.size()) {
+		Object *o = ObjectDB::get_instance(to_mouse_exit.front()->get());
+		CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
+		co->_mouse_exit();
+		to_mouse_exit.pop_front();
+	}
+
+	while (shapes_to_mouse_exit.size()) {
+		Pair<ObjectID, int> e = shapes_to_mouse_exit.front()->get();
+		Object *o = ObjectDB::get_instance(e.first);
+		CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
+		co->_mouse_shape_exit(e.second);
+		shapes_to_mouse_exit.pop_front();
+	}
 }
 }
 
 
 void Viewport::_gui_grab_click_focus(Control *p_control) {
 void Viewport::_gui_grab_click_focus(Control *p_control) {