propane 3.1.0.pre-java → 3.2.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }