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.bergmann@allotropia.de>
This commit is contained in:
parent
2df1dcc324
commit
27ceca1996
37
include/static/unoembindhelpers/PrimaryBindings.hxx
Normal file
37
include/static/unoembindhelpers/PrimaryBindings.hxx
Normal file
@ -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: */
|
@ -226,12 +226,13 @@ Some usage examples through javascript of the current implementation:
|
|||||||
init_unoembind_uno(Module);
|
init_unoembind_uno(Module);
|
||||||
let css = Module.unoembind_uno.com.sun.star;
|
let css = Module.unoembind_uno.com.sun.star;
|
||||||
xModel = Module.getCurrentModelFromViewSh();
|
xModel = Module.getCurrentModelFromViewSh();
|
||||||
xTextDocument = new css.text.XTextDocument(xModel, Module.UnoReference_Query.UNO_QUERY);
|
xTextDocument = new css.text.XTextDocument(xModel.$query());
|
||||||
xText = xTextDocument.getText();
|
xText = xTextDocument.getText();
|
||||||
xSimpleText = new css.text.XSimpleText(xText, Module.UnoReference_Query.UNO_QUERY);
|
xSimpleText = new css.text.XSimpleText(xText.$query());
|
||||||
xTextCursor = xSimpleText.createTextCursor();
|
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!"));
|
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();
|
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);
|
init_unoembind_uno(Module);
|
||||||
let css = Module.unoembind_uno.com.sun.star;
|
let css = Module.unoembind_uno.com.sun.star;
|
||||||
xModel = Module.getCurrentModelFromViewSh();
|
xModel = Module.getCurrentModelFromViewSh();
|
||||||
xTextDocument = new css.text.XTextDocument(xModel, Module.UnoReference_Query.UNO_QUERY);
|
init_unoembind_uno(Module);
|
||||||
xText = xTextDocument.getText();
|
xEnumAccess = new css.container.XEnumerationAccess(xText.$query());
|
||||||
xEnumAccess = new css.container.XEnumerationAccess(xText, Module.UnoReference_Query.UNO_QUERY);
|
|
||||||
xParaEnumeration = xEnumAccess.createEnumeration();
|
xParaEnumeration = xEnumAccess.createEnumeration();
|
||||||
|
|
||||||
while (xParaEnumeration.hasMoreElements()) {
|
while (xParaEnumeration.hasMoreElements()) {
|
||||||
xParagraph = new css.text.XTextRange();
|
xParagraph = new css.text.XTextRange(xParaEnumeration.nextElement(), Module.uno_Reference.FromAny);
|
||||||
xParagraph.set(xParaEnumeration.nextElement(), Module.UnoReference_Query.UNO_QUERY);
|
if (xParagraph.$is()) {
|
||||||
if (xParagraph.is()) {
|
xParaProps = new css.beans.XPropertySet(xParagraph.$query());
|
||||||
xParaProps = new css.beans.XPropertySet(xParagraph, Module.UnoReference_Query.UNO_QUERY);
|
|
||||||
xParaProps.setPropertyValue(new Module.OUString("CharColor"), new Module.Any(Math.floor(Math.random() * 0xFFFFFF), Module.UnoType.long));
|
xParaProps.setPropertyValue(new Module.OUString("CharColor"), new Module.Any(Math.floor(Math.random() * 0xFFFFFF), Module.UnoType.long));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,52 +391,31 @@ void dumpParameters(std::ostream& out, rtl::Reference<TypeManager> const& manage
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dumpWrapper(std::ostream& out, rtl::Reference<TypeManager> const& manager,
|
void dumpWrapper(std::ostream& out, rtl::Reference<TypeManager> const& manager,
|
||||||
OUString const& interfaceName, unoidl::InterfaceTypeEntity::Method const& method,
|
OUString const& interfaceName, unoidl::InterfaceTypeEntity::Method const& method)
|
||||||
bool forReference)
|
|
||||||
{
|
{
|
||||||
out << " .function(\"" << method.name << "\", +[](";
|
out << " .function(\"" << method.name << "\", +[](" << cppName(interfaceName);
|
||||||
if (forReference)
|
|
||||||
{
|
|
||||||
out << "::com::sun::star::uno::Reference<";
|
|
||||||
}
|
|
||||||
out << cppName(interfaceName);
|
|
||||||
if (forReference)
|
|
||||||
{
|
|
||||||
out << ">";
|
|
||||||
}
|
|
||||||
out << " * the_self";
|
out << " * the_self";
|
||||||
if (!method.parameters.empty())
|
if (!method.parameters.empty())
|
||||||
{
|
{
|
||||||
out << ", ";
|
out << ", ";
|
||||||
}
|
}
|
||||||
dumpParameters(out, manager, method, true);
|
dumpParameters(out, manager, method, true);
|
||||||
out << ") { return the_self->";
|
out << ") { return the_self->" << method.name << "(";
|
||||||
if (forReference)
|
|
||||||
{
|
|
||||||
out << "get()->";
|
|
||||||
}
|
|
||||||
out << method.name << "(";
|
|
||||||
dumpParameters(out, manager, method, false);
|
dumpParameters(out, manager, method, false);
|
||||||
out << "); }, ::emscripten::allow_raw_pointers())\n";
|
out << "); }, ::emscripten::allow_raw_pointers())\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void dumpMethods(std::ostream& out, rtl::Reference<TypeManager> const& manager,
|
void dumpMethods(std::ostream& out, rtl::Reference<TypeManager> const& manager,
|
||||||
OUString const& name, rtl::Reference<unoidl::InterfaceTypeEntity> const& entity,
|
OUString const& name, rtl::Reference<unoidl::InterfaceTypeEntity> const& entity)
|
||||||
bool forReference)
|
|
||||||
{
|
{
|
||||||
for (auto const& meth : entity->getDirectMethods())
|
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);
|
dumpWrapper(out, manager, name, meth);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -455,7 +434,7 @@ void writeJsMap(std::ostream& out, Module const& module, std::string const& pref
|
|||||||
{
|
{
|
||||||
out << ",\n";
|
out << ",\n";
|
||||||
}
|
}
|
||||||
out << prefix << "'" << ifc.copy(ifc.lastIndexOf('.') + 1) << "': instance.uno_Reference_"
|
out << prefix << "'" << ifc.copy(ifc.lastIndexOf('.') + 1) << "': instance.uno_Type_"
|
||||||
<< jsName(ifc);
|
<< jsName(ifc);
|
||||||
comma = true;
|
comma = true;
|
||||||
}
|
}
|
||||||
@ -518,7 +497,8 @@ SAL_IMPLEMENT_MAIN()
|
|||||||
}
|
}
|
||||||
cppOut << "#include <emscripten/bind.h>\n"
|
cppOut << "#include <emscripten/bind.h>\n"
|
||||||
"#include <com/sun/star/uno/Any.hxx>\n"
|
"#include <com/sun/star/uno/Any.hxx>\n"
|
||||||
"#include <com/sun/star/uno/Reference.hxx>\n";
|
"#include <com/sun/star/uno/Reference.hxx>\n"
|
||||||
|
"#include <static/unoembindhelpers/PrimaryBindings.hxx>\n";
|
||||||
for (auto const& ifc : interfaces)
|
for (auto const& ifc : interfaces)
|
||||||
{
|
{
|
||||||
cppOut << "#include <" << ifc.replace('.', '/') << ".hpp>\n";
|
cppOut << "#include <" << ifc.replace('.', '/') << ".hpp>\n";
|
||||||
@ -544,33 +524,31 @@ SAL_IMPLEMENT_MAIN()
|
|||||||
cppOut << "static void __attribute__((noinline)) register" << n
|
cppOut << "static void __attribute__((noinline)) register" << n
|
||||||
<< "() {\n"
|
<< "() {\n"
|
||||||
" ::emscripten::class_<"
|
" ::emscripten::class_<"
|
||||||
<< cppName(ifc) << ">(\"uno_Type_" << jsName(ifc) << "\")\n";
|
<< cppName(ifc) << ">(\"uno_Type_" << jsName(ifc)
|
||||||
|
<< "\")\n"
|
||||||
|
" .smart_ptr<::com::sun::star::uno::Reference<"
|
||||||
|
<< cppName(ifc) << ">>(\"uno_Reference_" << jsName(ifc)
|
||||||
|
<< "\")\n"
|
||||||
|
" "
|
||||||
|
".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); })\n"
|
||||||
|
" .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); })\n"
|
||||||
|
" .function(\"$is\", +[](::com::sun::star::uno::Reference<"
|
||||||
|
<< cppName(ifc)
|
||||||
|
<< "> const & the_self) { return the_self.is(); })\n"
|
||||||
|
" .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); })\n";
|
||||||
dumpAttributes(cppOut, ifc, ifcEnt);
|
dumpAttributes(cppOut, ifc, ifcEnt);
|
||||||
dumpMethods(cppOut, mgr, ifc, ifcEnt, false);
|
dumpMethods(cppOut, mgr, ifc, ifcEnt);
|
||||||
cppOut
|
|
||||||
<< " ;\n"
|
|
||||||
" ::emscripten::class_<::com::sun::star::uno::Reference<"
|
|
||||||
<< cppName(ifc)
|
|
||||||
<< ">, ::emscripten::base<::com::sun::star::uno::BaseReference>>(\"uno_Reference_"
|
|
||||||
<< jsName(ifc)
|
|
||||||
<< "\")\n"
|
|
||||||
" .constructor<>()\n"
|
|
||||||
" .constructor<::com::sun::star::uno::BaseReference, "
|
|
||||||
"::com::sun::star::uno::UnoReference_Query>()\n"
|
|
||||||
" .function(\"is\", &::com::sun::star::uno::Reference<"
|
|
||||||
<< cppName(ifc)
|
|
||||||
<< ">::is)\n"
|
|
||||||
" .function(\"get\", &::com::sun::star::uno::Reference<"
|
|
||||||
<< cppName(ifc)
|
|
||||||
<< ">::get, ::emscripten::allow_raw_pointers())\n"
|
|
||||||
" .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))\n";
|
|
||||||
dumpAttributes(cppOut, ifc, ifcEnt);
|
|
||||||
dumpMethods(cppOut, mgr, ifc, ifcEnt, true);
|
|
||||||
cppOut << " ;\n"
|
cppOut << " ;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
++n;
|
++n;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <sal/log.hxx>
|
#include <sal/log.hxx>
|
||||||
#include <sfx2/viewsh.hxx>
|
#include <sfx2/viewsh.hxx>
|
||||||
|
#include <static/unoembindhelpers/PrimaryBindings.hxx>
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
using namespace css::uno;
|
using namespace css::uno;
|
||||||
@ -34,8 +35,8 @@ Reference<css::frame::XModel> getCurrentModelFromViewSh()
|
|||||||
EMSCRIPTEN_BINDINGS(PrimaryBindings)
|
EMSCRIPTEN_BINDINGS(PrimaryBindings)
|
||||||
{
|
{
|
||||||
// Reference bits
|
// Reference bits
|
||||||
class_<BaseReference>("BaseReference");
|
enum_<unoembindhelpers::uno_Reference>("uno_Reference")
|
||||||
enum_<UnoReference_Query>("UnoReference_Query").value("UNO_QUERY", UNO_QUERY);
|
.value("FromAny", unoembindhelpers::uno_Reference::FromAny);
|
||||||
|
|
||||||
class_<OUString>("OUString")
|
class_<OUString>("OUString")
|
||||||
.constructor(+[](const std::u16string& rString) -> OUString { return OUString(rString); },
|
.constructor(+[](const std::u16string& rString) -> OUString { return OUString(rString); },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user