The language choice, tl;dr
:Use JavaScript unless Lua is your preference or you require headless (no GUI) operation.
Since Hz supports two programming language options, let's quickly touch
upon the similarities and differences between the JavaScript and Lua API
bindings. With that behind us we'll document the API in JavaScript
and
expect that the mapping to its Lua
equivalent is straightforward.
The primary difference between the language bindings pertain to
notations for expressing asynchronous behavior. Asynchronous programming
is central to Hz's music programming model and is covered in
more detail here. In short, Lua's coroutine
support can often be hidden behind the scenes while JavaScript's
generators
and async functions
are necessarily more explicit.
Feature | JavaScript | Lua |
---|---|---|
Execution Model | interpretted | interpretted |
Learning Curve | Gentle | Gentle |
Usage | widespread | slightly obscure |
Peformance | highly optimized | lightweight+fast |
GUI Integration | built-in | indirect via JavaScript |
"Headless" Operation | no (requires WebView/WebKit) | yes |
Class Function Notation | ClassName. func(…) |
ClassName. func(…) |
Object Method Notation | object. method(…) |
object: method(…) |
Coroutine/Fiber | separate async and generator |
coroutine |
Multiple Sandboxes | yes | no (not implemented) |
Other differences are implicit in these examples. Code comments highlight the usage differences driven by the hosting language.
// JavaScript example
let scene = await Ascene.BeginFiber(this); // <-- use javascript await keyword
console.notice("Audio scene is initialized.");
let inst = scene.NewAnode("Vital");
let dac = scene.GetDAC();
scene.Chain(inst, dac); // setup our trivial audio graph
await scene.Sync();
let noteDur = scene.Seconds(.1);
for(let key=40;key<60;k++)
{
console.notice(`key: ${key}`);
inst.NoteOn(key, .8);
await scene.Wait(noteDur); // async ("blocking") await
inst.NoteOff(key, 0);
yield; // javascript yield keyword to
}
-- Lua example
local Ascene = require("ascene")
Ascene:init(function(scene) -- <-- scene instance delivered to callback
Log.notice("Audio scene is initialized.")
local inst = scene:newAnode("Vital")
local dac = scene:getDAC()
scene:chain(inst, dac) -- setup our trivial audio graph
scene:begin() -- begin yields behind the scenes.
local noteDur = scene:seconds(.1)
for key=40,60 do
Log.notice("key: "..key)
inst:noteOn(key, .8)
scene:wait(noteDur) -- wait yields behind the scenes.
inst:noteOff(key, 0)
end
end)