[Top][All Lists]

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

Re: about RunLoop, joystick support and so on

From: Xavier Glattard
Subject: Re: about RunLoop, joystick support and so on
Date: Wed, 14 Feb 2007 16:56:53 +0000 (UTC)
User-agent: Loom/3.14 (

Richard Frith-Macdonald <richard <at>> writes:

> On 13 Feb 2007, at 19:53, Xavier Glattard wrote:
> > I posted here some days ago more details about this opengl program.
> > If you need more, just ask. Did you launch it ?
> > It behaves as if the runLoop would block waiting for event from the  
> > gui
> > while some performers or user events are waiting. Under x11 only  
> > windows
> > with non retain backing store are faulty with 'Performers',  
> > 'Events&Perf' and 'Events&Timer' methods.
> I ran it on gnu/linux and it looked very good but the menu and the  
> controls on the window stopped operating ... I haven't had time to  
> really look at the code and figure out why.

Does it hang when you click the 'Start' button ?
I dont undertstand : it runs fine on my debian system (x86)
An OpenGL problem ?
> > Under w32 i just remember than the program
> > doesnt work properly in many more cases. You can select the backing  
> > store in the menu.
> I tried building under win32, but failed with a lot of link errors.   
> I'm probably missing an essential library.

I will try to rebuild it from the tarball. I may have missed something.
> (...) 
> The runloop uses a poll() or select() or WaitForMultipleObjects()  
> call to perform an idle wait for *all* events the program is  
> currently interested in.
> That means  that it does not do a busy poll using up the CPU with  
> repeated calls, and it does not block waiting for a single event  
> source, preventing other events from being received.

We agree :-)
The diagram was a simplification of what it should actually be done.
I've just put in a column all the messages that might be sent.
And i understand than it would be difficult to include in the run loop
a 'watcher' that can't be 'selected'. Such an input source have to be 
tested periodically :
 - start loop
 - select other sources for some 1/1[000] of a second
 - test the 'unselectable' source(s)
 - loop
So the is not busy all the time. It wakes up some time to time then 
goes back to sleep.

> (...)
>  From the point of view of the main public API it's in the  
> NSApplication instance and is accessible using NSApplication methods  
> like -nextEventMatchingMask:untilDate:inMode:dequeue: which have  
> certain implications such as the ability to extract events from  
> within the queue rather than just from the end.   The characteristics  
> that the queue has to have (picking items out of the queue rather  
> than just from the front, and accessing items in the queue without  
> necessarily removing them from it) are not those typical of a stream.

You're right. Streams may not be the right way to manage an event queue.
And for the moment i dont see a better way... Watchers might not be so
bad, after all ;o)

I've just found this :
I didn't read all but this might be the API you are waiting for ;-)

> > One problem is that the different queues (gui events, performers,
> > socket events...) are not handled by one only object.
> > When GSDisplay is asked for an event by the NSApp it returns one
> > from its queue or, if none is available, calls the runLoop. So the
> > runLoop doesn't manage the gui event queue and so has not all the
> > cards.
> That's perhaps a bug ... as I understand it the code it supposed to  
> return an X or windows event if it has already been received, and if  
> no event has been received, call the runloop to wait for more  
> events.  As long as that is working it's fine, but if the attempt to  
> check for an event already received also does a read to get new  
> events, then there is indeed the problem you describe of the runloop  
> never being called.  If this is happening, it's not a bug in the  
> runloop, just a subtle bug in the backend (in that it is failing to  
> run the runloop when it should).  Such a bug ought to be fairly easy  
> to fix ... a crude fix would be to run the runloop once  before  
> fetching each item from the windows message queue or X event queue.

