@@ -240,3 +240,68 @@ TEST(Enums, SubtreeRemapping)
240240 ASSERT_EQ (status, NodeStatus::SUCCESS);
241241 ASSERT_EQ (tree.rootBlackboard ()->get <BatteryStatus>(" fault_status" ), LOW_BATTERY);
242242}
243+
244+ // Issue #948: enums with a convertFromString<T> specialization should be parsed
245+ // correctly via getInput, without requiring ScriptingEnumsRegistry.
246+ class ActionWithNodeType : public SyncActionNode
247+ {
248+ public:
249+ ActionWithNodeType (const std::string& name, const NodeConfig& config)
250+ : SyncActionNode(name, config)
251+ {}
252+
253+ NodeStatus tick () override
254+ {
255+ auto res = getInput<NodeType>(" type" );
256+ if (!res)
257+ {
258+ throw RuntimeError (" getInput failed: " + res.error ());
259+ }
260+ parsed_type = res.value ();
261+ return NodeStatus::SUCCESS;
262+ }
263+
264+ static PortsList providedPorts ()
265+ {
266+ return { InputPort<NodeType>(" type" ) };
267+ }
268+
269+ NodeType parsed_type = NodeType::UNDEFINED;
270+ };
271+
272+ TEST (Enums, ParseEnumWithConvertFromString_Issue948)
273+ {
274+ std::string xml_txt = R"(
275+ <root BTCPP_format="4" >
276+ <BehaviorTree ID="Main">
277+ <Sequence>
278+ <ActionWithNodeType name="test_action" type="Action"/>
279+ <ActionWithNodeType name="test_control" type="Control"/>
280+ </Sequence>
281+ </BehaviorTree>
282+ </root>)" ;
283+
284+ BehaviorTreeFactory factory;
285+ factory.registerNodeType <ActionWithNodeType>(" ActionWithNodeType" );
286+ // Deliberately NOT registering NodeType in ScriptingEnumsRegistry.
287+ // convertFromString<NodeType> exists and should be used as fallback.
288+
289+ auto tree = factory.createTreeFromText (xml_txt);
290+ NodeStatus status = tree.tickWhileRunning ();
291+ ASSERT_EQ (status, NodeStatus::SUCCESS);
292+
293+ for (const auto & node : tree.subtrees .front ()->nodes )
294+ {
295+ if (auto typed = dynamic_cast <ActionWithNodeType*>(node.get ()))
296+ {
297+ if (typed->name () == " test_action" )
298+ {
299+ ASSERT_EQ (NodeType::ACTION, typed->parsed_type );
300+ }
301+ else if (typed->name () == " test_control" )
302+ {
303+ ASSERT_EQ (NodeType::CONTROL, typed->parsed_type );
304+ }
305+ }
306+ }
307+ }
0 commit comments