• TL中使用Lua脚本的过程 脚本中的Timer过程


    1.首先在c++源码中添加需要注册到Lua的函数

    INT LuaFnSetTimer(Lua_State* L)
    {
    LUA_ENTER_FUNCTION
    
    SceneID_t sceneId = Lua_ValueToNumber(L,1);
    ObjID_t selfId = Lua_ValueToNumber(L,2);
    ScriptID_t scriptId = Lua_ValueToNumber(L,3);
    const CHAR* funcName = Lua_ValueToString(L,4);
    INT tickTime = Lua_ValueToNumber(L,5);
    
    BEGINHUMANDEFINE(“LuaFnSetTimer”)
    if(pHuman->GetUseTimerCount() < pHuman->GetMaxTimerCount())
    {
    INT sceneTimerIndex = pScene->GetSceneTimer()->GetTimer();
    AssertEx(sceneTimerIndex>=0 && sceneTimerIndex < g_Config.m_ConfigInfo.m_MaxTimerCount,”No Timer resource for allocate”);
    
    if(sceneTimerIndex>=0 && sceneTimerIndex < g_Config.m_ConfigInfo.m_MaxTimerCount)
    {
    pHuman->AddTimer(sceneTimerIndex);
    pScene->GetSceneTimer()->StartTheTimer(sceneTimerIndex,selfId,scriptId,funcName,tickTime);
    
    Lua_PushNumber(L,sceneTimerIndex);
    return 1;
    }
    }
    ENDHUMANDEFINE
    
    RETURNFALSE
    
    LUA_LEAVE_FUNCTION
    RETURNFALSE
    }

    2.然后将函数注册进Lua中

    // 定义Lua注册通用的函数指针
    
    typedef INT (*FuncProto)(Lua_State * L);
    
    // 定义工具结构
    
    struct _Str2Func
    {
    CHAR* funcname;
    FuncProto proto;
    };
    
    // 像这样定义中间结构
    
    struct _Str2Func functbl[] =
    {
    {“AddEventList”,FuncProto(LuaFnAddNumText)},
    {“GetMission”, FuncProto(LuaFnGetMission)},
    
    {“CityMoveTo”, FuncProto(LuaFnCityMoveTo)},
    };
    }
    
    // 像这样进行 使用FireFox的Lua引擎进行 函数注册
    
    for(INT i=0; i<sizeof(LuaFnTbl::functbl)/sizeof(_Str2Func); i++)
    {
    mLua.RegisterFunction(LuaFnTbl::functbl[i].funcname,(VOID*)(LuaFnTbl::functbl[i].proto));
    }
    
     

    3.开始使用定时器

    // 然后脚本设置一个定时器 5个参数见函数定义 需要传人函数名
    
    LuaFnSetTimer(1,2,3,4,5);

    4.定时器实现

    //  调用服务器中的定时器 以下是定义

    class CMyTimer
    {
    private:
    UINT m_uTickTerm;
    UINT m_uTickOld;
    
    public:
    BOOL m_bOper;
    
    public:
    CMyTimer()
    {
    CleanUp() ;
    }
    
    BOOL IsSetTimer( ){ return m_bOper ; }
    
    VOID SetTermTime( UINT uTerm ){ m_uTickTerm =uTerm; }
    UINT GetTermTime( ){ return m_uTickTerm ; }
    
    UINT GetTickOldTime( ){ return m_uTickOld; }
    
    VOID CleanUp( )
    {
    m_uTickTerm = 0 ;
    m_bOper = FALSE ;
    m_uTickOld = 0 ;
    }
    
    VOID BeginTimer(UINT uTerm, UINT uNow)
    {
    m_bOper = TRUE;
    m_uTickTerm =uTerm;
    m_uTickOld =uNow;
    }
    
    BOOL CountingTimer(UINT uNow)
    {
    if(!m_bOper)
    return FALSE;
    
    UINT uNew =uNow;
    
    if(uNew<m_uTickOld+m_uTickTerm )
    return FALSE;
    
    m_uTickOld =uNew;
    
    return TRUE;
    }
    UINT GetLeaveTime(UINT uNow)//剩余时间;
    {
    if(!CountingTimer(uNow))
    {
    return m_uTickTerm+m_uTickOld-uNow;
    }
    return 0;
    }
    };
    
    // 场景定时器
    
    =================
    class SceneTimer
    {
    public:
    CMyTimer   mRefeshTimer;
    #define FuncNameLen 32
    
    typedef struct  _MyTimers
    {
    CHAR scriptFuncName[FuncNameLen];
    
    INT selfId;
    INT scriptId;
    
    CMyTimer timer;
    }MyTimer;
    
    MyTimer* m_pTimers;
    MyTimer* head;
    INT index;
    INT maxCount;
    Scene* m_pScene;
    
    //仅测试
    #if _DEBUG
    INT m_currentUse;
    #endif
    SceneTimer();
    
    ~SceneTimer();
    
    VOID CleanUp() ;
    
    BOOL IsInit()
    {
    if( m_pScene==NULL ) return FALSE ;
    else return TRUE ;
    };
    
    VOID CreateTimer(INT maxCount,Scene* pScene);
    
    VOID InitOne(INT i);
    
    INT GetTimer();
    
    VOID StartTheTimer(INT sceneTimerIndex,INT selfId,INT scriptId,const CHAR* funcName,INT tickTime);
    
    VOID FreeTimer(INT index);
    
    BOOL CheckTimer(INT index);
    
    VOID OnTimer(UINT uTime);
    
    Scene* GetScene()
    {
    return m_pScene;
    }
    };
    
     
    
    //每个场景有一个线程来做处理  *备注 每个:”=====->”  都表示进入下一个函数调用
    // 以下给出调用过程
    
    VOID SceneThread::run( )===== ->
    
    BOOL ret = m_apScene[i]->Tick( ) ; =====->
    
    ret = HeartBeat( ) ;===== ->
    
    m_pSceneTimers->OnTimer(uTime);->检查定时器是否触发<-=====–>
    
    GetScene()->GetLuaInterface()->ExeScript_DDDD(
    m_pTimers[i].scriptId,
    m_pTimers[i].scriptFuncName,
    (INT)GetScene()->SceneID(),
    (INT)m_pTimers[i].selfId,
    (INT)i,
    (INT)0 ) ; =====->

    1.依据数据组装出函数名

    2.return ExeFile_DDDD(filename,funcnameX,Param0,Param1,Param2,Param3,bLoad);=====->

    bRet = mLua.CallFunction( funcname, 1, “dddd”, Param0, Param1, Param2, Param3 ) ;

    到这里一个定时器就过程就算完成

  • 相关阅读:
    moment.js常用时间示例,时间管理
    RabbitMQ用户增删及权限控制
    CDN概念基本介绍
    在LinkedIn的 Kafka 生态系统
    发行说明
    Kafka 1.0版本发布
    redis应用场景及实例
    Redis哨兵集群
    redis-订阅与发布
    redis事务
  • 原文地址:https://www.cnblogs.com/dieangel/p/3326937.html
Copyright © 2020-2023  润新知