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