Skip to content

Commit dca05f8

Browse files
committed
adding router program
1 parent 57a0b07 commit dca05f8

File tree

1 file changed

+167
-84
lines changed

1 file changed

+167
-84
lines changed

router.py

100644100755
+167-84
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,88 @@
1+
#!/usr/bin/env python2
2+
# -*- coding: utf-8 -*-
3+
14
import sys
25
import rtmidi
6+
import signal
7+
import locale
8+
locale.setlocale(locale.LC_ALL, '')
9+
import curses
10+
11+
#from matrix import View
12+
13+
class View:
14+
def __init__(self, screen, model):
15+
self.screen = screen
16+
self.cursor = [0,0]
17+
self.model = model
18+
19+
def input_left(self):
20+
return 1 + len(self.model.inputs) * 2
21+
22+
def output_top(self):
23+
return 1 + len(self.model.inputs)
24+
25+
def draw(self):
26+
model = self.model
27+
s = self.screen
28+
y = 0
29+
x = self.input_left() - 1
30+
for i in model.inputs:
31+
s.move(y, x)
32+
s.addch(curses.ACS_HLINE)
33+
s.addstr(y, x + 1, i)
34+
y += 1
35+
max_y = y
36+
y += len(model.outputs)
37+
#y = 1
38+
x = 0
39+
for o in model.outputs:
40+
s.addstr(y, x, o)
41+
y -= 1
42+
x += 2
43+
44+
y = self.output_top() - 1
45+
for x in range(len(model.outputs)):
46+
s.move(y, x * 2)
47+
s.vline(curses.ACS_VLINE, len(model.outputs) - x)
48+
49+
for y in range(len(model.inputs)):
50+
for x in range(len(model.outputs)):
51+
s.move(y, x * 2)
52+
s.addch(curses.ACS_PLUS)
53+
s.addch(curses.ACS_HLINE)
54+
55+
for p1, p2 in model.connections:
56+
y = model.get_index_in(p1)
57+
x = model.get_index_out(p2) * 2
58+
s.move(y,x)
59+
s.addch(curses.ACS_DIAMOND)
60+
s.addstr(y, x, "◊")
61+
s.move( self.output_top() + len(model.outputs) + 2, 0)
62+
63+
def set_cursor(self, cursor):
64+
s = self.screen
65+
s.chgat( cursor[0], self.input_left(), len( self.model.inputs[cursor[0]] ), curses.A_REVERSE )
66+
s.chgat( len( self.model.outputs ) - cursor[1] + self.output_top() - 1, 2*cursor[1], len( self.model.outputs[cursor[1]] ), curses.A_REVERSE )
67+
self.cursor = cursor
68+
self.screen.move( cursor[0], cursor[1] * 2 )
69+
370

471
class Devices:
72+
_instance = None
573
def __init__(self):
6-
self.inputs = {}
774
self.open_inputs = {}
875
self.open_outputs = {}
76+
self.connections = []
77+
self.load()
78+
79+
@classmethod
80+
def instance(cls):
81+
if cls._instance is None:
82+
cls._instance = cls()
83+
return cls._instance
84+
85+
def load(self):
986
self.ins()
1087
self.outs()
1188

@@ -48,28 +125,31 @@ def __del__(self):
48125
for rt in self.open_inputs.values():
49126
rt.closePort()
50127

51-
class Device:
128+
class DeviceListener:
52129
channels = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
53-
def __init__(self):
54-
self.input = devices.input(self.name)
130+
def __init__(self, name):
131+
self.name = name
132+
self.input = Devices.instance().input(self.name)
55133
self.input.setCallback( self )
56-
self.output = devices.output(self.name)
134+
self.output = Devices.instance().output(self.name)
57135
self.subs = []
58136

59137
def __call__(self, message):
60138
data = message.getRawData()
61139
print '\033[2K',
62-
print ' '.join([hex(ord(d))[2:] for d in data]), "\r",
63-
sys.stdout.flush()
140+
print ' '.join([hex(ord(d))[2:] for d in data]),
64141
self.forward(message)
142+
print "\r",
143+
sys.stdout.flush()
65144

66145
def forward(self, message):
67-
ch = message.getChannel()
68146
for sub in self.subs:
69-
if ch in sub.channels:
70-
sub.send(message)
147+
if sub.filter(message):
148+
sub.output.send(message)
71149

72150
def send(self, message):
151+
data = message.getRawData()
152+
print self.name,
73153
self.output.sendMessage(message)
74154

75155
def send_unison(self, message, channel):
@@ -78,77 +158,80 @@ def send_unison(self, message, channel):
78158
self.output.sendMessage(msg)
79159

