diff --git a/client.py b/client.py index 5984c0d..e0e96d0 100755 --- a/client.py +++ b/client.py @@ -9,9 +9,9 @@ __version__ = 0.3 __author__ = "Jan Klopper " import random -from vloed import PixelVloedClient, NewMessage, RGBPixel, MAX_PIXELS +from vloed import PixelVloedClient, Packet, RGBPixel, MAX_PIXELS -def RandomFill(message, width, height): +def RandomFill(pixels, width, height): """Generates a random number of pixels with a random color""" for pixel in xrange(0, random.randint(10, MAX_PIXELS)): pixel = RGBPixel(random.randint(0, width), @@ -19,12 +19,7 @@ def RandomFill(message, width, height): random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) - try: - message.append(pixel) - except IndexError: - yield ''.join(message) - message[2:] = [pixel] - yield ''.join(message) + pixels.append(pixel) def RunClient(options): """Discover the servers and start sending to the first one""" @@ -36,15 +31,20 @@ def RunClient(options): options.width, # Screen pixels wide, None for autodetect options.height # Screen pixels height, None for autodetect ) - message = NewMessage() #create a new message that buffers the output etc # loop the effect until we cancel by pressing ctrl+c / exit the program while True: - # create a new message and send it every time the buffer is full + + # 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 - for packet in RandomFill(message, client.width, client.height): - # send the message we just filled with random pixels - client.SendPacket(packet) + RandomFill(pixels, client.width, client.height) + + # send whatever pixels are left in the packet + pixels.flush() + if __name__ == '__main__': # if this script is called from the command line, and thus not imported diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..da40369 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +gevent==1.2.1 +numpy==1.12.1 +pygame==1.9.3 diff --git a/vloed.py b/vloed.py index fe69a12..6bf9b86 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,11 @@ 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 + +def InitMessage(message): message.append(SetRGBAMode(False)) message.append(SetVersionBit()) return message @@ -299,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),