gnustep-dev
[Top][All Lists]
Advanced

[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: Tue, 13 Feb 2007 19:53:54 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Richard Frith-Macdonald <richard <at> tiptree.demon.co.uk> writes:

> On 13 Feb 2007, at 11:03, Xavier Glattard wrote:
> 
> > Richard Frith-Macdonald <richard <at> tiptree.demon.co.uk> writes:
> >
> >> On 11 Feb 2007, at 19:18, Xavier Glattard wrote:
> >> (...)
> >> No, in fact both backends use the runloop and both use
> >> GSRunLoopWatcher which works perfectly.  The fact that both backends
> >> at certain points chose to poll their respective message queues
> >> without asking the runloop to tell them whether there is anything
> >> available does not imply anything about
> >
> > You're right : it works !
> > Well... most of the time.
> > GNUstep is not perfect. For instance it can't manage properly a  
> > intensive use of
> > performers or events, neither w32 nor x11 (see my openGL test tool).
> 
> I would need more details to know what you mean here.  it may be that  
> what you are seeing as a problem is actually a misunderstanding about  
> what the code is supposed to do.

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. Under w32 i just remember than the program 
doesnt work properly in many more cases. You can select the backing store 
in the menu.

> >> Actually I'm *hoping* that Apple will release something to specify
> >> clearly how an NSStream subclass (other than those subclasses Apple
> >> provide of course) can be tied in to an NSRunLoop.  Such an API would
> >> be able to take the place of GSRunLoopWatcher.  Without that API you
> >> can't write new subclasses of NSStream and get their event handing
> >> code called when an event becomes available, you can only base code
> >> on existing NSStream implementations.
> >
> > All you have to do to subclass NSStream is at Apple: look at NSStream,
> > NSOutputStream ans NSInputStream reference pages.
> 
> I was talking about how to get it to interact with an NSRunLoop  
> effectively ... ie how to get a runloop to trigger an event on the  
> stream when the low level operating system event occurs.  eg.  how do  
> you set things up to trigger a stream event when a semaphore flips or  
> a shared memory segment is updated.

Ok. I understand : something like a 'select' that works on NSStream.
That would be handy :-)

> (...)
> > What does a GSRLWatcher that a NSStream doesnt ?
> 
> On windows ... windows messages.

Yeah ! And on X11... X11 messages :-)

> > The  only difference I see is that GWRLWatcher handles _blocks_ of  
> > bytes while
> > NSStream handles _streams_ of bytes.
> 
> No, a watcher does not handle bytes at all.  It detects whether an  
> event has occurred (eg a file descriptor becoming readable) and  
> informs its delegate so that the delegate can handle any data transfer.

But it does handle data under w32 since it returns the message as 
the 'extra' argument of receivedEvent. Another weird behavior of the w32
backend...

> (...) 
> What you seem to be describing here is either a blocking or an  
> actively polling model ...
> the app asks the server for an event,
> the server checks the windows or X queue and if there is an event,  
> parses and returns it.
> If there is NOT an event, then either
> 1. (polling) a nil event is returned and the app asks again or
> 2. (blocking) the server waits until an event arrives, then returns that

Is there an other way ?
That what the runLoop does : polls/selects for a limited period of time,
until a timer has to be fired.

> (...)
> If you look at the API and documentation you will find that it *has*  
> an event queue.  Sure, the whole system could be designed and  
> implemented differently, but that's what the design of the OpenStep/ 
> MacOS-X/GNUstep AppKit/GUI library happens to be.

I can't see any event _in_ the NSApplication. NSApp gets events from a 
queue, post event to a queue, but we dont know where is this queue. I 
think it should be in the server. And it is!

