File: l10n.cpp

package info (click to toggle)
openmw 0.50.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 37,076 kB
  • sloc: cpp: 380,958; xml: 2,192; sh: 1,449; python: 911; makefile: 26; javascript: 5
file content (76 lines) | stat: -rw-r--r-- 2,767 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
#include "l10n.hpp"

#include <components/debug/debuglog.hpp>
#include <components/l10n/manager.hpp>
#include <components/lua/luastate.hpp>

namespace
{
    struct L10nContext
    {
        std::shared_ptr<const L10n::MessageBundles> mData;
    };

    void getICUArgs(std::string_view messageId, const sol::table& table, std::vector<icu::UnicodeString>& argNames,
        std::vector<icu::Formattable>& args)
    {
        for (auto& [key, value] : table)
        {
            // Argument values
            if (value.is<std::string>())
            {
                const auto& str = LuaUtil::cast<std::string>(value);
                args.push_back(icu::Formattable(icu::UnicodeString::fromUTF8(str.c_str())));
            }

            // Note: While we pass all numbers as doubles, they still seem to be handled appropriately.
            // Numbers can be forced to be integers using the argType number and argStyle integer
            //     E.g. {var, number, integer}
            else if (value.is<double>())
                args.push_back(icu::Formattable(LuaUtil::cast<double>(value)));
            else
            {
                Log(Debug::Error) << "Unrecognized argument type for key \"" << LuaUtil::cast<std::string>(key)
                                  << "\" when formatting message \"" << messageId << "\"";
            }

            // Argument names
            const auto str = LuaUtil::cast<std::string>(key);
            argNames.push_back(
                icu::UnicodeString::fromUTF8(icu::StringPiece(str.data(), static_cast<int32_t>(str.size()))));
        }
    }
}

namespace sol
{
    template <>
    struct is_automagical<L10nContext> : std::false_type
    {
    };
}

namespace LuaUtil
{
    sol::function initL10nLoader(lua_State* state, L10n::Manager* manager)
    {
        sol::state_view lua(state);
        sol::usertype<L10nContext> ctxDef = lua.new_usertype<L10nContext>("L10nContext");
        ctxDef[sol::meta_function::call]
            = [](const L10nContext& ctx, std::string_view key, sol::optional<sol::table> args) {
                  std::vector<icu::Formattable> argValues;
                  std::vector<icu::UnicodeString> argNames;
                  if (args)
                      getICUArgs(key, *args, argNames, argValues);
                  return ctx.mData->formatMessage(key, argNames, argValues);
              };

        return sol::make_object(
            lua, [manager](std::string_view contextName, sol::optional<std::string> fallbackLocale) {
                if (fallbackLocale)
                    return L10nContext{ manager->getContext(contextName, *fallbackLocale) };
                else
                    return L10nContext{ manager->getContext(contextName) };
            });
    }
}