mirror of
https://github.com/logos-co/logos-tutorial.git
synced 2026-08-27 10:51:12 +00:00
test(doctests): lm publishes the LIDL contract vocabulary, not Qt names
A universal module's `getMethods()` comes from the cdylib backend's
`lidlInterfaceJson()` (logos-plugin-qt's glue forwards
`logos_module_get_methods` verbatim), and that now answers in the LIDL
contract spelling. `lm methods`, `lm events` and `logoscore module-info`
print those strings straight through, so every listing in Part 1 changed:
qlonglong add(qlonglong a, qlonglong b) -> int add(int a, int b)
QString libVersion() -> tstr libVersion()
void versionReady(QString version) -> void versionReady(tstr version)
Six `expect_contains` in tutorial-wrapping-c-library.test.yaml were pinned
to the Qt spellings and now fail.
HOW THIS WAS ALMOST MISSED, because the trap will recur. The hand-pinned
`outputs/tutorial-wrapping-c-library.md` already showed `int add(int a, int b)`
and `add(int,int)` — a stale snapshot from an earlier era that happened to
read as "already LIDL, nothing to do". CI runs the ASSERTIONS in
`tests/*.test.yaml`; it never diffs the outputs tree. Clearing a file by
reading `outputs/` proves nothing.
Every replacement string is derived mechanically rather than by hand: the
tutorial's own `src/calc_module_impl.h` + `metadata.json` were run through
`logos-cpp-generator --from-header --backend cdylib`, the emitted
`lidlInterfaceJson()` was parsed back into JSON, and that JSON was rendered
through logos-module's own printer (`cmd/main.cpp`) and logoscore's
(`src/client/output.cpp`). The displayed blocks in BOTH trees now compare
byte-identical to that render.
Two accuracy fixes fall out of doing that, both pre-existing drift in the
blocks being rewritten:
* the derived identity methods `name()` / `version()` DO appear in every
listing (nothing filters `derived` on the read side) and were missing
from the shown output;
* the `module-info` block said `libVersion() -> QString` and
`versionReady(version: QString)`.
The C++-type table gains a column. "On the wire (Qt)" conflated two
different questions; it is now "LIDL contract type" — what the module
publishes, what Step 5 prints, what a Rust or Nim binding sees — and "A Qt
consumer sees", which is only the C++/Qt caller's spelling.
Also here, same cause:
* tutorial-composing-modules and tutorial-interface-dependencies had the
same "shows up as QString ... the wire types the generated glue exposes"
prose. Their assertions are name-only, so they did not fail — but they
described the listing wrongly. `LogosMap` publishes as `{tstr: any}`,
verified by generating calc_aggregator's glue.
* logos-developer-guide.md's `lm methods --json` example was a
handwritten-Qt listing (`initLogos(LogosAPI*)`) presented as the general
case. It now shows both publishers and says which is which: a universal
module publishes its contract, a handwritten Qt plugin publishes what its
QMetaObject says.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
dc4635d3c4
commit
d96387128d
@@ -442,17 +442,49 @@ Example JSON output:
|
||||
./lm/bin/lm methods ./result/lib/my_module_plugin.so --json
|
||||
```
|
||||
|
||||
Example JSON output:
|
||||
**The type names depend on which kind of module you are inspecting**, because
|
||||
two different things publish this JSON:
|
||||
|
||||
- A **universal / cdylib module** (`"interface": "universal"`, the style used
|
||||
throughout this guide and in the tutorials) publishes its **LIDL contract**
|
||||
types — `tstr`, `int`, `uint`, `bstr`, `[tstr]`, `{tstr: any}`, `? uint`,
|
||||
`result`, and a record's declared name. The module is Qt-free, so the
|
||||
contract is the only vocabulary in which the question has one answer, and
|
||||
a Rust module implementing the same contract answers identically.
|
||||
- A **handwritten Qt plugin** publishes what its `QMetaObject` says — `QString`,
|
||||
`QVariantList`, `QVariantMap` — because there the metaobject *is* the
|
||||
contract.
|
||||
|
||||
Example JSON output, for a universal module with
|
||||
`method doSomething(input: tstr) -> tstr`:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "initLogos",
|
||||
"signature": "initLogos(LogosAPI*)",
|
||||
"returnType": "void",
|
||||
"name": "doSomething",
|
||||
"signature": "doSomething(tstr)",
|
||||
"returnType": "tstr",
|
||||
"isInvokable": true,
|
||||
"parameters": [{ "name": "logosAPIInstance", "type": "LogosAPI*" }]
|
||||
"parameters": [{ "name": "input", "type": "tstr" }]
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"signature": "name()",
|
||||
"returnType": "tstr",
|
||||
"isInvokable": true,
|
||||
"description": "The module's name, as declared in its metadata."
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
`name` and `version` are **derived**: the generator emits them from
|
||||
`metadata.json`, so every module answers them without the author writing them,
|
||||
and they appear in every listing.
|
||||
|
||||
The same listing from a handwritten Qt plugin would instead read:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "doSomething",
|
||||
"signature": "doSomething(QString)",
|
||||
|
||||
@@ -485,7 +485,7 @@ Dependencies: calc_module
|
||||
./lm/bin/lm methods result/lib/calc_aggregator_plugin.dylib # macOS
|
||||
```
|
||||
|
||||
Every `public` method on the impl is here — `int64_t` shows up as `int`, `std::string` as `QString`, and `LogosMap` (from `computeReport`) as `QVariantMap`, because `lm` reports the wire types the generated glue exposes.
|
||||
Every `public` method on the impl is here, published in the **LIDL contract** vocabulary rather than in C++ or Qt names: `int64_t` shows up as `int`, `std::string` as `tstr`, and `LogosMap` (from `computeReport`) as `{tstr: any}`. `lm` is reporting what the module says about itself, and what a module publishes is its contract — the same words the generated `.lidl` uses, and the same words a Rust or Nim module implementing this contract would answer with.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -413,7 +413,7 @@ Dependencies:
|
||||
./lm/bin/lm methods result/lib/calc_via_interface_plugin.dylib # macOS
|
||||
```
|
||||
|
||||
Every `public` method is here. `int64_t` shows up as `int` and `std::string` as `QString` — the wire types the generated glue exposes.
|
||||
Every `public` method is here, published in the **LIDL contract** vocabulary rather than in C++ or Qt names: `int64_t` shows up as `int` and `std::string` as `tstr`. `lm` is reporting what the module says about itself, and what a module publishes is its contract.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -368,8 +368,8 @@ public:
|
||||
~CalcModuleImpl() = default;
|
||||
|
||||
// ── Public API — every method here is callable over IPC ──────────
|
||||
// The generator maps C++ types onto the wire automatically:
|
||||
// int64_t ↔ int std::string ↔ QString bool ↔ bool
|
||||
// The generator maps C++ types onto the contract automatically:
|
||||
// int64_t ↔ int std::string ↔ tstr bool ↔ bool
|
||||
//
|
||||
// A doc comment directly above a method becomes that method's
|
||||
// `description` in the module's method introspection — surfaced
|
||||
@@ -424,18 +424,24 @@ logos_events:
|
||||
- It's a normal C++ class. Any `public` method is exposed; `private` members and helpers are not.
|
||||
- **Supported parameter/return types** (what the generator can translate):
|
||||
|
||||
| C++ type | On the wire (Qt) |
|
||||
| --------------------------- | ------------------ |
|
||||
| `void` | `void` |
|
||||
| `bool` | `bool` |
|
||||
| `int64_t` | `int` |
|
||||
| `uint64_t` | `uint` |
|
||||
| `double` | `double` |
|
||||
| `std::string` | `QString` |
|
||||
| `std::vector<std::string>` | `QStringList` |
|
||||
| `std::vector<uint8_t>` | `QByteArray` |
|
||||
| `LogosMap` / `LogosList` | `QVariantMap` / `QVariantList` (from `<logos_json.h>`) |
|
||||
| `StdLogosResult` | `LogosResult` (from `<logos_result.h>`) — `{ success, value, error }` |
|
||||
| C++ type | LIDL contract type | A Qt consumer sees |
|
||||
| --------------------------- | ------------------ | ------------------ |
|
||||
| `void` | `void` | `void` |
|
||||
| `bool` | `bool` | `bool` |
|
||||
| `int64_t` | `int` | `qlonglong` |
|
||||
| `uint64_t` | `uint` | `qulonglong` |
|
||||
| `double` | `float64` | `double` |
|
||||
| `std::string` | `tstr` | `QString` |
|
||||
| `std::vector<std::string>` | `[tstr]` | `QStringList` |
|
||||
| `std::vector<uint8_t>` | `bstr` | `QByteArray` |
|
||||
| `LogosMap` / `LogosList` | `{tstr: any}` / `[any]` (from `<logos_json.h>`) | `QVariantMap` / `QVariantList` |
|
||||
| `StdLogosResult` | `result` | `LogosResult` (from `<logos_result.h>`) — `{ success, value, error }` |
|
||||
|
||||
The **middle** column is the one your module publishes about itself —
|
||||
it is what `lm` prints in Step 5, and what any other language's
|
||||
binding of this contract sees. The right column is what a *C++/Qt*
|
||||
caller of this module compiles against; a Rust or Nim caller gets
|
||||
that language's spelling of the same middle column.
|
||||
|
||||
- Use `int64_t` for integers (not `int`) — that's the type the parser recognizes.
|
||||
- **Document methods with `///`.** A doc comment (`///` or `/** … */`) directly above a method becomes its `description` in the module's introspection, surfaced by `lm`, `logoscore module-info`, and Basecamp. Plain `//` comments are ignored, so only intentional docs are exposed — you'll see this in action in Step 5.
|
||||
@@ -616,9 +622,12 @@ Dependencies: (none)
|
||||
```
|
||||
|
||||
Output — each method you declared, with its doc comment as a
|
||||
`Description`. A single-line comment renders inline; a multi-line
|
||||
comment (`factorial`'s two `///` lines, `libVersion`'s `/** ... */`
|
||||
block, and `libVersionNotify`'s two `///` lines) keeps its line breaks:
|
||||
`Description`, plus the two identity methods (`name`, `version`) the
|
||||
generator derives from `metadata.json` so every module answers them
|
||||
without you writing them. A single-line comment renders inline; a
|
||||
multi-line comment (`factorial`'s two `///` lines, `libVersion`'s
|
||||
`/** ... */` block, and `libVersionNotify`'s two `///` lines) keeps
|
||||
its line breaks:
|
||||
|
||||
```
|
||||
Plugin Methods:
|
||||
@@ -646,7 +655,7 @@ int fibonacci(int n)
|
||||
Invokable: yes
|
||||
Description: Returns the nth Fibonacci number (0-indexed).
|
||||
|
||||
QString libVersion()
|
||||
tstr libVersion()
|
||||
Signature: libVersion()
|
||||
Invokable: yes
|
||||
Description:
|
||||
@@ -659,11 +668,21 @@ void libVersionNotify()
|
||||
Description:
|
||||
Looks up the library version and emits it as a `versionReady`
|
||||
event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
|
||||
tstr name()
|
||||
Signature: name()
|
||||
Invokable: yes
|
||||
Description: The module's name, as declared in its metadata.
|
||||
|
||||
tstr version()
|
||||
Signature: version()
|
||||
Invokable: yes
|
||||
Description: The module's version, as declared in its metadata.
|
||||
```
|
||||
|
||||
Three things to notice:
|
||||
|
||||
- **Signatures are Qt-typed** (`int`, `QString`) even though you wrote `int64_t` / `std::string`. That's the generated glue: `lm` reports the wire types the synthesized Qt plugin exposes, so `int64_t add(int64_t, int64_t)` shows up as `add(int,int)`.
|
||||
- **Signatures are in LIDL, not C++** (`int`, `tstr`) even though you wrote `int64_t` / `std::string`. `lm` reports what the module *publishes about itself*, and a module publishes its **contract** — so `int64_t add(int64_t, int64_t)` shows up as `add(int,int)`. That is the same vocabulary as the `.lidl` the build derived from your header, and it is the only vocabulary in which this question has one right answer: your module is Qt-free, and a reader in Rust or Nim asking the same module the same question gets the same words back. Note `int` here is LIDL's `int`, which is **64-bit** — each type in the contract maps to exactly one type per language, and integers are 64-bit throughout, so a value that fits your `int64_t` cannot be silently truncated on the way across.
|
||||
- **Each `Description` is your doc comment**, carried through the module's method introspection. Plain `//` comments (like the type-mapping note in the header) are deliberately ignored, so only intentional docs surface; an undocumented method simply omits it.
|
||||
- **Line breaks are preserved** — a single-line comment renders inline; a multi-line comment (`factorial`, `libVersion`, `libVersionNotify`) keeps its breaks. The same descriptions appear in `logoscore module-info` and Basecamp's Methods list.
|
||||
|
||||
@@ -720,8 +739,8 @@ signature and `///` description:
|
||||
Plugin Events:
|
||||
==============
|
||||
|
||||
void versionReady(QString version)
|
||||
Signature: versionReady(QString)
|
||||
void versionReady(tstr version)
|
||||
Signature: versionReady(tstr)
|
||||
Description:
|
||||
Emitted by libVersionNotify() once the library version is known.
|
||||
Carries the version string read from libcalc.
|
||||
@@ -813,15 +832,19 @@ Methods:
|
||||
Defined as n * (n-1) * ... * 1, with 0! = 1.
|
||||
fibonacci(n: int) -> int
|
||||
Returns the nth Fibonacci number (0-indexed).
|
||||
libVersion() -> QString
|
||||
libVersion() -> tstr
|
||||
Returns the version string of the wrapped libcalc C library.
|
||||
Read straight from the linked native library, not metadata.json.
|
||||
libVersionNotify() -> void
|
||||
Looks up the library version and emits it as a `versionReady`
|
||||
event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
name() -> tstr
|
||||
The module's name, as declared in its metadata.
|
||||
version() -> tstr
|
||||
The module's version, as declared in its metadata.
|
||||
|
||||
Events:
|
||||
versionReady(version: QString)
|
||||
versionReady(version: tstr)
|
||||
Emitted by libVersionNotify() once the library version is known.
|
||||
Carries the version string read from libcalc.
|
||||
```
|
||||
|
||||
@@ -482,7 +482,7 @@ sections:
|
||||
- "bumpRunCount"
|
||||
- "persistenceDir"
|
||||
post_text: |
|
||||
Every `public` method on the impl is here — `int64_t` shows up as `int`, `std::string` as `QString`, and `LogosMap` (from `computeReport`) as `QVariantMap`, because `lm` reports the wire types the generated glue exposes.
|
||||
Every `public` method on the impl is here, published in the **LIDL contract** vocabulary rather than in C++ or Qt names: `int64_t` shows up as `int`, `std::string` as `tstr`, and `LogosMap` (from `computeReport`) as `{tstr: any}`. `lm` is reporting what the module says about itself, and what a module publishes is its contract — the same words the generated `.lidl` uses, and the same words a Rust or Nim module implementing this contract would answer with.
|
||||
|
||||
# ── Step 6: Run it with logoscore ───────────────────────────────────────────
|
||||
- title: "Run it with `logoscore`"
|
||||
|
||||
@@ -416,7 +416,7 @@ sections:
|
||||
- "startFibVia"
|
||||
- "watchVersion"
|
||||
post_text: |
|
||||
Every `public` method is here. `int64_t` shows up as `int` and `std::string` as `QString` — the wire types the generated glue exposes.
|
||||
Every `public` method is here, published in the **LIDL contract** vocabulary rather than in C++ or Qt names: `int64_t` shows up as `int` and `std::string` as `tstr`. `lm` is reporting what the module says about itself, and what a module publishes is its contract.
|
||||
|
||||
# ── Step 7: Run it with logoscore ───────────────────────────────────────────
|
||||
- title: "Run it with `logoscore`"
|
||||
|
||||
@@ -367,8 +367,8 @@ sections:
|
||||
~CalcModuleImpl() = default;
|
||||
|
||||
// ── Public API — every method here is callable over IPC ──────────
|
||||
// The generator maps C++ types onto the wire automatically:
|
||||
// int64_t ↔ int std::string ↔ QString bool ↔ bool
|
||||
// The generator maps C++ types onto the contract automatically:
|
||||
// int64_t ↔ int std::string ↔ tstr bool ↔ bool
|
||||
//
|
||||
// A doc comment directly above a method becomes that method's
|
||||
// `description` in the module's method introspection — surfaced
|
||||
@@ -422,18 +422,24 @@ sections:
|
||||
- It's a normal C++ class. Any `public` method is exposed; `private` members and helpers are not.
|
||||
- **Supported parameter/return types** (what the generator can translate):
|
||||
|
||||
| C++ type | On the wire (Qt) |
|
||||
| --------------------------- | ------------------ |
|
||||
| `void` | `void` |
|
||||
| `bool` | `bool` |
|
||||
| `int64_t` | `int` |
|
||||
| `uint64_t` | `uint` |
|
||||
| `double` | `double` |
|
||||
| `std::string` | `QString` |
|
||||
| `std::vector<std::string>` | `QStringList` |
|
||||
| `std::vector<uint8_t>` | `QByteArray` |
|
||||
| `LogosMap` / `LogosList` | `QVariantMap` / `QVariantList` (from `<logos_json.h>`) |
|
||||
| `StdLogosResult` | `LogosResult` (from `<logos_result.h>`) — `{ success, value, error }` |
|
||||
| C++ type | LIDL contract type | A Qt consumer sees |
|
||||
| --------------------------- | ------------------ | ------------------ |
|
||||
| `void` | `void` | `void` |
|
||||
| `bool` | `bool` | `bool` |
|
||||
| `int64_t` | `int` | `qlonglong` |
|
||||
| `uint64_t` | `uint` | `qulonglong` |
|
||||
| `double` | `float64` | `double` |
|
||||
| `std::string` | `tstr` | `QString` |
|
||||
| `std::vector<std::string>` | `[tstr]` | `QStringList` |
|
||||
| `std::vector<uint8_t>` | `bstr` | `QByteArray` |
|
||||
| `LogosMap` / `LogosList` | `{tstr: any}` / `[any]` (from `<logos_json.h>`) | `QVariantMap` / `QVariantList` |
|
||||
| `StdLogosResult` | `result` | `LogosResult` (from `<logos_result.h>`) — `{ success, value, error }` |
|
||||
|
||||
The **middle** column is the one your module publishes about itself —
|
||||
it is what `lm` prints in Step 5, and what any other language's
|
||||
binding of this contract sees. The right column is what a *C++/Qt*
|
||||
caller of this module compiles against; a Rust or Nim caller gets
|
||||
that language's spelling of the same middle column.
|
||||
|
||||
- Use `int64_t` for integers (not `int`) — that's the type the parser recognizes.
|
||||
- **Document methods with `///`.** A doc comment (`///` or `/** … */`) directly above a method becomes its `description` in the module's introspection, surfaced by `lm`, `logoscore module-info`, and Basecamp. Plain `//` comments are ignored, so only intentional docs are exposed — you'll see this in action in Step 5.
|
||||
@@ -595,47 +601,50 @@ sections:
|
||||
# macOS
|
||||
./lm/bin/lm methods result/lib/calc_module_plugin.dylib
|
||||
expect_contains:
|
||||
- "qlonglong add(qlonglong a, qlonglong b)"
|
||||
- "qlonglong multiply(qlonglong a, qlonglong b)"
|
||||
- "qlonglong factorial(qlonglong n)"
|
||||
- "qlonglong fibonacci(qlonglong n)"
|
||||
- "QString libVersion()"
|
||||
- "int add(int a, int b)"
|
||||
- "int multiply(int a, int b)"
|
||||
- "int factorial(int n)"
|
||||
- "int fibonacci(int n)"
|
||||
- "tstr libVersion()"
|
||||
- "Description: Adds two integers and returns the sum."
|
||||
- "Defined as n * (n-1) * ... * 1, with 0! = 1."
|
||||
- "Read straight from the linked native library, not metadata.json."
|
||||
post_text: |
|
||||
Output — each method you declared, with its doc comment as a
|
||||
`Description`. A single-line comment renders inline; a multi-line
|
||||
comment (`factorial`'s two `///` lines, `libVersion`'s `/** ... */`
|
||||
block, and `libVersionNotify`'s two `///` lines) keeps its line breaks:
|
||||
`Description`, plus the two identity methods (`name`, `version`) the
|
||||
generator derives from `metadata.json` so every module answers them
|
||||
without you writing them. A single-line comment renders inline; a
|
||||
multi-line comment (`factorial`'s two `///` lines, `libVersion`'s
|
||||
`/** ... */` block, and `libVersionNotify`'s two `///` lines) keeps
|
||||
its line breaks:
|
||||
|
||||
```
|
||||
Plugin Methods:
|
||||
===============
|
||||
|
||||
qlonglong add(qlonglong a, qlonglong b)
|
||||
Signature: add(qlonglong,qlonglong)
|
||||
int add(int a, int b)
|
||||
Signature: add(int,int)
|
||||
Invokable: yes
|
||||
Description: Adds two integers and returns the sum.
|
||||
|
||||
qlonglong multiply(qlonglong a, qlonglong b)
|
||||
Signature: multiply(qlonglong,qlonglong)
|
||||
int multiply(int a, int b)
|
||||
Signature: multiply(int,int)
|
||||
Invokable: yes
|
||||
Description: Multiplies two integers and returns the product.
|
||||
|
||||
qlonglong factorial(qlonglong n)
|
||||
Signature: factorial(qlonglong)
|
||||
int factorial(int n)
|
||||
Signature: factorial(int)
|
||||
Invokable: yes
|
||||
Description:
|
||||
Computes the factorial n! of a non-negative integer.
|
||||
Defined as n * (n-1) * ... * 1, with 0! = 1.
|
||||
|
||||
qlonglong fibonacci(qlonglong n)
|
||||
Signature: fibonacci(qlonglong)
|
||||
int fibonacci(int n)
|
||||
Signature: fibonacci(int)
|
||||
Invokable: yes
|
||||
Description: Returns the nth Fibonacci number (0-indexed).
|
||||
|
||||
QString libVersion()
|
||||
tstr libVersion()
|
||||
Signature: libVersion()
|
||||
Invokable: yes
|
||||
Description:
|
||||
@@ -648,11 +657,21 @@ sections:
|
||||
Description:
|
||||
Looks up the library version and emits it as a `versionReady`
|
||||
event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
|
||||
tstr name()
|
||||
Signature: name()
|
||||
Invokable: yes
|
||||
Description: The module's name, as declared in its metadata.
|
||||
|
||||
tstr version()
|
||||
Signature: version()
|
||||
Invokable: yes
|
||||
Description: The module's version, as declared in its metadata.
|
||||
```
|
||||
|
||||
Three things to notice:
|
||||
|
||||
- **Signatures are Qt-typed** (`qlonglong`, `QString`) even though you wrote `int64_t` / `std::string`. That's the generated glue: `lm` reports the wire types the synthesized Qt plugin exposes, so `int64_t add(int64_t, int64_t)` shows up as `add(qlonglong,qlonglong)`. Note the width is **preserved** — `qlonglong` is Qt's 64-bit integer, not `int`. Each type in the contract maps to exactly one type per language, and integers are 64-bit throughout, so a value that fits your `int64_t` cannot be silently truncated on the way across.
|
||||
- **Signatures are in LIDL, not C++** (`int`, `tstr`) even though you wrote `int64_t` / `std::string`. `lm` reports what the module *publishes about itself*, and a module publishes its **contract** — so `int64_t add(int64_t, int64_t)` shows up as `add(int,int)`. That is the same vocabulary as the `.lidl` the build derived from your header, and it is the only vocabulary in which this question has one right answer: your module is Qt-free, and a reader in Rust or Nim asking the same module the same question gets the same words back. Note `int` here is LIDL's `int`, which is **64-bit** — each type in the contract maps to exactly one type per language, and integers are 64-bit throughout, so a value that fits your `int64_t` cannot be silently truncated on the way across.
|
||||
- **Each `Description` is your doc comment**, carried through the module's method introspection. Plain `//` comments (like the type-mapping note in the header) are deliberately ignored, so only intentional docs surface; an undocumented method simply omits it.
|
||||
- **Line breaks are preserved** — a single-line comment renders inline; a multi-line comment (`factorial`, `libVersion`, `libVersionNotify`) keeps its breaks. The same descriptions appear in `logoscore module-info` and Basecamp's Methods list.
|
||||
|
||||
@@ -705,7 +724,7 @@ sections:
|
||||
# macOS
|
||||
./lm/bin/lm events result/lib/calc_module_plugin.dylib
|
||||
expect_contains:
|
||||
- "void versionReady(QString version)"
|
||||
- "void versionReady(tstr version)"
|
||||
- "Emitted by libVersionNotify() once the library version is known."
|
||||
- "Carries the version string read from libcalc."
|
||||
post_text: |
|
||||
@@ -713,8 +732,8 @@ sections:
|
||||
Plugin Events:
|
||||
==============
|
||||
|
||||
void versionReady(QString version)
|
||||
Signature: versionReady(QString)
|
||||
void versionReady(tstr version)
|
||||
Signature: versionReady(tstr)
|
||||
Description:
|
||||
Emitted by libVersionNotify() once the library version is known.
|
||||
Carries the version string read from libcalc.
|
||||
@@ -786,15 +805,19 @@ sections:
|
||||
Defined as n * (n-1) * ... * 1, with 0! = 1.
|
||||
fibonacci(n: int) -> int
|
||||
Returns the nth Fibonacci number (0-indexed).
|
||||
libVersion() -> QString
|
||||
libVersion() -> tstr
|
||||
Returns the version string of the wrapped libcalc C library.
|
||||
Read straight from the linked native library, not metadata.json.
|
||||
libVersionNotify() -> void
|
||||
Looks up the library version and emits it as a `versionReady`
|
||||
event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
name() -> tstr
|
||||
The module's name, as declared in its metadata.
|
||||
version() -> tstr
|
||||
The module's version, as declared in its metadata.
|
||||
|
||||
Events:
|
||||
versionReady(version: QString)
|
||||
versionReady(version: tstr)
|
||||
Emitted by libVersionNotify() once the library version is known.
|
||||
Carries the version string read from libcalc.
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user