Current section
Files
Jump to
Current section
Files
src/core/blackboard.erl
-module(blackboard).
-compile([inline]).
%%--------------------------------------------------------------------
%% include
%%--------------------------------------------------------------------
-include("behavior3.hrl").
%%--------------------------------------------------------------------
%% export API
%%--------------------------------------------------------------------
-export([init_blackboard/2]).
-export([set/4, get/3, get/4, remove/3]).
-export([get_tree_mod/1, get_root_node_id/1, erase_node/2, erase_tree_nodes/1, get_global_maps/1, set_io/2, get_io/1]).
%%--------------------------------------------------------------------
%% API functions
%%--------------------------------------------------------------------
%% @doc
%% 初始化黑板
-spec init_blackboard(TreeMod :: module(), Title :: string()) -> BB :: blackboard().
init_blackboard(TreeMod, Title) ->
Title1 = unicode:characters_to_binary(Title),
RootID = TreeMod:get_root_id(Title1),
#blackboard{
tree_mod = TreeMod, title = Title1, root_id = RootID,
global_maps = #{}, io = erlang:group_leader()
}.
%% @doc
%% 设置节点变量
-spec set(Key :: term(), Value :: term(), NodeID :: node_id(), BB :: blackboard()) -> UpBB :: blackboard().
set(Key, Value, NodeID, #blackboard{global_maps = GlobalMaps} = BB) ->
case GlobalMaps of
#{NodeID := #{Key := _} = NodeMaps} ->
BB#blackboard{global_maps = GlobalMaps#{NodeID := NodeMaps#{Key := Value}}};
#{NodeID := NodeMaps} ->
BB#blackboard{global_maps = GlobalMaps#{NodeID := NodeMaps#{Key => Value}}};
#{} ->
BB#blackboard{global_maps = GlobalMaps#{NodeID => #{Key => Value}}}
end.
%% @doc
%% 获取节点变量
-spec get(Key :: term(), NodeID :: node_id(), BB :: blackboard()) -> Value :: term()|undefined.
get(Key, NodeID, #blackboard{global_maps = GlobalMaps}) ->
case GlobalMaps of
#{NodeID := #{Key := Value}} ->
Value;
#{} ->
undefined
end.
%% @doc
%% 获取节点变量,不存在则返回Default
-spec get(Key :: term(), NodeID :: node_id(), Default :: term(), BB :: blackboard()) -> Value :: term().
get(Key, NodeID, Default, BB) ->
case get(Key, NodeID, BB) of
undefined ->
Default;
Value ->
Value
end.
%% @doc
%% 删除节点变量
-spec remove(Key :: term(), NodeID :: node_id(), BB :: blackboard()) -> UpBB :: blackboard().
remove(Key, NodeID, #blackboard{global_maps = GlobalMaps} = BB) ->
case GlobalMaps of
#{NodeID := NodeMaps} ->
BB#blackboard{global_maps = GlobalMaps#{NodeID := maps:remove(Key, NodeMaps)}};
#{} ->
BB
end.
%% @doc
%% 获取当前运行中行为树模块名
-spec get_tree_mod(BB :: blackboard()) -> TreeMod :: module().
get_tree_mod(#blackboard{tree_mod = TreeMod}) ->
TreeMod.
%% @doc
%% 获取根节点id
-spec get_root_node_id(BB :: blackboard()) -> RootID :: node_id().
get_root_node_id(#blackboard{root_id = RootID}) ->
RootID.
%% @doc
%% 擦除节点所有信息
-spec erase_node(NodeID :: node_id(), BB :: blackboard()) -> UpBB :: blackboard().
erase_node(NodeID, #blackboard{global_maps = GlobalMaps} = BB) ->
BB#blackboard{global_maps = maps:remove(NodeID, GlobalMaps)}.
%% @doc
%% 擦除行为树所有节点信息
-spec erase_tree_nodes(BB :: blackboard()) -> UpBB :: blackboard().
erase_tree_nodes(BB) ->
BB#blackboard{global_maps = #{}}.
%% @doc
%% 获取行为树所有节点信息
get_global_maps(#blackboard{global_maps = GlobalMaps}) ->
GlobalMaps.
%% @doc
%% 设置IO
%% 可用于重定向调试日志输出位置,默认erlang:group_leader()
-spec set_io(IO :: io:device(), BB :: blackboard()) -> UpBB :: blackboard().
set_io(IO, BB) ->
BB#blackboard{io = IO}.
%% @doc
%% 获取IO
-spec get_io(BB :: blackboard()) -> IO :: io:device().
get_io(#blackboard{io = IO}) ->
IO.
%%--------------------------------------------------------------------
%% Internal functions
%%--------------------------------------------------------------------