Skip to content

Commit fa1850d

Browse files
authored
Merge pull request #164 from smalruby/issues/134_sound
convert Ruby to Sound blocks. (refs #134)
2 parents ef139ae + 8fb0e76 commit fa1850d

File tree

6 files changed

+464
-10
lines changed

6 files changed

+464
-10
lines changed

src/lib/ruby-generator/sound.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,34 @@
55
*/
66
export default function (Generator){
77
Generator.sound_sounds_menu = function (block) {
8-
const sound = Generator.quote_(Generator.getFieldValue(block, 'SOUND_MENU') || null);
8+
const sound = Generator.quote_(Generator.getFieldValue(block, 'SOUND_MENU') || '');
99
return [sound, Generator.ORDER_ATOMIC];
1010
};
1111

1212
Generator.sound_playuntildone = function (block) {
1313
const sound = Generator.valueToCode(block, 'SOUND_MENU', Generator.ORDER_NONE) || null;
14-
return `play_until_done(name: ${sound})\n`;
14+
return `play_until_done(${sound})\n`;
1515
};
1616

1717
Generator.sound_play = function (block) {
1818
const sound = Generator.valueToCode(block, 'SOUND_MENU', Generator.ORDER_NONE) || null;
19-
return `play(name: ${sound})\n`;
19+
return `play(${sound})\n`;
2020
};
2121

2222
Generator.sound_stopallsounds = function () {
2323
return 'stop_all_sounds\n';
2424
};
2525

2626
Generator.sound_changeeffectby = function (block) {
27-
const effect = Generator.quote_(Generator.getFieldValue(block, 'EFFECT') || null);
27+
const effect = Generator.quote_(Generator.getFieldValue(block, 'EFFECT') || '');
2828
const value = Generator.valueToCode(block, 'VALUE', Generator.ORDER_NONE) || '0';
29-
return `change_sound_effect_by(effect: ${effect}, value: ${value})\n`;
29+
return `change_sound_effect_by(${effect}, ${value})\n`;
3030
};
3131

3232
Generator.sound_seteffectto = function (block) {
33-
const effect = Generator.quote_(Generator.getFieldValue(block, 'EFFECT') || null);
33+
const effect = Generator.quote_(Generator.getFieldValue(block, 'EFFECT') || '');
3434
const value = Generator.valueToCode(block, 'VALUE', Generator.ORDER_NONE) || '0';
35-
return `set_sound_effect(effect: ${effect}, value: ${value})\n`;
35+
return `set_sound_effect(${effect}, ${value})\n`;
3636
};
3737

3838
Generator.sound_cleareffects = function () {
@@ -50,7 +50,7 @@ export default function (Generator){
5050
};
5151

5252
Generator.sound_volume = function () {
53-
return ['self.volume', Generator.ORDER_ATOMIC];
53+
return ['volume', Generator.ORDER_ATOMIC];
5454
};
5555

5656
return Generator;

src/lib/ruby-to-blocks-converter/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {RubyToBlocksConverterError} from './errors';
1010

1111
import MotionConverter from './motion';
1212
import LooksConverter from './looks';
13+
import SoundConverter from './sound';
1314
import EventConverter from './event';
1415
import ControlConverter from './control';
1516
import SensingConverter from './sensing';
@@ -26,6 +27,7 @@ class RubyToBlocksConverter {
2627
this._converters = [
2728
MotionConverter,
2829
LooksConverter,
30+
SoundConverter,
2931
EventConverter,
3032
ControlConverter,
3133
SensingConverter,
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/* global Opal */
2+
import _ from 'lodash';
3+
4+
const Effect = [
5+
'PITCH',
6+
'PAN'
7+
];
8+
9+
/**
10+
* Sound converter
11+
*/
12+
const SoundConverter = {
13+
// eslint-disable-next-line no-unused-vars
14+
onSend: function (receiver, name, args, rubyBlockArgs, rubyBlock) {
15+
let block;
16+
if ((this._isSelf(receiver) || receiver === Opal.nil) && !rubyBlock) {
17+
switch (name) {
18+
case 'play_until_done':
19+
case 'play':
20+
if (args.length === 1 && this._isStringOrBlock(args[0])) {
21+
let opcode;
22+
if (name === 'play_until_done') {
23+
opcode = 'sound_playuntildone';
24+
} else {
25+
opcode = 'sound_play';
26+
}
27+
const menuBlock = this._createBlock('sound_sounds_menu', 'value', {
28+
shadow: true
29+
});
30+
let inputBlock;
31+
let shadowBlock;
32+
if (this._isString(args[0])) {
33+
this._addField(menuBlock, 'SOUND_MENU', args[0]);
34+
inputBlock = menuBlock;
35+
shadowBlock = menuBlock;
36+
} else {
37+
this._addField(menuBlock, 'SOUND_MENU', '');
38+
inputBlock = args[0];
39+
shadowBlock = menuBlock;
40+
}
41+
block = this._createBlock(opcode, 'statement');
42+
this._addInput(block, 'SOUND_MENU', inputBlock, shadowBlock);
43+
}
44+
break;
45+
case 'stop_all_sounds':
46+
case 'clear_sound_effects':
47+
case 'volume':
48+
if (args.length === 0) {
49+
let opcode;
50+
let blockType;
51+
switch (name) {
52+
case 'stop_all_sounds':
53+
opcode = 'sound_stopallsounds';
54+
blockType = 'statement';
55+
break;
56+
case 'clear_sound_effects':
57+
opcode = 'sound_cleareffects';
58+
blockType = 'statement';
59+
break;
60+
case 'volume':
61+
opcode = 'sound_volume';
62+
blockType = 'value';
63+
break;
64+
}
65+
block = this._createBlock(opcode, blockType);
66+
}
67+
break;
68+
case 'change_sound_effect_by':
69+
case 'set_sound_effect':
70+
if (args.length === 2 && this._isString(args[0]) && Effect.indexOf(args[0].toString()) >= 0 &&
71+
this._isNumberOrBlock(args[1])) {
72+
let opcode;
73+
let value;
74+
if (name === 'change_sound_effect_by') {
75+
opcode = 'sound_changeeffectby';
76+
value = 10;
77+
} else {
78+
opcode = 'sound_seteffectto';
79+
value = 100;
80+
}
81+
block = this._createBlock(opcode, 'statement');
82+
this._addField(block, 'EFFECT', args[0]);
83+
this._addNumberInput(block, 'VALUE', 'math_number', args[1], value);
84+
}
85+
break;
86+
case 'volume=':
87+
if (args.length === 1 && this._isNumberOrBlock(args[0])) {
88+
block = this._createBlock('sound_setvolumeto', 'statement');
89+
this._addNumberInput(block, 'VOLUME', 'math_number', args[0], 100);
90+
}
91+
break;
92+
}
93+
}
94+
return block;
95+
},
96+
97+
// eslint-disable-next-line no-unused-vars
98+
onOpAsgn: function (lh, operator, rh) {
99+
let block;
100+
if (this._isBlock(lh) && lh.opcode === 'sound_volume' && operator === '+' && this._isNumberOrBlock(rh)) {
101+
block = this._changeBlock(lh, 'sound_changevolumeby', 'statement');
102+
this._addNumberInput(block, 'VOLUME', 'math_number', rh, -10);
103+
}
104+
return block;
105+
}
106+
};
107+
108+
export default SoundConverter;

test/helpers/expect-to-equal-blocks.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ const expectedInfo = {
423423
})
424424
};
425425

426-
const expectNoArgsMethod = function (opcode, methodName) {
426+
const expectNoArgsMethod = function (opcode, methodName, blockType = 'statement') {
427427
let converter;
428428
let target;
429429
let code;
@@ -455,6 +455,36 @@ const expectNoArgsMethod = function (opcode, methodName) {
455455
convertAndExpectToEqualBlocks(converter, target, code, expected);
456456
});
457457

458+
if (blockType === 'statement') {
459+
test('statement', () => {
460+
code = `
461+
bounce_if_on_edge
462+
${methodName}
463+
bounce_if_on_edge
464+
`;
465+
expected = [
466+
rubyToExpected(converter, target, 'bounce_if_on_edge')[0]
467+
];
468+
expected[0].next = rubyToExpected(converter, target, `${methodName}`)[0];
469+
expected[0].next.next = rubyToExpected(converter, target, 'bounce_if_on_edge')[0];
470+
convertAndExpectToEqualBlocks(converter, target, code, expected);
471+
});
472+
} else if (blockType === 'value') {
473+
test('value', () => {
474+
code = `
475+
bounce_if_on_edge
476+
${methodName}
477+
bounce_if_on_edge
478+
`;
479+
expected = [
480+
rubyToExpected(converter, target, 'bounce_if_on_edge')[0],
481+
rubyToExpected(converter, target, `${methodName}`)[0],
482+
rubyToExpected(converter, target, 'bounce_if_on_edge')[0]
483+
];
484+
convertAndExpectToEqualBlocks(converter, target, code, expected);
485+
});
486+
}
487+
458488
test('invalid', () => {
459489
[
460490
`${methodName}(false)`,

test/unit/lib/ruby-to-blocks-converter/looks.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ describe('RubyToBlocksConverter/Looks', () => {
607607
expectNoArgsMethod('looks_cleargraphiceffects', 'clear_graphic_effects');
608608
expectNoArgsMethod('looks_show', 'show');
609609
expectNoArgsMethod('looks_hide', 'hide');
610-
expectNoArgsMethod('looks_size', 'size');
610+
expectNoArgsMethod('looks_size', 'size', 'value');
611611

612612
describe('looks_gotofrontback', () => {
613613
test('normal', () => {

0 commit comments

Comments
 (0)