[glibmm] ObjectBase: Add initialize_move().



commit 41708be88a1ea1513029221868f48b9c8aa23808
Author: Murray Cumming <murrayc murrayc com>
Date:   Sat Aug 22 17:32:03 2015 +0200

    ObjectBase: Add initialize_move().
    
    And _move_current_wrapper() for it to use.
    Object and Interface can use initialize_move() in their move
    constructors. They need to do this because their calls to the
    ObjectBase move constructors will not actually run, at least
    when in a derived class, because ObjectBase is a virtual base
    class (for use in virtual inheritance).
    We have initialize() for much the same reason, for the regular
    constructors.

 glib/glibmm/objectbase.cc |   44 ++++++++++++++++++++++++++++++++++++++++++++
 glib/glibmm/objectbase.h  |    6 ++++++
 2 files changed, 50 insertions(+), 0 deletions(-)
---
diff --git a/glib/glibmm/objectbase.cc b/glib/glibmm/objectbase.cc
index c3fddeb..370e2f5 100644
--- a/glib/glibmm/objectbase.cc
+++ b/glib/glibmm/objectbase.cc
@@ -90,6 +90,28 @@ void ObjectBase::initialize(GObject* castitem)
   _set_current_wrapper(castitem);
 }
 
+void ObjectBase::initialize_move(GObject* castitem, Glib::ObjectBase* previous_wrapper)
+{
+  if(gobject_)
+  {
+    g_assert(gobject_ == castitem);
+
+    // TODO: Think about it.  Will this really be called twice?
+    g_printerr("ObjectBase::initialize_move() called twice for the same GObject\n");
+
+    return; // Don't initialize the wrapper twice.
+  }
+
+  gobject_ = castitem;
+  _move_current_wrapper(castitem, previous_wrapper);
+  custom_type_name_ = previous_wrapper->custom_type_name_;
+  cpp_destruction_in_progress_ = previous_wrapper->cpp_destruction_in_progress_;
+
+  //Clear the previous wrapper:
+  previous_wrapper->custom_type_name_ = nullptr;
+  previous_wrapper->cpp_destruction_in_progress_ = false;
+}
+
 ObjectBase::ObjectBase(ObjectBase&& src) noexcept
 : gobject_(std::move(src.gobject_)),
   custom_type_name_(std::move(src.custom_type_name_)),
@@ -195,6 +217,28 @@ void ObjectBase::_set_current_wrapper(GObject* object)
   }
 }
 
+void ObjectBase::_move_current_wrapper(GObject* object, Glib::ObjectBase* previous_wrapper) noexcept
+{
+  //See _set_current_wrapper().
+  ObjectBase* current_wrapper = _get_current_wrapper(object);
+  if(current_wrapper != previous_wrapper)
+  {
+    g_warning("%s: Unexpected previous wrapper, for object of type %s.\n"
+              "previous_wrapper=%p, current_wrapper=%p",
+                G_STRFUNC, G_OBJECT_TYPE_NAME(object),
+                previous_wrapper, current_wrapper);
+  }
+
+  //Remove the previous wrapper, without invoking destroy_notify_callback_():
+  g_object_steal_qdata(object, Glib::quark_);
+
+  //Set the new wrapper:
+  g_object_set_qdata_full(object, Glib::quark_, this, &destroy_notify_callback_);
+
+  //Clear the previous wrapper:
+  previous_wrapper->gobject_ = nullptr;
+}
+
 // static
 ObjectBase* ObjectBase::_get_current_wrapper(GObject* object)
 {
diff --git a/glib/glibmm/objectbase.h b/glib/glibmm/objectbase.h
index e5407ab..3f2771e 100644
--- a/glib/glibmm/objectbase.h
+++ b/glib/glibmm/objectbase.h
@@ -103,6 +103,9 @@ protected:
   // Called by Glib::Object and Glib::Interface constructors. See comments there.
   void initialize(GObject* castitem);
 
+  // Called by Glib::Object and Glib::Interface C++ move operations.
+  void initialize_move(GObject* castitem, Glib::ObjectBase* previous_wrapper);
+
 public:
 
   /// You probably want to use a specific property_*() accessor method instead.
@@ -241,6 +244,9 @@ protected:
   virtual void destroy_notify_();
 
   void _set_current_wrapper(GObject* object);
+
+  /// For (indirect) use by C++ move operations.
+  void _move_current_wrapper(GObject* object, Glib::ObjectBase* previous_wrapper) noexcept;
 #endif //DOXYGEN_SHOULD_SKIP_THIS
 
 private:


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