propane 3.3.1-java → 3.6.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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -2
  3. data/.mvn/wrapper/MavenWrapperDownloader.java +117 -0
  4. data/.mvn/wrapper/maven-wrapper.properties +2 -3
  5. data/.travis.yml +9 -0
  6. data/CHANGELOG.md +17 -5
  7. data/Gemfile +2 -0
  8. data/README.md +17 -8
  9. data/Rakefile +16 -30
  10. data/bin/propane +3 -1
  11. data/lib/propane.rb +6 -4
  12. data/lib/propane/app.rb +20 -10
  13. data/lib/propane/creators/sketch_class.rb +7 -1
  14. data/lib/propane/creators/sketch_factory.rb +4 -2
  15. data/lib/propane/creators/sketch_writer.rb +1 -0
  16. data/lib/propane/helper_methods.rb +23 -24
  17. data/lib/propane/helpers/numeric.rb +2 -0
  18. data/lib/propane/helpers/version_error.rb +1 -0
  19. data/lib/propane/library.rb +5 -1
  20. data/lib/propane/library_loader.rb +2 -0
  21. data/lib/propane/native_folder.rb +21 -15
  22. data/lib/propane/native_loader.rb +3 -0
  23. data/lib/propane/runner.rb +14 -6
  24. data/lib/propane/version.rb +2 -1
  25. data/library/boids/boids.rb +21 -11
  26. data/library/color_group/color_group.rb +28 -0
  27. data/library/control_panel/control_panel.rb +8 -5
  28. data/library/dxf/dxf.rb +6 -0
  29. data/library/file_chooser/chooser.rb +10 -9
  30. data/library/file_chooser/file_chooser.rb +10 -9
  31. data/library/library_proxy/library_proxy.rb +2 -0
  32. data/library/net/net.rb +7 -0
  33. data/library/simplex_noise/simplex_noise.rb +2 -0
  34. data/library/slider/slider.rb +23 -22
  35. data/library/vector_utils/vector_utils.rb +4 -0
  36. data/library/video_event/video_event.rb +4 -1
  37. data/mvnw +127 -51
  38. data/mvnw.cmd +182 -145
  39. data/pom.rb +53 -50
  40. data/pom.xml +17 -8
  41. data/propane.gemspec +13 -11
  42. data/src/main/java/monkstone/ColorUtil.java +13 -1
  43. data/src/main/java/monkstone/MathToolModule.java +253 -203
  44. data/src/main/java/monkstone/PropaneLibrary.java +2 -2
  45. data/src/main/java/monkstone/fastmath/Deglut.java +1 -1
  46. data/src/main/java/monkstone/filechooser/Chooser.java +2 -1
  47. data/src/main/java/monkstone/noise/SimplexNoise.java +2 -2
  48. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +1 -1
  49. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
  50. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +1 -1
  51. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +1 -1
  52. data/src/main/java/monkstone/slider/SliderBar.java +1 -1
  53. data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
  54. data/src/main/java/monkstone/slider/WheelHandler.java +7 -6
  55. data/src/main/java/monkstone/vecmath/package-info.java +1 -1
  56. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +2 -2
  57. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
  58. data/src/main/java/monkstone/videoevent/CaptureEvent.java +27 -0
  59. data/src/main/java/monkstone/videoevent/{VideoInterface.java → MovieEvent.java} +11 -27
  60. data/src/main/java/monkstone/videoevent/package-info.java +1 -1
  61. data/src/main/java/processing/awt/PGraphicsJava2D.java +2164 -1661
  62. data/src/main/java/processing/awt/PImageAWT.java +377 -0
  63. data/src/main/java/processing/awt/PShapeJava2D.java +280 -268
  64. data/src/main/java/processing/awt/PSurfaceAWT.java +942 -829
  65. data/src/main/java/processing/awt/ShimAWT.java +581 -0
  66. data/src/main/java/processing/core/PApplet.java +831 -824
  67. data/src/main/java/processing/core/PConstants.java +477 -447
  68. data/src/main/java/processing/core/PFont.java +914 -880
  69. data/src/main/java/processing/core/PGraphics.java +229 -213
  70. data/src/main/java/processing/core/PImage.java +620 -318
  71. data/src/main/java/processing/core/PMatrix.java +172 -159
  72. data/src/main/java/processing/core/PMatrix2D.java +478 -409
  73. data/src/main/java/processing/core/PMatrix3D.java +762 -735
  74. data/src/main/java/processing/core/PShape.java +2888 -2652
  75. data/src/main/java/processing/core/PShapeOBJ.java +436 -415
  76. data/src/main/java/processing/core/PShapeSVG.java +1702 -1479
  77. data/src/main/java/processing/core/PStyle.java +40 -37
  78. data/src/main/java/processing/core/PSurface.java +139 -97
  79. data/src/main/java/processing/core/PSurfaceNone.java +296 -208
  80. data/src/main/java/processing/core/PVector.java +997 -965
  81. data/src/main/java/processing/core/ThinkDifferent.java +12 -17
  82. data/src/main/java/processing/data/DoubleDict.java +756 -710
  83. data/src/main/java/processing/data/DoubleList.java +749 -696
  84. data/src/main/java/processing/data/FloatDict.java +748 -702
  85. data/src/main/java/processing/data/FloatList.java +751 -697
  86. data/src/main/java/processing/data/IntDict.java +720 -673
  87. data/src/main/java/processing/data/IntList.java +699 -633
  88. data/src/main/java/processing/data/JSONArray.java +931 -873
  89. data/src/main/java/processing/data/JSONObject.java +1262 -1165
  90. data/src/main/java/processing/data/JSONTokener.java +351 -341
  91. data/src/main/java/processing/data/LongDict.java +710 -663
  92. data/src/main/java/processing/data/LongList.java +701 -635
  93. data/src/main/java/processing/data/Sort.java +37 -41
  94. data/src/main/java/processing/data/StringDict.java +525 -486
  95. data/src/main/java/processing/data/StringList.java +626 -580
  96. data/src/main/java/processing/data/Table.java +3690 -3510
  97. data/src/main/java/processing/data/TableRow.java +182 -183
  98. data/src/main/java/processing/data/XML.java +957 -883
  99. data/src/main/java/processing/dxf/RawDXF.java +404 -0
  100. data/src/main/java/processing/event/Event.java +87 -66
  101. data/src/main/java/processing/event/KeyEvent.java +48 -41
  102. data/src/main/java/processing/event/MouseEvent.java +88 -113
  103. data/src/main/java/processing/event/TouchEvent.java +10 -6
  104. data/src/main/java/processing/javafx/PGraphicsFX2D.java +20 -345
  105. data/src/main/java/processing/javafx/PSurfaceFX.java +149 -121
  106. data/src/main/java/processing/net/Client.java +744 -0
  107. data/src/main/java/processing/net/Server.java +388 -0
  108. data/src/main/java/processing/opengl/FontTexture.java +289 -270
  109. data/src/main/java/processing/opengl/FrameBuffer.java +386 -364
  110. data/src/main/java/processing/opengl/LinePath.java +547 -500
  111. data/src/main/java/processing/opengl/LineStroker.java +588 -581
  112. data/src/main/java/processing/opengl/PGL.java +3047 -2914
  113. data/src/main/java/processing/opengl/PGraphics2D.java +408 -315
  114. data/src/main/java/processing/opengl/PGraphics3D.java +107 -72
  115. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12378 -12075
  116. data/src/main/java/processing/opengl/PJOGL.java +1753 -1670
  117. data/src/main/java/processing/opengl/PShader.java +1266 -1257
  118. data/src/main/java/processing/opengl/PShapeOpenGL.java +4678 -4580
  119. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1114 -1027
  120. data/src/main/java/processing/opengl/Texture.java +1492 -1401
  121. data/src/main/java/processing/opengl/VertexBuffer.java +57 -55
  122. data/test/create_test.rb +21 -20
  123. data/test/deglut_spec_test.rb +4 -2
  124. data/test/helper_methods_test.rb +49 -20
  125. data/test/math_tool_test.rb +39 -32
  126. data/test/native_folder.rb +47 -0
  127. data/test/respond_to_test.rb +3 -2
  128. data/test/sketches/key_event.rb +2 -2
  129. data/test/sketches/library/my_library/my_library.rb +3 -0
  130. data/test/test_helper.rb +2 -0
  131. data/test/vecmath_spec_test.rb +35 -22
  132. data/vendors/Rakefile +33 -62
  133. metadata +54 -45
  134. data/src/main/java/processing/core/util/image/ImageLoadFacade.java +0 -161
  135. data/src/main/java/processing/core/util/image/ImageSaveFacade.java +0 -169
  136. data/src/main/java/processing/core/util/image/constants/TifConstants.java +0 -45
  137. data/src/main/java/processing/core/util/image/load/AwtImageLoadStrategy.java +0 -80
  138. data/src/main/java/processing/core/util/image/load/Base64StringImageLoadStrategy.java +0 -73
  139. data/src/main/java/processing/core/util/image/load/FallbackImageLoadStrategy.java +0 -70
  140. data/src/main/java/processing/core/util/image/load/ImageIoImageLoadStrategy.java +0 -132
  141. data/src/main/java/processing/core/util/image/load/ImageLoadStrategy.java +0 -48
  142. data/src/main/java/processing/core/util/image/load/ImageLoadUtil.java +0 -45
  143. data/src/main/java/processing/core/util/image/load/TgaImageLoadStrategy.java +0 -255
  144. data/src/main/java/processing/core/util/image/load/TiffImageLoadStrategy.java +0 -98
  145. data/src/main/java/processing/core/util/image/save/ImageSaveStrategy.java +0 -49
  146. data/src/main/java/processing/core/util/image/save/ImageSaveUtil.java +0 -48
  147. data/src/main/java/processing/core/util/image/save/ImageWriterImageSaveStrategy.java +0 -179
  148. data/src/main/java/processing/core/util/image/save/SaveImageException.java +0 -41
  149. data/src/main/java/processing/core/util/image/save/TgaImageSaveStrategy.java +0 -198
  150. data/src/main/java/processing/core/util/image/save/TiffImageSaveStrategy.java +0 -91
  151. data/src/main/java/processing/core/util/image/save/TiffNakedFilenameImageSaveStrategy.java +0 -57
  152. data/src/main/java/processing/core/util/io/InputFactory.java +0 -285
  153. data/src/main/java/processing/core/util/io/PathUtil.java +0 -109
  154. data/src/main/java/processing/opengl/shaders/LightVert-brcm.glsl +0 -154
  155. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +0 -154
  156. data/src/main/java/processing/opengl/shaders/TexLightVert-brcm.glsl +0 -160
  157. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +0 -160
