propane 3.1.0.pre-java → 3.2.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.mvn/wrapper/maven-wrapper.properties +1 -0
- data/CHANGELOG.md +1 -5
- data/README.md +23 -12
- data/Rakefile +23 -12
- data/lib/propane/helpers/version_error.rb +6 -0
- data/lib/propane/runner.rb +12 -0
- data/lib/propane/version.rb +1 -1
- data/library/slider/slider.rb +1 -1
- data/mvnw +234 -0
- data/mvnw.cmd +145 -0
- data/pom.xml +28 -27
- data/propane.gemspec +2 -2
- data/src/main/java/japplemenubar/JAppleMenuBar.java +41 -47
- data/src/main/java/monkstone/ColorUtil.java +1 -1
- data/src/main/java/monkstone/MathToolModule.java +12 -11
- data/src/main/java/monkstone/PropaneLibrary.java +9 -10
- data/src/main/java/monkstone/core/LibraryProxy.java +124 -113
- data/src/main/java/monkstone/fastmath/Deglut.java +86 -89
- data/src/main/java/monkstone/filechooser/Chooser.java +7 -13
- data/src/main/java/monkstone/noise/SimplexNoise.java +0 -1
- data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +4 -4
- data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
- data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +9 -9
- data/src/main/java/monkstone/slider/SimpleSlider.java +0 -9
- data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +11 -13
- data/src/main/java/monkstone/slider/Slider.java +1 -1
- data/src/main/java/monkstone/slider/SliderBar.java +1 -1
- data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
- data/src/main/java/monkstone/slider/WheelHandler.java +8 -9
- data/src/main/java/monkstone/vecmath/AppRender.java +2 -2
- data/src/main/java/monkstone/vecmath/ShapeRender.java +2 -2
- data/src/main/java/monkstone/vecmath/package-info.java +2 -2
- data/src/main/java/monkstone/vecmath/vec2/Vec2.java +2 -2
- data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
- data/src/main/java/monkstone/videoevent/VideoInterface.java +11 -5
- data/src/main/java/monkstone/videoevent/package-info.java +2 -2
- data/src/main/java/processing/awt/PGraphicsJava2D.java +1742 -2243
- data/src/main/java/processing/awt/PShapeJava2D.java +268 -270
- data/src/main/java/processing/awt/PSurfaceAWT.java +821 -920
- data/src/main/java/processing/core/DesktopHandler.java +94 -0
- data/src/main/java/processing/core/PApplet.java +14170 -14082
- data/src/main/java/processing/core/PConstants.java +447 -473
- data/src/main/java/processing/core/PFont.java +867 -873
- data/src/main/java/processing/core/PGraphics.java +7193 -7428
- data/src/main/java/processing/core/PImage.java +3051 -3117
- data/src/main/java/processing/core/PMatrix.java +159 -172
- data/src/main/java/processing/core/PMatrix2D.java +403 -444
- data/src/main/java/processing/core/PMatrix3D.java +735 -749
- data/src/main/java/processing/core/PShape.java +2651 -2793
- data/src/main/java/processing/core/PShapeOBJ.java +415 -422
- data/src/main/java/processing/core/PShapeSVG.java +1466 -1475
- data/src/main/java/processing/core/PStyle.java +37 -40
- data/src/main/java/processing/core/PSurface.java +98 -103
- data/src/main/java/processing/core/PSurfaceNone.java +208 -236
- data/src/main/java/processing/core/PVector.java +961 -990
- data/src/main/java/processing/data/DoubleDict.java +709 -753
- data/src/main/java/processing/data/DoubleList.java +695 -748
- data/src/main/java/processing/data/FloatDict.java +702 -746
- data/src/main/java/processing/data/FloatList.java +697 -751
- data/src/main/java/processing/data/IntDict.java +673 -718
- data/src/main/java/processing/data/IntList.java +633 -699
- data/src/main/java/processing/data/JSONArray.java +873 -931
- data/src/main/java/processing/data/JSONObject.java +1165 -1262
- data/src/main/java/processing/data/JSONTokener.java +341 -351
- data/src/main/java/processing/data/LongDict.java +662 -707
- data/src/main/java/processing/data/LongList.java +634 -700
- data/src/main/java/processing/data/Sort.java +41 -37
- data/src/main/java/processing/data/StringDict.java +486 -522
- data/src/main/java/processing/data/StringList.java +580 -624
- data/src/main/java/processing/data/Table.java +3508 -3686
- data/src/main/java/processing/data/TableRow.java +183 -182
- data/src/main/java/processing/data/XML.java +883 -957
- data/src/main/java/processing/event/Event.java +66 -87
- data/src/main/java/processing/event/KeyEvent.java +41 -48
- data/src/main/java/processing/event/MouseEvent.java +93 -103
- data/src/main/java/processing/event/TouchEvent.java +6 -10
- data/src/main/java/processing/javafx/PGraphicsFX2D.java +5 -69
- data/src/main/java/processing/javafx/PSurfaceFX.java +2 -7
- data/src/main/java/processing/opengl/FontTexture.java +270 -290
- data/src/main/java/processing/opengl/FrameBuffer.java +363 -375
- data/src/main/java/processing/opengl/LinePath.java +500 -543
- data/src/main/java/processing/opengl/LineStroker.java +582 -593
- data/src/main/java/processing/opengl/PGL.java +2881 -2904
- data/src/main/java/processing/opengl/PGraphics2D.java +315 -408
- data/src/main/java/processing/opengl/PGraphics3D.java +72 -107
- data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12043 -12230
- data/src/main/java/processing/opengl/PJOGL.java +1681 -1745
- data/src/main/java/processing/opengl/PShader.java +1257 -1260
- data/src/main/java/processing/opengl/PShapeOpenGL.java +4599 -4662
- data/src/main/java/processing/opengl/PSurfaceJOGL.java +1030 -1047
- data/src/main/java/processing/opengl/Texture.java +1397 -1462
- data/src/main/java/processing/opengl/VertexBuffer.java +55 -57
- data/src/main/resources/icon/icon-1024.png +0 -0
- data/src/main/resources/icon/icon-128.png +0 -0
- data/src/main/resources/icon/icon-16.png +0 -0
- data/src/main/resources/icon/icon-256.png +0 -0
- data/src/main/resources/icon/icon-32.png +0 -0
- data/src/main/resources/icon/icon-48.png +0 -0
- data/src/main/resources/icon/icon-512.png +0 -0
- data/src/main/resources/icon/icon-64.png +0 -0
- data/vendors/Rakefile +1 -1
- metadata +12 -8
- data/src/main/java/processing/core/ThinkDifferent.java +0 -70
|
@@ -6,7 +6,6 @@ import java.util.Iterator;
|
|
|
6
6
|
|
|
7
7
|
import processing.core.PApplet;
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
/**
|
|
11
10
|
* A simple table class to use a String as a lookup for an float value.
|
|
12
11
|
*
|
|
@@ -16,830 +15,787 @@ import processing.core.PApplet;
|
|
|
16
15
|
*/
|
|
17
16
|
public class FloatDict {
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Number of elements in the table
|
|
20
|
+
*/
|
|
21
|
+
protected int count;
|
|
22
|
+
|
|
23
|
+
protected String[] keys;
|
|
24
|
+
protected float[] values;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Internal implementation for faster lookups
|
|
28
|
+
*/
|
|
29
|
+
private HashMap<String, Integer> indices = new HashMap<>();
|
|
30
|
+
|
|
31
|
+
public FloatDict() {
|
|
32
|
+
count = 0;
|
|
33
|
+
keys = new String[10];
|
|
34
|
+
values = new float[10];
|
|
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
|
|
40
|
+
* you're creating.
|
|
41
|
+
*
|
|
42
|
+
* @nowebref
|
|
43
|
+
*/
|
|
44
|
+
public FloatDict(int length) {
|
|
45
|
+
count = 0;
|
|
46
|
+
keys = new String[length];
|
|
47
|
+
values = new float[length];
|
|
48
|
+
}
|
|
49
|
+
|
|
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 FloatDict(BufferedReader reader) {
|
|
57
|
+
String[] lines = PApplet.loadStrings(reader);
|
|
58
|
+
keys = new String[lines.length];
|
|
59
|
+
values = new float[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.parseFloat(pieces[1]);
|
|
66
|
+
indices.put(pieces[0], count);
|
|
67
|
+
count++;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
68
70
|
}
|
|
69
|
-
}
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
72
|
+
/**
|
|
73
|
+
* @nowebref
|
|
74
|
+
*/
|
|
75
|
+
public FloatDict(String[] keys, float[] 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
|
+
}
|
|
84
85
|
}
|
|
85
|
-
}
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Constructor to allow (more intuitive) inline initialization, e.g.:
|
|
89
|
+
* <pre>
|
|
90
|
+
* new FloatDict(new Object[][] {
|
|
91
|
+
* { "key1", 1 },
|
|
92
|
+
* { "key2", 2 }
|
|
93
|
+
* });
|
|
94
|
+
* </pre>
|
|
95
|
+
*/
|
|
96
|
+
public FloatDict(Object[][] pairs) {
|
|
97
|
+
count = pairs.length;
|
|
98
|
+
this.keys = new String[count];
|
|
99
|
+
this.values = new float[count];
|
|
100
|
+
for (int i = 0; i < count; i++) {
|
|
101
|
+
keys[i] = (String) pairs[i][0];
|
|
102
|
+
values[i] = (Float) pairs[i][1];
|
|
103
|
+
indices.put(keys[i], i);
|
|
104
|
+
}
|
|
105
105
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* @webref floatdict:method
|
|
111
|
-
* @brief Returns the number of key/value pairs
|
|
112
|
-
*/
|
|
113
|
-
public int size() {
|
|
114
|
-
return count;
|
|
115
|
-
}
|
|
116
106
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (length == count) return;
|
|
124
|
-
|
|
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");
|
|
107
|
+
/**
|
|
108
|
+
* @webref floatdict:method
|
|
109
|
+
* @brief Returns the number of key/value pairs
|
|
110
|
+
*/
|
|
111
|
+
public int size() {
|
|
112
|
+
return count;
|
|
130
113
|
}
|
|
131
114
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Remove all entries.
|
|
145
|
-
*
|
|
146
|
-
* @webref floatdict:method
|
|
147
|
-
* @brief Remove all entries
|
|
148
|
-
*/
|
|
149
|
-
public void clear() {
|
|
150
|
-
count = 0;
|
|
151
|
-
indices = new HashMap<>();
|
|
152
|
-
}
|
|
115
|
+
/**
|
|
116
|
+
* Resize the internal data, this can only be used to shrink the list.
|
|
117
|
+
* Helpful for situations like sorting and then grabbing the top 50 entries.
|
|
118
|
+
*/
|
|
119
|
+
public void resize(int length) {
|
|
120
|
+
if (length == count) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
153
123
|
|
|
124
|
+
if (length > count) {
|
|
125
|
+
throw new IllegalArgumentException("resize() can only be used to shrink the dictionary");
|
|
126
|
+
}
|
|
127
|
+
if (length < 1) {
|
|
128
|
+
throw new IllegalArgumentException("resize(" + length + ") is too small, use 1 or higher");
|
|
129
|
+
}
|
|
154
130
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
131
|
+
String[] newKeys = new String[length];
|
|
132
|
+
float[] newValues = new float[length];
|
|
133
|
+
PApplet.arrayCopy(keys, newKeys, length);
|
|
134
|
+
PApplet.arrayCopy(values, newValues, length);
|
|
135
|
+
keys = newKeys;
|
|
136
|
+
values = newValues;
|
|
137
|
+
count = length;
|
|
138
|
+
resetIndices();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Remove all entries.
|
|
143
|
+
*
|
|
144
|
+
* @webref floatdict:method
|
|
145
|
+
* @brief Remove all entries
|
|
146
|
+
*/
|
|
147
|
+
public void clear() {
|
|
148
|
+
count = 0;
|
|
149
|
+
indices = new HashMap<>();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private void resetIndices() {
|
|
153
|
+
indices = new HashMap<>(count);
|
|
154
|
+
for (int i = 0; i < count; i++) {
|
|
155
|
+
indices.put(keys[i], i);
|
|
156
|
+
}
|
|
159
157
|
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
164
158
|
|
|
159
|
+
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
160
|
+
public class Entry {
|
|
165
161
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
public float value;
|
|
162
|
+
public String key;
|
|
163
|
+
public float value;
|
|
169
164
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
165
|
+
Entry(String key, float value) {
|
|
166
|
+
this.key = key;
|
|
167
|
+
this.value = value;
|
|
168
|
+
}
|
|
173
169
|
}
|
|
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
170
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
Entry e = new Entry(keys[index], values[index]);
|
|
199
|
-
return e;
|
|
200
|
-
}
|
|
171
|
+
public Iterable<Entry> entries() {
|
|
172
|
+
return new Iterable<Entry>() {
|
|
201
173
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
174
|
+
public Iterator<Entry> iterator() {
|
|
175
|
+
return entryIterator();
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
210
179
|
|
|
180
|
+
public Iterator<Entry> entryIterator() {
|
|
181
|
+
return new Iterator<Entry>() {
|
|
182
|
+
int index = -1;
|
|
211
183
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
184
|
+
public void remove() {
|
|
185
|
+
removeIndex(index);
|
|
186
|
+
index--;
|
|
187
|
+
}
|
|
215
188
|
|
|
189
|
+
public Entry next() {
|
|
190
|
+
++index;
|
|
191
|
+
Entry e = new Entry(keys[index], values[index]);
|
|
192
|
+
return e;
|
|
193
|
+
}
|
|
216
194
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
195
|
+
public boolean hasNext() {
|
|
196
|
+
return index + 1 < size();
|
|
197
|
+
}
|
|
198
|
+
};
|
|
221
199
|
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
200
|
|
|
225
|
-
|
|
226
|
-
|
|
201
|
+
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
202
|
+
public String key(int index) {
|
|
203
|
+
return keys[index];
|
|
204
|
+
}
|
|
227
205
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
206
|
+
protected void crop() {
|
|
207
|
+
if (count != keys.length) {
|
|
208
|
+
keys = PApplet.subset(keys, 0, count);
|
|
209
|
+
values = PApplet.subset(values, 0, count);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
234
212
|
|
|
213
|
+
public Iterable<String> keys() {
|
|
214
|
+
return new Iterable<String>() {
|
|
235
215
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
216
|
+
@Override
|
|
217
|
+
public Iterator<String> iterator() {
|
|
218
|
+
return keyIterator();
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
240
222
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
223
|
+
// Use this to iterate when you want to be able to remove elements along the way
|
|
224
|
+
public Iterator<String> keyIterator() {
|
|
225
|
+
return new Iterator<String>() {
|
|
226
|
+
int index = -1;
|
|
245
227
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
228
|
+
public void remove() {
|
|
229
|
+
removeIndex(index);
|
|
230
|
+
index--;
|
|
231
|
+
}
|
|
249
232
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
};
|
|
254
|
-
}
|
|
233
|
+
public String next() {
|
|
234
|
+
return key(++index);
|
|
235
|
+
}
|
|
255
236
|
|
|
237
|
+
public boolean hasNext() {
|
|
238
|
+
return index + 1 < size();
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
256
242
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
243
|
+
/**
|
|
244
|
+
* Return a copy of the internal keys array. This array can be modified.
|
|
245
|
+
*
|
|
246
|
+
* @webref floatdict:method
|
|
247
|
+
* @brief Return a copy of the internal keys array
|
|
248
|
+
*/
|
|
249
|
+
public String[] keyArray() {
|
|
250
|
+
crop();
|
|
251
|
+
return keyArray(null);
|
|
252
|
+
}
|
|
267
253
|
|
|
254
|
+
public String[] keyArray(String[] outgoing) {
|
|
255
|
+
if (outgoing == null || outgoing.length != count) {
|
|
256
|
+
outgoing = new String[count];
|
|
257
|
+
}
|
|
258
|
+
System.arraycopy(keys, 0, outgoing, 0, count);
|
|
259
|
+
return outgoing;
|
|
260
|
+
}
|
|
268
261
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
outgoing = new String[count];
|
|
262
|
+
public float value(int index) {
|
|
263
|
+
return values[index];
|
|
272
264
|
}
|
|
273
|
-
System.arraycopy(keys, 0, outgoing, 0, count);
|
|
274
|
-
return outgoing;
|
|
275
|
-
}
|
|
276
265
|
|
|
266
|
+
/**
|
|
267
|
+
* @webref floatdict:method
|
|
268
|
+
* @brief Return the internal array being used to store the values
|
|
269
|
+
*/
|
|
270
|
+
public Iterable<Float> values() {
|
|
271
|
+
return new Iterable<Float>() {
|
|
277
272
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
273
|
+
@Override
|
|
274
|
+
public Iterator<Float> iterator() {
|
|
275
|
+
return valueIterator();
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
282
279
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
*/
|
|
287
|
-
public Iterable<Float> values() {
|
|
288
|
-
return new Iterable<Float>() {
|
|
280
|
+
public Iterator<Float> valueIterator() {
|
|
281
|
+
return new Iterator<Float>() {
|
|
282
|
+
int index = -1;
|
|
289
283
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
};
|
|
295
|
-
}
|
|
284
|
+
public void remove() {
|
|
285
|
+
removeIndex(index);
|
|
286
|
+
index--;
|
|
287
|
+
}
|
|
296
288
|
|
|
289
|
+
public Float next() {
|
|
290
|
+
return value(++index);
|
|
291
|
+
}
|
|
297
292
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
293
|
+
public boolean hasNext() {
|
|
294
|
+
return index + 1 < size();
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Create a new array and copy each of the values into it.
|
|
301
|
+
*
|
|
302
|
+
* @webref floatdict:method
|
|
303
|
+
* @brief Create a new array and copy each of the values into it
|
|
304
|
+
*/
|
|
305
|
+
public float[] valueArray() {
|
|
306
|
+
crop();
|
|
307
|
+
return valueArray(null);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Fill an already-allocated array with the values (more efficient than
|
|
312
|
+
* creating a new array each time). If 'array' is null, or not the same size
|
|
313
|
+
* as the number of values, a new array will be allocated and returned.
|
|
314
|
+
*/
|
|
315
|
+
public float[] valueArray(float[] array) {
|
|
316
|
+
if (array == null || array.length != size()) {
|
|
317
|
+
array = new float[count];
|
|
318
|
+
}
|
|
319
|
+
System.arraycopy(values, 0, array, 0, count);
|
|
320
|
+
return array;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Return a value for the specified key.
|
|
325
|
+
*
|
|
326
|
+
* @webref floatdict:method
|
|
327
|
+
* @brief Return a value for the specified key
|
|
328
|
+
*/
|
|
329
|
+
public float get(String key) {
|
|
330
|
+
int index = index(key);
|
|
331
|
+
if (index == -1) {
|
|
332
|
+
throw new IllegalArgumentException("No key named '" + key + "'");
|
|
333
|
+
}
|
|
334
|
+
return values[index];
|
|
335
|
+
}
|
|
301
336
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
index
|
|
305
|
-
|
|
337
|
+
public float get(String key, float alternate) {
|
|
338
|
+
int index = index(key);
|
|
339
|
+
if (index == -1) {
|
|
340
|
+
return alternate;
|
|
341
|
+
}
|
|
342
|
+
return values[index];
|
|
343
|
+
}
|
|
306
344
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
345
|
+
/**
|
|
346
|
+
* @webref floatdict:method
|
|
347
|
+
* @brief Create a new key/value pair or change the value of one
|
|
348
|
+
*/
|
|
349
|
+
public void set(String key, float amount) {
|
|
350
|
+
int index = index(key);
|
|
351
|
+
if (index == -1) {
|
|
352
|
+
create(key, amount);
|
|
353
|
+
} else {
|
|
354
|
+
values[index] = amount;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
310
357
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
System.arraycopy(values, 0, array, 0, count);
|
|
340
|
-
return array;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Return a value for the specified key.
|
|
346
|
-
*
|
|
347
|
-
* @webref floatdict:method
|
|
348
|
-
* @brief Return a value for the specified key
|
|
349
|
-
*/
|
|
350
|
-
public float get(String key) {
|
|
351
|
-
int index = index(key);
|
|
352
|
-
if (index == -1) {
|
|
353
|
-
throw new IllegalArgumentException("No key named '" + key + "'");
|
|
354
|
-
}
|
|
355
|
-
return values[index];
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
public float get(String key, float alternate) {
|
|
360
|
-
int index = index(key);
|
|
361
|
-
if (index == -1) {
|
|
362
|
-
return alternate;
|
|
363
|
-
}
|
|
364
|
-
return values[index];
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* @webref floatdict:method
|
|
370
|
-
* @brief Create a new key/value pair or change the value of one
|
|
371
|
-
*/
|
|
372
|
-
public void set(String key, float amount) {
|
|
373
|
-
int index = index(key);
|
|
374
|
-
if (index == -1) {
|
|
375
|
-
create(key, amount);
|
|
376
|
-
} else {
|
|
377
|
-
values[index] = amount;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
public void setIndex(int index, String key, float value) {
|
|
383
|
-
if (index < 0 || index >= count) {
|
|
384
|
-
throw new ArrayIndexOutOfBoundsException(index);
|
|
385
|
-
}
|
|
386
|
-
keys[index] = key;
|
|
387
|
-
values[index] = value;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* @webref floatdict:method
|
|
393
|
-
* @brief Check if a key is a part of the data structure
|
|
394
|
-
*/
|
|
395
|
-
public boolean hasKey(String key) {
|
|
396
|
-
return index(key) != -1;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* @webref floatdict:method
|
|
402
|
-
* @brief Add to a value
|
|
403
|
-
*/
|
|
404
|
-
public void add(String key, float amount) {
|
|
405
|
-
int index = index(key);
|
|
406
|
-
if (index == -1) {
|
|
407
|
-
create(key, amount);
|
|
408
|
-
} else {
|
|
409
|
-
values[index] += amount;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* @webref floatdict:method
|
|
416
|
-
* @brief Subtract from a value
|
|
417
|
-
*/
|
|
418
|
-
public void sub(String key, float amount) {
|
|
419
|
-
add(key, -amount);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* @webref floatdict:method
|
|
425
|
-
* @brief Multiply a value
|
|
426
|
-
*/
|
|
427
|
-
public void mult(String key, float amount) {
|
|
428
|
-
int index = index(key);
|
|
429
|
-
if (index != -1) {
|
|
430
|
-
values[index] *= amount;
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* @webref floatdict:method
|
|
437
|
-
* @brief Divide a value
|
|
438
|
-
*/
|
|
439
|
-
public void div(String key, float amount) {
|
|
440
|
-
int index = index(key);
|
|
441
|
-
if (index != -1) {
|
|
442
|
-
values[index] /= amount;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
private void checkMinMax(String functionName) {
|
|
448
|
-
if (count == 0) {
|
|
449
|
-
String msg =
|
|
450
|
-
String.format("Cannot use %s() on an empty %s.",
|
|
451
|
-
functionName, getClass().getSimpleName());
|
|
452
|
-
throw new RuntimeException(msg);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* @webref floatlist:method
|
|
459
|
-
* @brief Return the smallest value
|
|
460
|
-
*/
|
|
461
|
-
public int minIndex() {
|
|
462
|
-
//checkMinMax("minIndex");
|
|
463
|
-
if (count == 0) return -1;
|
|
464
|
-
|
|
465
|
-
// Will still return NaN if there are 1 or more entries, and they're all NaN
|
|
466
|
-
float m = Float.NaN;
|
|
467
|
-
int mi = -1;
|
|
468
|
-
for (int i = 0; i < count; i++) {
|
|
469
|
-
// find one good value to start
|
|
470
|
-
if (values[i] == values[i]) {
|
|
471
|
-
m = values[i];
|
|
472
|
-
mi = i;
|
|
473
|
-
|
|
474
|
-
// calculate the rest
|
|
475
|
-
for (int j = i+1; j < count; j++) {
|
|
476
|
-
float d = values[j];
|
|
477
|
-
if ((d == d) && (d < m)) {
|
|
478
|
-
m = values[j];
|
|
479
|
-
mi = j;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
break;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
return mi;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
// return the key for the minimum value
|
|
490
|
-
public String minKey() {
|
|
491
|
-
checkMinMax("minKey");
|
|
492
|
-
int index = minIndex();
|
|
493
|
-
if (index == -1) {
|
|
494
|
-
return null;
|
|
495
|
-
}
|
|
496
|
-
return keys[index];
|
|
497
|
-
}
|
|
358
|
+
public void setIndex(int index, String key, float value) {
|
|
359
|
+
if (index < 0 || index >= count) {
|
|
360
|
+
throw new ArrayIndexOutOfBoundsException(index);
|
|
361
|
+
}
|
|
362
|
+
keys[index] = key;
|
|
363
|
+
values[index] = value;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @webref floatdict:method
|
|
368
|
+
* @brief Check if a key is a part of the data structure
|
|
369
|
+
*/
|
|
370
|
+
public boolean hasKey(String key) {
|
|
371
|
+
return index(key) != -1;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @webref floatdict:method
|
|
376
|
+
* @brief Add to a value
|
|
377
|
+
*/
|
|
378
|
+
public void add(String key, float amount) {
|
|
379
|
+
int index = index(key);
|
|
380
|
+
if (index == -1) {
|
|
381
|
+
create(key, amount);
|
|
382
|
+
} else {
|
|
383
|
+
values[index] += amount;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
498
386
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
return Float.NaN;
|
|
387
|
+
/**
|
|
388
|
+
* @webref floatdict:method
|
|
389
|
+
* @brief Subtract from a value
|
|
390
|
+
*/
|
|
391
|
+
public void sub(String key, float amount) {
|
|
392
|
+
add(key, -amount);
|
|
506
393
|
}
|
|
507
|
-
return values[index];
|
|
508
|
-
}
|
|
509
394
|
|
|
395
|
+
/**
|
|
396
|
+
* @webref floatdict:method
|
|
397
|
+
* @brief Multiply a value
|
|
398
|
+
*/
|
|
399
|
+
public void mult(String key, float amount) {
|
|
400
|
+
int index = index(key);
|
|
401
|
+
if (index != -1) {
|
|
402
|
+
values[index] *= amount;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
510
405
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
406
|
+
/**
|
|
407
|
+
* @webref floatdict:method
|
|
408
|
+
* @brief Divide a value
|
|
409
|
+
*/
|
|
410
|
+
public void div(String key, float amount) {
|
|
411
|
+
int index = index(key);
|
|
412
|
+
if (index != -1) {
|
|
413
|
+
values[index] /= amount;
|
|
414
|
+
}
|
|
520
415
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
// calculate the rest
|
|
531
|
-
for (int j = i+1; j < count; j++) {
|
|
532
|
-
float d = values[j];
|
|
533
|
-
if (!Float.isNaN(d) && (d > m)) {
|
|
534
|
-
m = values[j];
|
|
535
|
-
mi = j;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
break;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
return mi;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
/** The key for a max value; null if empty or everything is NaN (no max). */
|
|
546
|
-
public String maxKey() {
|
|
547
|
-
//checkMinMax("maxKey");
|
|
548
|
-
int index = maxIndex();
|
|
549
|
-
if (index == -1) {
|
|
550
|
-
return null;
|
|
551
|
-
}
|
|
552
|
-
return keys[index];
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
/** The max value. (Or NaN if no entries or they're all NaN.) */
|
|
557
|
-
public float maxValue() {
|
|
558
|
-
//checkMinMax("maxValue");
|
|
559
|
-
int index = maxIndex();
|
|
560
|
-
if (index == -1) {
|
|
561
|
-
return Float.NaN;
|
|
562
|
-
}
|
|
563
|
-
return values[index];
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
public float sum() {
|
|
568
|
-
double amount = sumDouble();
|
|
569
|
-
if (amount > Float.MAX_VALUE) {
|
|
570
|
-
throw new RuntimeException("sum() exceeds " + Float.MAX_VALUE + ", use sumDouble()");
|
|
416
|
+
|
|
417
|
+
private void checkMinMax(String functionName) {
|
|
418
|
+
if (count == 0) {
|
|
419
|
+
String msg
|
|
420
|
+
= String.format("Cannot use %s() on an empty %s.",
|
|
421
|
+
functionName, getClass().getSimpleName());
|
|
422
|
+
throw new RuntimeException(msg);
|
|
423
|
+
}
|
|
571
424
|
}
|
|
572
|
-
if (amount < -Float.MAX_VALUE) {
|
|
573
|
-
throw new RuntimeException("sum() lower than " + -Float.MAX_VALUE + ", use sumDouble()");
|
|
574
|
-
}
|
|
575
|
-
return (float) amount;
|
|
576
|
-
}
|
|
577
425
|
|
|
426
|
+
/**
|
|
427
|
+
* @webref floatlist:method
|
|
428
|
+
* @brief Return the smallest value
|
|
429
|
+
*/
|
|
430
|
+
public int minIndex() {
|
|
431
|
+
//checkMinMax("minIndex");
|
|
432
|
+
if (count == 0) {
|
|
433
|
+
return -1;
|
|
434
|
+
}
|
|
578
435
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
436
|
+
// Will still return NaN if there are 1 or more entries, and they're all NaN
|
|
437
|
+
float m = Float.NaN;
|
|
438
|
+
int mi = -1;
|
|
439
|
+
for (int i = 0; i < count; i++) {
|
|
440
|
+
// find one good value to start
|
|
441
|
+
if (values[i] == values[i]) {
|
|
442
|
+
m = values[i];
|
|
443
|
+
mi = i;
|
|
444
|
+
|
|
445
|
+
// calculate the rest
|
|
446
|
+
for (int j = i + 1; j < count; j++) {
|
|
447
|
+
float d = values[j];
|
|
448
|
+
if ((d == d) && (d < m)) {
|
|
449
|
+
m = values[j];
|
|
450
|
+
mi = j;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return mi;
|
|
583
457
|
}
|
|
584
|
-
return sum;
|
|
585
|
-
}
|
|
586
458
|
|
|
459
|
+
// return the key for the minimum value
|
|
460
|
+
public String minKey() {
|
|
461
|
+
checkMinMax("minKey");
|
|
462
|
+
int index = minIndex();
|
|
463
|
+
if (index == -1) {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
return keys[index];
|
|
467
|
+
}
|
|
587
468
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
469
|
+
// return the minimum value, or throw an error if there are no values
|
|
470
|
+
public float minValue() {
|
|
471
|
+
checkMinMax("minValue");
|
|
472
|
+
int index = minIndex();
|
|
473
|
+
if (index == -1) {
|
|
474
|
+
return Float.NaN;
|
|
475
|
+
}
|
|
476
|
+
return values[index];
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* @webref floatlist:method
|
|
481
|
+
* @brief Return the largest value
|
|
482
|
+
*/
|
|
483
|
+
// The index of the entry that has the max value. Reference above is incorrect.
|
|
484
|
+
public int maxIndex() {
|
|
485
|
+
//checkMinMax("maxIndex");
|
|
486
|
+
if (count == 0) {
|
|
487
|
+
return -1;
|
|
488
|
+
}
|
|
489
|
+
// Will still return NaN if there is 1 or more entries, and they're all NaN
|
|
490
|
+
float m = Float.NaN;
|
|
491
|
+
int mi = -1;
|
|
492
|
+
for (int i = 0; i < count; i++) {
|
|
493
|
+
// find one good value to start
|
|
494
|
+
if (values[i] == values[i]) {
|
|
495
|
+
m = values[i];
|
|
496
|
+
mi = i;
|
|
497
|
+
|
|
498
|
+
// calculate the rest
|
|
499
|
+
for (int j = i + 1; j < count; j++) {
|
|
500
|
+
float d = values[j];
|
|
501
|
+
if (!Float.isNaN(d) && (d > m)) {
|
|
502
|
+
m = values[j];
|
|
503
|
+
mi = j;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
return mi;
|
|
510
|
+
}
|
|
592
511
|
|
|
512
|
+
/**
|
|
513
|
+
* The key for a max value; null if empty or everything is NaN (no max).
|
|
514
|
+
*/
|
|
515
|
+
public String maxKey() {
|
|
516
|
+
//checkMinMax("maxKey");
|
|
517
|
+
int index = maxIndex();
|
|
518
|
+
if (index == -1) {
|
|
519
|
+
return null;
|
|
520
|
+
}
|
|
521
|
+
return keys[index];
|
|
522
|
+
}
|
|
593
523
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
524
|
+
/**
|
|
525
|
+
* The max value. (Or NaN if no entries or they're all NaN.)
|
|
526
|
+
*/
|
|
527
|
+
public float maxValue() {
|
|
528
|
+
//checkMinMax("maxValue");
|
|
529
|
+
int index = maxIndex();
|
|
530
|
+
if (index == -1) {
|
|
531
|
+
return Float.NaN;
|
|
532
|
+
}
|
|
533
|
+
return values[index];
|
|
598
534
|
}
|
|
599
|
-
indices.put(what, Integer.valueOf(count));
|
|
600
|
-
keys[count] = what;
|
|
601
|
-
values[count] = much;
|
|
602
|
-
count++;
|
|
603
|
-
}
|
|
604
535
|
|
|
536
|
+
public float sum() {
|
|
537
|
+
double amount = sumDouble();
|
|
538
|
+
if (amount > Float.MAX_VALUE) {
|
|
539
|
+
throw new RuntimeException("sum() exceeds " + Float.MAX_VALUE + ", use sumDouble()");
|
|
540
|
+
}
|
|
541
|
+
if (amount < -Float.MAX_VALUE) {
|
|
542
|
+
throw new RuntimeException("sum() lower than " + -Float.MAX_VALUE + ", use sumDouble()");
|
|
543
|
+
}
|
|
544
|
+
return (float) amount;
|
|
545
|
+
}
|
|
605
546
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
removeIndex(index);
|
|
614
|
-
}
|
|
615
|
-
return index;
|
|
616
|
-
}
|
|
547
|
+
public double sumDouble() {
|
|
548
|
+
double sum = 0;
|
|
549
|
+
for (int i = 0; i < count; i++) {
|
|
550
|
+
sum += values[i];
|
|
551
|
+
}
|
|
552
|
+
return sum;
|
|
553
|
+
}
|
|
617
554
|
|
|
555
|
+
public int index(String what) {
|
|
556
|
+
Integer found = indices.get(what);
|
|
557
|
+
return (found == null) ? -1 : found.intValue();
|
|
558
|
+
}
|
|
618
559
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
560
|
+
protected void create(String what, float much) {
|
|
561
|
+
if (count == keys.length) {
|
|
562
|
+
keys = PApplet.expand(keys);
|
|
563
|
+
values = PApplet.expand(values);
|
|
564
|
+
}
|
|
565
|
+
indices.put(what, Integer.valueOf(count));
|
|
566
|
+
keys[count] = what;
|
|
567
|
+
values[count] = much;
|
|
568
|
+
count++;
|
|
622
569
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* @webref floatdict:method
|
|
573
|
+
* @brief Remove a key/value pair
|
|
574
|
+
*/
|
|
575
|
+
public int remove(String key) {
|
|
576
|
+
int index = index(key);
|
|
577
|
+
if (index != -1) {
|
|
578
|
+
removeIndex(index);
|
|
579
|
+
}
|
|
580
|
+
return index;
|
|
630
581
|
}
|
|
631
|
-
count--;
|
|
632
|
-
keys[count] = null;
|
|
633
|
-
values[count] = 0;
|
|
634
|
-
return key;
|
|
635
|
-
}
|
|
636
582
|
|
|
583
|
+
public String removeIndex(int index) {
|
|
584
|
+
if (index < 0 || index >= count) {
|
|
585
|
+
throw new ArrayIndexOutOfBoundsException(index);
|
|
586
|
+
}
|
|
587
|
+
String key = keys[index];
|
|
588
|
+
//System.out.println("index is " + which + " and " + keys[which]);
|
|
589
|
+
indices.remove(keys[index]);
|
|
590
|
+
for (int i = index; i < count - 1; i++) {
|
|
591
|
+
keys[i] = keys[i + 1];
|
|
592
|
+
values[i] = values[i + 1];
|
|
593
|
+
indices.put(keys[i], i);
|
|
594
|
+
}
|
|
595
|
+
count--;
|
|
596
|
+
keys[count] = null;
|
|
597
|
+
values[count] = 0;
|
|
598
|
+
return key;
|
|
599
|
+
}
|
|
637
600
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
601
|
+
public void swap(int a, int b) {
|
|
602
|
+
String tkey = keys[a];
|
|
603
|
+
float tvalue = values[a];
|
|
604
|
+
keys[a] = keys[b];
|
|
605
|
+
values[a] = values[b];
|
|
606
|
+
keys[b] = tkey;
|
|
607
|
+
values[b] = tvalue;
|
|
645
608
|
|
|
646
609
|
// indices.put(keys[a], Integer.valueOf(a));
|
|
647
610
|
// indices.put(keys[b], Integer.valueOf(b));
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
/**
|
|
652
|
-
* Sort the keys alphabetically (ignoring case). Uses the value as a
|
|
653
|
-
* tie-breaker (only really possible with a key that has a case change).
|
|
654
|
-
*
|
|
655
|
-
* @webref floatdict:method
|
|
656
|
-
* @brief Sort the keys alphabetically
|
|
657
|
-
*/
|
|
658
|
-
public void sortKeys() {
|
|
659
|
-
sortImpl(true, false, true);
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
/**
|
|
664
|
-
* @webref floatdict:method
|
|
665
|
-
* @brief Sort the keys alphabetically in reverse
|
|
666
|
-
*/
|
|
667
|
-
public void sortKeysReverse() {
|
|
668
|
-
sortImpl(true, true, true);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
/**
|
|
673
|
-
* Sort by values in descending order (largest value will be at [0]).
|
|
674
|
-
*
|
|
675
|
-
* @webref floatdict:method
|
|
676
|
-
* @brief Sort by values in ascending order
|
|
677
|
-
*/
|
|
678
|
-
public void sortValues() {
|
|
679
|
-
sortValues(true);
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
/**
|
|
684
|
-
* Set true to ensure that the order returned is identical. Slightly
|
|
685
|
-
* slower because the tie-breaker for identical values compares the keys.
|
|
686
|
-
* @param stable
|
|
687
|
-
*/
|
|
688
|
-
public void sortValues(boolean stable) {
|
|
689
|
-
sortImpl(false, false, stable);
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
/**
|
|
694
|
-
* @webref floatdict:method
|
|
695
|
-
* @brief Sort by values in descending order
|
|
696
|
-
*/
|
|
697
|
-
public void sortValuesReverse() {
|
|
698
|
-
sortValuesReverse(true);
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
public void sortValuesReverse(boolean stable) {
|
|
703
|
-
sortImpl(false, true, stable);
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
protected void sortImpl(final boolean useKeys, final boolean reverse,
|
|
708
|
-
final boolean stable) {
|
|
709
|
-
Sort s = new Sort() {
|
|
710
|
-
@Override
|
|
711
|
-
public int size() {
|
|
712
|
-
if (useKeys) {
|
|
713
|
-
return count; // don't worry about NaN values
|
|
714
|
-
|
|
715
|
-
} else if (count == 0) { // skip the NaN check, it'll AIOOBE
|
|
716
|
-
return 0;
|
|
717
|
-
|
|
718
|
-
} else { // first move NaN values to the end of the list
|
|
719
|
-
int right = count - 1;
|
|
720
|
-
while (values[right] != values[right]) {
|
|
721
|
-
right--;
|
|
722
|
-
if (right == -1) {
|
|
723
|
-
return 0; // all values are NaN
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
for (int i = right; i >= 0; --i) {
|
|
727
|
-
if (Float.isNaN(values[i])) {
|
|
728
|
-
swap(i, right);
|
|
729
|
-
--right;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
return right + 1;
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
@Override
|
|
737
|
-
public int compare(int a, int b) {
|
|
738
|
-
float diff = 0;
|
|
739
|
-
if (useKeys) {
|
|
740
|
-
diff = keys[a].compareToIgnoreCase(keys[b]);
|
|
741
|
-
if (diff == 0) {
|
|
742
|
-
diff = values[a] - values[b];
|
|
743
|
-
}
|
|
744
|
-
} else { // sort values
|
|
745
|
-
diff = values[a] - values[b];
|
|
746
|
-
if (diff == 0 && stable) {
|
|
747
|
-
diff = keys[a].compareToIgnoreCase(keys[b]);
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
if (diff == 0) {
|
|
751
|
-
return 0;
|
|
752
|
-
} else if (reverse) {
|
|
753
|
-
return diff < 0 ? 1 : -1;
|
|
754
|
-
} else {
|
|
755
|
-
return diff < 0 ? -1 : 1;
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
@Override
|
|
760
|
-
public void swap(int a, int b) {
|
|
761
|
-
FloatDict.this.swap(a, b);
|
|
762
|
-
}
|
|
763
|
-
};
|
|
764
|
-
s.run();
|
|
611
|
+
}
|
|
765
612
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
613
|
+
/**
|
|
614
|
+
* Sort the keys alphabetically (ignoring case). Uses the value as a
|
|
615
|
+
* tie-breaker (only really possible with a key that has a case change).
|
|
616
|
+
*
|
|
617
|
+
* @webref floatdict:method
|
|
618
|
+
* @brief Sort the keys alphabetically
|
|
619
|
+
*/
|
|
620
|
+
public void sortKeys() {
|
|
621
|
+
sortImpl(true, false, true);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* @webref floatdict:method
|
|
626
|
+
* @brief Sort the keys alphabetically in reverse
|
|
627
|
+
*/
|
|
628
|
+
public void sortKeysReverse() {
|
|
629
|
+
sortImpl(true, true, true);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Sort by values in descending order (largest value will be at [0]).
|
|
634
|
+
*
|
|
635
|
+
* @webref floatdict:method
|
|
636
|
+
* @brief Sort by values in ascending order
|
|
637
|
+
*/
|
|
638
|
+
public void sortValues() {
|
|
639
|
+
sortValues(true);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Set true to ensure that the order returned is identical. Slightly slower
|
|
644
|
+
* because the tie-breaker for identical values compares the keys.
|
|
645
|
+
*
|
|
646
|
+
* @param stable
|
|
647
|
+
*/
|
|
648
|
+
public void sortValues(boolean stable) {
|
|
649
|
+
sortImpl(false, false, stable);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* @webref floatdict:method
|
|
654
|
+
* @brief Sort by values in descending order
|
|
655
|
+
*/
|
|
656
|
+
public void sortValuesReverse() {
|
|
657
|
+
sortValuesReverse(true);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
public void sortValuesReverse(boolean stable) {
|
|
661
|
+
sortImpl(false, true, stable);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
protected void sortImpl(final boolean useKeys, final boolean reverse,
|
|
665
|
+
final boolean stable) {
|
|
666
|
+
Sort s = new Sort() {
|
|
667
|
+
@Override
|
|
668
|
+
public int size() {
|
|
669
|
+
if (useKeys) {
|
|
670
|
+
return count; // don't worry about NaN values
|
|
671
|
+
|
|
672
|
+
} else if (count == 0) { // skip the NaN check, it'll AIOOBE
|
|
673
|
+
return 0;
|
|
674
|
+
|
|
675
|
+
} else { // first move NaN values to the end of the list
|
|
676
|
+
int right = count - 1;
|
|
677
|
+
while (values[right] != values[right]) {
|
|
678
|
+
right--;
|
|
679
|
+
if (right == -1) {
|
|
680
|
+
return 0; // all values are NaN
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
for (int i = right; i >= 0; --i) {
|
|
684
|
+
if (Float.isNaN(values[i])) {
|
|
685
|
+
swap(i, right);
|
|
686
|
+
--right;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return right + 1;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
769
692
|
|
|
693
|
+
@Override
|
|
694
|
+
public int compare(int a, int b) {
|
|
695
|
+
float diff = 0;
|
|
696
|
+
if (useKeys) {
|
|
697
|
+
diff = keys[a].compareToIgnoreCase(keys[b]);
|
|
698
|
+
if (diff == 0) {
|
|
699
|
+
diff = values[a] - values[b];
|
|
700
|
+
}
|
|
701
|
+
} else { // sort values
|
|
702
|
+
diff = values[a] - values[b];
|
|
703
|
+
if (diff == 0 && stable) {
|
|
704
|
+
diff = keys[a].compareToIgnoreCase(keys[b]);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
if (diff == 0) {
|
|
708
|
+
return 0;
|
|
709
|
+
} else if (reverse) {
|
|
710
|
+
return diff < 0 ? 1 : -1;
|
|
711
|
+
} else {
|
|
712
|
+
return diff < 0 ? -1 : 1;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
770
715
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
716
|
+
@Override
|
|
717
|
+
public void swap(int a, int b) {
|
|
718
|
+
FloatDict.this.swap(a, b);
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
s.run();
|
|
722
|
+
|
|
723
|
+
// Set the indices after sort/swaps (performance fix 160411)
|
|
724
|
+
resetIndices();
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Sum all of the values in this dictionary, then return a new FloatDict of
|
|
729
|
+
* each key, divided by the total sum. The total for all values will be
|
|
730
|
+
* ~1.0.
|
|
731
|
+
*
|
|
732
|
+
* @return a FloatDict with the original keys, mapped to their pct of the
|
|
733
|
+
* total
|
|
734
|
+
*/
|
|
735
|
+
public FloatDict getPercent() {
|
|
736
|
+
double sum = sum();
|
|
737
|
+
FloatDict outgoing = new FloatDict();
|
|
738
|
+
for (int i = 0; i < size(); i++) {
|
|
739
|
+
double percent = value(i) / sum;
|
|
740
|
+
outgoing.set(key(i), (float) percent);
|
|
741
|
+
}
|
|
742
|
+
return outgoing;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Returns a duplicate copy of this object.
|
|
747
|
+
*/
|
|
748
|
+
public FloatDict copy() {
|
|
749
|
+
FloatDict outgoing = new FloatDict(count);
|
|
750
|
+
System.arraycopy(keys, 0, outgoing.keys, 0, count);
|
|
751
|
+
System.arraycopy(values, 0, outgoing.values, 0, count);
|
|
752
|
+
for (int i = 0; i < count; i++) {
|
|
753
|
+
outgoing.indices.put(keys[i], i);
|
|
754
|
+
}
|
|
755
|
+
outgoing.count = count;
|
|
756
|
+
return outgoing;
|
|
782
757
|
}
|
|
783
|
-
return outgoing;
|
|
784
|
-
}
|
|
785
758
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
System.arraycopy(keys, 0, outgoing.keys, 0, count);
|
|
791
|
-
System.arraycopy(values, 0, outgoing.values, 0, count);
|
|
792
|
-
for (int i = 0; i < count; i++) {
|
|
793
|
-
outgoing.indices.put(keys[i], i);
|
|
759
|
+
public void print() {
|
|
760
|
+
for (int i = 0; i < size(); i++) {
|
|
761
|
+
System.out.println(keys[i] + " = " + values[i]);
|
|
762
|
+
}
|
|
794
763
|
}
|
|
795
|
-
outgoing.count = count;
|
|
796
|
-
return outgoing;
|
|
797
|
-
}
|
|
798
764
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
765
|
+
/**
|
|
766
|
+
* Save tab-delimited entries to a file (TSV format, UTF-8 encoding)
|
|
767
|
+
*/
|
|
768
|
+
public void save(File file) {
|
|
769
|
+
PrintWriter writer = PApplet.createWriter(file);
|
|
770
|
+
write(writer);
|
|
771
|
+
writer.close();
|
|
803
772
|
}
|
|
804
|
-
}
|
|
805
|
-
|
|
806
773
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
write(writer)
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
/**
|
|
818
|
-
* Write tab-delimited entries out to
|
|
819
|
-
* @param writer
|
|
820
|
-
*/
|
|
821
|
-
public void write(PrintWriter writer) {
|
|
822
|
-
for (int i = 0; i < count; i++) {
|
|
823
|
-
writer.println(keys[i] + "\t" + values[i]);
|
|
774
|
+
/**
|
|
775
|
+
* Write tab-delimited entries out to
|
|
776
|
+
*
|
|
777
|
+
* @param writer
|
|
778
|
+
*/
|
|
779
|
+
public void write(PrintWriter writer) {
|
|
780
|
+
for (int i = 0; i < count; i++) {
|
|
781
|
+
writer.println(keys[i] + "\t" + values[i]);
|
|
782
|
+
}
|
|
783
|
+
writer.flush();
|
|
824
784
|
}
|
|
825
|
-
writer.flush();
|
|
826
|
-
}
|
|
827
|
-
|
|
828
785
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
786
|
+
/**
|
|
787
|
+
* Return this dictionary as a String in JSON format.
|
|
788
|
+
*/
|
|
789
|
+
public String toJSON() {
|
|
790
|
+
StringList items = new StringList();
|
|
791
|
+
for (int i = 0; i < count; i++) {
|
|
792
|
+
items.append(JSONObject.quote(keys[i]) + ": " + values[i]);
|
|
793
|
+
}
|
|
794
|
+
return "{ " + items.join(", ") + " }";
|
|
836
795
|
}
|
|
837
|
-
return "{ " + items.join(", ") + " }";
|
|
838
|
-
}
|
|
839
|
-
|
|
840
796
|
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
797
|
+
@Override
|
|
798
|
+
public String toString() {
|
|
799
|
+
return getClass().getSimpleName() + " size=" + size() + " " + toJSON();
|
|
800
|
+
}
|
|
845
801
|
}
|