sonolus.py 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl

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.

Potentially problematic release.


This version of sonolus.py might be problematic. Click here for more details.

Files changed (79) hide show
  1. sonolus/backend/finalize.py +18 -10
  2. sonolus/backend/interpret.py +7 -7
  3. sonolus/backend/ir.py +24 -0
  4. sonolus/backend/optimize/__init__.py +0 -0
  5. sonolus/backend/{allocate.py → optimize/allocate.py} +4 -3
  6. sonolus/backend/{constant_evaluation.py → optimize/constant_evaluation.py} +7 -7
  7. sonolus/backend/{coalesce.py → optimize/copy_coalesce.py} +3 -3
  8. sonolus/backend/optimize/dead_code.py +185 -0
  9. sonolus/backend/{dominance.py → optimize/dominance.py} +2 -17
  10. sonolus/backend/{flow.py → optimize/flow.py} +6 -5
  11. sonolus/backend/{inlining.py → optimize/inlining.py} +4 -17
  12. sonolus/backend/{liveness.py → optimize/liveness.py} +69 -65
  13. sonolus/backend/optimize/optimize.py +44 -0
  14. sonolus/backend/{passes.py → optimize/passes.py} +1 -1
  15. sonolus/backend/optimize/simplify.py +191 -0
  16. sonolus/backend/{ssa.py → optimize/ssa.py} +31 -18
  17. sonolus/backend/place.py +17 -25
  18. sonolus/backend/utils.py +10 -0
  19. sonolus/backend/visitor.py +360 -101
  20. sonolus/build/cli.py +14 -3
  21. sonolus/build/compile.py +8 -8
  22. sonolus/build/engine.py +10 -5
  23. sonolus/build/project.py +30 -1
  24. sonolus/script/archetype.py +429 -138
  25. sonolus/script/array.py +25 -8
  26. sonolus/script/array_like.py +297 -0
  27. sonolus/script/bucket.py +73 -11
  28. sonolus/script/containers.py +234 -51
  29. sonolus/script/debug.py +8 -8
  30. sonolus/script/easing.py +147 -105
  31. sonolus/script/effect.py +60 -0
  32. sonolus/script/engine.py +71 -4
  33. sonolus/script/globals.py +66 -32
  34. sonolus/script/instruction.py +79 -25
  35. sonolus/script/internal/builtin_impls.py +138 -27
  36. sonolus/script/internal/constant.py +139 -0
  37. sonolus/script/internal/context.py +14 -5
  38. sonolus/script/internal/dict_impl.py +65 -0
  39. sonolus/script/internal/generic.py +6 -9
  40. sonolus/script/internal/impl.py +38 -13
  41. sonolus/script/internal/introspection.py +5 -2
  42. sonolus/script/{math.py → internal/math_impls.py} +28 -28
  43. sonolus/script/internal/native.py +3 -3
  44. sonolus/script/internal/random.py +67 -0
  45. sonolus/script/internal/range.py +81 -0
  46. sonolus/script/internal/transient.py +51 -0
  47. sonolus/script/internal/tuple_impl.py +113 -0
  48. sonolus/script/interval.py +234 -16
  49. sonolus/script/iterator.py +120 -167
  50. sonolus/script/level.py +24 -0
  51. sonolus/script/num.py +79 -47
  52. sonolus/script/options.py +78 -12
  53. sonolus/script/particle.py +37 -4
  54. sonolus/script/pointer.py +4 -4
  55. sonolus/script/print.py +22 -1
  56. sonolus/script/project.py +59 -0
  57. sonolus/script/{graphics.py → quad.py} +75 -12
  58. sonolus/script/record.py +44 -13
  59. sonolus/script/runtime.py +50 -1
  60. sonolus/script/sprite.py +198 -115
  61. sonolus/script/text.py +2 -0
  62. sonolus/script/timing.py +72 -0
  63. sonolus/script/transform.py +296 -66
  64. sonolus/script/ui.py +134 -78
  65. sonolus/script/values.py +6 -13
  66. sonolus/script/vec.py +118 -3
  67. {sonolus_py-0.1.4.dist-info → sonolus_py-0.1.6.dist-info}/METADATA +1 -1
  68. sonolus_py-0.1.6.dist-info/RECORD +89 -0
  69. sonolus/backend/dead_code.py +0 -80
  70. sonolus/backend/optimize.py +0 -37
  71. sonolus/backend/simplify.py +0 -47
  72. sonolus/script/comptime.py +0 -160
  73. sonolus/script/random.py +0 -14
  74. sonolus/script/range.py +0 -58
  75. sonolus_py-0.1.4.dist-info/RECORD +0 -84
  76. /sonolus/script/{callbacks.py → internal/callbacks.py} +0 -0
  77. {sonolus_py-0.1.4.dist-info → sonolus_py-0.1.6.dist-info}/WHEEL +0 -0
  78. {sonolus_py-0.1.4.dist-info → sonolus_py-0.1.6.dist-info}/entry_points.txt +0 -0
  79. {sonolus_py-0.1.4.dist-info → sonolus_py-0.1.6.dist-info}/licenses/LICENSE +0 -0
