From 53e237dfe4aa550fa52a1187d1b19e7b5ec555eb Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 31 Jan 2016 15:09:52 -0300 Subject: [PATCH] -Fix crash opening and closing the scene, closes #3491 --- scene/3d/camera.cpp | 23 +++++------------------ scene/main/viewport.cpp | 32 +++++++++++++++++++++++++++++++- scene/main/viewport.h | 6 +++++- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 3e78fef1471..01163e40e81 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -213,8 +213,7 @@ void Camera::_notification(int p_what) { case NOTIFICATION_ENTER_WORLD: { - bool first_camera = get_viewport()->cameras.size()==0; - get_viewport()->cameras.insert(this); + bool first_camera = get_viewport()->_camera_add(this); if (!get_tree()->is_node_being_edited(this) && (current || first_camera)) make_current(); @@ -236,7 +235,7 @@ void Camera::_notification(int p_what) { } } - get_viewport()->cameras.erase(this); + get_viewport()->_camera_remove(this); } break; @@ -304,7 +303,7 @@ void Camera::make_current() { if (!is_inside_tree()) return; - get_viewport()->_set_camera(this); + get_viewport()->_camera_set(this); //get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,camera_group,"_camera_make_current",this); } @@ -319,20 +318,8 @@ void Camera::clear_current() { return; if (get_viewport()->get_camera()==this) { - get_viewport()->_set_camera(NULL); - //a group is used beause this needs to be in order to be deterministic - - for (Set::Element *E=get_viewport()->cameras.front();E;E=E->next()) { - - if (this==E->get()) - continue; - if (!E->get()->is_inside_tree()) - continue; - if (get_viewport()->get_camera()!=NULL) - return; - - E->get()->make_current(); - } + get_viewport()->_camera_set(NULL); + get_viewport()->_camera_make_next_current(this); } } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index a1bfbda1fcf..7ed1882d778 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -855,7 +855,7 @@ void Viewport::_camera_transform_changed_notify() { #endif } -void Viewport::_set_camera(Camera* p_camera) { +void Viewport::_camera_set(Camera* p_camera) { #ifndef _3D_DISABLED @@ -880,6 +880,36 @@ void Viewport::_set_camera(Camera* p_camera) { #endif } +bool Viewport::_camera_add(Camera* p_camera) { + + cameras.insert(p_camera); + return cameras.size()==1; +} + +void Viewport::_camera_remove(Camera* p_camera) { + + cameras.erase(p_camera); + if (camera==p_camera) { + camera=NULL; + } +} + +void Viewport::_camera_make_next_current(Camera* p_exclude) { + + for(Set::Element *E=cameras.front();E;E=E->next()) { + + if (p_exclude==E->get()) + continue; + if (!E->get()->is_inside_tree()) + continue; + if (camera!=NULL) + return; + + E->get()->make_current(); + + } +} + void Viewport::set_transparent_background(bool p_enable) { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index cff729612e7..5bf7418ee93 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -264,7 +264,11 @@ friend class Control; friend class Camera; void _camera_transform_changed_notify(); - void _set_camera(Camera* p_camera); + void _camera_set(Camera* p_camera); + bool _camera_add(Camera* p_camera); //true if first + void _camera_remove(Camera* p_camera); + void _camera_make_next_current(Camera* p_exclude); + protected: void _notification(int p_what);