Refactor spell casts to use task utilities and simplify callbacks
Add task.chain utility for chaining asynchronous tasks
This commit is contained in:
parent
403ba5a03f
commit
1986228670
@ -70,7 +70,7 @@ function sprite:draw()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @return Task<nil>
|
--- @return Task<nil>
|
||||||
function sprite:animate(state, node)
|
function sprite:animate(state)
|
||||||
return function(callback)
|
return function(callback)
|
||||||
if not self.animationGrid[state] then
|
if not self.animationGrid[state] then
|
||||||
print("[SpriteBehavior]: no animation for '" .. state .. "'")
|
print("[SpriteBehavior]: no animation for '" .. state .. "'")
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
--- --TODO: каждый каст должен возвращать объект, который позволит отследить момент завершения анимации спелла
|
--- --TODO: каждый каст должен возвращать объект, который позволит отследить момент завершения анимации спелла
|
||||||
--- Да, это Future/Promise/await/async
|
--- Да, это Future/Promise/await/async
|
||||||
|
|
||||||
local Counter = require 'lib.utils.counter'
|
local task = require 'lib.utils.task'
|
||||||
|
|
||||||
--- @class Spell Здесь будет много бойлерплейта, поэтому тоже понадобится спеллмейкерский фреймворк, который просто вернет готовый Spell
|
--- @class Spell Здесь будет много бойлерплейта, поэтому тоже понадобится спеллмейкерский фреймворк, который просто вернет готовый Spell
|
||||||
--- @field tag string
|
--- @field tag string
|
||||||
@ -55,11 +55,7 @@ function walk:cast(caster, target)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
return function(callback)
|
return caster:has(Tree.behaviors.tiled):followPath(path)
|
||||||
return caster:has(Tree.behaviors.tiled):followPath(path)(
|
|
||||||
callback
|
|
||||||
) -- <- callback вызовется после followPath
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function walk:update(caster, dt)
|
function walk:update(caster, dt)
|
||||||
@ -103,14 +99,10 @@ function regenerateMana:cast(caster, target)
|
|||||||
Tree.behaviors.positioned.new(caster:has(Tree.behaviors.positioned).position + Vec3 { 0.5, 0.5 }),
|
Tree.behaviors.positioned.new(caster:has(Tree.behaviors.positioned).position + Vec3 { 0.5, 0.5 }),
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(callback)
|
return task.wait {
|
||||||
light:has(Tree.behaviors.light):animateColor(Vec3 {})(
|
light:has(Tree.behaviors.light):animateColor(Vec3 {}),
|
||||||
function()
|
sprite:animate("hurt")
|
||||||
light:die()
|
}
|
||||||
end
|
|
||||||
)
|
|
||||||
sprite:animate("hurt")(callback)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local attack = setmetatable({}, spell)
|
local attack = setmetatable({}, spell)
|
||||||
@ -143,20 +135,16 @@ function attack:cast(caster, target)
|
|||||||
|
|
||||||
caster:try(Tree.behaviors.positioned, function(b) b:lookAt(target) end)
|
caster:try(Tree.behaviors.positioned, function(b) b:lookAt(target) end)
|
||||||
|
|
||||||
return function(callback)
|
return
|
||||||
local c = Counter(callback)
|
task.wait {
|
||||||
|
sprite:animate("attack"),
|
||||||
c.push()
|
task.wait {
|
||||||
sprite:animate("attack")(c.pop)
|
task.chain(targetCharacter:has(Tree.behaviors.residentsleeper):sleep(200),
|
||||||
|
function() return targetSprite:animate("hurt") end
|
||||||
c.push()
|
),
|
||||||
targetCharacter:has(Tree.behaviors.residentsleeper):sleep(200)(
|
|
||||||
function()
|
|
||||||
targetSprite:animate("hurt")(c.pop)
|
|
||||||
Tree.audio:play(Tree.assets.files.audio.sounds.hurt)
|
Tree.audio:play(Tree.assets.files.audio.sounds.hurt)
|
||||||
end
|
}
|
||||||
)
|
}
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|||||||
@ -61,6 +61,23 @@ local function wait(tasks)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Последовательно объединяет два `Task` в один.
|
||||||
|
--- @generic T
|
||||||
|
--- @generic R
|
||||||
|
--- @param task Task<T> `Task`, который выполнится первым
|
||||||
|
--- @param onCompleted fun(value: T): Task<R> Конструктор второго `Task`. Принимает результат выполнения первого `Task`
|
||||||
|
--- @return Task<R>
|
||||||
|
local function chain(task, onCompleted)
|
||||||
|
return function(callback)
|
||||||
|
task(function(value)
|
||||||
|
local task2 = onCompleted(value)
|
||||||
|
task2(callback)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wait = wait,
|
wait = wait,
|
||||||
|
chain = chain
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,21 @@ function test:run(complete)
|
|||||||
|
|
||||||
print("task.wait completed in " .. dt .. " sec", "t1 = " .. t1 - t0, "t2 = " .. t2 - t0)
|
print("task.wait completed in " .. dt .. " sec", "t1 = " .. t1 - t0, "t2 = " .. t2 - t0)
|
||||||
|
|
||||||
complete()
|
|
||||||
|
t0 = love.timer.getTime()
|
||||||
|
task.chain(task1(), function(value)
|
||||||
|
t1 = value
|
||||||
|
assert(t1 - t0 >= 1)
|
||||||
|
return task2()
|
||||||
|
end)(
|
||||||
|
function(value)
|
||||||
|
t2 = value
|
||||||
|
assert(t2 - t0 >= 2)
|
||||||
|
print("task.chain completed in " .. t2 - t0 .. " sec")
|
||||||
|
|
||||||
|
complete()
|
||||||
|
end
|
||||||
|
)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user