propane 3.6.0-java → 3.10.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 (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,807 @@
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 class to use a String as a lookup for an int value.
13
+ *
14
+ * @webref data:composite
15
+ * @see FloatDict
16
+ * @see StringDict
17
+ */
18
+ public class IntDict {
19
+
20
+ /** Number of elements in the table */
21
+ protected int count;
22
+
23
+ protected String[] keys;
24
+ protected int[] values;
25
+
26
+ /** Internal implementation for faster lookups */
27
+ private HashMap<String, Integer> indices = new HashMap<>();
28
+
29
+
30
+ public IntDict() {
31
+ count = 0;
32
+ keys = new String[10];
33
+ values = new int[10];
34
+ }
35
+
36
+
37
+ /**
38
+ * Create a new lookup with a specific size. This is more efficient than not
39
+ * specifying a size. Use it when you know the rough size of the thing you're creating.
40
+ *
41
+ * @nowebref
42
+ */
43
+ public IntDict(int length) {
44
+ count = 0;
45
+ keys = new String[length];
46
+ values = new int[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 IntDict(BufferedReader reader) {
57
+ String[] lines = PApplet.loadStrings(reader);
58
+ keys = new String[lines.length];
59
+ values = new int[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] = PApplet.parseInt(pieces[1]);
66
+ indices.put(pieces[0], count);
67
+ count++;
68
+ }
69
+ }
70
+ }
71
+
72
+ /**
73
+ * @nowebref
74
+ */
75
+ public IntDict(String[] keys, int[] 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
+ }
86
+
87
+
88
+ /**
89
+ * Constructor to allow (more intuitive) inline initialization, e.g.:
90
+ * <pre>
91
+ * new FloatDict(new Object[][] {
92
+ * { "key1", 1 },
93
+ * { "key2", 2 }
94
+ * });
95
+ * </pre>
96
+ */
97
+ public IntDict(Object[][] pairs) {
98
+ count = pairs.length;
99
+ this.keys = new String[count];
100
+ this.values = new int[count];
101
+ for (int i = 0; i < count; i++) {
102
+ keys[i] = (String) pairs[i][0];
103
+ values[i] = (Integer) pairs[i][1];
104
+ indices.put(keys[i], i);
105
+ }
106
+ }
107
+
108
+
109
+ /**
110
+ * Returns the number of key/value pairs
111
+ *
112
+ * @webref intdict:method
113
+ * @brief Returns the number of key/value pairs
114
+ */
115
+ public int size() {
116
+ return count;
117
+ }
118
+
119
+
120
+ /**
121
+ * Resize the internal data, this can only be used to shrink the list.
122
+ * Helpful for situations like sorting and then grabbing the top 50 entries.
123
+ */
124
+ public void resize(int length) {
125
+ if (length > count) {
126
+ throw new IllegalArgumentException("resize() can only be used to shrink the dictionary");
127
+ }
128
+ if (length < 1) {
129
+ throw new IllegalArgumentException("resize(" + length + ") is too small, use 1 or higher");
130
+ }
131
+
132
+ String[] newKeys = new String[length];
133
+ int[] newValues = new int[length];
134
+ PApplet.arrayCopy(keys, newKeys, length);
135
+ PApplet.arrayCopy(values, newValues, length);
136
+ keys = newKeys;
137
+ values = newValues;
138
+ count = length;
139
+ resetIndices();
140
+ }
141
+
142
+
143
+ /**
144
+ * Remove all entries.
145
+ *
146
+ * @webref intdict:method
147
+ * @brief Remove all entries
148
+ */
149
+ public void clear() {
150
+ count = 0;
151
+ indices = new HashMap<>();
152
+ }
153
+
154
+
155
+ private void resetIndices() {
156
+ indices = new HashMap<>(count);
157
+ for (int i = 0; i < count; i++) {
158
+ indices.put(keys[i], i);
159
+ }
160
+ }
161
+
162
+
163
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
164
+
165
+
166
+ public class Entry {
167
+ public String key;
168
+ public int value;
169
+
170
+ Entry(String key, int value) {
171
+ this.key = key;
172
+ this.value = value;
173
+ }
174
+ }
175
+
176
+
177
+ public Iterable<Entry> entries() {
178
+ return new Iterable<Entry>() {
179
+
180
+ public Iterator<Entry> iterator() {
181
+ return entryIterator();
182
+ }
183
+ };
184
+ }
185
+
186
+
187
+ public Iterator<Entry> entryIterator() {
188
+ return new Iterator<Entry>() {
189
+ int index = -1;
190
+
191
+ public void remove() {
192
+ removeIndex(index);
193
+ index--;
194
+ }
195
+
196
+ public Entry next() {
197
+ ++index;
198
+ Entry e = new Entry(keys[index], values[index]);
199
+ return e;
200
+ }
201
+
202
+ public boolean hasNext() {
203
+ return index+1 < size();
204
+ }
205
+ };
206
+ }
207
+
208
+
209
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
210
+
211
+
212
+ public String key(int index) {
213
+ return keys[index];
214
+ }
215
+
216
+
217
+ protected void crop() {
218
+ if (count != keys.length) {
219
+ keys = PApplet.subset(keys, 0, count);
220
+ values = PApplet.subset(values, 0, count);
221
+ }
222
+ }
223
+
224
+
225
+ public Iterable<String> keys() {
226
+ return new Iterable<String>() {
227
+
228
+ @Override
229
+ public Iterator<String> iterator() {
230
+ return keyIterator();
231
+ }
232
+ };
233
+ }
234
+
235
+
236
+ // Use this to iterate when you want to be able to remove elements along the way
237
+ public Iterator<String> keyIterator() {
238
+ return new Iterator<String>() {
239
+ int index = -1;
240
+
241
+ public void remove() {
242
+ removeIndex(index);
243
+ index--;
244
+ }
245
+
246
+ public String next() {
247
+ return key(++index);
248
+ }
249
+
250
+ public boolean hasNext() {
251
+ return index+1 < size();
252
+ }
253
+ };
254
+ }
255
+
256
+
257
+ /**
258
+ * Return a copy of the internal keys array. This array can be modified.
259
+ *
260
+ * @webref intdict:method
261
+ * @brief Return a copy of the internal keys array
262
+ */
263
+ public String[] keyArray() {
264
+ crop();
265
+ return keyArray(null);
266
+ }
267
+
268
+
269
+ public String[] keyArray(String[] outgoing) {
270
+ if (outgoing == null || outgoing.length != count) {
271
+ outgoing = new String[count];
272
+ }
273
+ System.arraycopy(keys, 0, outgoing, 0, count);
274
+ return outgoing;
275
+ }
276
+
277
+
278
+ public int value(int index) {
279
+ return values[index];
280
+ }
281
+
282
+
283
+ /**
284
+ * @webref intdict:method
285
+ * @brief Return the internal array being used to store the values
286
+ */
287
+ public Iterable<Integer> values() {
288
+ return new Iterable<Integer>() {
289
+
290
+ @Override
291
+ public Iterator<Integer> iterator() {
292
+ return valueIterator();
293
+ }
294
+ };
295
+ }
296
+
297
+
298
+ public Iterator<Integer> valueIterator() {
299
+ return new Iterator<Integer>() {
300
+ int index = -1;
301
+
302
+ public void remove() {
303
+ removeIndex(index);
304
+ index--;
305
+ }
306
+
307
+ public Integer next() {
308
+ return value(++index);
309
+ }
310
+
311
+ public boolean hasNext() {
312
+ return index+1 < size();
313
+ }
314
+ };
315
+ }
316
+
317
+
318
+ /**
319
+ * Create a new array and copy each of the values into it.
320
+ *
321
+ * @webref intdict:method
322
+ * @brief Create a new array and copy each of the values into it
323
+ */
324
+ public int[] valueArray() {
325
+ crop();
326
+ return valueArray(null);
327
+ }
328
+
329
+
330
+ /**
331
+ * Fill an already-allocated array with the values (more efficient than
332
+ * creating a new array each time). If 'array' is null, or not the same
333
+ * size as the number of values, a new array will be allocated and returned.
334
+ *
335
+ * @param array values to copy into the array
336
+ */
337
+ public int[] valueArray(int[] array) {
338
+ if (array == null || array.length != size()) {
339
+ array = new int[count];
340
+ }
341
+ System.arraycopy(values, 0, array, 0, count);
342
+ return array;
343
+ }
344
+
345
+
346
+ /**
347
+ * Return a value for the specified key.
348
+ *
349
+ * @webref intdict:method
350
+ * @brief Return a value for the specified key
351
+ */
352
+ public int get(String key) {
353
+ int index = index(key);
354
+ if (index == -1) {
355
+ throw new IllegalArgumentException("No key named '" + key + "'");
356
+ }
357
+ return values[index];
358
+ }
359
+
360
+
361
+ public int get(String key, int alternate) {
362
+ int index = index(key);
363
+ if (index == -1) return alternate;
364
+ return values[index];
365
+ }
366
+
367
+
368
+ /**
369
+ * Create a new key/value pair or change the value of one.
370
+ *
371
+ * @webref intdict:method
372
+ * @brief Create a new key/value pair or change the value of one
373
+ */
374
+ public void set(String key, int amount) {
375
+ int index = index(key);
376
+ if (index == -1) {
377
+ create(key, amount);
378
+ } else {
379
+ values[index] = amount;
380
+ }
381
+ }
382
+
383
+
384
+ public void setIndex(int index, String key, int value) {
385
+ if (index < 0 || index >= count) {
386
+ throw new ArrayIndexOutOfBoundsException(index);
387
+ }
388
+ keys[index] = key;
389
+ values[index] = value;
390
+ }
391
+
392
+
393
+ /**
394
+ * @webref intdict:method
395
+ * @brief Check if a key is a part of the data structure
396
+ */
397
+ public boolean hasKey(String key) {
398
+ return index(key) != -1;
399
+ }
400
+
401
+
402
+ /**
403
+ * Increase the value associated with a specific key by 1.
404
+ *
405
+ * @webref intdict:method
406
+ * @brief Increase the value of a specific key value by 1
407
+ */
408
+ public void increment(String key) {
409
+ add(key, 1);
410
+ }
411
+
412
+
413
+ /**
414
+ * Merge another dictionary into this one. Calling this increment()
415
+ * since it doesn't make sense in practice for the other dictionary types,
416
+ * even though it's technically an add().
417
+ */
418
+ public void increment(IntDict dict) {
419
+ for (int i = 0; i < dict.count; i++) {
420
+ add(dict.key(i), dict.value(i));
421
+ }
422
+ }
423
+
424
+
425
+ /**
426
+ * @webref intdict:method
427
+ * @brief Add to a value
428
+ */
429
+ public void add(String key, int amount) {
430
+ int index = index(key);
431
+ if (index == -1) {
432
+ create(key, amount);
433
+ } else {
434
+ values[index] += amount;
435
+ }
436
+ }
437
+
438
+
439
+ /**
440
+ * @webref intdict:method
441
+ * @brief Subtract from a value
442
+ */
443
+ public void sub(String key, int amount) {
444
+ add(key, -amount);
445
+ }
446
+
447
+
448
+ /**
449
+ * @webref intdict:method
450
+ * @brief Multiply a value
451
+ */
452
+ public void mult(String key, int amount) {
453
+ int index = index(key);
454
+ if (index != -1) {
455
+ values[index] *= amount;
456
+ }
457
+ }
458
+
459
+
460
+ /**
461
+ * @webref intdict:method
462
+ * @brief Divide a value
463
+ */
464
+ public void div(String key, int amount) {
465
+ int index = index(key);
466
+ if (index != -1) {
467
+ values[index] /= amount;
468
+ }
469
+ }
470
+
471
+
472
+ private void checkMinMax(String functionName) {
473
+ if (count == 0) {
474
+ String msg =
475
+ String.format("Cannot use %s() on an empty %s.",
476
+ functionName, getClass().getSimpleName());
477
+ throw new RuntimeException(msg);
478
+ }
479
+ }
480
+
481
+
482
+ // return the index of the minimum value
483
+ public int minIndex() {
484
+ //checkMinMax("minIndex");
485
+ if (count == 0) return -1;
486
+
487
+ int index = 0;
488
+ int value = values[0];
489
+ for (int i = 1; i < count; i++) {
490
+ if (values[i] < value) {
491
+ index = i;
492
+ value = values[i];
493
+ }
494
+ }
495
+ return index;
496
+ }
497
+
498
+
499
+ // return the key for the minimum value
500
+ public String minKey() {
501
+ checkMinMax("minKey");
502
+ int index = minIndex();
503
+ if (index == -1) {
504
+ return null;
505
+ }
506
+ return keys[index];
507
+ }
508
+
509
+
510
+ // return the minimum value, or throw an error if there are no values
511
+ public int minValue() {
512
+ checkMinMax("minValue");
513
+ return values[minIndex()];
514
+ }
515
+
516
+
517
+ // return the index of the max value
518
+ public int maxIndex() {
519
+ //checkMinMax("maxIndex");
520
+ if (count == 0) {
521
+ return -1;
522
+ }
523
+ int index = 0;
524
+ int value = values[0];
525
+ for (int i = 1; i < count; i++) {
526
+ if (values[i] > value) {
527
+ index = i;
528
+ value = values[i];
529
+ }
530
+ }
531
+ return index;
532
+ }
533
+
534
+
535
+ /** return the key corresponding to the maximum value or null if no entries */
536
+ public String maxKey() {
537
+ //checkMinMax("maxKey");
538
+ int index = maxIndex();
539
+ if (index == -1) {
540
+ return null;
541
+ }
542
+ return keys[index];
543
+ }
544
+
545
+
546
+ // return the maximum value or throw an error if zero length
547
+ public int maxValue() {
548
+ checkMinMax("maxIndex");
549
+ return values[maxIndex()];
550
+ }
551
+
552
+
553
+ public int sum() {
554
+ long amount = sumLong();
555
+ if (amount > Integer.MAX_VALUE) {
556
+ throw new RuntimeException("sum() exceeds " + Integer.MAX_VALUE + ", use sumLong()");
557
+ }
558
+ if (amount < Integer.MIN_VALUE) {
559
+ throw new RuntimeException("sum() less than " + Integer.MIN_VALUE + ", use sumLong()");
560
+ }
561
+ return (int) amount;
562
+ }
563
+
564
+
565
+ public long sumLong() {
566
+ long sum = 0;
567
+ for (int i = 0; i < count; i++) {
568
+ sum += values[i];
569
+ }
570
+ return sum;
571
+ }
572
+
573
+
574
+ public int index(String what) {
575
+ Integer found = indices.get(what);
576
+ return (found == null) ? -1 : found.intValue();
577
+ }
578
+
579
+
580
+ protected void create(String what, int much) {
581
+ if (count == keys.length) {
582
+ keys = PApplet.expand(keys);
583
+ values = PApplet.expand(values);
584
+ }
585
+ indices.put(what, Integer.valueOf(count));
586
+ keys[count] = what;
587
+ values[count] = much;
588
+ count++;
589
+ }
590
+
591
+ /**
592
+ * @webref intdict:method
593
+ * @brief Remove a key/value pair
594
+ */
595
+ public int remove(String key) {
596
+ int index = index(key);
597
+ if (index == -1) {
598
+ throw new NoSuchElementException("'" + key + "' not found");
599
+ }
600
+ int value = values[index];
601
+ removeIndex(index);
602
+ return value;
603
+ }
604
+
605
+
606
+ public int removeIndex(int index) {
607
+ if (index < 0 || index >= count) {
608
+ throw new ArrayIndexOutOfBoundsException(index);
609
+ }
610
+ int value = values[index];
611
+ indices.remove(keys[index]);
612
+ for (int i = index; i < count-1; i++) {
613
+ keys[i] = keys[i+1];
614
+ values[i] = values[i+1];
615
+ indices.put(keys[i], i);
616
+ }
617
+ count--;
618
+ keys[count] = null;
619
+ values[count] = 0;
620
+ return value;
621
+ }
622
+
623
+
624
+ public void swap(int a, int b) {
625
+ String tkey = keys[a];
626
+ int tvalue = values[a];
627
+ keys[a] = keys[b];
628
+ values[a] = values[b];
629
+ keys[b] = tkey;
630
+ values[b] = tvalue;
631
+
632
+ // indices.put(keys[a], Integer.valueOf(a));
633
+ // indices.put(keys[b], Integer.valueOf(b));
634
+ }
635
+
636
+
637
+ /**
638
+ * Sort the keys alphabetically (ignoring case). Uses the value as a
639
+ * tie-breaker (only really possible with a key that has a case change).
640
+ *
641
+ * @webref intdict:method
642
+ * @brief Sort the keys alphabetically
643
+ */
644
+ public void sortKeys() {
645
+ sortImpl(true, false, true);
646
+ }
647
+
648
+ /**
649
+ * Sort the keys alphabetically in reverse (ignoring case). Uses the value as a
650
+ * tie-breaker (only really possible with a key that has a case change).
651
+ *
652
+ * @webref intdict:method
653
+ * @brief Sort the keys alphabetically in reverse
654
+ */
655
+ public void sortKeysReverse() {
656
+ sortImpl(true, true, true);
657
+ }
658
+
659
+
660
+ /**
661
+ * Sort by values in ascending order. The smallest value will be at [0].
662
+ *
663
+ * @webref intdict:method
664
+ * @brief Sort by values in ascending order
665
+ */
666
+ public void sortValues() {
667
+ sortValues(true);
668
+ }
669
+
670
+
671
+ /**
672
+ * Set true to ensure that the order returned is identical. Slightly
673
+ * slower because the tie-breaker for identical values compares the keys.
674
+ * @param stable
675
+ */
676
+ public void sortValues(boolean stable) {
677
+ sortImpl(false, false, stable);
678
+ }
679
+
680
+
681
+ /**
682
+ * Sort by values in descending order. The largest value will be at [0].
683
+ *
684
+ * @webref intdict:method
685
+ * @brief Sort by values in descending order
686
+ */
687
+ public void sortValuesReverse() {
688
+ sortValuesReverse(true);
689
+ }
690
+
691
+
692
+ public void sortValuesReverse(boolean stable) {
693
+ sortImpl(false, true, stable);
694
+ }
695
+
696
+
697
+ protected void sortImpl(final boolean useKeys, final boolean reverse,
698
+ final boolean stable) {
699
+ Sort s = new Sort() {
700
+ @Override
701
+ public int size() {
702
+ return count;
703
+ }
704
+
705
+ @Override
706
+ public int compare(int a, int b) {
707
+ int diff = 0;
708
+ if (useKeys) {
709
+ diff = keys[a].compareToIgnoreCase(keys[b]);
710
+ if (diff == 0) {
711
+ diff = values[a] - values[b];
712
+ }
713
+ } else { // sort values
714
+ diff = values[a] - values[b];
715
+ if (diff == 0 && stable) {
716
+ diff = keys[a].compareToIgnoreCase(keys[b]);
717
+ }
718
+ }
719
+ return reverse ? -diff : diff;
720
+ }
721
+
722
+ @Override
723
+ public void swap(int a, int b) {
724
+ IntDict.this.swap(a, b);
725
+ }
726
+ };
727
+ s.run();
728
+
729
+ // Set the indices after sort/swaps (performance fix 160411)
730
+ resetIndices();
731
+ }
732
+
733
+
734
+ /**
735
+ * Sum all of the values in this dictionary, then return a new FloatDict of
736
+ * each key, divided by the total sum. The total for all values will be ~1.0.
737
+ * @return an IntDict with the original keys, mapped to their pct of the total
738
+ */
739
+ public FloatDict getPercent() {
740
+ double sum = sum(); // a little more accuracy
741
+ FloatDict outgoing = new FloatDict();
742
+ for (int i = 0; i < size(); i++) {
743
+ double percent = value(i) / sum;
744
+ outgoing.set(key(i), (float) percent);
745
+ }
746
+ return outgoing;
747
+ }
748
+
749
+
750
+ /** Returns a duplicate copy of this object. */
751
+ public IntDict copy() {
752
+ IntDict outgoing = new IntDict(count);
753
+ System.arraycopy(keys, 0, outgoing.keys, 0, count);
754
+ System.arraycopy(values, 0, outgoing.values, 0, count);
755
+ for (int i = 0; i < count; i++) {
756
+ outgoing.indices.put(keys[i], i);
757
+ }
758
+ outgoing.count = count;
759
+ return outgoing;
760
+ }
761
+
762
+
763
+ public void print() {
764
+ for (int i = 0; i < size(); i++) {
765
+ System.out.println(keys[i] + " = " + values[i]);
766
+ }
767
+ }
768
+
769
+
770
+ /**
771
+ * Save tab-delimited entries to a file (TSV format, UTF-8 encoding)
772
+ */
773
+ public void save(File file) {
774
+ PrintWriter writer = PApplet.createWriter(file);
775
+ write(writer);
776
+ writer.close();
777
+ }
778
+
779
+
780
+ /**
781
+ * Write tab-delimited entries to a PrintWriter
782
+ */
783
+ public void write(PrintWriter writer) {
784
+ for (int i = 0; i < count; i++) {
785
+ writer.println(keys[i] + "\t" + values[i]);
786
+ }
787
+ writer.flush();
788
+ }
789
+
790
+
791
+ /**
792
+ * Return this dictionary as a String in JSON format.
793
+ */
794
+ public String toJSON() {
795
+ StringList items = new StringList();
796
+ for (int i = 0; i < count; i++) {
797
+ items.append(JSONObject.quote(keys[i])+ ": " + values[i]);
798
+ }
799
+ return "{ " + items.join(", ") + " }";
800
+ }
801
+
802
+
803
+ @Override
804
+ public String toString() {
805
+ return getClass().getSimpleName() + " size=" + size() + " " + toJSON();
806
+ }
807
+ }