sonolus.py 0.1.3__py3-none-any.whl → 0.1.4__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 (68) hide show
  1. sonolus/backend/allocate.py +125 -51
  2. sonolus/backend/blocks.py +756 -756
  3. sonolus/backend/coalesce.py +85 -0
  4. sonolus/backend/constant_evaluation.py +374 -0
  5. sonolus/backend/dead_code.py +80 -0
  6. sonolus/backend/dominance.py +111 -0
  7. sonolus/backend/excepthook.py +37 -37
  8. sonolus/backend/finalize.py +69 -69
  9. sonolus/backend/flow.py +121 -92
  10. sonolus/backend/inlining.py +150 -0
  11. sonolus/backend/ir.py +5 -3
  12. sonolus/backend/liveness.py +173 -0
  13. sonolus/backend/mode.py +24 -24
  14. sonolus/backend/node.py +40 -40
  15. sonolus/backend/ops.py +197 -197
  16. sonolus/backend/optimize.py +37 -9
  17. sonolus/backend/passes.py +52 -6
  18. sonolus/backend/simplify.py +47 -30
  19. sonolus/backend/ssa.py +187 -0
  20. sonolus/backend/utils.py +48 -48
  21. sonolus/backend/visitor.py +892 -882
  22. sonolus/build/cli.py +7 -1
  23. sonolus/build/compile.py +88 -90
  24. sonolus/build/level.py +24 -23
  25. sonolus/build/node.py +43 -43
  26. sonolus/script/archetype.py +23 -6
  27. sonolus/script/array.py +2 -2
  28. sonolus/script/bucket.py +191 -191
  29. sonolus/script/callbacks.py +127 -127
  30. sonolus/script/comptime.py +1 -1
  31. sonolus/script/containers.py +23 -0
  32. sonolus/script/debug.py +19 -3
  33. sonolus/script/easing.py +323 -0
  34. sonolus/script/effect.py +131 -131
  35. sonolus/script/globals.py +269 -269
  36. sonolus/script/graphics.py +200 -150
  37. sonolus/script/instruction.py +151 -151
  38. sonolus/script/internal/__init__.py +5 -5
  39. sonolus/script/internal/builtin_impls.py +144 -144
  40. sonolus/script/internal/context.py +12 -4
  41. sonolus/script/internal/descriptor.py +17 -17
  42. sonolus/script/internal/introspection.py +14 -14
  43. sonolus/script/internal/native.py +40 -38
  44. sonolus/script/internal/value.py +3 -3
  45. sonolus/script/interval.py +120 -112
  46. sonolus/script/iterator.py +214 -214
  47. sonolus/script/math.py +30 -1
  48. sonolus/script/num.py +1 -1
  49. sonolus/script/options.py +191 -191
  50. sonolus/script/particle.py +157 -157
  51. sonolus/script/pointer.py +30 -30
  52. sonolus/script/print.py +81 -81
  53. sonolus/script/random.py +14 -0
  54. sonolus/script/range.py +58 -58
  55. sonolus/script/record.py +3 -3
  56. sonolus/script/runtime.py +2 -0
  57. sonolus/script/sprite.py +333 -333
  58. sonolus/script/text.py +407 -407
  59. sonolus/script/timing.py +42 -42
  60. sonolus/script/transform.py +77 -23
  61. sonolus/script/ui.py +160 -160
  62. sonolus/script/vec.py +81 -78
  63. {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.4.dist-info}/METADATA +1 -1
  64. sonolus_py-0.1.4.dist-info/RECORD +84 -0
  65. {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.4.dist-info}/WHEEL +1 -1
  66. {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.4.dist-info}/licenses/LICENSE +21 -21
  67. sonolus_py-0.1.3.dist-info/RECORD +0 -75
  68. {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.4.dist-info}/entry_points.txt +0 -0
