Merge lp:~thomas-voss/properties-cpp/make-scoped-connection-movable into lp:properties-cpp

Proposed by Thomas Voß on 2014-01-13
Status: Merged
Approved by: Timo Jyrinki on 2014-01-14
Approved revision: 13
Merged at revision: 11
Proposed branch: lp:~thomas-voss/properties-cpp/make-scoped-connection-movable
Merge into: lp:properties-cpp
Diff against target: 166 lines (+61/-5)
3 files modified
include/core/connection.h (+31/-3)
include/core/property.h (+19/-2)
tests/properties_test.cpp (+11/-0)
To merge this branch: bzr merge lp:~thomas-voss/properties-cpp/make-scoped-connection-movable
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve on 2014-01-13
Ubuntu Phablet Team 2014-01-13 Pending
Review via email: mp+201454@code.launchpad.net

Commit message

Refactor to rely on default move-operator for core::Connection.
Enable property chaining.
Make sure that an abandoned connection safely accesses its private member.
Make ScopedConnection a movable type.

Description of the change

Refactor to rely on default move-operator for core::Connection.
Enable property chaining.
Make sure that an abandoned connection safely accesses its private member.
Make ScopedConnection a movable type.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/core/connection.h'
2--- include/core/connection.h 2013-11-28 07:35:14 +0000
3+++ include/core/connection.h 2014-01-13 16:44:20 +0000
4@@ -24,6 +24,7 @@
5
6 namespace core
7 {
8+class ScopedConnection;
9 /**
10 * @brief The Connection class models a signal-slot connection.
11 */
12@@ -38,6 +39,9 @@
13 */
14 inline bool is_connected() const
15 {
16+ if (!d)
17+ return false;
18+
19 return (d->disconnector ? true : false);
20 }
21
22@@ -46,7 +50,8 @@
23 */
24 inline void disconnect()
25 {
26- d->disconnect();
27+ if (d)
28+ d->disconnect();
29 }
30
31 /**
32@@ -55,11 +60,13 @@
33 */
34 inline void dispatch_via(const Dispatcher& dispatcher)
35 {
36- if (d->dispatcher_installer)
37+ if (d && d->dispatcher_installer)
38 d->dispatcher_installer(dispatcher);
39 }
40
41 private:
42+ friend class ScopedConnection;
43+
44 typedef std::function<void()> Disconnector;
45 typedef std::function<void(const Dispatcher&)> DispatcherInstaller;
46
47@@ -71,9 +78,15 @@
48 {
49 }
50
51+ inline bool operator<(const Connection& rhs) const
52+ {
53+ return d < rhs.d;
54+ }
55+
56 inline void reset()
57 {
58- d->reset();
59+ if (d)
60+ d->reset();
61 }
62
63 struct Private
64@@ -136,6 +149,10 @@
65 {
66 }
67
68+ inline ScopedConnection(ScopedConnection&& rhs) : connection(std::move(rhs.connection))
69+ {
70+ }
71+
72 ScopedConnection(const ScopedConnection&) = delete;
73
74 /**
75@@ -151,9 +168,20 @@
76 }
77 }
78
79+ inline ScopedConnection& operator=(ScopedConnection&& rhs)
80+ {
81+ connection = std::move(rhs.connection);
82+ return *this;
83+ }
84+
85 ScopedConnection& operator=(const ScopedConnection&) = delete;
86 bool operator==(const ScopedConnection&) = delete;
87
88+ inline bool operator<(const ScopedConnection& rhs) const
89+ {
90+ return connection < rhs.connection;
91+ }
92+
93 private:
94 Connection connection;
95 };
96
97=== modified file 'include/core/property.h'
98--- include/core/property.h 2013-11-28 07:35:14 +0000
99+++ include/core/property.h 2014-01-13 16:44:20 +0000
100@@ -20,12 +20,17 @@
101
102 #include <core/signal.h>
103
104-#include <iostream>
105+#include <set>
106
107 namespace core
108 {
109 /**
110 * @brief A very simple, templated class that allows for uniform declaration of get-able/set-able/observable members.
111+ *
112+ * A note on thread-safety: The property class itself does not give any thread-safety guarantees.
113+ * That is, consumers must not assume that concurrent get() and set() operations are synchronized by
114+ * this class.
115+ *
116 * @tparam The type of the value contained within the property.
117 */
118 template<typename T>
119@@ -166,8 +171,19 @@
120 return false;
121 }
122
123+ friend inline const Property<T>& operator|(const Property<T>& lhs, Property<T>& rhs)
124+ {
125+ rhs.connections.emplace(
126+ lhs.changed().connect(
127+ std::bind(
128+ &Property<T>::set,
129+ std::ref(rhs),
130+ std::placeholders::_1)));
131+ return lhs;
132+ }
133+
134 protected:
135- inline T& mutable_get() const
136+ inline virtual T& mutable_get() const
137 {
138 return value;
139 }
140@@ -175,6 +191,7 @@
141 private:
142 mutable T value;
143 Signal<T> signal_changed;
144+ std::set<ScopedConnection> connections;
145 };
146 }
147
148
149=== modified file 'tests/properties_test.cpp'
150--- tests/properties_test.cpp 2013-11-28 07:35:14 +0000
151+++ tests/properties_test.cpp 2014-01-13 16:44:20 +0000
152@@ -166,3 +166,14 @@
153
154 EXPECT_EQ(22, position);
155 }
156+
157+TEST(Property, chaining_properties_works)
158+{
159+ core::Property<int> p1, p2;
160+
161+ p1 | p2;
162+
163+ p1.set(42);
164+
165+ EXPECT_EQ(42, p2.get());
166+}

Subscribers

People subscribed via source and target branches