Behave/behave.lua

175 lines
3.3 KiB
Lua
Raw Normal View History

local Node, Decorate, Repeat
2017-12-09 16:53:37 +00:00
local running = setmetatable({ }, {
__tostring = function()
return "running"
end
})
local make
2018-03-16 07:07:40 +00:00
make = function(tab)
if "function" == type(tab) then
return tab
elseif tab.decorate then
return Decorate(tab)
elseif tab["repeat"] then
return Repeat(tab)
elseif "function" == type(tab.type) then
return tab.type(tab)
2018-03-16 07:07:40 +00:00
else
return Node(tab)
end
end
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
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(...)
2018-03-16 07:07:40 +00:00
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
local Inverted
Inverted = function(tab)
local node = make(tab[1])
return function(...)
local result = node(...)
if not (result == running) then
return not result
end
end
end
Repeat = function(tab)
local node = make(tab[1])
local i, r = 1, tab["repeat"]
return function(...)
while i <= r do
if running == node(...) then
return running
end
i = i + 1
end
i = 1
return true
end
end
local Once
Once = function(tab)
local node = make(tab[1])
local ran = false
return function(...)
if ran then
return false
end
local result = node(...)
if not (result == running) then
ran = true
end
return result
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,
Decorator = Decorator,
Inverter = Inverter,
Repeat = Repeat,
Once = Once,
2018-03-16 07:07:40 +00:00
Selector = Selector,
Sequence = Sequence,
Random = Random
}