@@ -1,157 +1,157 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from typing import Annotated, Any, NewType, dataclass_transform, get_origin
5
-
6
- from sonolus.backend.ops import Op
7
- from sonolus.script.graphics import QuadLike, flatten_quad
8
- from sonolus.script.internal.introspection import get_field_specifiers
9
- from sonolus.script.internal.native import native_function
10
- from sonolus.script.record import Record
11
-
12
-
13
- class Particle(Record):
14
- id: int
15
-
16
- def is_available(self) -> bool:
17
- return _has_particle_effect(self.id)
18
-
19
- def spawn(self, quad: QuadLike, duration: float, loop: bool = False) -> ParticleHandle:
20
- return ParticleHandle(_spawn_particle_effect(self.id, *flatten_quad(quad), duration, loop))
21
-
22
-
23
- class ParticleHandle(Record):
24
- id: int
25
-
26
- def move(self, quad: QuadLike) -> None:
27
- _move_particle_effect(self.id, *flatten_quad(quad))
28
-
29
- def destroy(self) -> None:
30
- _destroy_particle_effect(self.id)
31
-
32
-
33
- @native_function(Op.HasParticleEffect)
34
- def _has_particle_effect(particle_id: int) -> bool:
35
- raise NotImplementedError
36
-
37
-
38
- @native_function(Op.SpawnParticleEffect)
39
- def _spawn_particle_effect(
40
- particle_id: int,
41
- x1: float,
42
- y1: float,
43
- x2: float,
44
- y2: float,
45
- x3: float,
46
- y3: float,
47
- x4: float,
48
- y4: float,
49
- duration: float,
50
- loop: bool,
51
- ) -> int:
52
- raise NotImplementedError
53
-
54
-
55
- @native_function(Op.MoveParticleEffect)
56
- def _move_particle_effect(
57
- handle: int, x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, x4: float, y4: float
58
- ) -> None:
59
- raise NotImplementedError
60
-
61
-
62
- @native_function(Op.DestroyParticleEffect)
63
- def _destroy_particle_effect(handle: int) -> None:
64
- raise NotImplementedError
65
-
66
-
67
- @dataclass
68
- class ParticleInfo:
69
- name: str
70
-
71
-
72
- def particle(name: str) -> Any:
73
- return ParticleInfo(name)
74
-
75
-
76
- type Particles = NewType("Particles", Any)
77
-
78
-
79
- @dataclass_transform()
80
- def particles[T](cls: type[T]) -> T | Particles:
81
- if len(cls.__bases__) != 1:
82
- raise ValueError("Particles class must not inherit from any class (except object)")
83
- instance = cls()
84
- names = []
85
- for i, (name, annotation) in enumerate(get_field_specifiers(cls).items()):
86
- if get_origin(annotation) is not Annotated:
87
- raise TypeError(f"Invalid annotation for particles: {annotation}")
88
- annotation_type = annotation.__args__[0]
89
- annotation_values = annotation.__metadata__
90
- if annotation_type is not Particle:
91
- raise TypeError(f"Invalid annotation for particles: {annotation}, expected annotation of type Particle")
92
- if len(annotation_values) != 1 or not isinstance(annotation_values[0], ParticleInfo):
93
- raise TypeError(
94
- f"Invalid annotation for particles: {annotation}, expected a single string annotation value"
95
- )
96
- particle_name = annotation_values[0].name
97
- names.append(particle_name)
98
- setattr(instance, name, Particle(i))
99
- instance._particles_ = names
100
- instance._is_comptime_value_ = True
101
- return instance
102
-
103
-
104
- class StandardParticle:
105
- NOTE_CIRCULAR_TAP_NEUTRAL = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_NEUTRAL")]
106
- NOTE_CIRCULAR_TAP_RED = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_RED")]
107
- NOTE_CIRCULAR_TAP_GREEN = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_GREEN")]
108
- NOTE_CIRCULAR_TAP_BLUE = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_BLUE")]
109
- NOTE_CIRCULAR_TAP_YELLOW = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_YELLOW")]
110
- NOTE_CIRCULAR_TAP_PURPLE = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_PURPLE")]
111
- NOTE_CIRCULAR_TAP_CYAN = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_CYAN")]
112
- NOTE_CIRCULAR_ALTERNATIVE_NEUTRAL = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_NEUTRAL")]
113
- NOTE_CIRCULAR_ALTERNATIVE_RED = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_RED")]
114
- NOTE_CIRCULAR_ALTERNATIVE_GREEN = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_GREEN")]
115
- NOTE_CIRCULAR_ALTERNATIVE_BLUE = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_BLUE")]
116
- NOTE_CIRCULAR_ALTERNATIVE_YELLOW = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_YELLOW")]
117
- NOTE_CIRCULAR_ALTERNATIVE_PURPLE = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_PURPLE")]
118
- NOTE_CIRCULAR_ALTERNATIVE_CYAN = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_CYAN")]
119
- NOTE_CIRCULAR_HOLD_NEUTRAL = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_NEUTRAL")]
120
- NOTE_CIRCULAR_HOLD_RED = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_RED")]
121
- NOTE_CIRCULAR_HOLD_GREEN = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_GREEN")]
122
- NOTE_CIRCULAR_HOLD_BLUE = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_BLUE")]
123
- NOTE_CIRCULAR_HOLD_YELLOW = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_YELLOW")]
124
- NOTE_CIRCULAR_HOLD_PURPLE = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_PURPLE")]
125
- NOTE_CIRCULAR_HOLD_CYAN = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_CYAN")]
126
- NOTE_LINEAR_TAP_NEUTRAL = Annotated[Particle, particle("#NOTE_LINEAR_TAP_NEUTRAL")]
127
- NOTE_LINEAR_TAP_RED = Annotated[Particle, particle("#NOTE_LINEAR_TAP_RED")]
128
- NOTE_LINEAR_TAP_GREEN = Annotated[Particle, particle("#NOTE_LINEAR_TAP_GREEN")]
129
- NOTE_LINEAR_TAP_BLUE = Annotated[Particle, particle("#NOTE_LINEAR_TAP_BLUE")]
130
- NOTE_LINEAR_TAP_YELLOW = Annotated[Particle, particle("#NOTE_LINEAR_TAP_YELLOW")]
131
- NOTE_LINEAR_TAP_PURPLE = Annotated[Particle, particle("#NOTE_LINEAR_TAP_PURPLE")]
132
- NOTE_LINEAR_TAP_CYAN = Annotated[Particle, particle("#NOTE_LINEAR_TAP_CYAN")]
133
- NOTE_LINEAR_ALTERNATIVE_NEUTRAL = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_NEUTRAL")]
134
- NOTE_LINEAR_ALTERNATIVE_RED = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_RED")]
135
- NOTE_LINEAR_ALTERNATIVE_GREEN = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_GREEN")]
136
- NOTE_LINEAR_ALTERNATIVE_BLUE = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_BLUE")]
137
- NOTE_LINEAR_ALTERNATIVE_YELLOW = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_YELLOW")]
138
- NOTE_LINEAR_ALTERNATIVE_PURPLE = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_PURPLE")]
139
- NOTE_LINEAR_ALTERNATIVE_CYAN = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_CYAN")]
140
- NOTE_LINEAR_HOLD_NEUTRAL = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_NEUTRAL")]
141
- NOTE_LINEAR_HOLD_RED = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_RED")]
142
- NOTE_LINEAR_HOLD_GREEN = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_GREEN")]
143
- NOTE_LINEAR_HOLD_BLUE = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_BLUE")]
144
- NOTE_LINEAR_HOLD_YELLOW = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_YELLOW")]
145
- NOTE_LINEAR_HOLD_PURPLE = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_PURPLE")]
146
- NOTE_LINEAR_HOLD_CYAN = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_CYAN")]
147
- LANE_CIRCULAR = Annotated[Particle, particle("#LANE_CIRCULAR")]
148
- LANE_LINEAR = Annotated[Particle, particle("#LANE_LINEAR")]
149
- SLOT_CIRCULAR = Annotated[Particle, particle("#SLOT_CIRCULAR")]
150
- SLOT_LINEAR = Annotated[Particle, particle("#SLOT_LINEAR")]
151
- JUDGE_LINE_CIRCULAR = Annotated[Particle, particle("#JUDGE_LINE_CIRCULAR")]
152
- JUDGE_LINE_LINEAR = Annotated[Particle, particle("#JUDGE_LINE_LINEAR")]
153
-
154
-
155
- @particles
156
- class EmptyParticles:
157
- pass
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Annotated, Any, NewType, dataclass_transform, get_origin
5
+
6
+ from sonolus.backend.ops import Op
7
+ from sonolus.script.graphics import QuadLike, flatten_quad
8
+ from sonolus.script.internal.introspection import get_field_specifiers
9
+ from sonolus.script.internal.native import native_function
10
+ from sonolus.script.record import Record
11
+
12
+
13
+ class Particle(Record):
14
+ id: int
15
+
16
+ def is_available(self) -> bool:
17
+ return _has_particle_effect(self.id)
18
+
19
+ def spawn(self, quad: QuadLike, duration: float, loop: bool = False) -> ParticleHandle:
20
+ return ParticleHandle(_spawn_particle_effect(self.id, *flatten_quad(quad), duration, loop))
21
+
22
+
23
+ class ParticleHandle(Record):
24
+ id: int
25
+
26
+ def move(self, quad: QuadLike) -> None:
27
+ _move_particle_effect(self.id, *flatten_quad(quad))
28
+
29
+ def destroy(self) -> None:
30
+ _destroy_particle_effect(self.id)
31
+
32
+
33
+ @native_function(Op.HasParticleEffect)
34
+ def _has_particle_effect(particle_id: int) -> bool:
35
+ raise NotImplementedError
36
+
37
+
38
+ @native_function(Op.SpawnParticleEffect)
39
+ def _spawn_particle_effect(
40
+ particle_id: int,
41
+ x1: float,
42
+ y1: float,
43
+ x2: float,
44
+ y2: float,
45
+ x3: float,
46
+ y3: float,
47
+ x4: float,
48
+ y4: float,
49
+ duration: float,
50
+ loop: bool,
51
+ ) -> int:
52
+ raise NotImplementedError
53
+
54
+
55
+ @native_function(Op.MoveParticleEffect)
56
+ def _move_particle_effect(
57
+ handle: int, x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, x4: float, y4: float
58
+ ) -> None:
59
+ raise NotImplementedError
60
+
61
+
62
+ @native_function(Op.DestroyParticleEffect)
63
+ def _destroy_particle_effect(handle: int) -> None:
64
+ raise NotImplementedError
65
+
66
+
67
+ @dataclass
68
+ class ParticleInfo:
69
+ name: str
70
+
71
+
72
+ def particle(name: str) -> Any:
73
+ return ParticleInfo(name)
74
+
75
+
76
+ type Particles = NewType("Particles", Any)
77
+
78
+
79
+ @dataclass_transform()
80
+ def particles[T](cls: type[T]) -> T | Particles:
81
+ if len(cls.__bases__) != 1:
82
+ raise ValueError("Particles class must not inherit from any class (except object)")
83
+ instance = cls()
84
+ names = []
85
+ for i, (name, annotation) in enumerate(get_field_specifiers(cls).items()):
86
+ if get_origin(annotation) is not Annotated:
87
+ raise TypeError(f"Invalid annotation for particles: {annotation}")
88
+ annotation_type = annotation.__args__[0]
89
+ annotation_values = annotation.__metadata__
90
+ if annotation_type is not Particle:
91
+ raise TypeError(f"Invalid annotation for particles: {annotation}, expected annotation of type Particle")
92
+ if len(annotation_values) != 1 or not isinstance(annotation_values[0], ParticleInfo):
93
+ raise TypeError(
94
+ f"Invalid annotation for particles: {annotation}, expected a single string annotation value"
95
+ )
96
+ particle_name = annotation_values[0].name
97
+ names.append(particle_name)
98
+ setattr(instance, name, Particle(i))
99
+ instance._particles_ = names
100
+ instance._is_comptime_value_ = True
101
+ return instance
102
+
103
+
104
+ class StandardParticle:
105
+ NOTE_CIRCULAR_TAP_NEUTRAL = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_NEUTRAL")]
106
+ NOTE_CIRCULAR_TAP_RED = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_RED")]
107
+ NOTE_CIRCULAR_TAP_GREEN = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_GREEN")]
108
+ NOTE_CIRCULAR_TAP_BLUE = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_BLUE")]
109
+ NOTE_CIRCULAR_TAP_YELLOW = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_YELLOW")]
110
+ NOTE_CIRCULAR_TAP_PURPLE = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_PURPLE")]
111
+ NOTE_CIRCULAR_TAP_CYAN = Annotated[Particle, particle("#NOTE_CIRCULAR_TAP_CYAN")]
112
+ NOTE_CIRCULAR_ALTERNATIVE_NEUTRAL = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_NEUTRAL")]
113
+ NOTE_CIRCULAR_ALTERNATIVE_RED = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_RED")]
114
+ NOTE_CIRCULAR_ALTERNATIVE_GREEN = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_GREEN")]
115
+ NOTE_CIRCULAR_ALTERNATIVE_BLUE = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_BLUE")]
116
+ NOTE_CIRCULAR_ALTERNATIVE_YELLOW = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_YELLOW")]
117
+ NOTE_CIRCULAR_ALTERNATIVE_PURPLE = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_PURPLE")]
118
+ NOTE_CIRCULAR_ALTERNATIVE_CYAN = Annotated[Particle, particle("#NOTE_CIRCULAR_ALTERNATIVE_CYAN")]
119
+ NOTE_CIRCULAR_HOLD_NEUTRAL = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_NEUTRAL")]
120
+ NOTE_CIRCULAR_HOLD_RED = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_RED")]
121
+ NOTE_CIRCULAR_HOLD_GREEN = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_GREEN")]
122
+ NOTE_CIRCULAR_HOLD_BLUE = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_BLUE")]
123
+ NOTE_CIRCULAR_HOLD_YELLOW = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_YELLOW")]
124
+ NOTE_CIRCULAR_HOLD_PURPLE = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_PURPLE")]
125
+ NOTE_CIRCULAR_HOLD_CYAN = Annotated[Particle, particle("#NOTE_CIRCULAR_HOLD_CYAN")]
126
+ NOTE_LINEAR_TAP_NEUTRAL = Annotated[Particle, particle("#NOTE_LINEAR_TAP_NEUTRAL")]
127
+ NOTE_LINEAR_TAP_RED = Annotated[Particle, particle("#NOTE_LINEAR_TAP_RED")]
128
+ NOTE_LINEAR_TAP_GREEN = Annotated[Particle, particle("#NOTE_LINEAR_TAP_GREEN")]
129
+ NOTE_LINEAR_TAP_BLUE = Annotated[Particle, particle("#NOTE_LINEAR_TAP_BLUE")]
130
+ NOTE_LINEAR_TAP_YELLOW = Annotated[Particle, particle("#NOTE_LINEAR_TAP_YELLOW")]
131
+ NOTE_LINEAR_TAP_PURPLE = Annotated[Particle, particle("#NOTE_LINEAR_TAP_PURPLE")]
132
+ NOTE_LINEAR_TAP_CYAN = Annotated[Particle, particle("#NOTE_LINEAR_TAP_CYAN")]
133
+ NOTE_LINEAR_ALTERNATIVE_NEUTRAL = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_NEUTRAL")]
134
+ NOTE_LINEAR_ALTERNATIVE_RED = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_RED")]
135
+ NOTE_LINEAR_ALTERNATIVE_GREEN = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_GREEN")]
136
+ NOTE_LINEAR_ALTERNATIVE_BLUE = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_BLUE")]
137
+ NOTE_LINEAR_ALTERNATIVE_YELLOW = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_YELLOW")]
138
+ NOTE_LINEAR_ALTERNATIVE_PURPLE = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_PURPLE")]
139
+ NOTE_LINEAR_ALTERNATIVE_CYAN = Annotated[Particle, particle("#NOTE_LINEAR_ALTERNATIVE_CYAN")]
140
+ NOTE_LINEAR_HOLD_NEUTRAL = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_NEUTRAL")]
141
+ NOTE_LINEAR_HOLD_RED = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_RED")]
142
+ NOTE_LINEAR_HOLD_GREEN = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_GREEN")]
143
+ NOTE_LINEAR_HOLD_BLUE = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_BLUE")]
144
+ NOTE_LINEAR_HOLD_YELLOW = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_YELLOW")]
145
+ NOTE_LINEAR_HOLD_PURPLE = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_PURPLE")]
146
+ NOTE_LINEAR_HOLD_CYAN = Annotated[Particle, particle("#NOTE_LINEAR_HOLD_CYAN")]
147
+ LANE_CIRCULAR = Annotated[Particle, particle("#LANE_CIRCULAR")]
148
+ LANE_LINEAR = Annotated[Particle, particle("#LANE_LINEAR")]
149
+ SLOT_CIRCULAR = Annotated[Particle, particle("#SLOT_CIRCULAR")]
150
+ SLOT_LINEAR = Annotated[Particle, particle("#SLOT_LINEAR")]
151
+ JUDGE_LINE_CIRCULAR = Annotated[Particle, particle("#JUDGE_LINE_CIRCULAR")]
152
+ JUDGE_LINE_LINEAR = Annotated[Particle, particle("#JUDGE_LINE_LINEAR")]
153
+
154
+
155
+ @particles
156
+ class EmptyParticles:
157
+ pass
sonolus/script/pointer.py CHANGED
@@ -1,30 +1,30 @@
1
- from sonolus.backend.place import BlockPlace
2
- from sonolus.script.internal.impl import meta_fn, validate_value
3
- from sonolus.script.internal.value import Value
4
- from sonolus.script.num import Num, is_num
5
-
6
-
7
- @meta_fn
8
- def deref[T: Value](block: Num, offset: Num, type_: type[T]) -> T:
9
- block = Num._accept_(block)
10
- offset = Num._accept_(offset)
11
- type_ = validate_value(type_)._as_py_()
12
- if block._is_py_():
13
- block = block._as_py_()
14
- if not isinstance(block, int):
15
- raise TypeError("block must be an integer")
16
- else:
17
- if not is_num(block):
18
- raise TypeError("block must be a Num")
19
- block = block.index()
20
- if offset._is_py_():
21
- offset = offset._as_py_()
22
- if not isinstance(offset, int):
23
- raise TypeError("offset must be an integer")
24
- else:
25
- if not is_num(offset):
26
- raise TypeError("offset must be a Num")
27
- offset = offset.index()
28
- if not (isinstance(type_, type) and issubclass(type_, Value)):
29
- raise TypeError("type_ must be a Value")
30
- return type_._from_place_(BlockPlace(block, offset))
1
+ from sonolus.backend.place import BlockPlace
2
+ from sonolus.script.internal.impl import meta_fn, validate_value
3
+ from sonolus.script.internal.value import Value
4
+ from sonolus.script.num import Num, is_num
5
+
6
+
7
+ @meta_fn
8
+ def deref[T: Value](block: Num, offset: Num, type_: type[T]) -> T:
9
+ block = Num._accept_(block)
10
+ offset = Num._accept_(offset)
11
+ type_ = validate_value(type_)._as_py_()
12
+ if block._is_py_():
13
+ block = block._as_py_()
14
+ if not isinstance(block, int):
15
+ raise TypeError("block must be an integer")
16
+ else:
17
+ if not is_num(block):
18
+ raise TypeError("block must be a Num")
19
+ block = block.index()
20
+ if offset._is_py_():
21
+ offset = offset._as_py_()
22
+ if not isinstance(offset, int):
23
+ raise TypeError("offset must be an integer")
24
+ else:
25
+ if not is_num(offset):
26
+ raise TypeError("offset must be a Num")
27
+ offset = offset.index()
28
+ if not (isinstance(type_, type) and issubclass(type_, Value)):
29
+ raise TypeError("type_ must be a Value")
30
+ return type_._from_place_(BlockPlace(block, offset))
sonolus/script/print.py CHANGED
@@ -1,81 +1,81 @@
1
- from enum import IntEnum
2
-
3
- from sonolus.backend.ops import Op
4
- from sonolus.script.internal.native import native_function
5
- from sonolus.script.runtime import HorizontalAlign
6
- from sonolus.script.vec import Vec2
7
-
8
-
9
- class PrintFormat(IntEnum):
10
- NUMBER = 0
11
- PERCENTAGE = 1
12
- TIME = 10
13
- SCORE = 11
14
- BPM = 20
15
- TIMESCALE = 21
16
- BEAT_COUNT = 30
17
- MEASURE_COUNT = 31
18
- ENTITY_COUNT = 32
19
-
20
-
21
- class PrintColor(IntEnum):
22
- THEME = -1
23
- NEUTRAL = 0
24
- RED = 1
25
- GREEN = 2
26
- BLUE = 3
27
- YELLOW = 4
28
- PURPLE = 5
29
- CYAN = 6
30
-
31
-
32
- @native_function(Op.Print)
33
- def _print(
34
- value: int | float,
35
- format: PrintFormat, # noqa: A002
36
- decimal_places: int,
37
- anchor_x: float,
38
- anchor_y: float,
39
- pivot_x: float,
40
- pivot_y: float,
41
- width: float,
42
- height: float,
43
- rotation: float,
44
- color: PrintColor,
45
- alpha: float,
46
- horizontal_align: HorizontalAlign,
47
- background: bool,
48
- ):
49
- raise NotImplementedError
50
-
51
-
52
- def print_number(
53
- value: int | float,
54
- *,
55
- fmt: PrintFormat,
56
- decimal_places: int = 0,
57
- anchor: Vec2,
58
- pivot: Vec2,
59
- dimensions: Vec2,
60
- rotation: float = 0,
61
- color: PrintColor = PrintColor.THEME,
62
- alpha: float = 1,
63
- horizontal_align: HorizontalAlign = HorizontalAlign.LEFT,
64
- background: bool = False,
65
- ):
66
- _print(
67
- value,
68
- fmt,
69
- decimal_places,
70
- anchor.x,
71
- anchor.y,
72
- pivot.x,
73
- pivot.y,
74
- dimensions.x,
75
- dimensions.y,
76
- rotation,
77
- color,
78
- alpha,
79
- horizontal_align,
80
- background,
81
- )
1
+ from enum import IntEnum
2
+
3
+ from sonolus.backend.ops import Op
4
+ from sonolus.script.internal.native import native_function
5
+ from sonolus.script.runtime import HorizontalAlign
6
+ from sonolus.script.vec import Vec2
7
+
8
+
9
+ class PrintFormat(IntEnum):
10
+ NUMBER = 0
11
+ PERCENTAGE = 1
12
+ TIME = 10
13
+ SCORE = 11
14
+ BPM = 20
15
+ TIMESCALE = 21
16
+ BEAT_COUNT = 30
17
+ MEASURE_COUNT = 31
18
+ ENTITY_COUNT = 32
19
+
20
+
21
+ class PrintColor(IntEnum):
22
+ THEME = -1
23
+ NEUTRAL = 0
24
+ RED = 1
25
+ GREEN = 2
26
+ BLUE = 3
27
+ YELLOW = 4
28
+ PURPLE = 5
29
+ CYAN = 6
30
+
31
+
32
+ @native_function(Op.Print)
33
+ def _print(
34
+ value: int | float,
35
+ format: PrintFormat, # noqa: A002
36
+ decimal_places: int,
37
+ anchor_x: float,
38
+ anchor_y: float,
39
+ pivot_x: float,
40
+ pivot_y: float,
41
+ width: float,
42
+ height: float,
43
+ rotation: float,
44
+ color: PrintColor,
45
+ alpha: float,
46
+ horizontal_align: HorizontalAlign,
47
+ background: bool,
48
+ ):
49
+ raise NotImplementedError
50
+
51
+
52
+ def print_number(
53
+ value: int | float,
54
+ *,
55
+ fmt: PrintFormat,
56
+ decimal_places: int = 0,
57
+ anchor: Vec2,
58
+ pivot: Vec2,
59
+ dimensions: Vec2,
60
+ rotation: float = 0,
61
+ color: PrintColor = PrintColor.THEME,
62
+ alpha: float = 1,
63
+ horizontal_align: HorizontalAlign = HorizontalAlign.LEFT,
64
+ background: bool = False,
65
+ ):
66
+ _print(
67
+ value,
68
+ fmt,
69
+ decimal_places,
70
+ anchor.x,
71
+ anchor.y,
72
+ pivot.x,
73
+ pivot.y,
74
+ dimensions.x,
75
+ dimensions.y,
76
+ rotation,
77
+ color,
78
+ alpha,
79
+ horizontal_align,
80
+ background,
81
+ )
@@ -0,0 +1,14 @@
1
+ import random as _random
2
+
3
+ from sonolus.backend.ops import Op
4
+ from sonolus.script.internal.native import native_function
5
+
6
+
7
+ @native_function(Op.Random)
8
+ def random_float(lo: float = 0.0, hi: float = 1.0, /) -> float:
9
+ return lo + (hi - lo) * _random.random()
10
+
11
+
12
+ @native_function(Op.RandomInteger)
13
+ def random_integer(lo: int, hi: int, /) -> int:
14
+ return _random.randint(lo, hi)