Repository navigation
Conversation
Companion to ossia/libossia#957, which adds the three-argument `osc(address, values, typetags)` to the QML sockets. Every number a script put in an OSC message went out as a float, so there was no way to send the int source index SpatGRIS's /spat/serv grammar requires: the shipped Spatial Protocol Mapper emits it as "sffffff" with the index as 1.000000. The fixture sends the /spat/serv shape with "sifffff", one argument per supported tag, a message with no tag string at all, and a tag string shorter than the argument list. The test asserts the exact datagram bytes against hand-written OSC fixtures -- address and type tag strings padded to four bytes, network-order IEEE-754 payloads -- so nothing libossia encodes is its own oracle, and reads the type tag string back out of the packet with its own four-byte-padding arithmetic. The untyped case is there to pin the default: it must stay "f", byte for byte, or every script and document already out there changes meaning. Submodule: 3rdparty/libossia moves to the branch commit. To be re-pointed at master once the libossia PR lands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019QYyvhRXvSMSRQPaq12Teq
2e69f77 to
a76778e
Compare
|
Closing in favour of #2323 for the consolidated engine branch. The branch It is deliberately not on |
|
Recovered: the test from this PR is now in #2330 as |
Draft: depends on ossia/libossia#957. The submodule here points at that PR's branch commit (
74fa1a3); it must be re-pointed at libossiamasteronce #957 lands, and this PR cannot go green before then.The bug
Every number a QML script puts in an OSC message goes on the wire as a float, so there is no way to send the int source index SpatGRIS's
/spat/servgrammar requires.ossia::qt::value_from_jshas a lone numeric branch andQJSValue::toNumber()is a double. The shipped Spatial Protocol Mapper, which builds that message in QML, emits (oscdump, released package):score's own C++ SpatGRIS protocol gets this right —
SpatGrisSourceOffsetTest.cppassertsIsInt32()on that argument — so the QML path is the odd one out.libossia#957 adds the opt-in third argument
osc(address, values, typetags), the type tag string of liblo'soscsend. It is opt-in rather than inferred from the value because a JavaScript number carries no integer-ness: inferring would make the shape of the packet depend on the data (siiiifffor a source on an axis,sifffffa moment later), which is worse than being consistently wrong. The reasoning is in that PR.This PR
The score-side regression test, because this is where the Mapper + loopback-socket harness lives.
tests/testdata/protocols-qml/test_osc_typetags.qml— a Mapper that sends the/spat/servshape with"sifffff", one argument per supported tag ("ifsTF"), a message with no tag string at all, and a tag string shorter than the argument list.MapperDatagramProtocolsTest.cpp— asserts the exact datagram bytes against hand-written OSC fixtures (address and type tag strings padded to four bytes, network-order IEEE-754 payloads), so nothing libossia encodes is its own oracle, and reads the type tag string back out of the packet with its own four-byte-padding arithmetic.The untyped case is there to pin the default: it must stay
,fbyte for byte, or every script and stored document already out there changes meaning.Failing without the fix
With the submodule back at libossia
master, QML resolvesosc(address, values, typetags)to the two-argument overload and silently drops the third argument — i.e. exactly the shipped behaviour:Exactly the 6 typed assertions fail; the untyped ones pass in both builds, and so do the other 25 cases in the binary.
Wire evidence
oscdump— an independent liblo decoder — reading the datagrams this Mapper actually emitted:🤖 Generated with Claude Code
https://claude.ai/code/session_019QYyvhRXvSMSRQPaq12Teq