mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-09 04:49:39 -10:00
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.
126 lines
2.4 KiB
C++
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;
|
|
}
|
|
|
|
}
|
|
|
|
}
|