%%% -------------------------------------------------------
%%% @author huangyongxing@yeah.net
%%% @doc
%%% 一些调试辅助接口
%%%
%%% 严重警告：相关接口不可用于正式业务
%%% @end
%%% @since 2020-08-01
%%% -------------------------------------------------------
-module(gm_util).
-export([
        gm_role_replace_state/2
        ,gm_role_do/2
        ,gm_role_do_state/2

        ,gm_scene_do/2
        ,gm_scene_do/3

        ,gm_scene_call/2
        ,gm_scene_call/3
    ]).

-include("server.hrl").


%% -------------------------------------------------------
%% 调用角色进程执行某任务，并可打印指定资料
%% 主要用于必须角色进程才方便调试打印的一些信息打印或接口调用
%% -------------------------------------------------------

%% 角色进程执行指定Func，并完成状态替换
%% 仅限GM使用，不可滥用
gm_role_replace_state(RoleId, Func) when is_integer(RoleId) ->
    Pid = misc:get_player_process(RoleId),
    gm_role_replace_state(Pid, Func);
gm_role_replace_state(Pid, Func) when is_pid(Pid) ->
    NewFun = fun(PS) ->
            NewPS = Func(PS),
            case is_record(NewPS, player_status) of
                true  -> NewPS;
                false -> PS
            end
    end,
    %% proc_replace_state会替换group leader，将输出打印到当前调用终端
    dev_tool:proc_replace_state(Pid, NewFun);
gm_role_replace_state(_, _) ->
    error.

%% 角色进程执行Func
%% Func为0个参数的function.
gm_role_do(RoleId, Func) when is_integer(RoleId) ->
    Pid = misc:get_player_process(RoleId),
    gm_role_do(Pid, Func);
gm_role_do(Pid, Func) when is_pid(Pid) ->
    dev_tool:proc_do(Pid, Func).

%% 角色进程执行Func【带ProcState为函数参数】
%% Func为1个参数的function，该参数为otp进程的State数据
gm_role_do_state(RoleId, Func) when is_integer(RoleId) ->
    Pid = misc:get_player_process(RoleId),
    gm_role_do_state(Pid, Func);
gm_role_do_state(Pid, Func) when is_pid(Pid) ->
    dev_tool:proc_do_state(Pid, Func).

%% -------------------------------------------------------

%% 场景进程执行指定的函数
gm_scene_do(ScenePid, Func) when is_pid(ScenePid) ->
    dev_tool:proc_do(ScenePid, Func).

%% 场景进程执行指定的函数
gm_scene_do(SceneId, PoolId, Func) ->
    case dev_tool:find_scene_pid(SceneId, PoolId) of
        undefined ->    % 场景未创建
            undefined;
        clusters ->
            clusters_node:apply_cast(
                ?MODULE, gm_scene_do, [SceneId, PoolId, Func]
            );
        Pid ->
            gm_scene_do(Pid, Func)
    end.

%% 场景进程执行指定的函数，返回执行结果【不改变进程原ProcState数据】
gm_scene_call(ScenePid, Func) when is_pid(ScenePid) ->
    dev_tool:proc_call(ScenePid, Func).

gm_scene_call(SceneId, PoolId, Func) ->
    case mod_scene_agent:find_scene_pid(SceneId, PoolId) of
        undefined ->    % 场景未创建
            {error, scene_pid_undefined};
        clusters ->
            clusters_node:apply_call(?MODULE, gm_scene_call, [SceneId, PoolId, Func]);
        Pid ->
            gm_scene_call(Pid, Func)
    end.

