Erlang中是不建议用进程字典的,但进程字典是数据存取最快的方式,对于游戏这种高性能要求的应用,进程字典是不二的选择。使用进程字典时要切记在对应的进程中操作,最好按功能把put,get操作封装到模块接口中,避免误用。
作为自身状态的一部分,每个进程都有一个私有的进程字典(换句话说每个进程字典只供它所属的进程调用,其他进程调用不了,进程字典的key和value没有特定的关系),这是一个可以用任何值作为键的简单哈希表,用于存储Erlang项式。通过内置函数put( Key,Value)和get( Key)可以从中存取项式。
put( Key,Val ) -> OldVal | underfined
在进程字典里添加一个与值 Val 关联的新键 Key,并返回 undefined,如果键已经存在,则旧的值会被删除并被替换成 Val,最后函数返回旧的值。
get() -> [ { Key,Val}]
以一个{ Key,Val } 元组列表的形式返回进程里的所有字典值
get( Key ) -> Val | undefined
在进程字典里获取一个跟键Key相关的值Val,如果这个键不存在,则返回undefined。
erase() -> [{ Key,Val}]
返回所有进程字典数据并删除之
erase(Key) -> Val | undefined
获取并清除进程字典里跟键Key所对应的值,如果进程字典里没有跟键相关联的值,则返回undefined。
例如:
%%定义宏
-define(DIC_ROLE_ITEMS,dic_role_item).
%%初始化RoleItemList,在此进程初始化的时候调用
init_role_item(RoleId) ->
RoleItemList = [list_to_tuple([ets_role_item | X]) || X <- db_agent_item:get_role_item_by_roleid(RoleId)],
update_role_item_list(RoleItemList).
%%更新DIC_ROLE_ITEMS进程字典
update_role_item_list(RoleItemList) ->
put(?DIC_ROLE_ITEMS,List).
%%获取进程字典的数据
get_roleitemlist() ->
case get(?DIC_ROLE_ITEMS) of
undefined ->
[];
List when is_list(List) ->
List;
_ ->
[]
end.
%% 处理用户离线
role_offline() ->
erase(?DIC_ROLE_ITEMS).
%%更新内存中道具信息
update_role_item_info(RoleItemInfo) ->
case is_record(RoleItemInfo,ets_role_equip) of
true ->
List = get_roleitemlist(),
List1 =
case lists:keyfind(RoleItemInfo#ets_role_item.role_itemId,#ets_role_item.role_itemId,List) of
false ->
List ++ [RoleItemInfo];
_ ->
lists:keyreplace(RoleItemInfo#ets_role_item.roleItemId,#ets_role_item.roleItemId,List,RoleItemInfo)
end,
update_role_item_list(List1);
false ->
?WARNING_MSG("RoleItemInfo is not record:~p~n",[RoleItemInfo])
end.
%%删除内存中指定道具的信息
delete_role_item_info(RoleItemId) ->
case get_roleitemlist() of
[] ->
skip;
RoleItemList ->
NewRoleItemList = lists:keydelete(RoleItemId,#ets_role_item.roleItemId,RoleItemList),
update_role_item_list(NewRoleItemList)
end.