mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 12:58:00 +03:00
Use unique_ptr to handle lua state lifetime
This commit is contained in:
parent
87d77a6882
commit
f80283422f
5 changed files with 48 additions and 42 deletions
|
@ -59,7 +59,7 @@ list(APPEND COMPONENT_FILES "${OpenMW_BINARY_DIR}/${OSG_PLUGIN_CHECKER_CPP_FILE}
|
||||||
|
|
||||||
add_component_dir (lua
|
add_component_dir (lua
|
||||||
luastate scriptscontainer asyncpackage utilpackage serialization configuration l10n storage utf8
|
luastate scriptscontainer asyncpackage utilpackage serialization configuration l10n storage utf8
|
||||||
shapes/box inputactions yamlloader scripttracker
|
shapes/box inputactions yamlloader scripttracker luastateptr
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (l10n
|
add_component_dir (l10n
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "luascripts.hpp"
|
#include "luascripts.hpp"
|
||||||
|
|
||||||
#include "components/esm3/esmreader.hpp"
|
#include <components/esm3/esmreader.hpp>
|
||||||
#include "components/esm3/esmwriter.hpp"
|
#include <components/esm3/esmwriter.hpp>
|
||||||
|
|
||||||
|
#include <components/lua/luastateptr.hpp>
|
||||||
#include <components/lua/serialization.hpp>
|
#include <components/lua/serialization.hpp>
|
||||||
|
|
||||||
// List of all records, that are related to Lua.
|
// List of all records, that are related to Lua.
|
||||||
|
@ -102,13 +103,16 @@ void ESM::LuaScriptsCfg::adjustRefNums(const ESMReader& esm)
|
||||||
throw std::runtime_error("Incorrect contentFile index");
|
throw std::runtime_error("Incorrect contentFile index");
|
||||||
};
|
};
|
||||||
|
|
||||||
lua_State* L = luaL_newstate();
|
LuaUtil::LuaStatePtr state(luaL_newstate());
|
||||||
|
if (state == nullptr)
|
||||||
|
throw std::runtime_error("Failed to create Lua runtime");
|
||||||
|
|
||||||
LuaUtil::BasicSerializer serializer(adjustRefNumFn);
|
LuaUtil::BasicSerializer serializer(adjustRefNumFn);
|
||||||
|
|
||||||
auto adjustLuaData = [&](std::string& data) {
|
auto adjustLuaData = [&](std::string& data) {
|
||||||
if (data.empty())
|
if (data.empty())
|
||||||
return;
|
return;
|
||||||
sol::object luaData = LuaUtil::deserialize(L, data, &serializer);
|
sol::object luaData = LuaUtil::deserialize(state.get(), data, &serializer);
|
||||||
data = LuaUtil::serialize(luaData, &serializer);
|
data = LuaUtil::serialize(luaData, &serializer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,7 +127,6 @@ void ESM::LuaScriptsCfg::adjustRefNums(const ESMReader& esm)
|
||||||
refCfg.mRefnumContentFile = adjustRefNumFn(refCfg.mRefnumContentFile);
|
refCfg.mRefnumContentFile = adjustRefNumFn(refCfg.mRefnumContentFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lua_close(L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::LuaScriptsCfg::save(ESMWriter& esm) const
|
void ESM::LuaScriptsCfg::save(ESMWriter& esm) const
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <components/files/conversion.hpp>
|
#include <components/files/conversion.hpp>
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
|
||||||
|
#include "luastateptr.hpp"
|
||||||
#include "scriptscontainer.hpp"
|
#include "scriptscontainer.hpp"
|
||||||
#include "utf8.hpp"
|
#include "utf8.hpp"
|
||||||
|
|
||||||
|
@ -151,37 +152,37 @@ namespace LuaUtil
|
||||||
return newPtr;
|
return newPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_State* LuaState::createLuaRuntime(LuaState* luaState)
|
LuaStatePtr LuaState::createLuaRuntime(LuaState* luaState)
|
||||||
{
|
{
|
||||||
if (sProfilerEnabled)
|
if (sProfilerEnabled)
|
||||||
{
|
{
|
||||||
Log(Debug::Info) << "Initializing LuaUtil::LuaState with profiler";
|
Log(Debug::Info) << "Initializing LuaUtil::LuaState with profiler";
|
||||||
lua_State* L = lua_newstate(&trackingAllocator, luaState);
|
LuaStatePtr state(lua_newstate(&trackingAllocator, luaState));
|
||||||
if (L)
|
if (state != nullptr)
|
||||||
return L;
|
return state;
|
||||||
else
|
sProfilerEnabled = false;
|
||||||
{
|
Log(Debug::Error) << "Failed to initialize LuaUtil::LuaState with custom allocator; disabling Lua profiler";
|
||||||
sProfilerEnabled = false;
|
|
||||||
Log(Debug::Error)
|
|
||||||
<< "Failed to initialize LuaUtil::LuaState with custom allocator; disabling Lua profiler";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Log(Debug::Info) << "Initializing LuaUtil::LuaState without profiler";
|
Log(Debug::Info) << "Initializing LuaUtil::LuaState without profiler";
|
||||||
lua_State* L = luaL_newstate();
|
LuaStatePtr state(luaL_newstate());
|
||||||
if (!L)
|
if (state == nullptr)
|
||||||
throw std::runtime_error("Can't create Lua runtime");
|
throw std::runtime_error("Failed to create Lua runtime");
|
||||||
return L;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaState::LuaState(const VFS::Manager* vfs, const ScriptsConfiguration* conf, const LuaStateSettings& settings)
|
LuaState::LuaState(const VFS::Manager* vfs, const ScriptsConfiguration* conf, const LuaStateSettings& settings)
|
||||||
: mSettings(settings)
|
: mSettings(settings)
|
||||||
, mLuaHolder(createLuaRuntime(this))
|
, mLuaState([&] {
|
||||||
, mSol(mLuaHolder.get())
|
LuaStatePtr state = createLuaRuntime(this);
|
||||||
|
sol::set_default_state(state.get());
|
||||||
|
return state;
|
||||||
|
}())
|
||||||
|
, mSol(mLuaState.get())
|
||||||
, mConf(conf)
|
, mConf(conf)
|
||||||
, mVFS(vfs)
|
, mVFS(vfs)
|
||||||
{
|
{
|
||||||
if (sProfilerEnabled)
|
if (sProfilerEnabled)
|
||||||
lua_sethook(mLuaHolder.get(), &countHook, LUA_MASKCOUNT, countHookStep);
|
lua_sethook(mLuaState.get(), &countHook, LUA_MASKCOUNT, countHookStep);
|
||||||
|
|
||||||
protectedCall([&](LuaView& view) {
|
protectedCall([&](LuaView& view) {
|
||||||
auto& sol = view.sol();
|
auto& sol = view.sol();
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <components/vfs/pathutil.hpp>
|
#include <components/vfs/pathutil.hpp>
|
||||||
|
|
||||||
#include "configuration.hpp"
|
#include "configuration.hpp"
|
||||||
|
#include "luastateptr.hpp"
|
||||||
|
|
||||||
namespace VFS
|
namespace VFS
|
||||||
{
|
{
|
||||||
|
@ -188,7 +189,7 @@ namespace LuaUtil
|
||||||
static void countHook(lua_State* L, lua_Debug* ar);
|
static void countHook(lua_State* L, lua_Debug* ar);
|
||||||
static void* trackingAllocator(void* ud, void* ptr, size_t osize, size_t nsize);
|
static void* trackingAllocator(void* ud, void* ptr, size_t osize, size_t nsize);
|
||||||
|
|
||||||
lua_State* createLuaRuntime(LuaState* luaState);
|
static LuaStatePtr createLuaRuntime(LuaState* luaState);
|
||||||
|
|
||||||
struct AllocOwner
|
struct AllocOwner
|
||||||
{
|
{
|
||||||
|
@ -206,25 +207,8 @@ namespace LuaUtil
|
||||||
uint64_t mSmallAllocMemoryUsage = 0;
|
uint64_t mSmallAllocMemoryUsage = 0;
|
||||||
std::vector<int64_t> mMemoryUsage;
|
std::vector<int64_t> mMemoryUsage;
|
||||||
|
|
||||||
class LuaStateHolder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LuaStateHolder(lua_State* L)
|
|
||||||
: L(L)
|
|
||||||
{
|
|
||||||
sol::set_default_state(L);
|
|
||||||
}
|
|
||||||
~LuaStateHolder() { lua_close(L); }
|
|
||||||
LuaStateHolder(const LuaStateHolder&) = delete;
|
|
||||||
LuaStateHolder(LuaStateHolder&&) = delete;
|
|
||||||
lua_State* get() { return L; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
lua_State* L;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Must be declared before mSol and all sol-related objects. Then on exit it will be destructed the last.
|
// Must be declared before mSol and all sol-related objects. Then on exit it will be destructed the last.
|
||||||
LuaStateHolder mLuaHolder;
|
LuaStatePtr mLuaState;
|
||||||
|
|
||||||
sol::state_view mSol;
|
sol::state_view mSol;
|
||||||
const ScriptsConfiguration* mConf;
|
const ScriptsConfiguration* mConf;
|
||||||
|
|
18
components/lua/luastateptr.hpp
Normal file
18
components/lua/luastateptr.hpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_LUA_LUASTATEPTR_H
|
||||||
|
#define OPENMW_COMPONENTS_LUA_LUASTATEPTR_H
|
||||||
|
|
||||||
|
#include <sol/state.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace LuaUtil
|
||||||
|
{
|
||||||
|
struct CloseLuaState
|
||||||
|
{
|
||||||
|
void operator()(lua_State* state) noexcept { lua_close(state); }
|
||||||
|
};
|
||||||
|
|
||||||
|
using LuaStatePtr = std::unique_ptr<lua_State, CloseLuaState>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue