mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
fix event handling bugs
This commit is contained in:
@@ -560,15 +560,6 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
redraw = true; // draw this guy once
|
||||
firstMotion = true;
|
||||
|
||||
// these need to be inited before setup
|
||||
sizeMethods = new RegisteredMethods();
|
||||
preMethods = new RegisteredMethods();
|
||||
drawMethods = new RegisteredMethods();
|
||||
postMethods = new RegisteredMethods();
|
||||
mouseEventMethods = new RegisteredMethods();
|
||||
keyEventMethods = new RegisteredMethods();
|
||||
disposeMethods = new RegisteredMethods();
|
||||
|
||||
Context context = getApplicationContext();
|
||||
sketchPath = context.getFilesDir().getAbsolutePath();
|
||||
|
||||
@@ -584,7 +575,7 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
System.out.println("configuration changed: " + newConfig);
|
||||
if (DEBUG) System.out.println("configuration changed: " + newConfig);
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@@ -597,6 +588,7 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
// surfaceView.onResume();
|
||||
if (DEBUG) System.out.println("PApplet.onResume() called");
|
||||
paused = false;
|
||||
handleMethods("resume");
|
||||
//start(); // kick the thread back on
|
||||
resume();
|
||||
// surfaceView.onResume();
|
||||
@@ -607,10 +599,10 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
|
||||
// TODO need to save all application state here!
|
||||
// System.out.println("PApplet.onPause() called");
|
||||
paused = true;
|
||||
handleMethods("pause");
|
||||
pause(); // handler for others to write
|
||||
// synchronized (this) {
|
||||
// paused = true;
|
||||
@@ -1094,51 +1086,69 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
protected RegisteredMethods sizeMethods;
|
||||
protected RegisteredMethods preMethods, drawMethods, postMethods;
|
||||
protected RegisteredMethods mouseEventMethods, keyEventMethods;
|
||||
protected RegisteredMethods disposeMethods;
|
||||
|
||||
public class RegisteredMethods {
|
||||
/** Map of registered methods, stored by name. */
|
||||
HashMap<String, RegisteredMethods> registerMap =
|
||||
new HashMap<String, PApplet.RegisteredMethods>();
|
||||
|
||||
|
||||
class RegisteredMethods {
|
||||
int count;
|
||||
Object objects[];
|
||||
Method methods[];
|
||||
Object[] objects;
|
||||
// Because the Method comes from the class being called,
|
||||
// it will be unique for most, if not all, objects.
|
||||
Method[] methods;
|
||||
Object[] emptyArgs = new Object[] { };
|
||||
|
||||
|
||||
// convenience version for no args
|
||||
public void handle() {
|
||||
handle(new Object[] { });
|
||||
void handle() {
|
||||
handle(emptyArgs);
|
||||
}
|
||||
|
||||
public void handle(Object oargs[]) {
|
||||
|
||||
void handle(Object[] args) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
try {
|
||||
//System.out.println(objects[i] + " " + args);
|
||||
methods[i].invoke(objects[i], oargs);
|
||||
methods[i].invoke(objects[i], args);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// check for wrapped exception, get root exception
|
||||
Throwable t;
|
||||
if (e instanceof InvocationTargetException) {
|
||||
InvocationTargetException ite = (InvocationTargetException) e;
|
||||
t = ite.getCause();
|
||||
} else {
|
||||
t = e;
|
||||
}
|
||||
// check for RuntimeException, and allow to bubble up
|
||||
if (t instanceof RuntimeException) {
|
||||
// re-throw exception
|
||||
throw (RuntimeException) t;
|
||||
} else {
|
||||
// trap and print as usual
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add(Object object, Method method) {
|
||||
if (objects == null) {
|
||||
objects = new Object[5];
|
||||
methods = new Method[5];
|
||||
|
||||
void add(Object object, Method method) {
|
||||
if (findIndex(object) == -1) {
|
||||
if (objects == null) {
|
||||
objects = new Object[5];
|
||||
methods = new Method[5];
|
||||
|
||||
} else if (count == objects.length) {
|
||||
objects = (Object[]) PApplet.expand(objects);
|
||||
methods = (Method[]) PApplet.expand(methods);
|
||||
}
|
||||
objects[count] = object;
|
||||
methods[count] = method;
|
||||
count++;
|
||||
} else {
|
||||
die(method.getName() + "() already added for this instance of " +
|
||||
object.getClass().getName());
|
||||
}
|
||||
if (count == objects.length) {
|
||||
objects = (Object[]) PApplet.expand(objects);
|
||||
methods = (Method[]) PApplet.expand(methods);
|
||||
// Object otemp[] = new Object[count << 1];
|
||||
// System.arraycopy(objects, 0, otemp, 0, count);
|
||||
// objects = otemp;
|
||||
// Method mtemp[] = new Method[count << 1];
|
||||
// System.arraycopy(methods, 0, mtemp, 0, count);
|
||||
// methods = mtemp;
|
||||
}
|
||||
objects[count] = object;
|
||||
methods[count] = method;
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
@@ -1147,8 +1157,10 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
* must be called multiple times if object is registered multiple times).
|
||||
* Does not shrink array afterwards, silently returns if method not found.
|
||||
*/
|
||||
public void remove(Object object, Method method) {
|
||||
int index = findIndex(object, method);
|
||||
// public void remove(Object object, Method method) {
|
||||
// int index = findIndex(object, method);
|
||||
public void remove(Object object) {
|
||||
int index = findIndex(object);
|
||||
if (index != -1) {
|
||||
// shift remaining methods by one to preserve ordering
|
||||
count--;
|
||||
@@ -1162,9 +1174,12 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
protected int findIndex(Object object, Method method) {
|
||||
|
||||
// protected int findIndex(Object object, Method method) {
|
||||
protected int findIndex(Object object) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (objects[i] == object && methods[i].equals(method)) {
|
||||
if (objects[i] == object) {
|
||||
// if (objects[i] == object && methods[i].equals(method)) {
|
||||
//objects[i].equals() might be overridden, so use == for safety
|
||||
// since here we do care about actual object identity
|
||||
//methods[i]==method is never true even for same method, so must use
|
||||
@@ -1177,126 +1192,177 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a built-in event so that it can be fired for libraries, etc.
|
||||
* Supported events include:
|
||||
* <ul>
|
||||
* <li>pre – at the very top of the draw() method (safe to draw)
|
||||
* <li>draw – at the end of the draw() method (safe to draw)
|
||||
* <li>post – after draw() has exited (not safe to draw)
|
||||
* <li>pause() – called when the sketch is paused
|
||||
* <li>resume() – called when the sketch is resumed
|
||||
* <li>dispose – when the sketch is shutting down (definitely not safe to draw)
|
||||
* <ul>
|
||||
* In addition, the new (for 2.0) processing.event classes are passed to
|
||||
* the following event types:
|
||||
* <ul>
|
||||
* <li>mouseEvent
|
||||
* <li>keyEvent
|
||||
* <li>touchEvent
|
||||
* </ul>
|
||||
* The older java.awt events are no longer supported.
|
||||
* See the Library Wiki page for more details.
|
||||
* @param methodName name of the method to be called
|
||||
* @param target the target object that should receive the event
|
||||
*/
|
||||
public void registerMethod(String methodName, Object target) {
|
||||
if (methodName.equals("mouseEvent")) {
|
||||
registerWithArgs("mouseEvent", target, new Class[] { processing.event.MouseEvent.class });
|
||||
|
||||
} else if (methodName.equals("keyEvent")) {
|
||||
registerWithArgs("keyEvent", target, new Class[] { processing.event.KeyEvent.class });
|
||||
|
||||
} else if (methodName.equals("touchEvent")) {
|
||||
registerWithArgs("touchEvent", target, new Class[] { processing.event.TouchEvent.class });
|
||||
|
||||
} else {
|
||||
registerNoArgs(methodName, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void registerNoArgs(String name, Object o) {
|
||||
RegisteredMethods meth = registerMap.get(name);
|
||||
if (meth == null) {
|
||||
meth = new RegisteredMethods();
|
||||
registerMap.put(name, meth);
|
||||
}
|
||||
Class<?> c = o.getClass();
|
||||
try {
|
||||
Method method = c.getMethod(name, new Class[] {});
|
||||
meth.add(o, method);
|
||||
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
die("There is no public " + name + "() method in the class " +
|
||||
o.getClass().getName());
|
||||
|
||||
} catch (Exception e) {
|
||||
die("Could not register " + name + " + () for " + o, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void registerWithArgs(String name, Object o, Class<?> cargs[]) {
|
||||
RegisteredMethods meth = registerMap.get(name);
|
||||
if (meth == null) {
|
||||
meth = new RegisteredMethods();
|
||||
registerMap.put(name, meth);
|
||||
}
|
||||
Class<?> c = o.getClass();
|
||||
try {
|
||||
Method method = c.getMethod(name, cargs);
|
||||
meth.add(o, method);
|
||||
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
die("There is no public " + name + "() method in the class " +
|
||||
o.getClass().getName());
|
||||
|
||||
} catch (Exception e) {
|
||||
die("Could not register " + name + " + () for " + o, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public void registerMethod(String methodName, Object target, Object... args) {
|
||||
// registerWithArgs(methodName, target, args);
|
||||
// }
|
||||
|
||||
|
||||
public void unregisterMethod(String name, Object target) {
|
||||
RegisteredMethods meth = registerMap.get(name);
|
||||
if (meth == null) {
|
||||
die("No registered methods with the name " + name + "() were found.");
|
||||
}
|
||||
try {
|
||||
// Method method = o.getClass().getMethod(name, new Class[] {});
|
||||
// meth.remove(o, method);
|
||||
meth.remove(target);
|
||||
} catch (Exception e) {
|
||||
die("Could not unregister " + name + "() for " + target, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void handleMethods(String methodName) {
|
||||
RegisteredMethods meth = registerMap.get(methodName);
|
||||
if (meth != null) {
|
||||
meth.handle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void registerSize(Object o) {
|
||||
Class<?> methodArgs[] = new Class[] { Integer.TYPE, Integer.TYPE };
|
||||
registerWithArgs(sizeMethods, "size", o, methodArgs);
|
||||
System.err.println("The registerSize() command is no longer supported.");
|
||||
// Class<?> methodArgs[] = new Class[] { Integer.TYPE, Integer.TYPE };
|
||||
// registerWithArgs(sizeMethods, "size", o, methodArgs);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void registerPre(Object o) {
|
||||
registerNoArgs(preMethods, "pre", o);
|
||||
registerNoArgs("pre", o);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void registerDraw(Object o) {
|
||||
registerNoArgs(drawMethods, "draw", o);
|
||||
registerNoArgs("draw", o);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void registerPost(Object o) {
|
||||
registerNoArgs(postMethods, "post", o);
|
||||
}
|
||||
|
||||
public void registerMouseEvent(Object o) {
|
||||
// Class<?> methodArgs[] = new Class[] { MouseEvent.class };
|
||||
// registerWithArgs(mouseEventMethods, "mouseEvent", o, methodArgs);
|
||||
registerNoArgs("post", o);
|
||||
}
|
||||
|
||||
|
||||
public void registerKeyEvent(Object o) {
|
||||
Class<?> methodArgs[] = new Class[] { KeyEvent.class };
|
||||
registerWithArgs(keyEventMethods, "keyEvent", o, methodArgs);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void registerDispose(Object o) {
|
||||
//registerNoArgs(disposeMethods, "dispose", o);
|
||||
}
|
||||
|
||||
|
||||
protected void registerNoArgs(RegisteredMethods meth,
|
||||
String name, Object o) {
|
||||
Class<?> c = o.getClass();
|
||||
try {
|
||||
Method method = c.getMethod(name, new Class[] {});
|
||||
meth.add(o, method);
|
||||
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
die("There is no public " + name + "() method in the class " +
|
||||
o.getClass().getName());
|
||||
|
||||
} catch (Exception e) {
|
||||
die("Could not register " + name + " + () for " + o, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void registerWithArgs(RegisteredMethods meth,
|
||||
String name, Object o, Class<?> cargs[]) {
|
||||
Class<?> c = o.getClass();
|
||||
try {
|
||||
Method method = c.getMethod(name, cargs);
|
||||
meth.add(o, method);
|
||||
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
die("There is no public " + name + "() method in the class " +
|
||||
o.getClass().getName());
|
||||
|
||||
} catch (Exception e) {
|
||||
die("Could not register " + name + " + () for " + o, e);
|
||||
}
|
||||
registerNoArgs("dispose", o);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void unregisterSize(Object o) {
|
||||
Class<?> methodArgs[] = new Class[] { Integer.TYPE, Integer.TYPE };
|
||||
unregisterWithArgs(sizeMethods, "size", o, methodArgs);
|
||||
System.err.println("The unregisterSize() command is no longer supported.");
|
||||
// Class<?> methodArgs[] = new Class[] { Integer.TYPE, Integer.TYPE };
|
||||
// unregisterWithArgs(sizeMethods, "size", o, methodArgs);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void unregisterPre(Object o) {
|
||||
unregisterNoArgs(preMethods, "pre", o);
|
||||
unregisterMethod("pre", o);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void unregisterDraw(Object o) {
|
||||
unregisterNoArgs(drawMethods, "draw", o);
|
||||
unregisterMethod("draw", o);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void unregisterPost(Object o) {
|
||||
unregisterNoArgs(postMethods, "post", o);
|
||||
unregisterMethod("post", o);
|
||||
}
|
||||
|
||||
public void unregisterMouseEvent(Object o) {
|
||||
// Class<?> methodArgs[] = new Class[] { MouseEvent.class };
|
||||
// unregisterWithArgs(mouseEventMethods, "mouseEvent", o, methodArgs);
|
||||
}
|
||||
|
||||
public void unregisterKeyEvent(Object o) {
|
||||
Class<?> methodArgs[] = new Class[] { KeyEvent.class };
|
||||
unregisterWithArgs(keyEventMethods, "keyEvent", o, methodArgs);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void unregisterDispose(Object o) {
|
||||
unregisterNoArgs(disposeMethods, "dispose", o);
|
||||
}
|
||||
|
||||
|
||||
protected void unregisterNoArgs(RegisteredMethods meth,
|
||||
String name, Object o) {
|
||||
Class<?> c = o.getClass();
|
||||
try {
|
||||
Method method = c.getMethod(name, new Class[] {});
|
||||
meth.remove(o, method);
|
||||
} catch (Exception e) {
|
||||
die("Could not unregister " + name + "() for " + o, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void unregisterWithArgs(RegisteredMethods meth,
|
||||
String name, Object o, Class<?> cargs[]) {
|
||||
Class<?> c = o.getClass();
|
||||
try {
|
||||
Method method = c.getMethod(name, cargs);
|
||||
meth.remove(o, method);
|
||||
} catch (Exception e) {
|
||||
die("Could not unregister " + name + "() for " + o, e);
|
||||
}
|
||||
unregisterMethod("dispose", o);
|
||||
}
|
||||
|
||||
|
||||
@@ -1876,6 +1942,10 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
float instantaneousRate = (float) rate / 1000.0f;
|
||||
frameRate = (frameRate * 0.9f) + (instantaneousRate * 0.1f);
|
||||
|
||||
if (frameCount != 0) {
|
||||
handleMethods("pre");
|
||||
}
|
||||
|
||||
// use dmouseX/Y as previous mouse pos, since this is the
|
||||
// last position the mouse was in during the previous draw.
|
||||
pmouseX = dmouseX;
|
||||
@@ -1900,13 +1970,17 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
dequeueMotionEvents();
|
||||
dequeueKeyEvents();
|
||||
|
||||
handleMethods("draw");
|
||||
|
||||
redraw = false; // unset 'redraw' flag in case it was set
|
||||
// (only do this once draw() has run, not just setup())
|
||||
|
||||
}
|
||||
|
||||
g.endDraw();
|
||||
|
||||
if (frameCount != 0) {
|
||||
handleMethods("post");
|
||||
}
|
||||
|
||||
frameRateLastNanos = now;
|
||||
frameCount++;
|
||||
}
|
||||
@@ -2746,7 +2820,7 @@ public class PApplet extends Activity implements PConstants, Runnable {
|
||||
// call to shut down renderer, in case it needs it (pdf does)
|
||||
if (g != null) g.dispose();
|
||||
|
||||
disposeMethods.handle();
|
||||
handleMethods("dispose");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012 The Processing Foundation
|
||||
|
||||
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, version 2.1.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
package processing.event;
|
||||
|
||||
|
||||
public class KeyEvent {
|
||||
Object nativeObject;
|
||||
|
||||
char key;
|
||||
int keyCode;
|
||||
|
||||
|
||||
public KeyEvent(Object nativeObject) {
|
||||
this.nativeObject = nativeObject;
|
||||
}
|
||||
|
||||
|
||||
public Object getNative() {
|
||||
return nativeObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012 The Processing Foundation
|
||||
|
||||
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, version 2.1.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
package processing.event;
|
||||
|
||||
|
||||
public class MouseEvent {
|
||||
Object nativeObject;
|
||||
|
||||
int x, y;
|
||||
|
||||
|
||||
public MouseEvent(Object nativeObject) {
|
||||
this.nativeObject = nativeObject;
|
||||
}
|
||||
|
||||
|
||||
public Object getNative() {
|
||||
return nativeObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012 The Processing Foundation
|
||||
|
||||
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, version 2.1.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
package processing.event;
|
||||
|
||||
|
||||
public class TouchEvent {
|
||||
Object nativeObject;
|
||||
|
||||
float x, y;
|
||||
|
||||
|
||||
public TouchEvent(Object nativeObject) {
|
||||
this.nativeObject = nativeObject;
|
||||
}
|
||||
|
||||
|
||||
public Object getNative() {
|
||||
return nativeObject;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user