mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-28 12:40:06 +00:00
Add a storage mode to drop section on game exit
This commit is contained in:
parent
595e42ae43
commit
ddd0945645
@ -80,7 +80,7 @@ message(STATUS "Configuring OpenMW...")
|
|||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 49)
|
set(OPENMW_VERSION_MINOR 49)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
set(OPENMW_VERSION_RELEASE 0)
|
||||||
set(OPENMW_LUA_API_REVISION 55)
|
set(OPENMW_LUA_API_REVISION 56)
|
||||||
set(OPENMW_POSTPROCESSING_API_REVISION 1)
|
set(OPENMW_POSTPROCESSING_API_REVISION 1)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
|
@ -112,13 +112,12 @@ namespace MWLua
|
|||||||
mPlayerPackages.insert(mLocalPackages.begin(), mLocalPackages.end());
|
mPlayerPackages.insert(mLocalPackages.begin(), mLocalPackages.end());
|
||||||
|
|
||||||
LuaUtil::LuaStorage::initLuaBindings(mLua.sol());
|
LuaUtil::LuaStorage::initLuaBindings(mLua.sol());
|
||||||
mGlobalScripts.addPackage(
|
mGlobalScripts.addPackage("openmw.storage", LuaUtil::LuaStorage::initGlobalPackage(mLua, &mGlobalStorage));
|
||||||
"openmw.storage", LuaUtil::LuaStorage::initGlobalPackage(mLua.sol(), &mGlobalStorage));
|
|
||||||
mMenuScripts.addPackage(
|
mMenuScripts.addPackage(
|
||||||
"openmw.storage", LuaUtil::LuaStorage::initMenuPackage(mLua.sol(), &mGlobalStorage, &mPlayerStorage));
|
"openmw.storage", LuaUtil::LuaStorage::initMenuPackage(mLua, &mGlobalStorage, &mPlayerStorage));
|
||||||
mLocalPackages["openmw.storage"] = LuaUtil::LuaStorage::initLocalPackage(mLua.sol(), &mGlobalStorage);
|
mLocalPackages["openmw.storage"] = LuaUtil::LuaStorage::initLocalPackage(mLua, &mGlobalStorage);
|
||||||
mPlayerPackages["openmw.storage"]
|
mPlayerPackages["openmw.storage"]
|
||||||
= LuaUtil::LuaStorage::initPlayerPackage(mLua.sol(), &mGlobalStorage, &mPlayerStorage);
|
= LuaUtil::LuaStorage::initPlayerPackage(mLua, &mGlobalStorage, &mPlayerStorage);
|
||||||
|
|
||||||
mPlayerStorage.setActive(true);
|
mPlayerStorage.setActive(true);
|
||||||
mGlobalStorage.setActive(false);
|
mGlobalStorage.setActive(false);
|
||||||
|
@ -17,6 +17,15 @@ namespace LuaUtil
|
|||||||
{
|
{
|
||||||
LuaStorage::Value LuaStorage::Section::sEmpty;
|
LuaStorage::Value LuaStorage::Section::sEmpty;
|
||||||
|
|
||||||
|
void LuaStorage::registerLifeTime(LuaUtil::LuaState& luaState, sol::table& res)
|
||||||
|
{
|
||||||
|
res["LIFE_TIME"] = LuaUtil::makeStrictReadOnly(luaState.tableFromPairs<std::string_view, Section::LifeTime>({
|
||||||
|
{ "Persistent", Section::LifeTime::Persistent },
|
||||||
|
{ "GameSession", Section::LifeTime::GameSession },
|
||||||
|
{ "Temporary", Section::LifeTime::Temporary },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
sol::object LuaStorage::Value::getCopy(lua_State* L) const
|
sol::object LuaStorage::Value::getCopy(lua_State* L) const
|
||||||
{
|
{
|
||||||
return deserialize(L, mSerializedValue);
|
return deserialize(L, mSerializedValue);
|
||||||
@ -142,7 +151,12 @@ namespace LuaUtil
|
|||||||
sview["removeOnExit"] = [](const SectionView& section) {
|
sview["removeOnExit"] = [](const SectionView& section) {
|
||||||
if (section.mReadOnly)
|
if (section.mReadOnly)
|
||||||
throw std::runtime_error("Access to storage is read only");
|
throw std::runtime_error("Access to storage is read only");
|
||||||
section.mSection->mPermanent = false;
|
section.mSection->mLifeTime = Section::Temporary;
|
||||||
|
};
|
||||||
|
sview["setLifeTime"] = [](const SectionView& section, Section::LifeTime lifeTime) {
|
||||||
|
if (section.mReadOnly)
|
||||||
|
throw std::runtime_error("Access to storage is read only");
|
||||||
|
section.mSection->mLifeTime = lifeTime;
|
||||||
};
|
};
|
||||||
sview["set"] = [](const SectionView& section, std::string_view key, const sol::object& value) {
|
sview["set"] = [](const SectionView& section, std::string_view key, const sol::object& value) {
|
||||||
if (section.mReadOnly)
|
if (section.mReadOnly)
|
||||||
@ -151,26 +165,33 @@ namespace LuaUtil
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::initGlobalPackage(lua_State* lua, LuaStorage* globalStorage)
|
sol::table LuaStorage::initGlobalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage)
|
||||||
{
|
{
|
||||||
sol::table res(lua, sol::create);
|
sol::table res(luaState.sol(), sol::create);
|
||||||
|
registerLifeTime(luaState, res);
|
||||||
|
|
||||||
res["globalSection"]
|
res["globalSection"]
|
||||||
= [globalStorage](std::string_view section) { return globalStorage->getMutableSection(section); };
|
= [globalStorage](std::string_view section) { return globalStorage->getMutableSection(section); };
|
||||||
res["allGlobalSections"] = [globalStorage]() { return globalStorage->getAllSections(); };
|
res["allGlobalSections"] = [globalStorage]() { return globalStorage->getAllSections(); };
|
||||||
return LuaUtil::makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::initLocalPackage(lua_State* lua, LuaStorage* globalStorage)
|
sol::table LuaStorage::initLocalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage)
|
||||||
{
|
{
|
||||||
sol::table res(lua, sol::create);
|
sol::table res(luaState.sol(), sol::create);
|
||||||
|
registerLifeTime(luaState, res);
|
||||||
|
|
||||||
res["globalSection"]
|
res["globalSection"]
|
||||||
= [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); };
|
= [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); };
|
||||||
return LuaUtil::makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::initPlayerPackage(lua_State* lua, LuaStorage* globalStorage, LuaStorage* playerStorage)
|
sol::table LuaStorage::initPlayerPackage(
|
||||||
|
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage)
|
||||||
{
|
{
|
||||||
sol::table res(lua, sol::create);
|
sol::table res(luaState.sol(), sol::create);
|
||||||
|
registerLifeTime(luaState, res);
|
||||||
|
|
||||||
res["globalSection"]
|
res["globalSection"]
|
||||||
= [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); };
|
= [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); };
|
||||||
res["playerSection"]
|
res["playerSection"]
|
||||||
@ -179,9 +200,12 @@ namespace LuaUtil
|
|||||||
return LuaUtil::makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::initMenuPackage(lua_State* lua, LuaStorage* globalStorage, LuaStorage* playerStorage)
|
sol::table LuaStorage::initMenuPackage(
|
||||||
|
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage)
|
||||||
{
|
{
|
||||||
sol::table res(lua, sol::create);
|
sol::table res(luaState.sol(), sol::create);
|
||||||
|
registerLifeTime(luaState, res);
|
||||||
|
|
||||||
res["playerSection"] = [playerStorage](std::string_view section) {
|
res["playerSection"] = [playerStorage](std::string_view section) {
|
||||||
return playerStorage->getMutableSection(section, /*forMenuScripts=*/true);
|
return playerStorage->getMutableSection(section, /*forMenuScripts=*/true);
|
||||||
};
|
};
|
||||||
@ -199,7 +223,7 @@ namespace LuaUtil
|
|||||||
it->second->mCallbacks.clear();
|
it->second->mCallbacks.clear();
|
||||||
// Note that we don't clear menu callbacks for permanent sections
|
// Note that we don't clear menu callbacks for permanent sections
|
||||||
// because starting/loading a game doesn't reset menu scripts.
|
// because starting/loading a game doesn't reset menu scripts.
|
||||||
if (!it->second->mPermanent)
|
if (it->second->mLifeTime == Section::Temporary)
|
||||||
{
|
{
|
||||||
it->second->mMenuScriptsCallbacks.clear();
|
it->second->mMenuScriptsCallbacks.clear();
|
||||||
it->second->mValues.clear();
|
it->second->mValues.clear();
|
||||||
@ -238,7 +262,7 @@ namespace LuaUtil
|
|||||||
sol::table data(mLua, sol::create);
|
sol::table data(mLua, sol::create);
|
||||||
for (const auto& [sectionName, section] : mData)
|
for (const auto& [sectionName, section] : mData)
|
||||||
{
|
{
|
||||||
if (section->mPermanent && !section->mValues.empty())
|
if (section->mLifeTime == Section::Persistent && !section->mValues.empty())
|
||||||
data[sectionName] = section->asTable();
|
data[sectionName] = section->asTable();
|
||||||
}
|
}
|
||||||
std::string serializedData = serialize(data);
|
std::string serializedData = serialize(data);
|
||||||
|
@ -14,11 +14,13 @@ namespace LuaUtil
|
|||||||
class LuaStorage
|
class LuaStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void initLuaBindings(lua_State*);
|
static void initLuaBindings(lua_State* L);
|
||||||
static sol::table initGlobalPackage(lua_State* lua, LuaStorage* globalStorage);
|
static sol::table initGlobalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage);
|
||||||
static sol::table initLocalPackage(lua_State* lua, LuaStorage* globalStorage);
|
static sol::table initLocalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage);
|
||||||
static sol::table initPlayerPackage(lua_State* lua, LuaStorage* globalStorage, LuaStorage* playerStorage);
|
static sol::table initPlayerPackage(
|
||||||
static sol::table initMenuPackage(lua_State* lua, LuaStorage* globalStorage, LuaStorage* playerStorage);
|
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage);
|
||||||
|
static sol::table initMenuPackage(
|
||||||
|
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage);
|
||||||
|
|
||||||
explicit LuaStorage(lua_State* lua)
|
explicit LuaStorage(lua_State* lua)
|
||||||
: mLua(lua)
|
: mLua(lua)
|
||||||
@ -78,6 +80,13 @@ namespace LuaUtil
|
|||||||
|
|
||||||
struct Section
|
struct Section
|
||||||
{
|
{
|
||||||
|
enum LifeTime
|
||||||
|
{
|
||||||
|
Persistent,
|
||||||
|
GameSession,
|
||||||
|
Temporary
|
||||||
|
};
|
||||||
|
|
||||||
explicit Section(LuaStorage* storage, std::string name)
|
explicit Section(LuaStorage* storage, std::string name)
|
||||||
: mStorage(storage)
|
: mStorage(storage)
|
||||||
, mSectionName(std::move(name))
|
, mSectionName(std::move(name))
|
||||||
@ -96,7 +105,7 @@ namespace LuaUtil
|
|||||||
std::vector<Callback> mCallbacks;
|
std::vector<Callback> mCallbacks;
|
||||||
std::vector<Callback> mMenuScriptsCallbacks; // menu callbacks are in a separate vector because we don't
|
std::vector<Callback> mMenuScriptsCallbacks; // menu callbacks are in a separate vector because we don't
|
||||||
// remove them in clear()
|
// remove them in clear()
|
||||||
bool mPermanent = true;
|
LifeTime mLifeTime = Persistent;
|
||||||
static Value sEmpty;
|
static Value sEmpty;
|
||||||
|
|
||||||
void checkIfActive() const { mStorage->checkIfActive(); }
|
void checkIfActive() const { mStorage->checkIfActive(); }
|
||||||
@ -120,6 +129,7 @@ namespace LuaUtil
|
|||||||
if (!mActive)
|
if (!mActive)
|
||||||
throw std::logic_error("Trying to access inactive storage");
|
throw std::logic_error("Trying to access inactive storage");
|
||||||
}
|
}
|
||||||
|
static void registerLifeTime(LuaUtil::LuaState& luaState, sol::table& res);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,15 @@
|
|||||||
-- end
|
-- end
|
||||||
-- end))
|
-- end))
|
||||||
|
|
||||||
|
--- Possible @{#LifeTime} values
|
||||||
|
-- @field [parent=#storage] #LifeTime LIFE_TIME
|
||||||
|
|
||||||
|
--- `storage.LIFE_TIME`
|
||||||
|
-- @type LifeTime
|
||||||
|
-- @field #number Persistent "0" Data is stored for the whole game session and remains on disk after quitting the game
|
||||||
|
-- @field #number GameSession "1" Data is stored for the whole game session
|
||||||
|
-- @field #number Temporary "2" Data is stored until script context reset
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Get a section of the global storage; can be used by any script, but only global scripts can change values.
|
-- Get a section of the global storage; can be used by any script, but only global scripts can change values.
|
||||||
-- Menu scripts can only access it when a game is running.
|
-- Menu scripts can only access it when a game is running.
|
||||||
@ -83,12 +92,28 @@
|
|||||||
-- @param #table values (optional) New values
|
-- @param #table values (optional) New values
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Make the whole section temporary: will be removed on exit or when load a save.
|
-- (DEPRECATED, use `setLifeTime(openmw.storage.LIFE_TIME.Temporary)`) Make the whole section temporary: will be removed on exit or when load a save.
|
||||||
-- Temporary sections have the same interface to get/set values, the only difference is they will not
|
-- Temporary sections have the same interface to get/set values, the only difference is they will not
|
||||||
-- be saved to the permanent storage on exit.
|
-- be saved to the permanent storage on exit.
|
||||||
-- This function can not be used for a global storage section from a local script.
|
-- This function can be used for a global storage section from a global script or for a player storage section from a player or menu script.
|
||||||
-- @function [parent=#StorageSection] removeOnExit
|
-- @function [parent=#StorageSection] removeOnExit
|
||||||
-- @param self
|
-- @param self
|
||||||
|
-- @usage
|
||||||
|
-- local storage = require('openmw.storage')
|
||||||
|
-- local myModData = storage.globalSection('MyModExample')
|
||||||
|
-- myModData:removeOnExit()
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Set the life time of given storage section.
|
||||||
|
-- New sections initially have a Persistent life time.
|
||||||
|
-- This function can be used for a global storage section from a global script or for a player storage section from a player or menu script.
|
||||||
|
-- @function [parent=#StorageSection] setLifeTime
|
||||||
|
-- @param self
|
||||||
|
-- @param #LifeTime lifeTime Section life time
|
||||||
|
-- @usage
|
||||||
|
-- local storage = require('openmw.storage')
|
||||||
|
-- local myModData = storage.globalSection('MyModExample')
|
||||||
|
-- myModData:setLifeTime(storage.LIFE_TIME.Temporary)
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Set value by a string key; can not be used for global storage from a local script.
|
-- Set value by a string key; can not be used for global storage from a local script.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user