-module(yaml_parse_sequence). -export([ parse/6 ]). -include("../bt_node_behaviours/bt_nodes.hrl"). get_child_and_blackboard({Child = {ChildName, _}, Idx}, Namespace, ParentContext, Blackboard, YAMLDictionary, FileDirectory) -> IdxString = integer_to_list(Idx), ChildNamespace = bt_parser_utils:get_namespace(Namespace, ChildName ++ "_" ++ IdxString), bt_yaml_parser:parse(Child, ChildNamespace, ParentContext, Blackboard, YAMLDictionary, FileDirectory). -spec parse( Sequence :: {string(), list({term(), term()})}, Namespace :: list(string()), ParentContext :: map(), Blackboard :: map(), YAMLDictionary :: term(), FileDirectory :: string() ) -> {ParsedTree :: sequence(), Blackboard :: blackboard()}. parse(Sequence = {"sequence", List}, Namespace, ParentContext, Blackboard, YAMLDictionary, FileDirectory) -> Decorators = proplists:get_value("decorators", List, []), parse(Sequence, Decorators, Namespace, ParentContext, Blackboard, YAMLDictionary, FileDirectory). -spec parse( Sequence :: {string(), list({term(), term()})}, Decorators :: list({term(), term()}), Namespace :: list(string()), ParentContext :: map(), Blackboard :: map(), YAMLDictionary :: term(), FileDirectory :: string() ) -> {ParsedTree :: sequence(), Blackboard :: blackboard()}. parse(_Sequence = {"sequence", List}, [], Namespace, ParentContext, Blackboard, YAMLDictionary, FileDirectory) -> %% order of traversal is dependent on implementation, so not using it. instead using list comprehension ChildList = proplists:get_value("children", List), ChildrenBlackboardPairs = [ get_child_and_blackboard(X, Namespace, ParentContext, Blackboard, YAMLDictionary, FileDirectory) || X <- lists:zip(ChildList, lists:seq(1, length(ChildList))) ], %% merge all the blackboards NewBlackboard = lists:foldl( fun({_ChildTree, ChildBlackboard}, Acc) -> maps:merge(ChildBlackboard, Acc) end, Blackboard, ChildrenBlackboardPairs ), %% proplists:get_keys doesn't preserve order! use list comprehension ChildrenTrees = [X || {X, _} <- ChildrenBlackboardPairs], %% here name is actually filled in by the parent subtree (if any). the sequence entry in .yml shouldn't have a name... Name = proplists:get_value("name", List, "sequence"), {#sequence{ name = Name, namespace = Namespace, children = ChildrenTrees }, NewBlackboard}; parse(Sequence = {"sequence", _List}, [Decorator | RestOfDecorators], Namespace, ParentContext, Blackboard, YAMLDictionary, FileDirectory) -> ParsedDecorator = yaml_parser_utils:get_decorator(Decorator, ParentContext), {Child, NewBlackboard} = parse(Sequence, RestOfDecorators, Namespace, ParentContext, Blackboard, YAMLDictionary, FileDirectory), { ParsedDecorator#decorator{ child = Child }, NewBlackboard }.