mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
This adds a mechanism for running generic operations at specific points of the frame execution. This can be used by any part of the code an not just Lua since it simply executes std::functions. It also adds an "execution context" concept that specifies in which situation an operation should be executed. This is then used by the Lua Coroutines code for resuming coroutines at specific points instead of always when the awaited promise resolves.
92 lines
2.2 KiB
C++
92 lines
2.2 KiB
C++
|
|
#include "LuaReference.h"
|
|
|
|
#include "globalincs/pstypes.h"
|
|
|
|
#include "LuaException.h"
|
|
#include "LuaHeaders.h"
|
|
#include "LuaUtil.h"
|
|
|
|
namespace luacpp {
|
|
LuaReference UniqueLuaReference::create(lua_State* state, int position)
|
|
{
|
|
if (state == nullptr) {
|
|
throw LuaException("Need a valid lua state!");
|
|
}
|
|
|
|
lua_pushvalue(state, position);
|
|
|
|
// Always store the main thread here to ensure that we do not store a possible invalid thread reference
|
|
LuaReference ref =
|
|
std::make_shared<UniqueLuaReference>(util::getMainThread(state), luaL_ref(state, LUA_REGISTRYINDEX));
|
|
|
|
return ref;
|
|
}
|
|
|
|
LuaReference UniqueLuaReference::copy(const LuaReference& other) {
|
|
other->pushValue(other->_luaState);
|
|
|
|
return create(other->_luaState);
|
|
}
|
|
|
|
UniqueLuaReference::UniqueLuaReference(lua_State* state, int reference) : _luaState(state), _reference(reference)
|
|
{
|
|
if (state == nullptr) {
|
|
throw LuaException("Need a valid lua state!");
|
|
}
|
|
|
|
if (reference < 0 && reference != LUA_REFNIL) {
|
|
throw LuaException("Reference must be greater than or equal to zero!");
|
|
}
|
|
}
|
|
UniqueLuaReference::UniqueLuaReference() : _luaState(nullptr), _reference(LUA_NOREF) {}
|
|
|
|
UniqueLuaReference::UniqueLuaReference(UniqueLuaReference&& other) noexcept : _luaState(nullptr), _reference(LUA_NOREF) {
|
|
*this = std::move(other);
|
|
}
|
|
UniqueLuaReference& UniqueLuaReference::operator=(UniqueLuaReference&& other) noexcept {
|
|
std::swap(_luaState, other._luaState);
|
|
std::swap(_reference, other._reference);
|
|
return *this;
|
|
}
|
|
|
|
UniqueLuaReference::~UniqueLuaReference() {
|
|
this->removeReference();
|
|
}
|
|
|
|
bool UniqueLuaReference::removeReference() {
|
|
if (this->isValid()) {
|
|
luaL_unref(_luaState, LUA_REGISTRYINDEX, _reference);
|
|
_reference = LUA_NOREF;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int UniqueLuaReference::getReference() const {
|
|
return _reference;
|
|
}
|
|
|
|
bool UniqueLuaReference::isValid() const {
|
|
if (_luaState == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
if (_reference == LUA_NOREF) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void UniqueLuaReference::pushValue(lua_State* thread) const
|
|
{
|
|
Assertion(thread != nullptr, "Valid thread state must be specified!");
|
|
|
|
if (this->isValid()) {
|
|
lua_rawgeti(thread, LUA_REGISTRYINDEX, this->getReference());
|
|
}
|
|
}
|
|
}
|