@@ -1,13 +1,20 @@
1
- # fmt: off
1
+ from math import cos, sin
2
2
  from typing import Self
3
3
 
4
- from sonolus.script.graphics import Quad, QuadLike
5
- from sonolus.script.math import cos, sin
4
+ from sonolus.script.quad import Quad, QuadLike
6
5
  from sonolus.script.record import Record
7
6
  from sonolus.script.vec import Vec2
8
7
 
9
8
 
10
9
  class Transform2d(Record):
10
+ """A transformation matrix for 2D points.
11
+
12
+ Usage:
13
+ ```
14
+ Transform2d.new()
15
+ ```
16
+ """
17
+
11
18
  a00: float
12
19
  a01: float
13
20
  a02: float
@@ -20,19 +27,36 @@ class Transform2d(Record):
20
27
 
21
28
  @classmethod
22
29
  def new(cls) -> Self:
23
- """Create a new identity transform."""
30
+ """Create a new identity transform.
31
+
32
+ Returns:
33
+ A new identity transform.
34
+ """
24
35
  return cls(
25
- 1, 0, 0,
26
- 0, 1, 0,
27
- 0, 0, 1,
36
+ 1,
37
+ 0,
38
+ 0,
39
+ 0,
40
+ 1,
41
+ 0,
42
+ 0,
43
+ 0,
44
+ 1,
28
45
  )
29
46
 
30
- def _compose(self,
31
- b00: float, b01: float, b02: float,
32
- b10: float, b11: float, b12: float,
33
- b20: float, b21: float, b22: float,
47
+ def _compose(
48
+ self,
49
+ b00: float,
50
+ b01: float,
51
+ b02: float,
52
+ b10: float,
53
+ b11: float,
54
+ b12: float,
55
+ b20: float,
56
+ b21: float,
57
+ b22: float,
34
58
  ) -> Self:
35
- """Multiply the matrix with another matrix on the left."""
59
+ # Multiply by b on the left (b @ a)
36
60
  a00 = self.a00 * b00 + self.a10 * b01 + self.a20 * b02
37
61
  a01 = self.a01 * b00 + self.a11 * b01 + self.a21 * b02
38
62
  a02 = self.a02 * b00 + self.a12 * b01 + self.a22 * b02
@@ -43,123 +67,329 @@ class Transform2d(Record):
43
67
  a21 = self.a01 * b20 + self.a11 * b21 + self.a21 * b22
44
68
  a22 = self.a02 * b20 + self.a12 * b21 + self.a22 * b22
45
69
  return Transform2d(
46
- a00, a01, a02,
47
- a10, a11, a12,
48
- a20, a21, a22,
70
+ a00,
71
+ a01,
72
+ a02,
73
+ a10,
74
+ a11,
75
+ a12,
76
+ a20,
77
+ a21,
78
+ a22,
49
79
  )
50
80
 
51
81
  def translate(self, translation: Vec2, /) -> Self:
52
- """Translate along the x and y axes."""
82
+ """Translate along the x and y axes and return a new transform.
83
+
84
+ Args:
85
+ translation: The translation vector.
86
+
87
+ Returns:
88
+ A new transform after translation.
89
+ """
53
90
  return self._compose(
54
- 1, 0, translation.x,
55
- 0, 1, translation.y,
56
- 0, 0, 1,
91
+ 1,
92
+ 0,
93
+ translation.x,
94
+ 0,
95
+ 1,
96
+ translation.y,
97
+ 0,
98
+ 0,
99
+ 1,
57
100
  )
58
101
 
59
102
  def scale(self, factor: Vec2, /) -> Self:
60
- """Scale around the origin."""
103
+ """Scale about the origin and return a new transform.
104
+
105
+ Args:
106
+ factor: The scale factor vector.
107
+
108
+ Returns:
109
+ A new transform after scaling.
110
+ """
61
111
  return self._compose(
62
- factor.x, 0, 0,
63
- 0, factor.y, 0,
64
- 0, 0, 1,
112
+ factor.x,
113
+ 0,
114
+ 0,
115
+ 0,
116
+ factor.y,
117
+ 0,
118
+ 0,
119
+ 0,
120
+ 1,
65
121
  )
66
122
 
67
123
  def scale_about(self, factor: Vec2, /, pivot: Vec2) -> Self:
68
- """Scale around the pivot."""
124
+ """Scale about the pivot and return a new transform.
125
+
126
+ Args:
127
+ factor: The scale factor vector.
128
+ pivot: The pivot point for scaling.
129
+
130
+ Returns:
131
+ A new transform after scaling.
132
+ """
69
133
  return self.translate(-pivot).scale(factor).translate(pivot)
70
134
 
71
135
  def rotate(self, angle: float, /) -> Self:
72
- """Rotate around the origin."""
136
+ """Rotate about the origin and return a new transform.
137
+
138
+ Args:
139
+ angle: The angle of rotation in radians.
140
+
141
+ Returns:
142
+ A new transform after rotation.
143
+ """
73
144
  c = cos(angle)
74
145
  s = sin(angle)
75
146
  return self._compose(
76
- c, -s, 0,
77
- s, c, 0,
78
- 0, 0, 1,
147
+ c,
148
+ -s,
149
+ 0,
150
+ s,
151
+ c,
152
+ 0,
153
+ 0,
154
+ 0,
155
+ 1,
79
156
  )
80
157
 
81
158
  def rotate_about(self, angle: float, /, pivot: Vec2) -> Self:
82
- """Rotate around the pivot."""
159
+ """Rotate about the pivot and return a new transform.
160
+
161
+ Args:
162
+ angle: The angle of rotation in radians.
163
+ pivot: The pivot point for rotation.
164
+
165
+ Returns:
166
+ A new transform after rotation.
167
+ """
83
168
  return self.translate(-pivot).rotate(angle).translate(pivot)
84
169
 
85
170
  def shear_x(self, m: float, /) -> Self:
86
- """Shear along the x-axis."""
171
+ """Shear along the x-axis and return a new transform.
172
+
173
+ Args:
174
+ m: The shear factor along the x-axis.
175
+
176
+ Returns:
177
+ A new transform after shearing.
178
+ """
87
179
  return self._compose(
88
- 1, m, 0,
89
- 0, 1, 0,
90
- 0, 0, 1,
180
+ 1,
181
+ m,
182
+ 0,
183
+ 0,
184
+ 1,
185
+ 0,
186
+ 0,
187
+ 0,
188
+ 1,
91
189
  )
92
190
 
93
191
  def shear_y(self, m: float, /) -> Self:
94
- """Shear along the y-axis."""
192
+ """Shear along the y-axis and return a new transform.
193
+
194
+ Args:
195
+ m: The shear factor along the y-axis.
196
+
197
+ Returns:
198
+ A new transform after shearing.
199
+ """
95
200
  return self._compose(
96
- 1, 0, 0,
97
- m, 1, 0,
98
- 0, 0, 1,
201
+ 1,
202
+ 0,
203
+ 0,
204
+ m,
205
+ 1,
206
+ 0,
207
+ 0,
208
+ 0,
209
+ 1,
99
210
  )
100
211
 
101
- def perspective_vanish_y(self, y: float, /) -> Self:
102
- """Apply perspective vanish along the y-axis with vanish point at the given y coordinate.
212
+ def simple_perspective_x(self, x: float, /) -> Self:
213
+ """Apply perspective along the x-axis with vanishing point at the given x coordinate and return a new transform.
214
+
215
+ Args:
216
+ x: The x coordinate of the vanishing point.
103
217
 
104
- Note: Conveniently, the inverse can be obtained simply by negating the argument.
218
+ Returns:
219
+ A new transform after applying perspective.
105
220
  """
106
221
  return self._compose(
107
- 1, 0, 0,
108
- 0, 1, 0,
109
- 0, 1 / y, 1,
222
+ 1,
223
+ 0,
224
+ 0,
225
+ 0,
226
+ 1,
227
+ 0,
228
+ 1 / x,
229
+ 0,
230
+ 1,
110
231
  )
111
232
 
112
- def perspective(self, foreground_y, vanishing_point: Vec2, /) -> Self:
113
- """Apply a perspective transformation.
233
+ def simple_perspective_y(self, y: float, /) -> Self:
234
+ """Apply perspective along the y-axis with vanishing point at the given y coordinate and return a new transform.
114
235
 
115
- When the original y is 0, the transformed x coordinate will be unchanged and the y coordinates will
116
- be equal to foreground_y.
117
- As the original y coordinate approaches infinity in the direction of the vanishing point,
118
- the transformed x and y coordinates will approach the vanishing point.
236
+ Args:
237
+ y: The y coordinate of the vanishing point.
238
+
239
+ Returns:
240
+ A new transform after applying perspective.
241
+ """
242
+ return self._compose(
243
+ 1,
244
+ 0,
245
+ 0,
246
+ 0,
247
+ 1,
248
+ 0,
249
+ 0,
250
+ 1 / y,
251
+ 1,
252
+ )
253
+
254
+ def perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) -> Self:
255
+ """Apply a perspective transformation along the x-axis and return a new transform.
256
+
257
+ Args:
258
+ foreground_x: The foreground x-coordinate.
259
+ vanishing_point: The vanishing point vector.
260
+
261
+ Returns:
262
+ A new transform after applying perspective.
263
+ """
264
+ return (
265
+ self.simple_perspective_x(vanishing_point.x - foreground_x)
266
+ .shear_y(vanishing_point.y / (vanishing_point.x - foreground_x))
267
+ .translate(Vec2(foreground_x, 0))
268
+ )
269
+
270
+ def perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) -> Self:
271
+ """Apply a perspective transformation along the y-axis and return a new transform.
272
+
273
+ Args:
274
+ foreground_y: The foreground y-coordinate.
275
+ vanishing_point: The vanishing point vector.
276
+
277
+ Returns:
278
+ A new transform after applying perspective.
119
279
  """
120
280
  return (
121
- self
122
- .perspective_vanish_y(vanishing_point.y - foreground_y)
281
+ self.simple_perspective_y(vanishing_point.y - foreground_y)
123
282
  .shear_x(vanishing_point.x / (vanishing_point.y - foreground_y))
124
283
  .translate(Vec2(0, foreground_y))
125
284
  )
126
285
 
127
- def inverse_perspective(self, foreground_y, vanishing_point: Vec2, /) -> Self:
128
- """Apply the inverse of a perspective transformation."""
286
+ def inverse_perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) -> Self:
287
+ """Apply the inverse of a perspective transformation along the x-axis and return a new transform.
288
+
289
+ Args:
290
+ foreground_x: The foreground x-coordinate.
291
+ vanishing_point: The vanishing point vector.
292
+
293
+ Returns:
294
+ A new transform after applying the inverse perspective.
295
+ """
296
+ return (
297
+ self.translate(Vec2(-foreground_x, 0))
298
+ .shear_y(-vanishing_point.y / (vanishing_point.x - foreground_x))
299
+ .simple_perspective_x(-vanishing_point.x + foreground_x)
300
+ )
301
+
302
+ def inverse_perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) -> Self:
303
+ """Apply the inverse of a perspective transformation along the y-axis and return a new transform.
304
+
305
+ Args:
306
+ foreground_y: The foreground y-coordinate.
307
+ vanishing_point: The vanishing point vector.
308
+
309
+ Returns:
310
+ A new transform after applying the inverse perspective.
311
+ """
129
312
  return (
130
- self
131
- .translate(Vec2(0, -foreground_y))
313
+ self.translate(Vec2(0, -foreground_y))
132
314
  .shear_x(-vanishing_point.x / (vanishing_point.y - foreground_y))
133
- .perspective_vanish_y(-vanishing_point.y + foreground_y)
315
+ .simple_perspective_y(-vanishing_point.y + foreground_y)
134
316
  )
135
317
 
136
- def normalize(self):
137
- """Normalize the transform to have a 1 in the bottom right corner."""
318
+ def normalize(self) -> Self:
319
+ """Normalize the transform to have a 1 in the bottom right corner and return a new transform.
320
+
321
+ This may fail in some special cases involving perspective transformations where the bottom right corner is 0.
322
+
323
+ Returns:
324
+ A new normalized transform.
325
+ """
138
326
  return Transform2d(
139
- self.a00 / self.a22, self.a01 / self.a22, self.a02 / self.a22,
140
- self.a10 / self.a22, self.a11 / self.a22, self.a12 / self.a22,
141
- self.a20 / self.a22, self.a21 / self.a22, 1,
327
+ self.a00 / self.a22,
328
+ self.a01 / self.a22,
329
+ self.a02 / self.a22,
330
+ self.a10 / self.a22,
331
+ self.a11 / self.a22,
332
+ self.a12 / self.a22,
333
+ self.a20 / self.a22,
334
+ self.a21 / self.a22,
335
+ 1,
142
336
  )
143
337
 
144
338
  def compose(self, other: Self, /) -> Self:
145
- """Compose with another transform which is applied after this transform."""
339
+ """Compose with another transform which is applied after this transform and return a new transform.
340
+
341
+ Args:
342
+ other: The other transform to compose with.
343
+
344
+ Returns:
345
+ A new transform resulting from the composition.
346
+ """
146
347
  return self._compose(
147
- other.a00, other.a01, other.a02,
148
- other.a10, other.a11, other.a12,
149
- other.a20, other.a21, other.a22,
348
+ other.a00,
349
+ other.a01,
350
+ other.a02,
351
+ other.a10,
352
+ other.a11,
353
+ other.a12,
354
+ other.a20,
355
+ other.a21,
356
+ other.a22,
150
357
  )
151
358
 
152
359
  def compose_before(self, other: Self, /) -> Self:
153
- """Compose with another transform which is applied before this transform."""
360
+ """Compose with another transform which is applied before this transform and return a new transform.
361
+
362
+ Args:
363
+ other: The other transform to compose with.
364
+
365
+ Returns:
366
+ A new transform resulting from the composition.
367
+ """
154
368
  return other.compose(self)
155
369
 
156
370
  def transform_vec(self, v: Vec2) -> Vec2:
371
+ """Transform a Vec2 and return a new Vec2.
372
+
373
+ Args:
374
+ v: The vector to transform.
375
+
376
+ Returns:
377
+ A new transformed vector.
378
+ """
157
379
  x = self.a00 * v.x + self.a01 * v.y + self.a02
158
380
  y = self.a10 * v.x + self.a11 * v.y + self.a12
159
381
  w = self.a20 * v.x + self.a21 * v.y + self.a22
160
382
  return Vec2(x / w, y / w)
161
383
 
162
384
  def transform_quad(self, quad: QuadLike) -> Quad:
385
+ """Transform a Quad and return a new Quad.
386
+
387
+ Args:
388
+ quad: The quad to transform.
389
+
390
+ Returns:
391
+ A new transformed quad.
392
+ """
163
393
  return Quad(
164
394
  bl=self.transform_vec(quad.bl),
165
395
  br=self.transform_vec(quad.br),