@@ -1,50 +1,46 @@
1
1
  package processing.data;
2
2
 
3
+
3
4
  /**
4
- * Internal sorter used by several data classes. Advanced users only, not
5
- * official API.
5
+ * Internal sorter used by several data classes.
6
+ * Advanced users only, not official API.
6
7
  */
7
8
  public abstract class Sort implements Runnable {
8
9
 
9
- public Sort() {
10
- }
11
-
12
- public void run() {
13
- int c = size();
14
- if (c > 1) {
15
- sort(0, c - 1);
16
- }
17
- }
10
+ public Sort() { }
18
11
 
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
- }
31
12
 
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;
13
+ public void run() {
14
+ int c = size();
15
+ if (c > 1) {
16
+ sort(0, c - 1);
43
17
  }
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
- }
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
+ }
@@ -3,9 +3,11 @@ package processing.data;
3
3
  import java.io.*;
4
4
  import java.util.HashMap;
5
5
  import java.util.Iterator;
6
+ import java.util.NoSuchElementException;
6
7
 
7
8
  import processing.core.PApplet;
8
9
 
10
+
9
11
  /**
10
12
  * A simple table class to use a String as a lookup for another String value.
11
13
  *
@@ -15,560 +17,597 @@ import processing.core.PApplet;
15
17
  */
