From d65e1170b98cb48893cefeb354503403af901132 Mon Sep 17 00:00:00 2001 From: Luciano Iam Date: Sun, 14 Jun 2020 12:34:27 +0200 Subject: [PATCH] WS: make ArdourClient extend Component This allows the client object to be observed using the on() method just like with the mixer and transport components, instead of passing separate callbacks. See mixer-demo/js/main.js for an example. --- .../builtin/mixer-demo/js/main.js | 40 ++++++------ .../builtin/mixer-demo/manifest.xml | 2 +- .../builtin/transport/manifest.xml | 2 +- share/web_surfaces/shared/ardour.js | 63 ++++++++----------- share/web_surfaces/shared/base/component.js | 4 +- share/web_surfaces/shared/components/mixer.js | 2 +- .../web_surfaces/shared/components/plugin.js | 2 +- share/web_surfaces/shared/components/strip.js | 2 +- 8 files changed, 51 insertions(+), 66 deletions(-) diff --git a/share/web_surfaces/builtin/mixer-demo/js/main.js b/share/web_surfaces/builtin/mixer-demo/js/main.js index b3e943495d..83ae67c829 100644 --- a/share/web_surfaces/builtin/mixer-demo/js/main.js +++ b/share/web_surfaces/builtin/mixer-demo/js/main.js @@ -27,29 +27,21 @@ import { Switch, DiscreteSlider, ContinuousSlider, LogarithmicSlider, const ardour = new ArdourClient(); - function main () { - ardour.handlers = { - onConnected: (connected) => { - if (connected) { - log('Client connected', 'info'); - } else { - log('Client disconnected', 'error'); - } - }, - - onMessage: (message, inbound) => { - if (inbound) { - log(`↙ ${message}`, 'message-in'); - } else { - log(`↗ ${message}`, 'message-out'); - } + async function main () { + ardour.on('connected', (connected) => { + if (connected) { + log('Client connected', 'info'); + } else { + log('Client disconnected', 'error'); } - }; + }); - ardour.getSurfaceManifest().then((manifest) => { - const div = document.getElementById('manifest'); - div.innerHTML = manifest.name.toUpperCase() - + ' v' + manifest.version + ' — ' + manifest.description; + ardour.on('message', (msg, inbound) => { + if (inbound) { + log(`↙ ${msg}`, 'message-in'); + } else { + log(`↗ ${msg}`, 'message-out'); + } }); ardour.mixer.on('ready', () => { @@ -59,7 +51,11 @@ import { Switch, DiscreteSlider, ContinuousSlider, LogarithmicSlider, } }); - ardour.connect(); + await ardour.connect(); + + const manifest = await ardour.getSurfaceManifest(); + document.getElementById('manifest').innerHTML = manifest.name.toUpperCase() + + ' v' + manifest.version + ' — ' + manifest.description; } function createStrip (strip, parentDiv) { diff --git a/share/web_surfaces/builtin/mixer-demo/manifest.xml b/share/web_surfaces/builtin/mixer-demo/manifest.xml index b394006db8..75476a4f9e 100644 --- a/share/web_surfaces/builtin/mixer-demo/manifest.xml +++ b/share/web_surfaces/builtin/mixer-demo/manifest.xml @@ -2,5 +2,5 @@ - + diff --git a/share/web_surfaces/builtin/transport/manifest.xml b/share/web_surfaces/builtin/transport/manifest.xml index be9936e4c0..93d7fcd075 100644 --- a/share/web_surfaces/builtin/transport/manifest.xml +++ b/share/web_surfaces/builtin/transport/manifest.xml @@ -2,5 +2,5 @@ - + diff --git a/share/web_surfaces/shared/ardour.js b/share/web_surfaces/shared/ardour.js index 5ba980e0f1..2626768e50 100644 --- a/share/web_surfaces/shared/ardour.js +++ b/share/web_surfaces/shared/ardour.js @@ -16,36 +16,34 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +import { Component } from './base/component.js'; import { StateNode } from './base/protocol.js'; import MessageChannel from './base/channel.js'; import Mixer from './components/mixer.js'; import Transport from './components/transport.js'; -export default class ArdourClient { +function getOption (options, key, defaultValue) { + return options ? (key in options ? options[key] : defaultValue) : defaultValue; +} - constructor (handlers, options) { - this._options = options || {}; - this._components = []; - this._connected = false; +export default class ArdourClient extends Component { - this._channel = new MessageChannel(this._getOption('host', location.host)); + constructor (options) { + super(new MessageChannel(getOption(options, 'host', location.host))); - this._channel.onMessage = (msg, inbound) => { - this._handleMessage(msg, inbound); - }; - - if (this._getOption('components', true)) { - this._mixer = new Mixer(this._channel); - this._transport = new Transport(this._channel); - this._components.push(this._mixer, this._transport); + if (getOption(options, 'components', true)) { + this._mixer = new Mixer(this.channel); + this._transport = new Transport(this.channel); + this._components = [this._mixer, this._transport]; + } else { + this._components = []; } - this.handlers = handlers; - } + this._autoReconnect = getOption(options, 'autoReconnect', true); + this._connected = false; - set handlers (handlers) { - this._handlers = handlers || {}; - this._channel.onError = this._handlers.onError || console.log; + this.channel.onMessage = (msg, inbound) => this._handleMessage(msg, inbound); + this.channel.onError = (err) => this.notifyObservers('error', err); } // Access to the object-oriented API (enabled by default) @@ -61,12 +59,12 @@ export default class ArdourClient { // Low level control messages flow through a WebSocket async connect () { - this._channel.onClose = async () => { + this.channel.onClose = async () => { if (this._connected) { this._setConnected(false); } - if (this._getOption('autoReconnect', true)) { + if (this._autoReconnect) { await this._sleep(1000); await this._connect(); } @@ -76,17 +74,17 @@ export default class ArdourClient { } disconnect () { - this._channel.onClose = () => {}; - this._channel.close(); + this.channel.onClose = () => {}; + this.channel.close(); this._connected = false; } send (msg) { - this._channel.send(msg); + this.channel.send(msg); } async sendAndReceive (msg) { - return await this._channel.sendAndReceive(msg); + return await this.channel.sendAndReceive(msg); } // Surface metadata API goes over HTTP @@ -126,22 +124,17 @@ export default class ArdourClient { } async _connect () { - await this._channel.open(); + await this.channel.open(); this._setConnected(true); } _setConnected (connected) { this._connected = connected; - - if (this._handlers.onConnected) { - this._handlers.onConnected(this._connected); - } + this.notifyPropertyChanged('connected'); } _handleMessage (msg, inbound) { - if (this._handlers.onMessage) { - this._handlers.onMessage(msg, inbound); - } + this.notifyObservers('message', msg, inbound); if (inbound) { for (const component of this._components) { @@ -156,8 +149,4 @@ export default class ArdourClient { return new Error(`HTTP response status ${status}`); } - _getOption (key, defaultValue) { - return key in this._options ? this._options[key] : defaultValue; - } - } diff --git a/share/web_surfaces/shared/base/component.js b/share/web_surfaces/shared/base/component.js index 1273338dec..cbd26895c9 100644 --- a/share/web_surfaces/shared/base/component.js +++ b/share/web_surfaces/shared/base/component.js @@ -34,7 +34,7 @@ export class Component extends Observable { this.addObserver(event, callback); } - notify (property) { + notifyPropertyChanged (property) { this.notifyObservers(property, this['_' + property]); } @@ -52,7 +52,7 @@ export class Component extends Observable { updateLocal (property, value) { this['_' + property] = value; - this.notify(property); + this.notifyPropertyChanged(property); } updateRemote (property, value, node, addr) { diff --git a/share/web_surfaces/shared/components/mixer.js b/share/web_surfaces/shared/components/mixer.js index bcbaa82ca9..18488d68ec 100644 --- a/share/web_surfaces/shared/components/mixer.js +++ b/share/web_surfaces/shared/components/mixer.js @@ -45,7 +45,7 @@ export default class Mixer extends Component { if (node.startsWith('strip')) { if (node == StateNode.STRIP_DESCRIPTION) { this._strips[addr] = new Strip(this, addr, val); - this.notify('strips'); + this.notifyPropertyChanged('strips'); return true; } else { const stripAddr = [addr[0]]; diff --git a/share/web_surfaces/shared/components/plugin.js b/share/web_surfaces/shared/components/plugin.js index 2245d4006a..be69a77c3e 100644 --- a/share/web_surfaces/shared/components/plugin.js +++ b/share/web_surfaces/shared/components/plugin.js @@ -53,7 +53,7 @@ export default class Plugin extends AddressableComponent { if (node.startsWith('strip_plugin_param')) { if (node == StateNode.STRIP_PLUGIN_PARAM_DESCRIPTION) { this._parameters[addr] = new Parameter(this, addr, val); - this.notify('parameters'); + this.notifyPropertyChanged('parameters'); return true; } else { if (addr in this._parameters) { diff --git a/share/web_surfaces/shared/components/strip.js b/share/web_surfaces/shared/components/strip.js index 4cc5eef3b9..203822bd94 100644 --- a/share/web_surfaces/shared/components/strip.js +++ b/share/web_surfaces/shared/components/strip.js @@ -84,7 +84,7 @@ export default class Strip extends AddressableComponent { if (node.startsWith('strip_plugin')) { if (node == StateNode.STRIP_PLUGIN_DESCRIPTION) { this._plugins[addr] = new Plugin(this, addr, val); - this.notify('plugins'); + this.notifyPropertyChanged('plugins'); return true; } else { const pluginAddr = [addr[0], addr[1]];