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); },

Reply via email to