propane 3.1.0.pre-java → 3.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/wrapper/maven-wrapper.properties +1 -0
  3. data/CHANGELOG.md +1 -5
  4. data/README.md +23 -12
  5. data/Rakefile +23 -12
  6. data/lib/propane/helpers/version_error.rb +6 -0
  7. data/lib/propane/runner.rb +12 -0
  8. data/lib/propane/version.rb +1 -1
  9. data/library/slider/slider.rb +1 -1
  10. data/mvnw +234 -0
  11. data/mvnw.cmd +145 -0
  12. data/pom.xml +28 -27
  13. data/propane.gemspec +2 -2
  14. data/src/main/java/japplemenubar/JAppleMenuBar.java +41 -47
  15. data/src/main/java/monkstone/ColorUtil.java +1 -1
  16. data/src/main/java/monkstone/MathToolModule.java +12 -11
  17. data/src/main/java/monkstone/PropaneLibrary.java +9 -10
  18. data/src/main/java/monkstone/core/LibraryProxy.java +124 -113
  19. data/src/main/java/monkstone/fastmath/Deglut.java +86 -89
  20. data/src/main/java/monkstone/filechooser/Chooser.java +7 -13
  21. data/src/main/java/monkstone/noise/SimplexNoise.java +0 -1
  22. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +4 -4
  23. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
  24. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +9 -9
  25. data/src/main/java/monkstone/slider/SimpleSlider.java +0 -9
  26. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +11 -13
  27. data/src/main/java/monkstone/slider/Slider.java +1 -1
  28. data/src/main/java/monkstone/slider/SliderBar.java +1 -1
  29. data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
  30. data/src/main/java/monkstone/slider/WheelHandler.java +8 -9
  31. data/src/main/java/monkstone/vecmath/AppRender.java +2 -2
  32. data/src/main/java/monkstone/vecmath/ShapeRender.java +2 -2
  33. data/src/main/java/monkstone/vecmath/package-info.java +2 -2
  34. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +2 -2
  35. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
  36. data/src/main/java/monkstone/videoevent/VideoInterface.java +11 -5
  37. data/src/main/java/monkstone/videoevent/package-info.java +2 -2
  38. data/src/main/java/processing/awt/PGraphicsJava2D.java +1742 -2243
  39. data/src/main/java/processing/awt/PShapeJava2D.java +268 -270
  40. data/src/main/java/processing/awt/PSurfaceAWT.java +821 -920
  41. data/src/main/java/processing/core/DesktopHandler.java +94 -0
  42. data/src/main/java/processing/core/PApplet.java +14170 -14082
  43. data/src/main/java/processing/core/PConstants.java +447 -473
  44. data/src/main/java/processing/core/PFont.java +867 -873
  45. data/src/main/java/processing/core/PGraphics.java +7193 -7428
  46. data/src/main/java/processing/core/PImage.java +3051 -3117
  47. data/src/main/java/processing/core/PMatrix.java +159 -172
  48. data/src/main/java/processing/core/PMatrix2D.java +403 -444
  49. data/src/main/java/processing/core/PMatrix3D.java +735 -749
  50. data/src/main/java/processing/core/PShape.java +2651 -2793
  51. data/src/main/java/processing/core/PShapeOBJ.java +415 -422
  52. data/src/main/java/processing/core/PShapeSVG.java +1466 -1475
  53. data/src/main/java/processing/core/PStyle.java +37 -40
  54. data/src/main/java/processing/core/PSurface.java +98 -103
  55. data/src/main/java/processing/core/PSurfaceNone.java +208 -236
  56. data/src/main/java/processing/core/PVector.java +961 -990
  57. data/src/main/java/processing/data/DoubleDict.java +709 -753
  58. data/src/main/java/processing/data/DoubleList.java +695 -748
  59. data/src/main/java/processing/data/FloatDict.java +702 -746
  60. data/src/main/java/processing/data/FloatList.java +697 -751
  61. data/src/main/java/processing/data/IntDict.java +673 -718
  62. data/src/main/java/processing/data/IntList.java +633 -699
  63. data/src/main/java/processing/data/JSONArray.java +873 -931
  64. data/src/main/java/processing/data/JSONObject.java +1165 -1262
  65. data/src/main/java/processing/data/JSONTokener.java +341 -351
  66. data/src/main/java/processing/data/LongDict.java +662 -707
  67. data/src/main/java/processing/data/LongList.java +634 -700
  68. data/src/main/java/processing/data/Sort.java +41 -37
  69. data/src/main/java/processing/data/StringDict.java +486 -522
  70. data/src/main/java/processing/data/StringList.java +580 -624
  71. data/src/main/java/processing/data/Table.java +3508 -3686
  72. data/src/main/java/processing/data/TableRow.java +183 -182
  73. data/src/main/java/processing/data/XML.java +883 -957
  74. data/src/main/java/processing/event/Event.java +66 -87
  75. data/src/main/java/processing/event/KeyEvent.java +41 -48
  76. data/src/main/java/processing/event/MouseEvent.java +93 -103
  77. data/src/main/java/processing/event/TouchEvent.java +6 -10
  78. data/src/main/java/processing/javafx/PGraphicsFX2D.java +5 -69
  79. data/src/main/java/processing/javafx/PSurfaceFX.java +2 -7
  80. data/src/main/java/processing/opengl/FontTexture.java +270 -290
  81. data/src/main/java/processing/opengl/FrameBuffer.java +363 -375
  82. data/src/main/java/processing/opengl/LinePath.java +500 -543
  83. data/src/main/java/processing/opengl/LineStroker.java +582 -593
  84. data/src/main/java/processing/opengl/PGL.java +2881 -2904
  85. data/src/main/java/processing/opengl/PGraphics2D.java +315 -408
  86. data/src/main/java/processing/opengl/PGraphics3D.java +72 -107
  87. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12043 -12230
  88. data/src/main/java/processing/opengl/PJOGL.java +1681 -1745
  89. data/src/main/java/processing/opengl/PShader.java +1257 -1260
  90. data/src/main/java/processing/opengl/PShapeOpenGL.java +4599 -4662
  91. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1030 -1047
  92. data/src/main/java/processing/opengl/Texture.java +1397 -1462
  93. data/src/main/java/processing/opengl/VertexBuffer.java +55 -57
  94. data/src/main/resources/icon/icon-1024.png +0 -0
  95. data/src/main/resources/icon/icon-128.png +0 -0
  96. data/src/main/resources/icon/icon-16.png +0 -0
  97. data/src/main/resources/icon/icon-256.png +0 -0
  98. data/src/main/resources/icon/icon-32.png +0 -0
  99. data/src/main/resources/icon/icon-48.png +0 -0
  100. data/src/main/resources/icon/icon-512.png +0 -0
  101. data/src/main/resources/icon/icon-64.png +0 -0
  102. data/vendors/Rakefile +1 -1
  103. metadata +12 -8
  104. data/src/main/java/processing/core/ThinkDifferent.java +0 -70
