qcmd 0.1.7 → 0.1.8

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.
@@ -1,84 +0,0 @@
1
- module OSC
2
- class StoppingServer < Server
3
- def initialize *args
4
- @state = :initialized
5
- @port = args.first
6
- super(*args)
7
- end
8
-
9
- def run
10
- @state = :starting
11
- super
12
- end
13
-
14
- def stop
15
- @state = :stopping
16
- stop_detector
17
- stop_dispatcher
18
- end
19
-
20
- def state
21
- @state
22
- end
23
-
24
- private
25
-
26
- def stop_detector
27
- # send listening port a "CLOSE" signal on the open UDP port
28
- _closer = UDPSocket.new
29
- _closer.connect('', @port)
30
- _closer.puts "CLOSE-#{@port}"
31
- _closer.close unless _closer.closed? || !_closer.respond_to?(:close)
32
- end
33
-
34
- def stop_dispatcher
35
- @queue << :stop
36
- end
37
-
38
- def dispatcher
39
- loop do
40
- mesg = @queue.pop
41
- dispatch_message( mesg )
42
- end
43
- rescue StopException
44
- @state = :stopped
45
- end
46
-
47
- def dispatch_message message
48
- if message.is_a?(Symbol) && message.to_s == 'stop'
49
- raise StopException.new
50
- end
51
-
52
- super(message)
53
- end
54
-
55
- def detector
56
- @state = :listening
57
-
58
- loop do
59
- osc_data, network = @socket.recvfrom( 16384 )
60
-
61
- # quit if socket receives the close signal
62
- if osc_data == "CLOSE-#{@port}"
63
- @socket.close if !@socket.closed? && @socket.respond_to?(:close)
64
- break
65
- end
66
-
67
- unpack_socket_receipt osc_data, network
68
- end
69
- end
70
-
71
- def unpack_socket_receipt osc_data, network
72
- ip_info = Array.new
73
- ip_info << network[1]
74
- ip_info.concat(network[2].split('.'))
75
- OSC::OSCPacket.messages_from_network( osc_data, ip_info ).each do |message|
76
- @queue.push(message)
77
- end
78
- rescue EOFError
79
- # pass
80
- end
81
- end
82
-
83
- class StopException < Exception; end
84
- end
@@ -1,175 +0,0 @@
1
- require 'osc-ruby'
2
-
3
- require 'json'
4
-
5
- module Qcmd
6
- class TimeoutError < Exception; end
7
-
8
- class Server
9
- attr_accessor :receive_channel, :receive_thread, :receive_port, :send_channel, :machine
10
-
11
- def initialize *args
12
- options = args.extract_options!
13
-
14
- self.receive_port = options[:receive]
15
- connect_to_client
16
-
17
- @handler = Qcmd::Handler.new
18
- @sent_messages = []
19
- @sent_messages_expecting_reply = []
20
- @received_messages = []
21
- end
22
-
23
- def connect_to_client
24
- self.machine = Qcmd.context.machine
25
- self.send_channel = OSC::Client.new machine.address, machine.port
26
-
27
- Qcmd.debug '(setting up listening connection)'
28
- listen
29
- end
30
-
31
- def generic_responding_proc
32
- proc do |osc_message|
33
- @received_messages << osc_message
34
-
35
- begin
36
- Qcmd.debug "(received message: #{ osc_message.address })"
37
- reply_received QLab::Reply.new(osc_message)
38
- rescue => ex
39
- Qcmd.debug "(ERROR #{ ex.message })"
40
- end
41
- end
42
- end
43
-
44
- # initialize
45
- def listen
46
- if receive_channel
47
- stop
48
- end
49
-
50
- self.receive_channel = OSC::StoppingServer.new(self.receive_port)
51
-
52
- Qcmd.debug "(opening receiving channel: #{ self.receive_channel.inspect })"
53
-
54
- receive_channel.add_method %r{/reply/?(.*)}, &generic_responding_proc
55
- end
56
-
57
- def replies_expected?
58
- @sent_messages_expecting_reply.size > 0
59
- end
60
-
61
- def reply_received reply
62
- Qcmd.debug "(receiving #{ reply })"
63
-
64
- # update world state
65
- begin
66
- @handler.handle reply
67
- rescue => ex
68
- print "(ERROR: #{ ex.message })"
69
- end
70
-
71
- # FIFO
72
- @sent_messages_expecting_reply.shift
73
-
74
- Qcmd.debug "(#{ @sent_messages_expecting_reply.size } messages awaiting reply)"
75
- end
76
-
77
- def wait_for_replies
78
- begin
79
- yield
80
-
81
- naps = 0
82
- while replies_expected? do
83
- if naps > 20
84
- # FAILED TO GET RESPONSE
85
- raise TimeoutError.new
86
- end
87
-
88
- naps += 1
89
- sleep 0.1
90
- end
91
- rescue TimeoutError => ex
92
- Qcmd.log "[error: reply timeout]"
93
- # clear expecting reply item, assume it will never arrive
94
- @sent_messages_expecting_reply.shift
95
- end
96
- end
97
-
98
- def send_command command, *args
99
- options = args.extract_options!
100
-
101
- Qcmd.debug "(building command from command, args, options: #{ command.inspect }, #{ args.inspect }, #{ options.inspect })"
102
-
103
- # make sure command is valid OSC Address
104
- if %r[^/] =~ command
105
- address = command
106
- else
107
- address = "/#{ command }"
108
- end
109
-
110
- osc_message = OSC::Message.new address, *args
111
-
112
- send_message osc_message
113
- end
114
-
115
- def send_message osc_message
116
- Qcmd.debug "(sending osc message #{ osc_message.address } #{osc_message.has_arguments? ? 'with' : 'without'} args)"
117
-
118
- @sent_messages << osc_message
119
- if Qcmd::Commands.expects_reply?(osc_message)
120
- Qcmd.debug "(this command expects a reply)"
121
- @sent_messages_expecting_reply << osc_message
122
- end
123
-
124
- wait_for_replies do
125
- send_channel.send osc_message
126
- end
127
- end
128
-
129
- def stop
130
- receive_channel.stop if receive_channel && receive_channel.state == :listening
131
- end
132
-
133
- def run
134
- Qcmd.debug '(starting server)'
135
- self.receive_thread = Thread.new do
136
- Qcmd.debug '(server is up)'
137
- receive_channel.run
138
- end
139
- end
140
- alias :start :run
141
-
142
- def send_workspace_command _command, *args
143
- command = "workspace/#{ Qcmd.context.workspace.id }/#{ _command }"
144
- send_command(command, *args)
145
- end
146
-
147
- def send_cue_command number, action, *args
148
- command = "cue/#{ number }/#{ action }"
149
- send_workspace_command(command, *args)
150
- end
151
-
152
- ## QLab commands
153
-
154
- def load_workspaces
155
- send_command 'workspaces'
156
- end
157
-
158
- def load_cues
159
- send_workspace_command 'cueLists'
160
- end
161
-
162
- def connect_to_workspace workspace
163
- if workspace.passcode?
164
- send_command "workspace/#{workspace.id}/connect", "%04i" % workspace.passcode
165
- else
166
- send_command "workspace/#{workspace.id}/connect"
167
- end
168
-
169
- # if it worked, load cues automatically
170
- if Qcmd.context.workspace
171
- load_cues
172
- end
173
- end
174
- end
175
- end
@@ -1,78 +0,0 @@
1
- require File.join( File.dirname(__FILE__) , '..', 'spec_helper' )
2
- require 'qcmd'
3
- require 'socket'
4
-
5
- class PortFactory
6
- @@counter = 12345
7
-
8
- def self.new_port
9
- @@counter += 1
10
- @@counter
11
- end
12
- end
13
-
14
- describe OSC::StoppingServer do
15
- before :each do
16
- @port = PortFactory.new_port
17
- end
18
-
19
- it "should bind to a socket when initialized" do
20
- UDPSocket.any_instance.should_receive(:bind).with('', @port)
21
- server = OSC::StoppingServer.new @port
22
- end
23
-
24
- it 'should start a listening thread when started' do
25
- server = OSC::StoppingServer.new @port
26
-
27
- test_thread = Thread.new do
28
- Thread.should_receive :fork
29
- server.run
30
- end
31
-
32
- server.stop
33
- end
34
-
35
- it 'should kill the listening thread and close socket when stopped' do
36
- server = OSC::StoppingServer.new @port
37
-
38
- test_thread = Thread.new do
39
- server.run
40
- end
41
-
42
- sleep 0.1
43
- server.stop
44
- sleep 0.1
45
-
46
- # server has stopped blocking
47
- test_thread.alive?.should == false
48
-
49
- # server claims it is closed
50
- server.state.should == :stopped
51
- end
52
-
53
- it 'should create messages for legitimate OSC commands' do
54
- server = OSC::StoppingServer.new @port
55
-
56
- received = nil
57
-
58
- server.add_method '/test' do |message|
59
- received = message
60
- end
61
-
62
- test_thread = Thread.new do
63
- server.run
64
- end
65
-
66
- received.should == nil
67
-
68
- client = OSC::Client.new 'localhost', @port
69
- client.send OSC::Message.new('/test', 'ansible')
70
-
71
- sleep 0.1
72
- server.stop
73
-
74
- received.is_a?(OSC::Message).should == true
75
- received.to_a.first.should == 'ansible'
76
- end
77
- end
78
-