Skip to content

Commit fcdbb02

Browse files
committed
Merge remote-tracking branch 'origin/issue/88' into develop
2 parents 2a5f7a0 + fdcee0c commit fcdbb02

File tree

2 files changed

+167
-108
lines changed

2 files changed

+167
-108
lines changed

src/lib/ruby-generator/index.js

Lines changed: 102 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,40 @@ export default function (Blockly) {
103103
}
104104
}
105105
this.defineSprite(this.editingTarget);
106-
this.defineVariables(this.editingTarget);
106+
};
107+
108+
Blockly.Ruby.isString = function (s) {
109+
return (typeof s === 'string' || s instanceof String);
110+
};
111+
112+
Blockly.Ruby.scalarToCode = function (scalar) {
113+
if (this.isString(scalar)) {
114+
return this.quote_(scalar);
115+
}
116+
return scalar;
117+
};
118+
119+
Blockly.Ruby.listToCode = function (list) {
120+
const values = list.map(i => {
121+
if (this.isString(i)) {
122+
return this.quote_(i);
123+
}
124+
return i;
125+
}).join(', ');
126+
return `[${values}]`;
127+
};
128+
129+
Blockly.Ruby.hashToCode = function (hash, separator = ': ', brace = true) {
130+
const lines = [];
131+
for (const key in hash) {
132+
const value = hash[key];
133+
lines.push(`${key}${separator}${value}`);
134+
}
135+
let code = lines.join(',\n');
136+
if (brace) {
137+
code = ['{', this.prefixLines(code, this.INDENT), '}'].join('\n');
138+
}
139+
return code;
107140
};
108141

