Back to index

unity  6.0.0
GLibSignal.h
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003 * Copyright (C) 2011-2012 Canonical Ltd
00004 *
00005 * This program is free software: you can redistribute it and/or modify
00006 * it under the terms of the GNU General Public License version 3 as
00007 * published by the Free Software Foundation.
00008 *
00009 * This program is distributed in the hope that it will be useful,
00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 * GNU General Public License for more details.
00013 *
00014 * You should have received a copy of the GNU General Public License
00015 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 *
00017 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
00018 *              Marco Trevisan <marco.trevisan@canonical.com>
00019 */
00020 
00021 #ifndef UNITY_GLIB_SIGNAL_H
00022 #define UNITY_GLIB_SIGNAL_H
00023 
00024 #include <string>
00025 #include <vector>
00026 #include <memory>
00027 #include <boost/noncopyable.hpp>
00028 #include <glib-object.h>
00029 #include <sigc++/sigc++.h>
00030 
00031 namespace unity
00032 {
00033 namespace glib
00034 {
00035 
00036 class SignalBase : boost::noncopyable
00037 {
00038 public:
00039   typedef std::shared_ptr<SignalBase> Ptr;
00040 
00041   virtual ~SignalBase();
00042 
00043   void Disconnect();
00044 
00045   GObject* object() const;
00046   std::string const& name() const;
00047 
00048 protected:
00049   SignalBase();
00050 
00051   GObject* object_;
00052   guint32 connection_id_;
00053   std::string name_;
00054 };
00055 
00056 template <typename R, typename G, typename... Ts>
00057 class Signal : public SignalBase
00058 {
00059 public:
00060 /* Versions of GCC prior to 4.7 doesn't support the Ts... expansion, we can
00061  * workaround this issue using the trick below.
00062  * See GCC bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35722 */
00063 #if !defined(__GNUC__) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 7)
00064   typedef sigc::slot<R, G, Ts...> SignalCallback;
00065 #else
00066   template<template <typename...> class T, typename... params>
00067   struct expand_variadic {
00068       typedef T<params...> type;
00069   };
00070 
00071   typedef typename expand_variadic<sigc::slot, R, G, Ts...>::type SignalCallback;
00072 #endif
00073 
00074   inline Signal() {};
00075   inline Signal(G object, std::string const& signal_name, SignalCallback const& callback);
00076 
00077   inline void Connect(G Object, std::string const& signal_name, SignalCallback const& callback);
00078 
00079 private:
00080   static R Callback(G Object, Ts... vs, Signal* self);
00081 
00082   SignalCallback callback_;
00083 };
00084 
00085 class SignalManager : boost::noncopyable
00086 {
00087 public:
00088   SignalManager();
00089   void Add(SignalBase* signal);
00090   void Add(SignalBase::Ptr const& signal);
00091   template <typename R, typename G, typename... Ts>
00092   void Add(G object, std::string const& signal_name, typename Signal<R, G, Ts...>::SignalCallback const& callback)
00093   {
00094     Add(std::make_shared<Signal<R, G, Ts...>>(object, signal_name, callback));
00095   }
00096 
00097   void Disconnect(void* object, std::string const& signal_name = "");
00098 
00099 protected:
00100   std::vector<SignalBase::Ptr> connections_;
00101 };
00102 
00103 }
00104 }
00105 
00106 #include "GLibSignal-inl.h"
00107 
00108 #endif