16
18
  public class StringDict {
17
19
 
18
- /**
19
- * Number of elements in the table
20
- */
21
- protected int count;
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
+ }
22
110
 
23
- protected String[] keys;
24
- protected String[] values;
25
111
 
26
- /**
27
- * Internal implementation for faster lookups
28
- */
29
- private HashMap<String, Integer> indices = new HashMap<>();
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());
30
119
 
31
- public StringDict() {
32
- count = 0;
33
- keys = new String[10];
34
- values = new String[10];
120
+ String[] titles = row.getColumnTitles();
121
+ if (titles == null) {
122
+ titles = new StringList(IntList.fromRange(row.getColumnCount())).array();
35
123
  }
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];
124
+ for (int col = 0; col < row.getColumnCount(); col++) {
125
+ set(titles[col], row.getString(col));
48
126
  }
127
+ // remove unused and overwritten entries
128
+ crop();
129
+ }
49
130
 
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
- }
71
131
 
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
- }
132
+ /**
133
+ * @webref stringdict:method
134
+ * @brief Returns the number of key/value pairs
135
+ */
136
+ public int size() {
137
+ return count;
138
+ }
86
139
 
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
- }
106
- }
107
140
 
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();
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");
125
148
  }
126
-
127
- /**
128
- * @webref stringdict:method
129
- * @brief Returns the number of key/value pairs
130
- */
131
- public int size() {
132
- return count;
149
+ if (length < 1) {
150
+ throw new IllegalArgumentException("resize(" + length + ") is too small, use 1 or higher");
133
151
  }
134
152
 
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
- }
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
+ }
146
162
 
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
- }
156
163
 
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
- }
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
+ }
167
174
 
