- Joined
- Nov 7, 2014
- Messages
- 571
Unfortunately no one can be told what coroutines are, they have to see them for themselves.
Coroutine references 1, 2, 3.
1. Sequence of actions interleaved with waits (more accurate TriggerSleepAction)
Lua:
local tmr = CreateTimer()
local sequenceOfActionsInterleavedWithWaitsCo -- coroutine
local function resumeWait()
coroutine.resume(sequenceOfActionsInterleavedWithWaitsCo)
end
local function wait(seconds)
TimerStart(tmr, seconds, false, resumeWait)
coroutine.yield()
end
local function sequenceOfActionsInterleavedWithWaits()
print('A')
wait(1.0)
print('B')
wait(1.0)
for a = 1, 50 do
print(a)
wait(1.0/50.0)
end
end
...
-- the initial invocation of a coroutine is a bit different from that of regular functions
--
sequenceOfActionsInterleavedWithWaitsCo = coroutine.create(sequenceOfActionsInterleavedWithWaits)
coroutine.resume(sequenceOfActionsInterleavedWithWaitsCo) -- == resumeWait()
...
This is a very common thing to do (think cinematic triggers full of
TriggerSleepAction
s), a lot of the uses of timer
s. (1, 2, 3).2. State machines (Spells)
Lua:
local MySpell = {}
MySpell.__index =MySpell
local function wait()
coroutine.yield(true)
end
function MySpell:think()
return coroutine.resume(self.thinkCo)
end
function MySpell:stateSpawn()
self.fx = AddSpecialEffect("...", self.x, self.y)
...
a:stateMove()
end
function MySpell:stateMove()
while true do
if <condition> then
break
end
-- move code
wait() -- note the call to wait
end
self:stateDestroy()
end
function MySpell:stateDestroy()
DestroyEffect(self.fx)
end
function MySpell.new(a, b, c)
local s = setmetatable({}, MySpell)
s.thinkCo = coroutine.create(function()
s:stateSpawn() -- initial state
end)
s:think()
return s
end
local tmr: timer = CreateTimer()
local xs = {}
local function tmrLoop()
local a = 1
while a <= #xs do
local running = xs[a]:think()
if not running then
table.remove(xs, a)
else
a = a + 1
end
end
if 0 == #xs then
PauseTimer(tmr)
end
end
local function mySpellCasted()
local s = MySpell.new(...)
xs[#xs+1] = s
if 1 == #xs then
TimerStart(tmr, 1.0/32.0, true, tmrLoop)
end
end
This example has 3 states (stateSpawn, stateMove, stateDestroy), but its easy to add more states that do something interesting (animations, colors/fading etc.). If you have a spell and there's a field somewhere called 'state', you could probably use coroutines there.
If you know more uses of coroutines, please, do tell.