lignite 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.rubocop.yml +12 -0
  4. data/NEWS.md +5 -1
  5. data/README.md +2 -2
  6. data/Rakefile +1 -1
  7. data/VERSION +1 -1
  8. data/bin/ev3tool +111 -104
  9. data/examples/bobbee.rb +7 -7
  10. data/examples/hello.rb +2 -0
  11. data/examples/hello.yml +4 -0
  12. data/examples/light-sensor.rb +2 -0
  13. data/examples/light-sensor.yml +3 -0
  14. data/examples/lights.rb +7 -7
  15. data/examples/lights.yml +4 -0
  16. data/examples/sys_list_files.rb +4 -2
  17. data/examples/sys_list_files.yml +9 -0
  18. data/lib/lignite.rb +5 -1
  19. data/lib/lignite/assembler.rb +6 -6
  20. data/lib/lignite/body_compiler.rb +4 -0
  21. data/lib/lignite/connection.rb +59 -1
  22. data/lib/lignite/connection/bluetooth.rb +7 -1
  23. data/lib/lignite/connection/replay.rb +57 -0
  24. data/lib/lignite/connection/tap.rb +45 -0
  25. data/lib/lignite/connection/usb.rb +10 -7
  26. data/lib/lignite/direct_commands.rb +56 -5
  27. data/lib/lignite/message.rb +8 -5
  28. data/lib/lignite/motors.rb +5 -5
  29. data/lib/lignite/op_compiler.rb +19 -18
  30. data/lib/lignite/rbf_object.rb +1 -1
  31. data/lib/lignite/system_commands.rb +30 -2
  32. data/lib/lignite/variables.rb +2 -2
  33. data/lignite.gemspec +14 -4
  34. data/rubocop-suse.yml +74 -0
  35. data/spec/connection_usb_spec.rb +42 -0
  36. data/spec/data/ColorReadout.rb +11 -12
  37. data/spec/data/HelloWorld-subop.rb +1 -1
  38. data/spec/data/HelloWorld.rb +1 -1
  39. data/spec/data/NoDebug.rb +1 -1
  40. data/spec/data/VernierReadout.rb +4 -4
  41. data/spec/direct_commands_spec.rb +25 -0
  42. data/spec/system_commands_spec.rb +22 -0
  43. metadata +28 -3
  44. data/lib/lignite/message_sender.rb +0 -94
@@ -6,10 +6,10 @@ module Lignite
6
6
  # do the DCs spawn independent threads??
7
7
  # must run ready in the same block?
8
8
 
9
- attr :layer
10
- attr :nos
9
+ attr_reader :layer
10
+ attr_reader :nos
11
11
  # @return [Lignite::DirectCommands]
12
- attr :dc
12
+ attr_reader :dc
13
13
 
14
14
  # 0x02 | 0x04 | 0x08 -> [1, 2, 3]
15
15
  def nos_as_indices
@@ -24,7 +24,7 @@ module Lignite
24
24
  @dc = dc
25
25
  end
26
26
 
27
- # TODO filter out support: official: no
27
+ # TODO: filter out support: official: no
28
28
 
29
29
  # the type is an OUT param so the VM SETs and we GET to learn the type?
30
30
  def set_type
@@ -62,7 +62,7 @@ module Lignite
62
62
  end
63
63
 
64
64
  def start
65
- dc.output_start(layer, nos) # apparently not
65
+ dc.output_start(layer, nos) # apparently not
66
66
  end
67
67
 
68
68
  # ATTR ~polarity
@@ -119,7 +119,7 @@ module Lignite
119
119
  end
120
120
 
121
121
  enums = yml["enums"]
122
- enums.each do |ename, edata|
122
+ enums.each_value do |edata|
123
123
  edata["members"].each do |mname, mdata|
124
124
  load_const(mname, mdata["value"])
125
125
  end
@@ -177,29 +177,30 @@ module Lignite
177
177
  end
178
178
 
179
179
  def make_lc(n, bytes = nil)
180
- bytes ||= if (-31 .. 31).include? n
181
- 0
182
- elsif (-127 .. 127).include? n
183
- 1
184
- elsif (-32767 .. 32767).include? n
185
- 2
186
- else
187
- 4
188
- end
180
+ bytes ||= if (-31..31).cover? n
181
+ 0
182
+ elsif (-127..127).cover? n
183
+ 1
184
+ elsif (-32767..32767).cover? n
185
+ 2
186
+ else
187
+ 4
188
+ end
189
189
  make_lcn(n, bytes)
190
190
  end
