// A node builder is a functor that creates a std::unique_ptr<TreeNode>. // Using lambdas or std::bind, we can easily "inject" additional arguments. NodeBuilder builder_A = [](const std::string& name, const NodeConfiguration& config) { return std::make_unique<Action_A>( name, config, 42, 3.14, "hello world" ); };
// BehaviorTreeFactory::registerBuilder is a more general way to // register a custom node. factory.registerBuilder<Action_A>( "Action_A", builder_A);
// Register more custom nodes, if needed. // ....
// The rest of your code, where you create and tick the tree, goes here. // ....
public: // The constructor looks as usual. Action_B(const std::string& name, const NodeConfiguration& config): SyncActionNode(name, config) {}
// We want this method to be called ONCE and BEFORE the first tick() void init( int arg1, double arg2, const std::string& arg3 ) { _arg1 = (arg1); _arg2 = (arg2); _arg3 = (arg3); }
// this example doesn't require any port static PortsList providedPorts() { return {}; }
// tick() can access the private members NodeStatus tick() override;
private: int _arg1; double _arg2; std::string _arg3; };
// The regitration of Action_B is done as usual, but remember // that we still need to call Action_B::init() factory.registerNodeType<Action_B>( "Action_B" );
// Register more custom nodes, if needed. // ....
// Create the whole tree auto tree = factory.createTreeFromText(xml_text);
// Iterate through all the nodes and call init() if it is an Action_B for( auto& node: tree.nodes ) { // Not a typo: it is "=", not "=="此处是一个强转,不是做条件判断 if( auto action_B = dynamic_cast<Action_B*>( node.get() )) { action_B->init( 42, 3.14, "hello world"); } }
// The rest of your code, where you tick the tree, goes here. // ....