circuits 0.4.3 → 0.5.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTFhZjhiMjI3ODFkN2IzMmUyOGUwMGFkYjBiZTJhZmQ3YjVmMDhkOA==
4
+ YzIxYzBlMDM5ZmJjYjliOWZkODEwM2QxNGUwYmE5ZGIxMWZlYzFkZg==
5
5
  data.tar.gz: !binary |-
6
- M2RkOGE5YjkwOWNhNjA5NzcxOWM0ZTc4OTNiYTAxZDk2YTcxZmFmYg==
6
+ Y2E3NDYzMjVmMWY3OWI4MjliZmE5NTRlMTIyMDAwZTRmMGM5ZjNhZg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NWExY2I5NGI4NDEyZGM4ZDFhZmY0NjdmYzM5OWIxYWY0Y2IwYWNlMTg5NjRj
10
- YjJlYzFiMDYxZmFlZjdmMzIwY2I1ZWQ0MmJmZGJkMDZlYTFkNTZmMjk2YjVk
11
- NmRmNGNhZDU2Y2YzYTE0Y2JhNGE2MTgxNjIwODgzY2Q3ZTIxYzk=
9
+ MTJhMDdmNzE2ZDYyMjAzYjkyMGJlMmRkNmNhYjc4NTZhMzliYmM1MzZiNjdh
10
+ OGUwMzY2ZWM0OThjYTQyNDIwYTZmOWMxYTdlOTA3ODAwZDhiZjI2NmE0NjEy
11
+ ZTA1MDg2MTE4NmMyMWI2YTgzYzhjMzRiNmQzOTY4MGZhNTM5YjM=
12
12
  data.tar.gz: !binary |-
13
- N2E3YjI0MjkyYjBjN2I0YjA0NTZjYjVkMmM3ZGRhMWNlODNkOTIwNzJlMTdm
14
- OTgwMGJjNDBjYWMyZjhhOTIxZDcwNDNjNDM1YzkyY2U5NmJhNTJiNTI4ZmEw
15
- YzExMTc5MTM5MWRmNDQzYzhkMTA3NTA4YTk2OTcwZTc5YjE4NGI=
13
+ MjM5YzM1OTE2MTZlZDc4ZjdlNDI1ODgzNTkxNmUxZWVjYjgyNGFkNDU4Yjlh
14
+ MTZiNjY0MDM5OGJlMzRiNjc0ZjU3YjM5MzU3NzM5ZWQyNDVmZTE2ZjRlYTdl
15
+ MDVhZjViYjc2MTlhNTc5ZWU1NGYzM2E5YzYzMGIxMDI5MmYyZDM=
@@ -1,22 +1,19 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # Logical AND Operator
6
- class And
7
- include Component
6
+ class And < Base
7
+ def initialize(opts = {})
8
+ @input_count = 2
9
+ @output_count = 1
10
+ super opts
11
+ end
8
12
 
9
13
  # Sets the output to be the result of a logical AND of the inputs
10
14
  def tick
11
15
  outputs[0].set(inputs.map(&:get).inject(:&))
12
16
  end
13
-
14
- private
15
-
16
- def set_defaults
17
- @input_count = 2
18
- @output_count = 1
19
- end
20
17
  end
21
18
  end
22
19
  end
