mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-01-10 15:02:06 -05:00
Merge pull request #104 from tmickel/feature/io
VM "I/O devices"; clock, mouse as demo
This commit is contained in:
commit
fd5d85ed73
8 changed files with 151 additions and 2 deletions
|
@ -88,6 +88,24 @@ window.onload = function() {
|
|||
workspace.reportValue(data.id, data.value);
|
||||
});
|
||||
|
||||
// Feed mouse events as VM I/O events.
|
||||
document.addEventListener('mousemove', function (e) {
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var coordinates = {
|
||||
x: e.clientX - rect.left - rect.width / 2,
|
||||
y: e.clientY - rect.top - rect.height / 2
|
||||
};
|
||||
window.vm.postIOData('mouse', coordinates);
|
||||
});
|
||||
canvas.addEventListener('mousedown', function (e) {
|
||||
window.vm.postIOData('mouse', {isDown: true});
|
||||
e.preventDefault();
|
||||
});
|
||||
canvas.addEventListener('mouseup', function (e) {
|
||||
window.vm.postIOData('mouse', {isDown: false});
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
// Run threads
|
||||
vm.start();
|
||||
|
||||
|
|
43
src/blocks/scratch3_sensing.js
Normal file
43
src/blocks/scratch3_sensing.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
function Scratch3SensingBlocks(runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
*/
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the block primitives implemented by this package.
|
||||
* @return {Object.<string, Function>} Mapping of opcode to Function.
|
||||
*/
|
||||
Scratch3SensingBlocks.prototype.getPrimitives = function() {
|
||||
return {
|
||||
'sensing_timer': this.getTimer,
|
||||
'sensing_resettimer': this.resetTimer,
|
||||
'sensing_mousex': this.getMouseX,
|
||||
'sensing_mousey': this.getMouseY,
|
||||
'sensing_mousedown': this.getMouseDown
|
||||
};
|
||||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.getTimer = function (args, util) {
|
||||
return util.ioQuery('clock', 'projectTimer');
|
||||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.resetTimer = function (args, util) {
|
||||
util.ioQuery('clock', 'resetProjectTimer');
|
||||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.getMouseX = function (args, util) {
|
||||
return util.ioQuery('mouse', 'getX');
|
||||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.getMouseY = function (args, util) {
|
||||
return util.ioQuery('mouse', 'getY');
|
||||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.getMouseDown = function (args, util) {
|
||||
return util.ioQuery('mouse', 'getIsDown');
|
||||
};
|
||||
|
||||
module.exports = Scratch3SensingBlocks;
|
|
@ -77,7 +77,14 @@ var execute = function (sequencer, thread) {
|
|||
startBranch: function (branchNum) {
|
||||
sequencer.stepToBranch(thread, branchNum);
|
||||
},
|
||||
target: target
|
||||
target: target,
|
||||
ioQuery: function (device, func, args) {
|
||||
// Find the I/O device and execute the query/function call.
|
||||
if (runtime.ioDevices[device] && runtime.ioDevices[device][func]) {
|
||||
var devObject = runtime.ioDevices[device];
|
||||
return devObject[func].call(devObject, args);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Deal with any reported value.
|
||||
|
|
|
@ -3,12 +3,17 @@ var Sequencer = require('./sequencer');
|
|||
var Thread = require('./thread');
|
||||
var util = require('util');
|
||||
|
||||
// Virtual I/O devices.
|
||||
var Clock = require('../io/clock');
|
||||
var Mouse = require('../io/mouse');
|
||||
|
||||
var defaultBlockPackages = {
|
||||
'scratch3_control': require('../blocks/scratch3_control'),
|
||||
'scratch3_event': require('../blocks/scratch3_event'),
|
||||
'scratch3_looks': require('../blocks/scratch3_looks'),
|
||||
'scratch3_motion': require('../blocks/scratch3_motion'),
|
||||
'scratch3_operators': require('../blocks/scratch3_operators')
|
||||
'scratch3_operators': require('../blocks/scratch3_operators'),
|
||||
'scratch3_sensing': require('../blocks/scratch3_sensing')
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -43,6 +48,11 @@ function Runtime (targets) {
|
|||
*/
|
||||
this._primitives = {};
|
||||
this._registerBlockPackages();
|
||||
|
||||
this.ioDevices = {
|
||||
'clock': new Clock(),
|
||||
'mouse': new Mouse()
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
14
src/index.js
14
src/index.js
|
@ -101,6 +101,17 @@ VirtualMachine.prototype.animationFrame = function () {
|
|||
this.runtime.animationFrame();
|
||||
};
|
||||
|
||||
/**
|
||||
* Post I/O data to the virtual devices.
|
||||
* @param {?string} device Name of virtual I/O device.
|
||||
* @param {Object} data Any data object to post to the I/O device.
|
||||
*/
|
||||
VirtualMachine.prototype.postIOData = function (device, data) {
|
||||
if (this.runtime.ioDevices[device]) {
|
||||
this.runtime.ioDevices[device].postData(data);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Worker handlers: for all public methods available above,
|
||||
* we must also provide a message handler in case the VM is run
|
||||
|
@ -140,6 +151,9 @@ if (ENV_WORKER) {
|
|||
case 'animationFrame':
|
||||
self.vmInstance.animationFrame();
|
||||
break;
|
||||
case 'postIOData':
|
||||
self.vmInstance.postIOData(messageData.device, messageData.data);
|
||||
break;
|
||||
default:
|
||||
if (e.data.id == 'RendererConnected') {
|
||||
//initRenderWorker();
|
||||
|
|
16
src/io/clock.js
Normal file
16
src/io/clock.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
var Timer = require('../util/timer');
|
||||
|
||||
function Clock () {
|
||||
this._projectTimer = new Timer();
|
||||
this._projectTimer.start();
|
||||
}
|
||||
|
||||
Clock.prototype.projectTimer = function () {
|
||||
return this._projectTimer.timeElapsed() / 1000;
|
||||
};
|
||||
|
||||
Clock.prototype.resetProjectTimer = function () {
|
||||
this._projectTimer.start();
|
||||
};
|
||||
|
||||
module.exports = Clock;
|
33
src/io/mouse.js
Normal file
33
src/io/mouse.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
var MathUtil = require('../util/math-util');
|
||||
|
||||
function Mouse () {
|
||||
this._x = 0;
|
||||
this._y = 0;
|
||||
this._isDown = false;
|
||||
}
|
||||
|
||||
Mouse.prototype.postData = function(data) {
|
||||
if (data.x) {
|
||||
this._x = data.x;
|
||||
}
|
||||
if (data.y) {
|
||||
this._y = data.y;
|
||||
}
|
||||
if (typeof data.isDown !== 'undefined') {
|
||||
this._isDown = data.isDown;
|
||||
}
|
||||
};
|
||||
|
||||
Mouse.prototype.getX = function () {
|
||||
return MathUtil.clamp(this._x, -240, 240);
|
||||
};
|
||||
|
||||
Mouse.prototype.getY = function () {
|
||||
return MathUtil.clamp(-this._y, -180, 180);
|
||||
};
|
||||
|
||||
Mouse.prototype.getIsDown = function () {
|
||||
return this._isDown;
|
||||
};
|
||||
|
||||
module.exports = Mouse;
|
|
@ -51,6 +51,14 @@ VirtualMachine.prototype.getPlaygroundData = function () {
|
|||
this.vmWorker.postMessage({method: 'getPlaygroundData'});
|
||||
};
|
||||
|
||||
VirtualMachine.prototype.postIOData = function (device, data) {
|
||||
this.vmWorker.postMessage({
|
||||
method: 'postIOData',
|
||||
device: device,
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
VirtualMachine.prototype.start = function () {
|
||||
this.vmWorker.postMessage({method: 'start'});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue