diff --git a/client.py b/client.py index d79037b..e0e96d0 100755 --- a/client.py +++ b/client.py @@ -9,7 +9,7 @@ __version__ = 0.3 __author__ = "Jan Klopper " import random -from vloed import PixelVloedClient, InitMessage, RGBPixel, MAX_PIXELS +from vloed import PixelVloedClient, Packet, RGBPixel, MAX_PIXELS def RandomFill(pixels, width, height): """Generates a random number of pixels with a random color""" @@ -34,22 +34,17 @@ def RunClient(options): # loop the effect until we cancel by pressing ctrl+c / exit the program while True: - pixels = [] # list to store the pixels we want to send + + # packet will automatically send its pixels if gets to the maximum pixel length + pixels = Packet(client) # add some pixels to the output with our functions # the width/height are read from the client's config RandomFill(pixels, client.width, client.height) - # send our pixels in packets including a message header and less than - # MAX_PIXELS pixels - for part in SplitList(MAX_PIXELS, pixels): - packet = InitMessage([]) + part - client.SendPacket(''.join(packet)) + # send whatever pixels are left in the packet + pixels.flush() -def SplitList(max_size, lis): - """Splits a list into equal-sized chunks""" - for i in xrange(0, len(lis), max_size): - yield lis[i:i+max_size] if __name__ == '__main__': # if this script is called from the command line, and thus not imported diff --git a/vloed.py b/vloed.py index 52b8275..e92d52d 100755 --- a/vloed.py +++ b/vloed.py @@ -24,6 +24,8 @@ PROTOCOL_VERSION = 1 MAX_PROTOCOL_VERSION = 1 PROTOCOL_PREAMBLE = "pixelvloed" MAX_PIXELS = 140 +MESSAGE_HEADER_SIZE = 2 +MAX_MESSAGE = MAX_PIXELS + MESSAGE_HEADER_SIZE class Canvas(object): """PixelVloed display class""" @@ -263,7 +265,7 @@ class PixelVloedClient(object): def NewMessage(): """Creates a new message with the correct max size, rgb mode and version""" - message = MaxSizeList(MAX_PIXELS+2) + message = MaxSizeList(MAX_MESSAGE) InitMessage(message) return message @@ -303,6 +305,42 @@ class MaxSizeList(list): raise IndexError('max size reached') super(MaxSizeList, self).append(item) +class Packet(list): + """A Pixelvloed packet. + + Append pixels to it. It will send automatically if it has MAX_PIXELS length. + """ + + def __init__(self, client): + """Create a new pixelvloed packet. + + This packet can be reused for the whole program. + + Arguments: + client: PixelVloedClient used to send the packet when it is full. + """ + self.client = client + super(Packet, self).__init__() + InitMessage(self) + + def append(self, item): + """Appends a pixel to this packet. + + Sends pixels and resets the packet if packet would exceed MAX_MESSAGE + (MAX_PIXELS + MESSAGE_HEADER_SIZE). + """ + if self.__len__() >= MAX_MESSAGE: + self._send() + super(Packet, self).append(item) + + def flush(self): + """Immediately send all pixels currently in this packet and empty it""" + self._send() + + def _send(self): + self.client.SendPacket(''.join(self)) + del self[MESSAGE_HEADER_SIZE:] # reset packet + def RunServer(options): """Runs a pixelvloed server""" PixelVloedServer('%s:%d' %(options.ip, options.port),