propane 3.6.0-java → 3.10.0-java

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