effil/src/cpp/lua-helpers.cpp
2017-06-11 17:13:48 +03:00

63 lines
2.0 KiB
C++

#include "lua-helpers.h"
namespace effil {
namespace
{
std::string luaError(int errCode)
{
switch(errCode)
{
case LUA_ERRSYNTAX: return "Invalid syntax (LUA_ERRSYNTAX)";
case LUA_ERRMEM: return "Memory allocation error (LUA_ERRMEM)";
case LUA_ERRRUN: return "Execution error (LUA_ERRRUN)";
case LUA_ERRGCMM: return "Error in __gc method (LUA_ERRGCMM)";
case LUA_ERRERR: return "Recursive error (LUA_ERRERR)";
default: return "Unknown";
}
}
int dumpMemoryWriter(lua_State*, const void* batch, size_t batchSize, void* storage) {
if (storage == nullptr || batch == nullptr)
return 1;
if (batchSize) {
std::string& buff = *reinterpret_cast<std::string*>(storage);
const char* newData = reinterpret_cast<const char*>(batch);
buff.insert(buff.end(), newData, newData + batchSize);
}
return 0;
}
}
std::string dumpFunction(const sol::function& f) {
sol::state_view lua(f.lua_state());
sol::stack::push(lua, f);
std::string result;
int ret = lua_dump(lua, dumpMemoryWriter, &result);
REQUIRE(ret == LUA_OK) << "Unable to dump Lua function: " << luaError(ret);
sol::stack::remove(lua, -1, 1);
return result;
}
sol::function loadString(const sol::state_view& lua, const std::string& str) {
int ret = luaL_loadbuffer(lua, str.c_str(), str.size(), nullptr);
REQUIRE(ret == LUA_OK) << "Unable to load function from string: " << luaError(ret);
return sol::stack::pop<sol::function>(lua);
}
std::chrono::milliseconds fromLuaTime(int duration, const sol::optional<std::string>& period) {
using namespace std::chrono;
REQUIRE(duration >= 0) << "Invalid duration interval: " << duration;
std::string metric = period ? period.value() : "s";
if (metric == "ms") return milliseconds(duration);
else if (metric == "s") return seconds(duration);
else if (metric == "m") return minutes(duration);
else throw sol::error("invalid time identification: " + metric);
}
} // namespace effil