[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: Re[2]: why no "continue" statement for loops?
- From: "Nick Trout" <nick@...>
- Date: Mon, 23 Jun 2003 20:15:35 -0700
>
> Also, on a completely different note; whilst I would *never ever* use
> gotos
> in C++ or even C for that matter, there is an argument for having them
in
> a
> *multi-threaded* scripting language. (note the emphasis on
multi-threaded)
Shouldn't the emphasis be on "pre-emptive multi-threaded" scripting
language? Lua is cooperative hence you have to think about control flow
and suspend/yield points. You don't have to think about this in
pre-emptive environments. Gotos are nice where you are constantly
changing state and would otherwise meet a stack overflow by calling
functions - the lazy mans function call ;-)
> With multi-threaded scripting languages, especially those for games,
it is
> necessary to implement state machines, or more simply put, areas of
code
> you
> can *jump* to, to get a character to go into a particular state.
>
> I understand why lua doesn't have this right now, the "co-routines"
are a
> far call from multi-threading and require the user to write a whole
> multi-threading kernel in order to use them. However, once this is
> written
> you begin wanting to write code like this: (believe me, you really
*do*)
> (pseudo code)
>
> Thread AlienMonster
> init:
> initialise_state() // initialise function for this monster
>
> check:
> nearest_player = check_for_nearest_player();
> if ( nearest_player )
> {
> jump_to_state( attack );
> }
>
> idle:
> play( "scratch_arse" ); // animation (takes time to
complete)
> wait( 5 )
> play( "look_around_aimlessly" );
> jump_to_state( check );
>
> attack:
> play( "monster_roar" );
> while ( nearest_player == check_for_nearest_player() )
> {
> if ( turn_to_player() ) // facing player?
> {
> play( "chase_1_step" ); // step towards the player
> (takes
> time for animation to complete)
> }
> wait( 1 ) // wait 1 frame (or nth of a second)
> }
> jump_to_state( check );
> EndThread
You could possibly do this in Lua with the following completely seat of
the pants untested code:
-- Thread AlienMonster
function init()
initialise_state() // initialise function for this monster
jump_to_state(check)
end
function check()
nearest_player = check_for_nearest_player()
if nearest_player then
jump_to_state( attack )
else
jump_to_state(idle)
end
end
function idle()
play( "scratch_arse" ); // animation (takes time to
complete)
wait( 5 )
play( "look_around_aimlessly" );
jump_to_state( check );
end
function attack()
play( "monster_roar" );
while ( nearest_player == check_for_nearest_player() )
{
if ( turn_to_player() ) // facing player?
{
play( "chase_1_step" ); // step towards the player
(takes
time for animation to complete)
}
wait( 1 ) // wait 1 frame (or nth of a second)
}
jump_to_state( check );
end
-- EndThread
state = init
function wait(t)
while timer < t do
coroutine.yield()
end
end
function jump_to_state(newtstate)
state = newstate
coroutine.yield()
end
co = coroutine.create(function() state() end)
while couroutine.resume(co) do
end
> Of course I can make "attack", "idle" and "check" functions and then
have
> some kind of table which is run through in order, but then there are
no
> *conditions*, and quite frankly, setting up the table is just as much
a
> pain
> in the arse as writing the above using while/dos and lots of local
"state"
> variables, which is definitely *not* the way to write that kind of
code.
> Importantly, the above is *simple to understand*.
You can do some nice things with first class objects in Lua.
Nick