No : the problem would then be moved to the runLoop : if many non gui
events occur in the runLoop, gui events would never be handled.
> A more efficient option might be to use different calls to examine  
> the windows/X event queues (ones that don't read in new events), or  
> to count the events available each time the runloop signals event  
> availability, and re-run therunloop after the count of events has  
> been processed.

IMHO the best option would be to manage all events (gui and non gui) 
in one place, saying the runLoop. One loop could be :

 - for each source of events : get one event if available (not wait)
 - if there is no event, wait (until a timer fires)
 - sort the events in a queue
 - return the oldest event

This mechanism would need an other queue in the runLoop (or one more 
queue for each mode ?). May be they already exist (?)
> > I thought of NSStream as a way to include gui event management
> > in the runLoop, at the same level as performers, NSPort and so on.
> > At present if for any reason the server event queue is always filled
> > up (by a user loop : select 'events(pure)' in my tool), the runLoop
> > is _never_ run.
> I think that may be the 'correct' behavior (by 'correct' I mean what  
> the documentation says and MacOS-X does).
> The programming model seems to expect that you should empty the queue  
> before trying to receive any more events.
> So if you call the -postEvent:... method of NSApplication, you add an  
> event to the application event queue, and if the code to handle that  
> event then posts a new one then obviously you never empty the event  
> queue and you just loop forever.  Could that be what's happening?

Yes. That's why i added two animation modes : events+performer and events+timer.
A performer or a timer is used to 'break' the event loop and give a chance to
the runLoop to do its job.
> > MacOS is unix based. So everything come from file descriptors.
> Also Mach messages and system-V IPC I think.
> > And a NSStream is a tiny layer over that. Under unix, GNUstep use
> > 'select' on some file descriptors. So why not using NSStream ?
> >
> > But really, it's not that important.
> > I dont want to hide the windows stuff. I only suggest to _reduce_ the
> > windows stuff. Then you'd not need many windows programmers : GNUstep
> > programmers would do the job. 
> Sounds reasonable.
> > Furthermore it would be easier to create a new backend if it hasn't
> > to do so much : DirectFB, Opie/Qtopia, SDL, ...
> >
> >> (...)
> >> The runloop can't manage X event messages (because it knows nothing
> >> about X), so I guess you mean that the NSStream subclass would manage
> >> everything.
> >
> > That what i have in mind at first. But in the diagram i posted all
> > the system stuff is in the server.
> >
> >> That really just means that you are taking all the code for handling
> >> incoming events from the GSDisplayServer subclass and putting it in a
> >> different class (a subclass of NSStream).  Of course, in order to
> >> convert from X events to NSEvents that stream subclass will also need
> >> to know something about the state of requested made by the GUI to the
> >> backend,  and will need other internals of GSDisplayServer (eg to
> >> convert from X window coordinates to NSWindow coordinates), so the
> >> code still in the GSDisplayServer subclass will have to be tightly
> >> coupled with the code in the NSStream subclass.  And the  NSStream
> >> subclass will not be usable except in conjunction with the GSDisplay
> >> server subclass ... so all that has been achieved is to split the
> >> GSDisplayServer into two slightly more complex parts.
> >
> > You're right, that was stupid. So i change my mind... 
> > In the diagram i posted this morning the GSEventStream is not system
> > dependent.
> >> IMO it is legitmate for the backend code to make use of the public
> >> APIs of the frontend.
> >
> > I doesn't agree. Having two libraries referencing each other is  
> > bad 
> If we were talking about two normal libraries, I'd agree, but we are  
> really talking about one library (the AppKit in Cocoa) which happens  
> to be built as a main part (gnustep-gui) with alternative modules  
> (gnustep-back).

Thinking of AppKit and backend as two part of the same library is
of no use. Furthermore two different modules with well defined 
interfaces are easier to maintain.

> > In a perfect world, the backend could be use without Appkit. It should
> > be a black box with a given interface and any program that knows this
> > interface should be able to use it. The backend should even never
> > include any AppKit header... For instance NSEvent should be based on
> > (or should use) a GSEvent class (i'm a fundamentalist 
> That's OK ... but there is no practical pressure to be able to use  
> the backend indepedently of the gui, so I don't think you *have* to  
> take that view.
> I'm perfectly happy with avoiding calls from back to gui methods ...  
> but that does involve changing the interface to pass more information  
> in both directions, 

Which one ?
I think that would not involve so much changes. Calls from back to gui 
are not so numerous, some are simply bad (most in the win32 backend, like the
use of Notification from the AppKit; i saw a [window sendEvent: ev] ; some
AppKit classes are 'categorized' to change methods!!), many others can be easily
change to an other form (the use of an alert panel), and some other should be in
the AppKit (window level management in the x11 backend (ignore under win32),
getNextEventMatching because AppKit and user events should not be handle by the

The more i see the win32 backend, the more i think it needs a deep cleaning!

> and since nobody (afaik) wants to use back standalone,

I do :-)
Well.. i would like.

> there seems little to be gained by adding to the  
> interface rather than using existing gui api.

Some month ago I thought of a SDL backend. But such a backend would be 
a subset of the official backend (only ONE window) : the full AppKit 
would not run with a SDL backend. For instance i would have to write 
my own SDLApplication class. But the official backend does need 
NSApplication, and Panel, and Menu... So my SDLApplication would 
not run with an offical backend!
At end, the work would never be compatible with GNUstep in any way.
> >> identifying places where the behaviors of the backends differ, and
> >> trying to make them consistet would be really good.
> >
> > At first : determining what _is_ a good behavior : what a
> > displayServer should do, what it should not. It would be easy to
> > take the common part, then exclude what can be done elsewhere
> > (if any). Then clean up the code.
> Looking at the Quartz API  that Apple did may be a good guide ... I  
> don't really know though.

I cant find any window or event issue in Quartz...
Core Foundation may be a better source of information.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]