@@ -1,46 +1,50 @@
1
1
  package processing.data;
2
2
 
3
-
4
3
  /**
5
- * Internal sorter used by several data classes.
6
- * Advanced users only, not official API.
4
+ * Internal sorter used by several data classes. Advanced users only, not
5
+ * official API.
7
6
  */
8
7
  public abstract class Sort implements Runnable {
9
8
 
10
- public Sort() { }
9
+ public Sort() {
10
+ }
11
+
12
+ public void run() {
13
+ int c = size();
14
+ if (c > 1) {
15
+ sort(0, c - 1);
16
+ }
17
+ }
11
18
 
19
+ protected void sort(int i, int j) {
20
+ int pivotIndex = (i + j) / 2;
21
+ swap(pivotIndex, j);
22
+ int k = partition(i - 1, j);
23
+ swap(k, j);
24
+ if ((k - i) > 1) {
25
+ sort(i, k - 1);
26
+ }
27
+ if ((j - k) > 1) {
28
+ sort(k + 1, j);
29
+ }
30
+ }
12
31
 
13
- public void run() {
14
- int c = size();
15
- if (c > 1) {
16
- sort(0, c - 1);
32
+ protected int partition(int left, int right) {
33
+ int pivot = right;
34
+ do {
35
+ while (compare(++left, pivot) < 0) {
36
+ }
37
+ while ((right != 0) && (compare(--right, pivot) > 0)) {
38
+ }
39
+ swap(left, right);
40
+ } while (left < right);
41
+ swap(left, right);
42
+ return left;
17
43
  }
18
- }
19
-
20
-
21
- protected void sort(int i, int j) {
22
- int pivotIndex = (i+j)/2;
23
- swap(pivotIndex, j);
24
- int k = partition(i-1, j);
25
- swap(k, j);
26
- if ((k-i) > 1) sort(i, k-1);
27
- if ((j-k) > 1) sort(k+1, j);
28
- }
29
-
30
-
31
- protected int partition(int left, int right) {
32
- int pivot = right;
33
- do {
34
- while (compare(++left, pivot) < 0) { }
35
- while ((right != 0) && (compare(--right, pivot) > 0)) { }
36
- swap(left, right);
37
- } while (left < right);
38
- swap(left, right);
39
- return left;
40
- }
41
-
42
-
43
- abstract public int size();
44
- abstract public int compare(int a, int b);
45
- abstract public void swap(int a, int b);
46
- }
44
+
45
+ abstract public int size();
46
+
47
+ abstract public int compare(int a, int b);
48
+
49
+ abstract public void swap(int a, int b);
50
+ }
@@ -6,7 +6,6 @@ import java.util.Iterator;
6
6
 
7
7
  import processing.core.PApplet;
8
8
 
9
-
10
9
  /**
11
10
  * A simple table class to use a String as a lookup for another String value.
12
11
  *
@@ -16,595 +15,560 @@ import processing.core.PApplet;
16
15
  */
