Skip to content

Commit 3713198

Browse files
committed
supported terminate blocks like forever, stop.
1 parent c2fa72e commit 3713198

File tree

15 files changed

+1516
-1032
lines changed

15 files changed

+1516
-1032
lines changed

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

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ const createControlRepeatBlock = function (times, body) {
88
this._addSubstack(block, body);
99
return block;
1010
};
11+
12+
const StopOptions = [
13+
'all',
14+
'this script',
15+
'other scripts in sprite'
16+
];
1117
/* eslint-enable no-invalid-this */
1218

1319
/**
@@ -33,22 +39,34 @@ const ControlConverter = {
3339
break;
3440
case 'loop':
3541
case 'forever':
36-
if (args.length === 0 &&
37-
rubyBlockArgs && rubyBlockArgs.length === 0 &&
38-
rubyBlock && (name !== 'loop' || this._popWaitBlock(rubyBlock))) {
39-
block = this._createBlock('control_forever', 'statement');
40-
this._addSubstack(block, rubyBlock);
42+
if (args.length === 0 && rubyBlockArgs && rubyBlockArgs.length === 0 && rubyBlock) {
43+
let found;
44+
if (name === 'loop') {
45+
const b = this._popWaitBlock(rubyBlock);
46+
if (b) {
47+
if (b.id === rubyBlock.id) {
48+
rubyBlock = null;
49+
}
50+
found = true;
51+
}
52+
} else {
53+
found = true;
54+
}
55+
if (found) {
56+
block = this._createBlock('control_forever', 'terminate');
57+
this._addSubstack(block, rubyBlock);
58+
}
4159
}
4260
break;
4361
case 'stop':
4462
if (args.length === 1 &&
45-
_.isString(args[0]) && ['all', 'this script', 'other scripts in sprite'].indexOf(args[0]) >= 0) {
46-
block = this._createBlock('control_stop', 'statement');
63+
this._isString(args[0]) && StopOptions.indexOf(args[0].toString()) >= 0) {
64+
block = this._createBlock('control_stop', 'terminate');
4765
this._addField(block, 'STOP_OPTION', args[0]);
4866
}
4967
break;
5068
case 'create_clone':
51-
if (args.length === 1 && _.isString(args[0])) {
69+
if (args.length === 1 && this._isString(args[0])) {
5270
block = this._createBlock('control_create_clone_of', 'statement');
5371
const optionBlock = this._createBlock('control_create_clone_of_menu', 'value', {
5472
shadow: true
@@ -64,16 +82,12 @@ const ControlConverter = {
6482
break;
6583
case 'when':
6684
if (args.length === 1 &&
67-
_.isString(args[0]) && args[0] === 'start_as_a_clone' &&
68-
rubyBlockArgs && rubyBlockArgs.length === 0 &&
69-
rubyBlock) {
70-
block = this._createBlock('control_start_as_clone', 'hat', {
71-
topLevel: true
72-
});
73-
74-
if (this._isBlock(rubyBlock[0])) {
75-
rubyBlock[0].parent = block.id;
76-
block.next = rubyBlock[0].id;
85+
args[0].type === 'sym' && args[0].value === 'start_as_a_clone' &&
86+
rubyBlockArgs && rubyBlockArgs.length === 0) {
87+
block = this._createBlock('control_start_as_clone', 'hat');
88+
if (this._isBlock(rubyBlock)) {
89+
rubyBlock.parent = block.id;
90+
block.next = rubyBlock.id;
7791
}
7892
}
7993
break;
@@ -82,10 +96,12 @@ const ControlConverter = {
8296
switch (name) {
8397
case 'times':
8498
if (args.length === 0 &&
85-
rubyBlockArgs && rubyBlockArgs.length === 0 &&
86-
rubyBlock && rubyBlock.length >= 1) {
87-
const waitBlock = this._popWaitBlock(rubyBlock);
88-
if (waitBlock) {
99+
rubyBlockArgs && rubyBlockArgs.length === 0 && rubyBlock) {
100+
const b = this._popWaitBlock(rubyBlock);
101+
if (b) {
102+
if (b.id === rubyBlock.id) {
103+
rubyBlock = null;
104+
}
89105
block = createControlRepeatBlock.call(this, receiver, rubyBlock);
90106
}
91107
}
@@ -97,7 +113,7 @@ const ControlConverter = {
97113

98114
onIf: function (cond, statement, elseStatement) {
99115
const block = this._createBlock('control_if', 'statement');
100-
if (cond !== false) {
116+
if (!this._isFalse(cond)) {
101117
this._addInput(block, 'CONDITION', cond);
102118
}
103119
this._addSubstack(block, statement);
@@ -110,14 +126,19 @@ const ControlConverter = {
110126

111127
onUntil: function (cond, statement) {
112128
const block = this._createBlock('control_repeat_until', 'statement');
113-
if (cond !== false) {
129+
if (!this._isFalse(cond)) {
114130
this._addInput(block, 'CONDITION', cond);
115131
}
116-
if (statement.length === 1 && this._popWaitBlock(statement)) {
117-
block.opcode = 'control_wait_until';
118-
} else {
119-
this._addSubstack(block, statement);
132+
if (this._isBlock(statement) && statement.next === null) {
133+
const b = this._popWaitBlock(statement);
134+
if (b) {
135+
if (b.id === statement.id) {
136+
statement = null;
137+
}
138+
block.opcode = 'control_wait_until';
139+
}
120140
}
141+
this._addSubstack(block, statement);
121142
return block;
122143
}
123144
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Exception class for RubyToBlocksConverter
3+
*/
4+
class RubyToBlocksConverterError {
5+
constructor (node, message) {
6+
this.node = node;
7+
this.message = message;
8+
}
9+
}
10+
11+
export {
12+
RubyToBlocksConverterError
13+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* global Opal */
2+
import _ from 'lodash';
3+
4+
/**
5+
* Event converter
6+
*/
7+
const EventConverter = {
8+
// eslint-disable-next-line no-unused-vars
9+
onSend: function (receiver, name, args, rubyBlockArgs, rubyBlock) {
10+
let block;
11+
if (this._isSelf(receiver) || receiver === Opal.nil) {
12+
switch (name) {
13+
case 'when':
14+
if (args.length === 1) {
15+
if (args[0].type === 'sym' && args[0].value === 'flag_clicked' &&
16+
rubyBlockArgs && rubyBlockArgs.length === 0) {
17+
block = this._createBlock('event_whenflagclicked', 'hat');
18+
if (this._isBlock(rubyBlock)) {
19+
rubyBlock.parent = block.id;
20+
block.next = rubyBlock.id;
21+
}
22+
}
23+
}
24+
break;
25+
}
26+
}
27+
return block;
28+
}
29+
};
30+
31+
export default EventConverter;

0 commit comments

Comments
 (0)