191
191
 
192
192
  def make_v(n, local_or_global)
193
193
  vartag = PRIMPAR_VARIABEL | local_or_global
194
- if (0 .. 31).include? n
195
- return [vartag | (n & PRIMPAR_VALUE)]
196
- elsif (0 .. 255).include? n
197
- return [vartag | PRIMPAR_LONG | PRIMPAR_1_BYTE, n & 0xff]
198
- elsif (0 .. 65535).include? n
199
- return [vartag | PRIMPAR_LONG | PRIMPAR_2_BYTES, n & 0xff, (n >> 8) & 0xff]
194
+ if (0..31).cover? n
195
+ [vartag | (n & PRIMPAR_VALUE)]
196
+ elsif (0..255).cover? n
197
+ [vartag | PRIMPAR_LONG | PRIMPAR_1_BYTE, n & 0xff]
198
+ elsif (0..65535).cover? n
199
+ [vartag | PRIMPAR_LONG | PRIMPAR_2_BYTES, n & 0xff, (n >> 8) & 0xff]
200
+ else
201
+ [vartag | PRIMPAR_LONG | PRIMPAR_4_BYTES,
202
+ n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]
200
203
  end
201
- [vartag | PRIMPAR_LONG | PRIMPAR_4_BYTES,
202
- n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]
203
204
  end
204
205
 
205
206
  # Reference a variable.
@@ -18,7 +18,7 @@ module Lignite
18
18
  end
19
19
 
20
20
  # @return [ByteString] an already assembled body of the object
21
- attr :body
21
+ attr_reader :body
22
22
 
23
23
  def initialize(owner:, triggers:, local_bytes:, body:)
24
24
  @owner = owner
@@ -4,12 +4,24 @@ module Lignite
4
4
  include Logger
5
5
  extend Logger
6
6
 
7
+ def self.run(conn = Connection.create, &block)
8
+ sc = new(conn)
9
+ sc.instance_exec(&block)
10
+ sc.close
11
+ end
12
+
7
13
  # @param conn [Connection]
8
14
  def initialize(conn = Connection.create)
9
- @message_sender = MessageSender.new(conn)
15
+ @conn = conn
10
16
  load_yml
11
17
  end
12
18
 
19
+ def close
20
+ @conn.close
21
+ end
22
+
23
+ private
24
+
13
25
  def load_yml
14
26
  fname = File.expand_path("../../../data/sysops.yml", __FILE__)
15
27
  op_hash = YAML.load_file(fname)["sysops"]
@@ -38,7 +50,7 @@ module Lignite
38
50
  end.join("")
39
51
  logger.debug "sysop to execute: #{bytes.inspect}"
40
52
 
41
- reply = @message_sender.system_command_with_reply(bytes)
53
+ reply = system_command_with_reply(bytes)
42
54
 
43
55
  # TODO: parse it with return_handlers
44
56
  replies = return_handlers.map do |h|
@@ -99,5 +111,21 @@ module Lignite
99
111
  end
100
112
  end
101
113
 
114
+ def system_command_with_reply(instr_bytes)
115
+ cmd = Message.system_command_with_reply(instr_bytes)
116
+ @conn.send(cmd.bytes)
117
+
118
+ reply = Message.reply_from_bytes(@conn.receive)
119
+ assert_match(reply.msgid, cmd.msgid, "Reply id")
120
+ assert_match(reply.command, unpack_u8(instr_bytes[0]), "Command num")
121
+ raise VMError, format("Error: %u", reply.status) if reply.error?
122
+
123
+ reply.data
124
+ end
125
+
126
+ def assert_match(actual, expected, description)
127
+ return if actual == expected
128
+ raise "#{description} does not match, expected #{expected}, actual #{actual}"
129
+ end
102
130
  end
103
131
  end
@@ -14,7 +14,7 @@ module Lignite
14
14
  # declare
15
15
  def add(id, size, unpacker)
16
16
  raise "Duplicate variable #{id}" if @vars.key?(id)
17
- @vars[id] = {offset: @offset, size: size}
17
+ @vars[id] = { offset: @offset, size: size }
18
18
  @offset += size
19
19
  @unpacker += unpacker
20
20
  end
@@ -41,7 +41,7 @@ module Lignite
41
41
  end
42
42
  end
43
43
 
44
- # {#variables} are {Variables}
44
+ # `variables` are {Variables}
45
45
  module VariableDeclarer
46
46
  def data8(id)
47
47
  variables.add(id, 1, "C")