@@ -0,0 +1,114 @@
1
+ require 'circuits/terminal/input'
2
+ require 'circuits/terminal/output'
3
+
4
+ module Circuits
5
+ # A component has a set of inputs an outputs. Every `tick` a componnent
6
+ # computes its outputs, but the componnent will wait for the `tock` before the
7
+ # componnent updates its own outputs
8
+ module Component
9
+ # Base class to extend
10
+ class Base
11
+ # Creates the Component with inputs and outputs
12
+ # @param opts [Hash] options to create the Component with
13
+ # @option opts [Array<Input>, FixNum] :inputs The array of inputs to use,
14
+ # or the number of inputs to create
15
+ def initialize(opts = {})
16
+ create_inputs opts
17
+ create_outputs opts
18
+ end
19
+
20
+ # Does the internal computation and sets the outputs
21
+ def tick
22
+ fail NotImplementedError
23
+ end
24
+
25
+ # Sets all the outputs expose what was set in #tick
26
+ def tock
27
+ outputs.each(&:tock)
28
+ end
29
+
30
+ # Gets the teminal assigned to the port
31
+ # @param port [Symbol] The symbol that represents the terminal
32
+ # @return [Input, Output] The terminal
33
+ def [](port)
34
+ p = port_mappings[port]
35
+ case p[:type]
36
+ when :input
37
+ inputs[p[:number]]
38
+ when :output
39
+ outputs[p[:number]]
40
+ end
41
+ end
42
+
43
+ # Assigns to an input or output
44
+ # @param port [Symbol] The symbol that represents the terminal
45
+ # @param terminal [Input, Output] The terminal to assign
46
+ # @return [Input, Output] The terminal that was passed in
47
+ def []=(port, terminal)
48
+ p = port_mappings[port]
49
+ case p[:type]
50
+ when :input
51
+ inputs[p[:number]] = terminal
52
+ when :output
53
+ outputs[p[:number]] = terminal
54
+ end
55
+ end
56
+
57
+ # the inputs of this component
58
+ attr_reader :inputs
59
+
60
+ # the outputs of this component
61
+ attr_reader :outputs
62
+
63
+ private
64
+
65
+ def create_inputs(opts)
66
+ if opts[:inputs].class == Array
67
+ @inputs = opts[:inputs]
68
+ @input_count = @inputs.length
69
+ elsif opts[:inputs].class == Fixnum
70
+ @input_count = opts[:inputs]
71
+ end
72
+ @inputs ||= @input_count.times.collect { Circuits::Terminal::Input.new }
73
+ end
74
+
75
+ def create_outputs(opts)
76
+ if opts[:outputs].class == Array
77
+ @outputs = opts[:outputs]
78
+ @output_count = @outputs.length
79
+ elsif opts[:outputs].class == Fixnum
80
+ @output_count = opts[:outputs]
81
+ end
82
+ @outputs ||= @output_count.times.collect do
83
+ Circuits::Terminal::Output.new
84
+ end
85
+ end
86
+
87
+ def port_mappings
88
+ return @port_mappings unless @port_mappings.nil?
89
+ @port_mappings = {}
90
+ input_mappings.each { |x| @port_mappings.merge!(x) }
91
+ output_mappings.each { |x| @port_mappings.merge!(x) }
92
+ @port_mappings
93
+ end
94
+
95
+ def input_mappings
96
+ return [{ in: { type: :input, number: 0 } }] if @input_count == 1
97
+ @input_count.times.collect do |i|
98
+ { num_to_port(i) => { type: :input, number: i } }
99
+ end
100
+ end
101
+
102
+ def output_mappings
103
+ return[{ out: { type: :output, number: 0 } }] if @output_count == 1
104
+ @output_count.times.collect do |i|
105
+ { num_to_port(i + @input_count) => { type: :output, number: i } }
106
+ end
107
+ end
108
+
109
+ def num_to_port(i)
110
+ (i + 'a'.ord).chr.to_sym
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,22 +1,19 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # Logical NAND Operator
6
- class Nand
7
- include Component
6
+ class Nand < Base
7
+ def initialize(opts = {})
8
+ @input_count = 2
9
+ @output_count = 1
10
+ super opts
11
+ end
8
12
 
9
13
  # Sets the output to be the result of a logical NAND of the inputs
10
14
  def tick
11
15
  outputs[0].set(!inputs.map(&:get).inject(:&))
12
16
  end
13
-
14
- private
15
-
16
- def set_defaults
17
- @input_count = 2
18
- @output_count = 1
19
- end
20
17
  end
21
18
  end
22
19
  end
@@ -1,22 +1,19 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # Logical NOR Operator
6
- class Nor
7
- include Component
6
+ class Nor < Base
7
+ def initialize(opts = {})
8
+ @input_count = 2
9
+ @output_count = 1
10
+ super opts
11
+ end
8
12
 
9
13
  # Sets the output to be the result of a logical OR of the inputs
10
14
  def tick
11
15
  outputs[0].set(!inputs.map(&:get).inject(:|))
12
16
  end
13
-
14
- private
15
-
16
- def set_defaults
17
- @input_count = 2
18
- @output_count = 1
19
- end
20
17
  end
21
18
  end
22
19
  end
@@ -1,22 +1,19 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # Logical NOT Operator
6
- class Not
7
- include Component
6
+ class Not < Base
7
+ def initialize(opts = {})
8
+ @input_count = 1
9
+ @output_count = 1
10
+ super opts
11
+ end
8
12
 
9
13
  # Sets the output to be the result of a logical NOT of the inputs
10
14
  def tick
11
15
  outputs[0].set(!inputs[0].get)
12
16
  end
