Re: [sigc] Deprecate signal<>::slots() ?



On So, 2016-04-24 at 01:20 +0000, James Lin wrote:
Murray Cumming wrote:


James Lin wrote:

So if you could add sigc::signal<>::block/unblock methods, then
we
could stop using sigc::signal<>::slots (and have a better
mechanism
to do what we want).
Wouldn't it be best to just not emit signals that you don't want to
emit?
Ideally, yes, but in practice I think it's easier said than
done.  For example, suppose you have some object with a coarse-
grained `changed` signal that is automatically emitted whenever a
mutator on it is called.  But perhaps a client wants to mutate
multiple properties on that object at once and does not want to
trigger a flurry of unnecessary callbacks.  I think it'd be better
for the client to temporarily block the signal than to:
A. Add arguments to every mutator to opt out of signal emission.
B. Add a non-emitting version of each mutator.
C. Add mutator methods that update different combinations of
properties.

Surely, if you can call m_signal.block(), m_signal.unblock(), and
m_signal.emit(), then you can call the_signal_block(),
the_signal_unblock() and the_signal_emit().

the_signal_block()/unblock() just sets/unsets a bool and
the_signal_emit() checks that bool before emitting the signal.

I do this often, inside the emitting class, to make sure that I only
emit signals in response to outside events, such as user input, not in
response to intermediate changes that are implementation-dependent.

Even so, I think it's unwise to allow this from outside the class,
because it's too low-level an API. Ideally you'd have some way to
provide multiple properties in a single call, maybe via some Builder
object:

auto stuff = StuffBuilder.setFoo(foo).
  setBar(bar).
  setGoo(goo);
thing.set_stuff(stuff);

At the least, I would hope that the block/freeze/whatever method
doesn't mention the signal explicitly.


Also, if we add signal::block()/unblock() then any object's signals can
be blocked/unblocked even if you don't want to offer that ability. That
breaks encapsulation, letting client code interfere with the internal
logic of the class. glib's signals allow this, and it is quite often
abused. This leads to fragile hacky code, because the author of the
code that emits the signal never meant to offer that interface or make
any promise about its behaviour.


A signal also could be connected to another signal.  In that case,
one could block the sigc::connection for the child signal, but
keeping track of that is additional bookkeeping.

I suppose another alternative would be to create a separate class
that wraps a specific type of sigc::signal, but that seems a bit
awkward.

To some degree I also think that having sigc::signal::block/unblock
methods would be nice for consistency with sigc::slot and
sigc::connection.

-- 
Murray Cumming
murrayc murrayc com
www.murrayc.com





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