Skip to content

Commit

Permalink
Add selectable 8-bit or 16-bit colour support to LXOutput.
Browse files Browse the repository at this point in the history
  • Loading branch information
zestyping committed Apr 30, 2018
1 parent 0b49823 commit 57892ac
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 117 deletions.
9 changes: 9 additions & 0 deletions src/heronarts/lx/PolyBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ public void copyFrom(PolyBuffer src, Space space) {
@Deprecated
private static final Space DEFAULT_SPACE = Space.RGB8;

@Deprecated
public static PolyBuffer wrapArray(LX lx, final int[] array) {
PolyBuffer buffer = new PolyBuffer(lx);
buffer.setBuffer(new Buffer() {
public Object getArray() { return array; }
});
return buffer;
}

@Deprecated
public Buffer getBuffer() {
return getBuffer(DEFAULT_SPACE);
Expand Down
2 changes: 1 addition & 1 deletion src/heronarts/lx/color/LXColor16.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public static long hsb(float h, float s, float b) {
* @param brightness Brightness from 0.0 - 1.0
* @return RGB color value
*/
private static long scaledHsbToRgb(float hue, float saturation, float brightness) {
public static long scaledHsbToRgb(float hue, float saturation, float brightness) {
int r = 0, g = 0, b = 0;
if (saturation == 0) {
r = g = b = (int) (brightness*65535.0f + 0.5f);
Expand Down
61 changes: 55 additions & 6 deletions src/heronarts/lx/output/LXDatagram.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

package heronarts.lx.output;

import heronarts.lx.PolyBuffer;
import heronarts.lx.color.LXColor16;
import heronarts.lx.parameter.BooleanParameter;

import java.net.DatagramPacket;
Expand Down Expand Up @@ -125,7 +127,7 @@ public LXDatagram setPort(int port) {

/**
* Helper for subclasses to copy a list of points into the data buffer at a
* specified offset. For many subclasses which wrap RGB buffers, onSend() will
* specified offset. For many subclasses that wrap RGB buffers, onSend() will
* be a simple call to this method with the right parameters.
*
* @param colors Array of color values
Expand All @@ -147,11 +149,58 @@ protected LXDatagram copyPoints(int[] colors, int[] pointIndices, int offset) {
}

/**
* Invoked by engine to send this packet when new color data is available. The
* LXDatagram should update the packet object accordingly to contain the
* appropriate buffer.
* Helper for subclasses to copy 16-bit colors into the data buffer at a
* specified offset. For many subclasses that wrap RGB buffers, onSend() will
* be a simple call to this method with the right parameters.
*
* @param colors Color buffer
* @param colors16 Array of color values
* @param pointIndices Array of point indices
* @param dest Destination buffer to write into
* @param offset Offset in destination buffer to write
* @return this
*/
protected LXDatagram copyPoints16(long[] colors16, int[] pointIndices, byte[] dest, int offset) {
int i = offset;
int[] byteOffset = BYTE_ORDERING[this.byteOrder.ordinal()];
for (int index : pointIndices) {
long c = (index >= 0) ? colors16[index] : 0;
int red = LXColor16.red(c);
int green = LXColor16.green(c);
int blue = LXColor16.blue(c);
dest[i + byteOffset[0]] = (byte) (red >>> 8);
dest[i + byteOffset[0] + 1] = (byte) (red & 0xff);
dest[i + byteOffset[1]] = (byte) (green >>> 8);
dest[i + byteOffset[1] + 1] = (byte) (green & 0xff);
dest[i + byteOffset[2]] = (byte) (blue >>> 8);
dest[i + byteOffset[2] + 1] = (byte) (blue & 0xff);
i += 6;
}
return this;
}

/**
* Old-style subclasses override this method to populate the datagram
* packet with 8-bit color data. New-style subclasses should override
* onSend(PolyBuffer) instead.
* @param colors 8-bit color values
*/
public abstract void onSend(int[] colors);
@Deprecated
protected /* abstract */ void onSend(int[] colors) { }

/**
* Invoked by engine to send this packet when new color data is available.
* Implementations of this method should update the datagram packet
* accordingly to contain the data to send on the wire.
* @param src The color data to send.
*/
public /* abstract */ void onSend(PolyBuffer src) {
// For compatibility, this invokes the method that previous subclasses
// were supposed to implement. Implementations of onSend(int[]) know
// only how to send 8-bit color data, so that's what we pass to them.
onSend((int[]) src.getArray(PolyBuffer.Space.RGB8));

// New subclasses should override and replace this method with one that
// obtains a color array in the desired space using src.getArray(space),
// and populates the packed with data based on that array.
}
}
53 changes: 42 additions & 11 deletions src/heronarts/lx/output/LXDatagramOutput.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package heronarts.lx.output;

import heronarts.lx.LX;
import heronarts.lx.PolyBuffer;

import java.io.IOException;
import java.net.DatagramSocket;
Expand Down Expand Up @@ -72,29 +73,59 @@ public LXDatagramOutput addDatagrams(LXDatagram[] datagrams) {
}

/**
* Subclasses may override. Invoked before datagrams are sent.
*
* Old-style subclasses override this method if they want to do
* something before datagrams are sent. New-style subclasses should
* override beforeSend(PolyBuffer) insteaad.
* @param colors Color values
*/
protected /* abstract */ void beforeSend(int[] colors) {}
@Deprecated
protected /* abstract */ void beforeSend(int[] colors) { }

/**
* Subclasses may override. Invoked after datagrams are sent.
*
* Old-style subclasses override this method if they want to do
* something after datagrams are sent. New-style subclasses should
* override afterSend(PolyBuffer) insteaad.
* @param colors Color values
*/
protected /* abstract */ void afterSend(int[] colors) {}
@Deprecated
protected /* abstract */ void afterSend(int[] colors) { }

/**
* Subclasses may override. Invoked before datagrams are sent.
* @param src The color data to be sent.
*/
protected /* abstract */ void beforeSend(PolyBuffer src) {
// For compatibility, this invokes the method that previous subclasses
// were supposed to implement. Implementations of beforeSend(int[])
// know only how to handle 8-bit color data, so that's what we pass to them.
beforeSend((int[]) src.getArray(PolyBuffer.Space.RGB8));

// New subclasses that want to use this hook should override and
// replace this method.
}

/**
* Core method which sends the datagrams.
* Subclasses may override. Invoked after datagrams are sent.
* @param src The color data that was just sent.
*/
protected /* abstract */ void afterSend(PolyBuffer src) {
// For compatibility, this invokes the method that previous subclasses
// were supposed to implement. Implementations of beforeSend(int[])
// know only how to handle 8-bit color data, so that's what we pass to them.
afterSend((int[]) src.getArray(PolyBuffer.Space.RGB8));

// New subclasses that want to use this hook should override and
// replace this method.
}

/** Populates the datagrams with packet data and sends them out. */
@Override
protected final void onSend(int[] colors) {
protected void onSend(PolyBuffer src) {
long now = System.currentTimeMillis();
beforeSend(colors);
beforeSend(src);
for (LXDatagram datagram : this.datagrams) {
if (datagram.enabled.isOn() && (now > datagram.destination.sendAfter)) {
datagram.onSend(colors);
datagram.onSend(src);
try {
this.socket.send(datagram.packet);
if (datagram.destination.failureCount > 0) {
Expand Down Expand Up @@ -122,6 +153,6 @@ protected final void onSend(int[] colors) {
}
}
}
afterSend(colors);
afterSend(src);
}
}
Loading

0 comments on commit 57892ac

Please sign in to comment.