From c9fdfadcd7bf727d8847742cf1410478aaea6701 Mon Sep 17 00:00:00 2001 From: Kjell Ahlstedt Date: Mon, 1 Feb 2016 13:38:42 +0100 Subject: Add some connect() overloads that move the sigc::slot * glib/glibmm/dispatcher.[cc|h]: Add Dispatcher::connect(&&). * glib/glibmm/objectbase.[cc|h]: Add ObjectBase::connect_property_changed(&&) and ObjectBase::connect_property_changed_with_return(&&). * glib/glibmm/propertyproxy_base.[cc|h]: Add PropertyProxyConnectionNode(&&) ctor, PropertyProxyConnectionNode::connect_changed() and SignalProxyProperty::connect(&&). * glib/glibmm/signalproxy.[cc|h]: Add SignalProxyNormal::connect_impl_(&&), SignalProxy::connect(&&), SignalProxy::connect_notify(&&), SignalProxyDetailed::connect_impl_(&&), SignalProxyDetailedAnyType::connect(&&) and SignalProxyDetailedAnyType::connect_notify(&&). * glib/glibmm/signalproxy_connectionnode.[cc|h]: Add SignalProxyConnectionNode(&&) ctor --- glib/glibmm/dispatcher.cc | 9 ++++-- glib/glibmm/dispatcher.h | 6 ++-- glib/glibmm/objectbase.cc | 31 +++++++++++------- glib/glibmm/objectbase.h | 20 +++++++++--- glib/glibmm/propertyproxy_base.cc | 52 +++++++++++++++++++---------- glib/glibmm/propertyproxy_base.h | 21 ++++++++---- glib/glibmm/signalproxy.cc | 40 ++++++++++++++++++++--- glib/glibmm/signalproxy.h | 54 ++++++++++++++++++++++++++++++- glib/glibmm/signalproxy_connectionnode.cc | 17 ++++++---- glib/glibmm/signalproxy_connectionnode.h | 12 ++++--- 10 files changed, 202 insertions(+), 60 deletions(-) diff --git a/glib/glibmm/dispatcher.cc b/glib/glibmm/dispatcher.cc index 795a2242..1bbab0ec 100644 --- a/glib/glibmm/dispatcher.cc +++ b/glib/glibmm/dispatcher.cc @@ -1,6 +1,3 @@ -// -*- c++ -*- -/* $Id$ */ - /* Copyright 2002 The gtkmm Development Team * * This library is free software; you can redistribute it and/or @@ -27,6 +24,7 @@ #include #include #include +#include // For std::move() #ifdef G_OS_WIN32 # include @@ -501,4 +499,9 @@ sigc::connection Dispatcher::connect(const sigc::slot& slot) return signal_.connect(slot); } +sigc::connection Dispatcher::connect(sigc::slot&& slot) +{ + return signal_.connect(std::move(slot)); +} + } // namespace Glib diff --git a/glib/glibmm/dispatcher.h b/glib/glibmm/dispatcher.h index e7fda78a..f5dfa56c 100644 --- a/glib/glibmm/dispatcher.h +++ b/glib/glibmm/dispatcher.h @@ -1,9 +1,6 @@ -// -*- c++ -*- #ifndef _GLIBMM_DISPATCHER_H #define _GLIBMM_DISPATCHER_H -/* $Id$ */ - /* Copyright 2002 The gtkmm Development Team * * This library is free software; you can redistribute it and/or @@ -92,6 +89,9 @@ public: void operator()(); sigc::connection connect(const sigc::slot& slot); + /** @newin{2,48} + */ + sigc::connection connect(sigc::slot&& slot); private: sigc::signal signal_; diff --git a/glib/glibmm/objectbase.cc b/glib/glibmm/objectbase.cc index 59133edc..c32752e1 100644 --- a/glib/glibmm/objectbase.cc +++ b/glib/glibmm/objectbase.cc @@ -22,6 +22,7 @@ #include //For PropertyProxyConnectionNode #include #include +#include // For std::move() namespace { @@ -342,23 +343,31 @@ void ObjectBase::connect_property_changed(const Glib::ustring& property_name, co connect_property_changed_with_return(property_name, slot); } +void ObjectBase::connect_property_changed(const Glib::ustring& property_name, sigc::slot&& slot) +{ + connect_property_changed_with_return(property_name, std::move(slot)); +} + sigc::connection ObjectBase::connect_property_changed_with_return(const Glib::ustring& property_name, const sigc::slot& slot) { // Create a proxy to hold our connection info // This will be deleted by destroy_notify_handler. - PropertyProxyConnectionNode* pConnectionNode = new PropertyProxyConnectionNode(slot, gobj()); + auto pConnectionNode = new PropertyProxyConnectionNode(slot, gobj()); + + // connect it to glib + // pConnectionNode will be passed as the data argument to the callback. + return pConnectionNode->connect_changed(property_name); +} + +sigc::connection ObjectBase::connect_property_changed_with_return(const Glib::ustring& property_name, sigc::slot&& slot) +{ + // Create a proxy to hold our connection info + // This will be deleted by destroy_notify_handler. + auto pConnectionNode = new PropertyProxyConnectionNode(std::move(slot), gobj()); - // connect it to gtk+ + // connect it to glib // pConnectionNode will be passed as the data argument to the callback. - // The callback will then call the virtual Object::property_change_notify() method, - // which will contain a switch/case statement which will examine the property name. - const Glib::ustring notify_signal_name = "notify::" + property_name; - pConnectionNode->connection_id_ = g_signal_connect_data(gobj(), - notify_signal_name.c_str(), (GCallback)(&PropertyProxyConnectionNode::callback), pConnectionNode, - &PropertyProxyConnectionNode::destroy_notify_handler, - G_CONNECT_AFTER); - - return sigc::connection(pConnectionNode->slot_); + return pConnectionNode->connect_changed(property_name); } void ObjectBase::freeze_notify() diff --git a/glib/glibmm/objectbase.h b/glib/glibmm/objectbase.h index 7f13fe33..f16cfa55 100644 --- a/glib/glibmm/objectbase.h +++ b/glib/glibmm/objectbase.h @@ -119,21 +119,33 @@ public: template void get_property(const Glib::ustring& property_name, PropertyType& value) const; - /** You can use the signal_changed() signal of the property proxy instead, - * but this is necessary when using the reduced API. + //TODO: At the next ABI break, delete connect_property_changed_with_return() + // and let connect_property_changed() return sigc::connection. + /** You can use the signal_changed() signal of the property proxy instead. * * See also connect_property_changed_with_return(). */ void connect_property_changed(const Glib::ustring& property_name, const sigc::slot& slot); - /** You can use the signal_changed() signal of the property proxy instead, - * but this is necessary when using the reduced API. + /** You can use the signal_changed() signal of the property proxy instead. + * + * @newin{2,48} + */ + void connect_property_changed(const Glib::ustring& property_name, sigc::slot&& slot); + + /** You can use the signal_changed() signal of the property proxy instead. * * This method was added because connect_property_changed() does not return a sigc::connection, * and we could not break the ABI by changing that function. */ sigc::connection connect_property_changed_with_return(const Glib::ustring& property_name, const sigc::slot& slot); + /** You can use the signal_changed() signal of the property proxy instead. + * + * @newin{2,48} + */ + sigc::connection connect_property_changed_with_return(const Glib::ustring& property_name, sigc::slot&& slot); + /** Increases the freeze count on object. If the freeze count is non-zero, the * emission of "notify" signals on object is stopped. The signals are queued * until the freeze count is decreased to zero. diff --git a/glib/glibmm/propertyproxy_base.cc b/glib/glibmm/propertyproxy_base.cc index ea69ba34..a0e0bd74 100644 --- a/glib/glibmm/propertyproxy_base.cc +++ b/glib/glibmm/propertyproxy_base.cc @@ -1,6 +1,3 @@ -// -*- c++ -*- -/* $Id$ */ - /* propertyproxy_base.h * * Copyright 2002 The gtkmm Development Team @@ -26,15 +23,35 @@ #include #include #include +#include // For std::move() namespace Glib { +//PropertyProxyConnectionNode implementation: + PropertyProxyConnectionNode::PropertyProxyConnectionNode(const sigc::slot_base& slot, GObject* gobject) : SignalProxyConnectionNode(slot, gobject) { } +PropertyProxyConnectionNode::PropertyProxyConnectionNode(sigc::slot_base&& slot, GObject* gobject) +: SignalProxyConnectionNode(std::move(slot), gobject) +{ +} + +sigc::connection PropertyProxyConnectionNode::connect_changed(const Glib::ustring& property_name) +{ + // connect it to glib + // 'this' will be passed as the data argument to the callback. + const Glib::ustring notify_signal_name = "notify::" + property_name; + connection_id_ = g_signal_connect_data(object_, notify_signal_name.c_str(), + (GCallback)(&PropertyProxyConnectionNode::callback), this, + &PropertyProxyConnectionNode::destroy_notify_handler, G_CONNECT_AFTER); + + return sigc::connection(slot_); +} + void PropertyProxyConnectionNode::callback(GObject*, GParamSpec* pspec, gpointer data) //static { if(pspec && data) @@ -57,23 +74,26 @@ SignalProxyProperty::~SignalProxyProperty() noexcept { } -sigc::connection SignalProxyProperty::connect(const SlotType& sl) +sigc::connection SignalProxyProperty::connect(const SlotType& slot) { // Create a proxy to hold our connection info // This will be deleted by destroy_notify_handler. - PropertyProxyConnectionNode* pConnectionNode = new PropertyProxyConnectionNode(sl, obj_->gobj()); + auto pConnectionNode = new PropertyProxyConnectionNode(slot, obj_->gobj()); - // connect it to gtk+ + // connect it to glib // pConnectionNode will be passed as the data argument to the callback. - // The callback will then call the virtual Object::property_change_notify() method, - // which will contain a switch/case statement which will examine the property name. - const Glib::ustring notify_signal_name = "notify::" + Glib::ustring(property_name_); - pConnectionNode->connection_id_ = g_signal_connect_data(obj_->gobj(), - notify_signal_name.c_str(), (GCallback)(&PropertyProxyConnectionNode::callback), pConnectionNode, - &PropertyProxyConnectionNode::destroy_notify_handler, - G_CONNECT_AFTER); - - return sigc::connection(pConnectionNode->slot_); + return pConnectionNode->connect_changed(property_name_); +} + +sigc::connection SignalProxyProperty::connect(SlotType&& slot) +{ + // Create a proxy to hold our connection info + // This will be deleted by destroy_notify_handler. + auto pConnectionNode = new PropertyProxyConnectionNode(std::move(slot), obj_->gobj()); + + // connect it to glib + // pConnectionNode will be passed as the data argument to the callback. + return pConnectionNode->connect_changed(property_name_); } @@ -124,6 +144,4 @@ void PropertyProxy_Base::reset_property_() g_object_set_property(obj_->gobj(), property_name_, value.gobj()); } - } // namespace Glib - diff --git a/glib/glibmm/propertyproxy_base.h b/glib/glibmm/propertyproxy_base.h index c317a2eb..1045c5c9 100644 --- a/glib/glibmm/propertyproxy_base.h +++ b/glib/glibmm/propertyproxy_base.h @@ -1,4 +1,3 @@ -// -*- c++ -*- #ifndef _GLIBMM_PROPERTYPROXY_BASE_H #define _GLIBMM_PROPERTYPROXY_BASE_H @@ -41,7 +40,10 @@ public: ~SignalProxyProperty() noexcept; typedef sigc::slot SlotType; - sigc::connection connect(const SlotType& sl); + sigc::connection connect(const SlotType& slot); + /** @newin{2,48} + */ + sigc::connection connect(SlotType&& slot); protected: @@ -84,7 +86,7 @@ private: class SignalProxyProperty; /** PropertyProxyConnectionNode is a connection node for use with SignalProxyProperty. - * It's like ProxyConnectionNode, but it contains the property name too. + * It's like SignalProxyConnectionNode, but it contains the property name too. * This is not public API. */ class PropertyProxyConnectionNode : public SignalProxyConnectionNode @@ -93,6 +95,16 @@ public: friend class SignalProxyProperty; PropertyProxyConnectionNode(const sigc::slot_base& slot, GObject* gobject); + /** @newin{2,48} + */ + PropertyProxyConnectionNode(sigc::slot_base&& slot, GObject* gobject); + + /** Connect callback() to the notify::property_name signal. + * It invokes the slot, supplied in the constructor. + * + * @newin{2,48} + */ + sigc::connection connect_changed(const Glib::ustring& property_name); static void callback(GObject* object, GParamSpec* pspec, gpointer data); }; @@ -101,7 +113,4 @@ public: } // namespace Glib - - #endif /* _GLIBMM_PROPERTYPROXY_BASE_H */ - diff --git a/glib/glibmm/signalproxy.cc b/glib/glibmm/signalproxy.cc index 4c9e9d31..52c9ed7f 100644 --- a/glib/glibmm/signalproxy.cc +++ b/glib/glibmm/signalproxy.cc @@ -61,8 +61,7 @@ sigc::slot_base& SignalProxyNormal::connect_impl_(GCallback callback, const sigc::slot_base& slot, bool after) { // create a proxy to hold our connection info - SignalProxyConnectionNode *const pConnectionNode = - new SignalProxyConnectionNode(slot, obj_->gobj()); + auto pConnectionNode = new SignalProxyConnectionNode(slot, obj_->gobj()); // connect it to glib // pConnectionNode will be passed in the data argument to the callback. @@ -74,6 +73,23 @@ SignalProxyNormal::connect_impl_(GCallback callback, const sigc::slot_base& slot return pConnectionNode->slot_; } +sigc::slot_base& +SignalProxyNormal::connect_impl_(bool notify, sigc::slot_base&& slot, bool after) +{ + // create a proxy to hold our connection info + auto pConnectionNode = new SignalProxyConnectionNode(std::move(slot), obj_->gobj()); + + // connect it to glib + // pConnectionNode will be passed in the data argument to the callback. + pConnectionNode->connection_id_ = g_signal_connect_data( + obj_->gobj(), info_->signal_name, + notify ? info_->notify_callback : info_->callback, + pConnectionNode, &SignalProxyConnectionNode::destroy_notify_handler, + static_cast(after ? G_CONNECT_AFTER : 0)); + + return pConnectionNode->slot_; +} + void SignalProxyNormal::emission_stop() { g_signal_stop_emission_by_name(obj_->gobj(), info_->signal_name); @@ -116,8 +132,24 @@ sigc::slot_base& SignalProxyDetailed::connect_impl_(bool notify, const sigc::slot_base& slot, bool after) { // create a proxy to hold our connection info - SignalProxyConnectionNode *const pConnectionNode = - new SignalProxyConnectionNode(slot, obj_->gobj()); + auto pConnectionNode = new SignalProxyConnectionNode(slot, obj_->gobj()); + + // connect it to glib + // pConnectionNode will be passed in the data argument to the callback. + pConnectionNode->connection_id_ = g_signal_connect_data( + obj_->gobj(), detailed_name_.c_str(), + notify ? info_->notify_callback : info_->callback, + pConnectionNode, &SignalProxyConnectionNode::destroy_notify_handler, + static_cast(after ? G_CONNECT_AFTER : 0)); + + return pConnectionNode->slot_; +} + +sigc::slot_base& +SignalProxyDetailed::connect_impl_(bool notify, sigc::slot_base&& slot, bool after) +{ + // create a proxy to hold our connection info + auto pConnectionNode = new SignalProxyConnectionNode(std::move(slot), obj_->gobj()); // connect it to glib // pConnectionNode will be passed in the data argument to the callback. diff --git a/glib/glibmm/signalproxy.h b/glib/glibmm/signalproxy.h index a4d4fee5..f6f35480 100644 --- a/glib/glibmm/signalproxy.h +++ b/glib/glibmm/signalproxy.h @@ -29,6 +29,7 @@ extern "C" #include #include #include +#include // std::move() namespace Glib { @@ -121,6 +122,14 @@ protected: */ sigc::slot_base& connect_notify_(const sigc::slot_base& slot, bool after); + /** Connects a signal handler to a signal. + * @see connect_(const sigc::slot_base& slot, bool after) and + * connect_notify_(const sigc::slot_base& slot, bool after). + * + * @newin{2,48} + */ + sigc::slot_base& connect_impl_(bool notify, sigc::slot_base&& slot, bool after); + private: const SignalProxyInfo* info_; @@ -159,6 +168,14 @@ public: sigc::connection connect(const SlotType& slot, bool after = true) { return sigc::connection(connect_(slot, after)); } + /** Connects a signal handler to a signal. + * @see connect(const SlotType& slot, bool after). + * + * @newin{2,48} + */ + sigc::connection connect(SlotType&& slot, bool after = true) + { return sigc::connection(connect_impl_(false, std::move(slot), after)); } + /** Connects a signal handler without a return value to a signal. * By default, the signal handler will be called before the default signal handler. * @@ -182,6 +199,14 @@ public: */ sigc::connection connect_notify(const VoidSlotType& slot, bool after = false) { return sigc::connection(connect_notify_(slot, after)); } + + /** Connects a signal handler without a return value to a signal. + * @see connect_notify(const VoidSlotType& slot, bool after). + * + * @newin{2,48} + */ + sigc::connection connect_notify(VoidSlotType&& slot, bool after = false) + { return sigc::connection(connect_impl_(true, std::move(slot), after)); } }; /* Templates below has been added to avoid API break, and should not be @@ -204,6 +229,10 @@ template ; +//TODO: When we can break ABI, consider renaming +// SignalProxyDetailed => SignalProxyDetailedBase +// SignalProxyDetailedAnyType => SignalProxyDetailed + // Shared portion of a Signal with detail /** The SignalProxy provides an API similar to sigc::signal that can be used to * connect sigc::slots to glib signals. @@ -232,7 +261,7 @@ protected: SignalProxyDetailed(Glib::ObjectBase* obj, const SignalProxyInfo* info, const Glib::ustring& detail_name); /** Connects a signal handler to a signal. - * This is called by connect() and connect_notify() in derived SignalProxy classes. + * This is called by connect() and connect_notify() in derived SignalProxyDetailedAnyType classes. * * @param notify Whether this method is called by connect_notify() or by connect(). * @param slot The signal handler, usually created with sigc::mem_fun() or sigc::ptr_fun(). @@ -240,6 +269,13 @@ protected: */ sigc::slot_base& connect_impl_(bool notify, const sigc::slot_base& slot, bool after); + /** Connects a signal handler to a signal. + * @see connect_impl_(bool notify, const sigc::slot_base& slot, bool after). + * + * @newin{2,48} + */ + sigc::slot_base& connect_impl_(bool notify, sigc::slot_base&& slot, bool after); + private: const SignalProxyInfo* info_; // Pointer to statically allocated structure. const Glib::ustring detailed_name_; // signal_name[::detail_name] @@ -272,6 +308,14 @@ public: sigc::connection connect(const SlotType& slot, bool after = true) { return sigc::connection(connect_impl_(false, slot, after)); } + /** Connects a signal handler to a signal. + * @see connect(const SlotType& slot, bool after). + * + * @newin{2,48} + */ + sigc::connection connect(SlotType&& slot, bool after = true) + { return sigc::connection(connect_impl_(false, std::move(slot), after)); } + /** Connects a signal handler without a return value to a signal. * By default, the signal handler will be called before the default signal handler. * @@ -295,6 +339,14 @@ public: */ sigc::connection connect_notify(const VoidSlotType& slot, bool after = false) { return sigc::connection(connect_impl_(true, slot, after)); } + + /** Connects a signal handler without a return value to a signal. + * @see connect_notify(const VoidSlotType& slot, bool after). + * + * @newin{2,48} + */ + sigc::connection connect_notify(VoidSlotType&& slot, bool after = false) + { return sigc::connection(connect_impl_(true, std::move(slot), after)); } }; /* Templates below has been added to avoid API break, and should not be diff --git a/glib/glibmm/signalproxy_connectionnode.cc b/glib/glibmm/signalproxy_connectionnode.cc index 7c9b3212..21fea65a 100644 --- a/glib/glibmm/signalproxy_connectionnode.cc +++ b/glib/glibmm/signalproxy_connectionnode.cc @@ -1,7 +1,3 @@ -// -*- c++ -*- - -/* $Id$ */ - /* signalproxy_connectionnode.cc * * Copyright (C) 2002 The gtkmm Development Team @@ -23,7 +19,7 @@ #include #include - +#include // std::move() namespace Glib { @@ -38,6 +34,16 @@ SignalProxyConnectionNode::SignalProxyConnectionNode(const sigc::slot_base& slot slot_.set_parent(this, &SignalProxyConnectionNode::notify /* cleanup callback */); } +SignalProxyConnectionNode::SignalProxyConnectionNode(sigc::slot_base&& slot, GObject* gobject) +: + connection_id_ (0), + slot_ (std::move(slot)), + object_ (gobject) +{ + //The cleanup callback will be called when the connection is disconnected. + slot_.set_parent(this, &SignalProxyConnectionNode::notify /* cleanup callback */); +} + // notify is a message coming up from the slot to be passed back to Gtk+ // disconnect is a message coming up from the Gtk+ to be passed down to SigC++ //static @@ -91,4 +97,3 @@ void SignalProxyConnectionNode::destroy_notify_handler(gpointer data, GClosure*) } } /* namespace Glib */ - diff --git a/glib/glibmm/signalproxy_connectionnode.h b/glib/glibmm/signalproxy_connectionnode.h index 7309b5b1..b9deab0d 100644 --- a/glib/glibmm/signalproxy_connectionnode.h +++ b/glib/glibmm/signalproxy_connectionnode.h @@ -1,9 +1,6 @@ -// -*- c++ -*- #ifndef _GLIBMM_SIGNALPROXY_CONNECTIONNODE_H #define _GLIBMM_SIGNALPROXY_CONNECTIONNODE_H -/* $Id$ */ - /* signalproxy_connectionnode.h * * Copyright (C) 2002 The gtkmm Development Team @@ -49,6 +46,13 @@ public: */ SignalProxyConnectionNode(const sigc::slot_base& slot, GObject* gobject); + /** @param slot The signal handler for the glib signal. + * @param gobject The GObject that might emit this glib signal + * + * @newin{2,48} + */ + SignalProxyConnectionNode(sigc::slot_base&& slot, GObject* gobject); + /** Callback that is executed when the slot becomes invalid. * This callback is registered in the slot. * @param data The SignalProxyConnectionNode object (@p this). @@ -72,6 +76,4 @@ protected: } /* namespace Glib */ - #endif /* _GLIBMM_SIGNALPROXY_CONNECTIONNODE_H */ - -- cgit v1.2.1