new node types, bugfix, ReadMe update

* Inverted, Repeat, and Once node types
* fixed bug with Decorator
* documentation updated
This commit is contained in:
Paul Liverman III 2018-03-16 00:30:40 -07:00
parent 6455230334
commit 1c05bac30a
3 changed files with 124 additions and 32 deletions

View File

@ -38,17 +38,31 @@ WalkPath = {
} }
``` ```
## The Decorator Node ## Decorator Nodes
A very basic extension to the result of a leaf node, allowing you to alter the Basic extensions to leaf nodes. Decorator allows you to specify a function to
result it returns. Note: You cannot alter a `behave.running` return. modify returned results (except for `behave.running`). Inverted inverts the
result of its node. Repeat allows you to repeatedly call a node a specified
number of times. Once allows you to make a node only get called once.
``` ```
InvertSomeNode = { ManuallyInvertedSomeNode = {
decorator: (result) -> decorator: (result) ->
return not result return not result
SomeNode SomeNode
} }
InvertedSomeNode = {
type: behave.Inverted
SomeNode
}
SomeNodeRepeated = {
repeat: 20
SomeNode
}
SomeNodeOnce = {
type: behave.Once
SomeNode
}
``` ```
## Composite Nodes ## Composite Nodes
@ -67,7 +81,7 @@ Behaviors = {
## Custom Nodes ## Custom Nodes
You can create custom nodes and easily use them. Rather than explaining how to, You can create custom nodes and easily use them. Rather than explaining how to,
here's an example: here's an example inverter (note: `behave.Inverted` offers this feature):
``` ```
-- defining the node type: -- defining the node type:

View File

@ -1,9 +1,23 @@
local make, Node, Decorate local Node, Decorate, Repeat
local running = setmetatable({ }, { local running = setmetatable({ }, {
__tostring = function() __tostring = function()
return "running" return "running"
end end
}) })
local make
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)
else
return Node(tab)
end
end
local get_nodes local get_nodes
get_nodes = function(tab) get_nodes = function(tab)
local nodes = { } local nodes = { }
@ -13,17 +27,6 @@ get_nodes = function(tab)
end end
return nodes return nodes
end end
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)
end
end
Node = function(tab) Node = function(tab)
local state, started = { }, false local state, started = { }, false
return function(...) return function(...)
@ -52,13 +55,52 @@ local Decorator
Decorator = function(tab) Decorator = function(tab)
local node = make(tab[1]) local node = make(tab[1])
return function(...) return function(...)
local result = node(object, ...) local result = node(...)
if not (result == running) then if not (result == running) then
result = tab.decorate(result, ...) result = tab.decorate(result, ...)
end end
return result return result
end end
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
local Selector local Selector
Selector = function(tab) Selector = function(tab)
local nodes = get_nodes(tab) local nodes = get_nodes(tab)
@ -123,6 +165,9 @@ return {
failure = false, failure = false,
Node = Node, Node = Node,
Decorator = Decorator, Decorator = Decorator,
Inverter = Inverter,
Repeat = Repeat,
Once = Once,
Selector = Selector, Selector = Selector,
Sequence = Sequence, Sequence = Sequence,
Random = Random Random = Random

View File

@ -1,24 +1,26 @@
local make, Node, Decorate local Node, Decorate, Repeat
running = setmetatable {}, __tostring: -> return "running" running = setmetatable {}, __tostring: -> return "running"
-- produces a callable function from a defined node or full behavior tree
make = (tab) ->
if "function" == type tab
return tab
elseif tab.decorate
return Decorate tab
elseif tab.repeat
return Repeat tab
elseif "function" == type tab.type
return tab.type tab
else
return Node tab
get_nodes = (tab) -> get_nodes = (tab) ->
nodes = {} nodes = {}
for node in *tab for node in *tab
table.insert nodes, make node table.insert nodes, make node
return nodes return nodes
-- produces a callable function from a defined node or full behavior tree
make = (tab) ->
if "function" == type tab
return tab
elseif "function" == type tab.type
return tab.type tab
elseif tab.decorate
return Decorate tab
else
return Node tab
-- complex leaf node -- complex leaf node
-- state is preserved through calls, optional start/finish functions -- state is preserved through calls, optional start/finish functions
Node = (tab) -> Node = (tab) ->
@ -38,10 +40,37 @@ Node = (tab) ->
Decorator = (tab) -> Decorator = (tab) ->
node = make tab[1] node = make tab[1]
return (...) -> return (...) ->
result = node object, ... result = node(...)
result = tab.decorate result, ... unless result == running result = tab.decorate result, ... unless result == running
return result return result
-- inverts the result of a node before returning it
Inverted = (tab) ->
node = make tab[1]
return (...) ->
result = node(...)
return not result unless result == running
Repeat = (tab) ->
node = make tab[1]
i, r = 1, tab.repeat
return (...) ->
while i <= r
return running if running == node(...)
i += 1
i = 1
return true
Once = (tab) ->
node = make tab[1]
ran = false
return (...) ->
return false if ran
result = node(...)
unless result == running
ran = true
return result
-- returns first success/running, or failure -- returns first success/running, or failure
Selector = (tab) -> Selector = (tab) ->
nodes = get_nodes tab nodes = get_nodes tab
@ -91,9 +120,13 @@ Random = (tab) ->
success: true success: true
:running :running
failure: false failure: false
:Node :Node
:Decorator :Decorator
:Inverter
:Repeat
:Once
:Selector :Selector
:Sequence :Sequence
:Random :Random