[glom] Use std::weak_ptr instead of shared_ptr with sigc::bind().



commit bbfc6a20f7a92fca890fcd44a0c3af6edddcdf15
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Sep 30 09:01:51 2016 +0200

    Use std::weak_ptr instead of shared_ptr with sigc::bind().
    
    As suggested in Herb Sutter's 2016 CppCon talk, for parameters
    captured for lambdas:
    https://www.youtube.com/watch?v=JfmTagWcqoE
    
    I don't much like that this is a change in the signature of the handler,
    which isn't obvious from the code that connects the handler.

 glom/mode_data/box_data_details.cc      |   21 +++++++++++++++++----
 glom/mode_data/box_data_details.h       |    8 ++++----
 glom/mode_data/box_data_list.cc         |    9 +++++----
 glom/mode_data/box_data_list.h          |    2 +-
 glom/mode_data/box_data_list_related.cc |    3 ---
 glom/mode_data/flowtablewithfields.cc   |   27 +++++++++++++++++++++------
 glom/mode_data/flowtablewithfields.h    |   10 +++++-----
 glom/mode_find/box_data_details_find.cc |    2 +-
 glom/mode_find/box_data_details_find.h  |    2 +-
 9 files changed, 55 insertions(+), 29 deletions(-)
---
diff --git a/glom/mode_data/box_data_details.cc b/glom/mode_data/box_data_details.cc
index 77bafd6..cdd1c87 100644
--- a/glom/mode_data/box_data_details.cc
+++ b/glom/mode_data/box_data_details.cc
@@ -645,8 +645,12 @@ void Box_Data_Details::on_flowtable_related_record_changed(const Glib::ustring&
   recalculate_fields_for_related_records(relationship_name);
 }
 
-void Box_Data_Details::on_flowtable_field_open_details_requested(const std::shared_ptr<const 
LayoutItem_Field>& layout_field, const Gnome::Gda::Value& field_value)
+void Box_Data_Details::on_flowtable_field_open_details_requested(const std::weak_ptr<const 
LayoutItem_Field>& layout_field_weak, const Gnome::Gda::Value& field_value)
 {
+  const auto layout_field = layout_field_weak.lock();
+  if(!layout_field)
+    return;
+
   if(Conversions::value_is_empty(field_value))
     return; //Ignore empty ID fields.
 
@@ -677,8 +681,9 @@ void Box_Data_Details::on_flowtable_field_open_details_requested(const std::shar
   }
 }
 