17
16
  public class StringDict {
18
17
 
19
- /** Number of elements in the table */
20
- protected int count;
21
-
22
- protected String[] keys;
23
- protected String[] values;
24
-
25
- /** Internal implementation for faster lookups */
26
- private HashMap<String, Integer> indices = new HashMap<>();
27
-
28
-
29
- public StringDict() {
30
- count = 0;
31
- keys = new String[10];
32
- values = new String[10];
33
- }
34
-
35
-
36
- /**
37
- * Create a new lookup pre-allocated to a specific length. This will not
38
- * change the size(), but is more efficient than not specifying a length.
39
- * Use it when you know the rough size of the thing you're creating.
40
- *
41
- * @nowebref
42
- */
43
- public StringDict(int length) {
44
- count = 0;
45
- keys = new String[length];
46
- values = new String[length];
47
- }
48
-
49
-
50
- /**
51
- * Read a set of entries from a Reader that has each key/value pair on
52
- * a single line, separated by a tab.
53
- *
54
- * @nowebref
55
- */
56
- public StringDict(BufferedReader reader) {
57
- String[] lines = PApplet.loadStrings(reader);
58
- keys = new String[lines.length];
59
- values = new String[lines.length];
60
-
61
- for (int i = 0; i < lines.length; i++) {
62
- String[] pieces = PApplet.split(lines[i], '\t');
63
- if (pieces.length == 2) {
64
- keys[count] = pieces[0];
65
- values[count] = pieces[1];
66
- indices.put(keys[count], count);
67
- count++;
68
- }
69
- }
70
- }
71
-
72
-
73
- /**
74
- * @nowebref
75
- */
76
- public StringDict(String[] keys, String[] values) {
77
- if (keys.length != values.length) {
78
- throw new IllegalArgumentException("key and value arrays must be the same length");
79
- }
80
- this.keys = keys;
81
- this.values = values;
82
- count = keys.length;
83
- for (int i = 0; i < count; i++) {
84
- indices.put(keys[i], i);
85
- }
86
- }
87
-
88
-
89
- /**
90
- * Constructor to allow (more intuitive) inline initialization, e.g.:
91
- * <pre>
92
- * new StringDict(new String[][] {
93
- * { "key1", "value1" },
94
- * { "key2", "value2" }
95
- * });
96
- * </pre>
97
- * It's no Python, but beats a static { } block with HashMap.put() statements.
98
- */
99
- public StringDict(String[][] pairs) {
100
- count = pairs.length;
101
- this.keys = new String[count];
102
- this.values = new String[count];
103
- for (int i = 0; i < count; i++) {
104
- keys[i] = pairs[i][0];
105
- values[i] = pairs[i][1];
106
- indices.put(keys[i], i);
107
- }
108
- }
18
+ /**
19
+ * Number of elements in the table
20
+ */
21
+ protected int count;
109
22
 
23
+ protected String[] keys;
24
+ protected String[] values;
110
25
 
111
- /**
112
- * Create a dictionary that maps between column titles and cell entries
113
- * in a TableRow. If two columns have the same name, the later column's
114
- * values will override the earlier values.
115
- */
116
- public StringDict(TableRow row) {
117
- this(row.getColumnCount());
26
+ /**
27
+ * Internal implementation for faster lookups
28
+ */
29
+ private HashMap<String, Integer> indices = new HashMap<>();
118
30
 
119
- String[] titles = row.getColumnTitles();
120
- if (titles == null) {
121
- titles = new StringList(IntList.fromRange(row.getColumnCount())).array();
122
- }
123
- for (int col = 0; col < row.getColumnCount(); col++) {
124
- set(titles[col], row.getString(col));
31
+ public StringDict() {
32
+ count = 0;
33
+ keys = new String[10];
34
+ values = new String[10];
125
35
  }
126
- // remove unused and overwritten entries
127
- crop();
128
- }
129
36
 
37
+ /**
38
+ * Create a new lookup pre-allocated to a specific length. This will not
39
+ * change the size(), but is more efficient than not specifying a length.
40
+ * Use it when you know the rough size of the thing you're creating.
41
+ *
42
+ * @nowebref
43
+ */
44
+ public StringDict(int length) {
45
+ count = 0;
46
+ keys = new String[length];
47
+ values = new String[length];
48
+ }
130
49
 
131
- /**
132
- * @webref stringdict:method
133
- * @brief Returns the number of key/value pairs
134
- */
135
- public int size() {
136
- return count;
137
- }
50
+ /**
51
+ * Read a set of entries from a Reader that has each key/value pair on a
52
+ * single line, separated by a tab.
53
+ *
54
+ * @nowebref
55
+ */
56
+ public StringDict(BufferedReader reader) {
57
+ String[] lines = PApplet.loadStrings(reader);
58
+ keys = new String[lines.length];
59
+ values = new String[lines.length];
60
+
61
+ for (int i = 0; i < lines.length; i++) {
62
+ String[] pieces = PApplet.split(lines[i], '\t');
63
+ if (pieces.length == 2) {
64
+ keys[count] = pieces[0];
65
+ values[count] = pieces[1];
66
+ indices.put(keys[count], count);
67
+ count++;
68
+ }
69
+ }
70
+ }
138
71
 
72
+ /**
73
+ * @nowebref
74
+ */
75
+ public StringDict(String[] keys, String[] values) {
76
+ if (keys.length != values.length) {
77
+ throw new IllegalArgumentException("key and value arrays must be the same length");
78
+ }
79
+ this.keys = keys;
80
+ this.values = values;
81
+ count = keys.length;
82
+ for (int i = 0; i < count; i++) {
83
+ indices.put(keys[i], i);
84
+ }
85
+ }
139
86
 
140
- /**
141
- * Resize the internal data, this can only be used to shrink the list.
142
- * Helpful for situations like sorting and then grabbing the top 50 entries.
143
- */
144
- public void resize(int length) {
145
- if (length > count) {
146
- throw new IllegalArgumentException("resize() can only be used to shrink the dictionary");
87
+ /**
88
+ * Constructor to allow (more intuitive) inline initialization, e.g.:
89
+ * <pre>
90
+ * new StringDict(new String[][] {
91
+ * { "key1", "value1" },
92
+ * { "key2", "value2" }
93
+ * });
94
+ * </pre> It's no Python, but beats a static { } block with HashMap.put()
95
+ * statements.
96
+ */
97
+ public StringDict(String[][] pairs) {
98
+ count = pairs.length;
99
+ this.keys = new String[count];
100
+ this.values = new String[count];
101
+ for (int i = 0; i < count; i++) {
102
+ keys[i] = pairs[i][0];
103
+ values[i] = pairs[i][1];
104
+ indices.put(keys[i], i);
105
+ }
147
106
  }
148
- if (length < 1) {
149
- throw new IllegalArgumentException("resize(" + length + ") is too small, use 1 or higher");
107
+
108
+ /**
109
+ * Create a dictionary that maps between column titles and cell entries in a
110
+ * TableRow. If two columns have the same name, the later column's values
111
+ * will override the earlier values.
112
+ */
113
+ public StringDict(TableRow row) {
114
+ this(row.getColumnCount());
115
+
116
+ String[] titles = row.getColumnTitles();
117
+ if (titles == null) {
118
+ titles = new StringList(IntList.fromRange(row.getColumnCount())).array();
119
+ }
120
+ for (int col = 0; col < row.getColumnCount(); col++) {
121
+ set(titles[col], row.getString(col));
122
+ }
123
+ // remove unused and overwritten entries
124
+ crop();
150
125
  }
151
126
 
152
- String[] newKeys = new String[length];
153
- String[] newValues = new String[length];
154
- PApplet.arrayCopy(keys, newKeys, length);
155
- PApplet.arrayCopy(values, newValues, length);
156
- keys = newKeys;
157
- values = newValues;
158
- count = length;
159
- resetIndices();
160
- }
127
+ /**
128
+ * @webref stringdict:method
129
+ * @brief Returns the number of key/value pairs
130
+ */
131
+ public int size() {
132
+ return count;
133
+ }
161
134
 
135
+ /**
136
+ * Resize the internal data, this can only be used to shrink the list.
137
+ * Helpful for situations like sorting and then grabbing the top 50 entries.
138
+ */
139
+ public void resize(int length) {
140
+ if (length > count) {
141
+ throw new IllegalArgumentException("resize() can only be used to shrink the dictionary");
142
+ }
143
+ if (length < 1) {
144
+ throw new IllegalArgumentException("resize(" + length + ") is too small, use 1 or higher");
145
+ }
162
146
 
163
- /**
164
- * Remove all entries.
165
- *
166
- * @webref stringdict:method
167
- * @brief Remove all entries
168
- */
169
- public void clear() {
170
- count = 0;
171
- indices = new HashMap<>();
172
- }
147
+ String[] newKeys = new String[length];
148
+ String[] newValues = new String[length];
149
+ PApplet.arrayCopy(keys, newKeys, length);
150
+ PApplet.arrayCopy(values, newValues, length);
151
+ keys = newKeys;
152
+ values = newValues;
153
+ count = length;
154
+ resetIndices();
155
+ }
173
156
 
157
+ /**
158
+ * Remove all entries.
159
+ *
160
+ * @webref stringdict:method
161
+ * @brief Remove all entries
162
+ */
163
+ public void clear() {
164
+ count = 0;
165
+ indices = new HashMap<>();
166
+ }
174
167
 
175
- private void resetIndices() {
176
- indices = new HashMap<>(count);
177
- for (int i = 0; i < count; i++) {
178
- indices.put(keys[i], i);
168
+ private void resetIndices() {
169
+ indices = new HashMap<>(count);
170
+ for (int i = 0; i < count; i++) {
171
+ indices.put(keys[i], i);
172
+ }
179
173
  }
180
- }
181
174
 
175
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
176
+ public class Entry {
182
177
 
183
- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
178
+ public String key;
179
+ public String value;
184
180
 
181
+ Entry(String key, String value) {
182
+ this.key = key;
183
+ this.value = value;
184
+ }
185
+ }
185
186
 
186
- public class Entry {
187
- public String key;
188
- public String value;
187
+ public Iterable<Entry> entries() {
188
+ return new Iterable<Entry>() {
189
189
 
190
- Entry(String key, String value) {
191
- this.key = key;
192
- this.value = value;
190
+ public Iterator<Entry> iterator() {
191
+ return entryIterator();
192
+ }
193
+ };
193
194
  }
194
- }
195
195
 
196
+ public Iterator<Entry> entryIterator() {
197
+ return new Iterator<Entry>() {
198
+ int index = -1;
199
+
200
+ public void remove() {
201
+ removeIndex(index);
202
+ index--;
203
+ }
204
+
205
+ public Entry next() {
206
+ ++index;
207
+ Entry e = new Entry(keys[index], values[index]);
208
+ return e;
209
+ }
210
+
211
+ public boolean hasNext() {
212
+ return index + 1 < size();
213
+ }
214
+ };
215
+ }
196
216
 
197
- public Iterable<Entry> entries() {
198
- return new Iterable<Entry>() {
199
-
200
- public Iterator<Entry> iterator() {
201
- return entryIterator();
202
- }
203
- };
204
- }
217
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
218
+ public String key(int index) {
219
+ return keys[index];
220
+ }
205
221
 
222
+ protected void crop() {
223
+ if (count != keys.length) {
224
+ keys = PApplet.subset(keys, 0, count);
225
+ values = PApplet.subset(values, 0, count);
226
+ }
227
+ }
206
228
 
207
- public Iterator<Entry> entryIterator() {
208
- return new Iterator<Entry>() {
209
- int index = -1;
229
+ public Iterable<String> keys() {
230
+ return new Iterable<String>() {
210
231
 
211
- public void remove() {
212
- removeIndex(index);
213
- index--;
214
- }
232
+ @Override
233
+ public Iterator<String> iterator() {
234
+ return keyIterator();
235
+ }
236
+ };
237
+ }
215
238
 
216
- public Entry next() {
217
- ++index;
218
- Entry e = new Entry(keys[index], values[index]);
219
- return e;
220
- }
239
+ // Use this to iterate when you want to be able to remove elements along the way
240
+ public Iterator<String> keyIterator() {
241
+ return new Iterator<String>() {
242
+ int index = -1;
221
243
 
222
- public boolean hasNext() {
223
- return index+1 < size();
224
- }
225
- };
226
- }
244
+ public void remove() {
245
+ removeIndex(index);
246
+ index--;
247
+ }
227
248
 
249
+ public String next() {
250
+ return key(++index);
251
+ }
228
252
 
229
- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
253
+ public boolean hasNext() {
254
+ return index + 1 < size();
255
+ }
256
+ };
257
+ }
230
258
 
259
+ /**
260
+ * Return a copy of the internal keys array. This array can be modified.
261
+ *
262
+ * @webref stringdict:method
263
+ * @brief Return a copy of the internal keys array
264
+ */
265
+ public String[] keyArray() {
266
+ crop();
267
+ return keyArray(null);
268
+ }
231
269
 
232
- public String key(int index) {
233
- return keys[index];
234
- }
270
+ public String[] keyArray(String[] outgoing) {
271
+ if (outgoing == null || outgoing.length != count) {
272
+ outgoing = new String[count];
273
+ }
274
+ System.arraycopy(keys, 0, outgoing, 0, count);
275
+ return outgoing;
276
+ }
235
277
 
278
+ public String value(int index) {
279
+ return values[index];
280
+ }
236
281
 
237
- protected void crop() {
238
- if (count != keys.length) {
239
- keys = PApplet.subset(keys, 0, count);
240
- values = PApplet.subset(values, 0, count);
282
+ /**
283
+ * @webref stringdict:method
284
+ * @brief Return the internal array being used to store the values
285
+ */
286
+ public Iterable<String> values() {
287
+ return new Iterable<String>() {
288
+
289
+ @Override
290
+ public Iterator<String> iterator() {
291
+ return valueIterator();
292
+ }
293
+ };
241
294
  }
242
- }
243
295
 
296
+ public Iterator<String> valueIterator() {
297
+ return new Iterator<String>() {
298
+ int index = -1;
244
299
 
245
- public Iterable<String> keys() {
246
- return new Iterable<String>() {
300
+ public void remove() {
301
+ removeIndex(index);
302
+ index--;
303
+ }
247
304
 
248
- @Override
249
- public Iterator<String> iterator() {
250
- return keyIterator();
251
- }
252
- };
253
- }
305
+ public String next() {
306
+ return value(++index);
307
+ }
254
308
 
309
+ public boolean hasNext() {
310
+ return index + 1 < size();
311
+ }
312
+ };
313
+ }
255
314
 
256
- // Use this to iterate when you want to be able to remove elements along the way
257
- public Iterator<String> keyIterator() {
258
- return new Iterator<String>() {
259
- int index = -1;
315
+ /**
316
+ * Create a new array and copy each of the values into it.
317
+ *
318
+ * @webref stringdict:method
319
+ * @brief Create a new array and copy each of the values into it
320
+ */
321
+ public String[] valueArray() {
322
+ crop();
323
+ return valueArray(null);
324
+ }
260
325
 
261
- public void remove() {
262
- removeIndex(index);
263
- index--;
264
- }
326
+ /**
327
+ * Fill an already-allocated array with the values (more efficient than
328
+ * creating a new array each time). If 'array' is null, or not the same size
329
+ * as the number of values, a new array will be allocated and returned.
330
+ */
331
+ public String[] valueArray(String[] array) {
332
+ if (array == null || array.length != size()) {
333
+ array = new String[count];
334
+ }
335
+ System.arraycopy(values, 0, array, 0, count);
336
+ return array;
337
+ }
265
338
 
266
- public String next() {
267
- return key(++index);
268
- }
339
+ /**
340
+ * Return a value for the specified key.
341
+ *
342
+ * @webref stringdict:method
343
+ * @brief Return a value for the specified key
344
+ */
345
+ public String get(String key) {
346
+ int index = index(key);
347
+ if (index == -1) {
348
+ return null;
349
+ }
350
+ return values[index];
351
+ }
269
352
 
270
- public boolean hasNext() {
271
- return index+1 < size();
272
- }
273
- };
274
- }
353
+ public String get(String key, String alternate) {
354
+ int index = index(key);
355
+ if (index == -1) {
356
+ return alternate;
357
+ }
358
+ return values[index];
359
+ }
275
360
 
361
+ /**
362
+ * @webref stringdict:method
363
+ * @brief Create a new key/value pair or change the value of one
364
+ */
365
+ public void set(String key, String value) {
366
+ int index = index(key);
367
+ if (index == -1) {
368
+ create(key, value);
369
+ } else {
370
+ values[index] = value;
371
+ }
372
+ }
276
373
 
277
- /**
278
- * Return a copy of the internal keys array. This array can be modified.
279
- *
280
- * @webref stringdict:method
281
- * @brief Return a copy of the internal keys array
282
- */
283
- public String[] keyArray() {
284
- crop();
285
- return keyArray(null);
286
- }
374
+ public void setIndex(int index, String key, String value) {
375
+ if (index < 0 || index >= count) {
376
+ throw new ArrayIndexOutOfBoundsException(index);
377
+ }
378
+ keys[index] = key;
379
+ values[index] = value;
380
+ }
287
381
 
382
+ public int index(String what) {
383
+ Integer found = indices.get(what);
384
+ return (found == null) ? -1 : found.intValue();
385
+ }
288
386
 
289
- public String[] keyArray(String[] outgoing) {
290
- if (outgoing == null || outgoing.length != count) {
291
- outgoing = new String[count];
292
- }
293
- System.arraycopy(keys, 0, outgoing, 0, count);
294
- return outgoing;
295
- }
387
+ /**
388
+ * @webref stringdict:method
389
+ * @brief Check if a key is a part of the data structure
390
+ */
391
+ public boolean hasKey(String key) {
392
+ return index(key) != -1;
393
+ }
296
394
 
395
+ protected void create(String key, String value) {
396
+ if (count == keys.length) {
397
+ keys = PApplet.expand(keys);
398
+ values = PApplet.expand(values);
399
+ }
400
+ indices.put(key, Integer.valueOf(count));
401
+ keys[count] = key;
402
+ values[count] = value;
403
+ count++;
404
+ }
297
405
 
298
- public String value(int index) {
299
- return values[index];
300
- }
301
-
302
- /**
303
- * @webref stringdict:method
304
- * @brief Return the internal array being used to store the values
305
- */
306
- public Iterable<String> values() {
307
- return new Iterable<String>() {
308
-
309
- @Override
310
- public Iterator<String> iterator() {
311
- return valueIterator();
312
- }
313
- };
314
- }
315
-
316
-
317
- public Iterator<String> valueIterator() {
318
- return new Iterator<String>() {
319
- int index = -1;
406
+ /**
407
+ * @webref stringdict:method
408
+ * @brief Remove a key/value pair
409
+ */
410
+ public int remove(String key) {
411
+ int index = index(key);
412
+ if (index != -1) {
413
+ removeIndex(index);
414
+ }
415
+ return index;
416
+ }
320
417
 
321
- public void remove() {
322
- removeIndex(index);
323
- index--;
324
- }
418
+ public String removeIndex(int index) {
419
+ if (index < 0 || index >= count) {
420
+ throw new ArrayIndexOutOfBoundsException(index);
421
+ }
422
+ //System.out.println("index is " + which + " and " + keys[which]);
423
+ String key = keys[index];
424
+ indices.remove(key);
425
+ for (int i = index; i < count - 1; i++) {
426
+ keys[i] = keys[i + 1];
427
+ values[i] = values[i + 1];
428
+ indices.put(keys[i], i);
429
+ }
430
+ count--;
431
+ keys[count] = null;
432
+ values[count] = null;
433
+ return key;
434
+ }
325
435
 
326
- public String next() {
327
- return value(++index);
328
- }
329
-
330
- public boolean hasNext() {
331
- return index+1 < size();
332
- }
333
- };
334
- }
335
-
336
-
337
- /**
338
- * Create a new array and copy each of the values into it.
339
- *
340
- * @webref stringdict:method
341
- * @brief Create a new array and copy each of the values into it
342
- */
343
- public String[] valueArray() {
344
- crop();
345
- return valueArray(null);
346
- }
347
-
348
-
349
- /**
350
- * Fill an already-allocated array with the values (more efficient than
351
- * creating a new array each time). If 'array' is null, or not the same
352
- * size as the number of values, a new array will be allocated and returned.
353
- */
354
- public String[] valueArray(String[] array) {
355
- if (array == null || array.length != size()) {
356
- array = new String[count];
357
- }
358
- System.arraycopy(values, 0, array, 0, count);
359
- return array;
360
- }
361
-
362
-
363
- /**
364
- * Return a value for the specified key.
365
- *
366
- * @webref stringdict:method
367
- * @brief Return a value for the specified key
368
- */
369
- public String get(String key) {
370
- int index = index(key);
371
- if (index == -1) return null;
372
- return values[index];
373
- }
374
-
375
-
376
- public String get(String key, String alternate) {
377
- int index = index(key);
378
- if (index == -1) return alternate;
379
- return values[index];
380
- }
381
-
382
-
383
- /**
384
- * @webref stringdict:method
385
- * @brief Create a new key/value pair or change the value of one
386
- */
387
- public void set(String key, String value) {
388
- int index = index(key);
389
- if (index == -1) {
390
- create(key, value);
391
- } else {
392
- values[index] = value;
393
- }
394
- }
395
-
396
-
397
- public void setIndex(int index, String key, String value) {
398
- if (index < 0 || index >= count) {
399
- throw new ArrayIndexOutOfBoundsException(index);
400
- }
401
- keys[index] = key;
402
- values[index] = value;
403
- }
404
-
405
-
406
- public int index(String what) {
407
- Integer found = indices.get(what);
408
- return (found == null) ? -1 : found.intValue();
409
- }
410
-
411
-
412
- /**
413
- * @webref stringdict:method
414
- * @brief Check if a key is a part of the data structure
415
- */
416
- public boolean hasKey(String key) {
417
- return index(key) != -1;
418
- }
419
-
420
-
421
- protected void create(String key, String value) {
422
- if (count == keys.length) {
423
- keys = PApplet.expand(keys);
424
- values = PApplet.expand(values);
425
- }
426
- indices.put(key, Integer.valueOf(count));
427
- keys[count] = key;
428
- values[count] = value;
429
- count++;
430
- }
431
-
432
- /**
433
- * @webref stringdict:method
434
- * @brief Remove a key/value pair
435
- */
436
- public int remove(String key) {
437
- int index = index(key);
438
- if (index != -1) {
439
- removeIndex(index);
440
- }
441
- return index;
442
- }
443
-
444
-
445
- public String removeIndex(int index) {
446
- if (index < 0 || index >= count) {
447
- throw new ArrayIndexOutOfBoundsException(index);
448
- }
449
- //System.out.println("index is " + which + " and " + keys[which]);
450
- String key = keys[index];
451
- indices.remove(key);
452
- for (int i = index; i < count-1; i++) {
453
- keys[i] = keys[i+1];
454
- values[i] = values[i+1];
455
- indices.put(keys[i], i);
456
- }
457
- count--;
458
- keys[count] = null;
459
- values[count] = null;
460
- return key;
461
- }
462
-
463
-
464
- public void swap(int a, int b) {
465
- String tkey = keys[a];
466
- String tvalue = values[a];
467
- keys[a] = keys[b];
468
- values[a] = values[b];
469
- keys[b] = tkey;
470
- values[b] = tvalue;
436
+ public void swap(int a, int b) {
437
+ String tkey = keys[a];
438
+ String tvalue = values[a];
439
+ keys[a] = keys[b];
440
+ values[a] = values[b];
441
+ keys[b] = tkey;
442
+ values[b] = tvalue;
471
443
 
472
444
  // indices.put(keys[a], Integer.valueOf(a));
473
445
  // indices.put(keys[b], Integer.valueOf(b));
474
- }
475
-
476
-
477
- /**
478
- * Sort the keys alphabetically (ignoring case). Uses the value as a
479
- * tie-breaker (only really possible with a key that has a case change).
480
- *
481
- * @webref stringdict:method
482
- * @brief Sort the keys alphabetically
483
- */
484
- public void sortKeys() {
485
- sortImpl(true, false);
486
- }
487
-
488
- /**
489
- * @webref stringdict:method
490
- * @brief Sort the keys alphabetically in reverse
491
- */
492
- public void sortKeysReverse() {
493
- sortImpl(true, true);
494
- }
495
-
496
-
497
- /**
498
- * Sort by values in descending order (largest value will be at [0]).
499
- *
500
- * @webref stringdict:method
501
- * @brief Sort by values in ascending order
502
- */
503
- public void sortValues() {
504
- sortImpl(false, false);
505
- }
506
-
507
-
508
- /**
509
- * @webref stringdict:method
510
- * @brief Sort by values in descending order
511
- */
512
- public void sortValuesReverse() {
513
- sortImpl(false, true);
514
- }
515
-
516
-
517
- protected void sortImpl(final boolean useKeys, final boolean reverse) {
518
- Sort s = new Sort() {
519
- @Override
520
- public int size() {
521
- return count;
522
- }
523
-
524
- @Override
525
- public int compare(int a, int b) {
526
- int diff = 0;
527
- if (useKeys) {
528
- diff = keys[a].compareToIgnoreCase(keys[b]);
529
- if (diff == 0) {
530
- diff = values[a].compareToIgnoreCase(values[b]);
531
- }
532
- } else { // sort values
533
- diff = values[a].compareToIgnoreCase(values[b]);
534
- if (diff == 0) {
535
- diff = keys[a].compareToIgnoreCase(keys[b]);
536
- }
537
- }
538
- return reverse ? -diff : diff;
539
- }
540
-
541
- @Override
542
- public void swap(int a, int b) {
543
- StringDict.this.swap(a, b);
544
- }
545
- };
546
- s.run();
547
-
548
- // Set the indices after sort/swaps (performance fix 160411)
549
- resetIndices();
550
- }
551
-
446
+ }
552
447
 
553
- /** Returns a duplicate copy of this object. */
554
- public StringDict copy() {
555
- StringDict outgoing = new StringDict(count);
556
- System.arraycopy(keys, 0, outgoing.keys, 0, count);
557
- System.arraycopy(values, 0, outgoing.values, 0, count);
558
- for (int i = 0; i < count; i++) {
559
- outgoing.indices.put(keys[i], i);
448
+ /**
449
+ * Sort the keys alphabetically (ignoring case). Uses the value as a
450
+ * tie-breaker (only really possible with a key that has a case change).
451
+ *
452
+ * @webref stringdict:method
453
+ * @brief Sort the keys alphabetically
454
+ */
455
+ public void sortKeys() {
456
+ sortImpl(true, false);
560
457
  }
561
- outgoing.count = count;
562
- return outgoing;
563
- }
564
458
 
459
+ /**
460
+ * @webref stringdict:method
461
+ * @brief Sort the keys alphabetically in reverse
462
+ */
463
+ public void sortKeysReverse() {
464
+ sortImpl(true, true);
465
+ }
565
466
 
566
- public void print() {
567
- for (int i = 0; i < size(); i++) {
568
- System.out.println(keys[i] + " = " + values[i]);
467
+ /**
468
+ * Sort by values in descending order (largest value will be at [0]).
469
+ *
470
+ * @webref stringdict:method
471
+ * @brief Sort by values in ascending order
472
+ */
473
+ public void sortValues() {
474
+ sortImpl(false, false);
569
475
  }
570
- }
571
476
 
477
+ /**
478
+ * @webref stringdict:method
479
+ * @brief Sort by values in descending order
480
+ */
481
+ public void sortValuesReverse() {
482
+ sortImpl(false, true);
483
+ }
572
484
 
573
- /**
574
- * Save tab-delimited entries to a file (TSV format, UTF-8 encoding)
575
- */
576
- public void save(File file) {
577
- PrintWriter writer = PApplet.createWriter(file);
578
- write(writer);
579
- writer.close();
580
- }
485
+ protected void sortImpl(final boolean useKeys, final boolean reverse) {
486
+ Sort s = new Sort() {
487
+ @Override
488
+ public int size() {
489
+ return count;
490
+ }
491
+
492
+ @Override
493
+ public int compare(int a, int b) {
494
+ int diff = 0;
495
+ if (useKeys) {
496
+ diff = keys[a].compareToIgnoreCase(keys[b]);
497
+ if (diff == 0) {
498
+ diff = values[a].compareToIgnoreCase(values[b]);
499
+ }
500
+ } else { // sort values
501
+ diff = values[a].compareToIgnoreCase(values[b]);
502
+ if (diff == 0) {
503
+ diff = keys[a].compareToIgnoreCase(keys[b]);
504
+ }
505
+ }
506
+ return reverse ? -diff : diff;
507
+ }
508
+
509
+ @Override
510
+ public void swap(int a, int b) {
511
+ StringDict.this.swap(a, b);
512
+ }
513
+ };
514
+ s.run();
515
+
516
+ // Set the indices after sort/swaps (performance fix 160411)
517
+ resetIndices();
518
+ }
581
519
 
520
+ /**
521
+ * Returns a duplicate copy of this object.
522
+ */
523
+ public StringDict copy() {
524
+ StringDict outgoing = new StringDict(count);
525
+ System.arraycopy(keys, 0, outgoing.keys, 0, count);
526
+ System.arraycopy(values, 0, outgoing.values, 0, count);
527
+ for (int i = 0; i < count; i++) {
528
+ outgoing.indices.put(keys[i], i);
529
+ }
530
+ outgoing.count = count;
531
+ return outgoing;
532
+ }
582
533
 
583
- /**
584
- * Write tab-delimited entries to a PrintWriter
585
- */
586
- public void write(PrintWriter writer) {
587
- for (int i = 0; i < count; i++) {
588
- writer.println(keys[i] + "\t" + values[i]);
534
+ public void print() {
535
+ for (int i = 0; i < size(); i++) {
536
+ System.out.println(keys[i] + " = " + values[i]);
537
+ }
589
538
  }
590
- writer.flush();
591
- }
592
539
 
540
+ /**
541
+ * Save tab-delimited entries to a file (TSV format, UTF-8 encoding)
542
+ */
543
+ public void save(File file) {
544
+ PrintWriter writer = PApplet.createWriter(file);
545
+ write(writer);
546
+ writer.close();
547
+ }
593
548
 
594
- /**
595
- * Return this dictionary as a String in JSON format.
596
- */
597
- public String toJSON() {
598
- StringList items = new StringList();
599
- for (int i = 0; i < count; i++) {
600
- items.append(JSONObject.quote(keys[i])+ ": " + JSONObject.quote(values[i]));
549
+ /**
550
+ * Write tab-delimited entries to a PrintWriter
551
+ */
552
+ public void write(PrintWriter writer) {
553
+ for (int i = 0; i < count; i++) {
554
+ writer.println(keys[i] + "\t" + values[i]);
555
+ }
556
+ writer.flush();
601
557
  }
602
- return "{ " + items.join(", ") + " }";
603
- }
604
558
 
559
+ /**
560
+ * Return this dictionary as a String in JSON format.
561
+ */
562
+ public String toJSON() {
563
+ StringList items = new StringList();
564
+ for (int i = 0; i < count; i++) {
565
+ items.append(JSONObject.quote(keys[i]) + ": " + JSONObject.quote(values[i]));
566
+ }
567
+ return "{ " + items.join(", ") + " }";
568
+ }
605
569
 
606
- @Override
607
- public String toString() {
608
- return getClass().getSimpleName() + " size=" + size() + " " + toJSON();
609
- }
570
+ @Override
571
+ public String toString() {
572
+ return getClass().getSimpleName() + " size=" + size() + " " + toJSON();
573
+ }
610
574
  }