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,115 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2012-2014 The Processing Foundation
7
+ Copyright (c) 2007-2012 Ben Fry and Casey Reas
8
+
9
+ This program is free software; you can redistribute it and/or
10
+ modify it under the terms of the GNU General Public License
11
+ version 2, as published by the Free Software Foundation.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program; if not, write to the Free Software Foundation,
20
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
+ */
22
+
23
+ package processing.core;
24
+
25
+ import java.awt.Desktop;
26
+ import java.awt.Image;
27
+ import java.awt.Taskbar;
28
+
29
+
30
+ /**
31
+ * Deal with issues related to macOS application behavior.
32
+ *
33
+ * We have to register a quit handler to safely shut down the sketch,
34
+ * otherwise OS X will just kill the sketch when a user hits Cmd-Q.
35
+ * In addition, we have a method to set the dock icon image so we look more
36
+ * like a native application.
37
+ *
38
+ * This is a stripped-down version of what's in processing.app.platform to fix
39
+ * <a href="https://github.com/processing/processing/issues/3301">3301</a>.
40
+ */
41
+ public class ThinkDifferent {
42
+ static private Desktop desktop;
43
+ static private Taskbar taskbar;
44
+
45
+ // True if user has tried to quit once. Prevents us from canceling the quit
46
+ // call if the sketch is held up for some reason, like an exception that's
47
+ // managed to put the sketch in a bad state.
48
+ static boolean attemptedQuit;
49
+
50
+
51
+ /**
52
+ * Initialize the sketch with the quit handler.
53
+ *
54
+ * Initialize the sketch with the quit handler such that, if there is no known
55
+ * crash, the application will not exit on its own if this is the first quit
56
+ * attempt.
57
+ *
58
+ * @param sketch The sketch whose quit handler callback should be set.
59
+ */
60
+ static public void init(final PApplet sketch) {
61
+ getDesktop().setQuitHandler((event, quitResponse) -> {
62
+ sketch.exit();
63
+
64
+ boolean noKnownCrash = PApplet.uncaughtThrowable == null;
65
+
66
+ if (noKnownCrash && !attemptedQuit) { // haven't tried yet
67
+ quitResponse.cancelQuit(); // tell OS X we'll handle this
68
+ attemptedQuit = true;
69
+ } else {
70
+ quitResponse.performQuit(); // just force it this time
71
+ }
72
+ });
73
+ }
74
+
75
+
76
+ /**
77
+ * Remove the quit handler.
78
+ */
79
+ static public void cleanup() {
80
+ getDesktop().setQuitHandler(null);
81
+ }
82
+
83
+
84
+ /**
85
+ * Called via reflection from PSurfaceAWT and others, set the dock icon image.
86
+ * @param image The image to provide for Processing icon.
87
+ */
88
+ static public void setIconImage(Image image) {
89
+ getTaskbar().setIconImage(image);
90
+ }
91
+
92
+
93
+ /**
94
+ * Get the taskbar where OS visual settings can be provided.
95
+ * @return Cached taskbar singleton instance.
96
+ */
97
+ static private Taskbar getTaskbar() {
98
+ if (taskbar == null) {
99
+ taskbar = Taskbar.getTaskbar();
100
+ }
101
+ return taskbar;
102
+ }
103
+
104
+
105
+ /**
106
+ * Get the desktop where OS behavior can be provided.
107
+ * @return Cached desktop singleton instance.
108
+ */
109
+ static private Desktop getDesktop() {
110
+ if (desktop == null) {
111
+ desktop = Desktop.getDesktop();
112
+ }
113
+ return desktop;
114
+ }
115
+ }
@@ -0,0 +1,850 @@
1
+ package processing.data;
2
+
3
+ import java.io.*;
4
+ import java.util.HashMap;
5
+ import java.util.Iterator;
6
+ import java.util.Map;
7
+ import java.util.NoSuchElementException;
8
+
9
+ import processing.core.PApplet;
10
+
11
+
12
+ /**
13
+ * A simple table class to use a String as a lookup for an double value.
14
+ *
15
+ * @nowebref
16
+ * @see IntDict
17
+ * @see StringDict
18
+ */
19
+ public class DoubleDict {
20
+
21
+ /** Number of elements in the table */
22
+ protected int count;
23
+
24
+ protected String[] keys;
25
+ protected double[] values;
26
+
27
+ /** Internal implementation for faster lookups */
28
+ private HashMap<String, Integer> indices = new HashMap<>();
29
+
30
+
31
+ public DoubleDict() {
32
+ count = 0;
33
+ keys = new String[10];
34
+ values = new double[10];
35
+ }
36
+
37
+
38
+ /**
39
+ * Create a new lookup with a specific size. This is more efficient than not
40
+ * specifying a size. Use it when you know the rough size of the thing you're creating.
41
+ *
42
+ * @nowebref
43
+ */
44
+ public DoubleDict(int length) {
45
+ count = 0;
46
+ keys = new String[length];
47
+ values = new double[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 DoubleDict(BufferedReader reader) {
58
+ String[] lines = PApplet.loadStrings(reader);
59
+ keys = new String[lines.length];
60
+ values = new double[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] = PApplet.parseFloat(pieces[1]);
67
+ indices.put(pieces[0], count);
68
+ count++;
69
+ }
70
+ }
71
+ }
72
+
73
+
74
+ /**
75
+ * @nowebref
76
+ */
77
+ public DoubleDict(String[] keys, double[] 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 FloatDict(new Object[][] {
94
+ * { "key1", 1 },
95
+ * { "key2", 2 }
96
+ * });
97
+ * </pre>
98
+ */
99
+ public DoubleDict(Object[][] pairs) {
100
+ count = pairs.length;
101
+ this.keys = new String[count];
102
+ this.values = new double[count];
103
+ for (int i = 0; i < count; i++) {
104
+ keys[i] = (String) pairs[i][0];
105
+ values[i] = (Float) pairs[i][1];
106
+ indices.put(keys[i], i);
107
+ }
108
+ }
109
+
110
+
111
+ public DoubleDict(Map<String, Double> incoming) {
112
+ count = incoming.size();
113
+ keys = new String[count];
114
+ values = new double[count];
115
+ int index = 0;
116
+ for (Map.Entry<String, Double> e : incoming.entrySet()) {
117
+ keys[index] = e.getKey();
118
+ values[index] = e.getValue();
119
+ indices.put(keys[index], index);
120
+ index++;
121
+ }
122
+ }
123
+
124
+
125
+ /**
126
+ * @webref doubledict:method
127
+ * @brief Returns the number of key/value pairs
128
+ */
129
+ public int size() {
130
+ return count;
131
+ }
132
+
133
+
134
+ /**
135
+ * Resize the internal data, this can only be used to shrink the list.
136
+ * Helpful for situations like sorting and then grabbing the top 50 entries.
137
+ */
138
+ public void resize(int length) {
139
+ if (length == count) return;
140
+
141
+ if (length > count) {
142
+ throw new IllegalArgumentException("resize() can only be used to shrink the dictionary");
143
+ }
144
+ if (length < 1) {
145
+ throw new IllegalArgumentException("resize(" + length + ") is too small, use 1 or higher");
146
+ }
147
+
148
+ String[] newKeys = new String[length];
149
+ double[] newValues = new double[length];
150
+ PApplet.arrayCopy(keys, newKeys, length);
151
+ PApplet.arrayCopy(values, newValues, length);
152
+ keys = newKeys;
153
+ values = newValues;
154
+ count = length;
155
+ resetIndices();
156
+ }
157
+
158
+
159
+ /**
160
+ * Remove all entries.
161
+ *
162
+ * @webref doubledict:method
163
+ * @brief Remove all entries
164
+ */
165
+ public void clear() {
166
+ count = 0;
167
+ indices = new HashMap<>();
168
+ }
169
+
170
+
171
+ private void resetIndices() {
172
+ indices = new HashMap<>(count);
173
+ for (int i = 0; i < count; i++) {
174
+ indices.put(keys[i], i);
175
+ }
176
+ }
177
+
178
+
179
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
180
+
181
+
182
+ public class Entry {
183
+ public String key;
184
+ public double value;
185
+
186
+ Entry(String key, double value) {
187
+ this.key = key;
188
+ this.value = value;
189
+ }
190
+ }
191
+
192
+
193
+ public Iterable<Entry> entries() {
194
+ return new Iterable<Entry>() {
195
+
196
+ public Iterator<Entry> iterator() {
197
+ return entryIterator();
198
+ }
199
+ };
200
+ }
201
+
202
+
203
+ public Iterator<Entry> entryIterator() {
204
+ return new Iterator<Entry>() {
205
+ int index = -1;
206
+
207
+ public void remove() {
208
+ removeIndex(index);
209
+ index--;
210
+ }
211
+
212
+ public Entry next() {
213
+ ++index;
214
+ Entry e = new Entry(keys[index], values[index]);
215
+ return e;
216
+ }
217
+
218
+ public boolean hasNext() {
219
+ return index+1 < size();
220
+ }
221
+ };
222
+ }
223
+
224
+
225
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
226
+
227
+
228
+ public String key(int index) {
229
+ return keys[index];
230
+ }
231
+
232
+
233
+ protected void crop() {
234
+ if (count != keys.length) {
235
+ keys = PApplet.subset(keys, 0, count);
236
+ values = PApplet.subset(values, 0, count);
237
+ }
238
+ }
239
+
240
+
241
+ public Iterable<String> keys() {
242
+ return new Iterable<String>() {
243
+
244
+ @Override
245
+ public Iterator<String> iterator() {
246
+ return keyIterator();
247
+ }
248
+ };
249
+ }
250
+
251
+
252
+ // Use this to iterate when you want to be able to remove elements along the way
253
+ public Iterator<String> keyIterator() {
254
+ return new Iterator<String>() {
255
+ int index = -1;
256
+
257
+ public void remove() {
258
+ removeIndex(index);
259
+ index--;
260
+ }
261
+
262
+ public String next() {
263
+ return key(++index);
264
+ }
265
+
266
+ public boolean hasNext() {
267
+ return index+1 < size();
268
+ }
269
+ };
270
+ }
271
+
272
+
273
+ /**
274
+ * Return a copy of the internal keys array. This array can be modified.
275
+ *
276
+ * @webref doubledict:method
277
+ * @brief Return a copy of the internal keys array
278
+ */
279
+ public String[] keyArray() {
280
+ crop();
281
+ return keyArray(null);
282
+ }
283
+
284
+
285
+ public String[] keyArray(String[] outgoing) {
286
+ if (outgoing == null || outgoing.length != count) {
287
+ outgoing = new String[count];
288
+ }
289
+ System.arraycopy(keys, 0, outgoing, 0, count);
290
+ return outgoing;
291
+ }
292
+
293
+
294
+ public double value(int index) {
295
+ return values[index];
296
+ }
297
+
298
+
299
+ /**
300
+ * @webref doubledict:method
301
+ * @brief Return the internal array being used to store the values
302
+ */
303
+ public Iterable<Double> values() {
304
+ return new Iterable<Double>() {
305
+
306
+ @Override
307
+ public Iterator<Double> iterator() {
308
+ return valueIterator();
309
+ }
310
+ };
311
+ }
312
+
313
+
314
+ public Iterator<Double> valueIterator() {
315
+ return new Iterator<Double>() {
316
+ int index = -1;
317
+
318
+ public void remove() {
319
+ removeIndex(index);
320
+ index--;
321
+ }
322
+
323
+ public Double next() {
324
+ return value(++index);
325
+ }
326
+
327
+ public boolean hasNext() {
328
+ return index+1 < size();
329
+ }
330
+ };
331
+ }
332
+
333
+
334
+ /**
335
+ * Create a new array and copy each of the values into it.
336
+ *
337
+ * @webref doubledict:method
338
+ * @brief Create a new array and copy each of the values into it
339
+ */
340
+ public double[] valueArray() {
341
+ crop();
342
+ return valueArray(null);
343
+ }
344
+
345
+
346
+ /**
347
+ * Fill an already-allocated array with the values (more efficient than
348
+ * creating a new array each time). If 'array' is null, or not the same
349
+ * size as the number of values, a new array will be allocated and returned.
350
+ */
351
+ public double[] valueArray(double[] array) {
352
+ if (array == null || array.length != size()) {
353
+ array = new double[count];
354
+ }
355
+ System.arraycopy(values, 0, array, 0, count);
356
+ return array;
357
+ }
358
+
359
+
360
+ /**
361
+ * Return a value for the specified key.
362
+ *
363
+ * @webref doubledict:method
364
+ * @brief Return a value for the specified key
365
+ */
366
+ public double get(String key) {
367
+ int index = index(key);
368
+ if (index == -1) {
369
+ throw new IllegalArgumentException("No key named '" + key + "'");
370
+ }
371
+ return values[index];
372
+ }
373
+
374
+
375
+ public double get(String key, double alternate) {
376
+ int index = index(key);
377
+ if (index == -1) {
378
+ return alternate;
379
+ }
380
+ return values[index];
381
+ }
382
+
383
+
384
+ /**
385
+ * @webref doubledict:method
386
+ * @brief Create a new key/value pair or change the value of one
387
+ */
388
+ public void set(String key, double amount) {
389
+ int index = index(key);
390
+ if (index == -1) {
391
+ create(key, amount);
392
+ } else {
393
+ values[index] = amount;
394
+ }
395
+ }
396
+
397
+
398
+ public void setIndex(int index, String key, double 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
+ /**
408
+ * @webref doubledict:method
409
+ * @brief Check if a key is a part of the data structure
410
+ */
411
+ public boolean hasKey(String key) {
412
+ return index(key) != -1;
413
+ }
414
+
415
+
416
+ /**
417
+ * @webref doubledict:method
418
+ * @brief Add to a value
419
+ */
420
+ public void add(String key, double amount) {
421
+ int index = index(key);
422
+ if (index == -1) {
423
+ create(key, amount);
424
+ } else {
425
+ values[index] += amount;
426
+ }
427
+ }
428
+
429
+
430
+ /**
431
+ * @webref doubledict:method
432
+ * @brief Subtract from a value
433
+ */
434
+ public void sub(String key, double amount) {
435
+ add(key, -amount);
436
+ }
437
+
438
+
439
+ /**
440
+ * @webref doubledict:method
441
+ * @brief Multiply a value
442
+ */
443
+ public void mult(String key, double amount) {
444
+ int index = index(key);
445
+ if (index != -1) {
446
+ values[index] *= amount;
447
+ }
448
+ }
449
+
450
+
451
+ /**
452
+ * @webref doubledict:method
453
+ * @brief Divide a value
454
+ */
455
+ public void div(String key, double amount) {
456
+ int index = index(key);
457
+ if (index != -1) {
458
+ values[index] /= amount;
459
+ }
460
+ }
461
+
462
+
463
+ private void checkMinMax(String functionName) {
464
+ if (count == 0) {
465
+ String msg =
466
+ String.format("Cannot use %s() on an empty %s.",
467
+ functionName, getClass().getSimpleName());
468
+ throw new RuntimeException(msg);
469
+ }
470
+ }
471
+
472
+
473
+ /**
474
+ * @webref doublelist:method
475
+ * @brief Return the smallest value
476
+ */
477
+ public int minIndex() {
478
+ //checkMinMax("minIndex");
479
+ if (count == 0) return -1;
480
+
481
+ // Will still return NaN if there are 1 or more entries, and they're all NaN
482
+ double m = Float.NaN;
483
+ int mi = -1;
484
+ for (int i = 0; i < count; i++) {
485
+ // find one good value to start
486
+ if (values[i] == values[i]) {
487
+ m = values[i];
488
+ mi = i;
489
+
490
+ // calculate the rest
491
+ for (int j = i+1; j < count; j++) {
492
+ double d = values[j];
493
+ if ((d == d) && (d < m)) {
494
+ m = values[j];
495
+ mi = j;
496
+ }
497
+ }
498
+ break;
499
+ }
500
+ }
501
+ return mi;
502
+ }
503
+
504
+
505
+ // return the key for the minimum value
506
+ public String minKey() {
507
+ checkMinMax("minKey");
508
+ int index = minIndex();
509
+ if (index == -1) {
510
+ return null;
511
+ }
512
+ return keys[index];
513
+ }
514
+
515
+
516
+ // return the minimum value, or throw an error if there are no values
517
+ public double minValue() {
518
+ checkMinMax("minValue");
519
+ int index = minIndex();
520
+ if (index == -1) {
521
+ return Float.NaN;
522
+ }
523
+ return values[index];
524
+ }
525
+
526
+
527
+ /**
528
+ * @webref doublelist:method
529
+ * @brief Return the largest value
530
+ */
531
+ // The index of the entry that has the max value. Reference above is incorrect.
532
+ public int maxIndex() {
533
+ //checkMinMax("maxIndex");
534
+ if (count == 0) {
535
+ return -1;
536
+ }
537
+ // Will still return NaN if there is 1 or more entries, and they're all NaN
538
+ double m = Double.NaN;
539
+ int mi = -1;
540
+ for (int i = 0; i < count; i++) {
541
+ // find one good value to start
542
+ if (values[i] == values[i]) {
543
+ m = values[i];
544
+ mi = i;
545
+
546
+ // calculate the rest
547
+ for (int j = i+1; j < count; j++) {
548
+ double d = values[j];
549
+ if (!Double.isNaN(d) && (d > m)) {
550
+ m = values[j];
551
+ mi = j;
552
+ }
553
+ }
554
+ break;
555
+ }
556
+ }
557
+ return mi;
558
+ }
559
+
560
+
561
+ /** The key for a max value; null if empty or everything is NaN (no max). */
562
+ public String maxKey() {
563
+ //checkMinMax("maxKey");
564
+ int index = maxIndex();
565
+ if (index == -1) {
566
+ return null;
567
+ }
568
+ return keys[index];
569
+ }
570
+
571
+
572
+ /** The max value. (Or NaN if no entries or they're all NaN.) */
573
+ public double maxValue() {
574
+ //checkMinMax("maxValue");
575
+ int index = maxIndex();
576
+ if (index == -1) {
577
+ return Float.NaN;
578
+ }
579
+ return values[index];
580
+ }
581
+
582
+
583
+ public double sum() {
584
+ double sum = 0;
585
+ for (int i = 0; i < count; i++) {
586
+ sum += values[i];
587
+ }
588
+ return sum;
589
+ }
590
+
591
+
592
+ public int index(String what) {
593
+ Integer found = indices.get(what);
594
+ return (found == null) ? -1 : found.intValue();
595
+ }
596
+
597
+
598
+ protected void create(String what, double much) {
599
+ if (count == keys.length) {
600
+ keys = PApplet.expand(keys);
601
+ values = PApplet.expand(values);
602
+ }
603
+ indices.put(what, Integer.valueOf(count));
604
+ keys[count] = what;
605
+ values[count] = much;
606
+ count++;
607
+ }
608
+
609
+
610
+ /**
611
+ * @webref doubledict:method
612
+ * @brief Remove a key/value pair
613
+ */
614
+ public double remove(String key) {
615
+ int index = index(key);
616
+ if (index == -1) {
617
+ throw new NoSuchElementException("'" + key + "' not found");
618
+ }
619
+ double value = values[index];
620
+ removeIndex(index);
621
+ return value;
622
+ }
623
+
624
+
625
+ public double removeIndex(int index) {
626
+ if (index < 0 || index >= count) {
627
+ throw new ArrayIndexOutOfBoundsException(index);
628
+ }
629
+ double value = values[index];
630
+ indices.remove(keys[index]);
631
+ for (int i = index; i < count-1; i++) {
632
+ keys[i] = keys[i+1];
633
+ values[i] = values[i+1];
634
+ indices.put(keys[i], i);
635
+ }
636
+ count--;
637
+ keys[count] = null;
638
+ values[count] = 0;
639
+ return value;
640
+ }
641
+
642
+
643
+ public void swap(int a, int b) {
644
+ String tkey = keys[a];
645
+ double tvalue = values[a];
646
+ keys[a] = keys[b];
647
+ values[a] = values[b];
648
+ keys[b] = tkey;
649
+ values[b] = tvalue;
650
+
651
+ // indices.put(keys[a], Integer.valueOf(a));
652
+ // indices.put(keys[b], Integer.valueOf(b));
653
+ }
654
+
655
+
656
+ /**
657
+ * Sort the keys alphabetically (ignoring case). Uses the value as a
658
+ * tie-breaker (only really possible with a key that has a case change).
659
+ *
660
+ * @webref doubledict:method
661
+ * @brief Sort the keys alphabetically
662
+ */
663
+ public void sortKeys() {
664
+ sortImpl(true, false, true);
665
+ }
666
+
667
+
668
+ /**
669
+ * @webref doubledict:method
670
+ * @brief Sort the keys alphabetically in reverse
671
+ */
672
+ public void sortKeysReverse() {
673
+ sortImpl(true, true, true);
674
+ }
675
+
676
+
677
+ /**
678
+ * Sort by values in descending order (largest value will be at [0]).
679
+ *
680
+ * @webref doubledict:method
681
+ * @brief Sort by values in ascending order
682
+ */
683
+ public void sortValues() {
684
+ sortValues(true);
685
+ }
686
+
687
+
688
+ /**
689
+ * Set true to ensure that the order returned is identical. Slightly
690
+ * slower because the tie-breaker for identical values compares the keys.
691
+ * @param stable
692
+ */
693
+ public void sortValues(boolean stable) {
694
+ sortImpl(false, false, stable);
695
+ }
696
+
697
+
698
+ /**
699
+ * @webref doubledict:method
700
+ * @brief Sort by values in descending order
701
+ */
702
+ public void sortValuesReverse() {
703
+ sortValuesReverse(true);
704
+ }
705
+
706
+
707
+ public void sortValuesReverse(boolean stable) {
708
+ sortImpl(false, true, stable);
709
+ }
710
+
711
+
712
+ protected void sortImpl(final boolean useKeys, final boolean reverse,
713
+ final boolean stable) {
714
+ Sort s = new Sort() {
715
+ @Override
716
+ public int size() {
717
+ if (useKeys) {
718
+ return count; // don't worry about NaN values
719
+
720
+ } else if (count == 0) { // skip the NaN check, it'll AIOOBE
721
+ return 0;
722
+
723
+ } else { // first move NaN values to the end of the list
724
+ int right = count - 1;
725
+ while (values[right] != values[right]) {
726
+ right--;
727
+ if (right == -1) {
728
+ return 0; // all values are NaN
729
+ }
730
+ }
731
+ for (int i = right; i >= 0; --i) {
732
+ if (Double.isNaN(values[i])) {
733
+ swap(i, right);
734
+ --right;
735
+ }
736
+ }
737
+ return right + 1;
738
+ }
739
+ }
740
+
741
+ @Override
742
+ public int compare(int a, int b) {
743
+ double diff = 0;
744
+ if (useKeys) {
745
+ diff = keys[a].compareToIgnoreCase(keys[b]);
746
+ if (diff == 0) {
747
+ diff = values[a] - values[b];
748
+ }
749
+ } else { // sort values
750
+ diff = values[a] - values[b];
751
+ if (diff == 0 && stable) {
752
+ diff = keys[a].compareToIgnoreCase(keys[b]);
753
+ }
754
+ }
755
+ if (diff == 0) {
756
+ return 0;
757
+ } else if (reverse) {
758
+ return diff < 0 ? 1 : -1;
759
+ } else {
760
+ return diff < 0 ? -1 : 1;
761
+ }
762
+ }
763
+
764
+ @Override
765
+ public void swap(int a, int b) {
766
+ DoubleDict.this.swap(a, b);
767
+ }
768
+ };
769
+ s.run();
770
+
771
+ // Set the indices after sort/swaps (performance fix 160411)
772
+ resetIndices();
773
+ }
774
+
775
+
776
+ /**
777
+ * Sum all of the values in this dictionary, then return a new FloatDict of
778
+ * each key, divided by the total sum. The total for all values will be ~1.0.
779
+ * @return a FloatDict with the original keys, mapped to their pct of the total
780
+ */
781
+ public DoubleDict getPercent() {
782
+ double sum = sum();
783
+ DoubleDict outgoing = new DoubleDict();
784
+ for (int i = 0; i < size(); i++) {
785
+ double percent = value(i) / sum;
786
+ outgoing.set(key(i), percent);
787
+ }
788
+ return outgoing;
789
+ }
790
+
791
+
792
+ /** Returns a duplicate copy of this object. */
793
+ public DoubleDict copy() {
794
+ DoubleDict outgoing = new DoubleDict(count);
795
+ System.arraycopy(keys, 0, outgoing.keys, 0, count);
796
+ System.arraycopy(values, 0, outgoing.values, 0, count);
797
+ for (int i = 0; i < count; i++) {
798
+ outgoing.indices.put(keys[i], i);
799
+ }
800
+ outgoing.count = count;
801
+ return outgoing;
802
+ }
803
+
804
+
805
+ public void print() {
806
+ for (int i = 0; i < size(); i++) {
807
+ System.out.println(keys[i] + " = " + values[i]);
808
+ }
809
+ }
810
+
811
+
812
+ /**
813
+ * Save tab-delimited entries to a file (TSV format, UTF-8 encoding)
814
+ */
815
+ public void save(File file) {
816
+ PrintWriter writer = PApplet.createWriter(file);
817
+ write(writer);
818
+ writer.close();
819
+ }
820
+
821
+
822
+ /**
823
+ * Write tab-delimited entries out to
824
+ * @param writer
825
+ */
826
+ public void write(PrintWriter writer) {
827
+ for (int i = 0; i < count; i++) {
828
+ writer.println(keys[i] + "\t" + values[i]);
829
+ }
830
+ writer.flush();
831
+ }
832
+
833
+
834
+ /**
835
+ * Return this dictionary as a String in JSON format.
836
+ */
837
+ public String toJSON() {
838
+ StringList items = new StringList();
839
+ for (int i = 0; i < count; i++) {
840
+ items.append(JSONObject.quote(keys[i])+ ": " + values[i]);
841
+ }
842
+ return "{ " + items.join(", ") + " }";
843
+ }
844
+
845
+
846
+ @Override
847
+ public String toString() {
848
+ return getClass().getSimpleName() + " size=" + size() + " " + toJSON();
849
+ }
850
+ }