зеркало из https://github.com/mozilla/pluotsorbet.git
286 строки
8.5 KiB
JavaScript
286 строки
8.5 KiB
JavaScript
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/* vim: set shiftwidth=4 tabstop=4 autoindent cindent expandtab: */
|
|
|
|
'use strict';
|
|
|
|
var AccelerometerSensor = {};
|
|
|
|
AccelerometerSensor.IS_MOBILE = navigator.userAgent.search("Mobile") !== -1;
|
|
|
|
AccelerometerSensor.model = {
|
|
description: "Acceleration sensor measures acceleration in SI units for x, y and z - axis.",
|
|
model: "FirefoxOS",
|
|
quantity: "acceleration",
|
|
contextType: "user",
|
|
connectionType: 1, // ChannelType.TYPE_DOUBLE = 1
|
|
maxBufferSize: 256,
|
|
availabilityPush: 0,
|
|
conditionPush: 0,
|
|
channelCount: 3,
|
|
properties: [
|
|
"vendor", "FirefoxOS",
|
|
"version", "1.0",
|
|
"maxSamplingRate", "20.0",
|
|
"location", "NoLoc",
|
|
"security", "private"
|
|
]
|
|
};
|
|
|
|
var doubleToLongBits = (function() {
|
|
var da = new Float64Array(1);
|
|
var ia = new Int32Array(da.buffer);
|
|
return function(val) {
|
|
da[0] = val;
|
|
return Long.fromBits(ia[0], ia[1]);
|
|
}
|
|
})();
|
|
|
|
AccelerometerSensor.channels = [ {
|
|
scale: 0,
|
|
name: "axis_x",
|
|
unit: "m/s^2",
|
|
dataType: 1, // 1 == Double type
|
|
accuracy: 1,
|
|
mrangeArray: [
|
|
doubleToLongBits(-19.6), // smallest value
|
|
doubleToLongBits(19.6), // largest value
|
|
doubleToLongBits(0.153) // resolution
|
|
]
|
|
}, {
|
|
scale: 0,
|
|
name: "axis_y",
|
|
unit: "m/s^2",
|
|
dataType: 1, // 1 == Double type
|
|
accuracy: 1,
|
|
mrangeArray: [
|
|
doubleToLongBits(-19.6), // smallest value
|
|
doubleToLongBits(19.6), // largest value
|
|
doubleToLongBits(0.153) // resolution
|
|
]
|
|
}, {
|
|
scale: 0,
|
|
name: "axis_z",
|
|
unit: "m/s^2",
|
|
dataType: 1, // 1 == Double type
|
|
accuracy: 1,
|
|
mrangeArray: [
|
|
doubleToLongBits(-19.6), // smallest value
|
|
doubleToLongBits(19.6), // largest value
|
|
doubleToLongBits(0.153) // resolution
|
|
]
|
|
}
|
|
];
|
|
|
|
// Simulate acceleration data by moving mouse.
|
|
AccelerometerSensor.simulator = {
|
|
_intervalId: -1,
|
|
|
|
start: function() {
|
|
var currentMouseX = -1;
|
|
var currentMouseY = -1;
|
|
var c = MIDP.context2D.canvas;
|
|
c.onmousemove = function(ev) {
|
|
currentMouseX =ev.layerX;
|
|
currentMouseY =ev.layerY;
|
|
};
|
|
|
|
var time = 0;
|
|
var mouseX = -1;
|
|
var mouseY = -1;
|
|
var velocityX = -1;
|
|
var velocityY = -1;
|
|
this._intervalId = setInterval(function() {
|
|
var previousTime = time;
|
|
var previousMouseX = mouseX;
|
|
var previousMouseY = mouseY;
|
|
var previousVelocityX = velocityX;
|
|
var previousVelocityY = velocityY;
|
|
|
|
time = Date.now();
|
|
var dt = (time - previousTime) / 1000;
|
|
mouseX = currentMouseX * c.width / c.offsetWidth / 5000;
|
|
mouseY = currentMouseY * c.height / c.offsetHeight / 5000;
|
|
velocityX = (mouseX - previousMouseX) / dt;
|
|
velocityY = (mouseY - previousMouseY) / dt;
|
|
var ax = (velocityX - previousVelocityX) / dt;
|
|
var ay = ax;
|
|
var az = (velocityY - previousVelocityY) / dt;
|
|
|
|
AccelerometerSensor.handleEvent({
|
|
accelerationIncludingGravity: { x: ax, y: ay, z: az }
|
|
});
|
|
}, 50);
|
|
},
|
|
|
|
stop: function() {
|
|
MIDP.context2D.canvas.onmousemove = null;
|
|
clearInterval(this._interalId);
|
|
}
|
|
};
|
|
|
|
AccelerometerSensor.open = function() {
|
|
window.addEventListener('devicemotion', this);
|
|
if (!this.IS_MOBILE) {
|
|
this.simulator.start();
|
|
}
|
|
};
|
|
|
|
AccelerometerSensor.close = function() {
|
|
window.removeEventListener('devicemotion', this);
|
|
if (!this.IS_MOBILE) {
|
|
this.simulator.stop();
|
|
}
|
|
};
|
|
|
|
AccelerometerSensor.readBuffer = (function() {
|
|
var offset = 0;
|
|
|
|
var write_int32 = function(out, value) {
|
|
var a = new Int8Array(4);
|
|
new Int32Array(a.buffer)[0] = value;
|
|
Array.prototype.reverse.apply(a);
|
|
out.set(a, offset);
|
|
offset += 4;
|
|
};
|
|
|
|
var write_boolean = function(out, value) {
|
|
out[offset++] = value;
|
|
};
|
|
|
|
var write_float32 = function(out, value) {
|
|
var a = new Int8Array(4);
|
|
new Float32Array(a.buffer)[0] = value;
|
|
Array.prototype.reverse.apply(a);
|
|
out.set(a, offset);
|
|
offset += 4;
|
|
};
|
|
|
|
var write_double64 = function(out, value) {
|
|
var a = new Int8Array(8);
|
|
new Float64Array(a.buffer)[0] = value;
|
|
Array.prototype.reverse.apply(a);
|
|
out.set(a, offset);
|
|
offset += 8;
|
|
};
|
|
|
|
var DATA_LENGTH = 1;
|
|
var result = new Int8Array(5 + DATA_LENGTH * 13);
|
|
|
|
return function(channelNumber) {
|
|
offset = 0;
|
|
result[offset++] = this.channels[channelNumber].dataType;
|
|
// Set data length
|
|
write_int32(result, DATA_LENGTH);
|
|
// Set validity
|
|
write_boolean(result, 1);
|
|
// Set uncertainty
|
|
write_float32(result, 0);
|
|
// Set sensor data.
|
|
write_double64(result, this.acceleration[channelNumber]);
|
|
return result;
|
|
};
|
|
})();
|
|
|
|
AccelerometerSensor.acceleration = [0, 0, 0];
|
|
|
|
// Event handler to handle devicemotion event.
|
|
AccelerometerSensor.handleEvent = function(evt) {
|
|
var a = evt.accelerationIncludingGravity;
|
|
this.acceleration[0] = a.x;
|
|
this.acceleration[1] = a.y;
|
|
this.acceleration[2] = a.z;
|
|
};
|
|
|
|
Native["com/sun/javame/sensor/SensorRegistry.doGetNumberOfSensors.()I"] = function() {
|
|
// Only support the acceleration sensor.
|
|
return 1;
|
|
};
|
|
|
|
Native["com/sun/javame/sensor/Sensor.doGetSensorModel.(ILcom/sun/javame/sensor/SensorModel;)V"] = function(number, model) {
|
|
if (number !== 0) {
|
|
console.error("Invalid sensor number: " + number);
|
|
return;
|
|
}
|
|
var m = AccelerometerSensor.model;
|
|
model.description = J2ME.newString(m.description);
|
|
model.model = J2ME.newString(m.model);
|
|
model.quantity = J2ME.newString(m.quantity);
|
|
model.contextType = J2ME.newString(m.contextType);
|
|
model.connectionType = m.connectionType;
|
|
model.maxBufferSize = m.maxBufferSize;
|
|
model.availabilityPush = m.availabilityPush;
|
|
model.conditionPush = m.conditionPush;
|
|
model.channelCount = m.channelCount;
|
|
model.errorCodes = J2ME.newArray(J2ME.PrimitiveArrayClassInfo.I.klass, 0);
|
|
model.errorMsgs = J2ME.newStringArray(0);
|
|
|
|
var n = m.properties.length;
|
|
var p = J2ME.newStringArray(n);
|
|
for (var i = 0; i < n; i++) {
|
|
p[i] = J2ME.newString(m.properties[i]);
|
|
}
|
|
model.properties = p;
|
|
};
|
|
|
|
Native["com/sun/javame/sensor/ChannelImpl.doGetChannelModel.(IILcom/sun/javame/sensor/ChannelModel;)V"] = function(sensorsNumber, number, model) {
|
|
if (sensorsNumber !== 0) {
|
|
console.error("Invalid sensor number: " + sensorsNumber);
|
|
return;
|
|
}
|
|
if (number < 0 || number >= AccelerometerSensor.channels.length) {
|
|
console.error("Invalid channel number: " + number);
|
|
return;
|
|
}
|
|
var c = AccelerometerSensor.channels[number];
|
|
model.scale = c.scale;
|
|
model.name = J2ME.newString(c.name);
|
|
model.unit = J2ME.newString(c.unit);
|
|
model.dataType = c.dataType;
|
|
model.accuracy = c.accuracy;
|
|
model.mrangeCount = c.mrangeArray.length;
|
|
|
|
var n = c.mrangeArray.length;
|
|
var array = J2ME.newArray(J2ME.PrimitiveArrayClassInfo.J.klass, n);
|
|
for (var i = 0; i < n; i++) {
|
|
array[i] = c.mrangeArray[i];
|
|
}
|
|
model.mrageArray = array;
|
|
};
|
|
|
|
Native["com/sun/javame/sensor/NativeSensor.doIsAvailable.(I)Z"] = function(number) {
|
|
// Only support the acceleration sensor with number = 0.
|
|
return number === 0 ? 1 : 0;
|
|
};
|
|
|
|
Native["com/sun/javame/sensor/NativeSensor.doInitSensor.(I)Z"] = function(number) {
|
|
if (number !== 0) {
|
|
return 0;
|
|
}
|
|
AccelerometerSensor.open();
|
|
return 1;
|
|
};
|
|
|
|
Native["com/sun/javame/sensor/NativeSensor.doFinishSensor.(I)Z"] = function(number) {
|
|
if (number !== 0) {
|
|
return 0;
|
|
}
|
|
AccelerometerSensor.close();
|
|
return 1;
|
|
};
|
|
|
|
Native["com/sun/javame/sensor/NativeChannel.doMeasureData.(II)[B"] = function(sensorNumber, channelNumber) {
|
|
if (sensorNumber !== 0 || channelNumber < 0 || channelNumber >= 3) {
|
|
if (sensorNumber !== 0) {
|
|
console.error("Invalid sensor number: " + sensorsNumber);
|
|
} else {
|
|
console.error("Invalid channel number: " + channelNumber);
|
|
}
|
|
return J2ME.newArray(J2ME.PrimitiveArrayClassInfo.B.klass, 0);
|
|
}
|
|
|
|
asyncImpl("[B", new Promise(function(resolve, reject) {
|
|
var result = AccelerometerSensor.readBuffer(channelNumber);
|
|
setTimeout(resolve.bind(null, result), 50);
|
|
}));
|
|
};
|