data/lignite.gemspec CHANGED
@@ -1,5 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
1
  require File.expand_path(File.dirname(__FILE__) + "/lib/lignite/version")
4
2
 
5
3
  Gem::Specification.new do |s|
@@ -20,6 +18,8 @@ TXT
20
18
  s.files = [
21
19
  ".coveralls.yml",
22
20
  ".gitignore",
21
+ ".rspec",
22
+ ".rubocop.yml",
23
23
  ".travis.yml",
24
24
  ".yardopts",
25
25
  "COPYING",
@@ -34,22 +34,27 @@ TXT
34
34
  "data/sysops.yml",
35
35
  "examples/bobbee.rb",
36
36
  "examples/hello.rb",
37
+ "examples/hello.yml",
37
38
  "examples/light-sensor.rb",
39
+ "examples/light-sensor.yml",
38
40
  "examples/lights.rb",
41
+ "examples/lights.yml",
39
42
  "examples/motors.rb",
40
43
  "examples/sound.rb",
41
44
  "examples/sys_list_files.rb",
45
+ "examples/sys_list_files.yml",
42
46
  "lib/lignite.rb",
43
47
  "lib/lignite/assembler.rb",
44
48
  "lib/lignite/body_compiler.rb",
45
49
  "lib/lignite/bytes.rb",
46
50
  "lib/lignite/connection.rb",
47
51
  "lib/lignite/connection/bluetooth.rb",
52
+ "lib/lignite/connection/replay.rb",
53
+ "lib/lignite/connection/tap.rb",
48
54
  "lib/lignite/connection/usb.rb",
49
55
  "lib/lignite/direct_commands.rb",
50
56
  "lib/lignite/logger.rb",
51
57
  "lib/lignite/message.rb",
52
- "lib/lignite/message_sender.rb",
53
58
  "lib/lignite/motors.rb",
54
59
  "lib/lignite/op_compiler.rb",
55
60
  "lib/lignite/rbf_object.rb",
@@ -57,7 +62,9 @@ TXT
57
62
  "lib/lignite/variables.rb",
58
63
  "lib/lignite/version.rb",
59
64
  "lignite.gemspec",
65
+ "rubocop-suse.yml",
60
66
  "spec/assembler_spec.rb",
67
+ "spec/connection_usb_spec.rb",
61
68
  "spec/data/ColorReadout.lms",
62
69
  "spec/data/ColorReadout.rb",
63
70
  "spec/data/ColorReadout.rbf",
@@ -72,13 +79,16 @@ TXT
72
79
  "spec/data/VernierReadout.lms",
73
80
  "spec/data/VernierReadout.rb",
74
81
  "spec/data/VernierReadout.rbf",
75
- "spec/spec_helper.rb"
82
+ "spec/direct_commands_spec.rb",
83
+ "spec/spec_helper.rb",
84
+ "spec/system_commands_spec.rb"
76
85
  ]
77
86
 
