-module(run_task). -include("../bt_node_behaviours/bt_nodes.hrl"). -export([ run/3, preempt/3 ]). %% should call init first if state is undefined but init function is defined. %% should call run with args, state, blackboard, event if run/4 is defined; otherwise args, blackboard, event %% if return is success or failure, should set state as undefined and return success/failure %% otherwise update state and blackboard with NewState and NewBB and return running run3param(TaskNode, Module, BB, Event) when is_record(TaskNode, task) -> {Status, NewBB} = Module:run(TaskNode#task.args, BB, Event), %% since it doesn't need state, setting it to undefined only. {Status, undefined, NewBB}. run4param(TaskNode, Module, BB, Event) when is_record(TaskNode, task) -> %% init if not already StartingState = case TaskNode#task.state of undefined -> Module:init(TaskNode#task.args, BB); AlreadyInit -> AlreadyInit end, Module:run(TaskNode#task.args, StartingState, BB, Event). -spec run(TaskNode :: task(), BB :: blackboard(), Event :: event()) -> {Status :: status(), NewTaskNode :: task(), NewBB :: blackboard()}. run(TaskNode, BB, Event) when is_record(TaskNode, task) -> Module = TaskNode#task.module, %% check if run/4 is defined; otherwise do run/3 {Status, NewState, NewBB} = case erlang:function_exported(Module, run, 4) of false -> run3param(TaskNode, Module, BB, Event); true -> run4param(TaskNode, Module, BB, Event) end, case Status of running -> {running, TaskNode#task{state = NewState}, NewBB}; %% TODO: do we need to return old bb in case of failure or is this fine? %% resetting state to undefined in case of both success and failure. this means node was terminated failure -> {failure, TaskNode#task{state = undefined}, NewBB}; success -> {success, TaskNode#task{state = undefined}, NewBB} end. %% just clear state and return? -spec preempt(TaskNode :: task(), BB :: blackboard(), ShouldCleanBB :: boolean()) -> {NewNode :: term(), NewBB :: blackboard()}. preempt(TaskNode, BB, _ShouldCleanBB) when is_record(TaskNode, task) -> {TaskNode#task{state = undefined}, BB}.