lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> I don't think this functionality is readily available in Lua 
> out of the box. 

I fear that also.

> Neither am I missing it and it doesn't strike 
> me like a very common case either.

I am biased here, but games might need it. And games seem to take more and
more importance in the LUA user community.

> You could probably 
> implement your "reset" using C. Or you could accommodate for 
> the lack of this functionality in your engine design and find 
> another solution that, I suspect, is out there.  

Coroutines are the perfect tool to define a sequence and have it performed
over several cycles. Achieving this without coroutines would mean for me to
implement a system of context backup, which is what coroutines are about, in
a way. The only missing feature in coroutines is the possibility to reset
that context.


Anyway, here is what I need in more details, if that can help anyone have a
more complete thought about it :-)

What I have is a set of tasks. At each cycle, one task is selected, and is
invoked. I also need each task to be interruptible and to resume where it
was suspended, therefore they must be embedded in coroutines. Since I don't
want the coroutine to die if the task completes, but rather restart the task
from the beginning at the next cycle, a task is actually a job function
called within an infinite loop that yields just after the call, this being
the actual body of the coroutine wrapper.
If each task is always suspended at the infinite loop's yield point, there
is no problem. But there is no point in having this coroutine stuff: just
call the proper job function and have done with it: even if I swap from one
task to another, when a task is called, the actual job function will be
called from its beginning.
My concern regards tasks that are suspended in the middle of their job. If
in the middle of such a task, I swap to another task, then come back to the
first one, I want to restart its execution from the entry point of the job
function, and not from where it was suspended.

REAL LIFE EXAMPLE:

A task is the idle mode of the main character of the game, another one is
its walk mode. Most of the time, the idle mode does nothing, therefore
completes fully at each cycle. However, if idle for long, the character
might want to launch a sequence of the kind:
"play this animation"
"if weapon not fully loaded then reload it"
"play that animation"
Of course, if at any point during the sequence the player wants to walk, I
don't want to wait until the cycle is completed to start the movement.
Conversely, when the character stops walking, I don't want him to instantly
resume his sequence where it was interrupted, because obviously it is not in
a status where it is possible.

And I fear that
1) I need coroutines to achieve this in a simple way
2) the current implementation of coroutines does not enable this kind of
mechanism
3) my knowledge of the core is insufficient to add the necessary C code to
reset the coroutine

So, if anyone can prove me that #1 or #2 is wrong, or give me pointers
regarding the way to implement #3, I'd be most interested :-)

here is a little script that protoypes what I have done so far:

-- START
modeA =
{
	execute = function ( )
		print "modeA"
		doSequence ( )
	end
}

modeB =
{
	execute = function ( )
		print "modeB"
	end
}

function doSequence ( )
	coroutine . yield ( )
	print "sequence 1"
	coroutine . yield ( )
	print "sequence 2"
	coroutine . yield ( )
	print "sequence 3"
	coroutine . yield ( )
	print "sequence 4"
end

doModeA = coroutine . wrap (
	function ( )
		while true
		do
			modeA . execute ( )
			coroutine . yield ( )
		end
	end
)

doModeB = coroutine . wrap (
	function ( )
		while true
		do
			modeB . execute ( )
			coroutine . yield ( )
		end
	end
)

prevDoMode = doModeA
main=function(_doMode)
	if _doMode ~= prevDoMode
	then
		prevDoMode = _doMode
		-- TODO: reset _doMode so that it starts from the beginning
	end
	_doMode()
end
-- END

now, in the lua console, do:

> dofile "thisscript.lua"
> main(doModeA)
modeA
> main(doModeA)
sequence 1
> main(doModeA)
sequence 2
> main(doModeA)
sequence 3
> main(doModeB)
modeB
> main(doModeB)
modeB
> main(doModeB)
modeB
> main(doModeB)
modeB
> main(doModeA)
sequence 4

The thing is, when reverting to doModeA after calling doModeB, I want
modeA.execute() to restart from the beginning, and output "modeA" instead of
"sequence 4"


Regards,


Benoit.