mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
The iterator known as _L, besides having an absurdly poor name, clashes with standard headers on OpenBSD -current at the time of writing. This commit is the minimum needed to build on OpenBSD with an updated C++ standard library.
136 lines
2.8 KiB
C++
136 lines
2.8 KiB
C++
#include "LuaException.h"
|
|
#include "LuaTable.h"
|
|
|
|
namespace luacpp {
|
|
LuaTable LuaTable::create(lua_State* state) {
|
|
LuaTable table;
|
|
|
|
lua_newtable(state);
|
|
|
|
table.setReference(UniqueLuaReference::create(state));
|
|
|
|
lua_pop(state, 1);
|
|
|
|
return table;
|
|
}
|
|
|
|
LuaTable::LuaTable() : LuaValue() {
|
|
}
|
|
|
|
LuaTable::LuaTable(const LuaTable& other) : LuaValue(other) {
|
|
}
|
|
|
|
LuaTable::~LuaTable() {
|
|
}
|
|
|
|
bool LuaTable::setMetatable(const LuaTable& table) {
|
|
if (!table.getReference()->isValid()) {
|
|
throw LuaException("Meta table reference is not valid!");
|
|
}
|
|
|
|
this->pushValue();
|
|
table.pushValue();
|
|
|
|
lua_setmetatable(_luaState, -2);
|
|
|
|
lua_pop(_luaState, 1);
|
|
|
|
return true;
|
|
}
|
|
|
|
void LuaTable::setReference(luacpp::LuaReference ref) {
|
|
ref->pushValue();
|
|
|
|
lua_State* L = ref->getState();
|
|
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
lua_pop(L, 1);
|
|
throw LuaException("Reference does not refere to a table!");
|
|
} else {
|
|
lua_pop(L, 1);
|
|
LuaValue::setReference(ref);
|
|
}
|
|
}
|
|
|
|
size_t LuaTable::getLength() {
|
|
this->pushValue();
|
|
|
|
size_t length = lua_objlen(_luaState, -1);
|
|
|
|
lua_pop(_luaState, 1);
|
|
|
|
return length;
|
|
}
|
|
|
|
LuaTable::iterator::iterator(const LuaTable& parent) {
|
|
_iter.reset(new LuaTableIterator(parent));
|
|
}
|
|
LuaTable::iterator::iterator() : _iter(nullptr), _atEnd(true) {
|
|
}
|
|
bool LuaTable::iterator::operator==(const iterator& other) {
|
|
return _atEnd == other._atEnd;
|
|
}
|
|
bool LuaTable::iterator::operator!=(const LuaTable::iterator& other) {
|
|
return !(*this == other);
|
|
}
|
|
LuaTable::iterator& LuaTable::iterator::operator++() {
|
|
_iter->toNextElement();
|
|
|
|
_atEnd = !_iter->hasElement();
|
|
|
|
return *this;
|
|
}
|
|
LuaTable::iterator& LuaTable::iterator::operator++(int) {
|
|
return ++(*this); // Post-fix operator doesn't make sense for us.
|
|
}
|
|
std::pair<LuaValue, LuaValue> LuaTable::iterator::operator*() {
|
|
return _iter->getElement();
|
|
}
|
|
|
|
LuaTable::iterator LuaTable::begin() {
|
|
iterator iter(*this);
|
|
|
|
// This will call lua_next and automatically handle the end of the table
|
|
return iter;
|
|
}
|
|
LuaTable::iterator LuaTable::end() {
|
|
return iterator(); // Empty iterator
|
|
}
|
|
|
|
LuaTableIterator::LuaTableIterator(const LuaTable& t) : _luaState(t.getLuaState()) {
|
|
_stackTop = lua_gettop(_luaState);
|
|
|
|
t.pushValue();
|
|
lua_pushnil(_luaState);
|
|
|
|
toNextElement();
|
|
}
|
|
LuaTableIterator::~LuaTableIterator() {
|
|
lua_settop(_luaState, _stackTop);
|
|
}
|
|
bool LuaTableIterator::hasElement() {
|
|
return _hasElement;
|
|
}
|
|
void LuaTableIterator::toNextElement() {
|
|
auto ret = lua_next(_luaState, -2);
|
|
|
|
_hasElement = ret != 0;
|
|
|
|
if (_hasElement) {
|
|
LuaValue key;
|
|
key.setReference(UniqueLuaReference::create(_luaState, -2));
|
|
|
|
LuaValue value;
|
|
value.setReference(UniqueLuaReference::create(_luaState, -1));
|
|
|
|
_currentVal = std::make_pair(key, value);
|
|
|
|
// Remove value from stack
|
|
lua_pop(_luaState, 1);
|
|
}
|
|
}
|
|
std::pair<LuaValue, LuaValue> LuaTableIterator::getElement() {
|
|
return _currentVal;
|
|
}
|
|
}
|