File: content.hpp

package info (click to toggle)
openmw 0.49.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,992 kB
  • sloc: cpp: 372,479; xml: 2,149; sh: 1,403; python: 797; makefile: 26
file content (110 lines) | stat: -rw-r--r-- 3,572 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#ifndef COMPONENTS_LUAUI_CONTENT
#define COMPONENTS_LUAUI_CONTENT

#include <map>
#include <string>

#include <sol/sol.hpp>

#include <components/lua/luastate.hpp>

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::main_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<sol::object>(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<sol::object>(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<sol::protected_function>()(
                    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<size_t> indexOf(std::string_view name) const
        {
            sol::object result = callMethod("indexOf", name);
            if (result.is<size_t>())
                return fromLua(LuaUtil::cast<size_t>(result));
            else
                return std::nullopt;
        }
        std::optional<size_t> indexOf(const sol::table& table) const
        {
            sol::object result = callMethod("indexOf", table);
            if (result.is<size_t>())
                return fromLua(LuaUtil::cast<size_t>(result));
            else
                return std::nullopt;
        }

        sol::table getMetatable() const { return mTable[sol::metatable_key].get<sol::table>(); }

    private:
        sol::main_table mTable;

        template <typename... Arg>
        sol::object callMethod(std::string_view name, Arg&&... arg) const
        {
            return mTable.get<sol::protected_function>(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