78
87
  s.executables = s.files.grep(/^bin\//) { |f| File.basename(f) }
79
88
 
80
89
  s.required_ruby_version = ">= 2.1" # mandatory keyword arguments
81
90
  s.add_dependency "libusb", "~> 0.6"
91
+ s.add_dependency "thor", "~> 0.19"
82
92
 
83
93
  s.add_development_dependency "coveralls", "~> 0"
84
94
  s.add_development_dependency "simplecov", "~> 0"
data/rubocop-suse.yml ADDED
@@ -0,0 +1,74 @@
1
+ # This is the shared Rubocop configuration for SUSE projects. It is maintained
2
+ # at https://github.com/SUSE/style-guides/blob/master/rubocop-suse.yml
3
+ #
4
+ # The configuration is tested and used with the Rubocop version used by Hound
5
+ # (https://houndci.com).
6
+ #
7
+ # We use the default Hound config as a baseline:
8
+ #
9
+ # https://raw.githubusercontent.com/thoughtbot/hound/master/config/style_guides/ruby.yml
10
+ #
11
+ # This file contains the rules with derive from this.
12
+
13
+ Lint/EndAlignment:
14
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#lintendalignment
15
+ EnforcedStyleAlignWith: variable
16
+
17
+ Metrics/AbcSize:
18
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#metricsabcsize
19
+ Max: 30
20
+
21
+ Metrics/LineLength:
22
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#metricslinelength
23
+ Max: 100
24
+ # To make it possible to copy or click on URIs in the code, we allow lines
25
+ # contaning a URI to be longer than Max.
26
+ AllowURI: true
27
+ URISchemes:
28
+ - http
29
+ - https
30
+
31
+ Style/AlignHash:
32
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylealignhash
33
+ EnforcedHashRocketStyle: table
34
+ EnforcedColonStyle: table
35
+
36
+ Style/AlignParameters:
37
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylealignparameters
38
+ Enabled: false
39
+
40
+ Style/CollectionMethods:
41
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylecollectionmethods
42
+ Enabled: false
43
+
44
+ Style/EmptyLinesAroundBlockBody:
45
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#styleemptylinesaroundblockbody
46
+ Enabled: false
47
+
48
+ Style/MultilineOperationIndentation:
49
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylemultilineoperationindentation
50
+ EnforcedStyle: indented
51
+
52
+ Style/StringLiterals:
53
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylestringliterals
54
+ EnforcedStyle: double_quotes
55
+
56
+ Style/StringLiteralsInInterpolation:
57
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylestringliteralsininterpolation
58
+ EnforcedStyle: double_quotes
59
+
60
+ Style/WordArray:
61
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#deviations-from-the-upstream-style-guide
62
+ Enabled: false
63
+
64
+ Style/RegexpLiteral:
65
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#deviations-from-the-upstream-style-guide
66
+ Enabled: false
67
+
68
+ Style/SignalException:
69
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
70
+ EnforcedStyle: only_raise
71
+
72
+ Style/NumericLiterals:
73
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylenumericliterals
74
+ Enabled: false
@@ -0,0 +1,42 @@
1
+ require_relative "spec_helper"
2
+ require "lignite"
3
+
4
+ describe Lignite::Connection::Usb do
5
+ let(:device) do
6
+ instance_double("FakeDevice", interfaces: [interface])
7
+ end
8
+ let(:interface) { double("FakeInterface", endpoints: [in_ep, out_ep]) }
9
+ let(:in_ep) { double("InEndpoint", direction: :in) }
10
+ let(:out_ep) { double("OutEndpoint", direction: :out) }
11
+ let(:dev_handle) { double("FakeDevHandle") }
12
+
13
+ before(:each) do
14
+ usb = instance_double("FakeContext", devices: [device])
15
+ allow(LIBUSB::Context).to receive(:new).and_return(usb)
16
+ allow(dev_handle).to receive(:"auto_detach_kernel_driver=")
17
+ allow(dev_handle).to receive(:claim_interface).and_yield
18
+ end
19
+
20
+ describe "#write" do
21
+ it "does not crash" do
22
+ data = "hello"
23
+ allow(device).to receive(:open).and_yield(dev_handle)
24
+ allow(dev_handle).to receive(:interrupt_transfer).and_return(data.bytesize)
25
+ expect { subject.write(data) }.to_not raise_error
26
+ end
27
+ end
28
+
29
+ describe "#read" do
30
+ it "does not crash" do
31
+ allow(device).to receive(:open).and_yield(dev_handle)
32
+ allow(dev_handle).to receive(:interrupt_transfer).and_return("hello")
33
+ expect(subject.read(1000)).to eq("hello")
34
+ end
35
+ end
36
+
37
+ describe "#write" do
38
+ it "does not crash" do
39
+ expect { subject.close }.to_not raise_error
40
+ end
41
+ end
42
+ end
@@ -15,38 +15,37 @@ vmthread :MAIN do
15
15
  data8 :Mode
16
16
  data8 :State
17
17
 
18
-
19
18
  move8_8(3, :Mode)
20
19
 
21
- self.loop do
20
+ loop do
22
21
  ui_draw(FILLWINDOW, 0x00, 0, 0)
23
22
  ui_draw(SELECT_FONT, SMALL_FONT)
24
- ui_draw(TEXT, FG_COLOR, 0, 10, ' Color Readout V0.00 ')
25
- ui_draw(TEXT, FG_COLOR, 0, 30, 'Mode ')
23
+ ui_draw(TEXT, FG_COLOR, 0, 10, " Color Readout V0.00 ")
24
+ ui_draw(TEXT, FG_COLOR, 0, 30, "Mode ")
26
25
 
27
- ui_draw(TEXT, FG_COLOR, 0, 50, 'Raw 1')
28
- ui_draw(TEXT, FG_COLOR, 0, 65, 'Raw 2')
29
- ui_draw(TEXT, FG_COLOR, 0, 80, 'Raw 3')
30
- ui_draw(TEXT, FG_COLOR, 0, 118, 'Left = 3 Right = 4')
26
+ ui_draw(TEXT, FG_COLOR, 0, 50, "Raw 1")
27
+ ui_draw(TEXT, FG_COLOR, 0, 65, "Raw 2")
28
+ ui_draw(TEXT, FG_COLOR, 0, 80, "Raw 3")
29
+ ui_draw(TEXT, FG_COLOR, 0, 118, "Left = 3 Right = 4")
31
30
  ui_draw(SELECT_FONT, NORMAL_FONT)
32
31
 
33
32
  move8_32(:Mode, :Data1)
34
33
  and32(:Data1, 0xFF, :Data1)
35
- strings(NUMBER_FORMATTED, :Data1, '%1d', 8, :String)
34
+ strings(NUMBER_FORMATTED, :Data1, "%1d", 8, :String)
36
35
  ui_draw(TEXT, FG_COLOR, 64, 30, :String)
37
36
 
38
37
  input_device(READY_RAW, 0, PORT, 0, :Mode, 3, :Data1, :Data2, :Data3)
39
38
 
40
39
  and32(:Data1, 0xFFFF, :Data1)
41
- strings(NUMBER_FORMATTED, :Data1, '%-5d', 8, :String)
40
+ strings(NUMBER_FORMATTED, :Data1, "%-5d", 8, :String)
42
41
  ui_draw(TEXT, FG_COLOR, 64, 50, :String)
43
42
 
44
43
  and32(:Data2, 0xFFFF, :Data2)
45
- strings(NUMBER_FORMATTED, :Data2, '%-5d', 8, :String)
44
+ strings(NUMBER_FORMATTED, :Data2, "%-5d", 8, :String)
46
45
  ui_draw(TEXT, FG_COLOR, 64, 65, :String)
47
46
 
48
47
  and32(:Data3, 0xFFFF, :Data3)
49
- strings(NUMBER_FORMATTED, :Data3, '%-5d', 8, :String)
48
+ strings(NUMBER_FORMATTED, :Data3, "%-5d", 8, :String)
50
49
  ui_draw(TEXT, FG_COLOR, 64, 80, :String)
51
50
 
52
51
  ui_draw(UPDATE)
@@ -1,6 +1,6 @@
1
1
  vmthread :MAIN do
2
2
  ui_draw(FILLWINDOW, 0x00, 0, 0)
3
- ui_draw(TEXT, FG_COLOR, 10, 50, 'Hello, world!')
3
+ ui_draw(TEXT, FG_COLOR, 10, 50, "Hello, world!")
4
4
  ui_draw(UPDATE)
5
5
  ui_button(WAIT_FOR_PRESS)
6
6
  end
@@ -1,6 +1,6 @@
1
1
  vmthread :MAIN do
2
2
  ui_draw_fillwindow(0x00, 0, 0)
3
- ui_draw_text(1, 10, 50, 'Hello, world!')
3
+ ui_draw_text(1, 10, 50, "Hello, world!")
4
4
  ui_draw_update
5
5
  ui_button_wait_for_press
6
6
  end
data/spec/data/NoDebug.rb CHANGED
@@ -1,4 +1,4 @@
1
- appv = 'NoDebug V1.02'
1
+ appv = "NoDebug V1.02"
2
2
 
3
3
  vmthread :MAIN do
4
4
  data8 :ShowVersion
@@ -5,18 +5,18 @@ vmthread :MAIN do
5
5
  data32 :Data1
6
6
  datas :String, 8
7
7
 
8
- self.loop do
8
+ loop do
9
9
  ui_draw(FILLWINDOW, 0x00, 0, 0)
10
10
  ui_draw(SELECT_FONT, SMALL_FONT)
11
- ui_draw(TEXT, FG_COLOR, 0, 10, 'Vernier Readout V0.00')
11
+ ui_draw(TEXT, FG_COLOR, 0, 10, "Vernier Readout V0.00")
12
12
 
13
- ui_draw(TEXT, FG_COLOR, 0, 50, 'Raw 1')
13
+ ui_draw(TEXT, FG_COLOR, 0, 50, "Raw 1")
14
14
  ui_draw(SELECT_FONT, NORMAL_FONT)
15
15
 
16
16
  input_device(READY_RAW, 0, PORT, 1, 0, 1, :Data1)
17
17
 
18
18
  and32(:Data1, 0xFFFF, :Data1)
19
- strings(NUMBER_FORMATTED, :Data1, '%-5d', 8, :String)
19
+ strings(NUMBER_FORMATTED, :Data1, "%-5d", 8, :String)
20
20
  ui_draw(TEXT, FG_COLOR, 64, 50, :String)
21
21
 
22
22
  ui_draw(UPDATE)