Hi All. I'm aware of two kinds of GUI event response mechanisms. (I'm dropping phooey or cello since I don't know them. Furthermore, their implementation is probably too different of what I want to talk here.)
The first one is Immediate Mode GUI and the second one is the so classic Callbacks, event-driven mechanism. In this text, I'll try to say why I don't like the second one (I won't talk about the first one.) and provide an idea that only appeared clearly to me yesterday (although it's really simple). This idea avoids what I don't like about the Callbacks while letting the user still use them. I first thought I would implement it a bit (on top of the project with Brandon) before talking about it but I need to write to not forget. Also, those who are interested in Felix's GUI project might like it (and give some feedaback !). Disclaimer: I'm not an expert, I just have some ideas :) but I hope to say not to much stupid things. Immediate Mode GUI. The idea is to have the drawing and event-responsing of a widget happens at the same time. It thus needs some decent framerate. It means no callback : the code handling the event is written alongside the code displaying the widget (and the code testing the existence of the event). It can also means no data structure for the widgets (just like you can write a rectangle with opengl without having to store a Rectangle object; the code is the object). Google for references. See also 'A Zero Memory Widget Library'. ZMW uses a datastructure when traversing the code; it's necessary if you want to calculate the size of a widget which is made of other (unknown) widgets. Callbacks. Classical GUI libraries let the programmer write an application that responds to user actions : the A button is clicked or the Y window is moused-over. The code is bound to the event by registering a so called callback (simply a lambda abstraction on this side of the world, an ugly in-line class instanciation (and interface implementation) in the Java world). So basically, a function is called back when a gui event arises. The mechanism by which events are detected and functions called back is hidden (transparent for the programmer). What I Don't Like About Callbacks. a) Putted simply, you can't mix gui events with application specific events. b) (which is related) Since a function call results from an event, you can't generate an event whose callback needs the end of the event-generating-computation (i.e. it's not asynchronous). I'd rather like to finish a computation which generates an event before processing it. c) Also, say you want to code "When the left mouse button is pressed (elsewhere than above my two main widgets), make the first widget be blue and the second one be red.". (Call this the blue-red exemple for later reuse.) You'll need to register a callback on the background widget. This callback needs to access (to be aware of) the two other widgets. I don't like this. "My" Idea. I call it mine but I don't know .. maybe it's as old as the world ? - The callback mechanism is exposed and made not mandatory. - The widgets are aware of events, not the contrary (see c) above). - The event facility can be used for application-generated events. - The ol'callback way is still available. How. An event-queue keeps the not-yet-processed events. (For some application, it might be useful to timestamp events so they are dispatched later or even keep the already-processed events to be able to reverse time.) For some event, the current state is kept. Exemple: You might not want to have code run each time the <enter> key is pressed but only want to be able to query its state; is it pressed ? Or you might want to be able to respond to the many events that have appeared before your code is run. You already see the moment when an event is generated and the moment when it is processed are no tied. Also, sampling for events and processing them are not tied. The base API let you test the existence of an event. The test can be blocking or not. It can removes the event from the queue or not. (The api has to be extended so an event can be removed automatically when every interested widget has already received it.) (This last point let you write the blue-red program: the two widgets are aware of the events.) At this point, we have access to events. But how (when) the code accessing the events is run ? How the gui event-polling is done ? Here again we gain some flexibility. You can write yourself a loop that calls one API function to pump gui events then calls the event-testing-related API functions. Or you can use an API function set to let you register functions to be called regularly (independently of events) and then launch an API- provided main loop. Or register functions to be called only for some specific events. Yep, we approached the well-known callback mechanism. To make it really feels like that, we can provide a function which makes the widget generate an event *and* register a callback for that specific event. By 'specific event', I mean an event has some kind of name. When you register a function, you have to say for which event names you want it to respond. So the function I talked about in the previous paragraph can generate a unique name so only *that* widget and *that* callback are tied. To be continuously sampled, independently of events, you register the function for the 'tick event (or for the '20hz event ?). Briefly. A more general mechanism than traditional callbacks is presented. It involves an events-related data structure and API. It can involve a scheduler to call registered functions when some named event is present. Multiple handlers (functions) can react to the same event. Traditional callback style API is provided. It was Long but Done. Well, I'm eager to read your feedback ! Cheers, thu _______________________________________________ Chicken-users mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/chicken-users
