1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-16 07:10:08 +00:00
OpenMW/components/lua/storage.hpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

138 lines
4.7 KiB
C++
Raw Normal View History

2021-12-13 23:39:01 +00:00
#ifndef COMPONENTS_LUA_STORAGE_H
#define COMPONENTS_LUA_STORAGE_H
#include <map>
#include <sol/sol.hpp>
#include <stdexcept>
2021-12-13 23:39:01 +00:00
#include "asyncpackage.hpp"
2021-12-13 23:39:01 +00:00
#include "serialization.hpp"
namespace LuaUtil
{
class LuaStorage
{
public:
static void initLuaBindings(lua_State* L);
static sol::table initGlobalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage);
static sol::table initLocalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage);
static sol::table initPlayerPackage(
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage);
static sol::table initMenuPackage(
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage);
2021-12-13 23:39:01 +00:00
explicit LuaStorage(lua_State* lua)
: mLua(lua)
, mActive(false)
2021-12-13 23:39:01 +00:00
{
}
2022-04-23 13:37:08 +00:00
void clearTemporaryAndRemoveCallbacks();
void load(const std::filesystem::path& path);
void save(const std::filesystem::path& path) const;
2021-12-13 23:39:01 +00:00
sol::object getSection(std::string_view sectionName, bool readOnly, bool forMenuScripts = false);
sol::object getMutableSection(std::string_view sectionName, bool forMenuScripts = false)
{
return getSection(sectionName, false, forMenuScripts);
}
2022-04-23 13:37:08 +00:00
sol::object getReadOnlySection(std::string_view sectionName) { return getSection(sectionName, true); }
sol::table getAllSections(bool readOnly = false);
2021-12-13 23:39:01 +00:00
2022-04-23 13:37:08 +00:00
void setSingleValue(std::string_view section, std::string_view key, const sol::object& value)
{
getSection(section)->set(key, value);
}
2021-12-13 23:39:01 +00:00
2022-04-23 13:37:08 +00:00
void setSectionValues(std::string_view section, const sol::optional<sol::table>& values)
{
getSection(section)->setAll(values);
}
class Listener
{
public:
2023-02-03 20:29:26 +00:00
virtual ~Listener() = default;
2022-04-23 13:37:08 +00:00
virtual void valueChanged(
std::string_view section, std::string_view key, const sol::object& value) const = 0;
virtual void sectionReplaced(std::string_view section, const sol::optional<sol::table>& values) const = 0;
};
void setListener(const Listener* listener) { mListener = listener; }
void setActive(bool active) { mActive = active; }
2021-12-13 23:39:01 +00:00
private:
class Value
{
public:
Value() {}
Value(const sol::object& value)
: mSerializedValue(serialize(value))
{
}
sol::object getCopy(lua_State* L) const;
sol::object getReadOnly(lua_State* L) const;
private:
std::string mSerializedValue;
mutable sol::object mReadOnlyValue = sol::nil;
};
struct Section
{
enum LifeTime
{
Persistent,
GameSession,
Temporary
};
2021-12-13 23:39:01 +00:00
explicit Section(LuaStorage* storage, std::string name)
: mStorage(storage)
, mSectionName(std::move(name))
{
}
const Value& get(std::string_view key) const;
void set(std::string_view key, const sol::object& value);
2022-04-23 13:37:08 +00:00
void setAll(const sol::optional<sol::table>& values);
2021-12-13 23:39:01 +00:00
sol::table asTable();
2022-04-23 13:37:08 +00:00
void runCallbacks(sol::optional<std::string_view> changedKey);
2022-05-19 19:49:14 +00:00
void throwIfCallbackRecursionIsTooDeep();
2021-12-13 23:39:01 +00:00
LuaStorage* mStorage;
std::string mSectionName;
std::map<std::string, Value, std::less<>> mValues;
2022-04-23 13:37:08 +00:00
std::vector<Callback> mCallbacks;
std::vector<Callback> mMenuScriptsCallbacks; // menu callbacks are in a separate vector because we don't
// remove them in clear()
LifeTime mLifeTime = Persistent;
2021-12-13 23:39:01 +00:00
static Value sEmpty;
void checkIfActive() const { mStorage->checkIfActive(); }
2021-12-13 23:39:01 +00:00
};
2022-04-23 13:37:08 +00:00
struct SectionView
2021-12-13 23:39:01 +00:00
{
2022-04-23 13:37:08 +00:00
std::shared_ptr<Section> mSection;
bool mReadOnly;
bool mForMenuScripts = false;
2021-12-13 23:39:01 +00:00
};
const std::shared_ptr<Section>& getSection(std::string_view sectionName);
2021-12-13 23:39:01 +00:00
lua_State* mLua;
std::map<std::string_view, std::shared_ptr<Section>> mData;
2022-04-23 13:37:08 +00:00
const Listener* mListener = nullptr;
2022-05-19 19:49:14 +00:00
std::set<const Section*> mRunningCallbacks;
bool mActive;
void checkIfActive() const
{
if (!mActive)
throw std::logic_error("Trying to access inactive storage");
}
static void registerLifeTime(LuaUtil::LuaState& luaState, sol::table& res);
2021-12-13 23:39:01 +00:00
};
}
#endif // COMPONENTS_LUA_STORAGE_H