viff

changeset 597:5845aca82a6e

Split Runtime.incoming_data into a dict on each ShareExchanger.
author Martin Geisler <mg@daimi.au.dk>
date Sat, 22 Mar 2008 15:56:05 +0100
parents 4a1f03f138ba
children 79411fe0da54
files viff/runtime.py
diffstat 1 files changed, 20 insertions(+), 32 deletions(-) [+]
line diff
     1.1 --- a/viff/runtime.py	Sat Mar 22 15:53:25 2008 +0100
     1.2 +++ b/viff/runtime.py	Sat Mar 22 15:56:05 2008 +0100
     1.3 @@ -211,6 +211,17 @@
     1.4      def __init__(self):
     1.5          self.peer_id = None
     1.6  
     1.7 +        #: Data expected to be received in the future.
     1.8 +        #:
     1.9 +        #: Data from our peer is put here, either as an empty Deferred
    1.10 +        #: if we are waiting on input from the player, or the data
    1.11 +        #: itself if data is received from the other player before we
    1.12 +        #: are ready to use it.
    1.13 +        #:
    1.14 +        #: @type: C{dict} from C{(program_counter, data_type)} to
    1.15 +        #: deferred data.
    1.16 +        self.incoming_data = {}
    1.17 +
    1.18      def connectionMade(self):
    1.19          #print "Transport:", self.transport
    1.20          self.sendString(str(self.factory.runtime.id))
    1.21 @@ -225,7 +236,7 @@
    1.22  
    1.23          The string received is unmarshalled into the program counter,
    1.24          and a data part. The data is passed the appropriate Deferred
    1.25 -        in the L{Runtime.incoming_data}.
    1.26 +        in L{self.incoming_data}.
    1.27  
    1.28          @param string: bytes from the network.
    1.29          @type string: C{(program_counter, data)} in
    1.30 @@ -246,16 +257,13 @@
    1.31              self.factory.identify_peer(self)
    1.32          else:
    1.33              program_counter, type, data = marshal.loads(string)
    1.34 -            # TODO: The incoming_data mapping could also be stored
    1.35 -            # in self, and so self.peer_id would not be needed.
    1.36 -            key = (program_counter, self.peer_id, type)
    1.37 -            incoming_data = self.factory.runtime.incoming_data
    1.38 +            key = (program_counter, type)
    1.39  
    1.40              try:
    1.41 -                deferred = incoming_data.pop(key)
    1.42 +                deferred = self.incoming_data.pop(key)
    1.43                  deferred.callback(data)
    1.44              except KeyError:
    1.45 -                incoming_data[key] = data
    1.46 +                self.incoming_data[key] = data
    1.47  
    1.48              # TODO: marshal.loads can raise EOFError, ValueError, and
    1.49              # TypeError. They should be handled somehow.
    1.50 @@ -428,26 +436,6 @@
    1.51          #: @type: C{list} of integers.
    1.52          self.program_counter = [0]
    1.53  
    1.54 -        #: Data expected to be received in the future.
    1.55 -        #:
    1.56 -        #: Shares from other players are put here, either as an empty
    1.57 -        #: Deferred if we are waiting on input from the player, or as
    1.58 -        #: a succeeded Deferred if input is received from the other
    1.59 -        #: player before we are ready to use it.
    1.60 -        #:
    1.61 -        #: When we expect to receive data from another player,
    1.62 -        #: L{_expect_data} is used. If we are ahead of the other
    1.63 -        #: player, it sets up a Deferred waiting for the player's
    1.64 -        #: input. It is L{ShareExchanger.stringReceived} that triggers
    1.65 -        #: this deferred when the input eventually arrives. If the
    1.66 -        #: other player has already sent us its input, it will have
    1.67 -        #: been stored by L{ShareExchanger.stringReceived} and
    1.68 -        #: L{_expect_data} can do a callback immediatedly.
    1.69 -        #:
    1.70 -        #: @type: C{dict} from C{(program_counter, player_id,
    1.71 -        #: data_type)} to deferred data.
    1.72 -        self.incoming_data = {}
    1.73 -
    1.74          #: Connections to the other players.
    1.75          #:
    1.76          #: @type: C{dict} from Player ID to L{ShareExchanger} objects.
    1.77 @@ -551,15 +539,15 @@
    1.78  
    1.79      def _expect_data(self, peer_id, type, deferred):
    1.80          assert peer_id != self.id, "Do not expect data from yourself!"
    1.81 -        # Convert self.program_counter to a hashable value in order
    1.82 -        # to use it as a key in self.incoming_data.
    1.83 +        # Convert self.program_counter to a hashable value in order to
    1.84 +        # use it as a key in self.protocols[peer_id].incoming_data.
    1.85          pc = tuple(self.program_counter)
    1.86 -        key = (pc, peer_id, type)
    1.87 +        key = (pc, type)
    1.88  
    1.89 -        data = self.incoming_data.pop(key, None)
    1.90 +        data = self.protocols[peer_id].incoming_data.pop(key, None)
    1.91          if data is None:
    1.92              # We have not yet received data from the other side.
    1.93 -            self.incoming_data[key] = deferred
    1.94 +            self.protocols[peer_id].incoming_data[key] = deferred
    1.95          else:
    1.96              # We have already received the data from the other side.
    1.97              deferred.callback(data)