|
Boost : |
From: E. Gladyshev (eegg_at_[hidden])
Date: 2004-03-17 22:32:43
----- Original Message -----
From: "Douglas Gregor" <gregod_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Wednesday, March 17, 2004 9:22 AM
>
> This is the slot ordering issue again :) If you insert with a group that
> precedes the group being called, it will not be called during that
> invocation. If you insert with a group that follows the gorup being
called,
> it will be called during that invocation. If you insert in the same group
as
> the one being called, you don't know because there is no guaranteed
ordering
> within a group [*].
I see... makes sense to me.
>
> > > Which operation's complexity are you concerned about? I've never heard
of
> >
> > a
> >
> > > performance problem...
> >
> > Sometimes, from the event property values, the signal source can
> > tell what slot exactly or subset of slots need to be called and
> > that other slots should not be bothered with this event instance.
> > In what case the signal source should havea random access to the slots.
> > Otherwise it will have to propagate the event to *all*
> > slots and let them decide on what to do. If the number of slots
> > is not too big, this works just fine. However if the number
> > of slots is huge, the optimization is important and one
> > of the optimized solutions will most likely require
> > a random access to slots based on the slot index and slot ordering
> > support, including slot insertions at specified
> > positions in the slot list.
>
> Ok, I understand this. I thought you were referring to a different source
of
> inefficiency.
>
> In any case, getting random access (traversal) iterators and fast ordered
> insertions/deletions is not a trivial task. Did you have some particular
data
> structure in mind that could do this?
I guess it could be something like tree (balanced, Red-Black whatever).
But, I'd let the user to define the container type.
>
> Here is a question for you: would the ability to invoke only the slots
within
> a particular group solve this problem? That is implementable within the
> current semantics, although it will not give random access.
Bingo.
It'll give me a control over how the slots are called.
Then, what I can do is associate my group numbers
with the items.
//physical list box callback
void on_lisbox_event( event e );
listbox lb(on_lisbox_event); //physical listbox interface
signal<event> sig;
void connect_item( item i )
{
int group = generate_uniq_group_number();
//add the item label to the listbox
int index = lb.add(i.label()); //returns the new item index
//set my user data associate with the label
lb.set_user_data( index, group );
//make connection
sig.connect( group, i );
}
void on_lisbox_event( event e )
{
//index of the item that generated this event
int index = e.get_index();
//get the group
int group = lb.get_user_data( index );
//send event to the item
sig( e, group );
}
The set_user_data()/get_user_data() function is the key.
Except generate_uniq_group_number() (which is not going to be pretty),
it should work.
Will signals automatically free resources for groups that are empty?
A question about combiner:
struct combiner
{
template<typename InputIterator>
T operator()(InputIterator first, InputIterator last) const;
};
Are [first,last] iterators ordered by the group number?
[...]
>
> You might be better off with a vector of boost::function objects.
Yes, I thought about it too.
However I'd like to have the "trackable" feature.
>
> > I'd say that instead of changing the existing
> > signals semantic to support the slot ordering
> > and random slot access, I would make it possible
> > to access and call slots that are referenced
> > by signals::connection objects and leave the rest
> > to the user. In a way, it is just an
> > extension to the combiner semantic.
> > Indeed with combiner, the user can propagate the event
> > as she likes anyway except that she has no idea
> > what slot is what (it is really strange to me).
>
> You usually can't tell what slots you're calling anyway, because type
> information is lost to the user once you've connected the slot. The point
of
> a callback is that you don't know where you're calling back to.
It is not always the case. For example Win32 supports
the so called callback chains so you know where
in the chain you are. Even more... from your callback,
you can make a call that will send the event
down the chain then it will return
and your callback can do something else.
People use this technique all the time.
To make signals usable for serious GUI development,
I think that it should support something like this.
[...]
>
> > I'll try to give a real life example once again.
> > In Win32 the standard listbox control can generate
> > messages that have the listbox item index as one
> > of the message parameters.
> > Imagine that each item in the listbox is implemented
> > as a signal slot.
> > How would you propagate the Win32 messages
> > that are targeting separate listbox items
>
> If we had the ability to invoke only the slots that were part of a
particular
> group, you would make the group the listbox item number. Slots that are
> interested in all item numbers would not have any group; slots interested
in
> a particular item number would be in that group.
> Item numbers aren't all that great to use, because items can be inserted
or
> deleted. You'd probably be better off using some other form of identifier
for
> list items.
Yes, something like this (see my example above).
> It's a bit of a strange problem. I don't believe that random access
traversal
> iterators are the right answer; calling via a signals::connection derived
> class is rather redundant, because you'd be cloning the signal's internal
> ordering.
I will be imposing my own ordering, not cloning the signal's ordering
that I don't know anyway.
> Invocation of slots in a particular group might do it for you, but
> only if you don't need to deal with, e.g., slots that accept a subrange of
> item index numbers.
I need to build something like callback chains as well.
I guess that I'll have to do some not very pretty
tricks... but yes, it should do it for me.
Eugene
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk