Merge lp:~njpatel/unity/nicer-glib-signals into lp:unity

Proposed by Neil J. Patel on 2011-07-09
Status: Merged
Merged at revision: 1291
Proposed branch: lp:~njpatel/unity/nicer-glib-signals
Merge into: lp:unity
Diff against target: 1961 lines (+1361/-170)
34 files modified
CMakeLists.txt (+3/-3)
UnityCore/CMakeLists.txt (+3/-1)
UnityCore/DBusIndicators.cpp (+79/-83)
UnityCore/GLibSignal-inl.h (+299/-0)
UnityCore/GLibSignal.cpp (+87/-0)
UnityCore/GLibSignal.h (+307/-0)
UnityCore/UnityCore.h (+0/-32)
plugins/unityshell/src/FavoriteStoreGSettings.h (+1/-1)
plugins/unityshell/src/IconTexture.cpp (+8/-7)
plugins/unityshell/src/Launcher.cpp (+1/-1)
plugins/unityshell/src/LauncherIcon.cpp (+1/-1)
plugins/unityshell/src/PanelHomeButton.cpp (+1/-1)
plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp (+2/-1)
plugins/unityshell/src/PanelIndicatorObjectEntryView.h (+1/-1)
plugins/unityshell/src/PanelIndicatorObjectView.h (+1/-1)
plugins/unityshell/src/PanelMenuView.cpp (+1/-1)
plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp (+1/-1)
plugins/unityshell/src/PanelTray.h (+0/-2)
plugins/unityshell/src/PanelView.cpp (+1/-1)
plugins/unityshell/src/PanelView.h (+1/-1)
plugins/unityshell/src/PlacesHomeView.cpp (+1/-1)
plugins/unityshell/src/PlacesSearchBar.cpp (+1/-1)
plugins/unityshell/src/PlacesSimpleTile.cpp (+1/-1)
plugins/unityshell/src/PlacesView.cpp (+1/-1)
plugins/unityshell/src/QuicklistMenuItem.cpp (+1/-1)
plugins/unityshell/src/WindowButtons.cpp (+10/-20)
po/unity.pot (+1/-1)
tests/CMakeLists.txt (+16/-4)
tests/test_glib_signals.cpp (+366/-0)
tests/test_glib_signals_utils.cpp (+102/-0)
tests/test_glib_signals_utils.h (+46/-0)
tests/test_glib_signals_utils_marshal.list (+6/-0)
tests/test_indicator_entry.cpp (+1/-1)
tests/test_main.cpp (+10/-0)
To merge this branch: bzr merge lp:~njpatel/unity/nicer-glib-signals
Reviewer Review Type Date Requested Status
Tim Penhey (community) 2011-07-09 Approve on 2011-07-15
Unity Team 2011-07-09 Pending
Review via email: mp+67439@code.launchpad.net

Description of the change

This branch adds support for a cleaner way to connect to signals on GObjects inside Unity.

The idea behind the branch is that, with the current way, we need to take care of a few very annoying things:
- Connect the signal to a static member in our class and access members/variables from the callback via "self->"
- We need to remember to disconnect the signals (g_signal_handler_disconnect) when our class destructs. This means we need to keep around the signal id returned from g_signal_connect, as well as remember to disconnect in our destructor.

Both of these things have led to clumsy/cluttered code, or bugs where we've accidentally looked over something (like disconnecting).

The idea behind this branch is to:
- Allow the calling class to connect to signals on a GObject using sigc::slots (either sigc::ptr_fun or, more likely, sigc::mem_fun).
- Automatically handle disconnection of the signal on destruction of a Signal instance.
- Add a SignalManager class to manage multiple connections to different GObjects for an object. It will automatically disconnect the signals when it destructs.

Both these things mean that it's possible to ditch the multiple "static void Foo", "guint my_signal_id_", and "g_signal_handler_disconnect", from a class and replace with a simple "SignalManager signal_manger_" variable.

= API/Code =

I've tried to make it as clean as possible to use API-wise. My only real regret is having to use "new Signal<..." with a smartpointer to pass Signal instances to the SignalManager class. As explained in the code, this was mostly to strike a balance between a clean API and also to reduce the likelihood of bugs being introduced if the Signal class was passed in by reference and it's details "stolen" from it by the instance in the Vector (only one Signal class should manage a unique connection at any time).

Apart from that, I heard you like templates, so I put templates in your templates, so you can derive when you derive.

Oh, there're tests.

To post a comment you must log in.
lp:~njpatel/unity/nicer-glib-signals updated on 2011-07-09
1287. By Neil J. Patel on 2011-07-09

[merge] trunk

1288. By Neil J. Patel on 2011-07-09

Some cleanups

Sam Spilsbury (smspillaz) wrote :

Yo Dawg,

I went a little deeper into this code and found that in tests/ you've added what looks like generated marshallers for glib callbacks. It might be better to autogenerate that a build time instead of shipping it in the source distribution since the *.list could change whenever we need a new marshaller. For example

add_executable (test-signals ... ${CMAKE_CURRENT_BINARY_DIR}/generated/test_glib_signals_utils_marshal.cpp
...)

file (MAKE_DIRECTORY ${CMAKE_CURRENT_BUILD_DIR}/generated)
add_custom_command (TARGET test-signals PRE_BUILD
COMMAND glib-genmarshals ${CMAKE_CURRENT_SOURCE_DIR}/test_glib_signals_utils_marshal.list
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)

That way we can create and perceive the marshallers at the same time, without the person doing the compiling ever knowing that!

(I can't comment on the nature of the code itself, knowing little about glib, however I do intend to run the tests and try it out)

lp:~njpatel/unity/nicer-glib-signals updated on 2011-07-10
1289. By Neil J. Patel on 2011-07-10

Duh, commit and push all the work before merge review

Neil J. Patel (njpatel) wrote :

Thanks for reminding me, totally forgot to commit and push the generation before proposing the merge.

We already do this in services/CMakeFiles.txt, however the difference was that with all the funky new g++ flags we use, the code glib produces no longer compiles with g++, so had to add a small workaround for that for now. Going to see if I can just patch glib-genmarshal when I get some time.

lp:~njpatel/unity/nicer-glib-signals updated on 2011-07-10
1290. By Neil J. Patel on 2011-07-10

some style fixes

Tim Penhey (thumper) wrote :

OK Neil,

Well your description makes me keen to look at the code :-)

First question, since we are looking to use more glib stuff inside nux itself,
do you think perhaps the GLibSignal headers should go into nux itself?

Looking at a line like this:

  signal_manager_.Add (new glib::Signal<void, GDBusProxy*, char*, char*, GVariant*>
    (proxy_, "g-signal", sigc::mem_fun(this, &Impl::OnProxySignalReceived)));

It makes me wonder if we could simplify it. Given that the compiler has
enough type inference based on the sigc::mem_fun, we could perhaps get the
compiler to work out what glib::Signal we need, so we don't need to specify
it. I'm not entirely clear on the magic needed, but I'm 99% sure that it
could be done, allowing something like:

  signal_manager_.Add(proxy_, "g-signal",
                      sigc::mem_fun(this, &Impl::OnProxySignalReceived));

Perhaps for later...

Authored by in UnityCore/GLibSignal-inl.h, do you want to capitalise patel?

Please don't use capital O, or lowercase L for any single character variables
or type markers. It becomes non-obvious as zero is a valid template arg
(if the template is expecting an int tempate param).

Also, aligning the params in a multiline arguement clause actually hinders
readability (for me) - see the "O object"

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Function_Names
recommends that the accessors look like:

  GObject* object() const;
  std::string const& name() const;

The Signal template class constructor should take the std::string as a const&.

You should make the SignalManager non-copyable, and it doesn't need to define
a destructor, and certainly not a virtual destructor. The add method should
take SignalBase::Ptr const& as the param, not SignalBase*.

UnityCore/UnityCore.h makes me sad. Can we delete it?

I'm not clear on why you want the GObject type defined in the Signal template
parameteres. It seems to me that they could be removed completely and just
use a GObject*. Oh... I see now. It is the first param to the callback.
This was a little confusing as you have the first param given a special name.

Comments in tests are OK :-) I'd like to know what
TestGLibSignals.TestCleanDestruction is testing exactly.

Also, why do you sometimes pass in the address of a gboolean to
g_signal_emit_by_name?

I don't undestand the gobject test signal class and marshallers, but I'll
trust you on that.

On the whole, a bit +1 from me, but ask if you want to fix the Add method to
not need new signal ...

review: Needs Information
lp:~njpatel/unity/nicer-glib-signals updated on 2011-07-11
1291. By Neil J. Patel on 2011-07-11

Don't use upper case o

1292. By Neil J. Patel on 2011-07-11

get_foo/foo

1293. By Neil J. Patel on 2011-07-11

Use std::string const& in Signal template

1294. By Neil J. Patel on 2011-07-11

Remove Signal manager destructor

Tim Penhey (thumper) wrote :

r1294 fails to compile for me locally... I'm looking into it.

Tim Penhey (thumper) wrote :

CMakeFiles/test-gtest.dir/test_glib_signals.cpp.o: In function `(anonymous namespace)::TestGLibSignals_TestConstructions_Test::TestBody()':
test_glib_signals.cpp:(.text+0x4f5): undefined reference to `unity::glib::SignalBase::SignalBase()'
test_glib_signals.cpp:(.text+0x69f): undefined reference to `unity::glib::SignalBase::~SignalBase()'
test_glib_signals.cpp:(.text+0x7bc): undefined reference to `unity::glib::SignalBase::~SignalBase()'

and many more. It seems that the test is trying to link against the installed unity-core library rather than the one it has just compiled. Ideas?

lp:~njpatel/unity/nicer-glib-signals updated on 2011-07-13
1295. By Neil J. Patel on 2011-07-12

Prioritise library in UnityCore

1296. By Neil J. Patel on 2011-07-13

Switch to sigc::nil

1297. By Neil J. Patel on 2011-07-13

[merge] trunk

1298. By Neil J. Patel on 2011-07-13

[merge] c++0x support

1299. By Neil J. Patel on 2011-07-13

cleanup

Neil J. Patel (njpatel) wrote :
Download full text (3.5 KiB)

> OK Neil,
>
> Well your description makes me keen to look at the code :-)
>
> First question, since we are looking to use more glib stuff inside nux itself,
> do you think perhaps the GLibSignal headers should go into nux itself?

Sure, though let's get through a review here and then I can move over to Nux.

> Looking at a line like this:
>
> signal_manager_.Add (new glib::Signal<void, GDBusProxy*, char*, char*,
> GVariant*>
> (proxy_, "g-signal", sigc::mem_fun(this, &Impl::OnProxySignalReceived)));
>
> It makes me wonder if we could simplify it. Given that the compiler has
> enough type inference based on the sigc::mem_fun, we could perhaps get the
> compiler to work out what glib::Signal we need, so we don't need to specify
> it. I'm not entirely clear on the magic needed, but I'm 99% sure that it
> could be done, allowing something like:
>
> signal_manager_.Add(proxy_, "g-signal",
> sigc::mem_fun(this, &Impl::OnProxySignalReceived));

> Perhaps for later...

So, I implemented what we spoke about, however the compiler refuses to let it happen. It expects sigc::slot to be declared with the template types rather than being able to infer them from passes in sigc::bound_mem_functorN

Changing the arguments to take a sigc::bound_mem_functorN (where N is number of args), worked, but this is not a low-level class you can pass around, you'd need to create overrides for all the different types of functor's to make it work.

