mirror of
https://github.com/ENSL/NS.git
synced 2024-12-12 05:32:00 +00:00
164 lines
4.1 KiB
C++
164 lines
4.1 KiB
C++
|
extern "C" {
|
||
|
#include <lua.h>
|
||
|
#include <lualib.h>
|
||
|
#include <lauxlib.h>
|
||
|
}
|
||
|
#include "scriptengine/AvHLUA.h"
|
||
|
#include "scriptengine/AvHLUAUtil.h"
|
||
|
|
||
|
#ifdef AVH_CLIENT
|
||
|
extern double gClientTimeLastUpdate;
|
||
|
#endif
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
static int AvHLUATime_Now(lua_State *L)
|
||
|
{
|
||
|
#ifdef AVH_SERVER
|
||
|
float now = gpGlobals->time;
|
||
|
#else
|
||
|
float now = gClientTimeLastUpdate;
|
||
|
#endif
|
||
|
|
||
|
lua_pushnumber(L, (float)(now));
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
static int AvHLUATime_Sleep(lua_State *L)
|
||
|
{
|
||
|
float sleeptime = (float)(luaL_checknumber(L, 1));
|
||
|
if (sleeptime > 0)
|
||
|
{
|
||
|
return gLUA->Suspend(L, sleeptime);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return gLUA->Suspend(L, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
static int AvHLUATime_At(lua_State *L)
|
||
|
{
|
||
|
float time = (float)(luaL_checknumber(L, 1));
|
||
|
luaL_checktype(L, 2, LUA_TSTRING);
|
||
|
|
||
|
gLUA->DelayedExecute(L, time);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
static const luaL_reg meta_methods [] = {
|
||
|
{0,0}
|
||
|
};
|
||
|
|
||
|
static const luaL_reg time_methods [] = {
|
||
|
{"Now", AvHLUATime_Now},
|
||
|
{"Sleep", AvHLUATime_Sleep},
|
||
|
{"At", AvHLUATime_At},
|
||
|
{0,0}
|
||
|
};
|
||
|
|
||
|
void AvHLUA::RegisterNamespace_Time()
|
||
|
{
|
||
|
UTIL_LUARegisterObject(this->mGlobalContext, time_methods, meta_methods, "Time");
|
||
|
}
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
int AvHLUA::DelayedExecute(lua_State *L, float time)
|
||
|
{
|
||
|
int args = lua_gettop(L) - 2;
|
||
|
lua_State *threadContext = lua_newthread(L);
|
||
|
lua_getglobal(threadContext, lua_tostring(L, 2));
|
||
|
|
||
|
if (args > 0)
|
||
|
{
|
||
|
lua_xmove(L, threadContext, args + 1);
|
||
|
lua_pop(threadContext, 1);
|
||
|
}
|
||
|
|
||
|
this->mTimetable.insert(pair<float, LUATimetableCallbackType>((float)(time), LUATimetableCallbackType(args, threadContext)));
|
||
|
|
||
|
LUATimetableType::iterator firstCall = this->mTimetable.begin();
|
||
|
this->mNextCallTime = (float)((*firstCall).first);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
int AvHLUA::Suspend(lua_State *L, float delay)
|
||
|
{
|
||
|
#ifdef AVH_SERVER
|
||
|
float now = gpGlobals->time;
|
||
|
#else
|
||
|
float now = gClientTimeLastUpdate;
|
||
|
#endif
|
||
|
this->mTimetable.insert(pair<float, LUATimetableCallbackType>((float)(now + delay), LUATimetableCallbackType(0, L)));
|
||
|
|
||
|
LUATimetableType::iterator firstCall = this->mTimetable.begin();
|
||
|
this->mNextCallTime = (float)((*firstCall).first);
|
||
|
|
||
|
return (lua_yield(L, 0));
|
||
|
}
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
int AvHLUA::Resume(lua_State *L, int numargs)
|
||
|
{
|
||
|
int errorcode = lua_resume(L, numargs);
|
||
|
if (errorcode)
|
||
|
{
|
||
|
AvHLUA_OnError(lua_tostring(L, -1));
|
||
|
}
|
||
|
return errorcode;
|
||
|
}
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
bool AvHLUA::ExecuteCallbacks(float time)
|
||
|
{
|
||
|
if (time < this->mNextCallTime)
|
||
|
return false;
|
||
|
|
||
|
LUATimetableType::iterator TimetableStart = this->mTimetable.begin();
|
||
|
LUATimetableType::iterator TimetableEnd = this->mTimetable.end();
|
||
|
|
||
|
list<LUATimetableType::iterator> eraseList;
|
||
|
|
||
|
LUATimetableType::iterator current = TimetableStart;
|
||
|
while (current != TimetableEnd)
|
||
|
{
|
||
|
float calltime = (float)((*current).first);
|
||
|
if (calltime < time)
|
||
|
{
|
||
|
LUATimetableCallbackType callbackfunc = (*current).second;
|
||
|
int numargs = callbackfunc.first;
|
||
|
lua_State *L = callbackfunc.second;
|
||
|
this->Resume(L, numargs);
|
||
|
|
||
|
eraseList.push_back(current);
|
||
|
|
||
|
current++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->mNextCallTime = calltime;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (current == TimetableEnd)
|
||
|
{
|
||
|
#ifdef AVH_SERVER
|
||
|
this->mNextCallTime = gpGlobals->time + 99999;
|
||
|
#else
|
||
|
this->mNextCallTime = gClientTimeLastUpdate + 99999;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
while (eraseList.size() > 0)
|
||
|
{
|
||
|
LUATimetableType::iterator toErase = eraseList.front();
|
||
|
this->mTimetable.erase(toErase);
|
||
|
eraseList.pop_front();
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|