|
OSSIA
Open Scenario System for Interactive Application
|
Examples of usage
var sock = Protocols.outboundUDP({Transport: { Host: "127.0.0.1", Port: 1234 } }); sock.write("/foo\0\0\0\0,\0\0\0");
OSC. Two argument types a JavaScript number cannot express on its own - every number is a double, so every number goes out as a float: sock.osc("/test/value", [1.25]); // ",f"
... so the type tags can be given explicitly, as with liblo's oscsend. Supported: i h f d s S c b T F I. This is what a receiver with a fixed grammar needs - here SpatGRIS, whose /spat/serv wants an int index: sock.osc("/spat/serv", ["deg", 1, -90, 0, 1, 0.4, 0.6], "sifffff");
var sock = Protocols.inboundUDP({ Transport: { Bind: "127.0.0.1", Port: 1234 } , onMessage: function(bytes) { console.log(bytes); } });
Error callback of the UDP, TCP, Unix and WebSocket sockets: "onError" is the canonical spelling, "onFail" an accepted alias for it. They name one single callback: if a configuration carries both, the canonical spelling is used. var sock = Protocols.outboundTCP({ Transport: { Host: "127.0.0.1", Port: 1234 }, onOpen: function(socket) { console.log("open!"); socket.write("hello world"); }, onClose: function() { console.log("close!"); }, onFail: function() { console.log("fail!"); }, });
var sock = Protocols.inboundTCP({ Transport: { Host: "127.0.0.1", Port: 1234 }, onOpen: function() { console.log("open!"); }, onConnection: function(socket) { console.log("connection!", socket); socket.onClose = function() { console.log("socket.onClose"); } socket.receive(function(b) { console.log(" => ", b); }); }, onClose: function() { console.log("close!"); }, onFail: function() { console.log("fail!"); }, });
Legacy HTTP (GET only, no headers/body): Protocols.http("http://127.0.0.1:1234/toto", function(x){console.log(x);},"GET");
Full HTTP client (any method, custom headers, request body): Protocols.http({ url: "http://127.0.0.1:8080/api/resource", verb: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer token123" }, body: JSON.stringify({ action: "start", num: 1 }), onResponse: function(status, body) { console.log("HTTP", status, body); }, onError: function(err) { console.log("HTTP error:", err); } });
Encoding: optional, applies a binary-to-text encoding to the data Supported types: "base64", "ascii85", "hex", "intel_hex"/"ihex", "srec"/"s_record"/"motorola" var sock = Protocols.outboundTCP({ Transport: { Host: "127.0.0.1", Port: 1234 }, Framing: { type: "line" }, Encoding: { type: "base64" }, onOpen: function(socket) { socket.write("binary data here"); }, });
Classes | |
| struct | websocket_server_state |
| Shared between the server object and its connections: the websocketpp server lives on the mapper's asio context, the QJSValue callbacks on the Qt thread. More... | |
| class | log_sink |
| Converts log messages from spdlog to Qt signals. More... | |
Typedefs | |
| template<typename T> | |
| using | qpointer_set = ossia::hash_map<T*, QPointer<T>> |
| using | request_type |
| using | fetch_request_type |
| using | qml_device_cache = ossia::small_vector<ossia::net::device_base*, 4> |
| using | qml_device_push_function = smallfun::function<void(ossia::net::parameter_base&, const ossia::value_port&)> |
Functions | |
| void | reset_items (QQuickItem *root) |
| void | setup_models (std::size_t cur_model_size, std::size_t prev_model_size, qml_device &device) |
| void | clear_models_preset (std::size_t cur_model_size, std::size_t prev_model_size, qml_device &device) |
| void | setup_models_preset (std::size_t cur_model_size, std::size_t prev_model_size, qml_device &device) |
| template<typename T, typename Fun> | |
| void | run_async (T *self, Fun &&fun, Qt::ConnectionType type=Qt::QueuedConnection) |
| QByteArray | apply_encoding (ossia::net::encoding enc, const QByteArray &data) |
| QByteArray | apply_decoding (ossia::net::encoding enc, const unsigned char *data, std::size_t sz) |
| QByteArray | apply_decoding (ossia::net::encoding enc, const char *data, std::size_t sz) |
| bool | append_osc_argument (oscpack::OutboundPacketStream &p, char tag, const QJSValue &v) |
| Appends one argument to an OSC message with the type the caller asked for. | |
| template<typename Writer> | |
| void | write_osc_message (Writer &&write, const QByteArray &address, const QJSValueList &values, const QByteArray &typetags) |
Encodes an OSC message whose argument types the script spelled out, and hands the bytes to write. | |
| expression_ptr | make_expression (const QQmlScriptString &script, QObject *obj, expression_ptr deflt) |
| template<typename T> | |
| T | findParent (QObject *obj) |
| constexpr qint32 | infinite () |
| bool | isInfinite (qint32 t) |
| auto | defaultTime (qint32 t) -> ossia::time_value |
| auto | reverseTime (time_value t) -> qint32 |
| using ossia::qt::request_type |
| using ossia::qt::fetch_request_type |
|
inline |
Appends one argument to an OSC message with the type the caller asked for.
A JavaScript number carries no width and no integer-ness: 1, 1.0 and 2/2 are the same value, and QJSValue::toNumber() is the only honest reading of it. So the value cannot say which OSC type tag belongs on the wire – only the protocol can, and the script is the only thing that knows the protocol. This is where it says so.
Supported tags are the ones oscpack can emit: i (int32), h (int64), f (float32), d (float64), s (string), S (symbol), c (char), b (blob), T / F (true / false, which carry no payload), I (impulse / infinitum). Anything else – including a tag string shorter than the argument list – falls back to value_from_js(), i.e. the untyped default.
tag was not one of the above. | void ossia::qt::write_osc_message | ( | Writer && | write, |
| const QByteArray & | address, | ||
| const QJSValueList & | values, | ||
| const QByteArray & | typetags ) |
Encodes an OSC message whose argument types the script spelled out, and hands the bytes to write.
sock.osc("/spat/serv", ["deg", 1, az, el, r, h, v], "sifffff") – the type tag string of liblo's oscsend, and of OSC itself.
Without it every number goes out as a float, because that is the only thing a JavaScript number can be read as without guessing (see append_osc_argument). Guessing is not an option here: inferring the tag from the value would make the shape of the packet depend on the data, so /spat/serv deg 1 -90 0 1 0.4 0.6 would go out as "siiiiff" and the same message a moment later, with the source off-axis, as "sifffff". A receiver with a fixed grammar – SpatGRIS's /spat/serv wants an int index and floats after it – would then work or not depending on where the source happens to be, which is worse than always being wrong.
A tag string shorter than the argument list, or carrying a tag this build cannot emit, leaves those arguments to the untyped conversion rather than dropping them.