168
- private void resetIndices() {
169
- indices = new HashMap<>(count);
170
- for (int i = 0; i < count; i++) {
171
- indices.put(keys[i], i);
172
- }
175
+
176
+ private void resetIndices() {
177
+ indices = new HashMap<>(count);
178
+ for (int i = 0; i < count; i++) {
179
+ indices.put(keys[i], i);
173
180
  }
181
+ }
174
182
 
175
- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
176
- public class Entry {
177
183
 
178
- public String key;
179
- public String value;
184
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
180
185
 
181
- Entry(String key, String value) {
182
- this.key = key;
183
- this.value = value;
184
- }
185
- }
186
186
 
187
- public Iterable<Entry> entries() {
188
- return new Iterable<Entry>() {
187
+ public class Entry {
188
+ public String key;
189
+ public String value;
189
190
 
190
- public Iterator<Entry> iterator() {
191
- return entryIterator();
192
- }
193
- };
191
+ Entry(String key, String value) {
192
+ this.key = key;
193
+ this.value = value;
194
194
  }
195
+ }
195
196
 
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
- }
216
197
 
217
- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
218
- public String key(int index) {
219
- return keys[index];
220
- }
198
+ public Iterable<Entry> entries() {
199
+ return new Iterable<Entry>() {
221
200
 
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
- }
201
+ public Iterator<Entry> iterator() {
202
+ return entryIterator();
203
+ }
204
+ };
205
+ }
228
206
 
229
- public Iterable<String> keys() {
230
- return new Iterable<String>() {
231
207
 
232
- @Override
233
- public Iterator<String> iterator() {
234
- return keyIterator();
235
- }
236
- };
237
- }
208
+ public Iterator<Entry> entryIterator() {
209
+ return new Iterator<Entry>() {
210
+ int index = -1;
238
211
 
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;
212
+ public void remove() {
213
+ removeIndex(index);
214
+ index--;
215
+ }
243
216
 
244
- public void remove() {
245
- removeIndex(index);
246
- index--;
247
- }
217
+ public Entry next() {
218
+ ++index;
219
+ Entry e = new Entry(keys[index], values[index]);
220
+ return e;
221
+ }
248
222
 
249
- public String next() {
250
- return key(++index);
251
- }
223
+ public boolean hasNext() {
224
+ return index+1 < size();
225
+ }
226
+ };
227
+ }
252
228
 
253
- public boolean hasNext() {
254
- return index + 1 < size();
255
- }
256
- };
257
- }
258
229
 
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
- }
230
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
269
231
 
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
- }
277
232
 
278
- public String value(int index) {
279
- return values[index];
280
- }
233
+ public String key(int index) {
234
+ return keys[index];
235
+ }
236
+
281
237
 
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
- };
238
+ protected void crop() {
239
+ if (count != keys.length) {
240
+ keys = PApplet.subset(keys, 0, count);
241
+ values = PApplet.subset(values, 0, count);
294
242
  }
243
+ }
295
244
 
296
- public Iterator<String> valueIterator() {
297
- return new Iterator<String>() {
298
- int index = -1;
299
245
 
300
- public void remove() {
301
- removeIndex(index);
302
- index--;
303
- }
246
+ public Iterable<String> keys() {
247
+ return new Iterable<String>() {
304
248
 
305
- public String next() {
306
- return value(++index);
307
- }
249
+ @Override
250
+ public Iterator<String> iterator() {
251
+ return keyIterator();
252
+ }
253
+ };
254
+ }
308
255
 
309
- public boolean hasNext() {
310
- return index + 1 < size();
311
- }
312
- };
313
- }
314
256
 
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
- }
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;
325
261
 
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
- }
262
+ public void remove() {
263
+ removeIndex(index);
264
+ index--;
265
+ }
338
266
 
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
- }
267
+ public String next() {
268
+ return key(++index);
269
+ }
352
270
 
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
- }
271
+ public boolean hasNext() {
272
+ return index+1 < size();
273
+ }
274
+ };
275
+ }
360
276
 
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
- }
373
277
 
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
- }
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
+ }
381
288
 
382
- public int index(String what) {
383
- Integer found = indices.get(what);
384
- return (found == null) ? -1 : found.intValue();
385
- }
386
289
 
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
- }
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
+ }
394
297
 
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
- }
405
298
 
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
- }
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;
417
321
 
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
- }
322
+ public void remove() {
323
+ removeIndex(index);
324
+ index--;
325
+ }
435
326
 
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;
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;
443
474
 
444
475
  // indices.put(keys[a], Integer.valueOf(a));
445
476
  // indices.put(keys[b], Integer.valueOf(b));
446
- }
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
+ }
447
543
 
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);
457
- }
544
+ @Override
545
+ public void swap(int a, int b) {
546
+ StringDict.this.swap(a, b);
547
+ }
548
+ };
549
+ s.run();
458
550
 
459
- /**
460
- * @webref stringdict:method
461
- * @brief Sort the keys alphabetically in reverse
462
- */
463
- public void sortKeysReverse() {
464
- sortImpl(true, true);
465
- }
551
+ // Set the indices after sort/swaps (performance fix 160411)
552
+ resetIndices();
553
+ }
466
554
 
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);
475
- }
476
555
 
477
- /**
478
- * @webref stringdict:method
479
- * @brief Sort by values in descending order
480
- */
481
- public void sortValuesReverse() {
482
- sortImpl(false, true);
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);
483
563
  }
564
+ outgoing.count = count;
565
+ return outgoing;
566
+ }
484
567
 
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
- }
519
568
 
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;
569
+ public void print() {
570
+ for (int i = 0; i < size(); i++) {
571
+ System.out.println(keys[i] + " = " + values[i]);
532
572
  }
573
+ }
533
574
 
534
- public void print() {
535
- for (int i = 0; i < size(); i++) {
536
- System.out.println(keys[i] + " = " + values[i]);
537
- }
538
- }
539
575
 
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
- }
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
+ }
548
584
 
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();
557
- }
558
585
 
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(", ") + " }";
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]);
568
592
  }
593
+ writer.flush();
594
+ }
595
+
569
596
 
570
- @Override
571
- public String toString() {
572
- return getClass().getSimpleName() + " size=" + size() + " " + toJSON();
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]));
573
604
  }
605
+ return "{ " + items.join(", ") + " }";
606
+ }
607
+
608
+
609
+ @Override
610
+ public String toString() {
611
+ return getClass().getSimpleName() + " size=" + size() + " " + toJSON();
612
+ }
574
613
  }