diff options
author | Sarper Akdemir <sarper.akdemir.extern@allotropia.de> | 2023-08-07 14:41:32 +0300 |
---|---|---|
committer | Sarper Akdemir <sarper.akdemir.extern@allotropia.de> | 2023-09-18 19:59:57 +0200 |
commit | 841f898574affb526a516224d7c3db9b137ea62b (patch) | |
tree | b26718c1a063f47b2a75eb939b4fd0d55f90f79f /static | |
parent | 971425f9b7613183a565e9b4ec5792b3f67bb133 (diff) |
JavaScript uno bindings for WASM with Embind - first cut
A rough implementation of uno bindings for LOWA using embind.
Adds new parameter '-W' to cppumaker to generate _embind.cxx
files alongside .hdl & .hpp.
For usage examples see static/README.wasm.md
Change-Id: Iee5d05e37bfba8e101c08212b15c05f7f2fa6c33
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156273
Tested-by: Jenkins
Reviewed-by: Sarper Akdemir <sarper.akdemir.extern@allotropia.de>
Diffstat (limited to 'static')
-rw-r--r-- | static/README.wasm.md | 39 | ||||
-rw-r--r-- | static/source/unoembindhelpers/PrimaryBindings.cxx | 121 |
2 files changed, 160 insertions, 0 deletions
diff --git a/static/README.wasm.md b/static/README.wasm.md index 6e74599eb3ae..f39a79247d00 100644 --- a/static/README.wasm.md +++ b/static/README.wasm.md @@ -214,6 +214,45 @@ WASM dynamic dispatch: - <https://fitzgeraldnick.com/2018/04/26/how-does-dynamic-dispatch-work-in-wasm.html> +### UNO bindings with Embind + +Right now there's a very rough implementation in place. With lots of different +bits unimplemented. And it _might_ be leaking memory. i.e. Lots of room for +improvement! ;) + +Some usage examples through javascript of the current implementation: +```js +// inserts a string at the start of the Writer document. +xModel = Module.getCurrentModelFromViewSh(); +xTextDocument = new Module.com$sun$star$text$XTextDocumentRef(xModel, Module.UnoReference_Query.UNO_QUERY); +xText = xTextDocument.getText(); +xSimpleText = new Module.com$sun$star$text$XSimpleTextRef(xText, Module.UnoReference_Query.UNO_QUERY); +xTextCursor = xSimpleText.createTextCursor(); +xTextRange = new Module.com$sun$star$text$XTextRangeRef(xTextCursor, Module.UnoReference_Query.UNO_QUERY); +xTextRange.setString(new Module.OUString("string here!")); +xModel.delete(); xTextDocument.delete(); xText.delete(); xSimpleText.delete(); xTextCursor.delete(); xTextRange.delete(); +``` + +```js +// changes each paragraph of the Writer document to a random color. +xModel = Module.getCurrentModelFromViewSh(); +xTextDocument = new Module.com$sun$star$text$XTextDocumentRef(xModel, Module.UnoReference_Query.UNO_QUERY); +xText = xTextDocument.getText(); +xEnumAccess = new Module.com$sun$star$container$XEnumerationAccessRef(xText, Module.UnoReference_Query.UNO_QUERY); +xParaEnumeration = xEnumAccess.createEnumeration(); + +while (xParaEnumeration.hasMoreElements()) { + xParagraph = new Module.com$sun$star$text$XTextRangeRef(); + xParagraph.set(xParaEnumeration.nextElement(), Module.UnoReference_Query.UNO_QUERY); + if (xParagraph.is()) { + xParaProps = new Module.com$sun$star$beans$XPropertySetRef(xParagraph, Module.UnoReference_Query.UNO_QUERY); + xParaProps.setPropertyValue(new Module.OUString("CharColor"), new Module.Any(Math.floor(Math.random() * 0xFFFFFF), Module.UnoType.long)); + } +} +``` + + + ## Tools for problem diagnosis * `nm -s` should list the symbols in the archive, based on the index generated by ranlib. diff --git a/static/source/unoembindhelpers/PrimaryBindings.cxx b/static/source/unoembindhelpers/PrimaryBindings.cxx new file mode 100644 index 000000000000..e9a0c496310b --- /dev/null +++ b/static/source/unoembindhelpers/PrimaryBindings.cxx @@ -0,0 +1,121 @@ +/* -*- 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/. + */ +#ifdef EMSCRIPTEN +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/uno/XReference.hpp> + +#include <emscripten/bind.h> + +#include <sal/log.hxx> +#include <sfx2/viewsh.hxx> + +using namespace emscripten; +using namespace css::uno; + +namespace +{ +Reference<css::frame::XModel> getCurrentModelFromViewSh() +{ + SfxViewShell* pSh = nullptr; + pSh = SfxViewShell::Current(); + if (!pSh) + { + return {}; + } + return pSh->GetCurrentDocument(); +} +} + +EMSCRIPTEN_BINDINGS(PrimaryBindings) +{ + // Reference bits + class_<BaseReference>("BaseReference"); + enum_<UnoReference_Query>("UnoReference_Query").value("UNO_QUERY", UNO_QUERY); + + class_<OUString>("OUString") + .constructor( + +[](const std::string& rString) -> OUString { + return OUString::fromUtf8(std::string_view{ rString.c_str() }); + }, + allow_raw_pointers()) + .function("toString", +[](const OUString& rSelf) -> std::string { + return std::string{ rSelf.toUtf8() }; + }); + + // Types used for Any construction + enum_<TypeClass>("UnoType") + .value("void", TypeClass::TypeClass_VOID) + .value("char", TypeClass::TypeClass_CHAR) + .value("bool", TypeClass::TypeClass_BOOLEAN) + .value("byte", TypeClass::TypeClass_BYTE) + .value("short", TypeClass::TypeClass_SHORT) + .value("unsigned_short", TypeClass::TypeClass_UNSIGNED_SHORT) + .value("long", TypeClass::TypeClass_LONG) + .value("unsigned_long", TypeClass::TypeClass_UNSIGNED_LONG) + .value("hyper", TypeClass::TypeClass_HYPER) + .value("unsigned_hyper", TypeClass::TypeClass_UNSIGNED_HYPER) + .value("float", TypeClass::TypeClass_FLOAT) + .value("double", TypeClass::TypeClass_DOUBLE) + .value("string", TypeClass::TypeClass_STRING); + + // Any + class_<Any>("Any").constructor( + +[](const val& rObject, const TypeClass& rUnoType) -> Any { + switch (rUnoType) + { + case TypeClass_VOID: + break; + case TypeClass_CHAR: + return Any{ rObject.as<sal_Int8>() }; + case TypeClass_BOOLEAN: + return Any{ rObject.as<bool>() }; + case TypeClass_BYTE: + return Any{ rObject.as<sal_Int8>() }; + case TypeClass_SHORT: + return Any{ rObject.as<sal_Int16>() }; + case TypeClass_UNSIGNED_SHORT: + return Any{ rObject.as<sal_uInt16>() }; + case TypeClass_LONG: + return Any{ rObject.as<sal_Int32>() }; + case TypeClass_UNSIGNED_LONG: + return Any{ rObject.as<sal_uInt32>() }; + case TypeClass_HYPER: + return Any{ rObject.as<sal_Int64>() }; + case TypeClass_UNSIGNED_HYPER: + return Any{ rObject.as<sal_uInt64>() }; + case TypeClass_FLOAT: + return Any{ rObject.as<float>() }; + case TypeClass_DOUBLE: + return Any{ rObject.as<double>() }; + case TypeClass_STRING: + return Any{ OUString::fromUtf8(std::string_view{ rObject.as<std::string>() }) }; + case TypeClass_TYPE: + case TypeClass_ANY: + case TypeClass_ENUM: + case TypeClass_STRUCT: + case TypeClass_EXCEPTION: + case TypeClass_SEQUENCE: + case TypeClass_INTERFACE: + case TypeClass_TYPEDEF: + case TypeClass_SERVICE: + case TypeClass_MODULE: + case TypeClass_INTERFACE_METHOD: + case TypeClass_INTERFACE_ATTRIBUTE: + default: + break; + } + return {}; + }, + allow_raw_pointers()); + + function("getCurrentModelFromViewSh", &getCurrentModelFromViewSh); +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |