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

Re: [E-devel] evas object event callback API

Carsten Haitzler:
> On Sat, 19 Aug 2006 19:32:06 +0200 Jan Rychter <jan@rychter.com> babbled:
> > [the delay is because I wanted to have working code before I comment
> >  further, and work intervened]
> > 
> > Carsten Haitzler:
> > > On Sat, 05 Aug 2006 12:45:39 +0200 Jan Rychter <jan@rychter.com> babbled:
> > > In ecore_evas - you do have a problem as it expects ONE callabck only per
> > > ecore_evas canvas wrapper and events 
> > 
> > I maintain a table of callbacks anyway and register only one dispatching
> > function (that in turn calls the real callback functions), so ecore_evas
> > only knows about one callback: the dispatching function. I delete that
> > callback when the last callback in my table gets deleted. It's simple
> > enough: about 30 lines of code to deal with all ecore_evas callbacks.
> cool- thought to me i don't like this because of inconsistency - but anyway :)

Well, I can't see any other way given that the main point of the whole
thing is to be able to use closures as callbacks (local anonymous
functions), so I have to do a similar thing for every EFL library out
there. In C it makes sense to assume that every callback is a globally
defined function, in other languages it does not, and then you might end
up with a lot more callbacks.

> > > - BUT for evas this is not the case. you
> > > can attach N event callbacks to any objects for an event type. as you hve a
> > > generic void *data pointer for all of these, you can use this to
> > > differentiate, pass extra data for your binding (pass in an allocated
> > > struct ptr that then contains all of the data you could/would need - even
> > > like event type). the void *data pointer should be sufficient for all your
> > > needs - if used right. what about this makes it not possible to bind to
> > > another language? i have bound identical callbacks for timers for example
> > > in embryo for scripting - a timer gets passed only 1 parameter - a void *
> > > pointer.
> > 
> > Right. The *data pointer is a very neat and smart idea. I was just
> > hoping I wouldn't have to allocate/deallocate structures and use the
> > pointer just so that I can stick the event type in there. I really
> > expected the event type to be part of the callback signature, after all
> > you need it to decode the event info.
> yeah. in the world of c - the data pointer is your ultimate "1 thing does it
> all" friend and CAN do everything here - but you may need to allocate the data
> pointer per callback set. generally though this data pointer is used to point
> to some higher level object construct (eg the callback is on an object that is
> part of a window or a widget etc. etc.)

For the moment I ended up creating objects corresponding to each
Evas. That's where I store my lists of callbacks of each type. They are
accessed using a global hash table using the Evas pointer as a hash key.

> > > if your point is that you want to create the "1 callback does all" thing and
> > > only ever bind that 1 function to everything using the event type to then
> > > switch off internally - then you just are wanting to do things in a way evas
> > > was not intended to work. yes - it expects a callback to be set and
> > > specialized for at least that TYPE of event. so you will need N callbacks
> > > in the binding api - 1 per event type you  wish to handle, and then use the
> > > void *data to piggyback whatever extra info you need :) changing the
> > > callback api will basically break a few hundred thousand lines of code and
> > > i'd need a reason why the current api CANNOT do what you NEED - not just a
> > > "it doesn't work the way i wanted to do this" :)
> > 
> > Well, I still believe that the event type should be passed to the
> > callback function, but yes, I can work around it. I have to define 9
> > functions, one per event structure (plus one for all the NULL event
> > pointer cases). One could argue that I have to decode all these event
> > structures anyway, so I might as well do it in separate functions. It
> > makes my code larger, but if you really don't want to change the APIs,
> > it's fair enough. The code I've written now works.
> > 
> > I guess it isn't a question of "possible", but a question of
> > "elegant". Fundametally, everything is possible.
> yeah - but here the problem would be breaking the api in a way that breaks a
> LOT of code that would need changing, and for a very "dubious" reason - the
> code being broken won't be improved in this case. :( often things like this are
> a matter of weighing up the needs vs the impact and making a call - and in this
> case i think i make the call of "don't break the api" :(

I respectfully disagree -- e.g. I think changing the API in this way is
rather easy. It involves _adding_ another parameter to the callback
signature, which the existing code is perfectly free to ignore. It is
pretty much a search-and-replace operation, and does not affect existing

A quick grep of the e17 source tree shows 479 calls to
object_event_callback_add, so there are probably roughly as many
callbacks. None would break if another parameter was added. But -- as I
said -- I can live without that parameter. The code works without it.