> >> If different sources of NSEvents were going to be used by lots of
> >> different pieces of code, the encapsulation of all the work inside a
> >> stream interface would be really useful/clean/simple.  However, in
> >> practice we have a single source of events for a display server, and
> >> all those events go into the application's event queue and are pulled
> >> out of that queue by the code which needs the events,
> >
> > But the application has to handle many other events than those get  
> > from the GUI
> > : timers and performers. And socket/network messages, and so on.
> 
> I thought we were taking about gui events (NSEvent objects).
> Certainly we handle other events via callbacks from the runloop  
> too ... but they are not connected to the issue of handling the  
> NSEvens in a stream subclass.

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. 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.

>(...)
> > NSStream is only a better GSWatcher. That's not the main problem.
> 
> No, NSStream  deals with bytestream oriented I/O, and as part of that  
> can be scheduled in a runloop to be told when I/O is possible.
> GSRunLoopWatcher provides a mechanism to let objects be notified when  
> I/O is possible.
> Because the mechanism by which the runloop knows what events should  
> trigger the stream event handler is undefined in the MacOS-x NSStream  
> and NSRunLoop documentation, we use the GSRunLoopWatcher to provide  
> that linkage.

MacOS is unix based. So everything come from file descriptors. 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.

> (...)
> > At least i think the DispathMessage/windowProcedure should be  
> > hidden in a more
> > abstract mechanism. Without the window procedure the win32 backend  
> > would be more
> > like the x11 one, and with enough abstraction (that NSStream might  
> > gives) some
> > more code could be shared.
> 
> Maybe ... but if we want windows programmers to work on the windows  
> backend then it might be better to keep things as 'normal' for them  
> as possible rather than trying to hide the windows stuff.

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. :-)
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.

> (...diagram...)
> >
> > (*) Only two methods are specific to the underlying system. - 
> > getAndDecode is the
> >  main part.
> >
> > The runLoop wouldn't know anything of the backend : it'd only have  
> > to manage
> > streams.
> > The server wouldn't know anything of the runLoop nor the NSApp :  
> > it'd only have
> > to manage the events from the system.
> >
> > Ideally the real server shouldn't know anything of the AppKit but  
> > what is
> > included in GSDisplayServer.h. But that would only be true in a  
> > Perfect World(tm)
> > Some bad examples in X11 backend :
> >   [NSApp deactivate]
> >   [NSApp mainMenu]
> > In the w32 backend :
> >   [NSApp terminate: nil]
> >   use some Panels, includes NSText, NSMenu, NSTextField, ...
> >   get many notifications from NSApp
> 
> 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 ;-)

The backend is intented to be an abstract layer over the system, and 
the AppKit uses the backend for low level stuff. If the backend use 
some objects in the AppKit then either 1. that's system independent 
and then it could be done outside the backend, either 2. it's system 
dependent and then GNUstep behavior depends on the sytem : BAD !

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 ;-)

Well... That's the way i see it.
I know : the world is not so perfect. But it's up to us to make it 
better ;-)

> > I know : the backend does this because it needs to do this. But It  
> > should not
> > need to do this. The 2 backends are so different that their  
> > behaviors are realy
> > different sometimes. Most of this should be done by NSApp.
> 
> Certainly we should try to get behaviors to be as similar as is  
> practically possible.
> 
> > ....
> >
> > I know... I just come here and start to criticize :-p
> > But i only want to help because I like GNUstep 
> > My ideas are probably not perfect, but i'd be happy to talk about  
> > all that again
> > and again. And help to do job.
> 
> I'm not convinced that wrapping backend specific event handling  
> inside an NSStream would be an improvement. After all, the NSStream  
> API is intended for fairly low-level byte-stream oriented I/O rather  
> than to implement an event queue.   Surely it would be better to  
> clean up the existing code in the two backends, and continue to use  
> the existing event queue.  Even if we did want to go to a stream  
> based queue I expect it would be better to clean up existing code  
> first, and use  the cleaned up code as the basis for any change.

Yes. The NSStream/GSRLWatcher case and the window procedure stuff 
are not important.

> 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.

Xavier









reply via email to

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