Files
fs2open.github.com/code/scripting/lua/LuaValue.cpp
T
asarium f780d9e22a Add ability to dynamically add new SEXPs at runtime
This add a system for adding generic instances of the DynamicSEXP class
to the SEXP system. The only implementation at the moment is the LuaSEXP
which is used by the mn.addSEXP lua API to allow Lua to add new SEXPs.

Since this requires that FRED also runs lua scripts I added a mod table
option to enable scripting in FRED. Since the current scripts are not
built with FRED in mind it would likely break all these scripts if FRED
would be opened with normal scripting enabled.

This fixes #1320.
2017-12-20 10:45:40 +01:00

126 lines
2.4 KiB
C++

#include "LuaValue.h"
#include "LuaException.h"
namespace {
using namespace luacpp;
ValueType luaToEnumType(int luaType) {
switch (luaType) {
case LUA_TNONE:
return ValueType::NONE;
case LUA_TNIL:
return ValueType::NIL;
case LUA_TBOOLEAN:
return ValueType::BOOLEAN;
case LUA_TLIGHTUSERDATA:
return ValueType::LIGHTUSERDATA;
case LUA_TNUMBER:
return ValueType::NUMBER;
case LUA_TSTRING:
return ValueType::STRING;
case LUA_TTABLE:
return ValueType::TABLE;
case LUA_TFUNCTION:
return ValueType::FUNCTION;
case LUA_TUSERDATA:
return ValueType::USERDATA;
case LUA_TTHREAD:
return ValueType::THREAD;
default:
return ValueType::NONE;
}
}
}
namespace luacpp {
LuaValue LuaValue::createNil(lua_State* L) {
lua_pushnil(L);
LuaValue val(L);
val.setReference(UniqueLuaReference::create(L));
return val;
}
LuaValue::LuaValue(lua_State* state) : _luaState(state), _luaType(ValueType::NONE) {
if (state == nullptr) {
throw LuaException("Lua state pointer is not valid!");
}
}
LuaValue::LuaValue(const LuaValue& other) : _luaState(other._luaState) {
// Just copy the reference object from the other
this->setReference(other._reference);
}
LuaValue::~LuaValue() {
}
void LuaValue::setReference(LuaReference ref) {
this->_reference = ref;
if (isValid()) {
this->_reference->pushValue();
_luaState = ref->getState();
this->_luaType = luaToEnumType(lua_type(_luaState, -1));
lua_pop(_luaState, 1);
}
}
const LuaReference LuaValue::getReference() const {
return _reference;
}
ValueType LuaValue::getValueType() const {
return _luaType;
}
bool LuaValue::isValid() const {
return _reference && _reference->isValid();
}
bool LuaValue::pushValue() const {
if (this->_reference->isValid()) {
this->_reference->pushValue();
return true;
} else {
return false;
}
}
lua_State* LuaValue::getLuaState() const {
return _luaState;
}
namespace convert {
void pushValue(lua_State* luaState, const LuaValue& value) {
if (luaState != value.getLuaState()) {
throw LuaException("Lua state mismatch!");
}
value.pushValue();
}
bool popValue(lua_State* luaState, LuaValue& target, int stackposition, bool remove) {
if (!internal::isValidIndex(luaState, stackposition)) {
return false;
}
target.setReference(UniqueLuaReference::create(luaState, stackposition));
if (remove) {
lua_remove(luaState, stackposition);
}
return true;
}
}
}