mirror of
https://github.com/opus-tango/B12NumbersV3.git
synced 2026-03-20 03:55:20 +00:00
Mouse handling changes
Method relay now uses weak references rather than strong references. This gets rid of the dangling button memory leak
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
class MouseHandler {
|
class MouseHandler {
|
||||||
MouseData md;
|
private MouseData md;
|
||||||
private LiveMethodRelay[] mrs;
|
private LiveMethodRelay[] mrs;
|
||||||
|
|
||||||
MouseHandler(MouseData _md) {
|
MouseHandler(MouseData _md) {
|
||||||
@@ -7,11 +7,13 @@ class MouseHandler {
|
|||||||
mrs = new LiveMethodRelay[0];
|
mrs = new LiveMethodRelay[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PASSTHROUGH FOR MOUSE DATA //
|
||||||
float sMouseX(){return md.sMouseX();}
|
float sMouseX(){return md.sMouseX();}
|
||||||
float sMouseY(){return md.sMouseY();}
|
float sMouseY(){return md.sMouseY();}
|
||||||
float pSMouseX(){return md.pSMouseX();}
|
float pSMouseX(){return md.pSMouseX();}
|
||||||
float pSMouseY(){return md.pSMouseY();}
|
float pSMouseY(){return md.pSMouseY();}
|
||||||
void frameUpdate(PVector offset, float scale){md.update(offset, scale);}
|
void frameUpdate(PVector offset, float scale){md.update(offset, scale); println(mrs.length + " " + millis());}
|
||||||
|
|
||||||
|
|
||||||
void addRelay(LiveMethodRelay r) {
|
void addRelay(LiveMethodRelay r) {
|
||||||
clean();
|
clean();
|
||||||
@@ -30,6 +32,7 @@ class MouseHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cascade(char tag, float... data) {
|
void cascade(char tag, float... data) {
|
||||||
|
clean();
|
||||||
for (int i = 0; i < mrs.length; i++) {
|
for (int i = 0; i < mrs.length; i++) {
|
||||||
if(mrs[i].getTag() == tag){
|
if(mrs[i].getTag() == tag){
|
||||||
mrs[i].execute(data);
|
mrs[i].execute(data);
|
||||||
@@ -97,15 +100,18 @@ class LiveMethodRelay extends MethodRelay {
|
|||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
|
import java.lang.ref.*;
|
||||||
/**
|
/**
|
||||||
A class that encapsulates a named method to be invoked.
|
A class that encapsulates a named method to be invoked.
|
||||||
Quark 2015
|
Quark 2015
|
||||||
see https://forum.processing.org/two/discussion/13093/how-to-call-function-by-string-content.html
|
see https://forum.processing.org/two/discussion/13093/how-to-call-function-by-string-content.html
|
||||||
|
Modified to use weak references
|
||||||
*/
|
*/
|
||||||
public static class MethodRelay {
|
public static class MethodRelay {
|
||||||
|
|
||||||
/** The object to handle the draw event */
|
/** The object to handle the draw event */
|
||||||
private Object handlerObject = null;
|
private WeakReference reference = null;
|
||||||
|
//private Object handlerObject = null;
|
||||||
/** The method in drawHandlerObject to execute */
|
/** The method in drawHandlerObject to execute */
|
||||||
private Method handlerMethod = null;
|
private Method handlerMethod = null;
|
||||||
/** the name of the method to handle the event */
|
/** the name of the method to handle the event */
|
||||||
@@ -125,7 +131,7 @@ public static class MethodRelay {
|
|||||||
handlerMethodName = name;
|
handlerMethodName = name;
|
||||||
parameters = args;
|
parameters = args;
|
||||||
handlerMethod = obj.getClass().getMethod(handlerMethodName, parameters);
|
handlerMethod = obj.getClass().getMethod(handlerMethodName, parameters);
|
||||||
handlerObject = obj;
|
reference = new WeakReference(obj);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
println("Unable to find the function -");
|
println("Unable to find the function -");
|
||||||
@@ -160,9 +166,9 @@ public static class MethodRelay {
|
|||||||
to be passed to the method
|
to be passed to the method
|
||||||
*/
|
*/
|
||||||
void execute(Object... data) {
|
void execute(Object... data) {
|
||||||
if (handlerObject != null) {
|
if (reference.get() != null) {
|
||||||
try {
|
try {
|
||||||
handlerMethod.invoke(handlerObject, data);
|
handlerMethod.invoke(reference.get(), data);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
println("Error on invoke");
|
println("Error on invoke");
|
||||||
|
|||||||
@@ -3,15 +3,16 @@ float scale = 2;
|
|||||||
PVector offset;
|
PVector offset;
|
||||||
public static final int DECIMAL = 65;
|
public static final int DECIMAL = 65;
|
||||||
MouseHandler mh; // Mouse event handler
|
MouseHandler mh; // Mouse event handler
|
||||||
//MouseData md;
|
|
||||||
|
|
||||||
Calculator calc;
|
Calculator calc;
|
||||||
|
Button b;
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
size(400,400);
|
size(400,400);
|
||||||
offset = new PVector(width/2, height/2);
|
offset = new PVector(width/2, height/2);
|
||||||
mh = new MouseHandler(new MouseData(offset, scale));
|
mh = new MouseHandler(new MouseData(offset, scale));
|
||||||
//md = new MouseData(offset, scale);
|
b = new Button(mh, new PVector(20,-20), new PVector(20,20));
|
||||||
|
b.setFunction(new MethodRelay(this, "changeMode"));
|
||||||
|
|
||||||
calc = new Calculator(mh);
|
calc = new Calculator(mh);
|
||||||
|
|
||||||
@@ -23,7 +24,8 @@ void draw(){
|
|||||||
translate(offset.x,offset.y);
|
translate(offset.x,offset.y);
|
||||||
scale(scale);
|
scale(scale);
|
||||||
|
|
||||||
calc.display();
|
if(calc != null) calc.display();
|
||||||
|
b.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseClicked(){
|
void mouseClicked(){
|
||||||
@@ -31,11 +33,20 @@ void mouseClicked(){
|
|||||||
mh.cascade('c', mh.sMouseX(), mh.sMouseY(), mouseButton);
|
mh.cascade('c', mh.sMouseX(), mh.sMouseY(), mouseButton);
|
||||||
}
|
}
|
||||||
void mouseMoved(){mh.cascade('m', mh.sMouseX(), mh.sMouseY());}
|
void mouseMoved(){mh.cascade('m', mh.sMouseX(), mh.sMouseY());}
|
||||||
void mousePressed(){mh.cascade('m', mh.sMouseX(), mh.sMouseY(), mouseButton);}
|
void mousePressed(){mh.cascade('p', mh.sMouseX(), mh.sMouseY(), mouseButton);}
|
||||||
void mouseReleased(){mh.cascade('m', mh.sMouseX(), mh.sMouseY(), mouseButton);}
|
void mouseReleased(){mh.cascade('r', mh.sMouseX(), mh.sMouseY(), mouseButton);}
|
||||||
void mouseWheel(MouseEvent event){mh.cascade('m', mh.sMouseX(), mh.sMouseY(), event.getCount());}
|
void mouseWheel(MouseEvent event){mh.cascade('w', mh.sMouseX(), mh.sMouseY(), event.getCount());}
|
||||||
void mouseDragged(){mh.cascade('m', mh.sMouseX(), mh.sMouseY(), mouseButton);}
|
void mouseDragged(){mh.cascade('d', mh.sMouseX(), mh.sMouseY(), mouseButton);}
|
||||||
|
|
||||||
void call(String _call){
|
void call(String _call){
|
||||||
method(_call);
|
method(_call);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void changeMode(){
|
||||||
|
if(calc == null){
|
||||||
|
calc = new Calculator(mh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
calc = null;
|
||||||
|
Runtime.getRuntime().gc();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
class Button{ // TODO make most of the attributes private
|
class Button{ // TODO make most of the attributes private
|
||||||
MouseHandler mh;
|
private LiveMethodRelay listener;
|
||||||
PVector pos; // Position to render from
|
private MouseHandler mh;
|
||||||
PVector dim; // Second coordinate for CORNERS or len/wid for CORNER and CENTER
|
private PVector pos; // Position to render from
|
||||||
float radius; // Optional corner radius
|
private PVector dim; // Second coordinate for CORNERS or len/wid for CORNER and CENTER
|
||||||
int mode; // Stores rect draw mode for button
|
private float radius; // Optional corner radius
|
||||||
color col; // Stores static color
|
private int mode; // Stores rect draw mode for button
|
||||||
color highlight; // Stores mouseover color
|
private color col; // Stores static color
|
||||||
MethodRelay function; // Gets called when button is pressed
|
private color highlight; // Stores mouseover color
|
||||||
boolean mouseOver;
|
private MethodRelay function; // Gets called when button is pressed
|
||||||
Object[] data; // Anything that gets passed to MethodRelay function when key pressed. Must be set manually
|
private boolean mouseOver;
|
||||||
|
private Object[] data; // Anything that gets passed to MethodRelay function when key pressed. Must be set manually
|
||||||
|
|
||||||
Button(MouseHandler _mh, PVector _pos, PVector _dim, float _radius){
|
Button(MouseHandler _mh, PVector _pos, PVector _dim, float _radius){
|
||||||
mh = _mh;
|
mh = _mh;
|
||||||
@@ -19,7 +20,8 @@ class Button{ // TODO make most of the attributes private
|
|||||||
col = color(200);
|
col = color(200);
|
||||||
highlight = color(100);
|
highlight = color(100);
|
||||||
mouseOver = false;
|
mouseOver = false;
|
||||||
mh.addRelay(new LiveMethodRelay(this, "clicked", 'c', Object.class));
|
listener = new LiveMethodRelay(this, "clicked", 'p', Object.class);
|
||||||
|
mh.addRelay(listener);
|
||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
Button(MouseHandler _mh, PVector _pos, PVector _dim){
|
Button(MouseHandler _mh, PVector _pos, PVector _dim){
|
||||||
@@ -121,4 +123,12 @@ class Button{ // TODO make most of the attributes private
|
|||||||
}
|
}
|
||||||
mouseOver = true;
|
mouseOver = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GARBAGE COLLECTION //
|
||||||
|
// kill the mouse listener so it will get removed from the mouse event cascade
|
||||||
|
@Override
|
||||||
|
protected void finalize(){
|
||||||
|
println("finalized");
|
||||||
|
listener.kill();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ class B12Button extends Button{
|
|||||||
|
|
||||||
pushMatrix();
|
pushMatrix();
|
||||||
|
|
||||||
translate(pos.x,pos.y);
|
translate(super.pos.x,super.pos.y);
|
||||||
switch(mode){
|
switch(super.mode){
|
||||||
case CORNER: digit.setRefPos(dim.x/2 - 4,dim.y - 2);
|
case CORNER: digit.setRefPos(super.dim.x/2 - 4, super.dim.y - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
digit.display();
|
digit.display();
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
Includes method relay code be Quark - see https://forum.processing.org/two/discussion/13093/how-to-call-function-by-string-content.html
|
Includes method relay code be Quark - see https://forum.processing.org/two/discussion/13093/how-to-call-function-by-string-content.html
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
// TODO redo mouse handling -- in progress
|
// TODO redo position data handling
|
||||||
|
// WORKING redo mouse handling
|
||||||
// TODO add cursor and dynamic position for MathDisplay (Maybe add a "highlighted" attribute to B12Digit?) might need some restructuring
|
// TODO add cursor and dynamic position for MathDisplay (Maybe add a "highlighted" attribute to B12Digit?) might need some restructuring
|
||||||
// TODO add parsing expression to operable math string (tricky to get base 12 to base 10)
|
// TODO add parsing expression to operable math string (tricky to get base 12 to base 10)
|
||||||
// TODO add operator and action buttons to MathPad
|
// TODO add operator and action buttons to MathPad
|
||||||
@@ -20,7 +21,10 @@
|
|||||||
// MAYBE add additional operations like power, log, and trig functions
|
// MAYBE add additional operations like power, log, and trig functions
|
||||||
|
|
||||||
changelog 0.1.5.2
|
changelog 0.1.5.2
|
||||||
- major changes to mouse handling
|
- major changes to mouse handling, and MethodRelay now
|
||||||
|
uses weak references rather than strong references so
|
||||||
|
that there will no longer be the possibility of dangling
|
||||||
|
objects. This allows gc to collect dead buttons, Yay!
|
||||||
|
|
||||||
changelog 0.1.5.0
|
changelog 0.1.5.0
|
||||||
- Quite a few changes by this point. The readme has been
|
- Quite a few changes by this point. The readme has been
|
||||||
|
|||||||
Reference in New Issue
Block a user