80160
def subscribe(self, other):
81-
self.subs.append(other)
82-
83-
def __rshift__(self, others):
84-
for other in others:
85-
self.subscribe(other)
86-
87-
class Deluge(Device):
88-
name = 'Deluge'
89-
90-
class BCR(Device):
91-
name = 'BCR2000'
92-
93-
class JUNO(Device):
94-
name = 'JUNO-DS'
95-
channels = [4,5,6,7,9,11]
96-
97-
class Circuit(Device):
98-
name = 'Circuit'
99-
channels = [0,1,2,10]
100-
101-
class Phatty(Device):
102-
name = 'Little Phatty SE II'
103-
channels = [3]
104-
#def send(self, message):
105-
# self.send_unison(message, 3)
106-
107-
devices = Devices()
108-
deluge = Deluge()
109-
bcr = BCR()
110-
juno = JUNO()
111-
phatty = Phatty()
112-
circuit = Circuit()
113-
114-
deluge >> juno, circuit, phatty
115-
bcr >> phatty,
116-
juno >> deluge, circuit, phatty
117-
118-
119-
"""
120-
matrix = (
121-
(deluge, (juno, circuit, phatty)),
122-
(bcr, (phatty,)),
123-
(juno, (deluge, circuit, phatty)),
124-
)
125-
126-
for device, others in matrix:
127-
for other in others:
128-
device.subscribe(other)
129-
"""
130-
131-
"""
132-
deluge.subscribe(juno)
133-
deluge.subscribe(circuit)
134-
deluge.subscribe(phatty)
135-
136-
bcr.subscribe(phatty)
137-
138-
juno.subscribe(deluge)
139-
juno.subscribe(phatty)
140-
juno.subscribe(circuit)
141-
"""
142-
143-
144-
145-
146-
147-
#while True:
148-
# message = device.getMessage(100)
149-
# call(message)
150-
151-
152-
print 'HIT ENTER TO EXIT'
153-
sys.stdin.read(1)
154-
161+
if other not in self.subs:
162+
self.subs.append(other)
163+
164+
class Connection:
165+
def __init__(self, i, o):
166+
self.input = i
167+
self.output = o
168+
self.filter = lambda x: True
169+
170+
def connect(self):
171+
devs = Devices.instance()
172+
self.input.subscribe(self)
173+
174+
def __eq__(self, other):
175+
return self.input.name == other.input.name and self.output.name == other.output.name
176+
177+
class Router:
178+
def __init__(self):
179+
self.connections = []
180+
self.listeners = {}
181+
182+
def connect(self, i, o, filt=lambda x: True):
183+
if i not in self.listeners:
184+
self.listeners[i] = DeviceListener(i)
185+
if o not in self.listeners:
186+
self.listeners[o] = DeviceListener(o)
187+
188+
i = self.listeners[i]
189+
o = self.listeners[o]
190+
191+
new_connection = Connection(i,o)
192+
new_connection.filter = filt
193+
new_connection.connect()
194+
for connection in self.connections:
195+
if connection == new_connection:
196+
self.connections.remove(connection)
197+
self.connections.append(new_connection)
198+
199+
def main(stdscr):
200+
def channel_filter(channels):
201+
return lambda x: x.getChannel() in channels
202+
203+
devices = Devices.instance()
204+
devices.load()
205+
router = Router()
206+
router.connect("Deluge", "Little Phatty SE II", channel_filter((3,)))
207+
router.connect("Deluge", "Circuit", channel_filter((0,1,2,10,)))
208+
router.connect("Deluge", "JUNO-DS", channel_filter((4,5,6,7,9,11,)))
209+
router.connect("JUNO-DS", "Circuit", channel_filter((1,2,10,)))
210+
router.connect("JUNO-DS", "Deluge", channel_filter((8,)))
211+
router.connect("JUNO-DS", "Little Phatty SE II", channel_filter((3,)))
212+
router.connect("BCR2000", "Little Phatty SE II", channel_filter((3,)))
213+
214+
def hup(signum, frame):
215+
devices.load()
216+
signal.signal(signal.SIGHUP, hup)
217+
218+
#while True: #debug
219+
# message = device.getMessage(100)
220+
# call(message)
221+
222+
#ctrl = Controller(devices)
223+
view = View(stdscr, devices)
224+
225+
while True:
226+
view.draw()
227+
#view.set_cursor(ctrl.cursor)
228+
key = stdscr.getch()
229+
if key == ord('q'):
230+
break
231+
elif key == ord('r'):
232+
stdscr.clear()
233+
234+
#ctrl.key_press(key)
235+
236+
if __name__ == '__main__':
237+
curses.wrapper(main)

0 commit comments

Comments
 (0)