(function () { 'use strict'; /* eslint-env browser */ class Event { constructor(type, data) { this.type = type; this.data = data; } } class Observable { constructor() { this.listeners = {}; } addEventListener(type, callback) { if (this.listeners[type] === undefined) { this.listeners[type] = []; } this.listeners[type].push(callback); } notifyAll(event) { let listeners = this.listeners[event.type]; if (listeners) { for (let i = 0; i < listeners.length; i++) { listeners[i](event); } } } } /* eslint-env browser */ class GazeDataEvent extends Event { constructor(data) { super("gazeDataAvailable", data); } } class ConnectionEvent extends Event { constructor() { super("connected"); } } class WebSocketClient extends Observable { constructor() { super(); } connect(url) { this.ws = new WebSocket(url); this.ws.onopen = onOpen.bind(this); this.ws.onmessage = onMessage.bind(this); } } function onOpen() { let connectionEvent = new ConnectionEvent(); this.notifyAll(connectionEvent); } function onMessage(event) { let gazeEvent = new GazeDataEvent(event.data); this.notifyAll(gazeEvent); } /* eslint-env browser */ class GazeClient extends Observable { constructor() { super(); } connect(url) { this.url = url; this.client = new WebSocketClient(); this.client.addEventListener("connected", this.onConnected.bind(this)); this.client.addEventListener("gazeDataAvailable", this.onGazeDataAvailable .bind(this)); this.client.connect(url); } onOpen() { this.client.send("hello server"); } onConnected(event) { // TODO: Implement event broadcasting } onGazeDataAvailable(event) { this.notifyAll(event); } } window.GazeClient = GazeClient; }());