X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=OpenPixelControl.pde;h=0525d9013dce9f71f5bd813ffec078414e486f86;hb=HEAD;hp=118eb2a56cf10a20b7e1cc3c229d3c77d435068e;hpb=3ffd6241fa4f38d82cdb4dca434ca04b1edc9ccd;p=SugarCubes.git diff --git a/OpenPixelControl.pde b/OpenPixelControl.pde index 118eb2a..0525d90 100644 --- a/OpenPixelControl.pde +++ b/OpenPixelControl.pde @@ -1,77 +1,102 @@ -import processing.net.*; + +import java.io.*; +import java.net.*; // Server for Open Pixel Control patterns (http://openpixelcontrol.org/) -class OpenPixelControl extends SCPattern { +class OpenPixelControl extends SCPattern implements Runnable { int port = 7890; - - Server server; + Thread thread; + ServerSocket server; byte[] buffer; int bufferedByteCount; public OpenPixelControl(LX lx, PApplet parent) { super(lx); - server = new Server(parent, port); - println("Listening for Open Pixel Control data on port " + port); + parent.registerMethod("dispose", this); + + // Save a JSON layout file that some Open Pixel Control clients can use + writeMappingFile("openpixelcontrol-layout.json"); // Buffer space for two frames, worst case buffer = new byte[0x10004 * 2]; bufferedByteCount = 0; - - // Save a JSON layout file that some Open Pixel Control clients can use - writeMappingFile("openpixelcontrol-layout.json"); } - public void run(double deltaMs) { - readFromClient(); + public void dispose() { + thread = null; + if (server != null) { + try { + server.close(); + } catch (IOException e) { + e.printStackTrace(); + } + server = null; + } } - void readFromClient() { - Client client = server.available(); - - if (client == null) { - // No client; flush any stored partial frames - bufferedByteCount = 0; - return; - } + public void run() { + // Thread run function; handle OPC traffic. + while (Thread.currentThread() == thread) { + + try { + Socket cli = server.accept(); + InputStream input = cli.getInputStream(); + bufferedByteCount = 0; + + while (Thread.currentThread() == thread) { + + int r = input.read(buffer, bufferedByteCount, buffer.length - bufferedByteCount); + if (r <= 0) { + break; + } + bufferedByteCount += r; + + // Extract OPC packets from buffer + int offset = 0; + while (bufferedByteCount - offset >= 4) { + int channel = buffer[offset + 0] & 0xFF; + int command = buffer[offset + 1] & 0xFF; + int length = ((buffer[offset + 2] & 0xFF) << 8) | (buffer[offset + 3] & 0xFF); + + if (bufferedByteCount - offset < length + 4) { + // Not enough data for a full packet yet + break; + } + + // Handle the packet in-place + offset += 4; + opcPacket(channel, command, offset, length); + offset += length; + } + + // If we didn't use the whole buffer, save remainder for later + bufferedByteCount -= offset; + arrayCopy(buffer, offset, buffer, 0, bufferedByteCount); + } - while (true) { - int available = client.available(); - if (available <= 0) { - return; - } + cli.close(); - if (bufferedByteCount == 0) { - // Read directly to buffer - bufferedByteCount = client.readBytes(buffer); - } else { - // Append to an earlier partial frame - byte[] additional = client.readBytes(); - arrayCopy(additional, 0, buffer, bufferedByteCount, additional.length); - bufferedByteCount += additional.length; + } catch (IOException e) { + e.printStackTrace(); } + } + } - // Extract OPC packets from buffer - int offset = 0; - while (bufferedByteCount - offset >= 4) { - int channel = buffer[offset + 0] & 0xFF; - int command = buffer[offset + 1] & 0xFF; - int length = ((buffer[offset + 2] & 0xFF) << 8) | (buffer[offset + 3] & 0xFF); - - if (bufferedByteCount - offset < length + 4) { - // Not enough data for a full packet yet - break; - } - - // Handle the packet in-place - offset += 4; - opcPacket(channel, command, offset, length); - offset += length; + public void run(double deltaMs) { + // SCPattern run function; nothing to do except start our thread the first time. + + if (server == null) { + try { + server = new ServerSocket(this.port); + thread = new Thread(this); + thread.start(); + println("Listening for Open Pixel Control data on port " + port); + + } catch (IOException e) { + e.printStackTrace(); + thread = null; } - - // If we didn't use the whole buffer, save remainder for later - bufferedByteCount -= offset; - arrayCopy(buffer, offset, buffer, 0, bufferedByteCount); } }