package controlP5; /** * controlP5 is a processing and java library for creating simple control GUIs. * * 2007 by Andreas Schlegel * * This 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 2.1 * of the License, or (at your option) any later version. * This 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 this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * @author Andreas Schlegel (http://www.sojamo.de) * */ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Field; import java.util.Vector; /** * @invisible */ public class ControlBroadcaster { private Vector _myControllerPlugList; private int _myControlEventType = ControlP5Constants.INVALID; private ControllerPlug _myControlEventPlug = null; private ControlP5 _myControlP5; private String _myEventMethod = "controlEvent"; /** * @invisible * @param theControlP5 * ControlP5 */ protected ControlBroadcaster( ControlP5 theControlP5) { _myControlP5 = theControlP5; _myControllerPlugList = new Vector(); plug("", _myEventMethod); } /** * @param theControllerName * String * @param theTargetMethod * String * @invisible */ public void plug( final String theControllerName, final String theTargetMethod) { if (theTargetMethod.equals(_myEventMethod)) { _myControlEventPlug = checkObject(_myControlP5.papplet, _myEventMethod, new Class[] { ControlEvent.class }); if (_myControlEventPlug != null) { _myControlEventType = ControlP5Constants.METHOD; } return; } Controller myController = _myControlP5.controller(theControllerName); if (myController != null) { myController.setTarget(theTargetMethod); myController.setTargetObject(_myControlP5.papplet); ControllerPlug myControllerPlug = checkObject(_myControlP5.papplet, theTargetMethod, ControlP5Constants.acceptClassList); if (myControllerPlug != null) { if (myController.controllerPlug() == null) { _myControllerPlugList.add(myControllerPlug); myController.setControllerPlug(myControllerPlug); } else { myController.controllerPlug().set(myControllerPlug.object(), myControllerPlug.name(), myControllerPlug.type(), myControllerPlug.parameterType(), ControlP5Constants.acceptClassList); } } } else { System.out.println("### Controller " + theControllerName + " does not exist."); } } /** * @todo parameterCheck erweitern. * @invisible */ protected static ControllerPlug checkObject( final Object theObject, final String theTargetName, final Class[] theAcceptClassList) { Class myClass = theObject.getClass(); Method[] myMethods = myClass.getDeclaredMethods(); for (int i = 0; i < myMethods.length; i++) { if ((myMethods[i].getName()).equals(theTargetName)) { if (myMethods[i].getParameterTypes().length == 1) { for (int j = 0; j < theAcceptClassList.length; j++) { if (myMethods[i].getParameterTypes()[0] == theAcceptClassList[j]) { return new ControllerPlug(theObject, theTargetName, ControlP5Constants.METHOD, j, theAcceptClassList); } } } else if (myMethods[i].getParameterTypes().length == 0) { return new ControllerPlug(theObject, theTargetName, ControlP5Constants.METHOD, -1, theAcceptClassList); } break; } } Field[] myFields = myClass.getDeclaredFields(); for (int i = 0; i < myFields.length; i++) { if ((myFields[i].getName()).equals(theTargetName)) { for (int j = 0; j < theAcceptClassList.length; j++) { if (myFields[i].getType() == theAcceptClassList[j]) { return new ControllerPlug(theObject, theTargetName, ControlP5Constants.FIELD, j, theAcceptClassList); } } break; } } return null; } public void broadcast( final ControlEvent theControlEvent, final int theType) { if (theControlEvent.isTab() == false && theControlEvent.isGroup() == false) { if (theControlEvent.controller().controllerPlug() != null) { if (theType == ControlP5Constants.STRING) { callTarget(theControlEvent.controller().controllerPlug().name(), theControlEvent.stringValue()); } else if (theType == ControlP5Constants.ARRAY) { } else { callTarget(theControlEvent.controller().controllerPlug().name(), theControlEvent.value()); } } } if (_myControlEventType == ControlP5Constants.METHOD) { invokeMethod(_myControlEventPlug.object(), _myControlEventPlug.getMethod(), new Object[] { theControlEvent }); } } /** * * @param theName * String * @param theValue * float */ protected void callTarget( final String theName, final float theValue) { ControllerPlug p; for (int i = 0; i < _myControllerPlugList.size(); i++) { if (((ControllerPlug) _myControllerPlugList.get(i)).checkName(theName)) { p = (ControllerPlug) _myControllerPlugList.get(i); if (p.checkType(ControlP5Constants.METHOD)) { invokeMethod(p.object(), p.getMethod(), p.getMethodParameter(theValue)); } else if (p.checkType(ControlP5Constants.FIELD)) { invokeField(p.object(), p.getField(), p.getFieldParameter(theValue)); } } } } /** * * @param theName * String * @param theValue * String */ protected void callTarget( final String theName, final String theValue) { ControllerPlug p; for (int i = 0; i < _myControllerPlugList.size(); i++) { if (((ControllerPlug) _myControllerPlugList.get(i)).checkName(theName)) { p = (ControllerPlug) _myControllerPlugList.get(i); if (p.checkType(ControlP5Constants.METHOD)) { invokeMethod(p.object(), p.getMethod(), new Object[] { theValue }); } else if (p.checkType(ControlP5Constants.FIELD)) { invokeField(p.object(), p.getField(), theValue); } } } } /** * * @param theObject * Object * @param theField * Field * @param theParam * Object */ private void invokeField( final Object theObject, final Field theField, final Object theParam) { try { theField.set(theObject, theParam); } catch (IllegalAccessException e) { System.out.println("### WARNING @ ControlBroadcaster.invokeField " + e); } } /** * * @param theObject * Object * @param theMethod * Method * @param theParam * Object[] */ private void invokeMethod( final Object theObject, final Method theMethod, final Object[] theParam) { try { if (theParam[0] == null) { theMethod.invoke(theObject, new Object[0]); } else { theMethod.invoke(theObject, theParam); } } catch (IllegalArgumentException e) { System.out.println("### ERROR @ ControlP5.invokeMethod " + theMethod.toString() + " " + theMethod.getName() + " " + theParam.length + " " + e); /** * @todo thrown when plugging a String method/field. */ } catch (IllegalAccessException e) { printMethodError(theMethod, e); } catch (InvocationTargetException e) { printMethodError(theMethod, e); } catch (NullPointerException e) { printMethodError(theMethod, e); } } /** * * @param theMethod * Method * @param theException * Exception */ private void printMethodError( Method theMethod, Exception theException) { System.out.println("ERROR. an error occured while forwarding a Controller value\n " + "to a method in your program. please check your code for any \n" + "possible errors that might occur in this method .\n " + "e.g. check for casting errors, possible nullpointers, array overflows ... .\n" + "method: " + theMethod.getName() + "\n" + "exception: " + theException); } }