I'm not against that, but I'm hoping I messed something up that another pair of eyes can take a look at. I've moved everything to sigc::nil, could you try your idea out and let me know if you've more luck with it?

> Authored by in UnityCore/GLibSignal-inl.h, do you want to capitalise patel?
>
> Please don't use capital O, or lowercase L for any single character variables
> or type markers. It becomes non-obvious as zero is a valid template arg
> (if the template is expecting an int tempate param).

Both fixed.

> Also, aligning the params in a multiline arguement clause actually hinders
> readability (for me) - see the "O object"

I like it the way it is but not enough to care, can make that change before committing.

> http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Function_Names
> recommends that the accessors look like:
>
> GObject* object() const;
> std::string const& name() const;
>
> The Signal template class constructor should take the std::string as a const&.
>
> You should make the SignalManager non-copyable, and it doesn't need to define
> a destructor, and certainly not a virtual destructor.

All fixed.

> The add method should
> take SignalBase::Ptr const& as the param, not SignalBase*.

Hmm, doing this means that manager->Add becomes Add(SignalBase::Ptr(new Signal<void, GObject*, Bar*> (..... I don't like this. Am I missing something on how this would work? If the idea above works this is moot anyway.

> UnityCore/UnityCore.h makes me sad. Can we delete it?

Why?

> Comments in tests are OK :-) I'd like to know what
> TestGLibSignals.TestCleanDestruction is testing exactly.

If the object is no longer around, we shouldn't do anything stu...

Read more...

lp:~njpatel/unity/nicer-glib-signals updated on 2011-07-13
1300. By Neil J. Patel on 2011-07-13

Make SignalManager noncopyable

Tim Penhey (thumper) wrote :

Hi Neil,

After several hours of fluffing around trying to get a nicer Add method, I've
given up as well. It seems that the sigc wrappers don't give us access to the
type information for the function call arguments. We could perhaps submit a
patch to the sigc guys, but not with this branch.

I forgot that the shared_ptr has an explicit constructor, so passing through
the shared pointer would be a bit cumbersome as you mention. So lets not
worry about that here.

By having UnityCore/UnityCore.h we are pulling in headers that we don't care
about, and creating an artificial dependency between our code and other
headers that have no impact on the code in the source file. This increases
coupling between the files and increases compilation time.

review: Approve
Tim Penhey (thumper) wrote :

Actually, can you just change the using namespace sigc in the header to "using sigc::nul" ?

You should never have a using namespace * in a header.

lp:~njpatel/unity/nicer-glib-signals updated on 2011-07-15
1301. By Neil J. Patel on 2011-07-15

[merge] trunk

1302. By Neil J. Patel on 2011-07-15

s/using namepspace sigc/using sigc::nil/

1303. By Neil J. Patel on 2011-07-15

Get rid of UnityCore.h

1304. By Neil J. Patel on 2011-07-15

Try to not pad out the parameters for a method

Neil J. Patel (njpatel) wrote :

Okay, so last few commits should hopefully make this good for merge. Getting rid of UnityCore.h must have inflated the diff a bit but couldn't help that.

Neil J. Patel (njpatel) wrote :

Ah, forgot to answer the gboolean comment on this and Jason's merge proposal properly: bool and gboolean can be different sizes because "typedef int gboolean" (on my system sizeof(bool) = 1 and sizeof(gboolean)=4). As timeouts, signal-accumulators etc are often used by sending in a return location for the result (maybe from higher up in the callstack), sending a bool where glib expects to accumulate a gboolean causes all sorts of fun errors (timeouts sometimes return false but that is evaluated to TRUE, ask Sam :) and for things like GVariant we can easily cause memory errors.

So, since tackling a lot of this at the end of the last cycle (we managed to fix some of the worst crashes by auditing the bool/gboolean code), I've tried to make absolutely sure that we don't mix them up at all, even if it might be okay in some cases, I'd rather be more strict about it.

Ideally we'd reach a point where the few areas where we hit gboolean/guint32/etc/etc are handled by a wrapper that does the conversion back into standard C++ types internally and safely.

Sam Spilsbury (smspillaz) wrote :

Yep, that's static_cast <gboolean> ((bool) false) == TRUE :)

Tim Penhey (thumper) wrote :

On Mon, 18 Jul 2011 02:56:22 you wrote:
> Yep, that's static_cast <gboolean> ((bool) false) == TRUE :)

Casting can the be the source of many many problems. This is just one of the
reasons I don't like them.

They are a useful tool, but just because you have a hammer doesn't mean you
need to hit everything with it.

Neil J. Patel (njpatel) wrote :

Honestly I just do bool foo = my_gboolean == TRUE;

Seems the safest to me :)

Sent from my iPhone

On 17 Jul 2011, at 15:56, Sam Spilsbury <email address hidden> wrote:

> Yep, that's static_cast <gboolean> ((bool) false) == TRUE :)
>
> --
> https://code.launchpad.net/~njpatel/unity/nicer-glib-signals/+merge/67439
> You are the owner of lp:~njpatel/unity/nicer-glib-signals.

Tim Penhey (thumper) wrote :

On Mon, 18 Jul 2011 09:42:36 you wrote:
> Honestly I just do bool foo = my_gboolean == TRUE;
>
> Seems the safest to me :)

bool foo = my_gboolean is fine.

it is the casting of a bool to gboolean that is the issue.

The big issue here is exactly the above:

gboolean foo = 42; // entirely valid

foo -> true
bool(foo) -> true
foo != FALSE -> true
foo == TRUE -> false !!!!

We should not be doing == TRUE anywhere.

TRUE is defined to be !FALSE.
FALSE is defined to be 0.

