/*
* PtokaX - hub server for Direct Connect peer to peer network.
* Copyright (C) 2004-2022 Petr Kozelka, PPK at PtokaX dot org
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3
* as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
#include "stdinc.h"
//---------------------------------------------------------------------------
#include "LuaInc.h"
//---------------------------------------------------------------------------
#include "LuaTmrManLib.h"
//---------------------------------------------------------------------------
#include "LuaScriptManager.h"
#include "ServerManager.h"
#include "utility.h"
#include "GlobalDataQueue.h"
//---------------------------------------------------------------------------
#ifdef _WIN32
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
#include "LuaScript.h"
#include "GlobalDataQueue.h"
//---------------------------------------------------------------------------
static int AddTimer(lua_State * pLua)
{
GlobalDataQueue::m_Ptr->PrometheusLuaInc(__func__);
Script * cur = ScriptManager::m_Ptr->FindScript(pLua);
if (cur == NULL)
{
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
int n = lua_gettop(pLua);
size_t szLen = 0;
const char * sFunctionName = nullptr;
int iRef = 0;
if (n == 2)
{
if (lua_type(pLua, 1) != LUA_TNUMBER)
{
luaL_checktype(pLua, 1, LUA_TNUMBER);
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
if (lua_type(pLua, 2) == LUA_TSTRING)
{
sFunctionName = lua_tolstring(pLua, 2, &szLen);
if (szLen == 0)
{
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
}
else if (lua_type(pLua, 2) == LUA_TFUNCTION)
{
iRef = luaL_ref(pLua, LUA_REGISTRYINDEX);
}
else
{
luaL_error(pLua, "bad argument #2 to 'AddTimer' (string or function expected, got %s)", lua_typename(pLua, lua_type(pLua, 2)));
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
}
else if (n == 1)
{
if (lua_type(pLua, 1) != LUA_TNUMBER)
{
luaL_checktype(pLua, 1, LUA_TNUMBER);
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
sFunctionName = ScriptTimer::m_sDefaultTimerFunc;
}
else
{
luaL_error(pLua, "bad argument count to 'AddTimer' (1 or 2 expected, got %d)", lua_gettop(pLua));
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
if (sFunctionName != NULL)
{
lua_getglobal(pLua, sFunctionName);
int i = lua_gettop(pLua);
if (lua_isfunction(pLua, i) == 0)
{
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
}
#if defined(_WIN32) && !defined(_WIN_IOT)
#if LUA_VERSION_NUM < 503
UINT_PTR timer = SetTimer(NULL, 0, (UINT)lua_tonumber(pLua, 1), NULL);
#else
UINT_PTR timer = SetTimer(NULL, 0, (UINT)lua_tointeger(pLua, 1), NULL);
#endif
if (timer == 0)
{
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
ScriptTimer * pNewtimer = ScriptTimer::CreateScriptTimer(timer, sFunctionName, szLen, iRef, cur->m_pLua);
#else
ScriptTimer * pNewtimer = ScriptTimer::CreateScriptTimer(sFunctionName, szLen, iRef, cur->m_pLua);
#endif
if (pNewtimer == NULL)
{
#if defined(_WIN32) && !defined(_WIN_IOT)
KillTimer(NULL, timer);
#endif
AppendDebugLog("%s - [MEM] Cannot allocate pNewtimer in TmrMan.AddTimer\n");
lua_settop(pLua, 0);
lua_pushnil(pLua);
return 1;
}
#if !defined(_WIN32) || (defined(_WIN32) && defined(_WIN_IOT))
#if LUA_VERSION_NUM < 503
pNewtimer->m_ui64Interval = (uint64_t)lua_tonumber(pLua, 1);// ms
#else
pNewtimer->m_ui64Interval = (uint64_t)lua_tointeger(pLua, 1);// ms
#endif
#ifdef __MACH__
mach_timespec_t mts;
clock_get_time(ServerManager::m_csMachClock, &mts);
pNewtimer->m_ui64LastTick = (uint64_t(mts.tv_sec) * 1000) + (uint64_t(mts.tv_nsec) / 1000000);
#elif _WIN32
pNewtimer->m_ui64LastTick = ::GetTickCount64();
#else
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
pNewtimer->m_ui64LastTick = (uint64_t(ts.tv_sec) * 1000) + (uint64_t(ts.tv_nsec) / 1000000);
#endif
#endif
lua_settop(pLua, 0);
#if defined(_WIN32) && !defined(_WIN_IOT)
lua_pushlightuserdata(pLua, (void *)pNewtimer->m_uiTimerId);
#else
lua_pushlightuserdata(pLua, (void *)pNewtimer);
#endif
if (ScriptManager::m_Ptr->m_pTimerListS == NULL)
{
ScriptManager::m_Ptr->m_pTimerListS = pNewtimer;
ScriptManager::m_Ptr->m_pTimerListE = pNewtimer;
}
else
{
pNewtimer->m_pPrev = ScriptManager::m_Ptr->m_pTimerListE;
ScriptManager::m_Ptr->m_pTimerListE->m_pNext = pNewtimer;
ScriptManager::m_Ptr->m_pTimerListE = pNewtimer;
}
return 1;
}
//------------------------------------------------------------------------------
static int RemoveTimer(lua_State * pLua)
{
GlobalDataQueue::m_Ptr->PrometheusLuaInc(__func__);
if (lua_gettop(pLua) != 1)
{
luaL_error(pLua, "bad argument count to 'RemoveTimer' (1 expected, got %d)", lua_gettop(pLua));
lua_settop(pLua, 0);
return 0;
}
if (lua_type(pLua, 1) != LUA_TLIGHTUSERDATA)
{
luaL_checktype(pLua, 1, LUA_TLIGHTUSERDATA);
lua_settop(pLua, 0);
return 0;
}
Script * cur = ScriptManager::m_Ptr->FindScript(pLua);
if (cur == NULL)
{
lua_settop(pLua, 0);
return 0;
}
#if defined(_WIN32) && !defined(_WIN_IOT)
UINT_PTR timer = (UINT_PTR)lua_touserdata(pLua, 1);
#else
ScriptTimer * timer = reinterpret_cast<ScriptTimer *>(lua_touserdata(pLua, 1));
#endif
ScriptTimer * pCurTmr = NULL,
* pNextTmr = ScriptManager::m_Ptr->m_pTimerListS;
while (pNextTmr != NULL)
{
pCurTmr = pNextTmr;
pNextTmr = pCurTmr->m_pNext;
#if defined(_WIN32) && !defined(_WIN_IOT)
if (pCurTmr->m_uiTimerId == timer)
{
KillTimer(NULL, pCurTmr->m_uiTimerId);
#else
if (pCurTmr == timer)
{
#endif
if (pCurTmr->m_pPrev == NULL)
{
if (pCurTmr->m_pNext == NULL)
{
ScriptManager::m_Ptr->m_pTimerListS = NULL;
ScriptManager::m_Ptr->m_pTimerListE = NULL;
}
else
{
ScriptManager::m_Ptr->m_pTimerListS = pCurTmr->m_pNext;
ScriptManager::m_Ptr->m_pTimerListS->m_pPrev = NULL;
}
}
else if (pCurTmr->m_pNext == NULL)
{
ScriptManager::m_Ptr->m_pTimerListE = pCurTmr->m_pPrev;
ScriptManager::m_Ptr->m_pTimerListE->m_pNext = NULL;
}
else
{
pCurTmr->m_pPrev->m_pNext = pCurTmr->m_pNext;
pCurTmr->m_pNext->m_pPrev = pCurTmr->m_pPrev;
}
if (pCurTmr->m_sFunctionName == NULL)
{
luaL_unref(pLua, LUA_REGISTRYINDEX, pCurTmr->m_iFunctionRef);
}
delete pCurTmr;
break;
}
}
lua_settop(pLua, 0);
return 0;
}
//------------------------------------------------------------------------------
static const luaL_Reg TmrManRegs[] =
{
{ "AddTimer", AddTimer },
{ "RemoveTimer", RemoveTimer },
{ NULL, NULL }
};
//---------------------------------------------------------------------------
#if LUA_VERSION_NUM > 501
int RegTmrMan(lua_State * pLua)
{
luaL_newlib(pLua, TmrManRegs);
return 1;
#else
void RegTmrMan(lua_State * pLua)
{
luaL_register(pLua, "TmrMan", TmrManRegs);
#endif
}
//---------------------------------------------------------------------------
↑ V1042 This file is marked with copyleft license, which requires you to open the derived source code.