[glibmm] Add Glib::SignalProxyDetailed



commit 79a172fc184cbc167d58197a3e8eaf3641614ef2
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Sat May 23 08:18:20 2015 +0200

    Add Glib::SignalProxyDetailed
    
    * glib/glibmm/signalproxy.cc:
    * glib/src/signalproxy.h.m4: Add SignalProxyDetailed and
    SignalProxyDetailed[0-6]. Bug #749034.

 glib/glibmm/signalproxy.cc |   43 ++++++++++++++++--
 glib/src/signalproxy.h.m4  |  103 ++++++++++++++++++++++++++++++++++----------
 2 files changed, 118 insertions(+), 28 deletions(-)
---
diff --git a/glib/glibmm/signalproxy.cc b/glib/glibmm/signalproxy.cc
index e218ba9..41ee5f7 100644
--- a/glib/glibmm/signalproxy.cc
+++ b/glib/glibmm/signalproxy.cc
@@ -1,7 +1,3 @@
-// -*- c++ -*-
-
-/* $Id$ */
-
 /* signalproxy.cc
  *
  * Copyright (C) 2002 The gtkmm Development Team
@@ -101,5 +97,42 @@ void SignalProxyNormal::slot0_void_callback(GObject* self, void* data)
   }
 }
 
-} // namespace Glib
 
+// SignalProxyDetailed implementation:
+
+SignalProxyDetailed::SignalProxyDetailed(Glib::ObjectBase* obj,
+  const SignalProxyInfo* info, const Glib::ustring& detail_name)
+:
+  SignalProxyBase (obj),
+  info_           (info),
+  detailed_name_  (Glib::ustring(info->signal_name) +
+                   (detail_name.empty() ? Glib::ustring() : ("::" + detail_name)))
+{}
+
+SignalProxyDetailed::~SignalProxyDetailed()
+{}
+
+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());
+
+  // 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<GConnectFlags>(after ? G_CONNECT_AFTER : 0));
+
+  return pConnectionNode->slot_;
+}
+
+void SignalProxyDetailed::emission_stop()
+{
+  g_signal_stop_emission_by_name(obj_->gobj(), detailed_name_.c_str());
+}
+
+} // namespace Glib
diff --git a/glib/src/signalproxy.h.m4 b/glib/src/signalproxy.h.m4
index 69db201..a95d597 100644
--- a/glib/src/signalproxy.h.m4
+++ b/glib/src/signalproxy.h.m4
@@ -1,5 +1,3 @@
-// -*- c++ -*-
-dnl 
 dnl Glib SignalProxy Templates
 dnl 
 dnl  Copyright 2001 Free Software Foundation
@@ -19,7 +17,6 @@ dnl  You should have received a copy of the GNU Lesser General Public
 dnl  License along with this library; if not, write to the Free
 dnl  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 dnl 
-dnl Ignore the next line
 /* This is a generated file, do not edit.  Generated from __file__ */
 include(template.macros.m4)
 #ifndef __header__
@@ -33,7 +30,7 @@ extern "C"
 
 #include <sigc++/sigc++.h>
 #include <glibmm/signalproxy_connectionnode.h>
