sonolus.py 0.1.0__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 (75) hide show
  1. sonolus/__init__.py +0 -0
  2. sonolus/backend/__init__.py +0 -0
  3. sonolus/backend/allocate.py +51 -0
  4. sonolus/backend/blocks.py +756 -0
  5. sonolus/backend/excepthook.py +37 -0
  6. sonolus/backend/finalize.py +69 -0
  7. sonolus/backend/flow.py +92 -0
  8. sonolus/backend/interpret.py +333 -0
  9. sonolus/backend/ir.py +89 -0
  10. sonolus/backend/mode.py +24 -0
  11. sonolus/backend/node.py +40 -0
  12. sonolus/backend/ops.py +197 -0
  13. sonolus/backend/optimize.py +9 -0
  14. sonolus/backend/passes.py +6 -0
  15. sonolus/backend/place.py +90 -0
  16. sonolus/backend/simplify.py +30 -0
  17. sonolus/backend/utils.py +48 -0
  18. sonolus/backend/visitor.py +880 -0
  19. sonolus/build/__init__.py +0 -0
  20. sonolus/build/cli.py +170 -0
  21. sonolus/build/collection.py +293 -0
  22. sonolus/build/compile.py +90 -0
  23. sonolus/build/defaults.py +32 -0
  24. sonolus/build/engine.py +149 -0
  25. sonolus/build/level.py +23 -0
  26. sonolus/build/node.py +43 -0
  27. sonolus/build/project.py +94 -0
  28. sonolus/py.typed +0 -0
  29. sonolus/script/__init__.py +0 -0
  30. sonolus/script/archetype.py +651 -0
  31. sonolus/script/array.py +241 -0
  32. sonolus/script/bucket.py +192 -0
  33. sonolus/script/callbacks.py +105 -0
  34. sonolus/script/comptime.py +146 -0
  35. sonolus/script/containers.py +247 -0
  36. sonolus/script/debug.py +70 -0
  37. sonolus/script/effect.py +132 -0
  38. sonolus/script/engine.py +101 -0
  39. sonolus/script/globals.py +234 -0
  40. sonolus/script/graphics.py +141 -0
  41. sonolus/script/icon.py +73 -0
  42. sonolus/script/internal/__init__.py +5 -0
  43. sonolus/script/internal/builtin_impls.py +144 -0
  44. sonolus/script/internal/context.py +365 -0
  45. sonolus/script/internal/descriptor.py +17 -0
  46. sonolus/script/internal/error.py +15 -0
  47. sonolus/script/internal/generic.py +197 -0
  48. sonolus/script/internal/impl.py +69 -0
  49. sonolus/script/internal/introspection.py +14 -0
  50. sonolus/script/internal/native.py +38 -0
  51. sonolus/script/internal/value.py +144 -0
  52. sonolus/script/interval.py +98 -0
  53. sonolus/script/iterator.py +211 -0
  54. sonolus/script/level.py +52 -0
  55. sonolus/script/math.py +92 -0
  56. sonolus/script/num.py +382 -0
  57. sonolus/script/options.py +194 -0
  58. sonolus/script/particle.py +158 -0
  59. sonolus/script/pointer.py +30 -0
  60. sonolus/script/project.py +17 -0
  61. sonolus/script/range.py +58 -0
  62. sonolus/script/record.py +293 -0
  63. sonolus/script/runtime.py +526 -0
  64. sonolus/script/sprite.py +332 -0
  65. sonolus/script/text.py +404 -0
  66. sonolus/script/timing.py +42 -0
  67. sonolus/script/transform.py +118 -0
  68. sonolus/script/ui.py +160 -0
  69. sonolus/script/values.py +43 -0
  70. sonolus/script/vec.py +48 -0
  71. sonolus_py-0.1.0.dist-info/METADATA +10 -0
  72. sonolus_py-0.1.0.dist-info/RECORD +75 -0
  73. sonolus_py-0.1.0.dist-info/WHEEL +4 -0
  74. sonolus_py-0.1.0.dist-info/entry_points.txt +2 -0
  75. sonolus_py-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,526 @@
