include/static/unoembindhelpers/PrimaryBindings.hxx | 37 +++++++ static/README.wasm.md | 19 +--- static/source/embindmaker/embindmaker.cxx | 94 +++++++------------- static/source/unoembindhelpers/PrimaryBindings.cxx | 5 - 4 files changed, 85 insertions(+), 70 deletions(-)
New commits: commit 27ceca1996809c0f9390d1e9fb95dc7436ef1acf Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Mon Jan 29 15:57:30 2024 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Tue Jan 30 07:40:02 2024 +0100 Rework the Embind mapping of UNO interfaces ...to make use of the automatic finalization clean-up of smart pointers available with recent versions of Embind (so that explicitly calling delete() on them should largely be optional now). See the changes to static/README.wasm.md for how code should look like now. (The Module.uno_Reference.FromAny dummy argument for the interface constructor converting from an Any is only necessary to distinguish it from the other constructor, as otherwise Embind complains because: "Overload resolution is currently only performed using the parameter count, not actual type info!") Change-Id: Ia8a8c12e38af1093948bf8a20ecd31aa6591e912 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162697 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de> diff --git a/include/static/unoembindhelpers/PrimaryBindings.hxx b/include/static/unoembindhelpers/PrimaryBindings.hxx new file mode 100644 index 000000000000..0c744502848e --- /dev/null +++ b/include/static/unoembindhelpers/PrimaryBindings.hxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/config.h> + +#include <emscripten/bind.h> + +#include <com/sun/star/uno/Reference.hxx> +#include <sal/types.h> + +template <typename T> struct emscripten::smart_ptr_trait<css::uno::Reference<T>> +{ + using PointerType = css::uno::Reference<T>; + using element_type = T; + static T* get(css::uno::Reference<T> const& ptr) { return ptr.get(); } + static sharing_policy get_sharing_policy() { return sharing_policy::INTRUSIVE; } + static css::uno::Reference<T>* share(T* v) { return new css::uno::Reference<T>(v); } + static css::uno::Reference<T>* construct_null() { return new css::uno::Reference<T>(); } +}; + +namespace unoembindhelpers +{ +enum class uno_Reference +{ + FromAny +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/static/README.wasm.md b/static/README.wasm.md index da5d80309bf0..80e9e75607c0 100644 --- a/static/README.wasm.md +++ b/static/README.wasm.md @@ -226,12 +226,13 @@ Some usage examples through javascript of the current implementation: init_unoembind_uno(Module); let css = Module.unoembind_uno.com.sun.star; xModel = Module.getCurrentModelFromViewSh(); -xTextDocument = new css.text.XTextDocument(xModel, Module.UnoReference_Query.UNO_QUERY); +xTextDocument = new css.text.XTextDocument(xModel.$query()); xText = xTextDocument.getText(); -xSimpleText = new css.text.XSimpleText(xText, Module.UnoReference_Query.UNO_QUERY); +xSimpleText = new css.text.XSimpleText(xText.$query()); xTextCursor = xSimpleText.createTextCursor(); -xTextRange = new css.text.XTextRange(xTextCursor, Module.UnoReference_Query.UNO_QUERY); +xTextRange = new css.text.XTextRange(xTextCursor.$query()); xTextRange.setString(new Module.OUString("string here!")); +xSimpleText.delete(); xTextCursor.delete(); xTextRange.delete(); xModel.delete(); xTextDocument.delete(); xText.delete(); xSimpleText.delete(); xTextCursor.delete(); xTextRange.delete(); ``` @@ -240,16 +241,14 @@ xModel.delete(); xTextDocument.delete(); xText.delete(); xSimpleText.delete(); x init_unoembind_uno(Module); let css = Module.unoembind_uno.com.sun.star; xModel = Module.getCurrentModelFromViewSh(); -xTextDocument = new css.text.XTextDocument(xModel, Module.UnoReference_Query.UNO_QUERY); -xText = xTextDocument.getText(); -xEnumAccess = new css.container.XEnumerationAccess(xText, Module.UnoReference_Query.UNO_QUERY); +init_unoembind_uno(Module); +xEnumAccess = new css.container.XEnumerationAccess(xText.$query()); xParaEnumeration = xEnumAccess.createEnumeration(); while (xParaEnumeration.hasMoreElements()) { - xParagraph = new css.text.XTextRange(); - xParagraph.set(xParaEnumeration.nextElement(), Module.UnoReference_Query.UNO_QUERY); - if (xParagraph.is()) { - xParaProps = new css.beans.XPropertySet(xParagraph, Module.UnoReference_Query.UNO_QUERY); + xParagraph = new css.text.XTextRange(xParaEnumeration.nextElement(), Module.uno_Reference.FromAny); + if (xParagraph.$is()) { + xParaProps = new css.beans.XPropertySet(xParagraph.$query()); xParaProps.setPropertyValue(new Module.OUString("CharColor"), new Module.Any(Math.floor(Math.random() * 0xFFFFFF), Module.UnoType.long)); } } diff --git a/static/source/embindmaker/embindmaker.cxx b/static/source/embindmaker/embindmaker.cxx index b7c9b1a51eb2..0da6ce2ad41c 100644 --- a/static/source/embindmaker/embindmaker.cxx +++ b/static/source/embindmaker/embindmaker.cxx @@ -391,52 +391,31 @@ void dumpParameters(std::ostream& out, rtl::Reference<TypeManager> const& manage } void dumpWrapper(std::ostream& out, rtl::Reference<TypeManager> const& manager, - OUString const& interfaceName, unoidl::InterfaceTypeEntity::Method const& method, - bool forReference) + OUString const& interfaceName, unoidl::InterfaceTypeEntity::Method const& method) { - out << " .function(\"" << method.name << "\", +[]("; - if (forReference) - { - out << "::com::sun::star::uno::Reference<"; - } - out << cppName(interfaceName); - if (forReference) - { - out << ">"; - } + out << " .function(\"" << method.name << "\", +[](" << cppName(interfaceName); out << " * the_self"; if (!method.parameters.empty()) { out << ", "; } dumpParameters(out, manager, method, true); - out << ") { return the_self->"; - if (forReference) - { - out << "get()->"; - } - out << method.name << "("; + out << ") { return the_self->" << method.name << "("; dumpParameters(out, manager, method, false); out << "); }, ::emscripten::allow_raw_pointers()) "; } void dumpMethods(std::ostream& out, rtl::Reference<TypeManager> const& manager, - OUString const& name, rtl::Reference<unoidl::InterfaceTypeEntity> const& entity, - bool forReference) + OUString const& name, rtl::Reference<unoidl::InterfaceTypeEntity> const& entity) { for (auto const& meth : entity->getDirectMethods()) { - if (forReference) + if (std::any_of(meth.parameters.begin(), meth.parameters.end(), [](auto const& parameter) { + return parameter.direction + != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN; + })) { - dumpWrapper(out, manager, name, meth, true); - } - else if (std::any_of( - meth.parameters.begin(), meth.parameters.end(), [](auto const& parameter) { - return parameter.direction - != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN; - })) - { - dumpWrapper(out, manager, name, meth, false); + dumpWrapper(out, manager, name, meth); } else { @@ -455,7 +434,7 @@ void writeJsMap(std::ostream& out, Module const& module, std::string const& pref { out << ", "; } - out << prefix << "'" << ifc.copy(ifc.lastIndexOf('.') + 1) << "': instance.uno_Reference_" + out << prefix << "'" << ifc.copy(ifc.lastIndexOf('.') + 1) << "': instance.uno_Type_" << jsName(ifc); comma = true; } @@ -518,7 +497,8 @@ SAL_IMPLEMENT_MAIN() } cppOut << "#include <emscripten/bind.h> " "#include <com/sun/star/uno/Any.hxx> " - "#include <com/sun/star/uno/Reference.hxx> "; + "#include <com/sun/star/uno/Reference.hxx> " + "#include <static/unoembindhelpers/PrimaryBindings.hxx> "; for (auto const& ifc : interfaces) { cppOut << "#include <" << ifc.replace('.', '/') << ".hpp> "; @@ -544,33 +524,31 @@ SAL_IMPLEMENT_MAIN() cppOut << "static void __attribute__((noinline)) register" << n << "() { " " ::emscripten::class_<" - << cppName(ifc) << ">(\"uno_Type_" << jsName(ifc) << "\") "; - dumpAttributes(cppOut, ifc, ifcEnt); - dumpMethods(cppOut, mgr, ifc, ifcEnt, false); - cppOut - << " ; " - " ::emscripten::class_<::com::sun::star::uno::Reference<" - << cppName(ifc) - << ">, ::emscripten::base<::com::sun::star::uno::BaseReference>>(\"uno_Reference_" - << jsName(ifc) - << "\") " - " .constructor<>() " - " .constructor<::com::sun::star::uno::BaseReference, " - "::com::sun::star::uno::UnoReference_Query>() " - " .function(\"is\", &::com::sun::star::uno::Reference<" - << cppName(ifc) - << ">::is) " - " .function(\"get\", &::com::sun::star::uno::Reference<" - << cppName(ifc) - << ">::get, ::emscripten::allow_raw_pointers()) " - " .function(\"set\", " - "::emscripten::select_overload<bool(::com::sun::star::uno::Any const " - "&, " - "com::sun::star::uno::UnoReference_Query)>(&::com::sun::star::uno::" - "Reference<" - << cppName(ifc) << ">::set)) "; + << cppName(ifc) << ">(\"uno_Type_" << jsName(ifc) + << "\") " + " .smart_ptr<::com::sun::star::uno::Reference<" + << cppName(ifc) << ">>(\"uno_Reference_" << jsName(ifc) + << "\") " + " " + ".constructor(+[](::com::sun::star::uno::Reference<::com::sun::star::uno::" + "XInterface> const & the_object) { return ::com::sun::star::uno::Reference<" + << cppName(ifc) + << ">(the_object, ::com::sun::star::uno::UNO_QUERY); }) " + " .constructor(+[](::com::sun::star::uno::Any const & the_object, " + "[[maybe_unused]] ::unoembindhelpers::uno_Reference) { return " + "::com::sun::star::uno::Reference<" + << cppName(ifc) + << ">(the_object, ::com::sun::star::uno::UNO_QUERY); }) " + " .function(\"$is\", +[](::com::sun::star::uno::Reference<" + << cppName(ifc) + << "> const & the_self) { return the_self.is(); }) " + " .function(\"$query\", +[](::com::sun::star::uno::Reference<" + << cppName(ifc) + << "> const & the_self) { return " + "::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface>(the_" + "self); }) "; dumpAttributes(cppOut, ifc, ifcEnt); - dumpMethods(cppOut, mgr, ifc, ifcEnt, true); + dumpMethods(cppOut, mgr, ifc, ifcEnt); cppOut << " ; " "} "; ++n; diff --git a/static/source/unoembindhelpers/PrimaryBindings.cxx b/static/source/unoembindhelpers/PrimaryBindings.cxx index 1baf676dadc0..db75924b76f0 100644 --- a/static/source/unoembindhelpers/PrimaryBindings.cxx +++ b/static/source/unoembindhelpers/PrimaryBindings.cxx @@ -13,6 +13,7 @@ #include <sal/log.hxx> #include <sfx2/viewsh.hxx> +#include <static/unoembindhelpers/PrimaryBindings.hxx> using namespace emscripten; using namespace css::uno; @@ -34,8 +35,8 @@ Reference<css::frame::XModel> getCurrentModelFromViewSh() EMSCRIPTEN_BINDINGS(PrimaryBindings) { // Reference bits - class_<BaseReference>("BaseReference"); - enum_<UnoReference_Query>("UnoReference_Query").value("UNO_QUERY", UNO_QUERY); + enum_<unoembindhelpers::uno_Reference>("uno_Reference") + .value("FromAny", unoembindhelpers::uno_Reference::FromAny); class_<OUString>("OUString") .constructor(+[](const std::u16string& rString) -> OUString { return OUString(rString); },