From ea97ebc81775f328f4d5d8e1eee7783babbae934 Mon Sep 17 00:00:00 2001 From: GZharun Date: Tue, 31 Mar 2015 15:57:02 +0300 Subject: [PATCH] [Summary] Added cleanup for GUI properties when route is removed. [Details] This issue caused serious overhead when adding new routes after previous were removed. Also it resulted in garbage info saved in session file. [Reviewed by] PDavis, YPozdnyakov --- gtk2_ardour/automation_time_axis.cc | 1 + gtk2_ardour/axis_view.h | 8 ++++++ gtk2_ardour/gui_object.cc | 40 +++++++++++++++++++++++++++++ gtk2_ardour/gui_object.h | 6 ++++- gtk2_ardour/route_time_axis.cc | 3 +++ gtk2_ardour/route_ui.cc | 6 ++++- 6 files changed, 62 insertions(+), 2 deletions(-) diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index 1a99c0bc98..79f7c4bfcf 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -231,6 +231,7 @@ AutomationTimeAxisView::AutomationTimeAxisView ( AutomationTimeAxisView::~AutomationTimeAxisView () { + cleanup_gui_properties (); delete _view; } diff --git a/gtk2_ardour/axis_view.h b/gtk2_ardour/axis_view.h index 4ce76c92ce..51a48d3150 100644 --- a/gtk2_ardour/axis_view.h +++ b/gtk2_ardour/axis_view.h @@ -70,6 +70,14 @@ class AxisView : public virtual Selectable, public PBD::ScopedConnectionList, pu property_hashtable.emplace(property_name, s.str()); gui_object_state().set_property (state_id(), property_name, value); } + + void cleanup_gui_properties () + { + // remove related property node from the GUI state + gui_object_state().remove_node(state_id() ); + property_hashtable.clear (); + } + bool marked_for_display () const; virtual bool set_marked_for_display (bool); diff --git a/gtk2_ardour/gui_object.cc b/gtk2_ardour/gui_object.cc index 3e21f82fa4..bcc2fcdfa1 100644 --- a/gtk2_ardour/gui_object.cc +++ b/gtk2_ardour/gui_object.cc @@ -71,6 +71,46 @@ GUIObjectState::get_or_add_node (const string& id) return get_or_add_node (&_state, id); } +/** Remove property from the node with provided id. + * If there is no properties except the node id - remove the node. + * @param id property of Object node to look for. + * @param prop_name name of the Object property to remove. + * @return value of true if property is found, or false if not. + */ + +bool +GUIObjectState::remove_property (const std::string& id, const std::string& prop_name) +{ + XMLNode* child = get_node (&_state, id); + + if (!child) { + return false; + } + + XMLProperty* p = child->property (prop_name ); + if (!p) { + return false; + } + + child->remove_property (prop_name ); + + if (child->children().empty() && child->properties().size() == 1 && child->property (X_("id")) ) { + remove_node (id); + } + + return true; +} + +/** Remove node with provided id. + * @param id property of Object node to look for. +*/ + +void +GUIObjectState::remove_node (const std::string& id) +{ + _state.remove_nodes_and_delete(X_("id"), id ); +} + /** Get a string from our state. * @param id property of Object node to look for. * @param prop_name name of the Object property to return. diff --git a/gtk2_ardour/gui_object.h b/gtk2_ardour/gui_object.h index ee6d1cdf4c..9868ef9971 100644 --- a/gtk2_ardour/gui_object.h +++ b/gtk2_ardour/gui_object.h @@ -47,12 +47,16 @@ public: s << val; child->add_property (prop_name.c_str(), s.str()); } - + + bool remove_property (const std::string& id, const std::string& prop_name); + std::list all_ids () const; static XMLNode* get_node (const XMLNode *, const std::string &); XMLNode* get_or_add_node (const std::string &); static XMLNode* get_or_add_node (XMLNode *, const std::string &); + + void remove_node (const std::string& id); private: XMLNode _state; diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index e0ce6cde3f..d8cfd87e63 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -228,6 +228,9 @@ RouteTimeAxisView::set_route (boost::shared_ptr rt) RouteTimeAxisView::~RouteTimeAxisView () { + // must be handled before CatchDeletion (this) + cleanup_gui_properties (); + CatchDeletion (this); for (list::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) { diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 4631dca820..e9c3b022fb 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -102,9 +102,13 @@ RouteUI::RouteUI (ARDOUR::Session* sess, const std::string& layout_script_file) RouteUI::~RouteUI() { + // remove RouteUI property node from the GUI state + // must be handled before reseting _route + gui_object_state().remove_node(route_state_id() ); + _route.reset (); /* drop reference to route, so that it can be cleaned up */ route_connections.drop_connections (); - + delete solo_menu; delete mute_menu; delete sends_menu;