13
-
14
- private
15
-
16
- def set_defaults
17
- @input_count = 1
18
- @output_count = 1
19
- end
20
17
  end
21
18
  end
22
19
  end
@@ -1,22 +1,19 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # Logical OR Operator
6
- class Or
7
- include Component
6
+ class Or < Base
7
+ def initialize(opts = {})
8
+ @input_count = 2
9
+ @output_count = 1
10
+ super opts
11
+ end
8
12
 
9
13
  # Sets the output to be the result of a logical OR of the inputs
10
14
  def tick
11
15
  outputs[0].set(inputs.map(&:get).inject(:|))
12
16
  end
13
-
14
- private
15
-
16
- def set_defaults
17
- @input_count = 2
18
- @output_count = 1
19
- end
20
17
  end
21
18
  end
22
19
  end
@@ -1,14 +1,19 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # SR NAND Latch
6
- class SrNand
7
- include Component
6
+ class SrNand < Base
7
+ def initialize(opts = {})
8
+ set_defaults
9
+ super opts
10
+ create_sub_components
11
+ link_sub_components
12
+ end
8
13
 
9
14
  # Computes the outputs based on the inputs and previous state
10
15
  def tick
11
- update_internal_components
16
+ update_sub_components
12
17
  self[:q].set nand_1[:out].get
13
18
  self[:not_q].set nand_2[:out].get
14
19
  end
@@ -17,13 +22,13 @@ module Circuits
17
22
 
18
23
  attr_reader :nand_1, :nand_2, :sub_components
19
24
 
20
- def create_internal_components
25
+ def create_sub_components
21
26
  @nand_1 = Nand.new
22
27
  @nand_2 = Nand.new
23
28
  @sub_components = [@nand_1, @nand_2]
24
29
  end
25
30
 
26
- def link_internal_components
31
+ def link_sub_components
27
32
  nand_1[:a] = self[:not_s]
28
33
  nand_2[:a] = self[:not_r]
29
34
  nand_1[:b] = nand_2[:out]
@@ -41,12 +46,7 @@ module Circuits
41
46
  }
42
47
  end
43
48
 
44
- def setup
45
- create_internal_components
46
- link_internal_components
47
- end
48
-
49
- def update_internal_components
49
+ def update_sub_components
50
50
  2.times.each do
51
51
  sub_components.each(&:tick)
52
52
  sub_components.each(&:tock)
@@ -1,10 +1,15 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # SR NOR Latch
6
- class SrNor
7
- include Component
6
+ class SrNor < Base
7
+ def initialize(opts = {})
8
+ set_defaults
9
+ super opts
10
+ create_internal_components
11
+ link_internal_components
12
+ end
8
13
 
9
14
  # Computes the outputs based on the inputs and previous state
10
15
  def tick
@@ -41,11 +46,6 @@ module Circuits
41
46
  }
42
47
  end
43
48
 
44
- def setup
45
- create_internal_components
46
- link_internal_components
47
- end
48
-
49
49
  def update_internal_components
50
50
  2.times.each do
51
51
  sub_components.each(&:tick)
@@ -1,22 +1,19 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # Logical XNOR Operator
6
- class Xnor
7
- include Component
6
+ class Xnor < Base
7
+ def initialize(opts = {})
8
+ @input_count = 2
9
+ @output_count = 1
10
+ super opts
11
+ end
8
12
 
9
13
  # Sets the output to be the result of a logical XNOR of the inputs
10
14
  def tick
11
15
  outputs[0].set(!inputs.map(&:get).inject(:^))
12
16
  end
13
-
14
- private
15
-
16
- def set_defaults
17
- @input_count = 2
18
- @output_count = 1
19
- end
20
17
  end
21
18
  end
22
19
  end
@@ -1,22 +1,19 @@
1
- require 'circuits/component'
1
+ require 'circuits/component/base'
2
2
 
3
3
  module Circuits
4
4
  module Component
5
5
  # Logical XOR Operator
6
- class Xor
7
- include Component
6
+ class Xor < Base
7
+ def initialize(opts = {})
8
+ @input_count = 2
9
+ @output_count = 1
10
+ super opts
11
+ end
8
12
 
9
13
  # Sets the output to be the result of a logical XOR of the inputs
10
14
  def tick
11
15
  outputs[0].set(inputs.map(&:get).inject(:^))
12
16
  end
13
-
14
- private
15
-
16
- def set_defaults
17
- @input_count = 2
18
- @output_count = 1
19
- end
20
17
  end
