Current section
Files
Jump to
Current section
Files
src/bt_engine/runners/bt_runner.erl
-module(bt_runner).
-include("../bt_node_behaviours/bt_nodes.hrl").
-export([
run/3,
preempt/3,
clear_metadata/1
]).
%% clear metadata before running the node, then add it again based on result.
%% better to do it here instead of individual handling in node runners
%% just setting status for new, maybe will add rest of the stuff later on.
-spec run(
Node :: bt_node(),
BB :: blackboard(),
Event :: event()) -> {Status :: status(), NewNode :: bt_node(), NewBB :: blackboard()}.
run(Node, BB, Event) when is_record(Node, sequence) ->
{Status, NewNode, NewBB} = run_sequence:run(Node#sequence{metadata = undefined}, BB, Event),
{Status, NewNode#sequence{metadata = #metadata{status = Status}}, NewBB};
run(Node, BB, Event) when is_record(Node, decorator) ->
{Status, NewNode, NewBB} = run_decorator:run(Node#decorator{metadata = undefined}, BB, Event),
{Status, NewNode#decorator{metadata = #metadata{status = Status}}, NewBB};
run(Node, BB, Event) when is_record(Node, task) ->
{Status, NewNode, NewBB} = run_task:run(Node#task{metadata = undefined}, BB, Event),
{Status, NewNode#task{metadata = #metadata{status = Status}}, NewBB}.
%% set metadata to undefined for all preempted nodes. actually no? because we sometimes run and preempt the same node
%% in one cycle
-spec preempt(
Node :: bt_node(),
BB :: blackboard(),
ShouldCleanBB :: boolean()) -> {NewNode :: bt_node(), NewBB :: blackboard()}.
preempt(Node, BB, ShouldCleanBB) when is_record(Node, sequence) ->
run_sequence:preempt(Node, BB, ShouldCleanBB);
preempt(Node, BB, ShouldCleanBB) when is_record(Node, decorator) ->
run_decorator:preempt(Node, BB, ShouldCleanBB);
preempt(Node, BB, ShouldCleanBB) when is_record(Node, task) ->
run_task:preempt(Node, BB, ShouldCleanBB).
%% defining clear metadata together for all nodes here only...
-spec clear_metadata(
Node :: bt_node()
) -> NewNode :: bt_node().
clear_metadata(Node) when is_record(Node, sequence) ->
Node#sequence{metadata = undefined, children = [clear_metadata(Child) || Child <- Node#sequence.children]};
clear_metadata(Node) when is_record(Node, decorator) ->
Node#decorator{metadata = undefined, child = clear_metadata(Node#decorator.child)};
clear_metadata(Node) when is_record(Node, task) ->
Node#task{metadata = undefined}.