Files
fs2open.github.com/code/scripting/lua/LuaConvert.cpp
T
asarium 48b03a1789 Remove ADE signature from scripting API
This was previously used for allowing scripts to set arbitrary values on
scripting objects. However, it was used by only a few scripting
functions and, as far as I know, no script uses this features.

This removes that feature which simplifies the code ade_index_handler
of.

This also simplifies the code that handles the userdata for libraries
provided by FSO.
2018-11-18 12:43:39 +01:00

203 lines
4.8 KiB
C++

#include "LuaConvert.h"
namespace luacpp {
namespace convert {
namespace internal {
bool isValidIndex(lua_State* state, int index) {
if (1 <= std::abs(index) && std::abs(index) <= lua_gettop(state)) {
return true;
} else {
return false;
}
}
}
void pushValue(lua_State* luaState, const double& value) {
lua_pushnumber(luaState, value);
}
void pushValue(lua_State* luaState, const float& value) {
lua_pushnumber(luaState, value);
}
void pushValue(lua_State* luaState, const int& value) {
lua_pushnumber(luaState, value);
}
void pushValue(lua_State* luaState, const size_t& value) {
lua_pushnumber(luaState, (lua_Number)value);
}
void pushValue(lua_State* luaState, const std::string& value) {
lua_pushlstring(luaState, value.c_str(), value.size());
}
void pushValue(lua_State* luaState, const char* value) {
lua_pushstring(luaState, value);
}
void pushValue(lua_State* luaState, const bool& value) {
lua_pushboolean(luaState, value);
}
void pushValue(lua_State* luaState, const lua_CFunction& value) {
lua_pushcfunction(luaState, value);
}
void pushValue(lua_State* L, const scripting::ade_odata& od)
{
using namespace scripting;
//WMC - char must be 1 byte, foo.
static_assert(sizeof(char) == 1, "char must be 1 byte!");
//WMC - step by step
//Create new LUA object and get handle
char *newod = (char*)lua_newuserdata(L, od.size);
//Create or get object metatable
luaL_getmetatable(L, ::scripting::internal::getTableEntry(od.idx).Name);
//Set the metatable for the object
lua_setmetatable(L, -2);
//Copy the actual object data to the Lua object
memcpy(newod, od.buf, od.size);
}
bool popValue(lua_State* luaState, int& target, int stackposition, bool remove) {
double temp;
auto ret = popValue(luaState, temp, stackposition, remove);
if (ret) {
target = (int)temp;
}
return ret;
}
bool popValue(lua_State* luaState, size_t& target, int stackposition, bool remove) {
double temp;
auto ret = popValue(luaState, temp, stackposition, remove);
if (ret) {
target = (size_t)temp;
}
return ret;
}
bool popValue(lua_State* luaState, float& target, int stackposition, bool remove) {
double temp;
auto ret = popValue(luaState, temp, stackposition, remove);
if (ret) {
target = (float)temp;
}
return ret;
}
bool popValue(lua_State* luaState, double& target, int stackposition, bool remove) {
if (!internal::isValidIndex(luaState, stackposition)) {
return false;
}
if (!lua_isnumber(luaState, stackposition)) {
return false;
} else {
target = lua_tonumber(luaState, stackposition);
if (remove) {
lua_remove(luaState, stackposition);
}
return true;
}
}
bool popValue(lua_State* luaState, std::string& target, int stackposition, bool remove) {
if (!internal::isValidIndex(luaState, stackposition)) {
return false;
}
if (!lua_isstring(luaState, stackposition)) {
return false;
} else {
size_t size;
const char* string = lua_tolstring(luaState, stackposition, &size);
target.assign(string, size);
if (remove) {
lua_remove(luaState, stackposition);
}
return true;
}
}
bool popValue(lua_State* luaState, bool& target, int stackposition, bool remove) {
if (!internal::isValidIndex(luaState, stackposition)) {
return false;
}
if (!lua_isboolean(luaState, stackposition)) {
return false;
} else {
target = lua_toboolean(luaState, stackposition) != 0;
if (remove) {
lua_remove(luaState, stackposition);
}
return true;
}
}
bool popValue(lua_State* luaState, lua_CFunction& target, int stackposition, bool remove) {
if (!internal::isValidIndex(luaState, stackposition)) {
return false;
}
if (!lua_iscfunction(luaState, stackposition)) {
return false;
} else {
target = lua_tocfunction(luaState, stackposition);
if (remove) {
lua_remove(luaState, stackposition);
}
return true;
}
}
bool popValue(lua_State* L, scripting::ade_odata& od, int stackposition, bool remove) {
//WMC - Get metatable
lua_getmetatable(L, stackposition);
int mtb_ldx = lua_gettop(L);
Assert(!lua_isnil(L, -1));
//Get ID
lua_pushstring(L, "__adeid");
lua_rawget(L, mtb_ldx);
if (lua_tonumber(L, -1) != od.idx)
{
lua_pushstring(L, "__adederivid");
lua_rawget(L, mtb_ldx);
if ((uint)lua_tonumber(L, -1) != od.idx)
{
// Issue the LuaError here since this is the only place where we have all relevant information
LuaError(L, "Argument %d is the wrong type of userdata; '%s' given, but '%s' expected", stackposition,
::scripting::internal::getTableEntry((uint)lua_tonumber(L, -2)).Name,
::scripting::internal::getTableEntry(od.idx).GetName());
return false;
}
lua_pop(L, 1);
}
lua_pop(L, 2);
if (od.size != scripting::ODATA_PTR_SIZE) {
memcpy(od.buf, lua_touserdata(L, stackposition), od.size);
}
else {
(*(void**)od.buf) = lua_touserdata(L, stackposition);
}
if (remove) {
lua_remove(L, stackposition);
}
return true;
}
}
}