diff --git a/ReadMe.md b/ReadMe.md index 7ca3948..76e7031 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -13,10 +13,10 @@ bt = require "behave" tree = bt.Sequence({ bt.Node({ - run = function(self) + run = function(self, obj, ...) -- do stuff end, - finish = function(self) + finish = function(self, obj, ...) -- finish up end }), @@ -30,6 +30,9 @@ tree = bt.Sequence({ }) }) +tree:addObject(obj) +tree:update(obj) + node1 = { -- pretend this has run/finish functions or whatever } @@ -74,6 +77,7 @@ will be passed to their children as they are called). Pass a table of nodes to these to set their contents. All composite nodes repeat after the entire tree has been processed. +- Composite: Super class of the other composite nodes. - Sequence: Runs children until a failure or success of all. - Selector: Runs children until a success or failure of all. - Random: Runs a random child and returns its result. @@ -88,8 +92,8 @@ Pass a single node to these, except for `Repeat`, which needs a number followed by a node. All decorator nodes (except `RunOnce`) repeat after the entire tree has been processed. +- Decorator: Superclass. Just returns the result of its child node. - Repeat: Repeats a node a specified number of times, fails if the node fails. -- Decorator: Does nothing except return the result of its child node. - Succeed: Runs a node and returns success. - Fail: Runs a node and returns failure. - Invert: Runs a node, reporting a success on fail, and failure on success. diff --git a/behave.lua b/behave.lua index 9c48654..9b84d5e 100644 --- a/behave.lua +++ b/behave.lua @@ -70,12 +70,63 @@ do _base_0.__class = _class_0 Node = _class_0 end -local Sequence +local Composite do local _class_0 local _parent_0 = Node local _base_0 = { addObject = function(self, obj) + local _list_0 = self.nodes + for _index_0 = 1, #_list_0 do + local node = _list_0[_index_0] + node:addObject(obj) + end + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + _class_0 = setmetatable({ + __init = function(self, nodes) + if nodes == nil then + nodes = { } + end + self.nodes = nodes + return _class_0.__parent.__init(self) + end, + __base = _base_0, + __name = "Composite", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + local parent = rawget(cls, "__parent") + if parent then + return parent[name] + end + else + return val + end + end, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + if _parent_0.__inherited then + _parent_0.__inherited(_parent_0, _class_0) + end + Composite = _class_0 +end +local Sequence +do + local _class_0 + local _parent_0 = Composite + local _base_0 = { + addObject = function(self, obj) + _class_0.__parent.__base.addObject(self) obj[self.u] = { index = 0, running = 0 @@ -104,12 +155,8 @@ do _base_0.__index = _base_0 setmetatable(_base_0, _parent_0.__base) _class_0 = setmetatable({ - __init = function(self, nodes) - if nodes == nil then - nodes = { } - end - self.nodes = nodes - return _class_0.__parent.__init(self) + __init = function(self, ...) + return _class_0.__parent.__init(self, ...) end, __base = _base_0, __name = "Sequence", @@ -141,9 +188,10 @@ end local Selector do local _class_0 - local _parent_0 = Node + local _parent_0 = Composite local _base_0 = { addObject = function(self, obj) + _class_0.__parent.__base.addObject(self) obj[self.u] = { index = 0, running = 0 @@ -172,12 +220,8 @@ do _base_0.__index = _base_0 setmetatable(_base_0, _parent_0.__base) _class_0 = setmetatable({ - __init = function(self, nodes) - if nodes == nil then - nodes = { } - end - self.nodes = nodes - return _class_0.__parent.__init(self) + __init = function(self, ...) + return _class_0.__parent.__init(self, ...) end, __base = _base_0, __name = "Selector", @@ -209,7 +253,7 @@ end local Random do local _class_0 - local _parent_0 = Node + local _parent_0 = Composite local _base_0 = { update = function(self, obj, ...) local index = math.floor(math.random() * #self.nodes + 1) @@ -219,12 +263,8 @@ do _base_0.__index = _base_0 setmetatable(_base_0, _parent_0.__base) _class_0 = setmetatable({ - __init = function(self, nodes) - if nodes == nil then - nodes = { } - end - self.nodes = nodes - return _class_0.__parent.__init(self) + __init = function(self, ...) + return _class_0.__parent.__init(self, ...) end, __base = _base_0, __name = "Random", @@ -256,9 +296,10 @@ end local Randomizer do local _class_0 - local _parent_0 = Node + local _parent_0 = Composite local _base_0 = { addObject = function(self, obj) + _class_0.__parent.__base.addObject(self) obj[self.u] = { running = false } @@ -278,12 +319,8 @@ do _base_0.__index = _base_0 setmetatable(_base_0, _parent_0.__base) _class_0 = setmetatable({ - __init = function(self, nodes) - if nodes == nil then - nodes = { } - end - self.nodes = nodes - return _class_0.__parent.__init(self) + __init = function(self, ...) + return _class_0.__parent.__init(self, ...) end, __base = _base_0, __name = "Randomizer", @@ -430,82 +467,14 @@ do end RandomSelector = _class_0 end -local Repeat -do - local _class_0 - local _parent_0 = Node - local _base_0 = { - addObject = function(self, obj) - obj[self.u] = { - counter = 1, - running = false - } - end, - update = function(self, obj, ...) - local result = success - if obj[self.u].running then - result = self.node:update(obj, ...) - if not (result == running) then - obj[self.u].running = false - end - end - while result == success and obj[self.u].counter < self.cycles do - obj[self.u].counter = obj[self.u].counter + 1 - result = self.node:update(obj, ...) - end - if result == running then - obj[self.u].running = true - else - obj[self.u].counter = 1 - end - return result - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self, cycles, node) - if cycles == nil then - cycles = 2 - end - if node == nil then - node = Node() - end - self.cycles, self.node = cycles, node - return _class_0.__parent.__init(self) - end, - __base = _base_0, - __name = "Repeat", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - Repeat = _class_0 -end local Decorator do local _class_0 local _parent_0 = Node local _base_0 = { + addObject = function(self, obj) + return self.node:addObject(obj) + end, update = function(self, obj, ...) return self.node:update(obj, ...) end @@ -547,6 +516,78 @@ do end Decorator = _class_0 end +local Repeat +do + local _class_0 + local _parent_0 = Decorator + local _base_0 = { + addObject = function(self, obj) + _class_0.__parent.__base.addObject(self) + obj[self.u] = { + counter = 1, + running = false + } + end, + update = function(self, obj, ...) + local result = success + if obj[self.u].running then + result = self.node:update(obj, ...) + if not (result == running) then + obj[self.u].running = false + end + end + while result == success and obj[self.u].counter < self.cycles do + obj[self.u].counter = obj[self.u].counter + 1 + result = self.node:update(obj, ...) + end + if result == running then + obj[self.u].running = true + else + obj[self.u].counter = 1 + end + return result + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + _class_0 = setmetatable({ + __init = function(self, cycles, node) + if cycles == nil then + cycles = 2 + end + if node == nil then + node = Node() + end + self.cycles, self.node = cycles, node + return _class_0.__parent.__init(self, self.node) + end, + __base = _base_0, + __name = "Repeat", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + local parent = rawget(cls, "__parent") + if parent then + return parent[name] + end + else + return val + end + end, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + if _parent_0.__inherited then + _parent_0.__inherited(_parent_0, _class_0) + end + Repeat = _class_0 +end local Succeed do local _class_0 diff --git a/behave.moon b/behave.moon index 9afceb1..a3d4f07 100644 --- a/behave.moon +++ b/behave.moon @@ -33,12 +33,18 @@ class Node obj[@u].started = false return result --- Runs children in order until one returns fail, or all succeed. -class Sequence extends Node +class Composite extends Node new: (@nodes={}) => super! addObject: (obj) => + for node in *@nodes + node\addObject obj + +-- Runs children in order until one returns fail, or all succeed. +class Sequence extends Composite + addObject: (obj) => + super! obj[@u] = { index: 0 running: 0 @@ -64,11 +70,9 @@ class Sequence extends Node return result -- Runs children in order until one succeeds or all fail. -class Selector extends Node - new: (@nodes={}) => - super! - +class Selector extends Composite addObject: (obj) => + super! obj[@u] = { index: 0 running: 0 @@ -93,19 +97,14 @@ class Selector extends Node return result -- Runs a random child. -class Random extends Node - new: (@nodes={}) => - super! - +class Random extends Composite update: (obj, ...) => index = math.floor math.random! * #@nodes + 1 return @nodes[index]\update obj, ... -class Randomizer extends Node - new: (@nodes={}) => - super! - +class Randomizer extends Composite addObject: (obj) => + super! obj[@u] = { running: false } @@ -163,12 +162,23 @@ class RandomSelector extends Randomizer return result --- Repeats a node a specified number of times, unless it fails. -class Repeat extends Node - new: (@cycles=2, @node=Node!) => +class Decorator extends Node + new: (@node=Node!) => super! addObject: (obj) => + @node\addObject obj + + update: (obj, ...) => + return @node\update obj, ... + +-- Repeats a node a specified number of times, unless it fails. +class Repeat extends Decorator + new: (@cycles=2, @node=Node!) => + super @node + + addObject: (obj) => + super! obj[@u] = { counter: 1 running: false @@ -193,13 +203,6 @@ class Repeat extends Node return result -class Decorator extends Node - new: (@node=Node!) => - super! - - update: (obj, ...) => - return @node\update obj, ... - -- Returns success whether or not the node succeeds. class Succeed extends Decorator update: (obj, ...) => @@ -285,6 +288,7 @@ setmetatable { :Node -- Composite Nodes + :Composite :Sequence :Selector :Random