heroes-of-nerevelon/lib/animation_node.lua

74 lines
2.5 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--- @alias voidCallback fun(): nil
--- @alias animationRunner fun(node: AnimationNode)
--- Узел дерева анимаций.
---
--- Отслеживает завершение всех анимаций всех дочерних узлов и оповещает вышестоящий узел.
---
--- Дочерние узлы одного уровня запускают свою анимацию одновременно после завершения анимации родителя.
--- Example:
--- ```lua
--- AnimationNode {
--- function (node) residentsleeper:sleep(1000, node) end, -- must pass itself down as the parameter
--- onEnd = function() print("completed") end,
--- children = { -- children run in parallel after the parent animation is completed
--- AnimationNode {
--- function (node) sprite:animate("attack", node) end
--- },
--- AnimationNode {
--- function (node) other_sprite:animate("hurt", node) end
--- },
--- }
--- }:run()
--- ```
--- @class AnimationNode
--- @field count integer
--- @field run animationRunner
--- @field parent AnimationNode?
--- @field children AnimationNode[]
--- @field finish voidCallback
--- @field onEnd voidCallback?
local animation = {}
animation.__index = animation
--- Регистрация завершения дочерней анимации
function animation:bubbleUp()
self.count = self.count - 1
if self.count > 0 then return end
if self.onEnd then self.onEnd() end
if self.parent then self.parent:bubbleUp() end
end
--- @param children AnimationNode[]
--- Запланировать анимации после текущей, которые запустятся одновременно друг с другом
function animation:chain(children)
for _, child in ipairs(children) do
child.parent = self
table.insert(self.children, child)
self.count = self.count + 1
end
return self
end
--- @param data {[1]: animationRunner?, onEnd?: voidCallback, children?: AnimationNode[]}
--- @return AnimationNode
local function new(data)
local t = setmetatable({}, animation)
t.run = data[1] or function(self)
self:finish()
end
t.onEnd = data.onEnd
t.count = 1 -- своя анимация
t.children = {}
t:chain(data.children or {})
t.finish = function()
t:bubbleUp()
for _, anim in ipairs(t.children) do
anim:run()
end
end
return t
end
return new