2018-03-16 07:07:40 +00:00
|
|
|
local make, Node, Decorate
|
2017-12-09 16:53:37 +00:00
|
|
|
local running = setmetatable({ }, {
|
|
|
|
__tostring = function()
|
|
|
|
return "running"
|
|
|
|
end
|
|
|
|
})
|
2018-03-16 07:07:40 +00:00
|
|
|
local get_nodes
|
|
|
|
get_nodes = function(tab)
|
|
|
|
local nodes = { }
|
|
|
|
for _index_0 = 1, #tab do
|
|
|
|
local node = tab[_index_0]
|
|
|
|
table.insert(nodes, make(node))
|
|
|
|
end
|
|
|
|
return nodes
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
make = function(tab)
|
|
|
|
if "function" == type(tab) then
|
|
|
|
return tab
|
|
|
|
elseif "function" == type(tab.type) then
|
|
|
|
return tab.type(tab)
|
|
|
|
elseif tab.decorate then
|
|
|
|
return Decorate(tab)
|
|
|
|
else
|
|
|
|
return Node(tab)
|
2017-12-09 17:31:35 +00:00
|
|
|
end
|
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
Node = function(tab)
|
|
|
|
local state, started = { }, false
|
|
|
|
return function(...)
|
|
|
|
local result
|
|
|
|
if not (started) then
|
|
|
|
if tab.start then
|
|
|
|
result = tab.start(state, ...)
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
if not (result == false) then
|
|
|
|
started = true
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
if not (result == false) then
|
|
|
|
result = tab.run(state, ...)
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
if result ~= running then
|
|
|
|
started = false
|
|
|
|
if result and tab.finish then
|
|
|
|
result = tab.finish(state, ...)
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
return result
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
|
|
|
end
|
2017-12-09 20:53:49 +00:00
|
|
|
local Decorator
|
2018-03-16 07:07:40 +00:00
|
|
|
Decorator = function(tab)
|
|
|
|
local node = make(tab[1])
|
|
|
|
return function(...)
|
|
|
|
local result = node(object, ...)
|
|
|
|
if not (result == running) then
|
|
|
|
result = tab.decorate(result, ...)
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
return result
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
local Selector
|
|
|
|
Selector = function(tab)
|
|
|
|
local nodes = get_nodes(tab)
|
|
|
|
local length = #nodes
|
|
|
|
local i = 1
|
|
|
|
return function(...)
|
|
|
|
local result = nodes[i](...)
|
|
|
|
while not result do
|
|
|
|
i = i + 1
|
|
|
|
if i > length then
|
|
|
|
i = 1
|
|
|
|
return false
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
result = nodes[i](...)
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
if result ~= running then
|
|
|
|
i = 1
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
return result
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
local Sequence
|
|
|
|
Sequence = function(tab)
|
|
|
|
local nodes = get_nodes(tab)
|
|
|
|
local length = #nodes
|
|
|
|
local i = 1
|
|
|
|
return function(...)
|
|
|
|
local result = nodes[i](...)
|
|
|
|
while result and result ~= running do
|
|
|
|
i = i + 1
|
|
|
|
if i > length then
|
|
|
|
i = 1
|
2017-12-09 16:53:37 +00:00
|
|
|
return result
|
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
result = nodes[i](...)
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
if not (result) then
|
|
|
|
i = 1
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
return result
|
2017-12-09 16:53:37 +00:00
|
|
|
end
|
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
local Random
|
|
|
|
Random = function(tab)
|
|
|
|
local nodes = get_nodes(tab)
|
|
|
|
local length = #nodes
|
|
|
|
local r
|
|
|
|
return function(...)
|
|
|
|
if not (r) then
|
|
|
|
r = 1 + math.random(length)
|
2017-12-09 16:54:54 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
local result = nodes[r](...)
|
|
|
|
if not (result == running) then
|
|
|
|
r = nil
|
2017-12-09 16:54:54 +00:00
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
return result
|
2017-12-09 16:54:54 +00:00
|
|
|
end
|
|
|
|
end
|
2018-03-16 07:07:40 +00:00
|
|
|
return {
|
|
|
|
success = true,
|
|
|
|
running = running,
|
|
|
|
failure = false,
|
2017-12-09 16:53:37 +00:00
|
|
|
Node = Node,
|
2017-12-09 17:31:35 +00:00
|
|
|
Decorator = Decorator,
|
2018-03-16 07:07:40 +00:00
|
|
|
Selector = Selector,
|
|
|
|
Sequence = Sequence,
|
|
|
|
Random = Random
|
|
|
|
}
|