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 ) ;
到这里一个定时器就过程就算完成
原文链接: https://www.cnblogs.com/dieangel/archive/2012/08/21/3326937.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/60475
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!