diff --git a/init.lua b/init.lua index a26d388..3bef31a 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,5 @@ local Tactree = {} -Tactree.Nodes = {} +local Nodes = {} local function NodeStart(node, args) -- abort if started @@ -32,13 +32,13 @@ end local function default_impl(node) end function Tactree.Leaf(name) return function(t) - if Tactree.Nodes[name] then + if Nodes[name] then error('node with name \'' .. name .. '\' already exists.', 2) else - Tactree.Nodes[name] = {} + Nodes[name] = {} end - local node_type = Tactree.Nodes[name] + local node_type = Nodes[name] local tick = t.tick or t[1] if type(tick) ~= 'function' then error('no tick function supplied', 2) end @@ -52,14 +52,14 @@ end function Tactree.Composite(name) return function(parent_type_name) return function(children) - if Tactree.Nodes[name] then + if Nodes[name] then error('node with name \'' .. name .. '\' already exists.', 2) else - if not Tactree.Nodes[parent_type_name] then error('no such node \'' .. name .. '\'', 2) end - Tactree.Nodes[name] = setmetatable({}, Tactree.Nodes[parent_type_name]) + if not Nodes[parent_type_name] then error('no such node \'' .. name .. '\'', 2) end + Nodes[name] = setmetatable({}, { __index = Nodes[parent_type_name] }) end - local node_type = Tactree.Nodes[name] + local node_type = Nodes[name] node_type.children = {} @@ -73,7 +73,7 @@ function Tactree.Composite(name) end function Tactree.Tree(name) - if not Tactree.Nodes[name] then error('no such node \'' .. name .. '\'', 2) end + if not Nodes[name] then error('no such node \'' .. name .. '\'', 2) end local node = {} node.children = {} @@ -81,15 +81,59 @@ function Tactree.Tree(name) node.update = NodeUpdate node.private = NodePrivateData - if Tactree.Nodes[name].children then - for _, child in ipairs(Tactree.Nodes[name].children) do - table.insert(node.children, Tactree.Tree(child)) + -- this will crash if there is a recursive structure + -- find a way to prevent this? + if Nodes[name].children then + for _, child in ipairs(Nodes[name].children) do + local cn = Tactree.Tree(child) + cn.parent = node + table.insert(node.children, cn) end end - return setmetatable(node, { __index = Tactree.Nodes[name] }) + return setmetatable(node, { __index = Nodes[name] }) end +Tactree.Leaf 'Sequence' +{ + start = function(node) + node:private().current_child = 1 + node.children[node:private().current_child]:start() + end, + tick = function(node) + local result = node.children[node:private().current_child]:update() + + if type(result) == 'boolean' then + if result then + if node:private().current_child == #node.children then + return true + else + node:private().current_child = node:private().current_child + 1 + node.children[node:private().current_child]:start() + end + else + return false + end + end + end +} + +Tactree.Leaf 'Repeat' +{ + start = function(node) + node.children[1]:start() + end, + tick = function(node) + local result = node.children[1]:update() + + if type(result) == 'boolean' then + if not result then return false end + + node.children[1]:start() + end + end +} + --[[ Example usage -------------