spnet 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|