Current section

Files

Jump to
erlang_behaviour_trees src bt_engine bt_util.erl
Raw

src/bt_engine/bt_util.erl

-module(bt_util).
-export([to_file/1, to_jsonable_term/1]).
-include("bt_nodes.hrl").
%% Usage:
%% ---
%% bt_util:to_jsonable_term(bt_yaml_parser:parse("src/samples/trees/rackloop.yml", "single_rackloop", [{"BId", 3}])).
%% io:format("~s ~n", [jsx:encode(bt_util:to_jsonable_term(bt_yaml_parser:parse("src/samples/trees/rackloop.yml", "single_rackloop", [{"BId", 3}])))]).
to_jsonable_term({RootNode, BB}) ->
node_to_tree(<<"null">>, RootNode, BB).
to_file(ParseResult) ->
Data = jsx:encode(to_jsonable_term(ParseResult)),
{ok, F} = file:open("treedata.js", [write]),
file:write(F, "var treeData = ["),
file:write(F, Data),
file:write(F, "];"),
file:close(F).
node_to_tree(ParentName, #sequence{name = SequenceName, children = Children, metadata = Metadata}, BB) ->
Name = list_to_binary(lists:flatten(SequenceName)),
Map = #{name => Name, parent => ParentName, status => get_status(Metadata), type => sequence},
case length(Children) of
0 -> Map;
_ -> maps:put(children, lists:map(fun(X) -> node_to_tree(Name, X, BB) end, Children), Map)
end;
node_to_tree(ParentName, #decorator{name = DecoratorName, child = Child, metadata = Metadata, args = Args, module = Module}, BB) ->
Name = list_to_binary(lists:flatten(DecoratorName)),
Attributes = get_attributes(Args, BB),
Map = #{name => Name, parent => ParentName, status => get_status(Metadata), attributes => maps:put(node, Module, Attributes), type => decorator},
maps:put(children, [node_to_tree(Name, Child, BB)], Map);
node_to_tree(ParentName, #task{name = TaskName, metadata = Metadata, args = Args, module = Module}, BB) ->
Name = list_to_binary(lists:flatten(TaskName)),
Attributes = get_attributes(Args, BB),
#{name => Name, parent => ParentName, status => get_status(Metadata), attributes => maps:put(node, Module, Attributes), type => task}.
get_status(undefined) ->
unknown;
get_status(#bt_metadata{status = Status}) ->
Status.
get_attributes(Args, BB) when is_map(Args) ->
ArgsProplist = maps:to_list(Args),
EvalFn = fun(Value, BBTemp) ->
V = bt_blackboard:eval_with_default_fn(Value, BBTemp, fun (_BBKey) -> "???" end),
%% need to serialize it so its jsonable
lists:flatten(io_lib:format("~p", [V]))
end,
WithValues = [
%% jsx doesn't like strings ?? both keys and values?
%% https://github.com/talentdeficit/jsx/issues/81
{list_to_atom(Key), list_to_atom(EvalFn(Value, BB))} ||
{Key, Value} <- ArgsProplist
],
maps:from_list(WithValues).