1
+ from enum import IntEnum
2
+
3
+ from sonolus.backend.mode import Mode
4
+ from sonolus.script.array import Array
5
+ from sonolus.script.containers import VarArray
6
+ from sonolus.script.globals import (
7
+ _level_life,
8
+ _level_score,
9
+ _play_runtime_environment,
10
+ _play_runtime_update,
11
+ _preview_runtime_environment,
12
+ _runtime_background,
13
+ _runtime_particle_transform,
14
+ _runtime_skin_transform,
15
+ _runtime_touch_array,
16
+ _runtime_ui,
17
+ _runtime_ui_configuration,
18
+ _tutorial_runtime_environment,
19
+ _tutorial_runtime_update,
20
+ _watch_runtime_environment,
21
+ _watch_runtime_update,
22
+ )
23
+ from sonolus.script.graphics import Quad, Rect
24
+ from sonolus.script.internal.context import ctx
25
+ from sonolus.script.internal.impl import meta_fn
26
+ from sonolus.script.num import Num
27
+ from sonolus.script.record import Record
28
+ from sonolus.script.transform import Transform2d
29
+ from sonolus.script.vec import Vec2
30
+
31
+
32
+ @_play_runtime_environment
33
+ class _PlayRuntimeEnvironment:
34
+ is_debug: bool
35
+ aspect_ratio: float
36
+ audio_offset: float
37
+ input_offset: float
38
+ is_multiplayer: bool
39
+
40
+
41
+ @_watch_runtime_environment
42
+ class _WatchRuntimeEnvironment:
43
+ is_debug: bool
44
+ aspect_ratio: float
45
+ audio_offset: float
46
+ input_offset: float
47
+ is_replay: bool
48
+
49
+
50
+ @_preview_runtime_environment
51
+ class _PreviewRuntimeEnvironment:
52
+ is_debug: bool
53
+ aspect_ratio: float
54
+
55
+
56
+ @_tutorial_runtime_environment
57
+ class _TutorialRuntimeEnvironment:
58
+ is_debug: bool
59
+ aspect_ratio: float
60
+ audio_offset: float
61
+
62
+
63
+ @_play_runtime_update
64
+ class _PlayRuntimeUpdate:
65
+ time: float
66
+ delta_time: float
67
+ scaled_time: float
68
+ touch_count: int
69
+
70
+
71
+ @_watch_runtime_update
72
+ class _WatchRuntimeUpdate:
73
+ time: float
74
+ delta_time: float
75
+ scaled_time: float
76
+ is_skip: bool
77
+
78
+
79
+ @_tutorial_runtime_update
80
+ class _TutorialRuntimeUpdate:
81
+ time: float
82
+ delta_time: float
83
+ navigation_direction: int
84
+
85
+
86
+ class RuntimeUiConfig(Record):
87
+ scale: float
88
+ alpha: float
89
+
90
+
91
+ @_runtime_ui_configuration
92
+ class _RuntimeUiConfigs:
93
+ menu: RuntimeUiConfig
94
+ judgment: RuntimeUiConfig
95
+ combo: RuntimeUiConfig
96
+ primary_metric: RuntimeUiConfig
97
+ secondary_metric: RuntimeUiConfig
98
+ progress: RuntimeUiConfig
99
+
100
+
101
+ class HorizontalAlign(IntEnum):
102
+ LEFT = -1
103
+ CENTER = 0
104
+ RIGHT = 1
105
+
106
+
107
+ class RuntimeUiLayout(Record):
108
+ anchor: Vec2
109
+ pivot: Vec2
110
+ dimensions: Vec2
111
+ rotation: float
112
+ alpha: float
113
+ horizontal_align: HorizontalAlign
114
+ background: bool
115
+
116
+ def update(
117
+ self,
118
+ anchor: Vec2 | None = None,
119
+ pivot: Vec2 | None = None,
120
+ dimensions: Vec2 | None = None,
121
+ rotation: float | None = None,
122
+ alpha: float | None = None,
123
+ horizontal_align: HorizontalAlign | None = None,
124
+ background: bool | None = None,
125
+ ):
126
+ if anchor is not None:
127
+ self.anchor = anchor
128
+ if pivot is not None:
129
+ self.pivot = pivot
130
+ if dimensions is not None:
131
+ self.dimensions = dimensions
132
+ if rotation is not None:
133
+ self.rotation = rotation
134
+ if alpha is not None:
135
+ self.alpha = alpha
136
+ if horizontal_align is not None:
137
+ self.horizontal_align = horizontal_align
138
+ if background is not None:
139
+ self.background = background
140
+
141
+
142
+ @_runtime_ui
143
+ class _RuntimeUi:
144
+ menu: RuntimeUiLayout
145
+ judgment: RuntimeUiLayout
146
+ combo_value: RuntimeUiLayout
147
+ combo_text: RuntimeUiLayout
148
+ primary_metric_bar: RuntimeUiLayout
149
+ primary_metric_value: RuntimeUiLayout
150
+ secondary_metric_bar: RuntimeUiLayout
151
+ secondary_metric_value: RuntimeUiLayout
152
+ progress: RuntimeUiLayout
153
+
154
+
155
+ class Touch(Record):
156
+ id: int
157
+ started: bool
158
+ ended: bool
159
+ time: float
160
+ start_time: float
161
+ position: Vec2
162
+ start_position: Vec2
163
+ delta: Vec2
164
+ velocity: Vec2
165
+ speed: float
166
+ angle: float
167
+
168
+ @property
169
+ def total_time(self) -> float:
170
+ return self.time - self.start_time
171
+
172
+ @property
173
+ def total_delta(self) -> Vec2:
174
+ return self.position - self.start_position
175
+
176
+ @property
177
+ def total_velocity(self) -> Vec2:
178
+ return self.total_delta / self.total_time if self.total_time > 0 else Vec2(0, 0)
179
+
180
+ @property
181
+ def total_speed(self) -> float:
182
+ return self.total_velocity.magnitude
183
+
184
+ @property
185
+ def total_angle(self) -> float:
186
+ return self.total_delta.angle
187
+
188
+
189
+ @_runtime_touch_array
190
+ class _TouchArray:
191
+ touches: Array[Touch, 999]
192
+
193
+
194
+ @_runtime_skin_transform
195
+ class _SkinTransform:
196
+ value: Array[Array[float, 4], 4]
197
+
198
+ @property
199
+ @meta_fn
200
+ def transform(self) -> Transform2d:
201
+ values = self.value._to_list_()
202
+ return Transform2d._raw(
203
+ a00=Num(values[0 * 4 + 0]),
204
+ a01=Num(values[0 * 4 + 1]),
205
+ a02=Num(values[0 * 4 + 3]),
206
+ a10=Num(values[1 * 4 + 0]),
207
+ a11=Num(values[1 * 4 + 1]),
208
+ a12=Num(values[1 * 4 + 3]),
209
+ a20=Num(values[3 * 4 + 0]),
210
+ a21=Num(values[3 * 4 + 1]),
211
+ )
212
+
213
+
214
+ @_runtime_particle_transform
215
+ class _ParticleTransform:
216
+ value: Array[Array[float, 4], 4]
217
+
218
+ @property
219
+ @meta_fn
220
+ def transform(self) -> Transform2d:
221
+ values = self.value._to_list_()
222
+ return Transform2d._raw(
223
+ a00=Num(values[0 * 4 + 0]),
224
+ a01=Num(values[0 * 4 + 1]),
225
+ a02=Num(values[0 * 4 + 3]),
226
+ a10=Num(values[1 * 4 + 0]),
227
+ a11=Num(values[1 * 4 + 1]),
228
+ a12=Num(values[1 * 4 + 3]),
229
+ a20=Num(values[3 * 4 + 0]),
230
+ a21=Num(values[3 * 4 + 1]),
231
+ )
232
+
233
+
234
+ @_runtime_background
235
+ class _Background:
236
+ value: Quad
237
+
238
+
239
+ @_level_score
240
+ class _LevelScore:
241
+ perfect_multiplier: float
242
+ great_multiplier: float
243
+ good_multiplier: float
244
+ consecutive_perfect_multiplier: float
245
+ consecutive_perfect_step: float
246
+ consecutive_perfect_cap: float
247
+ consecutive_great_multiplier: float
248
+ consecutive_great_step: float
249
+ consecutive_great_cap: float
250
+ consecutive_good_multiplier: float
251
+ consecutive_good_step: float
252
+ consecutive_good_cap: float
253
+
254
+ def update(
255
+ self,
256
+ perfect_multiplier: float | None = None,
257
+ great_multiplier: float | None = None,
258
+ good_multiplier: float | None = None,
259
+ consecutive_perfect_multiplier: float | None = None,
260
+ consecutive_perfect_step: float | None = None,
261
+ consecutive_perfect_cap: float | None = None,
262
+ consecutive_great_multiplier: float | None = None,
263
+ consecutive_great_step: float | None = None,
264
+ consecutive_great_cap: float | None = None,
265
+ consecutive_good_multiplier: float | None = None,
266
+ consecutive_good_step: float | None = None,
267
+ consecutive_good_cap: float | None = None,
268
+ ):
269
+ if perfect_multiplier is not None:
270
+ self.perfect_multiplier = perfect_multiplier
271
+ if great_multiplier is not None:
272
+ self.great_multiplier = great_multiplier
273
+ if good_multiplier is not None:
274
+ self.good_multiplier = good_multiplier
275
+ if consecutive_perfect_multiplier is not None:
276
+ self.consecutive_perfect_multiplier = consecutive_perfect_multiplier
277
+ if consecutive_perfect_step is not None:
278
+ self.consecutive_perfect_step = consecutive_perfect_step
279
+ if consecutive_perfect_cap is not None:
280
+ self.consecutive_perfect_cap = consecutive_perfect_cap
281
+ if consecutive_great_multiplier is not None:
282
+ self.consecutive_great_multiplier = consecutive_great_multiplier
283
+ if consecutive_great_step is not None:
284
+ self.consecutive_great_step = consecutive_great_step
285
+ if consecutive_great_cap is not None:
286
+ self.consecutive_great_cap = consecutive_great_cap
287
+ if consecutive_good_multiplier is not None:
288
+ self.consecutive_good_multiplier = consecutive_good_multiplier
289
+ if consecutive_good_step is not None:
290
+ self.consecutive_good_step = consecutive_good_step
291
+ if consecutive_good_cap is not None:
292
+ self.consecutive_good_cap = consecutive_good_cap
293
+
294
+
295
+ @_level_life
296
+ class _LevelLife:
297
+ consecutive_perfect_increment: float
298
+ consecutive_perfect_step: float
299
+ consecutive_great_increment: float
300
+ consecutive_great_step: float
301
+ consecutive_good_increment: float
302
+ consecutive_good_step: float
303
+
304
+ def update(
305
+ self,
306
+ consecutive_perfect_increment: float | None = None,
307
+ consecutive_perfect_step: float | None = None,
308
+ consecutive_great_increment: float | None = None,
309
+ consecutive_great_step: float | None = None,
310
+ consecutive_good_increment: float | None = None,
311
+ consecutive_good_step: float | None = None,
312
+ ):
313
+ if consecutive_perfect_increment is not None:
314
+ self.consecutive_perfect_increment = consecutive_perfect_increment
315
+ if consecutive_perfect_step is not None:
316
+ self.consecutive_perfect_step = consecutive_perfect_step
317
+ if consecutive_great_increment is not None:
318
+ self.consecutive_great_increment = consecutive_great_increment
319
+ if consecutive_great_step is not None:
320
+ self.consecutive_great_step = consecutive_great_step
321
+ if consecutive_good_increment is not None:
322
+ self.consecutive_good_increment = consecutive_good_increment
323
+ if consecutive_good_step is not None:
324
+ self.consecutive_good_step = consecutive_good_step
325
+
326
+
327
+ @meta_fn
328
+ def is_debug() -> bool:
329
+ if not ctx():
330
+ return False
331
+ match ctx().global_state.mode:
332
+ case Mode.Play:
333
+ return _PlayRuntimeEnvironment.is_debug
334
+ case Mode.Watch:
335
+ return _WatchRuntimeEnvironment.is_debug
336
+ case Mode.Preview:
337
+ return _PreviewRuntimeEnvironment.is_debug
338
+ case Mode.Tutorial:
339
+ return _TutorialRuntimeEnvironment.is_debug
340
+ case _:
341
+ return False
342
+
343
+
344
+ @meta_fn
345
+ def aspect_ratio() -> float:
346
+ if not ctx():
347
+ return 16 / 9
348
+ match ctx().global_state.mode:
349
+ case Mode.Play:
350
+ return _PlayRuntimeEnvironment.aspect_ratio
351
+ case Mode.Watch:
352
+ return _WatchRuntimeEnvironment.aspect_ratio
353
+ case Mode.Preview:
354
+ return _PreviewRuntimeEnvironment.aspect_ratio
355
+ case Mode.Tutorial:
356
+ return _TutorialRuntimeEnvironment.aspect_ratio
357
+
358
+
359
+ @meta_fn
360
+ def audio_offset() -> float:
361
+ if not ctx():
362
+ return 0
363
+ match ctx().global_state.mode:
364
+ case Mode.Play:
365
+ return _PlayRuntimeEnvironment.audio_offset
366
+ case Mode.Watch:
367
+ return _WatchRuntimeEnvironment.audio_offset
368
+ case Mode.Tutorial:
369
+ return _TutorialRuntimeEnvironment.audio_offset
370
+ case _:
371
+ return 0
372
+
373
+
374
+ @meta_fn
375
+ def input_offset() -> float:
376
+ if not ctx():
377
+ return 0
378
+ match ctx().global_state.mode:
379
+ case Mode.Play:
380
+ return _PlayRuntimeEnvironment.input_offset
381
+ case Mode.Watch:
382
+ return _WatchRuntimeEnvironment.input_offset
383
+ case _:
384
+ return 0
385
+
386
+
387
+ @meta_fn
388
+ def is_multiplayer() -> bool:
389
+ if not ctx():
390
+ return False
391
+ match ctx().global_state.mode:
392
+ case Mode.Play:
393
+ return _PlayRuntimeEnvironment.is_multiplayer
394
+ case _:
395
+ return False
396
+
397
+
398
+ @meta_fn
399
+ def is_replay() -> bool:
400
+ if not ctx():
401
+ return False
402
+ match ctx().global_state.mode:
403
+ case Mode.Watch:
404
+ return _WatchRuntimeEnvironment.is_replay
405
+ case _:
406
+ return False
407
+
408
+
409
+ @meta_fn
410
+ def time() -> float:
411
+ if not ctx():
412
+ return 0
413
+ match ctx().global_state.mode:
414
+ case Mode.Play:
415
+ return _PlayRuntimeUpdate.time
416
+ case Mode.Watch:
417
+ return _WatchRuntimeUpdate.time
418
+ case Mode.Tutorial:
419
+ return _TutorialRuntimeUpdate.time
420
+ case _:
421
+ return 0
422
+
423
+
424
+ @meta_fn
425
+ def delta_time() -> float:
426
+ if not ctx():
427
+ return 0
428
+ match ctx().global_state.mode:
429
+ case Mode.Play:
430
+ return _PlayRuntimeUpdate.delta_time
431
+ case Mode.Watch:
432
+ return _WatchRuntimeUpdate.delta_time
433
+ case Mode.Tutorial:
434
+ return _TutorialRuntimeUpdate.delta_time
435
+ case _:
436
+ return 0
437
+
438
+
439
+ @meta_fn
440
+ def scaled_time() -> float:
441
+ if not ctx():
442
+ return 0
443
+ match ctx().global_state.mode:
444
+ case Mode.Play:
445
+ return _PlayRuntimeUpdate.scaled_time
446
+ case Mode.Watch:
447
+ return _WatchRuntimeUpdate.scaled_time
448
+ case Mode.Tutorial:
449
+ return _TutorialRuntimeUpdate.time
450
+ case _:
451
+ return 0
452
+
453
+
454
+ @meta_fn
455
+ def touches() -> VarArray[Touch, 999]:
456
+ if not ctx():
457
+ return VarArray(0, Array[Touch, 0]())
458
+ match ctx().global_state.mode:
459
+ case Mode.Play:
460
+ return VarArray(_PlayRuntimeUpdate.touch_count, _TouchArray.touches)
461
+ case _:
462
+ return VarArray(0, Array[Touch, 0]())
463
+
464
+
465
+ @meta_fn
466
+ def is_skip() -> bool:
467
+ if not ctx():
468
+ return False
469
+ match ctx().global_state.mode:
470
+ case Mode.Watch:
471
+ return _WatchRuntimeUpdate.is_skip
472
+ case _:
473
+ return False
474
+
475
+
476
+ @meta_fn
477
+ def navigation_direction() -> int:
478
+ if not ctx():
479
+ return 0
480
+ match ctx().global_state.mode:
481
+ case Mode.Tutorial:
482
+ return _TutorialRuntimeUpdate.navigation_direction
483
+ case _:
484
+ return 0
485
+
486
+
487
+ def skin_transform() -> Transform2d:
488
+ return _SkinTransform.transform
489
+
490
+
491
+ @meta_fn
492
+ def set_skin_transform(value: Transform2d):
493
+ _SkinTransform.transform._copy_from_(value)
494
+
495
+
496
+ def particle_transform() -> Transform2d:
497
+ return _ParticleTransform.transform
498
+
499
+
500
+ @meta_fn
501
+ def set_particle_transform(value: Transform2d):
502
+ _ParticleTransform.transform._copy_from_(value)
503
+
504
+
505
+ def background() -> Quad:
506
+ return _Background.value
507
+
508
+
509
+ def set_background(value: Quad):
510
+ _Background.value = value
511
+
512
+
513
+ runtime_ui = _RuntimeUi
514
+ runtime_ui_configs = _RuntimeUiConfigs
515
+
516
+
517
+ def screen() -> Rect:
518
+ return Rect(t=1, r=aspect_ratio(), b=-1, l=-aspect_ratio())
519
+
520
+
521
+ def level_score() -> _LevelScore:
522
+ return _LevelScore
523
+
524
+
525
+ def level_life() -> _LevelLife:
526
+ return _LevelLife