Re: Keeping program flow moving nicely
- From: "Timothy M. Shead" <tshead k-3d com>
- To: Dave Neary <dneary eircom net>
- Cc: gtk-list gnome org
- Subject: Re: Keeping program flow moving nicely
- Date: Sat, 10 Feb 2001 12:03:26 -0800
Dave Neary wrote:
Hi all,
I'm involved in writing a gnome/gtk game which has thrown up a
minor problem I hope you guys can help me with.
The game has computer players of varying strengths, and it's
possible for the computer to play itself. That's fine, but the
way we've been handling program flow was by checking, after
processing a move, whether it was the turn of a computer to
move, and based on that call the function to process a move for
the computer, a la
gint process_move(gint move)
{
...
switch_players();
if (is_computer(currentPlayer))
{
process_move(get_computer_move(state));
}
return 0;
}
This has been seizing control of the program and blocking any
events whenever it's a computer move, which is a pain when we
have two computers playing each other, when control never gets
restored to gtk_main() until the end of the game.
We've hacked fixes to this which aren't very pretty, although
they're effective. One is to process all pending gdk events
before the call to process_move() above. The second was to put
the check above in a function which we attached to the idle
loop, so that process_move() terminates normally and without
calling itself. We didn't really think either of these were
ideal. The first is just hackish, and the second means that
every single idle loop we're checking whether it's the
computer's turn, and this makes things much more processor
intensive than they should be.
We wanted a way to allow the process_move() function to
terminate normally , and still get called properly every time it
was the computer's turn. Due to an incomplete understanding of
signal handling, I thought this could be done by writing a
composite widget which added a new signal which we could emit at
the end of process_move, and attaching a callback to it that
would call process_move() with the computer's move. Obviously
this didn't achieve the desired goal, since the signal getting
emitted wa strapped, and we end up in the same cycle as the
original - the callback recursively emits the signal until
either the game is over, or we seg fault :) (thankfully, the
former happens).
What I want to know is how we can emit this signal, and get the
computer's move processed, without interfering with other events
that might happen in the meantime? Sorry if this mail is very
long - I probably went into too much detail about what I'd done,
and how I've arrived at where I'm at. My incorrect assumption
about signals, by the way, way that emitting a signal would just
add that signal to the queue of unprocessed signals/events, and
have it handled in order.
Thanks a lot,
Dave.
Use gtk_timeout_add() to create a 'timeout' signal that gets called,
say, every 100 milliseconds or so. In your handler for the timeout
event you decide whose turn it is and call process_move(). The timeout
event will get called frequently enough that there won't be any
noticeable delay, between moves but you won't be dragging down the CPU
(as you would if you used an idle handler). At the same time, normal
events will continue to be processed without any intervention on your
behalf, so the human user can hit pause, cancel, or whatever.
Regards,
Timothy M. Shead
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]