Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-02-27 11:33:00


On Tuesday 26 February 2002 01:10 pm, you wrote:
> I thing it would be better if you could connect several slots with
> the same name. And then disconnect them all with one disconnect call.
>
> If the user wants the other behaviour he can always 'just' disconnect
> before connecting. Or maybe add a unique_connect(..) method.
> Ex.
> s.connect( name, slot );
> becomes:
> s.disconnect( name );
> s.connect( name, slot );

I think I agree with you, but this would necessitate a naming change as well.
Instead of referring to the slot 'name', we should probably refer to the slot
'group' or 'group name'. Then it's more obvious that several slots can have
the same name, and that disconnect(group) will disconnect the entire group.
It also makes much better sense that there is an ordering between groups, but
not between members of the same group.

> It is really nice that the connection time for unnamed signals is
> O(1), I was not aware of this. It would be nice if we could keep
> it this way.
>
> If it is possible to connect with a priority value, It is not
> important to sort by name.
>
> I guess this will help with the O(lg n) connection time for
> unnamed connections with default priority?
>
> I would prefer a ordering by name.
>
> Soren

Unabashedly putting my implementor's cap on, it is hard to get the O(1)
insertions for unnamed slots and have priority or name-based ordering. Doing
this would essentially require two separate data structures: one for unnamed
slots that allows O(1) insertion and one for named slots that is kept
ordered. The slot call iterator can bridge the two data structures (using,
e.g., a version of the Union View from the View Template Library). Then we
would have two structures such as:

typedef std::multimap<SlotName, std::pair<connection, any> > named_slots_map;
typedef std::list<std::pair<connection, any> > unnamed_slots_list;

The iterator adaptation hierarchy to create the slot call iterator would
become even nastier:

   --------------------------- ------------------------------
  | named_slots_map::iterator | | unnamed_slots_list::iterator |
   --------------------------- ------------------------------
               ^ ^
               | |
     ---------------------- |
    | project_2nd_iterator | |
     ---------------------- |
               ^ |
               | |
                ---------- ------------
                          | |
                          ------------
                         | union_view |
                          ------------
                                ^
                                |
                    -------------------------
                   | filter_iterator_adaptor |
                   | skip disconnected slots |
                    -------------------------
                                ^
                                |
                      ----------------------
                     | project_2nd_iterator |
                      ----------------------
                                ^
                                |
                       ---------------------
                      | transform_iterator |
                      | any_cast<> |
                       ---------------------
                                ^
                                |
                      ---------------------
                     | transform_iterator |
                     | bind arguments |
                      ---------------------
                                ^
                                |
                     ------------------------
                    | input_caching_iterator |
                     ------------------------

Using the list we could guarantee either LIFO or FIFO ordering for unnamed
signals, and I would probably suggest LIFO so that it is clear that in the
following:

  sig1 calls slot1
  slot1 adds slot2 to sig1

if slot1 and slot2 are unnamed, slot2 is not immediately called.

The simpler alternative would be to not require O(1) insertion time for
unnamed signals. The named and unnamed signals could all reside in a
singlemultimap, and the key would be based on the slot name (if one existed).
This would hurt users that don't use named slots often, unfortunately.

What would users prefer? The first option, that would guarantee O(1)
insertion time for unnamed slots, O(lg n) insertion time for named slots, but
complicate (and somewhat slow down) the calling of slots? Or the second
option, that would guarantee O(lg n) insertion time for all slots but provide
a simpler implementation that might be (slightly) more efficient when calling
slots?

        Doug


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk