/
core.py
693 lines (599 loc) · 22.9 KB
/
core.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
# We expose many Processing-related names as builtins, so that no imports
# are necessary, even in auxilliary modules.
import __builtin__
import os.path
from numbers import Number
# Bring all of the core Processing classes by name into the builtin namespace.
from processing.core import PApplet
__builtin__.PApplet = PApplet
from processing.core import PConstants
__builtin__.PConstants = PConstants
from processing.core import PFont
__builtin__.PFont = PFont
from processing.core import PGraphics
__builtin__.PGraphics = PGraphics
from processing.core import PImage
__builtin__.PImage = PImage
from processing.core import PMatrix
__builtin__.PMatrix = PMatrix
from processing.core import PMatrix2D
__builtin__.PMatrix2D = PMatrix2D
from processing.core import PMatrix3D
__builtin__.PMatrix3D = PMatrix3D
from processing.core import PShape
__builtin__.PShape = PShape
from processing.core import PShapeOBJ
__builtin__.PShapeOBJ = PShapeOBJ
from processing.core import PShapeSVG
__builtin__.PShapeSVG = PShapeSVG
from processing.core import PStyle
__builtin__.PStyle = PStyle
from processing.core import PSurface
__builtin__.PSurface = PSurface
# PVector requires special handling, because it exposes the same method names
# as static methods and instance methods.
from processing.core import PVector as __pvector__
class PVector(__pvector__):
def __instance_add__(self, *args):
if len(args) == 1:
v = args[0]
self.x += v.x
self.y += v.y
self.z += v.z
else:
self.x += args[0]
self.y += args[1]
self.z += args[2]
return self
def __instance_sub__(self, *args):
if len(args) == 1:
v = args[0]
self.x -= v.x
self.y -= v.y
self.z -= v.z
else:
self.x -= args[0]
self.y -= args[1]
self.z -= args[2]
return self
def __instance_mult__(self, o):
return PVector.mult(self, o, self)
def __instance_div__(self, f):
return PVector.div(self, f, self)
def __instance_cross__(self, o):
return PVector.cross(self, o, self)
def __instance_dist__(self, o):
return PVector.dist(self, o)
def __instance_dot__(self, *args):
if len(args) == 1:
v = args[0]
return self.x * v.x + self.y * v.y + self.z * v.z
return self.x * args[0] + self.y * args[1] + self.z * args[2]
def __instance_lerp__(self, *args):
if len(args) == 4:
x = args[0]
y = args[1]
z = args[2]
t = args[3]
elif len(args) == 2:
v = args[0]
x = v.x
y = v.y
z = v.z
t = args[1]
else:
raise Exception('lerp takes either (x, y, z, t) or (v, t)')
__pvector__.lerp(self, x, y, z, t)
return self
def __init__(self, x=0, y=0, z=0):
__pvector__.__init__(self, x, y, z)
self.add = self.__instance_add__
self.sub = self.__instance_sub__
self.mult = self.__instance_mult__
self.div = self.__instance_div__
self.cross = self.__instance_cross__
self.dist = self.__instance_dist__
self.dot = self.__instance_dot__
self.lerp = self.__instance_lerp__
def get(self):
return PVector(self.x, self.y, self.z)
def copy(self):
return PVector(self.x, self.y, self.z)
def __copy__(self):
return PVector(self.x, self.y, self.z)
def __deepcopy__(self, memo):
return PVector(self.x, self.y, self.z)
@classmethod
def add(cls, a, b, dest=None):
if dest is None:
return PVector(a.x + b.x, a.y + b.y, a.z + b.z)
dest.set(a.x + b.x, a.y + b.y, a.z + b.z)
return dest
@classmethod
def sub(cls, a, b, dest=None):
if dest is None:
return PVector(a.x - b.x, a.y - b.y, a.z - b.z)
dest.set(a.x - b.x, a.y - b.y, a.z - b.z)
return dest
@classmethod
def mult(cls, a, b, dest=None):
if dest is None:
return PVector(a.x * b, a.y * b, a.z * b)
dest.set(a.x * b, a.y * b, a.z * b)
return dest
@classmethod
def div(cls, a, b, dest=None):
if dest is None:
return PVector(a.x / b, a.y / b, a.z / b)
dest.set(a.x / b, a.y / b, a.z / b)
return dest
@classmethod
def dist(cls, a, b):
return __pvector__.dist(a, b)
@classmethod
def dot(cls, a, b):
return __pvector__.dot(a, b)
@classmethod
def lerp(cls, a, b, f):
v = a.copy()
v.lerp(b, f)
return v
@classmethod
def cross(cls, a, b, dest=None):
x = a.y * b.z - b.y * a.z
y = a.z * b.x - b.z * a.x
z = a.x * b.y - b.x * a.y
if dest is None:
return PVector(x, y, z)
dest.set(x, y, z)
return dest
def __add__(a, b):
return PVector.add(a, b, None)
def __sub__(a, b):
return PVector.sub(a, b, None)
def __isub__(a, b):
a.sub(b)
return a
def __iadd__(a, b):
a.add(b)
return a
def __mul__(a, b):
if not isinstance(b, Number):
raise TypeError("The * operator can only be used to multiply a PVector by a number")
return PVector.mult(a, float(b), None)
def __rmul__(a, b):
if not isinstance(b, Number):
raise TypeError("The * operator can only be used to multiply a PVector by a number")
return PVector.mult(a, float(b), None)
def __imul__(a, b):
if not isinstance(b, Number):
raise TypeError("The *= operator can only be used to multiply a PVector by a number")
a.mult(float(b))
return a
def __div__(a, b):
if not isinstance(b, Number):
raise TypeError("The / operator can only be used to divide a PVector by a number")
return PVector.div(a, float(b), None)
def __idiv__(a, b):
if not isinstance(b, Number):
raise TypeError("The /= operator can only be used to divide a PVector by a number")
a.div(float(b))
return a
def __eq__(a, b):
return a.x == b.x and a.y == b.y and a.z == b.z
def __lt__(a, b):
return a.magSq() < b.magSq()
def __le__(a, b):
return a.magSq() <= b.magSq()
def __gt__(a, b):
return a.magSq() > b.magSq()
def __ge__(a, b):
return a.magSq() >= b.magSq()
# Now expose the funky PVector class as a builtin.
__builtin__.PVector = PVector
# Make the PApplet available to sketches by the name "this", to better match
# existing Java-based documentation for third-party libraries, and such.
__builtin__.this = __papplet__
# Expose all of the builtin Processing methods. Credit is due to
# https://github.com/kazimuth/python-mode-processing for the
# technique of exploiting Jython's bound methods, which is tidy
# and simple.
__builtin__.ambient = __papplet__.ambient
__builtin__.ambientLight = __papplet__.ambientLight
__builtin__.applyMatrix = __papplet__.applyMatrix
__builtin__.arc = __papplet__.arc
__builtin__.background = __papplet__.background
__builtin__.beginCamera = __papplet__.beginCamera
__builtin__.beginContour = __papplet__.beginContour
__builtin__.beginPGL = __papplet__.beginPGL
__builtin__.beginRaw = __papplet__.beginRaw
__builtin__.beginRecord = __papplet__.beginRecord
__builtin__.beginShape = __papplet__.beginShape
__builtin__.bezier = __papplet__.bezier
__builtin__.bezierDetail = __papplet__.bezierDetail
__builtin__.bezierPoint = __papplet__.bezierPoint
__builtin__.bezierTangent = __papplet__.bezierTangent
__builtin__.bezierVertex = __papplet__.bezierVertex
__builtin__.blend = __papplet__.blend
__builtin__.blendMode = __papplet__.blendMode
__builtin__.box = __papplet__.box
__builtin__.camera = __papplet__.camera
__builtin__.clear = __papplet__.clear
__builtin__.clip = __papplet__.clip
__builtin__.color = __papplet__.color
__builtin__.colorMode = __papplet__.colorMode
__builtin__.copy = __papplet__.copy
__builtin__.createFont = __papplet__.createFont
__builtin__.createGraphics = __papplet__.createGraphics
__builtin__.createImage = __papplet__.createImage
__builtin__.createInput = __papplet__.createInput
__builtin__.createOutput = __papplet__.createOutput
__builtin__.createReader = __papplet__.createReader
__builtin__.createShape = __papplet__.createShape
__builtin__.cursor = __papplet__.cursor
__builtin__.curve = __papplet__.curve
__builtin__.curveDetail = __papplet__.curveDetail
__builtin__.curvePoint = __papplet__.curvePoint
__builtin__.curveTangent = __papplet__.curveTangent
__builtin__.curveTightness = __papplet__.curveTightness
__builtin__.curveVertex = __papplet__.curveVertex
__builtin__.delay = __papplet__.delay
__builtin__.directionalLight = __papplet__.directionalLight
__builtin__.displayDensity = __papplet__.displayDensity
__builtin__.ellipse = __papplet__.ellipse
__builtin__.ellipseMode = __papplet__.ellipseMode
__builtin__.emissive = __papplet__.emissive
__builtin__.endCamera = __papplet__.endCamera
__builtin__.endContour = __papplet__.endContour
__builtin__.endPGL = __papplet__.endPGL
__builtin__.endRaw = __papplet__.endRaw
__builtin__.endRecord = __papplet__.endRecord
__builtin__.endShape = __papplet__.endShape
__builtin__.exit = __papplet__.exit
__builtin__.fill = __papplet__.fill
# We handle filter() by hand to permit both P5's filter() and Python's filter().
# __builtin__.filter = __papplet__.filter
__builtin__.frameRate = __papplet__.frameRate
__builtin__.frustum = __papplet__.frustum
__builtin__.fullScreen = __papplet__.fullScreen
__builtin__.hint = __papplet__.hint
__builtin__.image = __papplet__.image
__builtin__.imageMode = __papplet__.imageMode
__builtin__.launch = __papplet__.launch
__builtin__.lightFalloff = __papplet__.lightFalloff
__builtin__.lightSpecular = __papplet__.lightSpecular
__builtin__.lights = __papplet__.lights
__builtin__.line = __papplet__.line
__builtin__.link = __papplet__.link
__builtin__.loadBytes = __papplet__.loadBytes
__builtin__.loadFont = __papplet__.loadFont
__builtin__.loadImage = __papplet__.loadImage
__builtin__.loadJSONArray = __papplet__.loadJSONArray
__builtin__.loadJSONObject = __papplet__.loadJSONObject
__builtin__.loadPixels = __papplet__.loadPixels
__builtin__.loadShader = __papplet__.loadShader
__builtin__.loadShape = __papplet__.loadShape
__builtin__.loadTable = __papplet__.loadTable
__builtin__.loadXML = __papplet__.loadXML
__builtin__.loop = __papplet__.loop
__builtin__.millis = __papplet__.millis
__builtin__.modelX = __papplet__.modelX
__builtin__.modelY = __papplet__.modelY
__builtin__.modelZ = __papplet__.modelZ
__builtin__.noClip = __papplet__.noClip
__builtin__.noCursor = __papplet__.noCursor
__builtin__.noFill = __papplet__.noFill
__builtin__.noLights = __papplet__.noLights
__builtin__.noLoop = __papplet__.noLoop
__builtin__.noSmooth = __papplet__.noSmooth
__builtin__.noStroke = __papplet__.noStroke
__builtin__.noTint = __papplet__.noTint
__builtin__.noise = __papplet__.noise
__builtin__.noiseDetail = __papplet__.noiseDetail
__builtin__.noiseSeed = __papplet__.noiseSeed
__builtin__.normal = __papplet__.normal
__builtin__.ortho = __papplet__.ortho
__builtin__.parseXML = __papplet__.parseXML
__builtin__.perspective = __papplet__.perspective
__builtin__.pixelDensity = __papplet__.pixelDensity
__builtin__.point = __papplet__.point
__builtin__.pointLight = __papplet__.pointLight
__builtin__.popMatrix = __papplet__.popMatrix
__builtin__.popStyle = __papplet__.popStyle
__builtin__.printArray = __papplet__.printArray
__builtin__.printCamera = __papplet__.printCamera
__builtin__.printMatrix = __papplet__.printMatrix
__builtin__.printProjection = __papplet__.printProjection
__builtin__.quad = __papplet__.quad
__builtin__.quadraticVertex = __papplet__.quadraticVertex
# Processing's "random" function works as documented, but is blown
# away if the user does a python 'import random'. This seems
# reasonable to me.
__builtin__.random = __papplet__.random
__builtin__.randomGaussian = __papplet__.randomGaussian
__builtin__.randomSeed = __papplet__.randomSeed
__builtin__.rect = __papplet__.rect
__builtin__.rectMode = __papplet__.rectMode
__builtin__.redraw = __papplet__.redraw
__builtin__.requestImage = __papplet__.requestImage
__builtin__.resetMatrix = __papplet__.resetMatrix
__builtin__.resetShader = __papplet__.resetShader
__builtin__.rotate = __papplet__.rotate
__builtin__.rotateX = __papplet__.rotateX
__builtin__.rotateY = __papplet__.rotateY
__builtin__.rotateZ = __papplet__.rotateZ
__builtin__.save = __papplet__.save
__builtin__.saveBytes = __papplet__.saveBytes
__builtin__.saveFrame = __papplet__.saveFrame
__builtin__.saveJSONArray = __papplet__.saveJSONArray
__builtin__.saveJSONObject = __papplet__.saveJSONObject
__builtin__.saveStream = __papplet__.saveStream
__builtin__.saveStrings = __papplet__.saveStrings
__builtin__.saveTable = __papplet__.saveTable
__builtin__.saveXML = __papplet__.saveXML
__builtin__.scale = __papplet__.scale
__builtin__.screenX = __papplet__.screenX
__builtin__.screenY = __papplet__.screenY
__builtin__.screenZ = __papplet__.screenZ
__builtin__.selectFolder = __papplet__.selectFolder
__builtin__.selectInput = __papplet__.selectInput
__builtin__.selectOutput = __papplet__.selectOutput
__builtin__.shader = __papplet__.shader
__builtin__.shape = __papplet__.shape
__builtin__.shapeMode = __papplet__.shapeMode
__builtin__.shearX = __papplet__.shearX
__builtin__.shearY = __papplet__.shearY
__builtin__.shininess = __papplet__.shininess
__builtin__.size = __papplet__.size
__builtin__.sketchPath = __papplet__.sketchPath
__builtin__.smooth = __papplet__.smooth
__builtin__.specular = __papplet__.specular
__builtin__.sphere = __papplet__.sphere
__builtin__.sphereDetail = __papplet__.sphereDetail
__builtin__.spotLight = __papplet__.spotLight
__builtin__.stroke = __papplet__.stroke
__builtin__.strokeCap = __papplet__.strokeCap
__builtin__.strokeJoin = __papplet__.strokeJoin
__builtin__.strokeWeight = __papplet__.strokeWeight
# Because of two 5-arg text() methods, we have to do this in Java.
# __builtin__.text = __papplet__.text
__builtin__.textAlign = __papplet__.textAlign
__builtin__.textAscent = __papplet__.textAscent
__builtin__.textDescent = __papplet__.textDescent
__builtin__.textFont = __papplet__.textFont
__builtin__.textLeading = __papplet__.textLeading
__builtin__.textMode = __papplet__.textMode
__builtin__.textSize = __papplet__.textSize
__builtin__.textWidth = __papplet__.textWidth
__builtin__.texture = __papplet__.texture
__builtin__.textureMode = __papplet__.textureMode
__builtin__.textureWrap = __papplet__.textureWrap
__builtin__.tint = __papplet__.tint
__builtin__.translate = __papplet__.translate
__builtin__.triangle = __papplet__.triangle
__builtin__.updatePixels = __papplet__.updatePixels
__builtin__.vertex = __papplet__.vertex
'''
In order to get colors to behave reasonably, they have to be cast to positive
long quantities on their way into Python, and 32-bit signed quantities on
their way into Java.
'''
# We have to provide a funky get() because of int/long conversion woes.
__builtin__.get = __papplet__.get
# We handle lerpColor by hand because there's an instance method and a static method.
# __builtin__.lerpColor = __papplet__.lerpColor
# These must all be implemented in Java to support our funky color arguments.
'''
__builtin__.alpha = __papplet__.alpha
__builtin__.red = __papplet__.red
__builtin__.green = __papplet__.green
__builtin__.blue = __papplet__.blue
__builtin__.hue = __papplet__.hue
__builtin__.saturation = __papplet__.saturation
__builtin__.brightness = __papplet__.brightness
'''
# And these are PApplet static methods. Some are commented out to indicate
# that we prefer or require Jython's implementation.
#__builtin__.abs = PApplet.abs
__builtin__.acos = PApplet.acos
__builtin__.append = PApplet.append
__builtin__.arrayCopy = PApplet.arrayCopy
__builtin__.asin = PApplet.asin
__builtin__.atan = PApplet.atan
__builtin__.atan2 = PApplet.atan2
__builtin__.binary = PApplet.binary
__builtin__.blendColor = PApplet.blendColor
__builtin__.ceil = PApplet.ceil
__builtin__.concat = PApplet.concat
__builtin__.constrain = lambda x, a, b: max(min(x, b), a)
__builtin__.cos = PApplet.cos
__builtin__.createInput = PApplet.createInput
__builtin__.createOutput = PApplet.createOutput
__builtin__.createReader = PApplet.createReader
__builtin__.day = PApplet.day
__builtin__.debug = PApplet.debug
__builtin__.degrees = PApplet.degrees
__builtin__.dist = PApplet.dist
# __builtin__.exec = PApplet.exec
__builtin__.exp = PApplet.exp
__builtin__.expand = PApplet.expand
__builtin__.floor = PApplet.floor
__builtin__.hex = PApplet.hex
__builtin__.hour = PApplet.hour
__builtin__.join = PApplet.join
__builtin__.lerp = PApplet.lerp
__builtin__.loadBytes = PApplet.loadBytes
__builtin__.log = PApplet.log
__builtin__.mag = PApplet.mag
# We permit both Python and P5's map()s.
# __builtin__.map = PApplet.map
__builtin__.match = PApplet.match
__builtin__.matchAll = PApplet.matchAll
# __builtin__.max = PApplet.max
# __builtin__.min = PApplet.min
__builtin__.minute = PApplet.minute
__builtin__.month = PApplet.month
__builtin__.nf = PApplet.nf
__builtin__.nfc = PApplet.nfc
__builtin__.nfp = PApplet.nfp
__builtin__.nfs = PApplet.nfs
__builtin__.norm = PApplet.norm
__builtin__.pow = PApplet.pow
# __builtin__.print = PApplet.print
#__builtin__.println = PApplet.println
__builtin__.radians = PApplet.radians
__builtin__.reverse = PApplet.reverse
# __builtin__.round = PApplet.round
__builtin__.saveBytes = PApplet.saveBytes
__builtin__.saveStream = PApplet.saveStream
__builtin__.saveStrings = PApplet.saveStrings
__builtin__.second = PApplet.second
__builtin__.shorten = PApplet.shorten
__builtin__.sin = PApplet.sin
__builtin__.sort = PApplet.sort
__builtin__.splice = PApplet.splice
__builtin__.split = PApplet.split
__builtin__.splitTokens = PApplet.splitTokens
__builtin__.sq = PApplet.sq
__builtin__.sqrt = PApplet.sqrt
__builtin__.subset = PApplet.subset
__builtin__.tan = PApplet.tan
__builtin__.trim = PApplet.trim
__builtin__.unbinary = PApplet.unbinary
__builtin__.unhex = PApplet.unhex
__builtin__.year = PApplet.year
# Here are some names that resolve to static *and* instance methods.
# Dispatch them to the appropriate methods based on the type of their
# arguments.
def __createInput__(o):
if isinstance(o, basestring):
return __papplet__.createInput(o)
return PApplet.createInput(o)
__builtin__.createInput = __createInput__
def __createOutput__(o):
if isinstance(o, basestring):
return __papplet__.createOutput(o)
return PApplet.createOutput(o)
__builtin__.createOutput = __createOutput__
def __createReader__(o):
if isinstance(o, basestring):
return __papplet__.createReader(o)
return PApplet.createReader(o)
__builtin__.createReader = __createReader__
def __createWriter__(o):
if isinstance(o, basestring):
return __papplet__.createWriter(o)
return PApplet.createWriter(o)
__builtin__.createWriter = __createWriter__
def __loadStrings__(o):
if isinstance(o, basestring):
return __papplet__.loadStrings(o)
return PApplet.loadStrings(o)
__builtin__.loadStrings = __loadStrings__
def __loadBytes__(o):
if isinstance(o, basestring):
return __papplet__.loadBytes(o)
return PApplet.loadBytes(o)
__builtin__.loadBytes = __loadBytes__
def __loadJSONArray__(o):
if isinstance(o, basestring):
return __papplet__.loadJSONArray(o)
return PApplet.loadJSONArray(o)
__builtin__.loadJSONArray = __loadJSONArray__
def __loadJSONObject__(o):
if isinstance(o, basestring):
return __papplet__.loadJSONObject(o)
return PApplet.loadJSONObject(o)
__builtin__.loadJSONObject = __loadJSONObject__
def __saveStream__(target, source):
if isinstance(source, basestring) or isinstance(target, basestring):
return __papplet__.saveStream(target, source)
return PApplet.saveStream(target, source)
__builtin__.saveStream = __saveStream__
def __saveStrings__(where, data):
if isinstance(where, basestring):
return __papplet__.saveStrings(where, data)
return PApplet.saveStrings(where, data)
__builtin__.saveStrings = __saveStrings__
def __saveBytes__(where, data):
if isinstance(where, basestring):
return __papplet__.saveBytes(where, data)
return PApplet.saveBytes(where, data)
__builtin__.saveBytes = __saveBytes__
# Make "open" able to find files in the "data" folder, and also other folders if the sketch is in a temp directory
__realopen__ = open
def __open__(filename, *args, **kwargs):
if os.path.isfile(filename):
return __realopen__(filename, *args, **kwargs)
if not os.path.isabs(filename):
datafilename = __papplet__.dataPath(filename)
if os.path.isfile(datafilename):
return __realopen__(datafilename, *args, **kwargs)
sketchfilename = __papplet__.sketchPath(filename)
if os.path.isfile(sketchfilename):
return __realopen__(sketchfilename, *args, **kwargs)
# Fail naturally
return __realopen__(filename, *args, **kwargs)
__builtin__.open = __open__
# Due to a seeming bug in Jython, the print builtin ignores the the setting of
# interp.setOut and interp.setErr.
class FakeStdOut():
def write(self, s):
__stdout__.print(s)
def flush(self):
__stdout__.flush()
sys.stdout = FakeStdOut()
class FakeStdErr():
def write(self, s):
__stderr__.print(s)
def flush(self):
__stderr__.flush()
sys.stderr = FakeStdErr()
del FakeStdOut, FakeStdErr
def __println__(o):
print o
__builtin__.println = __println__
# Implement
#
# with pushFoo():
# doSomethingInFooContext()
# doSomethingOutOfFooContext()
#
# pushFoo()/popFoo() still works as usual.
def makePopper(pushName, popName, exposed_name=None, close_args=None):
if not close_args:
close_args = []
if not exposed_name:
exposed_name = pushName
bound_push = getattr(__papplet__, pushName)
bound_pop = getattr(__papplet__, popName)
class Popper(object):
def __init__(self, delegate):
self.delegate = delegate
def __enter__(self):
# The result of pushFoo/beginFoo is made available to
# the "as" clause of the "with" statement.
return self.delegate
def __exit__(self, exc_type, exc_val, exc_tb):
bound_pop(*close_args)
return False
# If you say
# foo = beginPGL()
# foo now is a Popper object, but the user will want
# PGL methods and properties, so we delegate those
# attribute fetches to the actual PGL object.
def __getattr__(self, attr):
return getattr(self.delegate, attr)
def shim(*args):
return Popper(bound_push(*args))
setattr(__builtin__, exposed_name, shim)
makePopper('pushStyle', 'popStyle')
makePopper('pushMatrix', 'popMatrix')
makePopper('beginContour', 'endContour')
makePopper('beginPGL', 'endPGL')
makePopper('beginShape', 'endShape')
makePopper('beginShape', 'endShape',
close_args=[CLOSE], exposed_name='beginClosedShape')
makePopper('beginCamera', 'endCamera')
import os
os.chdir(__cwd__)