spnet 0.1.2 → 0.1.3
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.
- data/ChangeLog.rdoc +8 -1
- data/README.rdoc +7 -1
- data/lib/spnet/block.rb +4 -6
- data/lib/spnet/in_port.rb +29 -0
- data/lib/spnet/out_port.rb +64 -0
- data/lib/spnet/ports/command_in_port.rb +27 -0
- data/lib/spnet/ports/command_out_port.rb +26 -0
- data/lib/spnet/ports/signal_in_port.rb +43 -0
- data/lib/spnet/ports/signal_out_port.rb +18 -0
- data/lib/spnet/ports/value_in_port.rb +27 -0
- data/lib/spnet/ports/value_out_port.rb +28 -0
- data/lib/spnet/version.rb +1 -1
- data/lib/spnet.rb +9 -7
- data/spec/block_spec.rb +11 -11
- data/spec/in_port_spec.rb +29 -0
- data/spec/{message_out_port_spec.rb → out_port_spec.rb} +13 -24
- data/spec/ports/command_in_port_spec.rb +42 -0
- data/spec/ports/command_out_port_spec.rb +53 -0
- data/spec/{signal_in_port_spec.rb → ports/signal_in_port_spec.rb} +1 -1
- data/spec/{signal_out_port_spec.rb → ports/signal_out_port_spec.rb} +2 -33
- data/spec/ports/value_in_port_spec.rb +31 -0
- data/spec/ports/value_out_port_spec.rb +41 -0
- data/spec/{spnetwork_spec.rb → spnet_spec.rb} +0 -0
- data/spnet.gemspec +1 -0
- metadata +46 -24
- data/lib/spnet/control_message.rb +0 -52
- data/lib/spnet/message.rb +0 -25
- data/lib/spnet/message_in_port.rb +0 -43
- data/lib/spnet/message_out_port.rb +0 -56
- data/lib/spnet/signal_in_port.rb +0 -60
- data/lib/spnet/signal_out_port.rb +0 -54
- data/spec/control_message_spec.rb +0 -40
- data/spec/message_in_port_spec.rb +0 -17
- data/spec/message_spec.rb +0 -11
data/ChangeLog.rdoc
CHANGED
@@ -11,4 +11,11 @@ Updated to use hashmake 0.1.1 gem.
|
|
11
11
|
* Update project files, including:
|
12
12
|
** Removing README.md so that YARD can run without needing the redcarpet gem.
|
13
13
|
** Removing unnecessary lines from .gitignore
|
14
|
-
** Remove specific hashmake version in hashmake.gemspec
|
14
|
+
** Remove specific hashmake version in hashmake.gemspec
|
15
|
+
|
16
|
+
=== 0.1.3 / 2013-02-06
|
17
|
+
|
18
|
+
Replace messages and message ports with more specific ports, like value ports and command ports, and use a base InPort and OutPort to share code for linking ports.
|
19
|
+
Each kind of port can only connect to its opposite (e.g. SignaInPort to SignalOutPort).
|
20
|
+
Instead of different messages for different actions, each kind of port will just have specific methods (e.g. SignalInPort#enqueue_values or ValueInPort#set_value).
|
21
|
+
In Block, contain all InPort objects in @in_ports, and all OutPort objects in @out_ports.
|
data/README.rdoc
CHANGED
@@ -6,10 +6,16 @@
|
|
6
6
|
|
7
7
|
== Description
|
8
8
|
|
9
|
-
|
9
|
+
Provide infrastructure for forming processing networks.
|
10
10
|
|
11
11
|
== Features
|
12
12
|
|
13
|
+
Signal ports: Used to pass a stream of data through a block.
|
14
|
+
|
15
|
+
Value ports: Used to get/set a value within a block (usually to control a parameter), with optional range limiting.
|
16
|
+
|
17
|
+
Command ports: Used to trigger the execution a command within a block, with optional data as well.
|
18
|
+
|
13
19
|
== Examples
|
14
20
|
|
15
21
|
require 'spnet'
|
data/lib/spnet/block.rb
CHANGED
@@ -3,17 +3,15 @@ module SPNet
|
|
3
3
|
class Block
|
4
4
|
include Hashmake::HashMakeable
|
5
5
|
|
6
|
-
attr_reader :name, :
|
6
|
+
attr_reader :name, :in_ports, :out_ports
|
7
7
|
|
8
8
|
DO_NOTHING = ->(){}
|
9
9
|
|
10
10
|
HASHED_ARG_SPECS = [
|
11
11
|
Hashmake::ArgSpec.new(:reqd => false, :key => :name, :type => String, :default => "UNNAMED"),
|
12
12
|
Hashmake::ArgSpec.new(:reqd => false, :key => :algorithm, :type => Proc, :default => DO_NOTHING),
|
13
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :
|
14
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :
|
15
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :message_in_ports, :type => MessageInPort, :array => true, :default => ->(){ Array.new }),
|
16
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :message_out_ports, :type => MessageOutPort, :array => true, :default => ->(){ Array.new })
|
13
|
+
Hashmake::ArgSpec.new(:reqd => false, :key => :in_ports, :type => InPort, :array => true, :default => ->(){ Array.new } ),
|
14
|
+
Hashmake::ArgSpec.new(:reqd => false, :key => :out_ports, :type => OutPort, :array => true, :default => ->(){ Array.new }),
|
17
15
|
]
|
18
16
|
|
19
17
|
def initialize args = {}
|
@@ -21,7 +19,7 @@ class Block
|
|
21
19
|
end
|
22
20
|
|
23
21
|
def find_ports name, ignore_case = true
|
24
|
-
matches = (@
|
22
|
+
matches = (@in_ports + @out_ports).select do |port|
|
25
23
|
if ignore_case
|
26
24
|
port.name.casecmp(name) == 0
|
27
25
|
else
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'hashmake'
|
2
|
+
|
3
|
+
module SPNet
|
4
|
+
class InPort
|
5
|
+
|
6
|
+
include Hashmake::HashMakeable
|
7
|
+
|
8
|
+
ARG_SPECS = [
|
9
|
+
Hashmake::ArgSpec.new(:reqd => false, :key => :name, :type => String, :default => "UNNAMED"),
|
10
|
+
Hashmake::ArgSpec.new(:reqd => true, :key => :matching_port_class, :type => Class),
|
11
|
+
]
|
12
|
+
|
13
|
+
attr_reader :name, :link
|
14
|
+
|
15
|
+
def initialize args
|
16
|
+
hash_make InPort::ARG_SPECS, args
|
17
|
+
@link = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def clear_link
|
21
|
+
@link = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_link link
|
25
|
+
raise ArgumentError, "link #{link} is not a #{@matching_port_class}" unless link.is_a?(@matching_port_class)
|
26
|
+
@link = link
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'hashmake'
|
3
|
+
|
4
|
+
module SPNet
|
5
|
+
class OutPort
|
6
|
+
|
7
|
+
include Hashmake::HashMakeable
|
8
|
+
|
9
|
+
ARG_SPECS = [
|
10
|
+
Hashmake::ArgSpec.new(:reqd => false, :key => :name, :type => String, :default => "UNNAMED"),
|
11
|
+
Hashmake::ArgSpec.new(:reqd => true, :key => :matching_port_class, :type => Class),
|
12
|
+
]
|
13
|
+
|
14
|
+
attr_reader :name, :links
|
15
|
+
|
16
|
+
def initialize hashed_args = {}
|
17
|
+
hash_make OutPort::ARG_SPECS, hashed_args
|
18
|
+
@links = Set.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_link link
|
22
|
+
raise ArgumentError, "link #{link} is not a #{@matching_port_class}" unless link.is_a?(@matching_port_class)
|
23
|
+
raise ArgumentError, "link #{link} is already linked" if link.link
|
24
|
+
@links.add link
|
25
|
+
link.set_link self
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove_link link
|
29
|
+
raise ArgumentError, "@links does not include link #{link}" unless @links.include? link
|
30
|
+
@links.delete link
|
31
|
+
link.clear_link
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove_bad_links
|
35
|
+
find_bad_links_and :remove
|
36
|
+
end
|
37
|
+
|
38
|
+
def correct_bad_links
|
39
|
+
find_bad_links_and :correct
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def find_bad_links_and action
|
45
|
+
marked = []
|
46
|
+
|
47
|
+
@links.each do |link|
|
48
|
+
bad = (link.link == nil) or (link.link != self)
|
49
|
+
if bad
|
50
|
+
marked.push link
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
marked.each do |link|
|
55
|
+
if action == :remove
|
56
|
+
@links.delete link
|
57
|
+
elsif action == :correct
|
58
|
+
link.set_link self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'hashmake'
|
2
|
+
|
3
|
+
module SPNet
|
4
|
+
class CommandInPort < InPort
|
5
|
+
|
6
|
+
include Hashmake::HashMakeable
|
7
|
+
|
8
|
+
ARG_SPECS = [
|
9
|
+
Hashmake::ArgSpec.new(:key => :list_commands_handler, :reqd => true, :type => Proc),
|
10
|
+
Hashmake::ArgSpec.new(:key => :exec_command_handler, :reqd => true, :type => Proc)
|
11
|
+
]
|
12
|
+
|
13
|
+
def initialize hashed_args
|
14
|
+
hash_make(CommandInPort::ARG_SPECS, hashed_args)
|
15
|
+
hashed_args.merge!(:matching_port_class => CommandOutPort)
|
16
|
+
super(hashed_args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def list_commands
|
20
|
+
@list_commands_handler.call
|
21
|
+
end
|
22
|
+
|
23
|
+
def exec_command command, data
|
24
|
+
@exec_command_handler.call command, data
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SPNet
|
2
|
+
class CommandOutPort < OutPort
|
3
|
+
|
4
|
+
def initialize hashed_args = {}
|
5
|
+
hashed_args.merge!(:matching_port_class => CommandInPort)
|
6
|
+
super(hashed_args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def list_commands
|
10
|
+
rvs = []
|
11
|
+
@links.each do |link|
|
12
|
+
rvs.push link.list_commands
|
13
|
+
end
|
14
|
+
return rvs
|
15
|
+
end
|
16
|
+
|
17
|
+
def exec_command command, data = nil
|
18
|
+
rvs = []
|
19
|
+
@links.each do |link|
|
20
|
+
rvs.push link.exec_command(command, data)
|
21
|
+
end
|
22
|
+
return rvs
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'hashmake'
|
2
|
+
require 'spcore'
|
3
|
+
|
4
|
+
module SPNet
|
5
|
+
class SignalInPort < InPort
|
6
|
+
|
7
|
+
include Hashmake::HashMakeable
|
8
|
+
|
9
|
+
DEFAULT_LIMITS = (-Float::MAX..Float::MAX)
|
10
|
+
|
11
|
+
ARG_SPECS = [
|
12
|
+
Hashmake::ArgSpec.new(:reqd => false, :key => :limits, :type => Range, :default => DEFAULT_LIMITS)
|
13
|
+
]
|
14
|
+
|
15
|
+
attr_reader :limits, :queue
|
16
|
+
|
17
|
+
def initialize hashed_args = {}
|
18
|
+
hash_make(SignalInPort::ARG_SPECS, hashed_args)
|
19
|
+
@queue = []
|
20
|
+
@skip_limiting = (@limits == DEFAULT_LIMITS)
|
21
|
+
@limiter = SPCore::Limiters.make_range_limiter @limits
|
22
|
+
|
23
|
+
hashed_args.merge!(:matching_port_class => SignalOutPort)
|
24
|
+
super(hashed_args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def enqueue_values values
|
28
|
+
unless @skip_limiting
|
29
|
+
for i in 0...values.count
|
30
|
+
values[i] = @limiter.call(values[i])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
@queue.concat values
|
35
|
+
end
|
36
|
+
|
37
|
+
def dequeue_values count = @queue.count
|
38
|
+
raise ArgumentError, "count is greater than @queue.count" if count > @queue.count
|
39
|
+
@queue.slice!(0...count)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module SPNet
|
4
|
+
class SignalOutPort < OutPort
|
5
|
+
|
6
|
+
def initialize hashed_args = {}
|
7
|
+
hashed_args.merge!(:matching_port_class => SignalInPort)
|
8
|
+
super(hashed_args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def send_values values
|
12
|
+
@links.each do |link|
|
13
|
+
link.enqueue_values values
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'hashmake'
|
2
|
+
|
3
|
+
module SPNet
|
4
|
+
class ValueInPort < InPort
|
5
|
+
|
6
|
+
include Hashmake::HashMakeable
|
7
|
+
|
8
|
+
ARG_SPECS = [
|
9
|
+
Hashmake::ArgSpec.new(:key => :get_value_handler, :reqd => true, :type => Proc),
|
10
|
+
Hashmake::ArgSpec.new(:key => :set_value_handler, :reqd => true, :type => Proc)
|
11
|
+
]
|
12
|
+
|
13
|
+
def initialize hashed_args = {}
|
14
|
+
hash_make(ValueInPort::ARG_SPECS, hashed_args)
|
15
|
+
hashed_args.merge!(:matching_port_class => ValueOutPort)
|
16
|
+
super(hashed_args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_value value
|
20
|
+
@set_value_handler.call value
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_value
|
24
|
+
@get_value_handler.call
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module SPNet
|
4
|
+
class ValueOutPort < OutPort
|
5
|
+
|
6
|
+
def initialize hashed_args = {}
|
7
|
+
hashed_args.merge!(:matching_port_class => ValueInPort)
|
8
|
+
super(hashed_args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def set_value value
|
12
|
+
rvs = []
|
13
|
+
@links.each do |link|
|
14
|
+
rvs.push link.set_value value
|
15
|
+
end
|
16
|
+
return rvs
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_value
|
20
|
+
rvs = []
|
21
|
+
@links.each do |link|
|
22
|
+
rvs.push link.get_value
|
23
|
+
end
|
24
|
+
return rvs
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/spnet/version.rb
CHANGED
data/lib/spnet.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'spnet/version'
|
2
|
-
|
3
|
-
require 'spnet/
|
4
|
-
require 'spnet/signal_out_port'
|
5
|
-
require 'spnet/message'
|
6
|
-
require 'spnet/control_message'
|
7
|
-
require 'spnet/message_in_port'
|
8
|
-
require 'spnet/message_out_port'
|
2
|
+
require 'spnet/in_port'
|
3
|
+
require 'spnet/out_port'
|
9
4
|
require 'spnet/block'
|
5
|
+
|
6
|
+
require 'spnet/ports/signal_in_port'
|
7
|
+
require 'spnet/ports/signal_out_port'
|
8
|
+
require 'spnet/ports/value_in_port'
|
9
|
+
require 'spnet/ports/value_out_port'
|
10
|
+
require 'spnet/ports/command_in_port'
|
11
|
+
require 'spnet/ports/command_out_port'
|
data/spec/block_spec.rb
CHANGED
@@ -8,30 +8,30 @@ describe SPNet::Block do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'should have no input ports' do
|
11
|
-
@block.
|
11
|
+
@block.in_ports.should be_empty
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'should have no output ports' do
|
15
|
-
@block.
|
15
|
+
@block.out_ports.should be_empty
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
context '1
|
19
|
+
context '1 in and 1 out port given' do
|
20
20
|
before :all do
|
21
21
|
@block = SPNet::Block.new(
|
22
|
-
:
|
23
|
-
:
|
22
|
+
:in_ports => [SPNet::SignalInPort.new(:name => "IN")],
|
23
|
+
:out_ports => [SPNet::SignalOutPort.new(:name => "OUT")],
|
24
24
|
)
|
25
25
|
end
|
26
26
|
|
27
|
-
it 'should have
|
28
|
-
@block.
|
29
|
-
@block.
|
27
|
+
it 'should have 1 input port' do
|
28
|
+
@block.in_ports.count.should be 1
|
29
|
+
@block.in_ports.first.name.should eq("IN")
|
30
30
|
end
|
31
31
|
|
32
|
-
it 'should have
|
33
|
-
@block.
|
34
|
-
@block.
|
32
|
+
it 'should have 1 output port' do
|
33
|
+
@block.out_ports.count.should be 1
|
34
|
+
@block.out_ports.first.name.should eq("OUT")
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe SPNet::InPort do
|
4
|
+
describe '.new' do
|
5
|
+
it 'should not have any links' do
|
6
|
+
port = SPNet::InPort.new :matching_port_class => SPNet::OutPort
|
7
|
+
port.link.should be_nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#set_link' do
|
12
|
+
it 'should set link to given OutPort' do
|
13
|
+
in_port = SPNet::InPort.new :matching_port_class => SPNet::OutPort
|
14
|
+
out_port = SPNet::OutPort.new :matching_port_class => SPNet::InPort
|
15
|
+
in_port.set_link out_port
|
16
|
+
in_port.link.should eq(out_port)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#clear_link' do
|
21
|
+
it 'should set link to given OutPort' do
|
22
|
+
in_port = SPNet::InPort.new :matching_port_class => SPNet::OutPort
|
23
|
+
out_port = SPNet::OutPort.new :matching_port_class => SPNet::InPort
|
24
|
+
in_port.set_link out_port
|
25
|
+
in_port.clear_link
|
26
|
+
in_port.link.should be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,21 +1,17 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
describe SPNet::
|
4
|
-
before :all do
|
5
|
-
processor = lambda do |message|
|
6
|
-
return message
|
7
|
-
end
|
8
|
-
@in_port = SPNet::MessageInPort.new :processor => processor, :message_type => SPNet::Message::CONTROL
|
9
|
-
end
|
10
|
-
|
3
|
+
describe SPNet::OutPort do
|
11
4
|
before :each do
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
@in_port = SPNet::MessageInPort.new :processor => processor, :message_type => SPNet::Message::CONTROL
|
16
|
-
@out_port = SPNet::MessageOutPort.new
|
5
|
+
@in_port = SPNet::InPort.new :matching_port_class => SPNet::OutPort
|
6
|
+
@out_port = SPNet::OutPort.new :matching_port_class => SPNet::InPort
|
17
7
|
end
|
18
|
-
|
8
|
+
|
9
|
+
describe '.new' do
|
10
|
+
it 'should have no links' do
|
11
|
+
@out_port.links.should be_empty
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
19
15
|
describe '#add_link' do
|
20
16
|
it 'should add the given input port to links' do
|
21
17
|
@out_port.add_link @in_port
|
@@ -34,8 +30,8 @@ describe SPNet::MessageOutPort do
|
|
34
30
|
end
|
35
31
|
|
36
32
|
it 'should raise ArgumentError if port is not input port' do
|
37
|
-
|
38
|
-
lambda { @out_port.add_link(
|
33
|
+
out_port2 = SPNet::OutPort.new :matching_port_class => SPNet::InPort
|
34
|
+
lambda { @out_port.add_link(out_port2) }.should raise_error(ArgumentError)
|
39
35
|
end
|
40
36
|
end
|
41
37
|
|
@@ -46,12 +42,5 @@ describe SPNet::MessageOutPort do
|
|
46
42
|
@out_port.links.should be_empty
|
47
43
|
end
|
48
44
|
end
|
49
|
-
|
50
|
-
describe '#send_message' do
|
51
|
-
it 'should pass the given message via recv_message to the processing callback' do
|
52
|
-
@out_port.add_link @in_port
|
53
|
-
rv = @out_port.send_message SPNet::ControlMessage.make_set_message(5)
|
54
|
-
rv.first.data.should eq(5)
|
55
|
-
end
|
56
|
-
end
|
45
|
+
|
57
46
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe SPNet::CommandInPort do
|
4
|
+
before :each do
|
5
|
+
@commands = ["add", "sub", "mul", "div"]
|
6
|
+
|
7
|
+
list_commands_handler = lambda { return @commands }
|
8
|
+
|
9
|
+
exec_command_handler = lambda do |command, data|
|
10
|
+
x = data[0]
|
11
|
+
y = data[1]
|
12
|
+
|
13
|
+
case command
|
14
|
+
when "add"
|
15
|
+
return x + y
|
16
|
+
when "sub"
|
17
|
+
return x - y
|
18
|
+
when "mul"
|
19
|
+
return x * y
|
20
|
+
when "div"
|
21
|
+
return x / y
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@port = SPNet::CommandInPort.new :list_commands_handler => list_commands_handler, :exec_command_handler => exec_command_handler
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#list_commands' do
|
29
|
+
it 'should pass back the return value from the list_commands handler' do
|
30
|
+
@port.list_commands.should eq(@commands)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#exec_command' do
|
35
|
+
it 'should pass the command and data to the exec_command handler, and pass back the return value' do
|
36
|
+
@port.exec_command("add", [1,2]).should eq(3)
|
37
|
+
@port.exec_command("sub", [5,4]).should eq(1)
|
38
|
+
@port.exec_command("mul", [3,2]).should eq(6)
|
39
|
+
@port.exec_command("div", [9,3]).should eq(3)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe SPNet::ValueOutPort do
|
4
|
+
before :each do
|
5
|
+
@commands = ["add", "sub", "mul", "div"]
|
6
|
+
|
7
|
+
list_commands_handler = lambda { return @commands }
|
8
|
+
|
9
|
+
exec_command_handler = lambda do |command, data|
|
10
|
+
x = data[0]
|
11
|
+
y = data[1]
|
12
|
+
|
13
|
+
case command
|
14
|
+
when "add"
|
15
|
+
return x + y
|
16
|
+
when "sub"
|
17
|
+
return x - y
|
18
|
+
when "mul"
|
19
|
+
return x * y
|
20
|
+
when "div"
|
21
|
+
return x / y
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@in_port = SPNet::CommandInPort.new :list_commands_handler => list_commands_handler, :exec_command_handler => exec_command_handler
|
26
|
+
@out_port = SPNet::CommandOutPort.new
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#add_link' do
|
30
|
+
it 'should raise ArgumentError if port is not ValueInPort' do
|
31
|
+
@in_port2 = SPNet::SignalInPort.new
|
32
|
+
lambda { @out_port.add_link(@in_port2) }.should raise_error(ArgumentError)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#list_commands' do
|
37
|
+
it 'should pass back the return value from the list_commands handler' do
|
38
|
+
@out_port.add_link @in_port
|
39
|
+
@out_port.list_commands.should eq([@commands])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#exec_command' do
|
44
|
+
it 'should pass the command and data to the exec_command handler, and pass back the return value' do
|
45
|
+
@out_port.add_link @in_port
|
46
|
+
@out_port.exec_command("add", [1,2]).should eq([3])
|
47
|
+
@out_port.exec_command("sub", [5,4]).should eq([1])
|
48
|
+
@out_port.exec_command("mul", [3,2]).should eq([6])
|
49
|
+
@out_port.exec_command("div", [9,3]).should eq([3])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
3
|
describe SPNet::SignalOutPort do
|
4
4
|
before :each do
|
@@ -6,44 +6,13 @@ describe SPNet::SignalOutPort do
|
|
6
6
|
@in_port = SPNet::SignalInPort.new
|
7
7
|
end
|
8
8
|
|
9
|
-
describe '
|
10
|
-
it 'should have no links' do
|
11
|
-
@out_port = SPNet::SignalOutPort.new
|
12
|
-
@out_port.links.should be_empty
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#add_link' do
|
17
|
-
it 'should add the given input port to links' do
|
18
|
-
@out_port.add_link @in_port
|
19
|
-
@out_port.links.count.should be 1
|
20
|
-
@out_port.links.first.should eq(@in_port)
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should also link the output port to the given input port' do
|
24
|
-
@out_port.add_link @in_port
|
25
|
-
@in_port.link.should eq(@out_port)
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should raise ArgumentError if the given input port is already linked' do
|
29
|
-
@out_port.add_link @in_port
|
30
|
-
lambda { @out_port.add_link(@in_port) }.should raise_error(ArgumentError)
|
31
|
-
end
|
32
|
-
|
9
|
+
describe '#add_link' do
|
33
10
|
it 'should raise ArgumentError if port is not input port' do
|
34
11
|
out_port2 = SPNet::SignalOutPort.new
|
35
12
|
lambda { @out_port.add_link(out_port2) }.should raise_error(ArgumentError)
|
36
13
|
end
|
37
14
|
end
|
38
15
|
|
39
|
-
describe '#remove_link' do
|
40
|
-
it 'should remove the given input port (if it is already linked to the output port)' do
|
41
|
-
@out_port.add_link @in_port
|
42
|
-
@out_port.remove_link @in_port
|
43
|
-
@out_port.links.should be_empty
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
16
|
describe '#send_values' do
|
48
17
|
context 'single linked input port' do
|
49
18
|
it 'should enqueue the values on the linked input port' do
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe SPNet::ValueInPort do
|
4
|
+
before :each do
|
5
|
+
@value = 0
|
6
|
+
|
7
|
+
set_value_handler = lambda do |value|
|
8
|
+
return @value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
get_value_handler = lambda do
|
12
|
+
return @value
|
13
|
+
end
|
14
|
+
|
15
|
+
@port = SPNet::ValueInPort.new :get_value_handler => get_value_handler, :set_value_handler => set_value_handler
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#set_value' do
|
19
|
+
it 'should pass the given value through the set_value handler' do
|
20
|
+
rv = @port.set_value 5
|
21
|
+
@value.should eq(5)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#get_value' do
|
26
|
+
it 'should return the value from the get_value handler' do
|
27
|
+
@value = 7
|
28
|
+
@port.get_value.should eq(7)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe SPNet::ValueOutPort do
|
4
|
+
before :each do
|
5
|
+
@value = 0
|
6
|
+
|
7
|
+
set_value_handler = lambda do |value|
|
8
|
+
return @value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
get_value_handler = lambda do
|
12
|
+
return @value
|
13
|
+
end
|
14
|
+
|
15
|
+
@out_port = SPNet::ValueOutPort.new
|
16
|
+
@in_port = SPNet::ValueInPort.new :get_value_handler => get_value_handler, :set_value_handler => set_value_handler
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#add_link' do
|
20
|
+
it 'should raise ArgumentError if port is not ValueInPort' do
|
21
|
+
@in_port2 = SPNet::SignalInPort.new
|
22
|
+
lambda { @out_port.add_link(@in_port2) }.should raise_error(ArgumentError)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#set_value' do
|
27
|
+
it 'should pass the given value through ValueInPort#set_value' do
|
28
|
+
@out_port.add_link @in_port
|
29
|
+
rv = @out_port.set_value 5
|
30
|
+
@value.should eq(5)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#get_value' do
|
35
|
+
it "should return the value from each linked port's ValueInPort#get_value" do
|
36
|
+
@value = 7
|
37
|
+
@out_port.add_link @in_port
|
38
|
+
@out_port.get_value.first.should eq(7)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
File without changes
|
data/spnet.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spnet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hashmake
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: spcore
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: bundler
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,22 +142,26 @@ files:
|
|
126
142
|
- Rakefile
|
127
143
|
- lib/spnet.rb
|
128
144
|
- lib/spnet/block.rb
|
129
|
-
- lib/spnet/
|
130
|
-
- lib/spnet/
|
131
|
-
- lib/spnet/
|
132
|
-
- lib/spnet/
|
133
|
-
- lib/spnet/signal_in_port.rb
|
134
|
-
- lib/spnet/signal_out_port.rb
|
145
|
+
- lib/spnet/in_port.rb
|
146
|
+
- lib/spnet/out_port.rb
|
147
|
+
- lib/spnet/ports/command_in_port.rb
|
148
|
+
- lib/spnet/ports/command_out_port.rb
|
149
|
+
- lib/spnet/ports/signal_in_port.rb
|
150
|
+
- lib/spnet/ports/signal_out_port.rb
|
151
|
+
- lib/spnet/ports/value_in_port.rb
|
152
|
+
- lib/spnet/ports/value_out_port.rb
|
135
153
|
- lib/spnet/version.rb
|
136
154
|
- spec/block_spec.rb
|
137
|
-
- spec/
|
138
|
-
- spec/
|
139
|
-
- spec/
|
140
|
-
- spec/
|
141
|
-
- spec/signal_in_port_spec.rb
|
142
|
-
- spec/signal_out_port_spec.rb
|
155
|
+
- spec/in_port_spec.rb
|
156
|
+
- spec/out_port_spec.rb
|
157
|
+
- spec/ports/command_in_port_spec.rb
|
158
|
+
- spec/ports/command_out_port_spec.rb
|
159
|
+
- spec/ports/signal_in_port_spec.rb
|
160
|
+
- spec/ports/signal_out_port_spec.rb
|
161
|
+
- spec/ports/value_in_port_spec.rb
|
162
|
+
- spec/ports/value_out_port_spec.rb
|
143
163
|
- spec/spec_helper.rb
|
144
|
-
- spec/
|
164
|
+
- spec/spnet_spec.rb
|
145
165
|
- spnet.gemspec
|
146
166
|
homepage: https://rubygems.org/gems/spnet
|
147
167
|
licenses:
|
@@ -158,7 +178,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
158
178
|
version: '0'
|
159
179
|
segments:
|
160
180
|
- 0
|
161
|
-
hash:
|
181
|
+
hash: -270931181
|
162
182
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
183
|
none: false
|
164
184
|
requirements:
|
@@ -167,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
187
|
version: '0'
|
168
188
|
segments:
|
169
189
|
- 0
|
170
|
-
hash:
|
190
|
+
hash: -270931181
|
171
191
|
requirements: []
|
172
192
|
rubyforge_project:
|
173
193
|
rubygems_version: 1.8.23
|
@@ -176,12 +196,14 @@ specification_version: 3
|
|
176
196
|
summary: Provide infrastructure for forming processing networks.
|
177
197
|
test_files:
|
178
198
|
- spec/block_spec.rb
|
179
|
-
- spec/
|
180
|
-
- spec/
|
181
|
-
- spec/
|
182
|
-
- spec/
|
183
|
-
- spec/signal_in_port_spec.rb
|
184
|
-
- spec/signal_out_port_spec.rb
|
199
|
+
- spec/in_port_spec.rb
|
200
|
+
- spec/out_port_spec.rb
|
201
|
+
- spec/ports/command_in_port_spec.rb
|
202
|
+
- spec/ports/command_out_port_spec.rb
|
203
|
+
- spec/ports/signal_in_port_spec.rb
|
204
|
+
- spec/ports/signal_out_port_spec.rb
|
205
|
+
- spec/ports/value_in_port_spec.rb
|
206
|
+
- spec/ports/value_out_port_spec.rb
|
185
207
|
- spec/spec_helper.rb
|
186
|
-
- spec/
|
208
|
+
- spec/spnet_spec.rb
|
187
209
|
has_rdoc:
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'hashmake'
|
2
|
-
|
3
|
-
module SPNet
|
4
|
-
class ControlMessage < Message
|
5
|
-
|
6
|
-
include Hashmake::HashMakeable
|
7
|
-
|
8
|
-
GET = :controlMessageSubtypeGet
|
9
|
-
SET = :controlMessageSubtypeSet
|
10
|
-
|
11
|
-
SUBTYPES = [
|
12
|
-
GET,
|
13
|
-
SET
|
14
|
-
]
|
15
|
-
|
16
|
-
HASHED_ARGS_SPECS = [
|
17
|
-
Hashmake::ArgSpec.new(:reqd => true, :key => :subtype, :type => Symbol, :validator => ->(a){ SUBTYPES.include?(a) } )
|
18
|
-
]
|
19
|
-
|
20
|
-
attr_reader :subtype
|
21
|
-
|
22
|
-
def initialize hashed_args
|
23
|
-
hash_make ControlMessage::HASHED_ARGS_SPECS, hashed_args
|
24
|
-
super_hashed_args = hashed_args.merge! :type => Message::CONTROL
|
25
|
-
super(super_hashed_args)
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.make_handler get_handler, set_handler
|
29
|
-
handler = lambda do |message|
|
30
|
-
raise ArgumentError, "message is not a ControlMessage" unless message.is_a?(ControlMessage)
|
31
|
-
|
32
|
-
if message.subtype == GET
|
33
|
-
return get_handler.call message
|
34
|
-
elsif message.subtype == SET
|
35
|
-
return set_handler.call message
|
36
|
-
else
|
37
|
-
raise ArgumentError, "message subtype #{message.subtype} is not valid"
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
return handler
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.make_set_message data
|
45
|
-
ControlMessage.new :subtype => SET, :data => data
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.make_get_message
|
49
|
-
ControlMessage.new :subtype => GET
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
data/lib/spnet/message.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'hashmake'
|
2
|
-
|
3
|
-
module SPNet
|
4
|
-
class Message
|
5
|
-
|
6
|
-
include Hashmake::HashMakeable
|
7
|
-
|
8
|
-
CONTROL = :messageTypeControl
|
9
|
-
COMMAND = :messageTypeCommand
|
10
|
-
|
11
|
-
TYPES = [ CONTROL, COMMAND ]
|
12
|
-
|
13
|
-
HASHED_ARGS_SPECS = [
|
14
|
-
Hashmake::ArgSpec.new(:reqd => true, :key => :type, :type => Symbol, :validator => ->(a){ TYPES.include?(a) } ),
|
15
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :data, :type => Object, :default => nil),
|
16
|
-
]
|
17
|
-
|
18
|
-
attr_accessor :data
|
19
|
-
attr_reader :type
|
20
|
-
|
21
|
-
def initialize hashed_args = {}
|
22
|
-
hash_make Message::HASHED_ARGS_SPECS, hashed_args
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'hashmake'
|
2
|
-
|
3
|
-
module SPNet
|
4
|
-
class MessageInPort
|
5
|
-
include Hashmake::HashMakeable
|
6
|
-
|
7
|
-
DEFAULT_VALIDATOR = ->(a){ true }
|
8
|
-
|
9
|
-
ARG_SPECS = [
|
10
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :name, :type => String, :default => "UNNAMED"),
|
11
|
-
Hashmake::ArgSpec.new(:reqd => true, :key => :processor, :type => Proc),
|
12
|
-
Hashmake::ArgSpec.new(:reqd => true, :key => :message_type, :type => Symbol, :validator => ->(a){ Message::TYPES.include?(a) })
|
13
|
-
]
|
14
|
-
|
15
|
-
attr_reader :name, :link
|
16
|
-
|
17
|
-
def initialize args
|
18
|
-
hash_make MessageInPort::ARG_SPECS, args
|
19
|
-
@queue = []
|
20
|
-
@link = nil
|
21
|
-
end
|
22
|
-
|
23
|
-
def recv_message message
|
24
|
-
raise ArgumentError, "message is not a Message" unless message.is_a?(Message)
|
25
|
-
if message.type == @message_type
|
26
|
-
return @processor.call(message)
|
27
|
-
else
|
28
|
-
raise ArgumentError, "message.type #{message.type} is not supported on this port"
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def clear_link
|
34
|
-
@link = nil
|
35
|
-
end
|
36
|
-
|
37
|
-
def set_link link
|
38
|
-
raise ArgumentError, "link #{link} is not a MessageOutPort" unless link.is_a?(MessageOutPort)
|
39
|
-
@link = link
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'hashmake'
|
3
|
-
|
4
|
-
module SPNet
|
5
|
-
class MessageOutPort
|
6
|
-
include Hashmake::HashMakeable
|
7
|
-
|
8
|
-
ARG_SPECS = [
|
9
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :name, :type => String, :default => "UNNAMED"),
|
10
|
-
]
|
11
|
-
|
12
|
-
attr_reader :name, :links
|
13
|
-
|
14
|
-
def initialize args = {}
|
15
|
-
hash_make MessageOutPort::ARG_SPECS, args
|
16
|
-
@links = Set.new
|
17
|
-
end
|
18
|
-
|
19
|
-
def send_message message
|
20
|
-
rvs = []
|
21
|
-
@links.each do |link|
|
22
|
-
rvs.push link.recv_message message
|
23
|
-
end
|
24
|
-
return rvs
|
25
|
-
end
|
26
|
-
|
27
|
-
def add_link link
|
28
|
-
raise ArgumentError, "link #{link} is not a MessageInPort" unless link.is_a?(MessageInPort)
|
29
|
-
raise ArgumentError, "link #{link} is already linked to a MessageInPort" if link.link
|
30
|
-
@links.add link
|
31
|
-
link.set_link self
|
32
|
-
end
|
33
|
-
|
34
|
-
def remove_link link
|
35
|
-
raise ArgumentError, "link #{link} is not a MessageInPort" unless link.is_a?(MessageInPort)
|
36
|
-
raise ArgumentError, "@links does not include link #{link}" unless @links.include? link
|
37
|
-
@links.delete link
|
38
|
-
link.clear_link
|
39
|
-
end
|
40
|
-
|
41
|
-
def remove_bad_links
|
42
|
-
marked_for_removal = []
|
43
|
-
|
44
|
-
@links.each do |link|
|
45
|
-
bad = (link.link == nil) or (link.link != self)
|
46
|
-
if bad
|
47
|
-
marked_for_removal.push link
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
marked_for_removal.each do |link|
|
52
|
-
@links.delete link
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
data/lib/spnet/signal_in_port.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'hashmake'
|
2
|
-
|
3
|
-
module SPNet
|
4
|
-
class SignalInPort
|
5
|
-
include Hashmake::HashMakeable
|
6
|
-
|
7
|
-
DEFAULT_LIMITS = (-Float::MAX..Float::MAX)
|
8
|
-
|
9
|
-
ARG_SPECS = [
|
10
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :name, :type => String, :default => "UNNAMED"),
|
11
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :limits, :type => Range, :default => DEFAULT_LIMITS)
|
12
|
-
]
|
13
|
-
|
14
|
-
attr_reader :name, :limits, :link, :queue
|
15
|
-
|
16
|
-
def make_range_limiter range
|
17
|
-
return lambda do |input|
|
18
|
-
if input < range.first
|
19
|
-
return range.first
|
20
|
-
elsif input > range.last
|
21
|
-
return range.last
|
22
|
-
else
|
23
|
-
return input
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def initialize args = {}
|
29
|
-
hash_make SignalInPort::ARG_SPECS, args
|
30
|
-
@queue = []
|
31
|
-
@skip_limiting = (@limits == DEFAULT_LIMITS)
|
32
|
-
@limiter = make_range_limiter @limits
|
33
|
-
@link = nil
|
34
|
-
end
|
35
|
-
|
36
|
-
def enqueue_values values
|
37
|
-
unless @skip_limiting
|
38
|
-
for i in 0...values.count
|
39
|
-
values[i] = @limiter.call(values[i])
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
@queue.concat values
|
44
|
-
end
|
45
|
-
|
46
|
-
def dequeue_values count = @queue.count
|
47
|
-
raise ArgumentError, "count is greater than @queue.count" if count > @queue.count
|
48
|
-
@queue.slice!(0...count)
|
49
|
-
end
|
50
|
-
|
51
|
-
def clear_link
|
52
|
-
@link = nil
|
53
|
-
end
|
54
|
-
|
55
|
-
def set_link link
|
56
|
-
raise ArgumentError, "link #{link} is not a SignalOutPort" unless link.is_a?(SignalOutPort)
|
57
|
-
@link = link
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'hashmake'
|
3
|
-
|
4
|
-
module SPNet
|
5
|
-
class SignalOutPort
|
6
|
-
include Hashmake::HashMakeable
|
7
|
-
|
8
|
-
ARG_SPECS = [
|
9
|
-
Hashmake::ArgSpec.new(:reqd => false, :key => :name, :type => String, :default => "UNNAMED"),
|
10
|
-
]
|
11
|
-
|
12
|
-
attr_reader :name, :links
|
13
|
-
|
14
|
-
def initialize args = {}
|
15
|
-
hash_make SignalOutPort::ARG_SPECS, args
|
16
|
-
@links = Set.new
|
17
|
-
end
|
18
|
-
|
19
|
-
def send_values values
|
20
|
-
@links.each do |link|
|
21
|
-
link.enqueue_values values
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def add_link link
|
26
|
-
raise ArgumentError, "link #{link} is not a SignalInPort" unless link.is_a?(SignalInPort)
|
27
|
-
raise ArgumentError, "link #{link} is already linked to a SignalOutPort" if link.link
|
28
|
-
@links.add link
|
29
|
-
link.set_link self
|
30
|
-
end
|
31
|
-
|
32
|
-
def remove_link link
|
33
|
-
raise ArgumentError, "link #{link} is not a SignalInPort" unless link.is_a?(SignalInPort)
|
34
|
-
raise ArgumentError, "@links does not include link #{link}" unless @links.include? link
|
35
|
-
@links.delete link
|
36
|
-
link.clear_link
|
37
|
-
end
|
38
|
-
|
39
|
-
def remove_bad_links
|
40
|
-
marked_for_removal = []
|
41
|
-
|
42
|
-
@links.each do |link|
|
43
|
-
bad = (link.link == nil) or (link.link != self)
|
44
|
-
if bad
|
45
|
-
marked_for_removal.push link
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
marked_for_removal.each do |link|
|
50
|
-
@links.delete link
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe SPNet::ControlMessage do
|
4
|
-
describe '.new' do
|
5
|
-
it 'should set type to Message::CONTROL' do
|
6
|
-
message = SPNet::ControlMessage.new :subtype => SPNet::ControlMessage::GET
|
7
|
-
message.type.should eq(SPNet::Message::CONTROL)
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'should ignore attempt to override type' do
|
11
|
-
message = SPNet::ControlMessage.new :subtype => SPNet::ControlMessage::GET, :type => :fakeType
|
12
|
-
message.type.should eq(SPNet::Message::CONTROL)
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should allow data to be set' do
|
16
|
-
message = SPNet::ControlMessage.new :subtype => SPNet::ControlMessage::GET, :data => 17
|
17
|
-
message.data.should eq(17)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe '.make_set_message' do
|
22
|
-
it 'should set data' do
|
23
|
-
message = SPNet::ControlMessage.make_set_message 18
|
24
|
-
message.data.should eq(18)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'should set subtype to ControlMessage::SET' do
|
28
|
-
message = SPNet::ControlMessage.make_set_message 18
|
29
|
-
message.subtype.should eq(SPNet::ControlMessage::SET)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe '.make_get_message' do
|
34
|
-
it 'should set subtype to ControlMessage::GET' do
|
35
|
-
message = SPNet::ControlMessage.make_get_message
|
36
|
-
message.subtype.should eq(SPNet::ControlMessage::GET)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe SPNet::MessageInPort do
|
4
|
-
describe '#recv_message' do
|
5
|
-
before :all do
|
6
|
-
processor = lambda do |message|
|
7
|
-
return message
|
8
|
-
end
|
9
|
-
@port = SPNet::MessageInPort.new :processor => processor, :message_type => SPNet::Message::CONTROL
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'should pass the given message to the processing callback' do
|
13
|
-
rv = @port.recv_message SPNet::ControlMessage.make_set_message(5)
|
14
|
-
rv.data.should eq(5)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/spec/message_spec.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe SPNet::Message do
|
4
|
-
describe '.new' do
|
5
|
-
it 'should set data and type' do
|
6
|
-
message = SPNet::Message.new :type => SPNet::Message::CONTROL, :data => 9
|
7
|
-
message.type.should eq(SPNet::Message::CONTROL)
|
8
|
-
message.data.should eq(9)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|