-void Box_Data_Details::on_flowtable_script_button_clicked(const std::shared_ptr<const LayoutItem_Button>& 
layout_item)
+void Box_Data_Details::on_flowtable_script_button_clicked(const std::weak_ptr<const LayoutItem_Button>& 
layout_item_weak)
 {
+  const auto layout_item = layout_item_weak.lock();
   if(!layout_item)
   {
     std::cerr << G_STRFUNC << ": layout_item is null\n";
@@ -706,11 +711,15 @@ void Box_Data_Details::on_flowtable_script_button_clicked(const std::shared_ptr<
   }
 }
 
-void Box_Data_Details::on_flowtable_field_edited(const std::shared_ptr<const LayoutItem_Field>& 
layout_field, const Gnome::Gda::Value& field_value)
+void Box_Data_Details::on_flowtable_field_edited(const std::weak_ptr<const LayoutItem_Field>& 
layout_field_weak, const Gnome::Gda::Value& field_value)
 {
   if(m_ignore_signals)
     return;
 
+  const auto layout_field = layout_field_weak.lock();
+  if (!layout_field)
+    return;
+
   const auto strFieldName = layout_field->get_name();
 
   auto window = get_app_window();
@@ -896,11 +905,15 @@ void Box_Data_Details::on_flowtable_field_edited(const std::shared_ptr<const Lay
   } //if(get_primary_key_value_selected().size())
 }
 
-void Box_Data_Details::on_flowtable_field_choices_changed(const std::shared_ptr<const LayoutItem_Field>& 
layout_field)
+void Box_Data_Details::on_flowtable_field_choices_changed(const std::weak_ptr<const LayoutItem_Field>& 
layout_field_weak)
 {
   if(m_ignore_signals)
     return;
 
+  const auto layout_field = layout_field_weak.lock();
+  if (!layout_field)
+    return;
+
   m_FlowTable.update_choices(*layout_field);
 }
 
diff --git a/glom/mode_data/box_data_details.h b/glom/mode_data/box_data_details.h
index e10f75d..f6af984 100644
--- a/glom/mode_data/box_data_details.h
+++ b/glom/mode_data/box_data_details.h
@@ -119,14 +119,14 @@ protected:
   //void on_related_user_requested_details(Gnome::Gda::Value key_value, Glib::ustring table_name);
 
   //This is virtual so it can be overriden in Box_Data_Details_Find.
-  virtual void on_flowtable_field_edited(const std::shared_ptr<const LayoutItem_Field>& layout_field, const 
Gnome::Gda::Value& value);
+  virtual void on_flowtable_field_edited(const std::weak_ptr<const LayoutItem_Field>& layout_field_weak, 
const Gnome::Gda::Value& value);
 
-  void on_flowtable_field_choices_changed(const std::shared_ptr<const LayoutItem_Field>& layout_field);
-  void on_flowtable_field_open_details_requested(const std::shared_ptr<const LayoutItem_Field>& id, const 
Gnome::Gda::Value& value);
+  void on_flowtable_field_choices_changed(const std::weak_ptr<const LayoutItem_Field>& layout_field_weak);
+  void on_flowtable_field_open_details_requested(const std::weak_ptr<const LayoutItem_Field>& id_weak, const 
Gnome::Gda::Value& value);
   void on_flowtable_related_record_changed(const Glib::ustring& relationship_name);
   void on_flowtable_requested_related_details(const Glib::ustring& table_name, Gnome::Gda::Value 
primary_key_value);
 
-  void on_flowtable_script_button_clicked(const std::shared_ptr<const LayoutItem_Button>& layout_item);
+  void on_flowtable_script_button_clicked(const std::weak_ptr<const LayoutItem_Button>& layout_item_weak);
 
   void recalculate_fields_for_related_records(const Glib::ustring& relationship_name);
 
diff --git a/glom/mode_data/box_data_list.cc b/glom/mode_data/box_data_list.cc
index 2b61205..60cba49 100644
--- a/glom/mode_data/box_data_list.cc
+++ b/glom/mode_data/box_data_list.cc
@@ -177,9 +177,6 @@ void Box_Data_List::set_primary_key_value(const Gtk::TreeModel::iterator& row, c
 
 void Box_Data_List::on_adddel_script_button_clicked(const std::shared_ptr<const LayoutItem_Button>& 
layout_item, const Gtk::TreeModel::iterator& row)
 {
-  if(!layout_item)
-    return;
-
   const auto primary_key_value = get_primary_key_value(row);
 
   // TODO: Calling refresh_data_from_database(),
@@ -195,8 +192,12 @@ void Box_Data_List::on_adddel_script_button_clicked(const std::shared_ptr<const
       primary_key_value));
 }
 
-bool Box_Data_List::on_script_button_idle(const std::shared_ptr<const LayoutItem_Button>& layout_item, const 
Gnome::Gda::Value& primary_key)
+bool Box_Data_List::on_script_button_idle(const std::weak_ptr<const LayoutItem_Button>& layout_item_weak, 
const Gnome::Gda::Value& primary_key)
 {
+  const auto layout_item = layout_item_weak.lock();
+  if(!layout_item)
+    return false;
+
   execute_button_script(layout_item, primary_key);
 
   // Refill view from database as the script might have changed arbitrary records
diff --git a/glom/mode_data/box_data_list.h b/glom/mode_data/box_data_list.h
index 1ba572f..c4fb7b6 100644
--- a/glom/mode_data/box_data_list.h
+++ b/glom/mode_data/box_data_list.h
@@ -97,7 +97,7 @@ protected:
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
   void on_adddel_script_button_clicked(const std::shared_ptr<const LayoutItem_Button>& layout_item, const 
Gtk::TreeModel::iterator& row);
-  bool on_script_button_idle(const std::shared_ptr<const LayoutItem_Button>& layout_item, const 
Gnome::Gda::Value& primary_key);
+  bool on_script_button_idle(const std::weak_ptr<const LayoutItem_Button>& layout_item, const 
Gnome::Gda::Value& primary_key);
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
   Dialog_Layout* create_layout_dialog() const override;
diff --git a/glom/mode_data/box_data_list_related.cc b/glom/mode_data/box_data_list_related.cc
index 5d28d05..0315b5b 100644
--- a/glom/mode_data/box_data_list_related.cc
+++ b/glom/mode_data/box_data_list_related.cc
@@ -218,9 +218,6 @@ void Box_Data_List_Related::on_adddel_user_requested_layout()
 
 void Box_Data_List_Related::on_adddel_script_button_clicked(const std::shared_ptr<const LayoutItem_Button>& 
layout_item, const Gtk::TreeModel::iterator& row)
 {
-  if(!layout_item)
-    return;
-
   const auto primary_key_value = get_primary_key_value(row);
 
   // TODO: Calling refresh_data_from_database(),
diff --git a/glom/mode_data/flowtablewithfields.cc b/glom/mode_data/flowtablewithfields.cc
index 3373985..61aa89c 100644
--- a/glom/mode_data/flowtablewithfields.cc
+++ b/glom/mode_data/flowtablewithfields.cc
@@ -511,8 +511,7 @@ void FlowTableWithFields::add_field(const std::shared_ptr<LayoutItem_Field>& lay
 
   add_widgets(*eventbox, *(info.m_second), true);
 
-  info.m_second->signal_edited().connect( sigc::bind(sigc::mem_fun(*this, 
&FlowTableWithFields::on_entry_edited), layoutitem_field)  ); //TODO:  Is it a good idea to bind the 
LayoutItem? sigc::bind() probably stores a copy at this point.
-
+  info.m_second->signal_edited().connect( sigc::bind(sigc::mem_fun(*this, 
&FlowTableWithFields::on_entry_edited), layoutitem_field)  );
   info.m_second->signal_choices_changed().connect( sigc::bind(sigc::mem_fun(*this, 
&FlowTableWithFields::on_entry_choices_changed), layoutitem_field)  );
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
@@ -1010,23 +1009,39 @@ FlowTableWithFields::type_signal_script_button_clicked FlowTableWithFields::sign
   return m_signal_script_button_clicked;
 }
 
-void FlowTableWithFields::on_script_button_clicked(const std::shared_ptr< LayoutItem_Button>& layout_item)
+void FlowTableWithFields::on_script_button_clicked(const std::weak_ptr< LayoutItem_Button>& layout_item_weak)
 {
+  const auto layout_item = layout_item_weak.lock();
+  if(!layout_item)
+    return;
+
   m_signal_script_button_clicked.emit(layout_item);
 }
 
-void FlowTableWithFields::on_entry_edited(const Gnome::Gda::Value& value, const std::shared_ptr<const 
LayoutItem_Field>& field)
+void FlowTableWithFields::on_entry_edited(const Gnome::Gda::Value& value, const std::weak_ptr<const 
LayoutItem_Field>& field_weak)
 {
+  const auto field = field_weak.lock();
+  if (!field)
+    return;
+
   m_signal_field_edited.emit(field, value);
 }
 
-void FlowTableWithFields::on_entry_choices_changed(const std::shared_ptr<const LayoutItem_Field>& field)
+void FlowTableWithFields::on_entry_choices_changed(const std::weak_ptr<const LayoutItem_Field>& field_weak)
 {
+  const auto field = field_weak.lock();
+  if (!field)
+    return;
+
   m_signal_field_choices_changed.emit(field);
 }
 
-void FlowTableWithFields::on_entry_open_details_requested(const Gnome::Gda::Value& value, const 
std::shared_ptr<const LayoutItem_Field>& field)
+void FlowTableWithFields::on_entry_open_details_requested(const Gnome::Gda::Value& value, const 
std::weak_ptr<const LayoutItem_Field>& field_weak)
 {
+  const auto field = field_weak.lock();
+  if (!field)
+    return;
+
   m_signal_field_open_details_requested.emit(field, value);
 }
 
diff --git a/glom/mode_data/flowtablewithfields.h b/glom/mode_data/flowtablewithfields.h
index 952e3b8..1f03852 100644
--- a/glom/mode_data/flowtablewithfields.h
+++ b/glom/mode_data/flowtablewithfields.h
@@ -171,7 +171,7 @@ public:
   type_signal_requested_related_details signal_requested_related_details();
 
  /** For instance,
-   * void on_script_button_clicked(const std::shared_ptr<LayoutItem_Button>& layout_item>);
+   * void on_script_button_clicked(const std::weak_ptr<LayoutItem_Button>& layout_item_weak>);
    */
   typedef sigc::signal<void(const std::shared_ptr<LayoutItem_Button>&)> type_signal_script_button_clicked;
   type_signal_script_button_clicked signal_script_button_clicked();
@@ -203,11 +203,11 @@ private:
 
   //int get_suitable_width(Field::glom_field_type field_type);
 
-  void on_entry_edited(const Gnome::Gda::Value& value, const std::shared_ptr<const LayoutItem_Field>& field);
-  void on_entry_choices_changed(const std::shared_ptr<const LayoutItem_Field>& field);
-  void on_entry_open_details_requested(const Gnome::Gda::Value& value, const std::shared_ptr<const 
LayoutItem_Field>& field);
+  void on_entry_edited(const Gnome::Gda::Value& value, const std::weak_ptr<const LayoutItem_Field>& field);
+  void on_entry_choices_changed(const std::weak_ptr<const LayoutItem_Field>& field);
+  void on_entry_open_details_requested(const Gnome::Gda::Value& value, const std::weak_ptr<const 
LayoutItem_Field>& field);
 
-  void on_script_button_clicked(const std::shared_ptr<LayoutItem_Button>& layout_item);
+  void on_script_button_clicked(const std::weak_ptr<LayoutItem_Button>& layout_item_weak);
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
   void on_datawidget_layout_item_added(LayoutWidgetBase::enumType item_type, DataWidget* pDataWidget);
diff --git a/glom/mode_find/box_data_details_find.cc b/glom/mode_find/box_data_details_find.cc
index 6ab3450..7a8fbc0 100644
--- a/glom/mode_find/box_data_details_find.cc
+++ b/glom/mode_find/box_data_details_find.cc
@@ -73,7 +73,7 @@ bool Box_Data_Details_Find::fill_from_database()
   return result;
 }
 
-void Box_Data_Details_Find::on_flowtable_field_edited(const std::shared_ptr<const LayoutItem_Field>& /* id 
*/, const Gnome::Gda::Value& /* value */)
+void Box_Data_Details_Find::on_flowtable_field_edited(const std::weak_ptr<const LayoutItem_Field>& /* id */, 
const Gnome::Gda::Value& /* value */)
 {
   //Don't do anything.
   //This just blocks the method in the base class.
diff --git a/glom/mode_find/box_data_details_find.h b/glom/mode_find/box_data_details_find.h
index 4a8ac73..f26df91 100644
--- a/glom/mode_find/box_data_details_find.h
+++ b/glom/mode_find/box_data_details_find.h
@@ -39,7 +39,7 @@ private:
 
   bool fill_from_database() override;
 
-  void on_flowtable_field_edited(const std::shared_ptr<const LayoutItem_Field>& id, const Gnome::Gda::Value& 
value) override;
+  void on_flowtable_field_edited(const std::weak_ptr<const LayoutItem_Field>& id_weak, const 
Gnome::Gda::Value& value) override;
 };
 
 } //namespace Glom


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]