[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Multiple Scripts, Pausing, Threads, and Persistant Variables
- From: Dave Bollinger <DBollinger@...>
- Date: Mon, 20 Mar 2000 20:39:36 -0500
Sean Middleditch wrote:
>> run a PORTION of that script, halt, run some other code, then return
First, search the message archive or e-group list for previous posts by
Bret Mogilefsky - he posted some interesting ideas on modifying the Lua
internals to do this. Otherwise, I think the answer is "no", not without
modifying the Lua source.
Second, you CAN do this with "plain" Lua if you're willing to suffer
some performance penalty. The setup is to store those scripts as text and
then do the line-by-line code stepping yourself. So you execute a script
that executes scripts - the performance penalty being the extra parsing of
the manual dostring() calls. Following is some old code that I was playing
with after reading Bret's posts. The "driver" script is runbob.lua and the
"actor" script is bob.lua, you'll need to manually snip them apart from
this message to try it. It isn't elegant as is but may give you some
ideas, the guts are in _ACTOR:runScript(). You can extrapolate to figure
out how you'd set up multiple actors running asynchronously.
Cheers,
Dave
<--cut here-->
-- runbob.lua
$debug
--
-- global pointer to current actor, used in "actor" scripts
--
currentActor = {}
--
-- base class for actor
--
_ACTOR = {}
function _ACTOR:loadScript(filename)
self.script = { n=0 }
readfrom(filename)
local s = read()
while (s) do
tinsert(self.script, s)
s = read()
end
readfrom()
end
-- runs until break or actor not alive or out of code
function _ACTOR:runScript()
breakFlag = nil
while (self.alive) and (not breakFlag) do
local s = self.script[self.codeptr]
if (s) then
-- increment code pointer
self.codeptr = self.codeptr + 1
-- set global actor pointer
currentActor = self
-- execute script snippet
dostring(s)
-- check if end of script
if (self.codeptr > self.script.n) then
self.alive = nil
end
end
end
end
function _ACTOR:move()
self.x = self.x + self.dx
self.y = self.y + self.dy
end
--
-- constructor for actor
--
function ACTOR(filename)
local t = {}
t.script = { n=0 }
t.alive = 1
t.codeptr = 1
t.x = 0
t.y = 0
t.dx = 0
t.dy = 0
t.loadScript = _ACTOR.loadScript
t.runScript = _ACTOR.runScript
t.move = _ACTOR.move
if (filename) then
t:loadScript(filename)
end
return t
end
--
-- utility functions
--
function isMoving()
if (currentActor.dx ~= 0) or (currentActor.dy ~= 0) then
print(" ..moving..")
currentActor:move()
return (currentActor.x ~= currentActor.targetx) -- and y's
else
return nil
end
end
function break()
breakFlag = 1
end
function waitTill(func)
if (not func()) then
-- decrement code pointer
currentActor.codeptr = currentActor.codeptr - 1
break()
end
end
function waitWhile(func)
if (func()) then
-- decrement code pointer
currentActor.codeptr = currentActor.codeptr - 1
break()
end
end
--
-- testing
--
bob = ACTOR("bob.lua")
-- this loop would be in host program
frame=1
while (bob.alive) do
print("FRAME =",frame) frame=frame+1
bob:runScript()
end
<--cut here-->
-- bob.lua
--
-- will execute on frame 1...
--
print(" Start..")
currentActor.x = 0
currentActor.dx = 1
break() -- prove break() works
--
-- will execute on frame 2
--
print(" frame = 2?")
currentActor.targetx = 10
--
-- will execute at end of frame 2, then 3-11...
--
waitWhile( isMoving )
--
-- will execute at end of frame 11...
--
print(" Done.")
print(" x =", currentActor.x)
currentActor.alive = nil
<--cut here-->