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
murr...@murrayc.com
www.murrayc.com



_______________________________________________
libsigc-list mailing list
libsigc-list@gnome.org
https://mail.gnome.org/mailman/listinfo/libsigc-list

Reply via email to