smalruby-editor 0.1.15-x86-mingw32 → 0.1.16-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of smalruby-editor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.rdoc +16 -1
- data/app/assets/javascripts/blocks/character.js.coffee.erb +8 -1
- data/app/assets/javascripts/blocks/hardware.js.coffee.erb +59 -7
- data/app/assets/javascripts/blocks/motion.js.coffee.erb +1 -2
- data/app/assets/javascripts/models/character.js.coffee +27 -0
- data/app/assets/javascripts/smalruby.js.coffee +4 -0
- data/app/assets/javascripts/views/character_modal_view.js.coffee +22 -1
- data/app/assets/javascripts/views/character_selector_view.js.coffee +7 -6
- data/app/assets/stylesheets/application.css +8 -0
- data/app/assets/stylesheets/editor.css.scss +15 -5
- data/app/controllers/application_controller.rb +4 -7
- data/app/models/concerns/ruby_to_block/block/character.rb +14 -6
- data/app/models/concerns/ruby_to_block/block/hardware_two_wheel_drive_car.rb +1 -1
- data/app/models/concerns/ruby_to_block/block/hardware_two_wheel_drive_car_commands.rb +15 -0
- data/app/models/concerns/ruby_to_block/block/hardware_two_wheel_drive_car_run.rb +19 -0
- data/app/models/concerns/ruby_to_block/block/motion_set_x.rb +1 -24
- data/app/models/concerns/ruby_to_block/block/motion_set_x_y.rb +21 -0
- data/app/models/source_code.rb +9 -6
- data/app/views/editor/_block_tab.html.haml +3 -1
- data/app/views/editor/_character_modal.html.haml +14 -5
- data/app/views/editor/_toolbox.html.haml +91 -78
- data/bin/smalruby-editor +15 -0
- data/lib/smalruby_editor.rb +39 -4
- data/lib/smalruby_editor/version.rb +1 -1
- data/public/assets/{application-51ab300acd1779bfba20b099e7000b7e.css → application-7f560d8d6d224f87269691c57ca9a376.css} +23 -9
- data/public/assets/{application-51ab300acd1779bfba20b099e7000b7e.css.gz → application-7f560d8d6d224f87269691c57ca9a376.css.gz} +0 -0
- data/public/assets/{application-dc485e2270d6c5fce20c149d1e2c4f8d.js → application-842ac8f5aa3fcc87bbb0e8b3a0fef5d7.js} +148 -21
- data/public/assets/{application-dc485e2270d6c5fce20c149d1e2c4f8d.js.gz → application-842ac8f5aa3fcc87bbb0e8b3a0fef5d7.js.gz} +0 -0
- data/public/assets/manifest-332a5a1668194028b55103e0ea45c054.json +1 -1
- data/smalruby-editor.gemspec +1 -1
- data/spec/acceptance/block_mode/blocks/motion/set_x_y.feature +2 -4
- data/spec/lib/smalruby_editor_spec.rb +12 -0
- data/spec/models/concerns/ruby_to_block/block/hardware_spec.rb +90 -10
- data/spec/models/concerns/ruby_to_block/block/motion_spec.rb +3 -6
- metadata +11 -8
@@ -3,7 +3,7 @@ module RubyToBlock
|
|
3
3
|
module Block
|
4
4
|
class HardwareTwoWheelDriveCar < CharacterMethodCall
|
5
5
|
# rubocop:disable LineLength
|
6
|
-
blocknize '^\s*' + CHAR_RE + 'two_wheel_drive_car\("(D(?:[2-9]|10))"\)
|
6
|
+
blocknize '^\s*' + CHAR_RE + 'two_wheel_drive_car\("(D(?:[2-9]|10))"\)\.(forward|backward|turn_left|turn_right|stop)\s*$',
|
7
7
|
statement: true
|
8
8
|
# rubocop:enable LineLength
|
9
9
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module RubyToBlock
|
3
|
+
module Block
|
4
|
+
class HardwareTwoWheelDriveCarCommands < Value
|
5
|
+
blocknize '^\s*"(forward|backward|turn_left|turn_right|stop)"\s*$',
|
6
|
+
value: true, priority: 1
|
7
|
+
|
8
|
+
def self.process_match_data(md, context)
|
9
|
+
md2 = regexp.match(md[type])
|
10
|
+
context.add_value(new(fields: { COMMAND: md2[1] }))
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module RubyToBlock
|
3
|
+
module Block
|
4
|
+
class HardwareTwoWheelDriveCarRun < CharacterMethodCall
|
5
|
+
# rubocop:disable LineLength
|
6
|
+
blocknize '^\s*' + CHAR_RE + 'two_wheel_drive_car\("(D(?:[2-9]|10))"\)\.run\(command:\s*("[^"]*")\s*,\s*sec:\s*(\d+)\)\s*$',
|
7
|
+
statement: true, inline: true
|
8
|
+
# rubocop:enable LineLength
|
9
|
+
|
10
|
+
def self.process_match_data(md, context)
|
11
|
+
md2 = regexp.match(md[type])
|
12
|
+
add_character_method_call_block(context, md2[1],
|
13
|
+
new(fields: { PIN: md2[2] }),
|
14
|
+
SEC: md2[4], COMMAND: md2[3])
|
15
|
+
true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -7,32 +7,9 @@ module RubyToBlock
|
|
7
7
|
|
8
8
|
def self.process_match_data(md, context)
|
9
9
|
md2 = regexp.match(md[type])
|
10
|
-
|
11
|
-
X: md2[2])
|
12
|
-
|
13
|
-
md3 = MotionSetY.regexp.match(context.look_next_line)
|
14
|
-
process_motion_set_y(context, block, md3) if md3
|
15
|
-
|
10
|
+
add_character_method_call_block(context, md2[1], new, X: md2[2])
|
16
11
|
true
|
17
12
|
end
|
18
|
-
|
19
|
-
def self.process_motion_set_y(context, block, md)
|
20
|
-
if block.character == get_character(context, md[1])
|
21
|
-
process_value_string(context, block, md[2], :Y)
|
22
|
-
context.next_line
|
23
|
-
end
|
24
|
-
rescue
|
25
|
-
return
|
26
|
-
end
|
27
|
-
private_class_method :process_motion_set_y
|
28
|
-
|
29
|
-
def type
|
30
|
-
if @values.key?(:Y)
|
31
|
-
'motion_set_x_y'
|
32
|
-
else
|
33
|
-
super
|
34
|
-
end
|
35
|
-
end
|
36
13
|
end
|
37
14
|
end
|
38
15
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module RubyToBlock
|
3
|
+
module Block
|
4
|
+
class MotionSetXY < CharacterMethodCall
|
5
|
+
blocknize '^\s*' + CHAR_RE +
|
6
|
+
'position\s*=\s*\[\s*(\S+)\s*,\s*(\S+)\s*\]\s*$',
|
7
|
+
statement: true, inline: true
|
8
|
+
|
9
|
+
def self.process_match_data(md, context)
|
10
|
+
md2 = regexp.match(md[type])
|
11
|
+
add_character_method_call_block(context, md2[1], new,
|
12
|
+
X: md2[2], Y: md2[3])
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def type
|
17
|
+
'motion_set_x_y'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/app/models/source_code.rb
CHANGED
@@ -4,6 +4,7 @@ require 'tempfile'
|
|
4
4
|
require 'open3'
|
5
5
|
require 'digest/sha2'
|
6
6
|
require 'bundler'
|
7
|
+
require 'smalruby_editor'
|
7
8
|
silence_warnings do
|
8
9
|
require_relative 'concerns/ruby_to_block'
|
9
10
|
end
|
@@ -72,13 +73,15 @@ class SourceCode < ActiveRecord::Base
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def ruby_cmd
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
if SmalrubyEditor.osx?
|
77
|
+
dirs = [RbConfig::CONFIG['bindir']] + ENV['PATH'].split(';')
|
78
|
+
dirs.each do |dir|
|
79
|
+
path = Pathname('rsdl').expand_path(dir)
|
80
|
+
return path if path.exist?
|
81
|
+
end
|
81
82
|
end
|
83
|
+
Pathname(RbConfig::CONFIG['RUBY_INSTALL_NAME'])
|
84
|
+
.expand_path(RbConfig::CONFIG['bindir'])
|
82
85
|
end
|
83
86
|
|
84
87
|
def open3_capture3_ruby_c
|
@@ -21,27 +21,36 @@
|
|
21
21
|
%label.control-label{:for => 'character_name'}<
|
22
22
|
名前
|
23
23
|
.controls
|
24
|
-
%input#character_name{:name => 'character[name]', :type => 'text', :placeholder => 'car1やball1など', :class => 'input-
|
24
|
+
%input#character_name{:name => 'character[name]', :type => 'text', :placeholder => 'car1やball1など', :class => 'input-large'}
|
25
25
|
.control-group
|
26
26
|
%label.control-label{:for => 'character_x'}<
|
27
27
|
X座標
|
28
28
|
.controls
|
29
|
-
%input#character_x{:name => 'character[x]', :type => 'range', :min => '0', :max => '639', :class => 'input-
|
29
|
+
%input#character_x{:name => 'character[x]', :type => 'range', :min => '0', :max => '639', :class => 'input-large'}
|
30
30
|
%span#character_x_value{:class => 'character_value'}
|
31
31
|
300
|
32
32
|
.control-group
|
33
33
|
%label.control-label{:for => 'character_y'}<
|
34
34
|
Y座標
|
35
35
|
.controls
|
36
|
-
%input#character_y{:name => 'character[y]', :type => 'range', :min => '0', :max => '439', :class => 'input-
|
36
|
+
%input#character_y{:name => 'character[y]', :type => 'range', :min => '0', :max => '439', :class => 'input-large'}
|
37
37
|
%span#character_y_value{:class => 'character_value'}
|
38
38
|
200
|
39
39
|
.control-group
|
40
40
|
%label.control-label{:for => 'character_angle'}<
|
41
41
|
向き
|
42
42
|
.controls
|
43
|
-
|
44
|
-
|
43
|
+
#character_rotation_style.btn-group
|
44
|
+
%button#character_rotation_style_free.btn{type: "button", class: "btn-small", value: "free"}<
|
45
|
+
%i.icon-repeat
|
46
|
+
%button#character_rotation_style_left_right.btn{type: "button", class: "btn-small", value: "left_right"}<
|
47
|
+
%i.icon-resize-horizontal
|
48
|
+
%button#character_rotation_style_none.btn{type: "button", class: "btn-small", value: "none"}<
|
49
|
+
%i.icon-arrow-right
|
50
|
+
%input#character_angle{:name => 'character[angle]', :type => 'range', :min => '0', :max => '359', :class => 'input-small', style: "margin-left: 4px;"}
|
51
|
+
%span#character_angle_vector{:class => 'character_value'}
|
52
|
+
→
|
53
|
+
%span#character_angle_value{:class => 'character_value', style: "margin-left: 4px;"}
|
45
54
|
100°
|
46
55
|
|
47
56
|
.modal-footer
|
@@ -341,87 +341,100 @@
|
|
341
341
|
%block{:type => "#{category}_p"}
|
342
342
|
|
343
343
|
- category = 'hardware'
|
344
|
-
%category{:name => '
|
344
|
+
%category{:name => 'ハードウェア'}
|
345
345
|
%category{:name => '準備'}
|
346
346
|
-# ハードウェアを準備する
|
347
347
|
%block{:type => "#{category}_init_hardware"}
|
348
348
|
|
349
|
-
%category{:name => '
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
349
|
+
%category{:name => 'アクチュエータ'}
|
350
|
+
%category{:name => 'LED'}
|
351
|
+
-# LED[▼ピン]をオンにする
|
352
|
+
%block{:type => "#{category}_led_on"}
|
353
|
+
|
354
|
+
-# LED[▼ピン]をオフにする
|
355
|
+
%block{:type => "#{category}_led_off"}
|
356
|
+
|
357
|
+
-# RGB LED[▼アノード]コモン[▼ピン]を[カラー]にする
|
358
|
+
-#%block{:type => "#{category}_rgb_led_on"}
|
359
|
+
|
360
|
+
-# RGB LED[▼アノード]コモン[▼ピン]をオフにする
|
361
|
+
-#%block{:type => "#{category}_rgb_led_off"}
|
362
|
+
|
363
|
+
-# 7セグディスプレイに[▼0-9]を表示する
|
364
|
+
-#%block{:type => "#{category}_seven_segment_display_show"}
|
365
|
+
|
366
|
+
-# 7セグディスプレイをオフにする
|
367
|
+
-#%block{:type => "#{category}_seven_segment_display_off"}
|
368
|
+
|
369
|
+
-#%category{:name => 'LCD'}
|
370
|
+
-# LCDに( )を表示する
|
371
|
+
%block{:type => "#{category}_lcd_puts"}
|
372
|
+
= toolbox_text_value('TEXT', 'Hello')
|
373
|
+
|
374
|
+
-# LCDをクリアする
|
375
|
+
%block{:type => "#{category}_lcd_clear"}
|
376
|
+
|
377
|
+
-#%category{:name => 'サーボ'}
|
378
|
+
-# サーボ[▼ピン]を( )度(5~180)にする
|
379
|
+
%block{:type => "#{category}_servo_set_position"}
|
380
|
+
= toolbox_number_value('POS', 90)
|
381
|
+
|
382
|
+
- subcategory = 'two_wheel_drive_car'
|
383
|
+
%category{:name => '車'}
|
384
|
+
-# 2WD車[▼ピン]を( )秒[▼コマンド]
|
385
|
+
%block{:type => "#{category}_#{subcategory}_run"}
|
386
|
+
%field{:name => 'PIN'}<
|
387
|
+
D6
|
388
|
+
= toolbox_number_value('SEC', 1)
|
389
|
+
%value{:name => 'COMMAND'}
|
390
|
+
%block{:type => "#{category}_#{subcategory}_commands"}
|
391
|
+
|
392
|
+
-# [▼コマンド]
|
393
|
+
%block{:type => "#{category}_#{subcategory}_commands"}
|
394
|
+
%field{:name => 'COMMAND'}<
|
395
|
+
forward
|
396
|
+
|
397
|
+
-# 2WD車[▼ピン]を進める
|
398
|
+
%block{:type => "#{category}_#{subcategory}_forward"}
|
399
|
+
%field{:name => 'PIN'}<
|
400
|
+
D6
|
401
|
+
|
402
|
+
-# 2WD車[▼ピン]をバックさせる
|
403
|
+
%block{:type => "#{category}_#{subcategory}_backward"}
|
404
|
+
%field{:name => 'PIN'}<
|
405
|
+
D6
|
406
|
+
|
407
|
+
-# 2WD車[▼ピン]を左に曲げる
|
408
|
+
%block{:type => "#{category}_#{subcategory}_turn_left"}
|
409
|
+
%field{:name => 'PIN'}<
|
410
|
+
D6
|
411
|
+
|
412
|
+
-# 2WD車[▼ピン]を右に曲げる
|
413
|
+
%block{:type => "#{category}_#{subcategory}_turn_right"}
|
414
|
+
%field{:name => 'PIN'}<
|
415
|
+
D6
|
416
|
+
|
417
|
+
-# 2WD車[▼ピン]を止める
|
418
|
+
%block{:type => "#{category}_#{subcategory}_stop"}
|
419
|
+
%field{:name => 'PIN'}<
|
420
|
+
D6
|
421
|
+
|
422
|
+
%category{:name => 'センサー'}
|
423
|
+
-# センサー[▼PIN]
|
424
|
+
%block{:type => "#{category}_sensor_value"}
|
425
|
+
|
426
|
+
-# センサー[▼PIN]が変化したとき
|
427
|
+
%block{:type => "#{category}_on_sensor_change"}
|
408
428
|
|
409
429
|
-#%category{:name => 'ボタン'}
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
%category{:name => 'センサー'}
|
423
|
-
-# センサー[▼PIN]
|
424
|
-
%block{:type => "#{category}_sensor_value"}
|
425
|
-
|
426
|
-
-# センサー[▼PIN]が変化したとき
|
427
|
-
%block{:type => "#{category}_on_sensor_change"}
|
430
|
+
-# 条件:ボタン[▼]を押している
|
431
|
+
%block{:type => "#{category}_button_down"}
|
432
|
+
|
433
|
+
-# 条件:ボタン[▼]を離している
|
434
|
+
%block{:type => "#{category}_button_up"}
|
435
|
+
|
436
|
+
-# ボタン[▼]を押したとき
|
437
|
+
%block{:type => "#{category}_on_button_down"}
|
438
|
+
|
439
|
+
-# ボタン[▼]を離したとき
|
440
|
+
%block{:type => "#{category}_on_button_up"}
|
data/bin/smalruby-editor
CHANGED
@@ -84,6 +84,21 @@ end
|
|
84
84
|
Rails::Server.new.tap do |server|
|
85
85
|
require APP_PATH
|
86
86
|
Dir.chdir(Rails.application.root)
|
87
|
+
if (pid_path = Pathname(server.default_options[:pid])).exist?
|
88
|
+
if SmalrubyEditor.windows?
|
89
|
+
pid = pid_path.read.to_i
|
90
|
+
require 'csv'
|
91
|
+
s = `tasklist /FI "IMAGENAME eq ruby.exe" /FO csv`
|
92
|
+
s.force_encoding('CP932')
|
93
|
+
csv = CSV.parse(s)
|
94
|
+
csv.shift # ヘッダを除去
|
95
|
+
pids = csv.map { |row| row[1].to_i }
|
96
|
+
if pids.include?(pid)
|
97
|
+
Process.kill('KILL', pid)
|
98
|
+
end
|
99
|
+
pid_path.unlink
|
100
|
+
end
|
101
|
+
end
|
87
102
|
server.start
|
88
103
|
end
|
89
104
|
# rubocop:enable all
|
data/lib/smalruby_editor.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require 'smalruby_editor/version'
|
2
3
|
|
3
4
|
module SmalrubyEditor
|
@@ -12,6 +13,42 @@ module SmalrubyEditor
|
|
12
13
|
end
|
13
14
|
module_function :create_home_directory
|
14
15
|
|
16
|
+
# Raspberry Piかどうかを返す
|
17
|
+
def raspberrypi?
|
18
|
+
if Rails.env != 'test' &&
|
19
|
+
(ENV['SMALRUBY_EDITOR_RASPBERRYPI_MODE'] ||
|
20
|
+
File.exist?(Rails.root.join('tmp', 'raspberrypi')))
|
21
|
+
true
|
22
|
+
else
|
23
|
+
RbConfig::CONFIG['arch'] == 'armv6l-linux-eabihf'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
module_function :raspberrypi?
|
27
|
+
|
28
|
+
# Mac OS Xかどうかを返す
|
29
|
+
def osx?
|
30
|
+
if Rails.env != 'test' &&
|
31
|
+
(ENV['SMALRUBY_EDITOR_OSX_MODE'] ||
|
32
|
+
File.exist?(Rails.root.join('tmp', 'osx')))
|
33
|
+
true
|
34
|
+
else
|
35
|
+
/darwin/ =~ RbConfig::CONFIG['arch']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
module_function :osx?
|
39
|
+
|
40
|
+
# Windowsかどうかを返す
|
41
|
+
def windows?
|
42
|
+
if Rails.env != 'test' &&
|
43
|
+
(ENV['SMALRUBY_EDITOR_WINDOWS_MODE'] ||
|
44
|
+
File.exist?(Rails.root.join('tmp', 'windows')))
|
45
|
+
true
|
46
|
+
else
|
47
|
+
/windows|mingw|cygwin/i.match(RbConfig::CONFIG['arch'])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
module_function :windows?
|
51
|
+
|
15
52
|
class << self
|
16
53
|
private
|
17
54
|
|
@@ -36,10 +73,8 @@ standalone:
|
|
36
73
|
def create_database_yml(home_dir)
|
37
74
|
database_yml_path = home_dir.join('config', 'database.yml')
|
38
75
|
db_path = home_dir.join('db', 'standalone.sqlite3')
|
39
|
-
|
40
|
-
|
41
|
-
f.write(DATABASE_YML_TEMPLATE.gsub(/%db_path%/, db_path.to_s))
|
42
|
-
end
|
76
|
+
File.open(database_yml_path, 'w') do |f|
|
77
|
+
f.write(DATABASE_YML_TEMPLATE.gsub(/%db_path%/, db_path.to_s))
|
43
78
|
end
|
44
79
|
end
|
45
80
|
end
|