trying... to... simplify.

This commit is contained in:
Ben Fry
2015-04-20 22:44:54 -07:00
parent 48b3bdf0a9
commit f49f7104bd
9 changed files with 591 additions and 372 deletions
+76 -49
View File
@@ -3,7 +3,7 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2012-14 The Processing Foundation
Copyright (c) 2012-15 The Processing Foundation
Copyright (c) 2004-12 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
@@ -24,15 +24,14 @@
package processing.core;
// used for setting bg colors and whatnot
import java.awt.Canvas;
// used for setting bg colors and whatnot
import java.awt.Color;
// use for the link() command (and maybe open()?)
import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.FileDialog;
import java.awt.Font;
// for the Frame object (deprecate?)
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;
@@ -66,26 +65,33 @@ import processing.opengl.*;
* Window Size and Full Screen</A> page on the Wiki has useful information
* about sizing, multiple displays, full screen, etc.
* <p/>
* Processing uses active mode rendering in all cases. All animation tasks
* happen on the "Processing Animation Thread". The setup() and draw() methods
* are handled by that thread, and events (like mouse movement and key presses,
* which are fired by the event dispatch thread or EDT) are queued to be safely
* handled at the end of draw(). For code that needs to run on the EDT,
* use EventQueue.invokeLater(). When doing so, be careful to synchronize
* between that code (since invokeLater() will make your code run from the EDT)
* and the Processing animation thread. Use of a callback function or the
* registerXxx() methods in PApplet can help ensure that your code doesn't do
* something naughty.
* Processing uses active mode rendering. All animation tasks happen on the
* "Processing Animation Thread". The setup() and draw() methods are handled
* by that thread, and events (like mouse movement and key presses, which are
* fired by the event dispatch thread or EDT) are queued to be safely handled
* at the end of draw().
* <p/>
* As of Processing 2.0, we have discontinued support for versions of Java
* prior to 1.6. We don't have enough people to support it, and for a
* project of our (tiny) size, we should be focusing on the future, rather
* than working around legacy Java code.
* Starting with 3.0a6, blit operations are on the EDT, so as not to cause
* GUI problems with Swing and AWT. In the case of the default renderer, the
* sketch renders to an offscreen image, then the EDT is asked to bring that
* image to the screen.
* <p/>
* For code that needs to run on the EDT, use EventQueue.invokeLater(). When
* doing so, be careful to synchronize between that code and the Processing
* animation thread. That is, you can't call Processing methods from the EDT
* or at any random time from another thread. Use of a callback function or
* the registerXxx() methods in PApplet can help ensure that your code doesn't
* do something naughty.
* <p/>
* As of Processing 3.0, we have removed Applet as the base class for PApplet.
* This means that we can remove lots of legacy code, however one downside is
* that it's no longer possible (without extra code) to embed a PApplet into
* another Java application.
* <p/>
* As of Processing 3.0, we have discontinued support for versions of Java
* prior to 1.8. We don't have enough people to support it, and for a
* project of our (tiny) size, we should be focusing on the future, rather
* than working around legacy Java code.
*/
public class PApplet implements PConstants {
//public class PApplet extends Applet
@@ -1614,9 +1620,7 @@ public class PApplet implements PConstants {
*
*/
public PGraphics createGraphics(int w, int h, String renderer) {
PGraphics pg = makeGraphics(w, h, renderer, null, false);
//pg.parent = this; // make save() work
return pg;
return createGraphics(w, h, renderer, null);
}
@@ -1627,12 +1631,17 @@ public class PApplet implements PConstants {
*/
public PGraphics createGraphics(int w, int h,
String renderer, String path) {
return makeGraphics(w, h, renderer, savePath(path), false);
/*
if (path != null) {
path = savePath(path);
}
PGraphics pg = makeGraphics(w, h, renderer, path, false);
pg.parent = this; // make save() work
//pg.parent = this; // why wasn't setParent() used before 3.0a6?
//pg.setParent(this); // make save() work
// Nevermind, parent is set in makeGraphics()
return pg;
*/
}
@@ -1641,13 +1650,12 @@ public class PApplet implements PConstants {
// }
/** Create default renderer, likely to be resized, but needed for surface init. */
protected PGraphics makePrimaryGraphics() {
return makeGraphics(sketchWidth(), sketchHeight(), sketchRenderer(), null, true);
}
/** Version of createGraphics() used internally. */
/**
* Version of createGraphics() used internally.
* @param path A full (not relative) path.
* {@link PApplet#createGraphics} will call
* {@link PApplet#savePath} first.
*/
protected PGraphics makeGraphics(int w, int h,
String renderer, String path,
boolean primary) {
@@ -1677,13 +1685,12 @@ public class PApplet implements PConstants {
pg.setParent(this);
pg.setPrimary(primary);
if (path != null) {
// Wrap in sketchPath() because it has to be absolute
pg.setPath(sketchPath(path));
pg.setPath(path);
}
// pg.setQuality(sketchQuality());
if (!primary) {
surface.initImage(pg, w, h);
}
// if (!primary) {
// surface.initImage(pg, w, h);
// }
pg.setSize(w, h);
// everything worked, return it
@@ -1738,12 +1745,19 @@ public class PApplet implements PConstants {
if (platform == MACOSX) {
e.printStackTrace(System.out); // OS X bug (still true?)
}
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
}
/** Create default renderer, likely to be resized, but needed for surface init. */
protected PGraphics createPrimaryGraphics() {
return makeGraphics(sketchWidth(), sketchHeight(), sketchRenderer(), null, true);
}
/**
* ( begin auto-generated from createImage.xml )
*
@@ -9370,9 +9384,8 @@ public class PApplet implements PConstants {
/**
* Moving this to the EDT for 3.0a6 because the main() messes with AWT
* components (or even Swing components, presumably). Hoping to get more
* consistent behavior across platforms and implementations.
* Moving this to the EDT for 3.0a6 because that's the proper thing to do
* when messing with AWT/Swing components. And boy, do we mess with 'em.
*/
static protected void runSketchEDT(final String[] args,
final PApplet constructedApplet) {
@@ -9512,6 +9525,7 @@ public class PApplet implements PConstants {
// Frame frame =
// surface.initFrame(applet, backgroundColor,
// displayIndex, present, spanDisplays);
PSurface surface =
applet.initSurface(backgroundColor, displayIndex, fullScreen, spanDisplays);
@@ -9528,15 +9542,15 @@ public class PApplet implements PConstants {
// // In a static mode app, this will be after setup() has completed,
// // and the empty draw() has set "finished" to true.
// // TODO make sure this won't hang if the applet has an exception.
// while (applet.defaultSize && !applet.finished) {
// //System.out.println("default size");
// try {
// Thread.sleep(5);
//
// } catch (InterruptedException e) {
// //System.out.println("interrupt");
// }
// }
while (applet.defaultSize && !applet.finished) {
//System.out.println("default size");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
//System.out.println("interrupt");
}
}
if (fullScreen) {
//surface.placeFullScreen(hideStop);
@@ -9565,10 +9579,16 @@ public class PApplet implements PConstants {
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
g = makePrimaryGraphics();
g = createPrimaryGraphics();
surface = g.createSurface();
frame = surface.initFrame(this, backgroundColor, displayIndex, present, spanDisplays);
surface.setTitle(getClass().getName());
if (g.displayable()) {
frame = surface.initFrame(this, backgroundColor, displayIndex, present, spanDisplays);
//surface.setTitle(getClass().getName());
frame.setTitle(getClass().getName());
// } else {
// // TODO necessary?
// surface.initOffscreen(this);
}
init();
@@ -9578,6 +9598,11 @@ public class PApplet implements PConstants {
// moving it to init() 141114
//applet.start();
// Removing this for 3.0a6. sketchWidth/Height() methods should give us
// good values for most cases, and removes the hackery seen here.
// TODO May need to keep since setup() may take a while, so why not have
// it first render offscreen before showing.
/*
// Wait until the applet has figured out its width.
// In a static mode app, this will be after setup() has completed,
// and the empty draw() has set "finished" to true.
@@ -9591,6 +9616,8 @@ public class PApplet implements PConstants {
//System.out.println("interrupt");
}
}
*/
// System.out.println("out of default size loop, " + width + " " + height);
// convenience to avoid another 'get' from the static main() method
return surface;
@@ -9618,7 +9645,7 @@ public class PApplet implements PConstants {
* sketch.init() // start the animation thread
*/
public Canvas getCanvas() {
g = makePrimaryGraphics();
g = createPrimaryGraphics();
surface = g.createSurface();
return surface.initCanvas(this);
}
+21 -8
View File
@@ -168,7 +168,7 @@ public class PGraphics extends PImage implements PConstants {
/// true if defaults() has been called a first time
protected boolean settingsInited;
/// true if defaults() has been called a first time
/// true if settings should be re-applied on next beginDraw()
protected boolean reapplySettings;
/// set to a PGraphics object being used inside a beginRaw/endRaw() block
@@ -516,6 +516,9 @@ public class PGraphics extends PImage implements PConstants {
*/
public Image image;
/** Surface object that we're talking to */
protected PSurface surface;
// ........................................................
// internal color for setting/calculating
@@ -653,7 +656,7 @@ public class PGraphics extends PImage implements PConstants {
* vertex() calls will be based on coordinates that are
* based on the IMAGE or NORMALIZED.
*/
public int textureMode = IMAGE;
public int textureMode = IMAGE;
/**
* Current horizontal coordinate for texture, will always
@@ -683,6 +686,11 @@ public class PGraphics extends PImage implements PConstants {
// INTERNAL
// Most renderers will only override the default implementation of one or
// two of the setXxxx() methods, so they're broken out here since the
// default implementations for each are simple, obvious, and common.
// They're also separate to avoid a monolithic and fragile constructor.
public PGraphics() {
// Allows subclasses to override
@@ -691,6 +699,8 @@ public class PGraphics extends PImage implements PConstants {
public void setParent(PApplet parent) { // ignore
this.parent = parent;
// Some renderers (OpenGL) need to know what smoothing level will be used
// before the rendering surface is even created.
quality = parent.sketchQuality();
}
@@ -737,17 +747,20 @@ public class PGraphics extends PImage implements PConstants {
width = w;
height = h;
/** {@link PImage.pixelFactor} set in {@link PImage#PImage()} */
pixelWidth = width * pixelFactor;
pixelHeight = height * pixelFactor;
// allocate();
reapplySettings();
// if (surface != null) {
// allocate();
// }
// reapplySettings();
reapplySettings = true;
}
// /**
// * Allocate memory for this renderer. Generally will need to be implemented
// * for all renderers.
// * Allocate memory or an image buffer for this renderer.
// */
// protected void allocate() { }
@@ -764,7 +777,7 @@ public class PGraphics extends PImage implements PConstants {
public PSurface createSurface() { // ignore
return new PSurfaceAWT(this);
return surface = new PSurfaceAWT(this);
}
@@ -950,7 +963,7 @@ public class PGraphics extends PImage implements PConstants {
settingsInited = true;
// defaultSettings() overlaps reapplySettings(), don't do both
//reapplySettings = false;
reapplySettings = false;
}
+44 -9
View File
@@ -137,6 +137,13 @@ public class PGraphicsJava2D extends PGraphics {
// }
// @Override
// protected void allocate() {
// //surface.initImage(this, width, height);
// surface.initImage(this);
// }
/*
@Override
protected void allocate() {
@@ -239,8 +246,8 @@ public class PGraphicsJava2D extends PGraphics {
@Override
public PSurface createSurface() {
//return (surface = new PSurfaceAWT());
return new PSurfaceAWT(this);
return surface = new PSurfaceAWT(this);
// return new PSurfaceAWT(this);
}
@@ -267,15 +274,43 @@ public class PGraphicsJava2D extends PGraphics {
// Graphics2D g2old;
public Graphics2D checkImage() {
if (image == null ||
((BufferedImage) image).getWidth() != width ||
((BufferedImage) image).getHeight() != height) {
// image = new BufferedImage(width * pixelFactor, height * pixelFactor
// format == RGB ? BufferedImage.TYPE_INT_ARGB);
GraphicsConfiguration gc = null;
if (surface != null) {
Component comp = surface.getComponent();
if (comp == null) {
comp = parent.frame;
}
if (comp != null) {
gc = comp.getGraphicsConfiguration();
}
}
// If not realized (off-screen, i.e the Color Selector Tool), gc will be null.
if (gc == null) {
//System.err.println("GraphicsConfiguration null in initImage()");
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
}
// Formerly this was broken into separate versions based on offscreen or
// not, but we may as well create a compatible image; it won't hurt, right?
int wide = width * pixelFactor;
int high = height * pixelFactor;
image = gc.createCompatibleImage(wide, high);
}
return (Graphics2D) image.getGraphics();
}
@Override
public void beginDraw() {
// TODO this will happen when it's offscreen.. need a better option here
if (image == null ||
((BufferedImage) image).getWidth() != width ||
((BufferedImage) image).getHeight() != height) {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
g2 = (Graphics2D) image.getGraphics();
g2 = checkImage();
//g2 = (Graphics2D) image.getGraphics();
// Calling getGraphics() seems to nuke the smoothing settings
smooth(quality);
+12 -14
View File
@@ -1,7 +1,5 @@
package processing.core;
import java.awt.*;
public class PGraphicsJava2D2X extends PGraphicsJava2D {
// PImage retina;
@@ -97,22 +95,22 @@ public class PGraphicsJava2D2X extends PGraphicsJava2D {
@Override
public void beginDraw() {
// GraphicsConfiguration gc = parent.getGraphicsConfiguration();
super.beginDraw();
//// GraphicsConfiguration gc = parent.getGraphicsConfiguration();
////
//// if (image == null) {
//// retina.width = width * 2;
//// retina.height = height * 2;
//// image = gc.createCompatibleImage(retina.width, retina.height);
//// }
// g2 = (Graphics2D) image.getGraphics();
//
// if (image == null) {
// retina.width = width * 2;
// retina.height = height * 2;
// image = gc.createCompatibleImage(retina.width, retina.height);
// }
g2 = (Graphics2D) image.getGraphics();
checkSettings();
resetMatrix(); // reset model matrix
// vertexCount = 0;
// checkSettings();
// resetMatrix(); // reset model matrix
// inserted here for retina
g2.scale(2, 2);
vertexCount = 0;
}
+38 -33
View File
@@ -3,7 +3,7 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2014 The Processing Foundation
Copyright (c) 2014-15 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
@@ -24,6 +24,7 @@ package processing.core;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
@@ -44,7 +45,7 @@ public interface PSurface {
static final Color WINDOW_BGCOLOR = new Color(0xDD, 0xDD, 0xDD);
// renderer that doesn't draw to the screen
public void initOffscreen();
public void initOffscreen(PApplet sketch);
public Canvas initCanvas(PApplet sketch);
@@ -53,14 +54,18 @@ public interface PSurface {
//
/** Set the window (and dock, or whatever necessary) title. */
public void setTitle(String title);
// Just call these on an AWT Frame object stored in PApplet.
// Silly, but prevents a lot of rewrite and extra methods for little benefit.
// However, maybe prevents us from having to document the 'frame' variable?
/** Show or hide the window. */
public void setVisible(boolean visible);
/** Set true if we want to resize things (default is not resizable) */
public void setResizable(boolean resizable);
// /** Set the window (and dock, or whatever necessary) title. */
// public void setTitle(String title);
//
// /** Show or hide the window. */
// public void setVisible(boolean visible);
//
// /** Set true if we want to resize things (default is not resizable) */
// public void setResizable(boolean resizable);
//
@@ -76,35 +81,13 @@ public interface PSurface {
//
/** Start the animation thread */
public void startThread();
/**
* On the next trip through the animation thread, things should go sleepy-bye.
* Does not pause the thread immediately because that needs to happen on the
* animation thread itself, so fires on the next trip through draw().
*/
public void pauseThread();
public void resumeThread();
/**
* Stop the animation thread (set it null)
* @return false if already stopped
*/
public boolean stopThread();
public boolean isStopped();
//
// sets displayWidth/Height inside PApplet
//public void checkDisplaySize();
public void setSize(int width, int height);
/**
* Called by {@link PApplet#createGraphics(int, int)} to nitialize the
* Called by {@link PApplet#createGraphics} to initialize the
* {@link PGraphics#image} object with an image that's compatible with this
* drawing surface/display/hardware.
* @param gr PGraphics object whose image will be set
@@ -112,7 +95,10 @@ public interface PSurface {
* @param high
*/
// create pixel buffer (pulled out for offscreen graphics)
public void initImage(PGraphics gr, int wide, int high);
//public void initImage(PGraphics gr, int wide, int high);
// create pixel buffer, called from allocate() to produce a compatible image for rendering efficiently
// public void initImage(PGraphics gr);
public Component getComponent();
/**
* Sometimes smoothing must be set at the drawing surface level
@@ -141,4 +127,23 @@ public interface PSurface {
//
/** Start the animation thread */
public void startThread();
/**
* On the next trip through the animation thread, things should go sleepy-bye.
* Does not pause the thread immediately because that needs to happen on the
* animation thread itself, so fires on the next trip through draw().
*/
public void pauseThread();
public void resumeThread();
/**
* Stop the animation thread (set it null)
* @return false if already stopped
*/
public boolean stopThread();
public boolean isStopped();
}
+74 -237
View File
@@ -36,11 +36,11 @@ import processing.event.KeyEvent;
import processing.event.MouseEvent;
public class PSurfaceAWT implements PSurface {
public class PSurfaceAWT extends PSurfaceBasic {
GraphicsDevice displayDevice;
// used for canvas to determine whether resizable or not
boolean resizable; // default is false
// boolean resizable; // default is false
// Internally, we know it's always a JFrame (not just a Frame)
JFrame frame;
@@ -55,20 +55,11 @@ public class PSurfaceAWT implements PSurface {
boolean useStrategy = false;
Canvas canvas;
PApplet sketch;
PGraphics graphics;
int sketchWidth;
int sketchHeight;
Thread thread;
boolean paused;
Object pauseObject = new Object();
/** As of release 0116, frameRate(60) is called as a default */
protected float frameRateTarget = 60;
protected long frameRatePeriod = 1000000000L / 60L;
public PSurfaceAWT(PGraphics graphics) {
this.graphics = graphics;
@@ -109,6 +100,7 @@ public class PSurfaceAWT implements PSurface {
* later on the EDT. Other implementations may not require that, so the
* invokeLater() happens in here rather than requiring the caller to wrap it.
*/
@Override
public void requestFocus() {
// for 2.0a6, moving this request to the EDT
EventQueue.invokeLater(new Runnable() {
@@ -156,7 +148,8 @@ public class PSurfaceAWT implements PSurface {
@Override
public Dimension getMaximumSize() {
return resizable ? super.getMaximumSize() : getPreferredSize();
//return resizable ? super.getMaximumSize() : getPreferredSize();
return frame.isResizable() ? super.getMaximumSize() : getPreferredSize();
}
@@ -270,6 +263,7 @@ public class PSurfaceAWT implements PSurface {
}
@Override
public void blit() {
// Other folks taht call render() (i.e. paint()) are already on the EDT.
// We need to be using the EDT since we're messing with the Canvas
@@ -283,8 +277,9 @@ public class PSurfaceAWT implements PSurface {
// what needs to happen here?
public void initOffscreen() {
@Override
public void initOffscreen(PApplet sketch) {
this.sketch = sketch;
}
/*
@@ -296,6 +291,7 @@ public class PSurfaceAWT implements PSurface {
}
*/
@Override
public Canvas initCanvas(PApplet sketch) {
this.sketch = sketch;
@@ -307,6 +303,7 @@ public class PSurfaceAWT implements PSurface {
}
@Override
public Frame initFrame(PApplet sketch, Color backgroundColor,
int deviceIndex, boolean fullScreen, boolean spanDisplays) {
this.sketch = sketch;
@@ -438,45 +435,46 @@ public class PSurfaceAWT implements PSurface {
}
/** Set the window (and dock, or whatever necessary) title. */
public void setTitle(String title) {
frame.setTitle(title);
}
/** Set true if we want to resize things (default is not resizable) */
public void setResizable(boolean resizable) {
this.resizable = resizable; // really only used for canvas
if (frame != null) {
frame.setResizable(resizable);
}
}
public void setVisible(boolean visible) {
frame.setVisible(visible);
// removing per https://github.com/processing/processing/pull/3162
// can remove the code below once 3.0a6 is tested and behaving
/*
if (visible && PApplet.platform == PConstants.LINUX) {
// Linux doesn't deal with insets the same way. We get fake insets
// earlier, and then the window manager will slap its own insets
// onto things once the frame is realized on the screen. Awzm.
if (PApplet.platform == PConstants.LINUX) {
Insets insets = frame.getInsets();
frame.setSize(Math.max(sketchWidth, MIN_WINDOW_WIDTH) +
insets.left + insets.right,
Math.max(sketchHeight, MIN_WINDOW_HEIGHT) +
insets.top + insets.bottom);
}
}
*/
}
// /** Set the window (and dock, or whatever necessary) title. */
// public void setTitle(String title) {
// frame.setTitle(title);
// }
//
//
// /** Set true if we want to resize things (default is not resizable) */
// public void setResizable(boolean resizable) {
// this.resizable = resizable; // really only used for canvas
//
// if (frame != null) {
// frame.setResizable(resizable);
// }
// }
//
//
// public void setVisible(boolean visible) {
// frame.setVisible(visible);
//
// // removing per https://github.com/processing/processing/pull/3162
// // can remove the code below once 3.0a6 is tested and behaving
///*
// if (visible && PApplet.platform == PConstants.LINUX) {
// // Linux doesn't deal with insets the same way. We get fake insets
// // earlier, and then the window manager will slap its own insets
// // onto things once the frame is realized on the screen. Awzm.
// if (PApplet.platform == PConstants.LINUX) {
// Insets insets = frame.getInsets();
// frame.setSize(Math.max(sketchWidth, MIN_WINDOW_WIDTH) +
// insets.left + insets.right,
// Math.max(sketchHeight, MIN_WINDOW_HEIGHT) +
// insets.top + insets.bottom);
// }
// }
//*/
// }
//public void placeFullScreen(boolean hideStop) {
@Override
public void placePresent(Color stopColor) {
// After the pack(), the screen bounds are gonna be 0s
frame.setBounds(screenRect);
@@ -510,6 +508,7 @@ public class PSurfaceAWT implements PSurface {
}
@Override
public void placeWindow(int[] location) {
setFrameSize(); //sketchWidth, sketchHeight);
@@ -549,7 +548,7 @@ public class PSurfaceAWT implements PSurface {
// all set for rockin
if (sketch.getGraphics().displayable()) {
setVisible(true);
frame.setVisible(true);
}
}
@@ -591,6 +590,7 @@ public class PSurfaceAWT implements PSurface {
}
@Override
public void placeWindow(int[] location, int[] editorLocation) {
//Dimension window = setFrameSize(sketchWidth, sketchHeight);
Dimension window = setFrameSize(); //sketchWidth, sketchHeight);
@@ -653,74 +653,21 @@ public class PSurfaceAWT implements PSurface {
// TODO this is much too late... why even create the enormous frame for PDF?
if (sketch.getGraphics().displayable()) {
setVisible(true);
}
}
public void startThread() {
if (thread == null) {
thread = new AnimationThread();
thread.start();
} else {
throw new IllegalStateException("Thread already started in PSurfaceAWT");
}
}
public boolean stopThread() {
if (thread == null) {
return false;
}
thread = null;
return true;
}
public boolean isStopped() {
return thread == null;
}
// sets a flag to pause the thread when ready
public void pauseThread() {
PApplet.debug("PApplet.run() paused, calling object wait...");
paused = true;
}
// halts the animation thread if the pause flag is set
protected void checkPause() {
if (paused) {
synchronized (pauseObject) {
try {
pauseObject.wait();
// PApplet.debug("out of wait");
} catch (InterruptedException e) {
// waiting for this interrupt on a start() (resume) call
}
}
}
// PApplet.debug("done with pause");
}
public void resumeThread() {
paused = false;
synchronized (pauseObject) {
pauseObject.notifyAll(); // wake up the animation thread
frame.setVisible(true);
}
}
// needs to resize the frame, which will resize the canvas, and so on...
@Override
public void setSize(int wide, int high) {
// System.out.format("frame visible %b, setSize(%d, %d) %n", frame.isVisible(), wide, high);
if (PApplet.DEBUG) {
//System.out.format("frame visible %b, setSize(%d, %d) %n", frame.isVisible(), wide, high);
new Exception(String.format("setSize(%d, %d)", wide, high)).printStackTrace(System.out);
}
if (wide == sketchWidth && high == sketchHeight) {
//if (wide == sketchWidth && high == sketchHeight) { // doesn't work on launch
if (wide == sketch.width && high == sketch.height) {
if (PApplet.DEBUG) {
new Exception("w/h unchanged " + wide + " " + high).printStackTrace(System.out);
}
@@ -732,7 +679,7 @@ public class PSurfaceAWT implements PSurface {
// canvas.setSize(wide, high);
// frame.setSize(wide, high);
if (frame != null) { // canvas only
if (frame != null) { // skip if just a canvas
setFrameSize(); //wide, high);
}
setCanvasSize();
@@ -740,7 +687,7 @@ public class PSurfaceAWT implements PSurface {
// frame.setLocationRelativeTo(null);
// }
initImage(graphics, wide, high);
//initImage(graphics, wide, high);
//throw new RuntimeException("implement me, see readme.md");
sketch.width = wide;
@@ -748,25 +695,32 @@ public class PSurfaceAWT implements PSurface {
// set PGraphics variables for width/height/pixelWidth/pixelHeight
graphics.setSize(wide, high);
// System.out.println("out of setSize()");
}
public void initImage(PGraphics gr, int wide, int high) {
//public void initImage(PGraphics gr, int wide, int high) {
/*
@Override
public void initImage(PGraphics graphics) {
GraphicsConfiguration gc = canvas.getGraphicsConfiguration();
// If not realized (off-screen, i.e the Color Selector Tool), gc will be null.
if (gc == null) {
System.err.println("GraphicsConfiguration null in setSize()");
System.err.println("GraphicsConfiguration null in initImage()");
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
}
// Formerly this was broken into separate versions based on offscreen or
// not, but we may as well create a compatible image; it won't hurt, right?
int factor = gr.pixelFactor;
gr.image = gc.createCompatibleImage(wide * factor, high * factor);
int wide = graphics.width * graphics.pixelFactor;
int high = graphics.height * graphics.pixelFactor;
graphics.image = gc.createCompatibleImage(wide, high);
}
*/
@Override
public void setSmooth(int level) {
}
@@ -850,6 +804,7 @@ public class PSurfaceAWT implements PSurface {
* (so that it will be saved by the PDE for the next run) and
* notify on quit. See more notes in the Worker class.
*/
@Override
public void setupExternalMessages() {
frame.addComponentListener(new ComponentAdapter() {
@@ -1291,128 +1246,6 @@ public class PSurfaceAWT implements PSurface {
// addListeners(comp);
// }
public void setFrameRate(float fps) {
frameRateTarget = fps;
frameRatePeriod = (long) (1000000000.0 / frameRateTarget);
//g.setFrameRate(fps);
}
class AnimationThread extends Thread {
public AnimationThread() {
super("Animation Thread");
}
/**
* Main method for the primary animation thread.
* <A HREF="http://java.sun.com/products/jfc/tsc/articles/painting/">Painting in AWT and Swing</A>
*/
@Override
public void run() { // not good to make this synchronized, locks things up
long beforeTime = System.nanoTime();
long overSleepTime = 0L;
int noDelays = 0;
// Number of frames with a delay of 0 ms before the
// animation thread yields to other running threads.
final int NO_DELAYS_PER_YIELD = 15;
/*
// If size un-initialized, might be a Canvas. Call setSize() here since
// we now have a parent object that this Canvas can use as a peer.
if (graphics.image == null) {
// System.out.format("it's null, sketchW/H already set to %d %d%n", sketchWidth, sketchHeight);
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
setSize(sketchWidth, sketchHeight);
}
});
} catch (InterruptedException ie) {
ie.printStackTrace();
} catch (InvocationTargetException ite) {
ite.printStackTrace();
}
// System.out.format(" but now, sketchW/H changed to %d %d%n", sketchWidth, sketchHeight);
}
*/
// un-pause the sketch and get rolling
sketch.start();
while ((Thread.currentThread() == thread) && !sketch.finished) {
checkPause();
// Don't resize the renderer from the EDT (i.e. from a ComponentEvent),
// otherwise it may attempt a resize mid-render.
// Dimension currentSize = canvas.getSize();
// if (currentSize.width != sketchWidth || currentSize.height != sketchHeight) {
// System.err.format("need to resize from %s to %d, %d%n", currentSize, sketchWidth, sketchHeight);
// }
// render a single frame
// try {
// EventQueue.invokeAndWait(new Runnable() {
// public void run() {
sketch.handleDraw();
// EventQueue.invokeLater(new Runnable() {
// public void run() {
if (sketch.frameCount == 1) {
requestFocus();
}
// }
// });
// }
// });
// } catch (InterruptedException ie) {
// ie.printStackTrace();
// } catch (InvocationTargetException ite) {
// ite.getTargetException().printStackTrace();
// }
// wait for update & paint to happen before drawing next frame
// this is necessary since the drawing is sometimes in a
// separate thread, meaning that the next frame will start
// before the update/paint is completed
long afterTime = System.nanoTime();
long timeDiff = afterTime - beforeTime;
//System.out.println("time diff is " + timeDiff);
long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
if (sleepTime > 0) { // some time left in this cycle
try {
Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
noDelays = 0; // Got some sleep, not delaying anymore
} catch (InterruptedException ex) { }
overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
} else { // sleepTime <= 0; the frame took longer than the period
overSleepTime = 0L;
noDelays++;
if (noDelays > NO_DELAYS_PER_YIELD) {
Thread.yield(); // give another thread a chance to run
noDelays = 0;
}
}
beforeTime = System.nanoTime();
}
sketch.dispose(); // call to shutdown libs?
// If the user called the exit() function, the window should close,
// rather than the sketch just halting.
if (sketch.exitCalled) {
sketch.exitActual();
}
}
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@@ -1423,6 +1256,7 @@ public class PSurfaceAWT implements PSurface {
Cursor invisibleCursor;
@Override
public void setCursor(int kind) {
// Swap the HAND cursor because MOVE doesn't seem to be available on OS X
// https://github.com/processing/processing/issues/2358
@@ -1435,6 +1269,7 @@ public class PSurfaceAWT implements PSurface {
}
@Override
public void setCursor(PImage img, int x, int y) {
// Don't set cursorType, instead use cursorType to save the last
// regular cursor type used for when cursor() is called.
@@ -1448,6 +1283,7 @@ public class PSurfaceAWT implements PSurface {
}
@Override
public void showCursor() {
// Maybe should always set here? Seems dangerous, since it's likely that
// Java will set the cursor to something else on its own, and the sketch
@@ -1459,6 +1295,7 @@ public class PSurfaceAWT implements PSurface {
}
@Override
public void hideCursor() {
// Because the OS may have shown the cursor on its own,
// don't return if 'cursorVisible' is set to true. [rev 0216]
+290
View File
@@ -0,0 +1,290 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Processing project - http://processing.org
Copyright (c) 2015 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.core;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
public class PSurfaceBasic implements PSurface {
PApplet sketch;
Thread thread;
boolean paused;
Object pauseObject = new Object();
protected float frameRateTarget = 60;
protected long frameRatePeriod = 1000000000L / 60L;
public PSurfaceBasic() { }
public void initOffscreen(PApplet sketch) {
// TODO Auto-generated method stub
}
public Canvas initCanvas(PApplet sketch) {
return null;
}
public Frame initFrame(PApplet sketch, Color backgroundColor,
int deviceIndex, boolean fullScreen,
boolean spanDisplays) {
return null;
}
public void placeWindow(int[] location) { }
public void placeWindow(int[] location, int[] editorLocation) { }
public void placePresent(Color stopColor) { }
public void setupExternalMessages() { }
//
public void setSize(int width, int height) {
// TODO Auto-generated method stub
}
// public void initImage(PGraphics graphics) {
// // TODO Auto-generated method stub
//
// }
public Component getComponent() {
return null;
}
public void setSmooth(int level) {
// TODO Auto-generated method stub
}
public void requestFocus() {
// TODO Auto-generated method stub
}
public void blit() {
// TODO Auto-generated method stub
}
public void setCursor(int kind) { }
public void setCursor(PImage image, int hotspotX, int hotspotY) { }
public void showCursor() { }
public void hideCursor() { }
//
public void startThread() {
if (thread == null) {
thread = new AnimationThread();
thread.start();
} else {
throw new IllegalStateException("Thread already started in PSurfaceAWT");
}
}
public boolean stopThread() {
if (thread == null) {
return false;
}
thread = null;
return true;
}
public boolean isStopped() {
return thread == null;
}
// sets a flag to pause the thread when ready
public void pauseThread() {
PApplet.debug("PApplet.run() paused, calling object wait...");
paused = true;
}
// halts the animation thread if the pause flag is set
protected void checkPause() {
if (paused) {
synchronized (pauseObject) {
try {
pauseObject.wait();
// PApplet.debug("out of wait");
} catch (InterruptedException e) {
// waiting for this interrupt on a start() (resume) call
}
}
}
// PApplet.debug("done with pause");
}
public void resumeThread() {
paused = false;
synchronized (pauseObject) {
pauseObject.notifyAll(); // wake up the animation thread
}
}
public void setFrameRate(float fps) {
frameRateTarget = fps;
frameRatePeriod = (long) (1000000000.0 / frameRateTarget);
//g.setFrameRate(fps);
}
class AnimationThread extends Thread {
public AnimationThread() {
super("Animation Thread");
}
/**
* Main method for the primary animation thread.
* <A HREF="http://java.sun.com/products/jfc/tsc/articles/painting/">Painting in AWT and Swing</A>
*/
@Override
public void run() { // not good to make this synchronized, locks things up
long beforeTime = System.nanoTime();
long overSleepTime = 0L;
int noDelays = 0;
// Number of frames with a delay of 0 ms before the
// animation thread yields to other running threads.
final int NO_DELAYS_PER_YIELD = 15;
/*
// If size un-initialized, might be a Canvas. Call setSize() here since
// we now have a parent object that this Canvas can use as a peer.
if (graphics.image == null) {
// System.out.format("it's null, sketchW/H already set to %d %d%n", sketchWidth, sketchHeight);
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
setSize(sketchWidth, sketchHeight);
}
});
} catch (InterruptedException ie) {
ie.printStackTrace();
} catch (InvocationTargetException ite) {
ite.printStackTrace();
}
// System.out.format(" but now, sketchW/H changed to %d %d%n", sketchWidth, sketchHeight);
}
*/
// un-pause the sketch and get rolling
sketch.start();
while ((Thread.currentThread() == thread) && !sketch.finished) {
checkPause();
// Don't resize the renderer from the EDT (i.e. from a ComponentEvent),
// otherwise it may attempt a resize mid-render.
// Dimension currentSize = canvas.getSize();
// if (currentSize.width != sketchWidth || currentSize.height != sketchHeight) {
// System.err.format("need to resize from %s to %d, %d%n", currentSize, sketchWidth, sketchHeight);
// }
// render a single frame
// try {
// EventQueue.invokeAndWait(new Runnable() {
// public void run() {
sketch.handleDraw();
// EventQueue.invokeLater(new Runnable() {
// public void run() {
if (sketch.frameCount == 1) {
requestFocus();
}
// }
// });
// }
// });
// } catch (InterruptedException ie) {
// ie.printStackTrace();
// } catch (InvocationTargetException ite) {
// ite.getTargetException().printStackTrace();
// }
// wait for update & paint to happen before drawing next frame
// this is necessary since the drawing is sometimes in a
// separate thread, meaning that the next frame will start
// before the update/paint is completed
long afterTime = System.nanoTime();
long timeDiff = afterTime - beforeTime;
//System.out.println("time diff is " + timeDiff);
long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
if (sleepTime > 0) { // some time left in this cycle
try {
Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
noDelays = 0; // Got some sleep, not delaying anymore
} catch (InterruptedException ex) { }
overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
} else { // sleepTime <= 0; the frame took longer than the period
overSleepTime = 0L;
noDelays++;
if (noDelays > NO_DELAYS_PER_YIELD) {
Thread.yield(); // give another thread a chance to run
noDelays = 0;
}
}
beforeTime = System.nanoTime();
}
sketch.dispose(); // call to shutdown libs?
// If the user called the exit() function, the window should close,
// rather than the sketch just halting.
if (sketch.exitCalled) {
sketch.exitActual();
}
}
}
}
+28 -21
View File
@@ -2,6 +2,7 @@ package processing.opengl;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
@@ -77,7 +78,7 @@ public class PSurfaceLWJGL implements PSurface {
@Override
public void initOffscreen() {
public void initOffscreen(PApplet sketch) {
}
@@ -232,24 +233,24 @@ public class PSurfaceLWJGL implements PSurface {
}
@Override
public void setTitle(String title) {
Display.setTitle(title);
}
@Override
public void setVisible(boolean visible) {
// Apparently not possible:
// http://forum.lwjgl.org/index.php?topic=5388.0
System.err.println("Cannot set visibility of window in OpenGL");
}
@Override
public void setResizable(boolean resizable) {
Display.setResizable(resizable);
}
// @Override
// public void setTitle(String title) {
// Display.setTitle(title);
// }
//
//
// @Override
// public void setVisible(boolean visible) {
// // Apparently not possible:
// // http://forum.lwjgl.org/index.php?topic=5388.0
// System.err.println("Cannot set visibility of window in OpenGL");
// }
//
//
// @Override
// public void setResizable(boolean resizable) {
// Display.setResizable(resizable);
// }
@Override
@@ -415,8 +416,12 @@ public class PSurfaceLWJGL implements PSurface {
}
public void initImage(PGraphics gr, int wide, int high) {
// TODO not sure yet how to implement [fry]
// @Override
// public void initImage(PGraphics graphics) {
// // TODO not sure yet how to implement [fry]
// }
public Component getComponent() {
return frame;
}
@@ -624,6 +629,8 @@ public class PSurfaceLWJGL implements PSurface {
}
}
///////////////////////////////////////////////////////////
// LWJGL event handling
@@ -100,6 +100,13 @@ public class PGraphicsPDF extends PGraphicsJava2D {
}
@Override
public PSurface createSurface() {
return surface = new PSurfaceBasic();
}
@Override
protected void defaultSettings() { // ignore
super.defaultSettings();
textMode = SHAPE;
@@ -141,7 +148,7 @@ public class PGraphicsPDF extends PGraphicsJava2D {
// g2 = template.createGraphics(width, height, mapper);
}
// System.out.println("beginDraw " + (System.currentTimeMillis() - t0));
// super in Java2D now creates an image buffer, don't do that
// super.beginDraw();
checkSettings();