[signals2] connection blocking
Hi, I've starting porting some code from signals to signals2, and I've run into a problem because of the removal of the 'block' and 'unblock' methods from a connection object. I understand the rational for using the 'shared_connection_block' object, but it doesn't really apply in my case. I have a GUI widget which receives events via a signal, unless it is in an "inactive" state, during which time events are blocked: class widget { private: boost::signals::connection conn; ... public: void toggle_active_state() { ... if (inactive) conn.block(); else conn.unblock(); } }; It is obviously awkward to be forced to convert this code to use an RAII object, and I'd rather not do a full connect/disconnect for this state change. What do you think? Should I be thinking about this differently? Or can a good case be made for bringing back the block()/unblock() methods? Thanks, -bryan
On Friday 15 May 2009, Bryan Green wrote:
It is obviously awkward to be forced to convert this code to use an RAII object, and I'd rather not do a full connect/disconnect for this state change. What do you think? Should I be thinking about this differently? Or can a good case be made for bringing back the block()/unblock() methods?
Is it really so awkward? shared_connection_block has block/unblock methods. The shared_connection_block constructor does always immediately block the connection though, maybe adding a constructor which defers blocking would help.
Frank Mori Hess writes:
On Friday 15 May 2009, Bryan Green wrote:
It is obviously awkward to be forced to convert this code to use an RAII object, and I'd rather not do a full connect/disconnect for this state change. What do you think? Should I be thinking about this differently? Or can a good case be made for bringing back the block()/unblock() methods?
Is it really so awkward? shared_connection_block has block/unblock methods. The shared_connection_block constructor does always immediately block the connection though, maybe adding a constructor which defers blocking would help.
Having such a constructor might save some work in some cases. It seems less awkward now that I realize the shared_connection_block does not hold a reference to the connection object it is initialized with. That had been my first impression. I guess what I still find awkward is having to dynamically allocate a shared_connection_block object for each of my connections, possibly in addition to a connection or a scoped connection object. I had previously been using one scoped connection object per connection. Now I need one scoped connection and one dynamically allocated shared_connection_block per connection, such as this: class widget { private: boost::signals2::scoped_connection conn; boost::scoped_ptrboost::signals2::shared_connection_block conn_blk; ... public: void initialize(const eventsource &src) { conn = src.event_signal().connect(&widget::update,this); conn_blk.reset(new boost::signals2::shared_connection_block(conn)); conn_blk->unblock(); } void toggle_active_state() { ... if (inactive) conn_blk->block(); else conn_blk->unblock(); } }; I suppose I don't need the connection object at all if the widget itself is trackable. But now that I've looked at the shared_connection_block code, I'm wondering, why is it noncopyable? It looks to me like it could be. If it were copyable/assignable (and ultimately, movable), I wouldn't need to dynamically allocate it. -bryan
Bryan Green writes:
I suppose I don't need the connection object at all if the widget itself is trackable. But now that I've looked at the shared_connection_block code, I'm wondering, why is it noncopyable? It looks to me like it could be. If it were copyable/assignable (and ultimately, movable), I wouldn't need t= o dynamically allocate it.
I have correct what I said here. The problem isn't copyability (they are copyable). Its that the shared_connection_block cannot be default-constructed. What would be the repercussions of allowing default construction of shared_connection_block objects? -bryan
I have correct what I said here. The problem isn't copyability (they are copyable). Its that the shared_connection_block cannot be default-constructed. What would be the repercussions of allowing default construction of shared_connection_block objects?
I guess it wouldn't be RAII then.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday 18 May 2009, Bryan Green wrote:
Bryan Green writes:
I suppose I don't need the connection object at all if the widget itself is trackable. But now that I've looked at the shared_connection_block code, I'm wondering, why is it noncopyable? It looks to me like it could be. If it were copyable/assignable (and ultimately, movable), I wouldn't need t= o dynamically allocate it.
I have correct what I said here. The problem isn't copyability (they are copyable). Its that the shared_connection_block cannot be default-constructed. What would be the repercussions of allowing default construction of shared_connection_block objects?
It probably wouldn't hurt. In the meantime you can also use
boost::optional
Frank Mori Hess writes:
On Monday 18 May 2009, Bryan Green wrote:
Bryan Green writes:
I suppose I don't need the connection object at all if the widget itself is trackable. But now that I've looked at the shared_connection_block code, I'm wondering, why is it noncopyable? It looks to me like it could be. If it were copyable/assignable (and ultimately, movable), I wouldn't need to dynamically allocate it.
I have correct what I said here. The problem isn't copyability (they are copyable). Its that the shared_connection_block cannot be default-constructed. What would be the repercussions of allowing default construction of shared_connection_block objects?
It probably wouldn't hurt. In the meantime you can also use boost::optional
to unintrusively add an uninitialized state and avoid dynamic allocation.
Thanks for the tip. That does the trick. Now, here's a crazy suggestion. How about adding a connection accessor method to the shared_connection_block? Since the shared_connection_block implicitly contains a connection object anyway, allowing access to it would alleviate the need to keep another one around: shared_connection_block blk(sig.connect(func)); ... blk.get_connection().disconnect(); I may be naive, but the implementation looks like it would be as simple as: connection shared_connection_block::get_connection() { connection c(_weak_connection_body); return c; } -bryan
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday 18 May 2009, Bryan Green wrote:
Thanks for the tip. That does the trick. Now, here's a crazy suggestion. How about adding a connection accessor method to the shared_connection_block? Since the shared_connection_block implicitly contains a connection object anyway, allowing access to it would alleviate the need to keep another one around:
I'll look into it. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkoSsPkACgkQ5vihyNWuA4X3VwCg4fQn+hbHxOQpNgV5j6tTaap5 A3wAnjFstZDWexvd5DZfWmX1H1eno67+ =hdL0 -----END PGP SIGNATURE-----
participants (4)
-
Bryan Green
-
Frank Mori Hess
-
Frank Mori Hess
-
Igor R