local bret = require 'behavior3.behavior_ret' local process = require 'behavior3.sample_process' local sformat = string.format local table = table local print = print local mt = {} mt.__index = mt local function new_node(...) local obj = setmetatable({}, mt) obj:init(...) return obj end function mt:init(node_data, tree) self.tree = tree self.name = node_data.name self.id = node_data.id self.info = sformat('node %s.%s %s', tree.name, self.id, self.name) self.data = node_data self.args = self.data.args or {} self.children = {} for _, child_data in ipairs(node_data.children or {}) do local child = new_node(child_data, tree) table.insert(self.children, child) end end function mt:run(env) --print("start", self.name, self.node_id) if env:get_inner_var(self, "YIELD") == nil then env:push_stack(self) end local vars = {} for i, var_name in ipairs(self.data.input or {}) do vars[i] = env:get_var(var_name) end local func = assert(process[self.name].run, self.name) vars = table.pack(func(self, env, table.unpack(vars))) local ret = vars[1] assert(ret, self.info) if ret ~= bret.RUNNING then env:set_inner_var(self, "YIELD", nil) env:pop_stack() end for i, var_name in ipairs(self.data.output or {}) do env:set_var(var_name, vars[i + 1]) end env.last_ret = ret --print("fini", self.name, self.node_id, table.unpack(vars)) if self.data.debug then local var_str = '' for k, v in pairs(env.vars) do var_str = sformat("[%s]=%s,", k, v) end print(sformat("[DEBUG] btree:%s, node:%s, ret:%s vars:{%s}", self.tree.name, self.id, ret, var_str)) end return ret end function mt:yield(env, arg) env:set_inner_var(self, "YIELD", arg or true) return bret.RUNNING end function mt:resume(env) return env:get_inner_var(self, "YIELD"), env.last_ret end local M = {} function M.new(...) return new_node(...) end function M.process(custom) process = custom end return M