21
18
  end
22
19
  end
@@ -1,5 +1,5 @@
1
1
  # Circuits allows you to express logical circuits in code
2
2
  module Circuits
3
3
  # The version of the Circuits gem
4
- VERSION = '0.4.3'
4
+ VERSION = '0.5.0'
5
5
  end
@@ -1,114 +1,102 @@
1
- require 'spec_helper'
2
- require 'circuits/component'
3
-
4
- # Mock component to include Circuits::Component for function accessability
5
- class MockComponent1
6
- include Circuits::Component
7
-
8
- def set_defaults
9
- @input_count = 1
10
- @output_count = 1
11
- end
12
- end
13
-
14
- # Mock component to include Circuits::Component for function accessability
15
- class MockComponent2
16
- include Circuits::Component
17
- end
18
-
19
- describe Circuits::Component do
20
- context 'when using defaults' do
21
- subject { MockComponent1.new }
22
-
23
- it 'has one input' do
24
- expect(subject.inputs.count).to eq(1)
25
- end
26
-
27
- it 'has one output' do
28
- expect(subject.outputs.count).to eq(1)
29
- end
30
-
31
- describe '#[]=' do
32
- let(:new_input) { double('new_input') }
33
- let(:new_output) { double('new_output') }
34
-
35
- before do
36
- subject[:in] = new_input
37
- subject[:out] = new_output
38
- end
39
-
40
- it 'has the new input available as :in' do
41
- expect(subject[:in]).to eq(new_input)
42
- end
43
-
44
- it 'has the new output available as :out' do
45
- expect(subject[:out]).to eq(new_output)
46
- end
47
- end
48
- end
49
-
50
- context 'when specifying input and output count' do
51
- subject { MockComponent1.new(inputs: 2, outputs: 2) }
52
-
53
- it 'has one input' do
54
- expect(subject.inputs.count).to eq(2)
55
- end
56
-
57
- it 'has one output' do
58
- expect(subject.outputs.count).to eq(2)
59
- end
60
- end
61
-
62
- context 'when supplying inputs and outputs' do
63
- let(:inputs) { [double('input')] }
64
- let(:outputs) { [double('output')] }
65
-
66
- subject { MockComponent1.new(inputs: inputs, outputs: outputs) }
67
-
68
- describe '#tick' do
69
- it 'raises NotImplementedError' do
70
- expect { subject.tick }.to raise_error(NotImplementedError)
71
- end
72
- end
73
-
74
- describe '#tock' do
75
- it 'tocks the outputs' do
76
- expect(outputs[0]).to receive(:tock)
77
- subject.tock
78
- end
79
- end
80
-
81
- describe '#[]' do
82
- context 'one input and one output' do
83
- it 'has the input available as :in' do
84
- expect(subject[:in]).to eq(inputs[0])
85
- end
86
-
87
- it 'has the output available as :out' do
88
- expect(subject[:out]).to eq(outputs[0])
89
- end
90
- end
91
-
92
- context 'two inputs and two outputs' do
93
- let(:inputs) { [double('input_1'), double('input_2')] }
94
- let(:outputs) { [double('output_1'), double('output_2')] }
95
-
96
- it 'has the inputs available as :a and :b' do
97
- expect(subject[:a]).to eq(inputs[0])
98
- expect(subject[:b]).to eq(inputs[1])
99
- end
100
-
101
- it 'has the outputs available as :c and :d' do
102
- expect(subject[:c]).to eq(outputs[0])
103
- expect(subject[:d]).to eq(outputs[1])
104
- end
105
- end
106
- end
107
- end
108
-
109
- context 'when you do not override #set_defaults' do
110
- it 'raises NotImplementedError' do
111
- expect { MockComponent2.new }.to raise_error(NotImplementedError)
112
- end
113
- end
114
- end
1
+ require 'spec_helper'
2
+ require 'circuits/component/base'
3
+
4
+ # Mock component to include Circuits::Component::Base
5
+ class MockComponent < Circuits::Component::Base
6
+ def initialize(opts = {})
7
+ @input_count = 1
8
+ @output_count = 1
9
+ super opts
10
+ end
11
+ end
12
+
13
+ describe Circuits::Component::Base do
14
+ context 'when using defaults' do
15
+ subject { MockComponent.new }
16
+
17
+ it 'has one input' do
18
+ expect(subject.inputs.count).to eq(1)
19
+ end
20
+
21
+ it 'has one output' do
22
+ expect(subject.outputs.count).to eq(1)
23
+ end
24
+
25
+ describe '#[]=' do
26
+ let(:new_input) { double('new_input') }
27
+ let(:new_output) { double('new_output') }
28
+
29
+ before do
30
+ subject[:in] = new_input
31
+ subject[:out] = new_output
32
+ end
33
+
34
+ it 'has the new input available as :in' do
35
+ expect(subject[:in]).to eq(new_input)
36
+ end
37
+
38
+ it 'has the new output available as :out' do
39
+ expect(subject[:out]).to eq(new_output)
40
+ end
41
+ end
42
+ end
43
+
44
+ context 'when specifying input and output count' do
45
+ subject { MockComponent.new(inputs: 2, outputs: 2) }
46
+
47
+ it 'has one input' do
48
+ expect(subject.inputs.count).to eq(2)
49
+ end
50
+
51
+ it 'has one output' do
52
+ expect(subject.outputs.count).to eq(2)
53
+ end
54
+ end
55
+
56
+ context 'when supplying inputs and outputs' do
57
+ let(:inputs) { [double('input')] }
58
+ let(:outputs) { [double('output')] }
59
+
60
+ subject { MockComponent.new(inputs: inputs, outputs: outputs) }
61
+
62
+ describe '#tick' do
63
+ it 'raises NotImplementedError' do
64
+ expect { subject.tick }.to raise_error(NotImplementedError)
65
+ end
66
+ end
67
+
68
+ describe '#tock' do
69
+ it 'tocks the outputs' do
70
+ expect(outputs[0]).to receive(:tock)
71
+ subject.tock
72
+ end
73
+ end
74
+
75
+ describe '#[]' do
76
+ context 'one input and one output' do
77
+ it 'has the input available as :in' do
78
+ expect(subject[:in]).to eq(inputs[0])
79
+ end
80
+
81
+ it 'has the output available as :out' do
82
+ expect(subject[:out]).to eq(outputs[0])
83
+ end
84
+ end
85
+
86
+ context 'two inputs and two outputs' do
87
+ let(:inputs) { [double('input_1'), double('input_2')] }
88
+ let(:outputs) { [double('output_1'), double('output_2')] }
89
+
90
+ it 'has the inputs available as :a and :b' do
91
+ expect(subject[:a]).to eq(inputs[0])
92
+ expect(subject[:b]).to eq(inputs[1])
93
+ end
94
+
95
+ it 'has the outputs available as :c and :d' do
96
+ expect(subject[:c]).to eq(outputs[0])
97
+ expect(subject[:d]).to eq(outputs[1])
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: circuits
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henry Muru Paenga
@@ -124,8 +124,8 @@ files:
124
124
  - Rakefile