-
+#include <glibmm/ustring.h>
 
 namespace Glib
 {
@@ -52,7 +49,7 @@ struct SignalProxyInfo
 
 #endif //DOXYGEN_SHOULD_SKIP_THIS
 
-// This base class is used by SignalProxyNormal and SignalProxyProperty.
+// This base class is used by SignalProxyNormal, SignalProxyDetailed and SignalProxyProperty.
 class SignalProxyBase
 {
 public:
@@ -76,7 +73,7 @@ private:
 };
 
 
-// shared portion of a Signal
+// Shared portion of a Signal without detail
 /** The SignalProxy provides an API similar to sigc::signal that can be used to
  * connect sigc::slots to glib signals.
  *
@@ -84,6 +81,8 @@ private:
  * which might emit it. Actually, proxies are controlled by
  * the template derivatives, which serve as gatekeepers for the
  * types allowed on a particular signal.
+ *
+ * For signals with a detailed name (signal_name::detail_name) see SignalProxyDetailed.
  */
 class SignalProxyNormal : public SignalProxyBase
 {
@@ -136,27 +135,77 @@ private:
   SignalProxyNormal& operator=(const SignalProxyNormal&);
 };
 
+// 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.
+ *
+ * This holds the name of the glib signal, including the detail name if any,
+ * and the object which might emit it. Actually, proxies are controlled by
+ * the template derivatives, which serve as gatekeepers for the
+ * types allowed on a particular signal.
+ */
+class SignalProxyDetailed : public SignalProxyBase
+{
+public:
+  ~SignalProxyDetailed();
+
+  /// Stops the current signal emission (not in libsigc++)
+  void emission_stop();
+
+protected:
+
+  /** Creates a proxy for a signal that can be emitted by @a obj.
+   * @param obj The object that can emit the signal.
+   * @param info Information about the signal, including its name
+   *             and the C callbacks that should be called by glib.
+   * @param detail_name The detail name, if any.
+   */
+  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.
+   *
+   * @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().
+   * @param after Whether this signal handler should be called before or after the default signal handler.
+   */
+  sigc::slot_base& connect_impl_(bool notify, const sigc::slot_base& slot, bool after);
+
+private:
+  const SignalProxyInfo* info_; // Pointer to statically allocated structure.
+  const Glib::ustring detailed_name_; // signal_name[[::detail_name]]dnl one pair of [] in the generated .h 
file
+
+
+  // no copy assignment
+  SignalProxyDetailed& operator=(const SignalProxyDetailed&);
+};
+
 dnl
-dnl GLIB_SIGNAL_PROXY([P1, P2, ...],return type)
+dnl GLIB_SIGNAL_PROXY([P1, P2, ...], Normal or Detailed)
 dnl
 define([GLIB_SIGNAL_PROXY],[dnl
 LINE(]__line__[)dnl
 
-/**** Glib::[SignalProxy]NUM($1) ***************************************************/
+/**** Glib::[SignalProxy]ifelse($2,Normal,,$2)[]NUM($1) ***************************************************/
 
-/** Proxy for signals with NUM($1) arguments.
+/** Proxy for signals with NUM($1) arguments[]ifelse($2,Normal,,[ and possibly a detailed name]).
  * Use the connect() or connect_notify() method, with sigc::mem_fun() or sigc::ptr_fun()
  * to connect signal handlers to signals.
  */
 template <LIST(class R,ARG_CLASS($1))>
-class [SignalProxy]NUM($1) : public SignalProxyNormal
+class [SignalProxy]ifelse($2,Normal,,$2)[]NUM($1) : public SignalProxy$2
 {
 public:
   typedef sigc::slot<LIST(R,ARG_TYPE($1))>    SlotType;
   typedef sigc::slot<LIST(void,ARG_TYPE($1))> VoidSlotType;
 
-  [SignalProxy]NUM($1)(ObjectBase* obj, const SignalProxyInfo* info)
+ifelse($2,Normal,dnl
+  [SignalProxy]NUM($1)[(ObjectBase* obj, const SignalProxyInfo* info)
     : SignalProxyNormal(obj, info) {}
+],dnl Detailed
+  [SignalProxyDetailed]NUM($1)[(ObjectBase* obj, const SignalProxyInfo* info, const Glib::ustring& 
detail_name)
+    : SignalProxyDetailed(obj, info, detail_name) {}
+])dnl
 
   /** Connects a signal handler to a signal.
    *
@@ -166,7 +215,7 @@ public:
    * @param after Whether this signal handler should be called before or after the default signal handler.
    */
   sigc::connection connect(const SlotType& slot, bool after = true)
-    { return sigc::connection(connect_(slot, after)); }
+    { return sigc::connection(ifelse($2,Normal,[connect_(slot, after)],[connect_impl_(false, 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.
@@ -190,20 +239,28 @@ public:
    * @param after Whether this signal handler should be called before or after the default signal handler.
    */
   sigc::connection connect_notify(const VoidSlotType& slot, bool after = false)
-    { return sigc::connection(connect_notify_(slot, after)); }
+    { return sigc::connection(ifelse($2,Normal,[connect_notify_(slot, after)],[connect_impl_(true, slot, 
after)])); }
 };
 ])dnl
-
+dnl
 dnl Template forms of SignalProxy
-
-GLIB_SIGNAL_PROXY(ARGS(P,0))
-GLIB_SIGNAL_PROXY(ARGS(P,1))
-GLIB_SIGNAL_PROXY(ARGS(P,2))
-GLIB_SIGNAL_PROXY(ARGS(P,3))
-GLIB_SIGNAL_PROXY(ARGS(P,4))
-GLIB_SIGNAL_PROXY(ARGS(P,5))
-GLIB_SIGNAL_PROXY(ARGS(P,6))
-
+dnl
+GLIB_SIGNAL_PROXY(ARGS(P,0), Normal)
+GLIB_SIGNAL_PROXY(ARGS(P,1), Normal)
+GLIB_SIGNAL_PROXY(ARGS(P,2), Normal)
+GLIB_SIGNAL_PROXY(ARGS(P,3), Normal)
+GLIB_SIGNAL_PROXY(ARGS(P,4), Normal)
+GLIB_SIGNAL_PROXY(ARGS(P,5), Normal)
+GLIB_SIGNAL_PROXY(ARGS(P,6), Normal)
+dnl
+GLIB_SIGNAL_PROXY(ARGS(P,0), Detailed)
+GLIB_SIGNAL_PROXY(ARGS(P,1), Detailed)
+GLIB_SIGNAL_PROXY(ARGS(P,2), Detailed)
+GLIB_SIGNAL_PROXY(ARGS(P,3), Detailed)
+GLIB_SIGNAL_PROXY(ARGS(P,4), Detailed)
+GLIB_SIGNAL_PROXY(ARGS(P,5), Detailed)
+GLIB_SIGNAL_PROXY(ARGS(P,6), Detailed)
+dnl
 } // namespace Glib
 
 #endif /* __header__ */


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