This repository has been archived on 2025-05-05. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
scratchx/scratch_extensions/scratch_deviceManager.js
Christopher Willis-Ford 47d9063829 Update scratch_extensions for upcoming scratchr2
This corresponds to the upcoming October 20th release
2016-10-07 12:09:17 -07:00

99 lines
3.3 KiB
JavaScript

// Communicate with the Scratch Device Manager through Socket.IO
window.ScratchDeviceManager = new (function () {
var instance = this;
var sockets = [];
// Assume it's OK until we find out otherwise
var isConnected = true;
// device-manager.scratch.mit.edu = 127.0.0.1
instance.deviceManagerHost = 'https://device-manager.scratch.mit.edu:3030';
// work around https://github.com/socketio/socket.io-client/issues/812
function connectNamespace(namespace) {
return io(instance.deviceManagerHost + namespace, {forceNew: true});
}
function onClose(){
for(var i=0; i<sockets.length; i++){
sockets[i].disconnect();
}
}
window.onbeforeunload = onClose;
instance.device_list = function (ext_type, ext_name, device_spec, callback) {
var url = instance.deviceManagerHost + '/' + ext_type + '/list';
var data = {
name: ext_name,
spec: device_spec
};
$.ajax(url, {
data: {data: JSON.stringify(data)},
dataType: 'json',
success: function (data, textStatus, jqXHR) {
isConnected = true;
if (data.constructor == Array) {
callback(data, ext_type, ext_name);
}
},
error: function (jqXHR, textStatus, errorThrown) {
isConnected = false;
}
});
};
// Attempt to open a device-specific socket connection to the Device Manager.
// This must call `callback` exactly once no matter what.
// The callback will receive a connected socket on success or `null` on failure.
instance.socket_open = function (ext_name, deviceType, deviceId, callback) {
function onDeviceWasOpened () {
// If this is the first event on this socket then respond with success.
if (clearOpenTimeout()) {
callback(socket);
}
}
function onDisconnect () {
var socketIndex = sockets.indexOf(socket);
if (socketIndex >= 0) {
sockets.splice(socketIndex, 1);
}
// If this is the first event on this socket then respond with failure.
if (clearOpenTimeout()) {
callback(null);
}
}
function onTimeout () {
// This will trigger `onDisconnect()`
socket.disconnect();
}
// If the timeout is still pending, clear it and return true. Otherwise, return false.
// Callers can use the return value to determine whether they are the first to respond on this socket.
function clearOpenTimeout () {
if (openTimeout !== null) {
clearTimeout(openTimeout);
openTimeout = null;
return true;
}
else {
return false;
}
}
var socket = connectNamespace('/' + deviceType);
sockets.push(socket);
socket.on('deviceWasOpened', onDeviceWasOpened);
socket.on('disconnect', onDisconnect);
var openTimeout = setTimeout(onTimeout, 10 * 1000);
socket.emit('open', {deviceId: deviceId, name: ext_name});
};
instance.isConnected = function () {
return isConnected;
};
})();