diff --git a/src/lib/monitor-adapter.js b/src/lib/monitor-adapter.js new file mode 100644 index 0000000000000000000000000000000000000000..eccf540be8c74b52bcc8966c06ca60d765d4aad8 --- /dev/null +++ b/src/lib/monitor-adapter.js @@ -0,0 +1,31 @@ +/** + * Convert monitors from VM format to what the GUI needs to render. + * - Convert opcode to a label and a category + * - Add missing XY position data if needed + */ +const log = require('./log'); + +const OpcodeLabels = require('../lib/opcode-labels.js'); + +const PADDING = 5; +const MONITOR_HEIGHT = 23; + +const isUndefined = a => typeof a === 'undefined'; + +module.exports = function ({id, opcode, value, x, y}, monitorIndex) { + + // Look up category and label from opcode label file + let opcodeData = OpcodeLabels[opcode]; + if (isUndefined(opcodeData)) { + log.error(`No category/label found for opcode: ${opcode}`); + opcodeData = {category: 'data', label: opcode}; + } + const {label, category} = opcodeData; + + // Simple layout if x or y are undefined + // @todo scratch2 has a more complex layout behavior we may want to adopt + if (isUndefined(x)) x = PADDING; + if (isUndefined(y)) y = PADDING + (monitorIndex * (PADDING + MONITOR_HEIGHT)); + + return {id, label, category, value, x, y}; +}; diff --git a/src/lib/opcode-labels.js b/src/lib/opcode-labels.js new file mode 100644 index 0000000000000000000000000000000000000000..402d6e56e02d1d04ae42bd56d22b41a1f6186c27 --- /dev/null +++ b/src/lib/opcode-labels.js @@ -0,0 +1,67 @@ +module.exports = { + // Motion + motion_direction: { + category: 'motion', + label: 'direction' + }, + motion_xposition: { + category: 'motion', + label: 'x position' + }, + motion_yposition: { + category: 'motion', + label: 'y position' + }, + + // Looks + looks_size: { + category: 'looks', + label: 'size' + }, + looks_costumeorder: { + category: 'looks', + label: 'costume #' + }, + looks_backdroporder: { + category: 'looks', + label: 'backdrop #' + }, + looks_backdropname: { + category: 'looks', + label: 'backdrop name' + }, + + // Data + data_variable: { + category: 'data', + label: 'Variable _' // @todo placeholder for params + }, + + // Sound + sound_volume: { + category: 'sound', + label: 'volume' + }, + sound_tempo: { + category: 'sound', + label: 'tempo' + }, + + // Sensing + sensing_loudness: { + category: 'sensing', + label: 'loundness' + }, + sensing_of: { + category: 'sensing', + label: '_ of _' // @todo placeholder for params + }, + sensing_current: { + category: 'sensing', + label: 'current _' // @todo placeholder for param + }, + sensing_timer: { + category: 'timer', + label: 'timer' + } +}; diff --git a/src/reducers/monitors.js b/src/reducers/monitors.js index e8b4fa947eee4862f24be5ea8727caef6793fe5c..18e9529f4ad417645101a5cc85ed60b6b8adecf0 100644 --- a/src/reducers/monitors.js +++ b/src/reducers/monitors.js @@ -1,3 +1,5 @@ +const monitorAdapter = require('../lib/monitor-adapter.js'); + const UPDATE_MONITORS = 'scratch-gui/monitors/UPDATE_MONITORS'; const initialState = []; @@ -6,7 +8,7 @@ const reducer = function (state, action) { if (typeof state === 'undefined') state = initialState; switch (action.type) { case UPDATE_MONITORS: - return [...action.monitors]; + return action.monitors.map(monitorAdapter); default: return state; }