/*
文件名:TimerClass.nut
路径:Dps_A/BaseClass/TimerClass/TimerClass.nut
创建日期:2024-09-19	12:39
文件用途:定时器类
*/
class Timer {
    //执行任务队列树
    Wait_Exec_Tree = null;
    //定时执行任务队列树
    Date_Exec_Tree = null;

    constructor() {
        Wait_Exec_Tree = RedBlackTree();
        Date_Exec_Tree = RedBlackTree();

        Cb_timer_dispatch_Func.rawset("__System__Timer__Event", Update.bindenv(this));
    }

    function ClockTime() {
        return Sq_GetTimestampString().slice(-10).tointeger();
    }

    //检测延时任务
    function CheckTimeOut() {
        local Node = Wait_Exec_Tree.GetPop();
        if (!Node) {
            return;
        }
        //取得函数体
        local Info = Node.Info;
        //执行时间
        local exec_time = Node.time;
        //如果没到执行时间，就不管
        if (ClockTime() <= exec_time) {
            return;
        }
        //该执行了从树中删除这个元素
        Wait_Exec_Tree.pop();

        //函数
        local func = Info[0];
        //参数
        local func_args = Info[1];
        //执行函数
        func.acall(func_args);
    }

    function SetTimeOut(target_func, delay_time, ...) {
        local target_arg_list = [];
        target_arg_list.push(getroottable());
        for (local i = 0; i< vargv.len(); i++) {
            target_arg_list.push(vargv[i]);
        }
        //当前时间戳，单位：秒
        local time_sec = ClockTime();
        //计算下一次执行的时间
        local exec_time_sec = time_sec + delay_time;
        //设置下一次执行
        local func_info = [];

        func_info.push(target_func);
        func_info.push(target_arg_list);

        _Timer_Object.Wait_Exec_Tree.insert(exec_time_sec, func_info);
    }

    //检测定时任务
    function CheckCronTask() {
        local Node = Date_Exec_Tree.GetPop();
        if (!Node) {
            return;
        }
        //取得函数体
        local Info = Node.Info;
        //执行时间
        local exec_time = Node.time;
        //如果没到执行时间，放回去，等待下次扫描
        if (time() <= exec_time) {
            // Date_Exec_Tree.insert(exec_time, Node.Info);
            return;
        }
        Date_Exec_Tree.pop();
        //函数
        local func = Info[0];
        //参数
        local func_args = Info[1];
        //Cron字符串
        local NextTimestep = Info[2];
        //执行函数
        func.acall(func_args);
        //继续构建下一次任务
        Date_Exec_Tree.insert(Sq_Cron_Next(NextTimestep, time()), Info);
    }

    function SetCronTask(target_func, CronString, ...) {
        local NowTimestep = time();

        //下一次执行的时间
        local NextTimestep = Sq_Cron_Next(CronString, NowTimestep);

        local target_arg_list = [];
        target_arg_list.push(getroottable());
        for (local i = 0; i< vargv.len(); i++) {
            target_arg_list.push(vargv[i]);
        }

        //设置下一次执行
        local func_info = [];

        //函数体
        func_info.push(target_func);
        //参数列表
        func_info.push(target_arg_list);
        //间隔时间戳时间
        func_info.push(CronString);

        _Timer_Object.Date_Exec_Tree.insert(NextTimestep, func_info);
    }


    function Update() {
        CheckTimeOut();
        CheckCronTask();
    }
}