125
125
  - circuits.gemspec
126
126
  - lib/circuits.rb
127
- - lib/circuits/component.rb
128
127
  - lib/circuits/component/and.rb
128
+ - lib/circuits/component/base.rb
129
129
  - lib/circuits/component/nand.rb
130
130
  - lib/circuits/component/nor.rb
131
131
  - lib/circuits/component/not.rb
@@ -140,6 +140,7 @@ files:
140
140
  - lib/circuits/version.rb
141
141
  - spec/spec_helper.rb
142
142
  - spec/unit/circuits/component/and_spec.rb
143
+ - spec/unit/circuits/component/base_spec.rb
143
144
  - spec/unit/circuits/component/nand_spec.rb
144
145
  - spec/unit/circuits/component/nor_spec.rb
145
146
  - spec/unit/circuits/component/not_spec.rb
@@ -148,7 +149,6 @@ files:
148
149
  - spec/unit/circuits/component/sr_nor_spec.rb
149
150
  - spec/unit/circuits/component/xnor_spec.rb
150
151
  - spec/unit/circuits/component/xor_spec.rb
151
- - spec/unit/circuits/component_spec.rb
152
152
  - spec/unit/circuits/terminal/input_spec.rb
153
153
  - spec/unit/circuits/terminal/output_spec.rb
154
154
  homepage: https://github.com/meringu/circuits
@@ -178,6 +178,7 @@ summary: Express logical circuits in code
178
178
  test_files:
179
179
  - spec/spec_helper.rb
180
180
  - spec/unit/circuits/component/and_spec.rb
181
+ - spec/unit/circuits/component/base_spec.rb
181
182
  - spec/unit/circuits/component/nand_spec.rb
182
183
  - spec/unit/circuits/component/nor_spec.rb
