summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authorSarper Akdemir <sarper.akdemir.extern@allotropia.de>2023-08-07 14:41:32 +0300
committerSarper Akdemir <sarper.akdemir.extern@allotropia.de>2023-09-18 19:59:57 +0200
commit841f898574affb526a516224d7c3db9b137ea62b (patch)
treeb26718c1a063f47b2a75eb939b4fd0d55f90f79f /static
parent971425f9b7613183a565e9b4ec5792b3f67bb133 (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.md39
-rw-r--r--static/source/unoembindhelpers/PrimaryBindings.cxx121
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: */