diff options
-rw-r--r-- | FActivity.py | 4 | ||||
-rwxr-xr-x | TamTam.py | 7 | ||||
-rw-r--r-- | Util/Network.py | 76 | ||||
-rw-r--r-- | miniTamTam/miniTamTamMain.py | 51 | ||||
-rwxr-xr-x | scripts/update-activity.sh | 7 |
5 files changed, 137 insertions, 8 deletions
diff --git a/FActivity.py b/FActivity.py index 2708a05..d24985f 100644 --- a/FActivity.py +++ b/FActivity.py @@ -6,4 +6,6 @@ import gtk class FakeActivity(gtk.Window): def __init__(self, handle): - gtk.Window.__init__(self)
\ No newline at end of file + gtk.Window.__init__(self) + + self._shared_activity = None @@ -63,7 +63,10 @@ class TamTam(Activity): self.instrumentPanel = InstrumentPanel( force_load = False ) self.preloadList = [ self.instrumentPanel ] - self.set_mode(mode) + if self._shared_activity: # if we're joining a shared activity force mini + self.set_mode("mini") + else: + self.set_mode(mode) def onPreloadTimeout( self ): if Config.DEBUG > 4: print "TamTam::onPreloadTimeout", self.preloadList @@ -175,8 +178,6 @@ class TamTam(Activity): if Config.DEBUG: print 'DEBUG: TamTam::onDestroy()' os.system('rm -f ' + Config.PREF_DIR + '/synthTemp*') - self.network.shutdown() - for m in self.modeList: if self.modeList[m] != None: self.modeList[m].onDestroy() diff --git a/Util/Network.py b/Util/Network.py index 85e8e5a..80f6d7c 100644 --- a/Util/Network.py +++ b/Util/Network.py @@ -24,12 +24,15 @@ import Config PORT = 24420 LISTENER_PORT = PORT-1 +WAIT_PORT = PORT-2 + BACKLOG = 5 # allow a backlog of N new connections MAX_SIZE = 1024 # max message size to receive in one go MD_OFFLINE = 0 MD_HOST = 1 MD_PEER = 2 +MD_WAIT = 3 # enumerate message types # format: ("NAME", <message size>) @@ -115,6 +118,8 @@ class Network: def __init__( self, mode = MD_OFFLINE, hostaddress = None ): # check for forced networking + print "------------------------------------------------------------" + print os.getcwd() if os.path.isfile("FORCE_HOST"): mode = MD_HOST elif os.path.isfile("FORCE_PEER"): @@ -195,6 +200,14 @@ class Network: self.connection.pop(self.socket) self.socket = None self.hostAddress = None + self.inputSockets = [ self.listenerSocket ] + + elif self.mode == MD_WAIT: + if Config.DEBUG > 1: print "Network:: wait - cleaning up old connections" + self.socket.close() + self.connection.pop(self.socket) + self.socket = None + self.inputSockets = [ self.listenerSocket ] # initialize new mode @@ -251,12 +264,64 @@ class Network: self.listenerSocket.sendto( "EXIT", ("localhost", LISTENER_PORT) ) self.listener = None + elif self.mode == MD_WAIT: + if Config.DEBUG > 1: print "Network:: initializing network, wait mode" + try: + self.socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) + address = ("",PORT) + self.connection[self.socket] = Connection( self.socket, address ) + self.socket.bind(address) + self.socket.listen(BACKLOG) + self.inputSockets.append(self.socket) + if self.listener: + self.listener.updateSockets( self.inputSockets, self.outputSockets, self.exceptSockets ) + self.listenerSocket.sendto( "REFRESH", ("localhost", LISTENER_PORT) ) + else: + self.listener = Listener( self, self.listenerSocket, self.inputSockets, self.outputSockets, self.exceptSockets ) + self.listener.start() + except socket.error, (value, message): + if self.socket: + self.socket.close() + self.connection.pop(self.socket) + print "Network:: FAILED to open socket: " + message + self.mode = MD_OFFLINE + if self.listener: + self.listenerSocket.sendto( "EXIT", ("localhost", LISTENER_PORT) ) + self.listener = None + else: if Config.DEBUG > 1: print "Network:: offline" if self.listener: self.listenerSocket.sendto( "EXIT", ("localhost", LISTENER_PORT) ) self.listener = None + def introducePeer( self, ip ): + if Config.DEBUG > 1: print "Network:: introducing self to peer " + ip + try: + poke = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) + poke.setblocking(0) + except socket.error, (value, message): + print "Network::introducePeer:: FAILED to open socket: " + message + return + if poke.connect_ex( (ip, WAIT_PORT) ): # failed to connect + gobject.timeout_add( 500, self._pokePeer, poke, ip, 0 ) + else: # connected + if Config.DEBUG > 1: print "Netwtork:: introduction succeeded" + poke.close() + + def _pokePeer( self, poke, ip, retry ): + if poke.connect_ex( (ip, WAIT_PORT) ): # failed to connect + if retry > 120: # give up + print "Network::introducePeer:: peer failed to respond after 60 seconds, giving up!" + else: + gobject.timeout_add( 500, self._pokePeer, poke, ip, retry+1 ) + else: # connected + if Config.DEBUG > 1: print "Netwtork:: introduction succeeded" + poke.close() + + return False + + def addPeer( self, peer, address ): if Config.DEBUG > 1: print "Network:: adding peer: %s" % address[0] self.connection[peer] = Connection( peer, address ) @@ -430,7 +495,7 @@ class Network: except socket.error, (value, message): print "Network:: error reading data: " + message - else: # MD_PEER + elif self.mode == MD_PEER: for s in inputReady: try: @@ -443,6 +508,15 @@ class Network: except socket.error, (value, message): print "Network:: error reading data: " + message + else: # MD_WAIT + + for s in inputReady: + try: + peer, address = self.socket.accept() + self.setMode( MD_PEER, address ) + except socket.error, (value, message): + print "Network:: error accepting connection: " + message + def processStream( self, sock, newData = "" ): con = self.connection[sock] diff --git a/miniTamTam/miniTamTamMain.py b/miniTamTam/miniTamTamMain.py index 466ecf2..412fbeb 100644 --- a/miniTamTam/miniTamTamMain.py +++ b/miniTamTam/miniTamTamMain.py @@ -7,6 +7,8 @@ import random import time import xdrlib +from gettext import gettext as _gettext + from types import * from math import sqrt from Util.NoteDB import PARAMETER @@ -40,6 +42,7 @@ class miniTamTamMain(SubActivity): def __init__(self, activity, set_mode): SubActivity.__init__(self, set_mode) + self.activity = activity self.set_border_width(Config.MAIN_WINDOW_PADDING) @@ -105,12 +108,27 @@ class miniTamTamMain(SubActivity): self.packer = xdrlib.Packer() self.unpacker = xdrlib.Unpacker("") + #-- handle forced networking --------------------------------------- if self.network.isHost(): self.updateSync() self.syncTimeout = gobject.timeout_add( 1000, self.updateSync ) elif self.network.isPeer(): self.sendTempoQuery() self.syncTimeout = gobject.timeout_add( 1000, self.updateSync ) + #------------------------------------------------------------------- + + + if os.path.isfile("FORCE_SHARE"): # HOST + r = random.random() + print "::::: Sharing as TamTam%f :::::" % r + self.activity.set_title(_gettext("TamTam%f" % r)) + self.activity.connect( "shared", self.shared ) + self.activity.share() + elif self.activity._shared_activity: # PEER + self.activity._shared_activity.connect( "buddy-joined", self.buddy_joined ) + self.activity._shared_activity.connect( "buddy-left", self.buddy_left ) + self.activity.connect( "joined", self.joinedTEMP ) + self.network.setMode( Net.MD_WAIT ) def drawSliders( self ): mainSliderBox = RoundHBox(fillcolor = Config.PANEL_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) @@ -507,9 +525,7 @@ class miniTamTamMain(SubActivity): self.csnd.loopClear() def onDestroy( self ): - #this gets called when the whole app is being destroyed - #QUESTION is this called before or after onDeactivate() - pass + self.network.shutdown() def scale(self, input,input_min,input_max,output_min,output_max): range_input = input_max - input_min @@ -536,6 +552,35 @@ class miniTamTamMain(SubActivity): #----------------------------------------------------------------------- # Network + #-- Activity ----------------------------------------------------------- + + def shared( self, activity ): + if Config.DEBUG: print "miniTamTam:: successfully shared, start host mode" + self.activity._shared_activity.connect( "buddy-joined", self.buddy_joined ) + self.activity._shared_activity.connect( "buddy-left", self.buddy_left ) + self.network.setMode( Net.MD_HOST ) + + def joinedTEMP( self, activity ): + print "miniTamTam:: joined activity!!" + for buddy in self.activity._shared_activity.get_joined_buddies(): + print buddy.props.ip4_address + + def buddy_joined( self, activity, buddy ): + print "buddy joined " + str(buddy) + print buddy.props.ip4_address + if self.network.isHost(): + if buddy.props.ip4_address: + self.network.introducePeer( buddy.props.ip4_address ) + else: + print "miniTamTam:: new buddy does not have an ip4_address!!" + + def buddy_left( self, activity, buddy): + print "buddy left" + + #def joined( self, activity ): + # if Config.DEBUG: print "miniTamTam:: successfully joined, wait for host" + # self.net.waitForHost() + #-- Senders ------------------------------------------------------------ def sendSyncQuery( self ): diff --git a/scripts/update-activity.sh b/scripts/update-activity.sh new file mode 100755 index 0000000..540cd08 --- /dev/null +++ b/scripts/update-activity.sh @@ -0,0 +1,7 @@ +#!/bin/sh +cp *.py /usr/share/activities/TamTam.activity +cp Edit/*.py /usr/share/activities/TamTam.activity/Edit +cp miniTamTam/*.py /usr/share/activities/TamTam.activity/miniTamTam +cp Util/*.py /usr/share/activities/TamTam.activity/Util +cp SynthLab/*.py /usr/share/activities/TamTam.activity/SynthLab +cp Generation/*.py /usr/share/activities/TamTam.activity/Generation |