Skip to content

Commit 3cd02d6

Browse files
authored
Merge pull request #1 from processing/master
merge commits
2 parents 929fdc7 + f74f3c1 commit 3cd02d6

File tree

10 files changed

+72
-91
lines changed

10 files changed

+72
-91
lines changed

core/src/processing/core/PApplet.java

Lines changed: 23 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@
6262
import java.text.*;
6363
import java.util.*;
6464
import java.util.concurrent.BlockingQueue;
65+
import java.util.concurrent.ExecutorService;
66+
import java.util.concurrent.Executors;
6567
import java.util.concurrent.LinkedBlockingQueue;
68+
import java.util.concurrent.ThreadFactory;
6669
import java.util.regex.*;
6770
import java.util.zip.*;
6871

@@ -5431,9 +5434,10 @@ public PImage loadImage(String filename) {
54315434
*/
54325435
public PImage loadImage(String filename, String extension) { //, Object params) {
54335436

5434-
// await... has to run on the main thread, because P2D and P3D call GL functions
5435-
// If this runs on background, requestImage() already called await... on the main thread
5436-
if (g != null && !Thread.currentThread().getName().startsWith(ASYNC_IMAGE_LOADER_THREAD_PREFIX)) {
5437+
// awaitAsyncSaveCompletion() has to run on the main thread, because P2D
5438+
// and P3D call GL functions. If this runs on background, requestImage()
5439+
// already called awaitAsyncSaveCompletion() on the main thread.
5440+
if (g != null && !Thread.currentThread().getName().startsWith(REQUEST_IMAGE_THREAD_PREFIX)) {
54375441
g.awaitAsyncSaveCompletion(filename);
54385442
}
54395443

@@ -5561,8 +5565,12 @@ public PImage loadImage(String filename, String extension) { //, Object params)
55615565
}
55625566

55635567

5568+
static private final String REQUEST_IMAGE_THREAD_PREFIX = "requestImage";
5569+
// fixed-size thread pool used by requestImage()
5570+
ExecutorService requestImagePool;
5571+
5572+
55645573
public PImage requestImage(String filename) {
5565-
// return requestImage(filename, null, null);
55665574
return requestImage(filename, null);
55675575
}
55685576

@@ -5596,62 +5604,17 @@ public PImage requestImage(String filename, String extension) {
55965604
g.awaitAsyncSaveCompletion(filename);
55975605
}
55985606
PImage vessel = createImage(0, 0, ARGB);
5599-
AsyncImageLoader ail =
5600-
new AsyncImageLoader(filename, extension, vessel);
5601-
ail.start();
5602-
return vessel;
5603-
}
5604-
5605-
5606-
// /**
5607-
// * @nowebref
5608-
// */
5609-
// public PImage requestImage(String filename, String extension, Object params) {
5610-
// PImage vessel = createImage(0, 0, ARGB, params);
5611-
// AsyncImageLoader ail =
5612-
// new AsyncImageLoader(filename, extension, vessel);
5613-
// ail.start();
5614-
// return vessel;
5615-
// }
5616-
5617-
5618-
/**
5619-
* By trial and error, four image loading threads seem to work best when
5620-
* loading images from online. This is consistent with the number of open
5621-
* connections that web browsers will maintain. The variable is made public
5622-
* (however no accessor has been added since it's esoteric) if you really
5623-
* want to have control over the value used. For instance, when loading local
5624-
* files, it might be better to only have a single thread (or two) loading
5625-
* images so that you're disk isn't simply jumping around.
5626-
*/
5627-
public int requestImageMax = 4;
5628-
volatile int requestImageCount;
56295607

5630-
private static final String ASYNC_IMAGE_LOADER_THREAD_PREFIX = "ASYNC_IMAGE_LOADER";
5631-
5632-
class AsyncImageLoader extends Thread {
5633-
String filename;
5634-
String extension;
5635-
PImage vessel;
5636-
5637-
public AsyncImageLoader(String filename, String extension, PImage vessel) {
5638-
// Give these threads distinct name so we can check whether we are loading
5639-
// on the main/background thread; for now they are all named the same
5640-
super(ASYNC_IMAGE_LOADER_THREAD_PREFIX);
5641-
this.filename = filename;
5642-
this.extension = extension;
5643-
this.vessel = vessel;
5608+
// if the image loading thread pool hasn't been created, create it
5609+
if (requestImagePool == null) {
5610+
ThreadFactory factory = new ThreadFactory() {
5611+
public Thread newThread(Runnable r) {
5612+
return new Thread(r, REQUEST_IMAGE_THREAD_PREFIX);
5613+
}
5614+
};
5615+
requestImagePool = Executors.newFixedThreadPool(4, factory);
56445616
}
5645-
5646-
@Override
5647-
public void run() {
5648-
while (requestImageCount == requestImageMax) {
5649-
try {
5650-
Thread.sleep(10);
5651-
} catch (InterruptedException e) { }
5652-
}
5653-
requestImageCount++;
5654-
5617+
requestImagePool.execute(() -> {
56555618
PImage actual = loadImage(filename, extension);
56565619

56575620
// An error message should have already printed
@@ -5669,31 +5632,11 @@ public void run() {
56695632
vessel.pixelHeight = actual.height;
56705633
vessel.pixelDensity = 1;
56715634
}
5672-
requestImageCount--;
5673-
}
5635+
});
5636+
return vessel;
56745637
}
56755638

56765639

5677-
// done internally by ImageIcon
5678-
// /**
5679-
// * Load an AWT image synchronously by setting up a MediaTracker for
5680-
// * a single image, and blocking until it has loaded.
5681-
// */
5682-
// protected PImage loadImageMT(Image awtImage) {
5683-
// MediaTracker tracker = new MediaTracker(this);
5684-
// tracker.addImage(awtImage, 0);
5685-
// try {
5686-
// tracker.waitForAll();
5687-
// } catch (InterruptedException e) {
5688-
// //e.printStackTrace(); // non-fatal, right?
5689-
// }
5690-
//
5691-
// PImage image = new PImage(awtImage);
5692-
// image.parent = this;
5693-
// return image;
5694-
// }
5695-
5696-
56975640
/**
56985641
* Use Java 1.4 ImageIO methods to load an image.
56995642
*/

core/src/processing/data/DoubleDict.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.*;
44
import java.util.HashMap;
55
import java.util.Iterator;
6+
import java.util.Map;
67

78
import processing.core.PApplet;
89

@@ -106,6 +107,20 @@ public DoubleDict(Object[][] pairs) {
106107
}
107108

108109

110+
public DoubleDict(Map<String, Double> incoming) {
111+
count = incoming.size();
112+
keys = new String[count];
113+
values = new double[count];
114+
int index = 0;
115+
for (Map.Entry<String, Double> e : incoming.entrySet()) {
116+
keys[index] = e.getKey();
117+
values[index] = e.getValue();
118+
indices.put(keys[index], index);
119+
index++;
120+
}
121+
}
122+
123+
109124
/**
110125
* @webref doubledict:method
111126
* @brief Returns the number of key/value pairs

core/src/processing/data/Table.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4350,7 +4350,15 @@ public int compare(int index1, int index2) {
43504350
double diffd = getDouble(a, column) - getDouble(b, column);
43514351
return diffd == 0 ? 0 : (diffd < 0 ? -1 : 1);
43524352
case STRING:
4353-
return getString(a, column).compareToIgnoreCase(getString(b, column));
4353+
String string1 = getString(a, column);
4354+
if (string1 == null) {
4355+
string1 = ""; // avoid NPE when cells are left empty
4356+
}
4357+
String string2 = getString(b, column);
4358+
if (string2 == null) {
4359+
string2 = "";
4360+
}
4361+
return string1.compareToIgnoreCase(string2);
43544362
case CATEGORY:
43554363
return getInt(a, column) - getInt(b, column);
43564364
default:

core/src/processing/data/XML.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,14 @@ public void removeChild(XML kid) {
594594
children = null; // TODO not efficient
595595
}
596596

597-
597+
/**
598+
* Removes whitespace nodes.
599+
* Those whitespace nodes are required to reconstruct the original XML's spacing and indentation.
600+
* If you call this and use saveXML() your original spacing will be gone.
601+
*
602+
* @nowebref
603+
* @brief Removes whitespace nodes
604+
*/
598605
public void trim() {
599606
try {
600607
XPathFactory xpathFactory = XPathFactory.newInstance();

core/todo.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
0265 (3.4)
22
X change lack of blendMode() to a warning rather than an error in PDF
33
X rewrite exec() to do threads, also handle fast/excessive output cases
4+
X rewrite requestImage() to fix errors/slowness/concurrency problems
45

56
data classes
67
X add Double and Long versions of the data classes
@@ -10,6 +11,7 @@ X sort only uses the sign of the value
1011
X more accurate than float, especially when using double and long values
1112
X consistently implement write(PrintWriter) in the List and Dict classes
1213
X add save(File) to the List and Dict classes
14+
X prevent Table.sort() from throwing NPE with empty cells
1315
_ Dict.remove() should return value, not index (for consistency w/ others)
1416
_ check again whether element 0,0 in a Table is working
1517
_ https://github.com/processing/processing/issues/3011

java/src/processing/mode/java/JavaEditor.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import processing.app.*;
2222
import processing.app.contrib.*;
2323
import processing.app.syntax.JEditTextArea;
24+
import processing.app.syntax.PdeTextArea;
2425
import processing.app.syntax.PdeTextAreaDefaults;
2526
import processing.app.ui.*;
2627
import processing.app.ui.Toolkit;
@@ -2078,7 +2079,7 @@ public void setCurrentLine(LineID line) {
20782079
cursorToLineStart(line.lineIdx());
20792080
// highlight line
20802081
currentLine = new LineHighlight(line.lineIdx(), this);
2081-
currentLine.setMarker(JavaTextArea.STEP_MARKER);
2082+
currentLine.setMarker(PdeTextArea.STEP_MARKER);
20822083
currentLine.setPriority(10); // fixes current line being hidden by the breakpoint when moved down
20832084
}
20842085

@@ -2107,7 +2108,7 @@ public void clearCurrentLine() {
21072108
*/
21082109
public void addBreakpointedLine(LineID lineID) {
21092110
LineHighlight hl = new LineHighlight(lineID, this);
2110-
hl.setMarker(JavaTextArea.BREAK_MARKER);
2111+
hl.setMarker(PdeTextArea.BREAK_MARKER);
21112112
breakpointedLines.add(hl);
21122113
// repaint current line if it's on this line
21132114
if (currentLine != null && currentLine.getLineID().equals(lineID)) {
@@ -2350,7 +2351,7 @@ private void showImportSuggestion(String[] list, int x, int y) {
23502351
frmImportSuggest = new JFrame();
23512352

23522353
frmImportSuggest.setUndecorated(true);
2353-
frmImportSuggest.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
2354+
frmImportSuggest.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
23542355
JPanel panel = new JPanel();
23552356
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
23562357
panel.setBackground(Color.WHITE);

java/src/processing/mode/java/pdex/DebugTree.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
import java.util.function.Consumer;
1010

1111
import javax.swing.JDialog;
12-
import javax.swing.JFrame;
1312
import javax.swing.JScrollPane;
1413
import javax.swing.JTree;
14+
import javax.swing.WindowConstants;
1515
import javax.swing.tree.DefaultMutableTreeNode;
1616
import javax.swing.tree.DefaultTreeModel;
1717

@@ -24,6 +24,7 @@
2424
import processing.mode.java.JavaEditor;
2525
import processing.mode.java.pdex.PreprocessedSketch.SketchInterval;
2626

27+
2728
class DebugTree {
2829
final JDialog window;
2930
final JTree tree;
@@ -59,7 +60,7 @@ public void componentHidden(ComponentEvent e) {
5960
tree.setModel(null);
6061
}
6162
});
62-
window.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
63+
window.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
6364
window.setBounds(new Rectangle(680, 100, 460, 620));
6465
window.setTitle("AST View - " + editor.getSketch().getName());
6566
JScrollPane sp = new JScrollPane();

java/src/processing/mode/java/pdex/Rename.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
import javax.swing.Box;
1818
import javax.swing.JButton;
1919
import javax.swing.JDialog;
20-
import javax.swing.JFrame;
2120
import javax.swing.JLabel;
2221
import javax.swing.JMenuItem;
2322
import javax.swing.JOptionPane;
2423
import javax.swing.JRootPane;
2524
import javax.swing.JTextField;
25+
import javax.swing.WindowConstants;
2626
import javax.swing.text.BadLocationException;
2727

2828
import org.eclipse.jdt.core.dom.ASTNode;
@@ -73,7 +73,7 @@ class Rename {
7373
window = new JDialog(editor);
7474
JRootPane rootPane = window.getRootPane();
7575
window.setTitle("Rename");
76-
window.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
76+
window.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
7777
Toolkit.registerWindowCloseKeys(rootPane, new ActionListener() {
7878
@Override
7979
public void actionPerformed(ActionEvent e) {

java/src/processing/mode/java/pdex/ShowUsage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
import java.util.stream.Collectors;
1717

1818
import javax.swing.JDialog;
19-
import javax.swing.JFrame;
2019
import javax.swing.JMenuItem;
2120
import javax.swing.JScrollPane;
2221
import javax.swing.JTree;
22+
import javax.swing.WindowConstants;
2323
import javax.swing.tree.DefaultMutableTreeNode;
2424
import javax.swing.tree.DefaultTreeModel;
2525
import javax.swing.tree.TreeModel;
@@ -63,7 +63,7 @@ class ShowUsage {
6363

6464
{ // Show Usage window
6565
window = new JDialog(editor);
66-
window.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
66+
window.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
6767
window.setAutoRequestFocus(false);
6868
window.addComponentListener(new ComponentAdapter() {
6969
@Override

todo.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ X update to Java 8u172
2727
_ Examples dialog causes high CPU load
2828
_ https://github.com/processing/processing/issues/5246
2929

30+
3031
contrib
3132
X updates to Japanese translation
3233
X https://github.com/processing/processing/pull/5263
@@ -37,6 +38,7 @@ X https://github.com/processing/processing/pull/5144
3738
X Update java.lang.UnsupportedClassVersionError message
3839
X https://github.com/processing/processing/pull/5459
3940

41+
4042
welcome
4143
o just remove the welcome dialog; but what should the default behavior be?
4244
o or should it only show up for people who have used <=2 but not 3?
@@ -98,6 +100,8 @@ _ https://github.com/processing/processing/pull/5126
98100

99101

100102
nasty ones
103+
_ errors inside setup() aren't coming through at all?
104+
_ seen in Eclipse; have to turn on the debugger
101105
_ "Sketch disappeared" infinite pop up dialogs
102106
_ https://github.com/processing/processing/pull/4808
103107
_ https://github.com/processing/processing/issues/4805

0 commit comments

Comments
 (0)