109142
Blockly.Ruby.defineSprite = function (renderedTarget) {
@@ -115,83 +148,97 @@ export default function (Blockly) {
115148
const definitionsId = `sprite_${name}`;
116149

117150
if (!this.definitions_.hasOwnProperty(definitionsId)) {
118-
const attributes = [''];
151+
const attributes = {};
119152

120153
if (renderedTarget.x !== 0) {
121-
attributes.push(`x: ${renderedTarget.x}`);
154+
attributes.x = renderedTarget.x;
122155
}
123156
if (renderedTarget.y !== 0) {
124-
attributes.push(`y: ${renderedTarget.y}`);
157+
attributes.y = renderedTarget.y;
125158
}
126159
if (renderedTarget.direction !== 90) {
127-
attributes.push(`direction: ${renderedTarget.direction}`);
160+
attributes.direction = renderedTarget.direction;
128161
}
129162
if (!renderedTarget.visible) {
130-
attributes.push(`visible: ${!!renderedTarget.visible}`);
163+
attributes.visible = !!renderedTarget.visible;
131164
}
132165
if (renderedTarget.size !== 100) {
133-
attributes.push(`size: ${renderedTarget.size}`);
166+
attributes.size = renderedTarget.size;
134167
}
135168
if (renderedTarget.currentCostume > 1) {
136-
attributes.push(`current_costume: ${renderedTarget.currentCostume - 1}`);
169+
attributes.current_costume = renderedTarget.currentCostume - 1;
137170
}
138-
if (renderedTarget.sprite.costumes.length > 0) {
139-
const costumesParams = ['costumes: ['];
140-
costumesParams.push(
141-
renderedTarget.sprite.costumes.map(costume => ` {
142-
asset_id: ${this.quote_(costume.assetId)},
143-
name: ${this.quote_(costume.name)},
144-
bitmap_resolution: ${costume.bitmapResolution},
145-
md5: ${this.quote_(costume.md5)},
146-
data_format: ${this.quote_(costume.dataFormat)},
147-
rotation_center_x: ${costume.rotationCenterX},
148-
rotation_center_y: ${costume.rotationCenterY}
149-
}`).join(',\n')
150-
);
151-
costumesParams.push(' ]');
152-
attributes.push(costumesParams.join('\n'));
171+
const costumes = renderedTarget.sprite.costumes;
172+
if (costumes.length > 0) {
173+
const s = costumes.map(i => {
174+
const h = {
175+
asset_id: this.quote_(i.assetId),
176+
name: this.quote_(i.name),
177+
bitmap_resolution: i.bitmapResolution,
178+
md5: this.quote_(i.md5),
179+
data_format: this.quote_(i.dataFormat),
180+
rotation_center_x: i.rotationCenterX,
181+
rotation_center_y: i.rotationCenterY
182+
};
183+
return this.hashToCode(h);
184+
}).join(',\n');
185+
attributes.costumes = `[\n${this.prefixLines(s, this.INDENT)}\n]`;
153186
}
154187
switch (renderedTarget.rotationStyle) {
155188
case RenderedTarget.ROTATION_STYLE_LEFT_RIGHT:
156-
attributes.push('rotation_style: :left_right');
189+
attributes.rotation_style = ':left_right';
157190
break;
158191
case RenderedTarget.ROTATION_STYLE_NONE:
159-
attributes.push('rotation_style: :none');
192+
attributes.rotation_style = ':none';
160193
break;
161194
}
162195

163-
this.definitions_[definitionsId] =
164-
`Sprite.new(${this.quote_(name)}${attributes.join(',\n ')})`;
165-
}
166-
return Blockly.Ruby.definitions_[definitionsId];
167-
};
168-
169-
Blockly.Ruby.defineVariables = function (renderedTarget) {
170-
if (!renderedTarget) {
171-
return null;
172-
}
196+
const variables = [];
197+
const lists = [];
198+
for (const id in renderedTarget.variables) {
199+
const v = renderedTarget.variables[id];
200+
switch (v.type) {
201+
case SCALAR_TYPE:
202+
variables.push(v);
203+
break;
204+
case LIST_TYPE:
205+
lists.push(v);
206+
break;
207+
}
208+
}
209+
if (variables.length > 0) {
210+
const s = variables.map(i => {
211+
const h = {
212+
name: this.quote_(i.name)
213+
};
214+
if (i.value !== 0) {
215+
h.value = this.scalarToCode(i.value);
216+
}
217+
return this.hashToCode(h);
218+
}).join(',\n');
219+
attributes.variables = `[\n${this.prefixLines(s, this.INDENT)}\n]`;
220+
}
221+
if (lists.length > 0) {
222+
const s = lists.map(i => {
223+
const h = {
224+
name: this.quote_(i.name)
225+
};
226+
if (i.value.length > 0) {
227+
h.value = this.listToCode(i.value);
228+
}
229+
return this.hashToCode(h);
230+
}).join(',\n');
231+
attributes.lists = `[\n${this.prefixLines(s, this.INDENT)}\n]`;
232+
}
173233

174-
const variables = [];
175-
const lists = [];
176-
for (const varId in renderedTarget.variables) {
177-
const currVar = renderedTarget.variables[varId];
178-
switch (currVar.type) {
179-
case SCALAR_TYPE:
180-
variables.push(currVar);
181-
break;
182-
case LIST_TYPE:
183-
lists.push(currVar);
184-
break;
234+
let code = this.hashToCode(attributes, ': ', false);
235+
if (code.length > 0) {
236+
code = `,\n${this.prefixLines(code, ' ')}`;
185237
}
238+
this.definitions_[definitionsId] =
239+
`Sprite.new(${this.quote_(name)}${code})`;
186240
}
187-
variables.forEach(currVar => {
188-
this.definitions_[`variable_${currVar.name}`] =
189-
`${this.spriteName(renderedTarget)}.make_variable(${this.quote_(currVar.name)})`;
190-
});
191-
lists.forEach(currVar => {
192-
this.definitions_[`list_${currVar.name}`] =
193-
`${this.spriteName(renderedTarget)}.make_list(${this.quote_(currVar.name)})`;
194-
});
241+
return Blockly.Ruby.definitions_[definitionsId];
195242
};
196243

197244
Blockly.Ruby.characterStack = function () {
@@ -301,7 +348,7 @@ export default function (Blockly) {
301348

302349
for (name in Blockly.Ruby.definitions_) {
303350
const def = this.definitions_[name];
304-
if (typeof def === 'string' || def instanceof String) {
351+
if (this.isString(def)) {
305352
if (name.match(/^require__/)) {
306353
requires.push(def);
307354
} else if (name.match(/^prepare__/)) {

test/unit/lib/ruby-generator.test.jsx

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ describe('RubyGenerator', () => {
77
let Blockly;
88
let Ruby;
99

10+
const SCALAR_TYPE = '';
11+
const LIST_TYPE = 'list';
12+
1013
beforeEach(() => {
1114
vm = new VM();
1215
Blockly = VMScratchBlocks(vm);
@@ -55,9 +58,6 @@ describe('RubyGenerator', () => {
5558
let renderedTarget;
5659

5760
beforeEach(() => {
58-
const SCALAR_TYPE = '';
59-
const LIST_TYPE = 'list';
60-
6161
renderedTarget = {
6262
sprite: {
6363
name: 'Sprite1'
@@ -176,7 +176,39 @@ describe('RubyGenerator', () => {
176176
visible: false,
177177
size: 44,
178178
currentCostume: 2,
179-
rotationStyle: 'left-right'
179+
rotationStyle: 'left-right',
180+
variables: {
181+
id1: {
182+
name: 'Variable1',
183+
type: SCALAR_TYPE,
184+
value: 10
185+
},
186+
id2: {
187+
name: 'List1',
188+
type: LIST_TYPE,
189+
value: [1, 2, 3]
190+
},
191+
id3: {
192+
name: 'Variable2',
193+
type: SCALAR_TYPE,
194+
value: 0
195+
},
196+
id4: {
197+
name: 'List2',
198+
type: LIST_TYPE,
199+
value: []
200+
},
201+
id5: {
202+
name: 'Variable3',
203+
type: SCALAR_TYPE,
204+
value: 'abc'
205+
},
206+
id6: {
207+
name: 'List3',
208+
type: LIST_TYPE,
209+
value: ['a', 'b', 'c']
210+
}
211+
}
180212
};
181213
});
182214

@@ -208,7 +240,33 @@ describe('RubyGenerator', () => {
208240
rotation_center_y: 61
209241
}
210242
],
211-
rotation_style: :left_right)`;
243+
rotation_style: :left_right,
244+
variables: [
245+
{
246+
name: "Variable1",
247+
value: 10
248+
},
249+
{
250+
name: "Variable2"
251+
},
252+
{
253+
name: "Variable3",
254+
value: "abc"
255+
}
256+
],
257+
lists: [
258+
{
259+
name: "List1",
260+
value: [1, 2, 3]
261+
},
262+
{
263+
name: "List2"
264+
},
265+
{
266+
name: "List3",
267+
value: ["a", "b", "c"]
268+
}
269+
])`;
212270
expect(Ruby.defineSprite(renderedTarget)).toEqual(expected);
213271
});
214272

@@ -225,58 +283,12 @@ describe('RubyGenerator', () => {
225283
visible: true,
226284
size: 100,
227285
currentCostume: 1,
228-
rotationStyle: 'all around'
286+
rotationStyle: 'all around',
287+
variables: {}
229288
});
230289
renderedTarget.sprite.costumes = [];
231290
const expected = `Sprite.new(${Ruby.quote_(spriteName)})`;
232291
expect(Ruby.defineSprite(renderedTarget)).toEqual(expected);
233292
});
234293
});
235-
236-
describe('defineVariables', () => {
237-
let renderedTarget;
238-
239-
beforeEach(() => {
240-
const SCALAR_TYPE = '';
241-
const LIST_TYPE = 'list';
242-
243-
renderedTarget = {
244-
sprite: {
245-
name: 'Sprite1'
246-
},
247-
variables: {
248-
id1: {
249-
name: 'Variable1',
250-
type: SCALAR_TYPE
251-
},
252-
id2: {
253-
name: 'List1',
254-
type: LIST_TYPE
255-
},
256-
id3: {
257-
name: 'Variable2',
258-
type: SCALAR_TYPE
259-
},
260-
id4: {
261-
name: 'List2',
262-
type: LIST_TYPE
263-
}
264-
}
265-
};
266-
});
267-
268-
test('add definitions_ the make_variable and make_list codes', () => {
269-
Ruby.defineVariables(renderedTarget);
270-
const spriteName = Ruby.spriteName(renderedTarget);
271-
const expecteds = {
272-
variable_Variable1: `${spriteName}.make_variable(${Ruby.quote_('Variable1')})`,
273-
variable_Variable2: `${spriteName}.make_variable(${Ruby.quote_('Variable2')})`,
274-
list_List1: `${spriteName}.make_list(${Ruby.quote_('List1')})`,
275-
list_List2: `${spriteName}.make_list(${Ruby.quote_('List2')})`
276-
};
277-
for (const name in expecteds) {
278-
expect(Ruby.definitions_[name]).toEqual(expecteds[name]);
279-
}
280-
});
281-
});
282294
});

0 commit comments

Comments
 (0)