@@ -32,6 +32,58 @@ namespace BT
32
32
typedef std::function<std::unique_ptr<TreeNode>(const std::string&, const NodeConfiguration&)>
33
33
NodeBuilder;
34
34
35
+ template <typename T>
36
+ using has_default_constructor = typename std::is_constructible<T, const std::string&>;
37
+
38
+ template <typename T>
39
+ using has_params_constructor = typename std::is_constructible<T, const std::string&, const NodeConfiguration&>;
40
+
41
+
42
+ template <typename T> inline
43
+ NodeBuilder CreateBuilder (typename std::enable_if<has_default_constructor<T>::value &&
44
+ has_params_constructor<T>::value >::type* = nullptr )
45
+ {
46
+ return [](const std::string& name, const NodeConfiguration& config)
47
+ {
48
+ // Special case. Use default constructor if parameters are empty
49
+ if ( config.input_ports .empty () &&
50
+ config.output_ports .empty () &&
51
+ has_default_constructor<T>::value)
52
+ {
53
+ return std::make_unique<T>(name);
54
+ }
55
+ return std::make_unique<T>(name, config);
56
+ };
57
+ }
58
+
59
+ template <typename T> inline
60
+ NodeBuilder CreateBuilder (typename std::enable_if<!has_default_constructor<T>::value &&
61
+ has_params_constructor<T>::value >::type* = nullptr )
62
+ {
63
+ return [](const std::string& name, const NodeConfiguration& params)
64
+ {
65
+ return std::unique_ptr<TreeNode>(new T (name, params));
66
+ };
67
+ }
68
+
69
+ template <typename T> inline
70
+ NodeBuilder CreateBuilder (typename std::enable_if<has_default_constructor<T>::value &&
71
+ !has_params_constructor<T>::value >::type* = nullptr )
72
+ {
73
+ return [](const std::string& name, const NodeConfiguration&)
74
+ {
75
+ return std::unique_ptr<TreeNode>(new T (name));
76
+ };
77
+ }
78
+
79
+
80
+ template <typename T> inline
81
+ TreeNodeManifest CreateManifest (const std::string& ID, PortsList portlist = getProvidedPorts<T>())
82
+ {
83
+ return { getType<T>(), ID, portlist };
84
+ }
85
+
86
+
35
87
constexpr const char * PLUGIN_SYMBOL = " BT_RegisterNodesFromPlugin" ;
36
88
37
89
#ifndef BT_PLUGIN_EXPORT
@@ -128,7 +180,7 @@ class BehaviorTreeFactory
128
180
template <typename T>
129
181
void registerBuilder (const std::string& ID, const NodeBuilder& builder )
130
182
{
131
- auto manifest = BehaviorTreeFactory::buildManifest <T>(ID);
183
+ auto manifest = CreateManifest <T>(ID);
132
184
registerBuilder (manifest, builder);
133
185
}
134
186
@@ -196,11 +248,11 @@ class BehaviorTreeFactory
196
248
std::is_base_of<ControlNode, T>::value ||
197
249
std::is_base_of<DecoratorNode, T>::value ||
198
250
std::is_base_of<ConditionNode, T>::value,
199
- " [registerBuilder ]: accepts only classed derived from either ActionNodeBase, "
251
+ " [registerNode ]: accepts only classed derived from either ActionNodeBase, "
200
252
" DecoratorNode, ControlNode or ConditionNode" );
201
253
202
254
static_assert (!std::is_abstract<T>::value,
203
- " [registerBuilder ]: Some methods are pure virtual. "
255
+ " [registerNode ]: Some methods are pure virtual. "
204
256
" Did you override the methods tick() and halt()?" );
205
257
206
258
constexpr bool default_constructable = std::is_constructible<T, const std::string&>::value;
@@ -210,20 +262,56 @@ class BehaviorTreeFactory
210
262
has_static_method_providedPorts<T>::value;
211
263
212
264
static_assert (default_constructable || param_constructable,
213
- " [registerBuilder ]: the registered class must have at least one of these two "
265
+ " [registerNode ]: the registered class must have at least one of these two "
214
266
" constructors: "
215
267
" (const std::string&, const NodeConfiguration&) or (const std::string&)." );
216
268
217
269
static_assert (!(param_constructable && !has_static_ports_list),
218
- " [registerBuilder ]: you MUST implement the static method: "
270
+ " [registerNode ]: you MUST implement the static method: "
219
271
" PortsList providedPorts();\n " );
220
272
221
273
static_assert (!(has_static_ports_list && !param_constructable),
222
- " [registerBuilder ]: since you have a static method requiredNodeParameters (), "
274
+ " [registerNode ]: since you have a static method providedPorts (), "
223
275
" you MUST add a constructor sign signature (const std::string&, const "
224
276
" NodeParameters&)\n " );
225
277
226
- registerNodeTypeImpl<T>(ID);
278
+ registerBuilder ( CreateManifest<T>(ID), CreateBuilder<T>());
279
+ }
280
+
281
+ template <typename T>
282
+ void registerNodeType (const std::string& ID, PortsList ports)
283
+ {
284
+ static_assert (std::is_base_of<ActionNodeBase, T>::value ||
285
+ std::is_base_of<ControlNode, T>::value ||
286
+ std::is_base_of<DecoratorNode, T>::value ||
287
+ std::is_base_of<ConditionNode, T>::value,
288
+ " [registerNode]: accepts only classed derived from either ActionNodeBase, "
289
+ " DecoratorNode, ControlNode or ConditionNode" );
290
+
291
+ static_assert (!std::is_abstract<T>::value,
292
+ " [registerNode]: Some methods are pure virtual. "
293
+ " Did you override the methods tick() and halt()?" );
294
+
295
+ constexpr bool default_constructable = std::is_constructible<T, const std::string&>::value;
296
+ constexpr bool param_constructable =
297
+ std::is_constructible<T, const std::string&, const NodeConfiguration&>::value;
298
+ constexpr bool has_static_ports_list =
299
+ has_static_method_providedPorts<T>::value;
300
+
301
+ static_assert (default_constructable || param_constructable,
302
+ " [registerNode]: the registered class must have at least one of these two "
303
+ " constructors: (const std::string&, const NodeConfiguration&) or (const std::string&)." );
304
+
305
+ static_assert (!has_static_ports_list,
306
+ " [registerNode]: ports are passed to this node explicitly. The static method"
307
+ " providedPorts() should be removed to avoid ambiguities\n " );
308
+
309
+ static_assert (param_constructable,
310
+ " [registerNode]: since this node has ports, "
311
+ " you MUST add a constructor sign signature (const std::string&, const "
312
+ " NodeParameters&)\n " );
313
+
314
+ registerBuilder ( CreateManifest<T>(ID, ports), CreateBuilder<T>());
227
315
}
228
316
229
317
// / All the builders. Made available mostly for debug purposes.
@@ -241,74 +329,15 @@ class BehaviorTreeFactory
241
329
Tree createTreeFromFile (const std::string& file_path,
242
330
Blackboard::Ptr blackboard = Blackboard::create());
243
331
244
- template <typename T> static
245
- TreeNodeManifest buildManifest (const std::string& ID)
246
- {
247
- return { getType<T>(), ID, getProvidedPorts<T>() };
248
- }
249
-
250
332
private:
251
333
std::unordered_map<std::string, NodeBuilder> builders_;
252
334
std::unordered_map<std::string, TreeNodeManifest> manifests_;
253
335
std::set<std::string> builtin_IDs_;
254
336
255
- // template specialization = SFINAE + black magic
256
-
257
- // clang-format off
258
- template <typename T>
259
- using has_default_constructor = typename std::is_constructible<T, const std::string&>;
260
-
261
- template <typename T>
262
- using has_params_constructor = typename std::is_constructible<T, const std::string&, const NodeConfiguration&>;
263
-
264
- template <typename T>
265
- void registerNodeTypeImpl (const std::string& ID)
266
- {
267
- NodeBuilder builder = getBuilder<T>();
268
- registerBuilder ( buildManifest<T>(ID), builder);
269
- }
270
-
271
- template <typename T> static
272
- NodeBuilder getBuilder (typename std::enable_if<has_default_constructor<T>::value &&
273
- has_params_constructor<T>::value >::type* = nullptr )
274
- {
275
- return [](const std::string& name, const NodeConfiguration& config)
276
- {
277
- // TODO FIXME
278
-
279
- // Special case. Use default constructor if parameters are empty
280
- if ( config.input_ports .empty () &&
281
- config.output_ports .empty () &&
282
- has_default_constructor<T>::value)
283
- {
284
- return std::make_unique<T>(name);
285
- }
286
- return std::make_unique<T>(name, config);
287
- };
288
- }
289
-
290
- template <typename T> static
291
- NodeBuilder getBuilder (typename std::enable_if<!has_default_constructor<T>::value &&
292
- has_params_constructor<T>::value >::type* = nullptr )
293
- {
294
- return [](const std::string& name, const NodeConfiguration& params)
295
- {
296
- return std::unique_ptr<TreeNode>(new T (name, params));
297
- };
298
- }
299
-
300
- template <typename T> static
301
- NodeBuilder getBuilder (typename std::enable_if<has_default_constructor<T>::value &&
302
- !has_params_constructor<T>::value >::type* = nullptr )
303
- {
304
- return [](const std::string& name, const NodeConfiguration&)
305
- {
306
- return std::unique_ptr<TreeNode>(new T (name));
307
- };
308
- }
309
337
// clang-format on
310
338
};
311
339
340
+
312
341
} // end namespace
313
342
314
343
#endif // BT_FACTORY_H
0 commit comments