(My game engine, which I’m trying to port to SDL does this in fact.
There are a handful of keyboard
commands that call Sleep() as part of their handler.) Doing this on the
rendering thread is a bad idea
for obvious reasons.
So don’t do it on the rendering thread. Do it in a separate thread. BTW,
why do they call Sleep()? Using
any kind of delay call in a threaded program is usually (not always) a
sign of a poor design. Generally
the result of not understanding how threads really work.
I’m aware of the pitfalls. But it’s the simplest way to do things if you’ve
got good timing routines to make sure thread-switching delays don’t throw
your timing off, or if you need to delay for a period that can be measured
in seconds, not fractions-of-seconds.
For example, when the user hits the “menu” key, the screen fades out, then
a menu fades in. This is implemented on the event handling thread like
this:
Change game engine state to “fading”.
Assign game engine’s fade time to 1200 ms and begin fadeout. (Handled by
rendering thread.)
Sleep(1500).
Set menu engine’s state to active and draw menu to render target.
Assign game engine’s fade time to 1200 ms and begin fadein.
Sleep(1500)
Change game engine state to “in_menu” and resume normal operation.
Well, if you really want to do it that way then the pseudo code above should
be run in a separate thread. You have the event handler start it and let it
handle things for you. My experience is that that won’t actually work
because there is no way to force the thread to execute, but this is a valid
use of sleep() in a thread.
Another problem with your approach to the problem is that the process takes
2.7 seconds to bring the menu up. During that time the customer may have
asked for a different menu so you need to be able to abort the whole thing.
I would do it a very different way. I would have an ordered queue (heap) of
future actions events that the rendering engine looks at to decide what to
do next. For complex interactions I would have a set of state machines that
are used to move the interactions along.
So my event handler would be rather different. In the following pseudo code
t is the current time. When the customer asks for a menu to pop up my
handler would push the following action events on the heap.
@ t+0 send “set fade out time” 1200 to rendering engine
@ t+0 send “begin fade out” to rendering engine
@ t+1200 send “Finish fade out” to rendering engine
@ t+1200 send “pop up menu” to menu engine
Now, I am assuming that the rendering engine is trying to keep a nice
animation going on the screen even while it is fading out. The “t+x” above
is the time the event should be delivered to the rendering engine. The
variable “t” is the current time. At the beginning of each frame the
rendering engine looks to see if there are any pending actions events whose
times are in the past or are to happen right now. So, the first two events
will be processed at the beginning of the next frame. The second two events
will be processed 1200 ms in the future. The rest of the interaction will be
initiated by the menu engine at some time in the future. No further
interaction with the input event handler is needed. Other interactions can
over lap with the ones already in the action queue.
Since the action queue is implemented as a heap inserting items is O(log n)
and removing items is O(n) so it is very efficient.
The result is a system that is very simple and very efficient and does not
require threads for very light weight interactions. You can save threads for
places where you can really make effective use of them.
The easy way to implement this is to have the action queue sorted by time
and have only pointers (or references depending on your choice of language)
to a closure that invokes a method of a class that implements a state
machine. That way the code that processes actions just invokes the closure
method for all pending actions whose action time is <= now.
The really nice thing about this approach is that you can (usually) run all
the pending actions in parallel and make nice use of a bunch of processors.
You can find lots off information on this approach in any book on discrete
event simulation.
Bob PendletonOn Tue, May 6, 2008 at 9:04 AM, Mason Wheeler wrote:
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
–
±-------------------------------------+