183
184
  - spec/unit/circuits/component/not_spec.rb
@@ -186,6 +187,5 @@ test_files:
186
187
  - spec/unit/circuits/component/sr_nor_spec.rb
187
188
  - spec/unit/circuits/component/xnor_spec.rb
188
189
  - spec/unit/circuits/component/xor_spec.rb
189
- - spec/unit/circuits/component_spec.rb
190
190
  - spec/unit/circuits/terminal/input_spec.rb
191
191
  - spec/unit/circuits/terminal/output_spec.rb
@@ -1,121 +0,0 @@
1
- require 'circuits/terminal/input'
2
- require 'circuits/terminal/output'
3
-
4
- module Circuits
5
- # A component has a set of inputs an outputs. Every `tick` a componnent
6
- # computes its outputs, but the componnent will wait for the `tock` before the
7
- # componnent updates its own outputs
8
- module Component
9
- # Creates the Component with inputs and outputs
10
- # @param opts [Hash] options to create the Component with
11
- # @option opts [Array<Input>, FixNum] :inputs The array of inputs to use, or
12
- # the number of inputs to create
13
- def initialize(opts = {})
14
- set_defaults
15
- create_inputs opts
16
- create_outputs opts
17
- create_port_mappings
18
- setup
19
- end
20
-
21
- # Does the internal computation and sets the outputs
22
- def tick
23
- fail NotImplementedError
24
- end
25
-
26
- # Sets all the outputs expose what was set in #tick
27
- def tock
28
- outputs.each(&:tock)
29
- end
30
-
31
- # Gets the teminal assigned to the port
32
- # @param port [Symbol] The symbol that represents the terminal
33
- # @return [Input, Output] The terminal
34
- def [](port)
35
- p = @port_mappings[port]
36
- case p[:type]
37
- when :input
38
- @inputs[p[:number]]
39
- when :output
40
- @outputs[p[:number]]
41
- end
42
- end
43
-
44
- # Assigns to an input or output
45
- # @param port [Symbol] The symbol that represents the terminal
46
- # @param terminal [Input, Output] The terminal to assign
47
- # @return [Input, Output] The terminal that was passed in
48
- def []=(port, terminal)
49
- p = @port_mappings[port]
50
- case p[:type]
51
- when :input
52
- @inputs[p[:number]] = terminal
53
- when :output
54
- @outputs[p[:number]] = terminal
55
- end
56
- end
57
-
58
- # the inputs of this component
59
- attr_reader :inputs
60
-
61
- # the outputs of this component
62
- attr_reader :outputs
63
-
64
- private
65
-
66
- def create_inputs(opts)
67
- if opts[:inputs].class == Array
68
- @inputs = opts[:inputs]
69
- @input_count = @inputs.length
70
- elsif opts[:inputs].class == Fixnum
71
- @input_count = opts[:inputs]
72
- end
73
- @inputs ||= @input_count.times.collect { Circuits::Terminal::Input.new }
74
- end
75
-
76
- def create_outputs(opts)
77
- if opts[:outputs].class == Array
78
- @outputs = opts[:outputs]
79
- @output_count = @outputs.length
80
- elsif opts[:outputs].class == Fixnum
81
- @output_count = opts[:outputs]
82
- end
83
- @outputs ||= @output_count.times.collect do
84
- Circuits::Terminal::Output.new
85
- end
86
- end
87
-
88
- def create_port_mappings
89
- return @port_mappings unless @port_mappings.nil?
90
- @port_mappings = {}
91
- input_mappings.each { |x| @port_mappings.merge!(x) }
92
- output_mappings.each { |x| @port_mappings.merge!(x) }
93
- @port_mappings
94
- end
95
-
96
- def input_mappings
97
- return [{ in: { type: :input, number: 0 } }] if @input_count == 1
98
- @input_count.times.collect do |i|
99
- { num_to_port(i) => { type: :input, number: i } }
100
- end
101
- end
102
-
103
- def output_mappings
104
- return[{ out: { type: :output, number: 0 } }] if @output_count == 1
105
- @output_count.times.collect do |i|
106
- { num_to_port(i + @input_count) => { type: :output, number: i } }
107
- end
108
- end
109
-
110
- def num_to_port(i)
111
- (i + 'a'.ord).chr.to_sym
112
- end
113
-
114
- def set_defaults
115
- fail NotImplementedError
116
- end
117
-
118
- def setup
119
- end
120
- end
121
- end