From 0bab5cda2123ecc7f3775d05ca5103bdef23bfe8 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Fri, 1 Mar 2024 14:30:38 +0100 Subject: [PATCH] Add Embing'ing of UNO Any getter for enums ...which taps into the internals of emscripten::val, which is based on std::type_info identifiers, so we need an additional statically-built mapping between UNO (enum, for now) types and std::type_info Change-Id: I9fc1ff33fe31a1e1052504905de446ed2193e014 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164359 Tested-by: Jenkins Reviewed-by: Stephan Bergmann --- .../unoembindhelpers/PrimaryBindings.hxx | 13 ++++++++ static/source/embindmaker/embindmaker.cxx | 1 + .../unoembindhelpers/PrimaryBindings.cxx | 33 ++++++++++++++++++- unotest/source/embindtest/embindtest.js | 2 +- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/include/static/unoembindhelpers/PrimaryBindings.hxx b/include/static/unoembindhelpers/PrimaryBindings.hxx index 80b55d5278ac..13ddd05cce26 100644 --- a/include/static/unoembindhelpers/PrimaryBindings.hxx +++ b/include/static/unoembindhelpers/PrimaryBindings.hxx @@ -14,11 +14,14 @@ #include #include #include +#include #include #include #include +#include +#include #include template struct emscripten::smart_ptr_trait> @@ -33,6 +36,11 @@ template struct emscripten::smart_ptr_trait> namespace unoembindhelpers { +namespace detail +{ +void registerUnoType(css::uno::Type const& type, std::type_info const* id); +} + enum class uno_Reference { FromAny @@ -76,6 +84,11 @@ void checkSequenceAccess(css::uno::Sequence const& sequence, sal_Int32 index) } } +template void registerUnoType() +{ + detail::registerUnoType(cppu::UnoType::get(), &typeid(T)); +} + template void registerSequence(char const* name) { emscripten::class_>(name) diff --git a/static/source/embindmaker/embindmaker.cxx b/static/source/embindmaker/embindmaker.cxx index 89fdf834ea1d..36b1f56fd5a3 100644 --- a/static/source/embindmaker/embindmaker.cxx +++ b/static/source/embindmaker/embindmaker.cxx @@ -849,6 +849,7 @@ SAL_IMPLEMENT_MAIN() << mem.name << ")"; } cppOut << ";\n"; + cppOut << " ::unoembindhelpers::registerUnoType<" << cppName(enm) << ">();\n"; dumpRegisterFunctionEpilog(cppOut, n); } std::set sequences; diff --git a/static/source/unoembindhelpers/PrimaryBindings.cxx b/static/source/unoembindhelpers/PrimaryBindings.cxx index 5b76b549cb13..7cf99c523f0d 100644 --- a/static/source/unoembindhelpers/PrimaryBindings.cxx +++ b/static/source/unoembindhelpers/PrimaryBindings.cxx @@ -31,6 +31,7 @@ #include #include #include +#include using namespace emscripten; using namespace css::uno; @@ -166,6 +167,31 @@ Reference getCurrentModelFromViewSh() } return pSh->GetCurrentDocument(); } + +struct LessType +{ + bool operator()(css::uno::Type const& type1, css::uno::Type const& type2) const + { + return type1.getTypeLibType() < type2.getTypeLibType(); + } +}; + +std::map unoTypes; + +std::type_info const* getTypeId(css::uno::Type const& type) +{ + auto const i = unoTypes.find(type); + if (i == unoTypes.end()) + { + throw std::runtime_error("unregistered UNO type"); + } + return i->second; +} +} + +namespace unoembindhelpers::detail +{ +void registerUnoType(css::uno::Type const& type, std::type_info const* id) { unoTypes[type] = id; } } EMSCRIPTEN_BINDINGS(PrimaryBindings) @@ -263,7 +289,12 @@ EMSCRIPTEN_BINDINGS(PrimaryBindings) case css::uno::TypeClass_SEQUENCE: return emscripten::val::undefined(); //TODO case css::uno::TypeClass_ENUM: - return emscripten::val::undefined(); //TODO + { + emscripten::internal::WireTypePack argv( + std::move(*static_cast(self.getValue()))); + return emscripten::val::take_ownership( + _emval_take_value(getTypeId(self.getValueType()), argv)); + } case css::uno::TypeClass_STRUCT: return emscripten::val::undefined(); //TODO case css::uno::TypeClass_EXCEPTION: diff --git a/unotest/source/embindtest/embindtest.js b/unotest/source/embindtest/embindtest.js index ab50c859e13e..d391f5bd15f5 100644 --- a/unotest/source/embindtest/embindtest.js +++ b/unotest/source/embindtest/embindtest.js @@ -265,7 +265,7 @@ Module.addOnPostRun(function() { { let v = test.getAnyEnum(); console.log(v); - //TODO: console.assert(v.get() === uno.org.libreoffice.embindtest.Enum.E_2); + console.assert(v.get() === uno.org.libreoffice.embindtest.Enum.E_2); console.assert(test.isAnyEnum(v)); v.delete(); //TODO: let a = new Module.Any(