2
# -*- coding: utf-8 -*-
4
# pySFML - Python bindings for SFML
5
# Copyright 2012-2013, Jonathan De Wachter <dewachter.jonathan@gmail.com>
7
# This software is released under the LGPLv3 license.
8
# You should have received a copy of the GNU Lesser General Public License
9
# along with this program. If not, see <http://www.gnu.org/licenses/>.
12
from __future__ import division
13
from numbers import Number, Integral
14
from copy import deepcopy
19
from libcpp.string cimport string
20
from libcpp.vector cimport vector
22
cimport libcpp.sfml as sf
23
from libcpp.sfml cimport Int8, Int16, Int32, Int64
24
from libcpp.sfml cimport Uint8, Uint16, Uint32, Uint64
26
#cdef extern from "<string>" namespace "std":
27
#cdef cppclass string:
30
cdef extern from "error.hpp":
31
void restorePythonErrorBuffer()
32
object getLastErrorMessage()
34
__all__ = ['Time', 'sleep', 'Clock', 'seconds', 'milliseconds', 'microseconds',
35
'Vector2', 'Vector3', 'Thread', 'Lock', 'Mutex']
37
# expose a function to restore the error handler
38
cdef api void restoreErrorHandler():
39
restorePythonErrorBuffer()
41
# expose a function to retrieve the last SFML error
42
cdef api object popLastErrorMessage():
43
error = getLastErrorMessage()
45
# remove the extra \n character (if any)
51
# redirect SFML errors to our stream buffer
54
cdef public class Vector2[type PyVector2Type, object PyVector2Object]:
58
def __init__(self, x=0, y=0):
63
return "sf.Vector2({0})".format(self)
66
return "{0}x, {1}y".format(self.x, self.y)
68
def __richcmp__(Vector2 x, y, op):
71
except TypeError: return False
73
if op == 2: return x1 == x2 and y1 == y2
74
elif op == 3: return not (x1 == x2 and y1 == y2)
75
else: raise NotImplementedError
78
return iter((self.x, self.y))
80
def __getitem__(self, key):
81
return (self.x, self.y)[key]
83
def __setitem__(self, key, value):
84
setattr(self, {0: 'x', 1: 'y'}[key], value)
86
def __add__(self, other):
87
if isinstance(other, Number):
88
return Vector2(self[0] + other, self[1] + other)
90
return Vector2(self[0] + other[0], self[1] + other[1])
92
def __sub__(self, other):
93
if isinstance(other, Number):
94
return Vector2(self[0] - other, self[1] - other)
96
return Vector2(self[0] - other[0], self[1] - other[1])
98
def __mul__(self, other):
99
if isinstance(other, Number):
100
return Vector2(self[0] * other, self[1] * other)
102
return Vector2(self[0] * other[0], self[1] * other[1])
104
def __truediv__(self, other):
105
if isinstance(other, Number):
106
return Vector2(self[0] / other, self[1] / other)
108
return Vector2(self[0] / other[0], self[1] / other[1])
110
def __floordiv__(self, other):
111
if isinstance(other, Number):
112
return Vector2(self[0] // other, self[1] // other)
114
return Vector2(self[0] // other[0], self[1] // other[1])
116
def __div__(self, other):
117
if isinstance(other, Integral):
118
return self.__floordiv__(other)
119
elif isinstance(other, Number) and not isinstance(other, Integral):
120
return self.__truediv__(other)
121
elif all(isinstance(i, Integral) for i in other):
122
return self.__floordiv__(other)
124
return self.__truediv__(other)
126
def __mod__(self, other):
127
if isinstance(other, Number):
128
return Vector2(self[0] % other, self[1] % other)
130
return Vector2(self[0] % other[0], self[1] % other[1])
132
def __divmod__(self, other):
133
return self // other, self % other
135
def __iadd__(self, other):
136
if isinstance(other, Number):
144
def __isub__(self, other):
145
if isinstance(other, Number):
153
def __imul__(self, other):
154
if isinstance(other, Number):
162
def __itruediv__(self, other):
163
if isinstance(other, Number):
171
def __ifloordiv__(self, other):
172
if isinstance(other, Number):
180
def __idiv__(self, other):
181
if isinstance(other, Integral):
182
return self.__ifloordiv__(other)
183
elif isinstance(other, Number) and not isinstance(other, Integral):
184
return self.__itruediv__(other)
185
elif all(isinstance(i, Integral) for i in other):
186
return self.__ifloordiv__(other)
188
return self.__itruediv__(other)
190
def __imod__(self, other):
191
if isinstance(other, Number):
200
cdef Vector2 p = Vector2.__new__(Vector2)
202
p.x, p.y = -p.x, -p.y
206
cdef Vector2 p = Vector2.__new__(Vector2)
208
p.x, p.y = +p.x, +p.y
212
cdef Vector2 p = Vector2.__new__(Vector2)
216
def __deepcopy__(self):
217
cdef Vector2 p = Vector2.__new__(Vector2)
218
p.x, p.y = deepcopy(self.x), deepcopy(self.y)
222
cdef public class Vector3[type PyVector3Type, object PyVector3Object]:
227
def __init__(self, x=0, y=0, z=0):
233
return "sf.Vector3({0})".format(self)
236
return "{0}x, {1}y, {2}z".format(self.x, self.y, self.z)
238
def __richcmp__(Vector3 x, y, op):
241
except Exception: return False
243
if op == 2: return x1 == x2 and y1 == y2 and z1 == z2
244
elif op == 3: return not (x1 == x2 and y1 == y2 and z1 == z2)
245
else: raise NotImplementedError
248
return iter((self.x, self.y, self.z))
250
def __getitem__(self, key):
251
return (self.x, self.y, self.z)[key]
253
def __setitem__(self, key, value):
254
setattr(self, {0: 'x', 1: 'y', 2: 'z'}[key], value)
256
def __add__(self, other):
257
if isinstance(other, Number):
258
return Vector3(self[0] + other,
259
self[1] + other, self[2] + other)
261
return Vector3(self[0] + other[0],
262
self[1] + other[1], self[2] + other[2])
264
def __sub__(self, other):
265
if isinstance(other, Number):
266
return Vector3(self[0] - other,
267
self[1] - other, self[2] - other)
269
return Vector3(self[0] - other[0],
270
self[1] - other[1], self[2] - other[2])
272
def __mul__(self, other):
273
if isinstance(other, Number):
274
return Vector3(self[0] * other,
275
self[1] * other, self[2] * other)
277
return Vector3(self[0] * other[0],
278
self[1] * other[1], self[2] * other[2])
280
def __truediv__(self, other):
281
if isinstance(other, Number):
282
return Vector3(self[0] / other,
283
self[1] / other, self[2] / other)
285
return Vector3(self[0] / other[0],
286
self[1] / other[1], self[2] / other[2])
288
def __floordiv__(self, other):
289
if isinstance(other, Number):
290
return Vector3(self[0] // other,
291
self[1] // other, self[2] // other)
293
return Vector3(self[0] // other[0],
294
self[1] // other[1], self[2] // other[2])
296
def __div__(self, other):
297
if isinstance(other, Integral):
298
return self.__floordiv__(other)
299
elif isinstance(other, Number) and not isinstance(other, Integral):
300
return self.__truediv__(other)
301
elif all(isinstance(i, Integral) for i in other):
302
return self.__floordiv__(other)
304
return self.__truediv__(other)
306
def __mod__(self, other):
307
if isinstance(other, Number):
308
return Vector3(self[0] % other,
309
self[1] % other, self[2] % other)
311
return Vector3(self[0] % other[0],
312
self[1] % other[1], self[2] % other[2])
314
def __divmod__(self, other):
315
return self // other, self % other
317
def __iadd__(self, other):
318
if isinstance(other, Number):
328
def __isub__(self, other):
329
if isinstance(other, Number):
339
def __imul__(self, other):
340
if isinstance(other, Number):
350
def __itruediv__(self, other):
351
if isinstance(other, Number):
361
def __ifloordiv__(self, other):
362
if isinstance(other, Number):
372
def __div__(self, other):
373
if isinstance(other, Integral):
374
return self.__ifloordiv__(other)
375
elif isinstance(other, Number) and not isinstance(other, Integral):
376
return self.__itruediv__(other)
377
elif all(isinstance(i, Integral) for i in other):
378
return self.__ifloordiv__(other)
380
return self.__itruediv__(other)
382
def __imod__(self, other):
383
if isinstance(other, Number):
394
cdef Vector3 p = Vector3.__new__(Vector3)
396
p.x, p.y, p.z = -p.x, -p.y, -p.z
400
cdef Vector3 p = Vector3.__new__(Vector3)
402
p.x, p.y, p.z = +p.x, +p.y, +p.z
406
cdef Vector3 p = Vector3.__new__(Vector3)
410
def __deepcopy__(self):
411
cdef Vector3 p = Vector3.__new__(Vector3)
412
p.x, p.y, p.z = deepcopy(self.x), deepcopy(self.y), deepcopy(self.z)
416
cdef api object wrap_vector2f(sf.Vector2f* p):
417
cdef Vector2 r = Vector2.__new__(Vector2)
423
cdef public class Time[type PyTimeType, object PyTimeObject]:
424
ZERO = wrap_time(<sf.Time*>&sf.time.Zero)
429
self.p_this = new sf.Time()
431
def __dealloc__(self):
435
return "sf.Time({0}s, {1}ms, {2}µs)".format(self.seconds, self.milliseconds, self.microseconds)
438
return "{0} milliseconds".format(self.milliseconds)
440
def __richcmp__(Time x, Time y, int op):
441
if op == 0: return x.p_this[0] < y.p_this[0]
442
elif op == 2: return x.p_this[0] == y.p_this[0]
443
elif op == 4: return x.p_this[0] > y.p_this[0]
444
elif op == 1: return x.p_this[0] <= y.p_this[0]
445
elif op == 3: return x.p_this[0] != y.p_this[0]
446
elif op == 5: return x.p_this[0] >= y.p_this[0]
448
def __add__(Time x, Time y):
449
cdef sf.Time* p = new sf.Time()
450
p[0] = x.p_this[0] + y.p_this[0]
453
def __sub__(Time x, Time y):
454
cdef sf.Time* p = new sf.Time()
455
p[0] = x.p_this[0] - y.p_this[0]
458
def __iadd__(self, Time x):
459
self.p_this[0] = self.p_this[0] + x.p_this[0]
462
def __isub__(self, Time x):
463
self.p_this[0] = self.p_this[0] - x.p_this[0]
468
return self.p_this.asSeconds()
470
def __set__(self, float seconds):
471
self.p_this[0] = sf.seconds(seconds)
473
property milliseconds:
475
return self.p_this.asMilliseconds()
477
def __set__(self, Int32 milliseconds):
478
self.p_this[0] = sf.milliseconds(milliseconds)
480
property microseconds:
482
return self.p_this.asMicroseconds()
484
def __set__(self, Int64 microseconds):
485
self.p_this[0] = sf.microseconds(microseconds)
488
cdef sf.Time* p = new sf.Time()
489
p[0] = self.p_this[0]
492
def __deepcopy__(self):
493
cdef sf.Time* p = new sf.Time()
494
p[0] = self.p_this[0]
498
cdef api object wrap_time(sf.Time* p):
499
cdef Time r = Time.__new__(Time)
503
def sleep(Time duration):
504
with nogil: sf.sleep(duration.p_this[0])
507
cdef sf.Clock *p_this
510
self.p_this = new sf.Clock()
512
def __dealloc__(self):
516
return "sf.Clock({0})".format(self.elapsed_time)
519
return "{0}".format(self.elapsed_time)
521
property elapsed_time:
523
cdef sf.Time* p = new sf.Time()
524
p[0] = self.p_this.getElapsedTime()
528
cdef sf.Time* p = new sf.Time()
529
p[0] = self.p_this.restart()
532
def seconds(float amount):
533
cdef sf.Time* p = new sf.Time()
534
p[0] = sf.seconds(amount)
537
def milliseconds(Int32 amount):
538
cdef sf.Time* p = new sf.Time()
539
p[0] = sf.milliseconds(amount)
542
def microseconds(Int64 amount):
543
cdef sf.Time* p = new sf.Time()
544
p[0] = sf.microseconds(amount)
552
self._lock = threading.RLock()
563
def __init__(self, Mutex mutex):
567
def __dealloc__(self):
574
def __init__(self, functor, *args, **kwargs):
575
self._thread = threading.Thread(target=functor, args=args, kwargs=kwargs)
585
self._thread._Thread__stop()
586
except AttributeError: