mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 18:31:26 -10:00
w_bank: add a move constructor. object_copy_including_array_member returns by value, and without a move constructor the return fell back to the shallow copy constructor whenever NRVO was not applied (e.g. MSVC debug builds), after which the local's destructor deleted the freshly allocated arrays -- leaving the stored bank dangling and double-deleting at model unload. Also add noexcept to the move operations, replace the destructor call in move-assignment with explicit delete[]s (using an object after its lifetime has ended is undefined behavior), guard against self-move, and document that the defaulted copy constructor is intentionally shallow for object_copy_including_array_member's copy-then-replace pattern. LuaThread: declare the defaulted move operations noexcept. This exposed that LuaTable was not movable at all (its user-declared destructor suppressed the implicit moves), so LuaThread's implicit move spec was formally throwing -- a hard error on gcc 9, which still requires the spec on a defaulted redeclaration to match the implicit one. Restore LuaTable's rule of five and declare the LuaValue and LuaFunction copy operations noexcept (they only copy a shared_ptr, a raw pointer, and an enum), making the noexcept claims hold throughout the hierarchy. Co-Authored-By: Claude Fable 5 <[email protected]>
78 lines
1.6 KiB
C++
78 lines
1.6 KiB
C++
#pragma once
|
|
|
|
#include "LuaConvert.h"
|
|
#include "LuaTypes.h"
|
|
#include "LuaValue.h"
|
|
#include "LuaFunction.h"
|
|
|
|
#include <iterator>
|
|
|
|
namespace luacpp {
|
|
|
|
/**
|
|
* @brief Class to improve handling of lua threads (aka coroutines).
|
|
*
|
|
* This class provides a high-level interface to lua threads.
|
|
*
|
|
* @see LuaConvert
|
|
*/
|
|
class LuaThread : public LuaValue {
|
|
|
|
LuaReference deleterUserdata;
|
|
LuaTable deleterTable;
|
|
LuaFunction deleterFunc;
|
|
public:
|
|
using ErrorCallback = std::function<bool(lua_State* mainState, lua_State* thread)>;
|
|
struct ResumeState
|
|
{
|
|
bool completed = false;
|
|
LuaValueList returnVals;
|
|
};
|
|
|
|
/**
|
|
* @brief Creates a new empty thread.
|
|
*/
|
|
static LuaThread create(lua_State* L, const LuaFunction& func);
|
|
|
|
/**
|
|
* @brief Default constructor
|
|
*/
|
|
LuaThread();
|
|
|
|
//Copying threads is VERY illegal
|
|
LuaThread(const LuaThread&) = delete;
|
|
LuaThread& operator=(const LuaThread&) = delete;
|
|
|
|
LuaThread(LuaThread&&) noexcept;
|
|
LuaThread& operator=(LuaThread&&) noexcept;
|
|
|
|
~LuaThread() override;
|
|
|
|
/**
|
|
* @brief Sets a new reference.
|
|
* This overload checks if the passed reference is a thread
|
|
*
|
|
* @param ref The new reference
|
|
* @return void
|
|
*/
|
|
void setReference(const LuaReference& ref) override;
|
|
|
|
void setErrorCallback(ErrorCallback errorCallback);
|
|
|
|
ResumeState resume(const LuaValueList& params) const;
|
|
|
|
lua_State* getThreadHandle() const;
|
|
private:
|
|
LuaThread(lua_State* luaState, lua_State* threadHandle);
|
|
|
|
lua_State* _thread = nullptr;
|
|
ErrorCallback _errorCallback;
|
|
};
|
|
|
|
namespace convert {
|
|
|
|
bool popValue(lua_State* luaState, LuaThread& target, int stackposition = -1, bool remove = true);
|
|
|
|
}
|
|
} // namespace luacpp
|