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.
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.
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...
Yeah ... the windows operating system APIs do not fit easily with the
OpenStep system ... but in a way the watcher isn't handling data (it
doesn't read or write any bytes), it's just passing on a pointer to
the message in the windows message queue (analagous to passing the
file descriptor for a unix file event) and leaving its delegate to
actually process the message and retrieve information from it.
(...)
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.
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.
(...)
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!
The point was, that we have to have an event queue, and it has to
have certain characteristics. I wasn't saying *where* the queue is
implemented (for instance you could argue that it's implemented in
the base library since it's an instance of the NSMutableArray class,
but that would be irrelevant).
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.
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.
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.
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?
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).
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, and since nobody (afaik) wants to use back
standalone, there seems little to be gained by adding to the
interface rather than using existing gui api.
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.
_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev