/** * Squidy Interaction Library is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * Squidy Interaction Library is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squidy Interaction Library. If not, see * <http://www.gnu.org/licenses/>. * * 2009 Human-Computer Interaction Group, University of Konstanz. * <http://hci.uni-konstanz.de> * * Please contact info@squidy-lib.de or visit our website * <http://www.squidy-lib.de> for further information. */ package org.squidy.nodes; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.squidy.manager.controls.ComboBox; import org.squidy.manager.controls.TextField; import org.squidy.manager.data.DataConstant; import org.squidy.manager.data.IData; import org.squidy.manager.data.IDataContainer; import org.squidy.manager.data.Processor; import org.squidy.manager.data.Property; import org.squidy.manager.data.Throughput; import org.squidy.manager.data.domainprovider.impl.EndianDomainProvider; import org.squidy.manager.data.impl.DataDigital; import org.squidy.manager.data.impl.DataObject; import org.squidy.manager.data.impl.DataPosition2D; import org.squidy.manager.model.AbstractNode; import org.squidy.manager.protocol.osc.OSCServer; import com.illposed.osc.Endian; import com.illposed.osc.OSCBundle; import com.illposed.osc.OSCMessage; /** * <code>BubbleGame</code>. * * <pre> * Date: Sep 26, 2008 * Time: 12:35:13 AM * </pre> * * @author Roman Rädle, <a * href="mailto:Roman.Raedle@uni-konstanz.de">Roman.Raedle@uni-konstanz.de</a>, * University of Konstanz * @version $Id: BubbleGame.java 772 2011-09-16 15:39:44Z raedle $ * @since 1.1.0 */ @XmlType(name = "Bubble Game") @Processor( name = "Bubble Game", types = { Processor.Type.OUTPUT }, description = "/org/squidy/nodes/html/BubbleGame.html", tags = {} ) public class BubbleGame extends AbstractNode { // Log to log info, error, debug,... messages. private static final Log LOG = LogFactory.getLog(BubbleGame.class); // ################################################################################ // BEGIN OF ADJUSTABLES // ################################################################################ @XmlAttribute(name = "osc-outgoing-address") @Property( name = "OSC outgoing address", description = "The outgoing address for the open-sound-control server." ) @TextField private String oscOutgoingAddress = "127.0.0.1"; /** * @return the oscOutgoingAddress */ public final String getOscOutgoingAddress() { return oscOutgoingAddress; } /** * @param oscOutgoingAddress the oscOutgoingAddress to set */ public final void setOscOutgoingAddress(String oscOutgoingAddress) { this.oscOutgoingAddress = oscOutgoingAddress; if (oscServer != null) { // Restart the osc server with new endian strategy. stopOSCServer(); startOSCServer(); } } @XmlAttribute(name = "osc-outgoing-port") @Property( name = "OSC outgoing port", description = "The outgoing port for the open-sound-control server." ) @TextField private int oscOutgoingPort = 7777; /** * @return the oscOutgoingPort */ public final int getOscOutgoingPort() { return oscOutgoingPort; } /** * @param oscOutgoingPort the oscOutgoingPort to set */ public final void setOscOutgoingPort(int oscOutgoingPort) { this.oscOutgoingPort = oscOutgoingPort; if (oscServer != null) { // Restart the osc server with new endian strategy. stopOSCServer(); startOSCServer(); } } @XmlAttribute(name = "endian") @Property( name = "Endian", description = "Indicates which endian strategy will be used to identify bytes or not." ) @ComboBox(domainProvider = EndianDomainProvider.class) private Endian endian = Endian.BIG_ENDIAN; /** * @return the endian */ public final Endian getEndian() { return endian; } /** * @param endian * the endian to set */ public final void setEndian(Endian endian) { this.endian = endian; if (oscServer != null) { // Restart the osc server with new endian strategy. stopOSCServer(); startOSCServer(); } } // ################################################################################ // END OF ADJUSTABLES // ################################################################################ private Map<Integer, Boolean> lastButtonState = new HashMap<Integer, Boolean>(); private OSCServer oscServer; /* (non-Javadoc) * @see org.squidy.manager.ReflectionProcessable#onStart() */ @Override public void onStart() { startOSCServer(); } /* (non-Javadoc) * @see org.squidy.manager.ReflectionProcessable#onStop() */ @Override public void onStop() { stopOSCServer(); } /** * */ protected void startOSCServer() { oscServer = new OSCServer(oscOutgoingAddress, oscOutgoingPort, endian); } /** * */ protected void stopOSCServer() { if (oscServer != null) { oscServer.stopListening(); oscServer.close(); } } /* (non-Javadoc) * @see org.squidy.manager.data.logic.ReflectionProcessable#beforeDataContainerProcessing(org.squidy.manager.data.IDataContainer) */ @Override public IDataContainer preProcess(IDataContainer dataContainer) { List<DataPosition2D> dataPositions2D = new ArrayList<DataPosition2D>(); for (IData data : dataContainer.getData()) { if (data instanceof DataPosition2D) { dataPositions2D.add((DataPosition2D) data); } else if (data instanceof DataDigital) { lastButtonState.put((Integer) data.getAttribute(DataConstant.DEVICE_ID), ((DataDigital) data).getFlag()); } } sendPositions(dataPositions2D.toArray(new DataPosition2D[dataPositions2D.size()]), new Date(dataContainer.getTimestamp())); return super.preProcess(dataContainer); } /** * @param positions * @param timestamp */ private void sendPositions(DataPosition2D[] positions, Date timestamp) { OSCBundle bundle = new OSCBundle(timestamp); for (DataPosition2D dataPosition2D : positions) { OSCMessage message = new OSCMessage("/squidy/2f1b"); Integer deviceId = (Integer) dataPosition2D.getAttribute(DataConstant.DEVICE_ID); if (deviceId == null) { deviceId = -1; } Boolean buttonState = lastButtonState.get((Integer) dataPosition2D.getAttribute(DataConstant.DEVICE_ID)); if (buttonState == null) { buttonState = Boolean.FALSE; } int fingerID = -1; Object fingerO = dataPosition2D.getAttribute(DataConstant.SESSION_ID); if(fingerO!=null) fingerID = (Integer) fingerO; // System.out.println("Finger "+fingerID); message.addArgument((float) dataPosition2D.getX()); message.addArgument((float) dataPosition2D.getY()); message.addArgument(deviceId); message.addArgument(fingerID); message.addArgument(buttonState); bundle.addPacket(message); } oscServer.send(bundle); } }