The C (and C++) standard say that 0 is false, and anything else is considered
to be true. If we are checking for equality to TRUE on an integral type, we
may well have situations where the variable is neither TRUE nor FALSE. We
should only ever check for FALSE, or != FALSE. Checking for TRUE is a world
of pain for integral types.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2011-07-10 14:16:30 +0000
3+++ CMakeLists.txt 2011-07-15 10:26:29 +0000
4@@ -16,9 +16,9 @@
5 set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}")
6 set (UNITY_API_VERSION "4.0")
7
8-set (CMAKE_CXX_FLAGS "-fno-permissive")
9-set (CMAKE_CXX_FLAGS_DEBUG "-fno-permissive")
10-set (CMAKE_CXX_FLAGS_RELEASE "-fno-permissive")
11+set (CMAKE_CXX_FLAGS "-std=c++0x -fno-permissive")
12+set (CMAKE_CXX_FLAGS_DEBUG "-std=c++0x -fno-permissive")
13+set (CMAKE_CXX_FLAGS_RELEASE "-std=c++0x -fno-permissive")
14
15 #
16 # Niceties
17
18=== modified file 'UnityCore/CMakeLists.txt'
19--- UnityCore/CMakeLists.txt 2011-06-22 14:08:16 +0000
20+++ UnityCore/CMakeLists.txt 2011-07-15 10:26:29 +0000
21@@ -6,17 +6,19 @@
22 #
23 set (CORE_HEADERS
24 DBusIndicators.h
25+ GLibSignal.h
26+ GLibSignal-inl.h
27 GLibWrapper.h
28 GLibWrapper-inl.h
29 IndicatorEntry.h
30 Indicator.h
31 Indicators.h
32- UnityCore.h
33 Variant.h
34 )
35
36 set (CORE_SOURCES
37 DBusIndicators.cpp
38+ GLibSignal.cpp
39 GLibWrapper.cpp
40 Indicator.cpp
41 IndicatorEntry.cpp
42
43=== modified file 'UnityCore/DBusIndicators.cpp'
44--- UnityCore/DBusIndicators.cpp 2011-06-29 15:40:49 +0000
45+++ UnityCore/DBusIndicators.cpp 2011-07-15 10:26:29 +0000
46@@ -27,6 +27,7 @@
47 #include <X11/Xlib.h>
48
49 #include "config.h"
50+#include "GLibSignal.h"
51 #include "GLibWrapper.h"
52 #include "Variant.h"
53
54@@ -83,12 +84,6 @@
55 bool run_local_panel_service();
56 gboolean reconnect_to_service(gpointer data);
57 void on_proxy_ready_cb(GObject* source, GAsyncResult* res, gpointer data);
58-void on_proxy_name_owner_changed(GDBusProxy* proxy, GParamSpec* pspec,
59- DBusIndicators::Impl* remote);
60-void on_proxy_signal_received(GDBusProxy* proxy,
61- char* sender_name, char* signal_name,
62- GVariant* parameters,
63- DBusIndicators::Impl* remote);
64 void request_sync(GDBusProxy* proxy, const char* method, GVariant* name,
65 SyncData* data);
66 void on_sync_ready_cb(GObject* source, GAsyncResult* res, gpointer data);
67@@ -113,6 +108,11 @@
68 void Sync(GVariant* args, SyncData* data);
69 void SyncGeometries(std::string const& name,
70 EntryLocationMap const& locations);
71+ void OnProxyNameOwnerChanged(GDBusProxy*proxy, GParamSpec *pspec);
72+ void OnProxySignalReceived(GDBusProxy* proxy,
73+ char* sender_name,
74+ char* signal_name_,
75+ GVariant* parameters);
76
77 virtual void OnEntryScroll(std::string const& entry_id, int delta);
78 virtual void OnEntryShowMenu(std::string const& entry_id,
79@@ -124,10 +124,10 @@
80
81 DBusIndicators* owner_;
82 GDBusProxy* proxy_;
83- guint32 proxy_signal_id_;
84- guint32 proxy_name_id_;
85 typedef std::vector<SyncDataPtr> PendingSyncs;
86 PendingSyncs pending_syncs_;
87+
88+ glib::SignalManager signal_manager_;
89 };
90
91
92@@ -143,8 +143,6 @@
93 {
94 if (G_IS_OBJECT (proxy_))
95 {
96- g_signal_handler_disconnect(proxy_, proxy_signal_id_);
97- g_signal_handler_disconnect(proxy_, proxy_name_id_);
98 g_object_unref(proxy_);
99 }
100 }
101@@ -178,12 +176,11 @@
102 {
103 proxy_ = proxy;
104 // Connect to interesting signals
105- proxy_signal_id_ = g_signal_connect(proxy_, "g-signal",
106- G_CALLBACK(on_proxy_signal_received),
107- this);
108- proxy_name_id_ = g_signal_connect(proxy_, "notify::g-name-owner",
109- G_CALLBACK(on_proxy_name_owner_changed),
110- this);
111+ signal_manager_.Add (new glib::Signal<void, GDBusProxy*, char*, char*, GVariant*>
112+ (proxy_, "g-signal", sigc::mem_fun(this, &Impl::OnProxySignalReceived)));
113+
114+ signal_manager_.Add(new glib::Signal<void, GDBusProxy*,GParamSpec*>
115+ (proxy_, "notify::g-name-owner", sigc::mem_fun(this, &Impl::OnProxyNameOwnerChanged)));
116 }
117 RequestSyncAll();
118 }
119@@ -373,6 +370,72 @@
120 return g_getenv("PANEL_USE_LOCAL_SERVICE") != NULL;
121 }
122
123+void DBusIndicators::Impl::OnProxyNameOwnerChanged(GDBusProxy* proxy,
124+ GParamSpec* pspec)
125+{
126+ char* name_owner = g_dbus_proxy_get_name_owner(proxy);
127+
128+ if (name_owner == NULL)
129+ {
130+ // The panel service has stopped for some reason. Restart it if not in
131+ // dev mode
132+ if (!g_getenv("UNITY_DEV_MODE"))
133+ Reconnect();
134+ }
135+
136+ g_free (name_owner);
137+}
138+
139+void DBusIndicators::Impl::OnProxySignalReceived(GDBusProxy* proxy,
140+ char* sender_name,
141+ char* signal_name_,
142+ GVariant* parameters)
143+{
144+ std::string signal_name(signal_name_);
145+ if (signal_name == "EntryActivated")
146+ {
147+ const char* entry_name = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL);
148+ if (entry_name) {
149+ owner_->ActivateEntry(entry_name);
150+ }
151+ }
152+ else if (signal_name == "EntryActivateRequest")
153+ {
154+ const char* entry_name = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL);
155+ if (entry_name) {
156+ owner_->on_entry_activate_request.emit(entry_name);
157+ }
158+ }
159+ else if (signal_name == "ReSync")
160+ {
161+ const char* id = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL);
162+ bool sync_one = !g_strcmp0 (id, "") == 0;
163+
164+ if (sync_one) {
165+ RequestSyncIndicator(id);
166+ }
167+ else {
168+ RequestSyncAll();
169+ }
170+ }
171+ else if (signal_name == "ActiveMenuPointerMotion")
172+ {
173+ int x = 0;
174+ int y = 0;
175+ g_variant_get (parameters, "(ii)", &x, &y);
176+ owner_->on_menu_pointer_moved.emit(x, y);
177+ }
178+ else if (signal_name == "EntryShowNowChanged")
179+ {
180+ gchar *id = NULL;
181+ gboolean show_now;
182+
183+ g_variant_get (parameters, "(sb)", &id, &show_now);
184+ owner_->SetEntryShowNow(id, show_now);
185+
186+ g_free (id);
187+ }
188+}
189
190 DBusIndicators::DBusIndicators()
191 : pimpl(new Impl(this))
192@@ -495,73 +558,6 @@
193 return true;
194 }
195
196-void on_proxy_signal_received(GDBusProxy* proxy,
197- char* sender_name, char* signal_name_,
198- GVariant* parameters,
199- DBusIndicators::Impl* remote)
200-{
201- std::string signal_name(signal_name_);
202- if (signal_name == "EntryActivated")
203- {
204- const char* entry_name = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL);
205- if (entry_name) {
206- remote->owner_->ActivateEntry(entry_name);
207- }
208- }
209- else if (signal_name == "EntryActivateRequest")
210- {
211- const char* entry_name = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL);
212- if (entry_name) {
213- remote->owner_->on_entry_activate_request.emit(entry_name);
214- }
215- }
216- else if (signal_name == "ReSync")
217- {
218- const char* id = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL);
219- bool sync_one = !g_strcmp0 (id, "") == 0;
220-
221- if (sync_one) {
222- remote->RequestSyncIndicator(id);
223- }
224- else {
225- remote->RequestSyncAll();
226- }
227- }
228- else if (signal_name == "ActiveMenuPointerMotion")
229- {
230- int x = 0;
231- int y = 0;
232- g_variant_get (parameters, "(ii)", &x, &y);
233- remote->owner_->on_menu_pointer_moved.emit(x, y);
234- }
235- else if (signal_name == "EntryShowNowChanged")
236- {
237- gchar *id = NULL;
238- gboolean show_now;
239-
240- g_variant_get (parameters, "(sb)", &id, &show_now);
241- remote->owner_->SetEntryShowNow(id, show_now);
242-
243- g_free (id);
244- }
245-}
246-
247-void on_proxy_name_owner_changed(GDBusProxy* proxy, GParamSpec* pspec,
248- DBusIndicators::Impl* remote)
249-{
250- char* name_owner = g_dbus_proxy_get_name_owner(proxy);
251-
252- if (name_owner == NULL)
253- {
254- // The panel service has stopped for some reason. Restart it if not in
255- // dev mode
256- if (!g_getenv("UNITY_DEV_MODE"))
257- remote->Reconnect();
258- }
259-
260- g_free (name_owner);
261-}
262-
263 void request_sync(GDBusProxy* proxy, const char* method, GVariant* name, SyncData* data)
264 {
265 g_dbus_proxy_call(proxy, method, name, G_DBUS_CALL_FLAGS_NONE,
266
267=== added file 'UnityCore/GLibSignal-inl.h'
268--- UnityCore/GLibSignal-inl.h 1970-01-01 00:00:00 +0000
269+++ UnityCore/GLibSignal-inl.h 2011-07-15 10:26:29 +0000
270@@ -0,0 +1,299 @@
271+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
272+/*
273+* Copyright (C) 2011 Canonical Ltd
274+*
275+* This program is free software: you can redistribute it and/or modify
276+* it under the terms of the GNU General Public License version 3 as
277+* published by the Free Software Foundation.
278+*
279+* This program is distributed in the hope that it will be useful,
280+* but WITHOUT ANY WARRANTY; without even the implied warranty of
281+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
282+* GNU General Public License for more details.
283+*
284+* You should have received a copy of the GNU General Public License
285+* along with this program. If not, see <http://www.gnu.org/licenses/>.
286+*
287+* Authored by: Neil Jagdish patel <neil.patel@canonical.com>
288+*/
289+
290+#ifndef UNITY_GLIB_SIGNAL_INL_H
291+#define UNITY_GLIB_SIGNAL_INL_H
292+
293+namespace unity {
294+namespace glib {
295+
296+template <typename R, typename G>
297+Signal0<R, G>::Signal0()
298+{}
299+
300+template <typename R, typename G>
301+void Signal0<R, G>::Connect(G object,
302+ std::string const& signal_name,
303+ SignalCallback callback)
304+{
305+ object_ = reinterpret_cast<GObject*>(object);
306+ name_ = signal_name;
307+ callback_ = callback;
308+ connection_id_ = g_signal_connect(object, signal_name.c_str (),
309+ G_CALLBACK(Callback), this);
310+}
311+
312+template <typename R, typename G>
313+R Signal0<R, G>::Callback(G object, Signal0* self)
314+{
315+ return self->callback_(object);
316+}
317+
318+template <typename R, typename G, typename T>
319+Signal1<R, G, T>::Signal1()
320+{}
321+
322+template <typename R, typename G, typename T>
323+void Signal1<R, G, T>::Connect(G object,
324+ std::string const& signal_name,
325+ SignalCallback callback)
326+{
327+ object_ = reinterpret_cast<GObject*>(object);
328+ name_ = signal_name;
329+ callback_ = callback;
330+ connection_id_ = g_signal_connect(object, signal_name.c_str (),
331+ G_CALLBACK(Callback), this);
332+}
333+
334+template <typename R, typename G, typename T>
335+R Signal1<R, G, T>::Callback(G object, T data1, Signal1* self)
336+{
337+ return self->callback_(object, data1);
338+}
339+
340+template <typename R, typename G, typename T1, typename T2>
341+Signal2<R, G, T1, T2>::Signal2()
342+{}
343+
344+template <typename R, typename G, typename T1, typename T2>
345+void Signal2<R, G, T1, T2>::Connect(G object,
346+ std::string const& signal_name,
347+ SignalCallback callback)
348+{
349+ object_ = reinterpret_cast<GObject*>(object);
350+ name_ = signal_name;
351+ callback_ = callback;
352+ connection_id_ = g_signal_connect(object, signal_name.c_str (),
353+ G_CALLBACK (Callback), this);
354+}
355+
356+template <typename R, typename G, typename T1, typename T2>
357+R Signal2<R, G, T1, T2>::Callback(G object,
358+ T1 data1,
359+ T2 data2,
360+ Signal2* self)
361+{
362+ return self->callback_(object, data1, data2);
363+}
364+
365+template <typename R, typename G, typename T1, typename T2, typename T3>
366+Signal3<R, G, T1, T2, T3>::Signal3()
367+{}
368+
369+template <typename R, typename G, typename T1, typename T2, typename T3>
370+void Signal3<R, G, T1, T2, T3>::Connect(G object,
371+ std::string const& signal_name,
372+ SignalCallback callback)
373+{
374+ object_ = reinterpret_cast<GObject*>(object);
375+ name_ = signal_name;
376+ callback_ = callback;
377+ connection_id_ = g_signal_connect(object, signal_name.c_str (),
378+ G_CALLBACK (Callback), this);
379+}
380+
381+template <typename R, typename G, typename T1, typename T2, typename T3>
382+R Signal3<R, G, T1, T2, T3>::Callback(G object,
383+ T1 data1,
384+ T2 data2,
385+ T3 data3,
386+ Signal3* self)
387+{
388+ return self->callback_(object, data1, data2, data3);
389+}
390+
391+template <typename R, typename G, typename T1, typename T2, typename T3, typename T4>
392+Signal4<R, G, T1, T2, T3, T4>::Signal4()
393+{}
394+
395+template <typename R, typename G, typename T1, typename T2, typename T3, typename T4>
396+void Signal4<R, G, T1, T2, T3, T4>::Connect(G object,
397+ std::string const& signal_name,
398+ SignalCallback callback)
399+{
400+ object_ = reinterpret_cast<GObject*>(object);
401+ name_ = signal_name;
402+ callback_ = callback;
403+ connection_id_ = g_signal_connect(object, signal_name.c_str (),
404+ G_CALLBACK (Callback), this);
405+}
406+
407+template <typename R, typename G, typename T1, typename T2, typename T3, typename T4>
408+R Signal4<R, G, T1, T2, T3, T4>::Callback(G object,
409+ T1 data1,
410+ T2 data2,
411+ T3 data3,
412+ T4 data4,
413+ Signal4* self)
414+{
415+ return self->callback_(object, data1, data2, data3, data4);
416+}
417+
418+
419+template <typename R, typename G, typename T1, typename T2,
420+ typename T3, typename T4, typename T5>
421+Signal5<R, G, T1, T2, T3, T4, T5>::Signal5()
422+{}
423+
424+template <typename R, typename G, typename T1, typename T2,
425+ typename T3, typename T4, typename T5 >
426+void Signal5<R, G, T1, T2, T3, T4, T5>::Connect(G object,
427+ std::string const& signal_name,
428+ SignalCallback callback)
429+{
430+ object_ = reinterpret_cast<GObject*>(object);
431+ name_ = signal_name;
432+ callback_ = callback;
433+ connection_id_ = g_signal_connect(object, signal_name.c_str (),
434+ G_CALLBACK (Callback), this);
435+}
436+
437+template <typename R, typename G, typename T1, typename T2,
438+ typename T3, typename T4, typename T5>
439+R Signal5<R, G, T1, T2, T3, T4, T5>::Callback(G object,
440+ T1 data1,
441+ T2 data2,
442+ T3 data3,
443+ T4 data4,
444+ T5 data5,
445+ Signal5* self)
446+{
447+ return self->callback_(object, data1, data2, data3, data4, data5);
448+}
449+
450+template <typename R, typename G, typename T1, typename T2,
451+ typename T3, typename T4, typename T5 , typename T6>
452+Signal6<R, G, T1, T2, T3, T4, T5, T6>::Signal6()
453+{}
454+
455+template <typename R, typename G, typename T1, typename T2,
456+ typename T3, typename T4, typename T5 , typename T6>
457+void Signal6<R, G, T1, T2, T3, T4, T5, T6>::Connect(G object,
458+ std::string const& signal_name,
459+ SignalCallback callback)
460+{
461+ object_ = reinterpret_cast<GObject*>(object);
462+ name_ = signal_name;
463+ callback_ = callback;
464+ connection_id_ = g_signal_connect(object, signal_name.c_str (),
465+ G_CALLBACK (Callback), this);
466+}
467+
468+template <typename R, typename G, typename T1, typename T2,
469+ typename T3, typename T4, typename T5, typename T6>
470+R Signal6<R, G, T1, T2, T3, T4, T5, T6>::Callback(G object,
471+ T1 data1,
472+ T2 data2,
473+ T3 data3,
474+ T4 data4,
475+ T5 data5,
476+ T6 data6,
477+ Signal6* self)
478+{
479+ return self->callback_(object, data1, data2, data3, data4, data5, data6);
480+}
481+
482+template<typename R, typename G>
483+Signal<R, G>::Signal()
484+{}
485+
486+template<typename R, typename G>
487+Signal<R, G>::Signal(G object, std::string const& signal_name, SignalCallback callback)
488+{
489+ Connect(object, signal_name, callback);
490+}
491+
492+template<typename R, typename G, typename T1>
493+Signal<R, G, T1>::Signal()
494+{}
495+
496+template<typename R, typename G, typename T1>
497+Signal<R, G, T1>::Signal(G object, std::string const& signal_name, SignalCallback callback)
498+{
499+ Connect(object, signal_name, callback);
500+}
501+
502+template<typename R, typename G, typename T1, typename T2>
503+Signal<R, G, T1, T2>::Signal()
504+{}
505+
506+template<typename R, typename G, typename T1, typename T2>
507+Signal<R, G, T1, T2>::Signal(G object,
508+ std::string const& signal_name,
509+ SignalCallback callback)
510+{
511+ Connect(object, signal_name, callback);
512+}
513+
514+template<typename R, typename G, typename T1, typename T2, typename T3>
515+Signal<R, G, T1, T2, T3>::Signal()
516+{}
517+
518+template<typename R, typename G, typename T1, typename T2, typename T3>
519+Signal<R, G, T1, T2, T3>::Signal(G object,
520+ std::string const& signal_name,
521+ SignalCallback callback)
522+{
523+ Connect(object, signal_name, callback);
524+}
525+
526+template<typename R, typename G, typename T1, typename T2, typename T3, typename T4>
527+Signal<R, G, T1, T2, T3, T4>::Signal()
528+{}
529+
530+template<typename R, typename G, typename T1, typename T2, typename T3, typename T4>
531+Signal<R, G, T1, T2, T3, T4>::Signal(G object,
532+ std::string const& signal_name,
533+ SignalCallback callback)
534+{
535+ Connect(object, signal_name, callback);
536+}
537+
538+template<typename R, typename G, typename T1, typename T2, typename T3, typename T4,
539+ typename T5>
540+Signal<R, G, T1, T2, T3, T4, T5>::Signal()
541+{}
542+
543+template<typename R, typename G, typename T1, typename T2, typename T3, typename T4,
544+ typename T5>
545+Signal<R, G, T1, T2, T3, T4, T5>::Signal(G object,
546+ std::string const& signal_name,
547+ SignalCallback callback)
548+{
549+ Connect(object, signal_name, callback);
550+}
551+
552+template<typename R, typename G, typename T1, typename T2, typename T3, typename T4,
553+ typename T5, typename T6>
554+Signal<R, G, T1, T2, T3, T4, T5, T6>::Signal()
555+{}
556+
557+template<typename R, typename G, typename T1, typename T2, typename T3, typename T4,
558+ typename T5, typename T6>
559+Signal<R, G, T1, T2, T3, T4, T5, T6>::Signal(G object,
560+ std::string const& signal_name,
561+ SignalCallback callback)
562+{
563+ Connect(object, signal_name, callback);
564+}
565+
566+}
567+}
568+
569+#endif
570
571=== added file 'UnityCore/GLibSignal.cpp'
572--- UnityCore/GLibSignal.cpp 1970-01-01 00:00:00 +0000
573+++ UnityCore/GLibSignal.cpp 2011-07-15 10:26:29 +0000
574@@ -0,0 +1,87 @@
575+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
576+/*
577+* Copyright (C) 2011 Canonical Ltd
578+*
579+* This program is free software: you can redistribute it and/or modify
580+* it under the terms of the GNU General Public License version 3 as
581+* published by the Free Software Foundation.
582+*
583+* This program is distributed in the hope that it will be useful,
584+* but WITHOUT ANY WARRANTY; without even the implied warranty of
585+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
586+* GNU General Public License for more details.
587+*
588+* You should have received a copy of the GNU General Public License
589+* along with this program. If not, see <http://www.gnu.org/licenses/>.
590+*
591+* Authored by: Neil Jagdish patel <neil.patel@canonical.com>
592+*/
593+
594+#include "GLibSignal.h"
595+
596+namespace unity {
597+namespace glib {
598+
599+SignalBase::SignalBase()
600+ : object_(0),
601+ connection_id_(0)
602+{}
603+
604+SignalBase::~SignalBase()
605+{
606+ Disconnect();
607+}
608+
609+void SignalBase::Disconnect()
610+{
611+ if (G_IS_OBJECT(object_) && connection_id_)
612+ g_signal_handler_disconnect(object_, connection_id_);
613+
614+ object_ = 0;
615+ connection_id_ = 0;
616+}
617+
618+GObject* SignalBase::object() const
619+{
620+ return object_;
621+}
622+
623+std::string const& SignalBase::name() const
624+{
625+ return name_;
626+}
627+
628+SignalManager::SignalManager()
629+{}
630+
631+// Ideally this would be SignalBase& but there is a specific requirment to allow
632+// only one instance of Signal to control a connection. With the templating, it
633+// was too messy to try and write a copy constructor/operator that would steal
634+// from "other" and make the new one the owner. Not only did it create
635+// opportunity for random bugs, it also made the API bad.
636+void SignalManager::Add(SignalBase* signal)
637+{
638+ SignalBase::Ptr s(signal);
639+ connections_.push_back(s);
640+}
641+
642+// This uses void* to keep in line with the g_signal* functions
643+// (it allows you to pass in a GObject without casting up).
644+void SignalManager::Disconnect(void* object, std::string const& signal_name)
645+{
646+ for (ConnectionVector::iterator it = connections_.begin();
647+ it != connections_.end();
648+ ++it)
649+ {
650+ if ((*it)->object() == object
651+ && (*it)->name() == signal_name)
652+ {
653+ (*it)->Disconnect();
654+ connections_.erase(it, it);
655+ }
656+ }
657+}
658+
659+}
660+}
661+
662
663=== added file 'UnityCore/GLibSignal.h'
664--- UnityCore/GLibSignal.h 1970-01-01 00:00:00 +0000
665+++ UnityCore/GLibSignal.h 2011-07-15 10:26:29 +0000
666@@ -0,0 +1,307 @@
667+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
668+/*
669+* Copyright (C) 2011 Canonical Ltd
670+*
671+* This program is free software: you can redistribute it and/or modify
672+* it under the terms of the GNU General Public License version 3 as
673+* published by the Free Software Foundation.
674+*
675+* This program is distributed in the hope that it will be useful,
676+* but WITHOUT ANY WARRANTY; without even the implied warranty of
677+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
678+* GNU General Public License for more details.
679+*
680+* You should have received a copy of the GNU General Public License
681+* along with this program. If not, see <http://www.gnu.org/licenses/>.
682+*
683+* Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
684+*/
685+
686+#ifndef UNITY_GLIB_SIGNAL_H
687+#define UNITY_GLIB_SIGNAL_H
688+
689+#include <string>
690+#include <vector>
691+#include <boost/noncopyable.hpp>
692+#include <boost/shared_ptr.hpp>
693+#include <glib-object.h>
694+#include <sigc++/sigc++.h>
695+
696+namespace unity {
697+namespace glib {
698+
699+using sigc::nil;
700+
701+class SignalBase
702+{
703+public:
704+ typedef boost::shared_ptr<SignalBase> Ptr;
705+
706+ SignalBase();
707+ virtual ~SignalBase();
708+
709+ void Disconnect();
710+
711+ GObject* object() const;
712+ std::string const& name() const;
713+
714+protected:
715+ GObject* object_;
716+ guint32 connection_id_;
717+ std::string name_;
718+};
719+
720+template <typename R, typename G>
721+class Signal0 : public SignalBase
722+{
723+public:
724+ typedef sigc::slot<R, G> SignalCallback;
725+
726+ Signal0();
727+
728+ void Connect(G Object,
729+ std::string const& signal_name,
730+ SignalCallback cb);
731+private:
732+ static R Callback(G object, Signal0* self);
733+private:
734+ SignalCallback callback_;
735+};
736+
737+template <typename R, typename G, typename T>
738+class Signal1 : public SignalBase
739+{
740+public:
741+ typedef sigc::slot<R, G, T> SignalCallback;
742+
743+ Signal1();
744+
745+ void Connect(G Object,
746+ std::string const& signal_name,
747+ SignalCallback callback);
748+private:
749+ static R Callback(G object, T data1, Signal1* self);
750+private:
751+ SignalCallback callback_;
752+};
753+
754+template <typename R, typename G, typename T1, typename T2>
755+class Signal2 : public SignalBase
756+{
757+public:
758+ typedef sigc::slot<R, G, T1, T2> SignalCallback;
759+
760+ Signal2();
761+
762+ void Connect(G Object,
763+ std::string const& signal_name,
764+ SignalCallback callback);
765+private:
766+ static R Callback(G Object,
767+ T1 data1,
768+ T2 data2,
769+ Signal2* self);
770+private:
771+ SignalCallback callback_;
772+};
773+
774+template <typename R, typename G, typename T1, typename T2, typename T3>
775+class Signal3 : public SignalBase
776+{
777+public:
778+ typedef sigc::slot<R, G, T1, T2, T3> SignalCallback;
779+
780+ Signal3();
781+
782+ void Connect(G Object,
783+ std::string const& signal_name,
784+ SignalCallback callback);
785+private:
786+ static R Callback(G Object,
787+ T1 data1,
788+ T2 data2,
789+ T3 data3,
790+ Signal3* self);
791+private:
792+ SignalCallback callback_;
793+};
794+
795+template <typename R, typename G, typename T1, typename T2, typename T3, typename T4>
796+class Signal4 : public SignalBase
797+{
798+public:
799+ typedef sigc::slot<R, G, T1, T2, T3, T4> SignalCallback;
800+
801+ Signal4();
802+
803+ void Connect(G Object,
804+ std::string const& signal_name,
805+ SignalCallback callback);
806+private:
807+ static R Callback(G Object,
808+ T1 data1,
809+ T2 data2,
810+ T3 data3,
811+ T4 data4,
812+ Signal4* self);
813+private:
814+ SignalCallback callback_;
815+};
816+
817+template <typename R, typename G, typename T1, typename T2,
818+ typename T3, typename T4, typename T5>
819+class Signal5 : public SignalBase
820+{
821+public:
822+ typedef sigc::slot<R, G, T1, T2, T3, T4, T5> SignalCallback;
823+
824+ Signal5();
825+
826+ void Connect(G Object,
827+ std::string const& signal_name,
828+ SignalCallback callback);
829+private:
830+ static R Callback(G Object,
831+ T1 data1,
832+ T2 data2,
833+ T3 data3,
834+ T4 data4,
835+ T5 data5,
836+ Signal5* self);
837+private:
838+ SignalCallback callback_;
839+};
840+
841+template <typename R, typename G, typename T1, typename T2,
842+ typename T3, typename T4, typename T5, typename T6>
843+class Signal6 : public SignalBase
844+{
845+public:
846+ typedef sigc::slot<R, G, T1, T2, T3, T4, T5, T6> SignalCallback;
847+
848+ Signal6();
849+
850+ void Connect(G Object,
851+ std::string const& signal_name,
852+ SignalCallback callback);
853+private:
854+ static R Callback(G Object,
855+ T1 data1,
856+ T2 data2,
857+ T3 data3,
858+ T4 data4,
859+ T5 data5,
860+ T6 data6,
861+ Signal6* self);
862+private:
863+ SignalCallback callback_;
864+};
865+
866+template <typename R, typename G,
867+ typename T1 = nil, typename T2 = nil,
868+ typename T3 = nil, typename T4 = nil,
869+ typename T5 = nil, typename T6 = nil>
870+class Signal : public Signal6<R, G, T1, T2, T3, T4, T5, T6>
871+{
872+public:
873+ typedef sigc::slot<R, G, T1, T2, T3, T4, T5, T6> SignalCallback;
874+
875+ inline Signal();
876+ inline Signal(G Object,
877+ std::string const& signal_name,
878+ SignalCallback callback);
879+};
880+
881+template <typename R, typename G>
882+class Signal<R, G, nil, nil, nil, nil, nil, nil> : public Signal0<R, G>
883+{
884+public:
885+ typedef sigc::slot<R, G> SignalCallback;
886+
887+ inline Signal();
888+ inline Signal(G Object,
889+ std::string const& signal_name,
890+ SignalCallback callback);
891+};
892+
893+template <typename R, typename G, typename T1>
894+class Signal<R, G, T1, nil, nil, nil, nil, nil> : public Signal1<R, G, T1>
895+{
896+public:
897+ typedef sigc::slot<R, G, T1> SignalCallback;
898+
899+ inline Signal();
900+ inline Signal(G Object,
901+ std::string const& signal_name,
902+ SignalCallback callback);
903+};
904+
905+template <typename R, typename G, typename T1, typename T2>
906+class Signal<R, G, T1, T2, nil, nil, nil, nil> : public Signal2<R, G, T1, T2>
907+{
908+public:
909+ typedef sigc::slot<R, G, T1, T2> SignalCallback;
910+
911+ inline Signal();
912+ inline Signal(G Object,
913+ std::string const& signal_name,
914+ SignalCallback callback);
915+};
916+
917+template <typename R, typename G, typename T1, typename T2, typename T3>
918+class Signal<R, G, T1, T2, T3, nil, nil, nil> : public Signal3<R, G, T1, T2 ,T3>
919+{
920+public:
921+ typedef sigc::slot<R, G, T1, T2, T3> SignalCallback;
922+
923+ inline Signal();
924+ inline Signal(G Object,
925+ std::string const& signal_name,
926+ SignalCallback callback);
927+};
928+
929+template <typename R, typename G, typename T1, typename T2, typename T3, typename T4>
930+class Signal<R, G, T1, T2, T3, T4, nil, nil>
931+ : public Signal4<R, G, T1, T2 ,T3, T4>
932+{
933+public:
934+ typedef sigc::slot<R, G, T1, T2, T3, T4> SignalCallback;
935+
936+ inline Signal();
937+ inline Signal(G Object,
938+ std::string const& signal_name,
939+ SignalCallback callback);
940+};
941+
942+template <typename R, typename G, typename T1, typename T2, typename T3, typename T4, typename T5>
943+class Signal<R, G, T1, T2, T3, T4, T5, nil>
944+ : public Signal5<R, G, T1, T2 ,T3, T4, T5>
945+{
946+public:
947+ typedef sigc::slot<R, G, T1, T2, T3, T4, T5> SignalCallback;
948+
949+ inline Signal();
950+ inline Signal(G Object,
951+ std::string const& signal_name,
952+ SignalCallback callback);
953+};
954+
955+class SignalManager : public boost::noncopyable
956+{
957+public:
958+ typedef std::vector<SignalBase::Ptr> ConnectionVector;
959+
960+ SignalManager();
961+ void Add(SignalBase* signal);
962+ void Disconnect(void* object, std::string const& signal_name);
963+
964+private:
965+ ConnectionVector connections_;
966+};
967+
968+}
969+}
970+
971+#include "GLibSignal-inl.h"
972+
973+#endif
974
975=== removed file 'UnityCore/UnityCore.h'
976--- UnityCore/UnityCore.h 2011-06-21 12:10:09 +0000
977+++ UnityCore/UnityCore.h 1970-01-01 00:00:00 +0000
978@@ -1,32 +0,0 @@
979-/*
980- * Copyright (C) 2011 Canonical Ltd
981- *
982- * This program is free software: you can redistribute it and/or modify
983- * it under the terms of the GNU General Public License version 3 as
984- * published by the Free Software Foundation.
985- *
986- * This program is distributed in the hope that it will be useful,
987- * but WITHOUT ANY WARRANTY; without even the implied warranty of
988- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
989- * GNU General Public License for more details.
990- *
991- * You should have received a copy of the GNU General Public License
992- * along with this program. If not, see <http://www.gnu.org/licenses/>.
993- *
994- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
995- */
996-
997-#ifndef _UNITY_CORE_H_
998-#define _UNITY_CORE_H_
999-
1000-// Single include for headers
1001-
1002-#include <UnityCore/DBusIndicators.h>
1003-#include <UnityCore/GLibWrapper.h>
1004-#include <UnityCore/GLibWrapper-inl.h>
1005-#include <UnityCore/Indicator.h>
1006-#include <UnityCore/IndicatorEntry.h>
1007-#include <UnityCore/Indicators.h>
1008-#include <UnityCore/Variant.h>
1009-
1010-#endif // _UNITY_CORE_H_
1011
1012=== modified file 'plugins/unityshell/src/FavoriteStoreGSettings.h'
1013--- plugins/unityshell/src/FavoriteStoreGSettings.h 2011-06-21 12:10:09 +0000
1014+++ plugins/unityshell/src/FavoriteStoreGSettings.h 2011-07-15 10:26:29 +0000
1015@@ -23,7 +23,7 @@
1016 #include <gio/gio.h>
1017
1018 #include "FavoriteStore.h"
1019-#include <UnityCore/UnityCore.h>
1020+#include <UnityCore/GLibWrapper.h>
1021
1022 // An abstract object that facilitates getting and modifying the list of favorites
1023 // Use GetDefault () to get the correct store for the session
1024
1025=== modified file 'plugins/unityshell/src/IconTexture.cpp'
1026--- plugins/unityshell/src/IconTexture.cpp 2011-06-21 12:10:09 +0000
1027+++ plugins/unityshell/src/IconTexture.cpp 2011-07-15 10:26:29 +0000
1028@@ -19,16 +19,17 @@
1029
1030 #include "config.h"
1031
1032-#include "Nux/Nux.h"
1033-#include "NuxGraphics/GLThread.h"
1034+#include <glib.h>
1035+#include <gtk/gtk.h>
1036+#include <pango/pangocairo.h>
1037+
1038+#include <Nux/Nux.h>
1039+#include <NuxGraphics/GLThread.h>
1040+#include <UnityCore/Variant.h>
1041+
1042 #include "IconLoader.h"
1043 #include "IconTexture.h"
1044 #include "TextureCache.h"
1045-#include <UnityCore/UnityCore.h>
1046-
1047-#include <glib.h>
1048-#include <pango/pangocairo.h>
1049-#include <gtk/gtk.h>
1050
1051 #define DEFAULT_ICON "text-x-preview"
1052
1053
1054=== modified file 'plugins/unityshell/src/Launcher.cpp'
1055--- plugins/unityshell/src/Launcher.cpp 2011-07-14 14:15:37 +0000
1056+++ plugins/unityshell/src/Launcher.cpp 2011-07-15 10:26:29 +0000
1057@@ -48,7 +48,7 @@
1058 #include "ubus-server.h"
1059 #include "UBusMessages.h"
1060
1061-#include <UnityCore/UnityCore.h>
1062+#include <UnityCore/Variant.h>
1063
1064 using namespace unity::ui;
1065
1066
1067=== modified file 'plugins/unityshell/src/LauncherIcon.cpp'
1068--- plugins/unityshell/src/LauncherIcon.cpp 2011-07-14 14:37:26 +0000
1069+++ plugins/unityshell/src/LauncherIcon.cpp 2011-07-15 10:26:29 +0000
1070@@ -42,7 +42,7 @@
1071
1072 #include "ubus-server.h"
1073 #include "UBusMessages.h"
1074-#include <UnityCore/UnityCore.h>
1075+#include <UnityCore/Variant.h>
1076
1077 #define DEFAULT_ICON "application-default-icon"
1078 #define MONO_TEST_ICON "gnome-home"
1079
1080=== modified file 'plugins/unityshell/src/PanelHomeButton.cpp'
1081--- plugins/unityshell/src/PanelHomeButton.cpp 2011-07-01 14:58:41 +0000
1082+++ plugins/unityshell/src/PanelHomeButton.cpp 2011-07-15 10:26:29 +0000
1083@@ -33,7 +33,7 @@
1084 #include <gtk/gtk.h>
1085
1086 #include "PanelStyle.h"
1087-#include <UnityCore/UnityCore.h>
1088+#include <UnityCore/Variant.h>
1089
1090 #define PANEL_HEIGHT 24
1091
1092
1093=== modified file 'plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp'
1094--- plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp 2011-07-07 10:22:47 +0000
1095+++ plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp 2011-07-15 10:26:29 +0000
1096@@ -37,7 +37,8 @@
1097 #include "PanelIndicatorObjectEntryView.h"
1098
1099 #include "PanelStyle.h"
1100-#include <UnityCore/UnityCore.h>
1101+#include <UnityCore/GLibWrapper.h>
1102+#include <UnityCore/Variant.h>
1103
1104
1105 namespace unity {
1106
1107=== modified file 'plugins/unityshell/src/PanelIndicatorObjectEntryView.h'
1108--- plugins/unityshell/src/PanelIndicatorObjectEntryView.h 2011-07-11 08:49:45 +0000
1109+++ plugins/unityshell/src/PanelIndicatorObjectEntryView.h 2011-07-15 10:26:29 +0000
1110@@ -25,7 +25,7 @@
1111 #include <NuxImage/CairoGraphics.h>
1112 #include <NuxGraphics/GraphicsEngine.h>
1113
1114-#include <UnityCore/UnityCore.h>
1115+#include <UnityCore/IndicatorEntry.h>
1116
1117 #include "Introspectable.h"
1118
1119
1120=== modified file 'plugins/unityshell/src/PanelIndicatorObjectView.h'
1121--- plugins/unityshell/src/PanelIndicatorObjectView.h 2011-06-21 12:10:09 +0000
1122+++ plugins/unityshell/src/PanelIndicatorObjectView.h 2011-07-15 10:26:29 +0000
1123@@ -22,7 +22,7 @@
1124
1125 #include <Nux/View.h>
1126
1127-#include <UnityCore/UnityCore.h>
1128+#include <UnityCore/Indicator.h>
1129 #include "PanelIndicatorObjectEntryView.h"
1130
1131 #include "Introspectable.h"
1132
1133=== modified file 'plugins/unityshell/src/PanelMenuView.cpp'
1134--- plugins/unityshell/src/PanelMenuView.cpp 2011-07-10 18:14:49 +0000
1135+++ plugins/unityshell/src/PanelMenuView.cpp 2011-07-15 10:26:29 +0000
1136@@ -31,7 +31,7 @@
1137
1138 #include "PanelMenuView.h"
1139 #include "PanelStyle.h"
1140-#include <UnityCore/UnityCore.h>
1141+#include <UnityCore/Variant.h>
1142
1143 #include "WindowManager.h"
1144
1145
1146=== modified file 'plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp'
1147--- plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp 2011-06-21 12:10:09 +0000
1148+++ plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp 2011-07-15 10:26:29 +0000
1149@@ -28,7 +28,7 @@
1150 #include "Nux/WindowCompositor.h"
1151
1152 #include "PanelTitlebarGrabAreaView.h"
1153-#include <UnityCore/UnityCore.h>
1154+#include <UnityCore/Variant.h>
1155
1156 #include <glib.h>
1157
1158
1159=== modified file 'plugins/unityshell/src/PanelTray.h'
1160--- plugins/unityshell/src/PanelTray.h 2011-06-21 12:10:09 +0000
1161+++ plugins/unityshell/src/PanelTray.h 2011-07-15 10:26:29 +0000
1162@@ -24,8 +24,6 @@
1163
1164 #include <gdk/gdkx.h>
1165
1166-#include <UnityCore/UnityCore.h>
1167-
1168 #include "Introspectable.h"
1169 #include "PanelIndicatorObjectView.h"
1170
1171
1172=== modified file 'plugins/unityshell/src/PanelView.cpp'
1173--- plugins/unityshell/src/PanelView.cpp 2011-07-01 14:58:41 +0000
1174+++ plugins/unityshell/src/PanelView.cpp 2011-07-15 10:26:29 +0000
1175@@ -34,7 +34,7 @@
1176
1177 #include "PanelStyle.h"
1178 #include "PanelIndicatorObjectView.h"
1179-#include <UnityCore/UnityCore.h>
1180+#include <UnityCore/Variant.h>
1181
1182 namespace unity {
1183
1184
1185=== modified file 'plugins/unityshell/src/PanelView.h'
1186--- plugins/unityshell/src/PanelView.h 2011-06-22 14:39:34 +0000
1187+++ plugins/unityshell/src/PanelView.h 2011-07-15 10:26:29 +0000
1188@@ -28,7 +28,7 @@
1189
1190 #include <gdk/gdkx.h>
1191
1192-#include <UnityCore/UnityCore.h>
1193+#include <UnityCore/DBusIndicators.h>
1194
1195 #include "Introspectable.h"
1196 #include "PanelHomeButton.h"
1197
1198=== modified file 'plugins/unityshell/src/PlacesHomeView.cpp'
1199--- plugins/unityshell/src/PlacesHomeView.cpp 2011-06-21 12:10:09 +0000
1200+++ plugins/unityshell/src/PlacesHomeView.cpp 2011-07-15 10:26:29 +0000
1201@@ -42,7 +42,7 @@
1202 #include "PlacesSettings.h"
1203 #include "PlacesSimpleTile.h"
1204 #include "PlacesStyle.h"
1205-#include <UnityCore/UnityCore.h>
1206+#include <UnityCore/Variant.h>
1207
1208 #include <string>
1209 #include <vector>
1210
1211=== modified file 'plugins/unityshell/src/PlacesSearchBar.cpp'
1212--- plugins/unityshell/src/PlacesSearchBar.cpp 2011-06-28 11:17:23 +0000
1213+++ plugins/unityshell/src/PlacesSearchBar.cpp 2011-07-15 10:26:29 +0000
1214@@ -40,7 +40,7 @@
1215 #include "UBusMessages.h"
1216
1217 #include "PlacesSearchBar.h"
1218-#include <UnityCore/UnityCore.h>
1219+#include <UnityCore/Variant.h>
1220
1221 #include "PlacesStyle.h"
1222
1223
1224=== modified file 'plugins/unityshell/src/PlacesSimpleTile.cpp'
1225--- plugins/unityshell/src/PlacesSimpleTile.cpp 2011-07-07 11:52:58 +0000
1226+++ plugins/unityshell/src/PlacesSimpleTile.cpp 2011-07-15 10:26:29 +0000
1227@@ -30,7 +30,7 @@
1228 #include <gtk/gtk.h>
1229 #include <gdk/gdk.h>
1230
1231-#include <UnityCore/UnityCore.h>
1232+#include <UnityCore/Variant.h>
1233
1234 PlacesSimpleTile::PlacesSimpleTile (const char *icon_name,
1235 const char *label,
1236
1237=== modified file 'plugins/unityshell/src/PlacesView.cpp'
1238--- plugins/unityshell/src/PlacesView.cpp 2011-06-28 12:19:37 +0000
1239+++ plugins/unityshell/src/PlacesView.cpp 2011-07-15 10:26:29 +0000
1240@@ -34,7 +34,7 @@
1241 #include "PlacesStyle.h"
1242 #include "PlacesSettings.h"
1243 #include "PlacesView.h"
1244-#include <UnityCore/UnityCore.h>
1245+#include <UnityCore/Variant.h>
1246
1247 static void place_entry_activate_request (GVariant *payload, PlacesView *self);
1248
1249
1250=== modified file 'plugins/unityshell/src/QuicklistMenuItem.cpp'
1251--- plugins/unityshell/src/QuicklistMenuItem.cpp 2011-06-21 12:10:09 +0000
1252+++ plugins/unityshell/src/QuicklistMenuItem.cpp 2011-07-15 10:26:29 +0000
1253@@ -23,7 +23,7 @@
1254
1255 #include "Nux/Nux.h"
1256 #include "QuicklistMenuItem.h"
1257-#include <UnityCore/UnityCore.h>
1258+#include <UnityCore/Variant.h>
1259
1260 #include <X11/Xlib.h>
1261
1262
1263=== modified file 'plugins/unityshell/src/WindowButtons.cpp'
1264--- plugins/unityshell/src/WindowButtons.cpp 2011-06-21 12:10:09 +0000
1265+++ plugins/unityshell/src/WindowButtons.cpp 2011-07-15 10:26:29 +0000
1266@@ -25,7 +25,7 @@
1267 #include "Nux/BaseWindow.h"
1268 #include "Nux/WindowCompositor.h"
1269
1270-#include <UnityCore/UnityCore.h>
1271+#include <UnityCore/Variant.h>
1272 #include "WindowButtons.h"
1273
1274 #include <glib.h>
1275@@ -58,7 +58,7 @@
1276 nux::Geometry geo = GetGeometry ();
1277 nux::BaseTexture *tex;
1278 nux::TexCoordXForm texxform;
1279-
1280+
1281 GfxContext.PushClippingRectangle (geo);
1282
1283 if (HasMouseFocus ())
1284@@ -123,23 +123,25 @@
1285 {
1286 WindowButton *but;
1287
1288+ auto lambda_statechanged = [&](int x, int y, unsigned long button_flags, unsigned long key_flags) { redraw_signal.emit (); };
1289+
1290 but = new WindowButton (PanelStyle::WINDOW_BUTTON_CLOSE);
1291 AddView (but, 0, nux::eCenter, nux::eFix);
1292 but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnCloseClicked));
1293- but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter));
1294- but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave));
1295+ but->OnMouseEnter.connect (lambda_statechanged);
1296+ but->OnMouseLeave.connect (lambda_statechanged);
1297
1298 but = new WindowButton (PanelStyle::WINDOW_BUTTON_MINIMIZE);
1299 AddView (but, 0, nux::eCenter, nux::eFix);
1300 but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnMinimizeClicked));
1301- but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter));
1302- but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave));
1303+ but->OnMouseEnter.connect (lambda_statechanged);
1304+ but->OnMouseLeave.connect (lambda_statechanged);
1305
1306 but = new WindowButton (PanelStyle::WINDOW_BUTTON_UNMAXIMIZE);
1307 AddView (but, 0, nux::eCenter, nux::eFix);
1308 but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnRestoreClicked));
1309- but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter));
1310- but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave));
1311+ but->OnMouseEnter.connect (lambda_statechanged);
1312+ but->OnMouseLeave.connect (lambda_statechanged);
1313
1314 SetContentDistribution (nux::eStackLeft);
1315 }
1316@@ -184,15 +186,3 @@
1317 {
1318 unity::variant::BuilderWrapper(builder).add(GetGeometry());
1319 }
1320-
1321-void WindowButtons::RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags)
1322-{
1323- redraw_signal.emit ();
1324-}
1325-
1326-void WindowButtons::RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags)
1327-{
1328- redraw_signal.emit ();
1329-}
1330-
1331-
1332
1333=== modified file 'po/unity.pot'
1334--- po/unity.pot 2011-07-13 13:54:57 +0000
1335+++ po/unity.pot 2011-07-15 10:26:29 +0000
1336@@ -8,7 +8,7 @@
1337 msgstr ""
1338 "Project-Id-Version: PACKAGE VERSION\n"
1339 "Report-Msgid-Bugs-To: ayatana-dev@lists.launchpad.net\n"
1340-"POT-Creation-Date: 2011-07-13 01:33-0400\n"
1341+"POT-Creation-Date: 2011-07-09 23:12+0100\n"
1342 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1343 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1344 "Language-Team: LANGUAGE <LL@li.org>\n"
1345
1346=== modified file 'tests/CMakeLists.txt'
1347--- tests/CMakeLists.txt 2011-07-13 14:20:07 +0000
1348+++ tests/CMakeLists.txt 2011-07-15 10:26:29 +0000
1349@@ -20,6 +20,7 @@
1350 "-DGETTEXT_PACKAGE=\"unity\""
1351 "-DINDICATORDIR=\"${CMAKE_BINARY_DIR}/tests\""
1352 "-DINDICATORICONDIR=\"${CMAKE_BINARY_DIR}/tests\""
1353+ "-I${CMAKE_CURRENT_BINARY_DIR}"
1354 )
1355 add_definitions (${CFLAGS})
1356
1357@@ -27,7 +28,7 @@
1358 link_libraries (${LIBS})
1359
1360 set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS})
1361-link_directories (${LIB_PATHS} ${CMAKE_BINARY_DIR}/UnityCore)
1362+link_directories (${CMAKE_BINARY_DIR}/UnityCore ${LIB_PATHS})
1363
1364 include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR})
1365
1366@@ -285,16 +286,27 @@
1367 #
1368 # GTest tests
1369 #
1370+find_program(GLIB_GENMARSHAL glib-genmarshal)
1371+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp
1372+ COMMAND ${GLIB_GENMARSHAL} ARGS test_glib_signals_utils_marshal.list --body --prefix=test_signals > ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp
1373+ COMMAND ${GLIB_GENMARSHAL} ARGS test_glib_signals_utils_marshal.list --header --prefix=test_signals > ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.h
1374+ COMMAND sed ARGS -i "s/glib-object/test_glib_signals_utils_marshal/" ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp
1375+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
1376+ DEPENDS test_glib_signals_utils_marshal.list
1377+ COMMENT "Generating marshallers")
1378
1379 enable_testing()
1380 find_package(GTest)
1381-
1382 if (${GTEST_FOUND} STREQUAL TRUE)
1383-
1384 include_directories(${GTEST_INCLUDE_DIRS})
1385 add_executable(test-gtest
1386+ test_glib_signals.cpp
1387+ test_glib_signals_utils.cpp
1388+ test_glib_signals_utils.h
1389+ ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp
1390+ test_indicator_entry.cpp
1391+ test_main.cpp
1392 test_timer.cpp
1393- test_indicator_entry.cpp
1394 ${UNITY_SRC}/Timer.h
1395 ${UNITY_SRC}/Timer.cpp
1396 )
1397
1398=== added file 'tests/test_glib_signals.cpp'
1399--- tests/test_glib_signals.cpp 1970-01-01 00:00:00 +0000
1400+++ tests/test_glib_signals.cpp 2011-07-15 10:26:29 +0000
1401@@ -0,0 +1,366 @@
1402+#include <UnityCore/GLibSignal.h>
1403+#include <gtest/gtest.h>
1404+
1405+#include "test_glib_signals_utils.h"
1406+
1407+using namespace std;
1408+using namespace unity;
1409+using namespace unity::glib;
1410+
1411+namespace {
1412+
1413+class TestGLibSignals : public testing::Test
1414+{
1415+public:
1416+ TestGLibSignals()
1417+ : signal0_received_(false)
1418+ , signal1_received_(false)
1419+ , signal2_received_(false)
1420+ , signal3_received_(false)
1421+ , signal4_received_(false)
1422+ , signal5_received_(false)
1423+ , signal6_received_(false)
1424+ , arg1_("")
1425+ , arg2_(-1)
1426+ , arg3_(0.0f)
1427+ , arg4_(0.00)
1428+ , arg5_(false)
1429+ , arg6_(0)
1430+ {
1431+ test_signals_ = static_cast<TestSignals*>(g_object_new(TEST_TYPE_SIGNALS, NULL));
1432+ }
1433+
1434+ virtual ~TestGLibSignals()
1435+ {
1436+ if (G_IS_OBJECT(test_signals_))
1437+ g_object_unref(test_signals_);
1438+ }
1439+
1440+ void Signal0Callback(TestSignals* signals)
1441+ {
1442+ signal0_received_ = true;
1443+ }
1444+
1445+ void Signal1Callback(TestSignals* signals, const char *str)
1446+ {
1447+ arg1_ = str;
1448+ signal1_received_ = true;
1449+ }
1450+
1451+ void Signal2Callback(TestSignals* signals, const char* str, int i)
1452+ {
1453+ arg1_ = str;
1454+ arg2_ = i;
1455+ signal2_received_ = true;
1456+ }
1457+
1458+ void Signal3Callback(TestSignals* signals, const char* str, int i, float f)
1459+ {
1460+ arg1_ = str;
1461+ arg2_ = i;
1462+ arg3_ = f;
1463+ signal3_received_ = true;
1464+ }
1465+
1466+ void Signal4Callback(TestSignals* signals, const char* str, int i, float f, double d) // heh
1467+ {
1468+ arg1_ = str;
1469+ arg2_ = i;
1470+ arg3_ = f;
1471+ arg4_ = d;
1472+ signal4_received_ = true;
1473+ }
1474+
1475+ void Signal5Callback(TestSignals* signals, const char* str, int i, float f,
1476+ double d, gboolean b)
1477+ {
1478+ arg1_ = str;
1479+ arg2_ = i;
1480+ arg3_ = f;
1481+ arg4_ = d;
1482+ arg5_ = b ? true : false;
1483+ signal5_received_ = true;
1484+ }
1485+
1486+ gboolean Signal6Callback(TestSignals* signals, const char* str, int i, float f,
1487+ double d, gboolean b, char c)
1488+ {
1489+ arg1_ = str;
1490+ arg2_ = i;
1491+ arg3_ = f;
1492+ arg4_ = d;
1493+ arg5_ = b ? true : false;
1494+ arg6_ = c;
1495+ signal6_received_ = true;
1496+ return TRUE;
1497+ }
1498+
1499+protected:
1500+ TestSignals* test_signals_;
1501+
1502+ bool signal0_received_;
1503+ bool signal1_received_;
1504+ bool signal2_received_;
1505+ bool signal3_received_;
1506+ bool signal4_received_;
1507+ bool signal5_received_;
1508+ bool signal6_received_;
1509+
1510+ string arg1_;
1511+ int arg2_;
1512+ float arg3_;
1513+ double arg4_;
1514+ bool arg5_;
1515+ char arg6_;
1516+};
1517+
1518+
1519+TEST_F(TestGLibSignals, TestConstructions)
1520+{
1521+ SignalBase base;
1522+
1523+ Signal0<void, TestSignals*> signal0;
1524+ Signal1<void, TestSignals*, string> signal1;
1525+ Signal2<void, TestSignals*, string, int> signal2;
1526+ Signal3<void, TestSignals*, string, int, float> signal3;
1527+ Signal4<void, TestSignals*, string, int, float, double> signal4;
1528+ Signal5<void, TestSignals*, string, int, float, double, gboolean> signal5;
1529+ Signal6<gboolean, TestSignals*, string, int, float, double, gboolean, char> signal6;
1530+
1531+ Signal<void, TestSignals*> signal00;
1532+ Signal<void, TestSignals*, string> signal01;
1533+ Signal<void, TestSignals*, string, int> signal02;
1534+ Signal<void, TestSignals*, string, int, float> signal03;
1535+ Signal<void, TestSignals*, string, int, float, double> signal04;
1536+ Signal<void, TestSignals*, string, int, float, double, gboolean> signal05;
1537+ Signal<gboolean, TestSignals*, string, int, float, double, gboolean, char> signal06;
1538+}
1539+
1540+TEST_F(TestGLibSignals, TestSignal0)
1541+{
1542+ Signal<void, TestSignals*> signal;
1543+ signal.Connect(test_signals_, "signal0",
1544+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
1545+
1546+ g_signal_emit_by_name(test_signals_, "signal0");
1547+
1548+ EXPECT_TRUE(signal0_received_);
1549+ EXPECT_EQ(arg1_, "");
1550+}
1551+
1552+TEST_F(TestGLibSignals, TestSignal1)
1553+{
1554+ Signal<void, TestSignals*, const char*> signal;
1555+ signal.Connect(test_signals_, "signal1",
1556+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
1557+
1558+ g_signal_emit_by_name(test_signals_, "signal1", "test");
1559+
1560+ EXPECT_TRUE(signal1_received_);
1561+ EXPECT_EQ(arg1_, "test");
1562+ EXPECT_EQ(arg2_, -1);
1563+}
1564+
1565+TEST_F(TestGLibSignals, TestSignal2)
1566+{
1567+ Signal<void, TestSignals*, const char*, int> signal;
1568+ signal.Connect(test_signals_, "signal2",
1569+ sigc::mem_fun(this, &TestGLibSignals::Signal2Callback));
1570+
1571+ g_signal_emit_by_name(test_signals_, "signal2", "test", 100);
1572+
1573+ EXPECT_TRUE(signal2_received_);
1574+ EXPECT_EQ(arg1_, "test");
1575+ EXPECT_EQ(arg2_, 100);
1576+ EXPECT_EQ(arg3_, 0.0f);
1577+}
1578+
1579+TEST_F(TestGLibSignals, TestSignal3)
1580+{
1581+ Signal<void, TestSignals*, const char*, int, float> signal;
1582+ signal.Connect(test_signals_, "signal3",
1583+ sigc::mem_fun(this, &TestGLibSignals::Signal3Callback));
1584+
1585+ g_signal_emit_by_name(test_signals_, "signal3", "test", 100, 200.0f);
1586+
1587+ EXPECT_TRUE(signal3_received_);
1588+ EXPECT_EQ(arg1_, "test");
1589+ EXPECT_EQ(arg2_, 100);
1590+ EXPECT_EQ(arg3_, 200.0f);
1591+ EXPECT_EQ(arg4_, 0.00);
1592+}
1593+
1594+
1595+TEST_F(TestGLibSignals, TestSignal4)
1596+{
1597+ Signal<void, TestSignals*, const char*, int, float, double> signal;
1598+ signal.Connect(test_signals_, "signal4",
1599+ sigc::mem_fun(this, &TestGLibSignals::Signal4Callback));
1600+
1601+ g_signal_emit_by_name(test_signals_, "signal4", "test", 100, 200.0f, 300.00);
1602+
1603+ EXPECT_TRUE(signal4_received_);
1604+ EXPECT_EQ(arg1_, "test");
1605+ EXPECT_EQ(arg2_, 100);
1606+ EXPECT_EQ(arg3_, 200.0f);
1607+ EXPECT_EQ(arg4_, 300.00);
1608+ EXPECT_EQ(arg5_, false);
1609+}
1610+
1611+TEST_F(TestGLibSignals, TestSignal5)
1612+{
1613+ Signal<void, TestSignals*, const char*, int, float, double, gboolean> signal;
1614+ signal.Connect(test_signals_, "signal5",
1615+ sigc::mem_fun(this, &TestGLibSignals::Signal5Callback));
1616+
1617+ g_signal_emit_by_name(test_signals_, "signal5", "test", 100, 200.0f, 300.00,
1618+ TRUE);
1619+
1620+ EXPECT_TRUE(signal5_received_);
1621+ EXPECT_EQ(arg1_, "test");
1622+ EXPECT_EQ(arg2_, 100);
1623+ EXPECT_EQ(arg3_, 200.0f);
1624+ EXPECT_EQ(arg4_, 300.00);
1625+ EXPECT_EQ(arg5_, true);
1626+ EXPECT_EQ(arg6_, 0);
1627+}
1628+
1629+// This tests accumulation as well
1630+TEST_F(TestGLibSignals, TestSignal6)
1631+{
1632+ Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char> signal;
1633+ signal.Connect(test_signals_, "signal6",
1634+ sigc::mem_fun(this, &TestGLibSignals::Signal6Callback));
1635+
1636+ gboolean ret = FALSE;
1637+ g_signal_emit_by_name(test_signals_, "signal6", "test", 100, 200.0f, 300.00,
1638+ TRUE, 'x', &ret);
1639+
1640+ EXPECT_TRUE(signal6_received_);
1641+ EXPECT_EQ(arg1_, "test");
1642+ EXPECT_EQ(arg2_, 100);
1643+ EXPECT_EQ(arg3_, 200.0f);
1644+ EXPECT_EQ(arg4_, 300.00);
1645+ EXPECT_EQ(arg5_, true);
1646+ EXPECT_EQ(arg6_, 'x');
1647+ EXPECT_EQ(ret, TRUE);
1648+}
1649+
1650+TEST_F(TestGLibSignals, TestDisconnection)
1651+{
1652+ Signal<void, TestSignals*> signal;
1653+ signal.Connect(test_signals_, "signal0",
1654+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
1655+ signal.Disconnect();
1656+
1657+ g_signal_emit_by_name(test_signals_, "signal0");
1658+
1659+ EXPECT_FALSE(signal0_received_);
1660+}
1661+
1662+TEST_F(TestGLibSignals, TestAutoDisconnection)
1663+{
1664+ {
1665+ Signal<void, TestSignals*> signal;
1666+ signal.Connect(test_signals_, "signal0",
1667+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
1668+ }
1669+
1670+ g_signal_emit_by_name(test_signals_, "signal0");
1671+
1672+ EXPECT_FALSE(signal0_received_);
1673+}
1674+
1675+TEST_F(TestGLibSignals, TestCleanDestruction)
1676+{
1677+ Signal<void, TestSignals*> signal;
1678+ signal.Connect(test_signals_, "signal0",
1679+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
1680+ g_object_unref (test_signals_);
1681+}
1682+
1683+TEST_F(TestGLibSignals, TestManagerConstruction)
1684+{
1685+ SignalManager manager;
1686+}
1687+
1688+TEST_F(TestGLibSignals, TestManagerAddition)
1689+{
1690+ SignalManager manager;
1691+
1692+ manager.Add(new Signal<void, TestSignals*>(test_signals_,
1693+ "signal0",
1694+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
1695+ manager.Add(new Signal<void, TestSignals*, const char *>(test_signals_,
1696+ "signal1",
1697+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)));
1698+ manager.Add(new Signal<void, TestSignals*, const char *, int>(test_signals_,
1699+ "signal2",
1700+ sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)));
1701+ manager.Add(new Signal<void, TestSignals*, const char *, int, float>(test_signals_,
1702+ "signal3",
1703+ sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)));
1704+ manager.Add(new Signal<void, TestSignals*, const char *, int, float, double>(test_signals_,
1705+ "signal4",
1706+ sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)));
1707+ manager.Add(new Signal<void, TestSignals*, const char *, int, float, double, gboolean>(test_signals_,
1708+ "signal5",
1709+ sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)));
1710+ manager.Add(new Signal<gboolean, TestSignals*, const char *, int, float, double, gboolean, char>(test_signals_,
1711+ "signal6",
1712+ sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)));
1713+}
1714+
1715+TEST_F(TestGLibSignals, TestManagerConnection)
1716+{
1717+ SignalManager manager;
1718+
1719+ manager.Add(new Signal<void, TestSignals*>(test_signals_,
1720+ "signal0",
1721+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
1722+
1723+ g_signal_emit_by_name(test_signals_, "signal0");
1724+ EXPECT_TRUE(signal0_received_);
1725+
1726+ manager.Add(new Signal<void, TestSignals*, const char *>(test_signals_,
1727+ "signal1",
1728+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)));
1729+ g_signal_emit_by_name(test_signals_, "signal1", "test");
1730+ EXPECT_TRUE(signal1_received_);
1731+
1732+ gboolean ret = FALSE;
1733+ manager.Add(new Signal<gboolean, TestSignals*, const char *, int, float, double, gboolean, char>(test_signals_,
1734+ "signal6",
1735+ sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)));
1736+ g_signal_emit_by_name(test_signals_, "signal6", "test", 100, 1.0f, 100.00, FALSE, 'x', &ret);
1737+ EXPECT_TRUE(signal6_received_);
1738+ EXPECT_TRUE(ret);
1739+}
1740+
1741+TEST_F(TestGLibSignals, TestManagerAutoDisconnect)
1742+{
1743+ {
1744+ SignalManager manager;
1745+ manager.Add(new Signal<void, TestSignals*>(test_signals_,
1746+ "signal0",
1747+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
1748+ }
1749+
1750+ g_signal_emit_by_name(test_signals_, "signal0");
1751+ EXPECT_FALSE(signal0_received_);
1752+}
1753+
1754+TEST_F(TestGLibSignals, TestManagerDisconnection)
1755+{
1756+ SignalManager manager;
1757+
1758+ manager.Add(new Signal<void, TestSignals*>(test_signals_,
1759+ "signal0",
1760+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
1761+ manager.Disconnect(test_signals_, "signal0");
1762+
1763+ g_signal_emit_by_name(test_signals_, "signal0");
1764+ EXPECT_FALSE(signal0_received_);
1765+}
1766+
1767+}
1768
1769=== added file 'tests/test_glib_signals_utils.cpp'
1770--- tests/test_glib_signals_utils.cpp 1970-01-01 00:00:00 +0000
1771+++ tests/test_glib_signals_utils.cpp 2011-07-15 10:26:29 +0000
1772@@ -0,0 +1,102 @@
1773+#include "test_glib_signals_utils.h"
1774+#include "test_glib_signals_utils_marshal.h"
1775+
1776+enum
1777+{
1778+ SIGNAL_0,
1779+ SIGNAL_1,
1780+ SIGNAL_2,
1781+ SIGNAL_3,
1782+ SIGNAL_4,
1783+ SIGNAL_5,
1784+ SIGNAL_6,
1785+
1786+ LAST_SIGNAL
1787+};
1788+
1789+
1790+static guint32 _service_signals[LAST_SIGNAL] = { 0 };
1791+
1792+G_DEFINE_TYPE (TestSignals, test_signals, G_TYPE_OBJECT);
1793+
1794+static void
1795+test_signals_class_init (TestSignalsClass *klass)
1796+{
1797+ GObjectClass *obj_class = G_OBJECT_CLASS (klass);
1798+
1799+ /* Signals */
1800+ _service_signals[SIGNAL_0] =
1801+ g_signal_new ("signal0",
1802+ G_OBJECT_CLASS_TYPE (obj_class),
1803+ G_SIGNAL_RUN_LAST,
1804+ 0,
1805+ NULL, NULL,
1806+ g_cclosure_marshal_VOID__VOID,
1807+ G_TYPE_NONE, 0);
1808+
1809+ _service_signals[SIGNAL_1] =
1810+ g_signal_new ("signal1",
1811+ G_OBJECT_CLASS_TYPE (obj_class),
1812+ G_SIGNAL_RUN_LAST,
1813+ 0,
1814+ NULL, NULL,
1815+ g_cclosure_marshal_VOID__STRING,
1816+ G_TYPE_NONE, 1, G_TYPE_STRING);
1817+
1818+ _service_signals[SIGNAL_2] =
1819+ g_signal_new ("signal2",
1820+ G_OBJECT_CLASS_TYPE (obj_class),
1821+ G_SIGNAL_RUN_LAST,
1822+ 0,
1823+ NULL, NULL,
1824+ test_signals_VOID__STRING_INT,
1825+ G_TYPE_NONE, 2,
1826+ G_TYPE_STRING, G_TYPE_INT);
1827+
1828+ _service_signals[SIGNAL_3] =
1829+ g_signal_new ("signal3",
1830+ G_OBJECT_CLASS_TYPE (obj_class),
1831+ G_SIGNAL_RUN_LAST,
1832+ 0,
1833+ NULL, NULL,
1834+ test_signals_VOID__STRING_INT_FLOAT,
1835+ G_TYPE_NONE, 3,
1836+ G_TYPE_STRING, G_TYPE_INT, G_TYPE_FLOAT);
1837+
1838+ _service_signals[SIGNAL_4] =
1839+ g_signal_new ("signal4",
1840+ G_OBJECT_CLASS_TYPE (obj_class),
1841+ G_SIGNAL_RUN_LAST,
1842+ 0,
1843+ NULL, NULL,
1844+ test_signals_VOID__STRING_INT_FLOAT_DOUBLE,
1845+ G_TYPE_NONE, 4,
1846+ G_TYPE_STRING, G_TYPE_INT, G_TYPE_FLOAT, G_TYPE_DOUBLE);
1847+
1848+ _service_signals[SIGNAL_5] =
1849+ g_signal_new ("signal5",
1850+ G_OBJECT_CLASS_TYPE (obj_class),
1851+ G_SIGNAL_RUN_LAST,
1852+ 0,
1853+ NULL, NULL,
1854+ test_signals_VOID__STRING_INT_FLOAT_DOUBLE_BOOLEAN,
1855+ G_TYPE_NONE, 5,
1856+ G_TYPE_STRING, G_TYPE_INT, G_TYPE_FLOAT,
1857+ G_TYPE_DOUBLE, G_TYPE_BOOLEAN);
1858+
1859+ _service_signals[SIGNAL_6] =
1860+ g_signal_new ("signal6",
1861+ G_OBJECT_CLASS_TYPE (obj_class),
1862+ G_SIGNAL_RUN_LAST,
1863+ 0,
1864+ NULL, NULL,
1865+ test_signals_BOOLEAN__STRING_INT_FLOAT_DOUBLE_BOOLEAN_CHAR,
1866+ G_TYPE_BOOLEAN, 6,
1867+ G_TYPE_STRING, G_TYPE_INT, G_TYPE_FLOAT,
1868+ G_TYPE_DOUBLE, G_TYPE_BOOLEAN, G_TYPE_CHAR);
1869+}
1870+
1871+static void
1872+test_signals_init (TestSignals *self)
1873+{
1874+}
1875
1876=== added file 'tests/test_glib_signals_utils.h'
1877--- tests/test_glib_signals_utils.h 1970-01-01 00:00:00 +0000
1878+++ tests/test_glib_signals_utils.h 2011-07-15 10:26:29 +0000
1879@@ -0,0 +1,46 @@
1880+/*
1881+ * GObject Class to allow for extensive testing of our Signal wrapper
1882+ */
1883+
1884+#ifndef _TEST_SIGNALS_H_
1885+#define _TEST_SIGNALS_H_
1886+
1887+#include <glib-object.h>
1888+
1889+G_BEGIN_DECLS
1890+
1891+#define TEST_TYPE_SIGNALS (test_signals_get_type ())
1892+
1893+#define TestSignals(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
1894+ TEST_TYPE_SIGNALS, TestSignals))
1895+
1896+#define TestSignals_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
1897+ TEST_TYPE_SIGNALS, TestSignalsClass))
1898+
1899+#define TEST_IS_SIGNALS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
1900+ TEST_TYPE_SIGNALS))
1901+
1902+#define TEST_IS_SIGNALS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
1903+ TEST_TYPE_SIGNALS))
1904+
1905+#define TestSignals_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
1906+ TEST_TYPE_SIGNALS, TestSignalsClass))
1907+
1908+typedef struct _TEST_SIGNALS TestSignals;
1909+typedef struct _TEST_SIGNALSClass TestSignalsClass;
1910+
1911+struct _TEST_SIGNALS
1912+{
1913+ GObject parent;
1914+};
1915+
1916+struct _TEST_SIGNALSClass
1917+{
1918+ GObjectClass parent_class;
1919+};
1920+
1921+GType test_signals_get_type(void) G_GNUC_CONST;
1922+
1923+G_END_DECLS
1924+
1925+#endif /* _TEST_SIGNALS_H_ */
1926
1927=== added file 'tests/test_glib_signals_utils_marshal.list'
1928--- tests/test_glib_signals_utils_marshal.list 1970-01-01 00:00:00 +0000
1929+++ tests/test_glib_signals_utils_marshal.list 2011-07-15 10:26:29 +0000
1930@@ -0,0 +1,6 @@
1931+VOID:STRING,INT
1932+VOID:STRING,INT,FLOAT
1933+VOID:STRING,INT,FLOAT,DOUBLE
1934+VOID:STRING,INT,FLOAT,DOUBLE,BOOL
1935+BOOL:STRING,INT,FLOAT,DOUBLE,BOOL,CHAR
1936+BOOL:STRING,INT,FLOAT,DOUBLE,BOOL,CHAR,UINT
1937
1938=== modified file 'tests/test_indicator_entry.cpp'
1939--- tests/test_indicator_entry.cpp 2011-06-21 12:10:09 +0000
1940+++ tests/test_indicator_entry.cpp 2011-07-15 10:26:29 +0000
1941@@ -1,4 +1,4 @@
1942-#include <UnityCore/UnityCore.h>
1943+#include <UnityCore/IndicatorEntry.h>
1944
1945 #include <gtest/gtest.h>
1946
1947
1948=== added file 'tests/test_main.cpp'
1949--- tests/test_main.cpp 1970-01-01 00:00:00 +0000
1950+++ tests/test_main.cpp 2011-07-15 10:26:29 +0000
1951@@ -0,0 +1,10 @@
1952+#include <gtest/gtest.h>
1953+#include <glib-object.h>
1954+
1955+int main(int argc, char **argv)
1956+{
1957+ ::testing::InitGoogleTest(&argc, argv);
1958+ g_type_init();
1959+
1960+ return RUN_ALL_TESTS();
1961+}