#ifndef COMPONENTS_LUAUI_CONTENT #define COMPONENTS_LUAUI_CONTENT #include #include #include #include namespace LuaUi { sol::protected_function loadContentConstructor(LuaUtil::LuaState* state); bool isValidContent(const sol::object& object); class ContentView { public: // accepts only Lua tables returned by ui.content explicit ContentView(sol::table table) : mTable(std::move(table)) { if (!isValidContent(mTable)) throw std::domain_error("Invalid UI Content"); } size_t size() const { return mTable.size(); } void assign(std::string_view name, const sol::table& table) { if (indexOf(name).has_value()) mTable[name] = table; else throw std::domain_error("Invalid Content key"); } void assign(size_t index, const sol::table& table) { if (index <= size()) mTable[toLua(index)] = table; else throw std::range_error("Invalid Content index"); } void insert(size_t index, const sol::table& table) { callMethod("insert", toLua(index), table); } sol::object at(size_t index) const { if (index < size()) return mTable.get(toLua(index)); else throw std::range_error("Invalid Content index"); } sol::object at(std::string_view name) const { if (indexOf(name).has_value()) return mTable.get(name); else throw std::range_error("Invalid Content key"); } void remove(size_t index) { if (index < size()) // for some reason mTable[key] = value doesn't call __newindex getMetatable()[sol::meta_function::new_index].get()( mTable, toLua(index), sol::nil); else throw std::range_error("Invalid Content index"); } void remove(std::string_view name) { auto index = indexOf(name); if (index.has_value()) remove(index.value()); else throw std::domain_error("Invalid Content key"); } std::optional indexOf(std::string_view name) const { sol::object result = callMethod("indexOf", name); if (result.is()) return fromLua(LuaUtil::cast(result)); else return std::nullopt; } std::optional indexOf(const sol::table& table) const { sol::object result = callMethod("indexOf", table); if (result.is()) return fromLua(LuaUtil::cast(result)); else return std::nullopt; } sol::table getMetatable() const { return mTable[sol::metatable_key].get(); } private: sol::table mTable; template sol::object callMethod(std::string_view name, Arg&&... arg) const { return mTable.get(name)(mTable, arg...); } static inline size_t toLua(size_t index) { return index + 1; } static inline size_t fromLua(size_t index) { return index - 1; } }; } #endif // COMPONENTS_LUAUI_CONTENT