#ifndef COMPONENTS_LUA_STORAGE_H #define COMPONENTS_LUA_STORAGE_H #include <map> #include <sol/sol.hpp> #include "serialization.hpp" namespace LuaUtil { class LuaStorage { public: static void initLuaBindings(lua_State*); explicit LuaStorage(lua_State* lua) : mLua(lua) {} void clearTemporary(); void load(const std::string& path); void save(const std::string& path) const; sol::object getReadOnlySection(std::string_view sectionName); sol::object getMutableSection(std::string_view sectionName); sol::table getAllSections(); void set(std::string_view section, std::string_view key, const sol::object& value) { getSection(section)->set(key, value); } using ListenerFn = std::function<void(std::string_view, std::string_view, const sol::object&)>; void setListener(ListenerFn fn) { mListener = std::move(fn); } 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 { 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); bool wasChanged(int64_t& lastCheck); sol::table asTable(); LuaStorage* mStorage; std::string mSectionName; std::map<std::string, Value, std::less<>> mValues; bool mPermanent = true; int64_t mChangeCounter = 0; static Value sEmpty; }; struct SectionMutableView { std::shared_ptr<Section> mSection = nullptr; int64_t mLastCheck = 0; }; struct SectionReadOnlyView { std::shared_ptr<Section> mSection = nullptr; int64_t mLastCheck = 0; }; const std::shared_ptr<Section>& getSection(std::string_view sectionName); lua_State* mLua; std::map<std::string_view, std::shared_ptr<Section>> mData; std::optional<ListenerFn> mListener; }; } #endif // COMPONENTS_LUA_STORAGE_H