sonolus.py 0.1.2__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 (72) 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 -880
  22. sonolus/build/cli.py +7 -1
  23. sonolus/build/compile.py +88 -90
  24. sonolus/build/engine.py +55 -5
  25. sonolus/build/level.py +24 -23
  26. sonolus/build/node.py +43 -43
  27. sonolus/script/archetype.py +23 -6
  28. sonolus/script/array.py +2 -2
  29. sonolus/script/bucket.py +191 -191
  30. sonolus/script/callbacks.py +127 -115
  31. sonolus/script/comptime.py +1 -1
  32. sonolus/script/containers.py +23 -0
  33. sonolus/script/debug.py +19 -3
  34. sonolus/script/easing.py +323 -0
  35. sonolus/script/effect.py +131 -131
  36. sonolus/script/engine.py +37 -1
  37. sonolus/script/globals.py +269 -269
  38. sonolus/script/graphics.py +200 -150
  39. sonolus/script/instruction.py +151 -0
  40. sonolus/script/internal/__init__.py +5 -5
  41. sonolus/script/internal/builtin_impls.py +144 -144
  42. sonolus/script/internal/context.py +12 -4
  43. sonolus/script/internal/descriptor.py +17 -17
  44. sonolus/script/internal/introspection.py +14 -14
  45. sonolus/script/internal/native.py +40 -38
  46. sonolus/script/internal/value.py +3 -3
  47. sonolus/script/interval.py +120 -112
  48. sonolus/script/iterator.py +214 -211
  49. sonolus/script/math.py +30 -1
  50. sonolus/script/num.py +1 -1
  51. sonolus/script/options.py +191 -191
  52. sonolus/script/particle.py +157 -157
  53. sonolus/script/pointer.py +30 -30
  54. sonolus/script/{preview.py → print.py} +81 -81
  55. sonolus/script/random.py +14 -0
  56. sonolus/script/range.py +58 -58
  57. sonolus/script/record.py +3 -3
  58. sonolus/script/runtime.py +45 -6
  59. sonolus/script/sprite.py +333 -333
  60. sonolus/script/text.py +407 -407
  61. sonolus/script/timing.py +42 -42
  62. sonolus/script/transform.py +77 -23
  63. sonolus/script/ui.py +160 -160
  64. sonolus/script/vec.py +81 -72
  65. {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/METADATA +1 -2
  66. sonolus_py-0.1.4.dist-info/RECORD +84 -0
  67. {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/WHEEL +1 -1
  68. {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/licenses/LICENSE +21 -21
  69. sonolus/build/defaults.py +0 -32
  70. sonolus/script/icon.py +0 -73
  71. sonolus_py-0.1.2.dist-info/RECORD +0 -76
  72. {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/entry_points.txt +0 -0
@@ -1,150 +1,200 @@
1
- from __future__ import annotations
2
-
3
- from typing import Protocol, Self
4
-
5
- from sonolus.script.record import Record
6
- from sonolus.script.vec import Vec2
7
-
8
-
9
- class Quad(Record):
10
- bl: Vec2
11
- tl: Vec2
12
- tr: Vec2
13
- br: Vec2
14
-
15
-
16
- class Rect(Record):
17
- t: float
18
- r: float
19
- b: float
20
- l: float # noqa: E741
21
-
22
- @classmethod
23
- def from_center(cls, center: Vec2, dimensions: Vec2) -> Rect:
24
- return cls(
25
- t=center.y + dimensions.y / 2,
26
- r=center.x + dimensions.x / 2,
27
- b=center.y - dimensions.y / 2,
28
- l=center.x - dimensions.x / 2,
29
- )
30
-
31
- @property
32
- def x(self) -> float:
33
- return self.l
34
-
35
- @x.setter
36
- def x(self, value: float):
37
- self.r += value - self.l
38
- self.l = value
39
-
40
- @property
41
- def y(self) -> float:
42
- return self.t
43
-
44
- @y.setter
45
- def y(self, value: float):
46
- self.b += value - self.t
47
- self.t = value
48
-
49
- @property
50
- def w(self) -> float:
51
- return self.r - self.l
52
-
53
- @w.setter
54
- def w(self, value: float):
55
- self.r = self.l + value
56
-
57
- @property
58
- def h(self) -> float:
59
- return self.t - self.b
60
-
61
- @h.setter
62
- def h(self, value: float):
63
- self.t = self.b + value
64
-
65
- @property
66
- def bl(self) -> Vec2:
67
- return Vec2(self.l, self.b)
68
-
69
- @property
70
- def tl(self) -> Vec2:
71
- return Vec2(self.l, self.t)
72
-
73
- @property
74
- def tr(self) -> Vec2:
75
- return Vec2(self.r, self.t)
76
-
77
- @property
78
- def br(self) -> Vec2:
79
- return Vec2(self.r, self.b)
80
-
81
- @property
82
- def center(self) -> Vec2:
83
- return Vec2((self.l + self.r) / 2, (self.t + self.b) / 2)
84
-
85
- def as_quad(self) -> Quad:
86
- return Quad(
87
- bl=self.bl,
88
- tl=self.tl,
89
- tr=self.tr,
90
- br=self.br,
91
- )
92
-
93
- def scale(self, factor: Vec2, /) -> Self:
94
- return Rect(
95
- t=self.t * factor.y,
96
- r=self.r * factor.x,
97
- b=self.b * factor.y,
98
- l=self.l * factor.x,
99
- )
100
-
101
- def expand(self, expansion: Vec2, /) -> Self:
102
- return Rect(
103
- t=self.t + expansion.y,
104
- r=self.r + expansion.x,
105
- b=self.b - expansion.y,
106
- l=self.l - expansion.x,
107
- )
108
-
109
- def shrink(self, shrinkage: Vec2, /) -> Self:
110
- return Rect(
111
- t=self.t - shrinkage.y,
112
- r=self.r - shrinkage.x,
113
- b=self.b + shrinkage.y,
114
- l=self.l + shrinkage.x,
115
- )
116
-
117
- def translate(self, translation: Vec2, /) -> Self:
118
- return Rect(
119
- t=self.t + translation.y,
120
- r=self.r + translation.x,
121
- b=self.b + translation.y,
122
- l=self.l + translation.x,
123
- )
124
-
125
-
126
- class QuadLike(Protocol):
127
- @property
128
- def bl(self) -> Vec2: ...
129
-
130
- @property
131
- def tl(self) -> Vec2: ...
132
-
133
- @property
134
- def tr(self) -> Vec2: ...
135
-
136
- @property
137
- def br(self) -> Vec2: ...
138
-
139
-
140
- def flatten_quad(quad: QuadLike) -> tuple[float, float, float, float, float, float, float, float]:
141
- return (
142
- quad.bl.x,
143
- quad.bl.y,
144
- quad.tl.x,
145
- quad.tl.y,
146
- quad.tr.x,
147
- quad.tr.y,
148
- quad.br.x,
149
- quad.br.y,
150
- )
1
+ from __future__ import annotations
2
+
3
+ from typing import Protocol, Self
4
+
5
+ from sonolus.script.record import Record
6
+ from sonolus.script.vec import Vec2
7
+
8
+
9
+ class Quad(Record):
10
+ bl: Vec2
11
+ tl: Vec2
12
+ tr: Vec2
13
+ br: Vec2
14
+
15
+ @property
16
+ def center(self) -> Vec2:
17
+ return (self.bl + self.tr + self.tl + self.br) / 4
18
+
19
+ def translate(self, translation: Vec2, /) -> Self:
20
+ return Quad(
21
+ bl=self.bl + translation,
22
+ tl=self.tl + translation,
23
+ tr=self.tr + translation,
24
+ br=self.br + translation,
25
+ )
26
+
27
+ def scale(self, factor: Vec2, /) -> Self:
28
+ return Quad(
29
+ bl=self.bl * factor,
30
+ tl=self.tl * factor,
31
+ tr=self.tr * factor,
32
+ br=self.br * factor,
33
+ )
34
+
35
+ def scale_about(self, factor: Vec2, /, pivot: Vec2) -> Self:
36
+ return Quad(
37
+ bl=(self.bl - pivot) * factor + pivot,
38
+ tl=(self.tl - pivot) * factor + pivot,
39
+ tr=(self.tr - pivot) * factor + pivot,
40
+ br=(self.br - pivot) * factor + pivot,
41
+ )
42
+
43
+ def scale_centered(self, factor: Vec2, /) -> Self:
44
+ return Quad(
45
+ bl=self.bl * factor,
46
+ tl=self.tl * factor,
47
+ tr=self.tr * factor,
48
+ br=self.br * factor,
49
+ ).translate(self.center * (Vec2(1, 1) - factor))
50
+
51
+ def rotate(self, angle: float, /) -> Self:
52
+ return Quad(
53
+ bl=self.bl.rotate(angle),
54
+ tl=self.tl.rotate(angle),
55
+ tr=self.tr.rotate(angle),
56
+ br=self.br.rotate(angle),
57
+ )
58
+
59
+ def rotate_about(
60
+ self,
61
+ angle: float,
62
+ /,
63
+ pivot: Vec2,
64
+ ) -> Self:
65
+ return Quad(
66
+ bl=self.bl.rotate_about(angle, pivot),
67
+ tl=self.tl.rotate_about(angle, pivot),
68
+ tr=self.tr.rotate_about(angle, pivot),
69
+ br=self.br.rotate_about(angle, pivot),
70
+ )
71
+
72
+ def rotate_centered(self, angle: float, /) -> Self:
73
+ return self.rotate_about(angle, self.center)
74
+
75
+
76
+ class Rect(Record):
77
+ t: float
78
+ r: float
79
+ b: float
80
+ l: float # noqa: E741
81
+
82
+ @classmethod
83
+ def from_center(cls, center: Vec2, dimensions: Vec2) -> Rect:
84
+ return cls(
85
+ t=center.y + dimensions.y / 2,
86
+ r=center.x + dimensions.x / 2,
87
+ b=center.y - dimensions.y / 2,
88
+ l=center.x - dimensions.x / 2,
89
+ )
90
+
91
+ @property
92
+ def w(self) -> float:
93
+ return self.r - self.l
94
+
95
+ @property
96
+ def h(self) -> float:
97
+ return self.t - self.b
98
+
99
+ @property
100
+ def bl(self) -> Vec2:
101
+ return Vec2(self.l, self.b)
102
+
103
+ @property
104
+ def tl(self) -> Vec2:
105
+ return Vec2(self.l, self.t)
106
+
107
+ @property
108
+ def tr(self) -> Vec2:
109
+ return Vec2(self.r, self.t)
110
+
111
+ @property
112
+ def br(self) -> Vec2:
113
+ return Vec2(self.r, self.b)
114
+
115
+ @property
116
+ def center(self) -> Vec2:
117
+ return Vec2((self.l + self.r) / 2, (self.t + self.b) / 2)
118
+
119
+ def as_quad(self) -> Quad:
120
+ return Quad(
121
+ bl=self.bl,
122
+ tl=self.tl,
123
+ tr=self.tr,
124
+ br=self.br,
125
+ )
126
+
127
+ def translate(self, translation: Vec2, /) -> Self:
128
+ return Rect(
129
+ t=self.t + translation.y,
130
+ r=self.r + translation.x,
131
+ b=self.b + translation.y,
132
+ l=self.l + translation.x,
133
+ )
134
+
135
+ def scale(self, factor: Vec2, /) -> Self:
136
+ return Rect(
137
+ t=self.t * factor.y,
138
+ r=self.r * factor.x,
139
+ b=self.b * factor.y,
140
+ l=self.l * factor.x,
141
+ )
142
+
143
+ def scale_about(self, factor: Vec2, /, pivot: Vec2) -> Self:
144
+ return Rect(
145
+ t=(self.t - pivot.y) * factor.y + pivot.y,
146
+ r=(self.r - pivot.x) * factor.x + pivot.x,
147
+ b=(self.b - pivot.y) * factor.y + pivot.y,
148
+ l=(self.l - pivot.x) * factor.x + pivot.x,
149
+ )
150
+
151
+ def scale_centered(self, factor: Vec2, /) -> Self:
152
+ return Rect(
153
+ t=self.t * factor.y,
154
+ r=self.r * factor.x,
155
+ b=self.b * factor.y,
156
+ l=self.l * factor.x,
157
+ ).translate(self.center * (Vec2(1, 1) - factor))
158
+
159
+ def expand(self, expansion: Vec2, /) -> Self:
160
+ return Rect(
161
+ t=self.t + expansion.y,
162
+ r=self.r + expansion.x,
163
+ b=self.b - expansion.y,
164
+ l=self.l - expansion.x,
165
+ )
166
+
167
+ def shrink(self, shrinkage: Vec2, /) -> Self:
168
+ return Rect(
169
+ t=self.t - shrinkage.y,
170
+ r=self.r - shrinkage.x,
171
+ b=self.b + shrinkage.y,
172
+ l=self.l + shrinkage.x,
173
+ )
174
+
175
+
176
+ class QuadLike(Protocol):
177
+ @property
178
+ def bl(self) -> Vec2: ...
179
+
180
+ @property
181
+ def tl(self) -> Vec2: ...
182
+
183
+ @property
184
+ def tr(self) -> Vec2: ...
185
+
186
+ @property
187
+ def br(self) -> Vec2: ...
188
+
189
+
190
+ def flatten_quad(quad: QuadLike) -> tuple[float, float, float, float, float, float, float, float]:
191
+ return (
192
+ quad.bl.x,
193
+ quad.bl.y,
194
+ quad.tl.x,
195
+ quad.tl.y,
196
+ quad.tr.x,
197
+ quad.tr.y,
198
+ quad.br.x,
199
+ quad.br.y,
200
+ )
@@ -0,0 +1,151 @@
1
+ from dataclasses import dataclass
2
+ from typing import Annotated, Any, NewType, dataclass_transform, get_origin
3
+
4
+ from sonolus.backend.ops import Op
5
+ from sonolus.script.internal.introspection import get_field_specifiers
6
+ from sonolus.script.internal.native import native_function
7
+ from sonolus.script.record import Record
8
+ from sonolus.script.runtime import _TutorialInstruction
9
+ from sonolus.script.text import StandardText
10
+ from sonolus.script.vec import Vec2
11
+
12
+
13
+ class InstructionText(Record):
14
+ id: int
15
+
16
+ def show(self):
17
+ show_instruction(self)
18
+
19
+
20
+ class InstructionIcon(Record):
21
+ id: int
22
+
23
+ def paint(self, position: Vec2, size: float, rotation: float, z: float, a: float):
24
+ _paint(self.id, position.x, position.y, size, rotation, z, a)
25
+
26
+
27
+ @dataclass
28
+ class InstructionTextInfo:
29
+ name: str
30
+
31
+
32
+ @dataclass
33
+ class InstructionIconInfo:
34
+ name: str
35
+
36
+
37
+ def instruction(name: str) -> Any:
38
+ return InstructionTextInfo(name=name)
39
+
40
+
41
+ def instruction_icon(name: str) -> Any:
42
+ return InstructionIconInfo(name=name)
43
+
44
+
45
+ type TutorialInstructions = NewType("TutorialInstructions", Any)
46
+ type TutorialInstructionIcons = NewType("TutorialInstructionIcons", Any)
47
+
48
+
49
+ @dataclass_transform()
50
+ def instructions[T](cls: type[T]) -> T | TutorialInstructions:
51
+ if len(cls.__bases__) != 1:
52
+ raise ValueError("Instructions class must not inherit from any class (except object)")
53
+ instance = cls()
54
+ names = []
55
+ for i, (name, annotation) in enumerate(get_field_specifiers(cls).items()):
56
+ if get_origin(annotation) is not Annotated:
57
+ raise TypeError(f"Invalid annotation for instruction: {annotation}")
58
+ annotation_type = annotation.__args__[0]
59
+ annotation_values = annotation.__metadata__
60
+ if annotation_type is not InstructionText:
61
+ raise TypeError(
62
+ f"Invalid annotation for instruction: {annotation}, expected annotation of type InstructionText"
63
+ )
64
+ if len(annotation_values) != 1 or not isinstance(annotation_values[0], InstructionTextInfo):
65
+ raise TypeError(f"Invalid annotation for instruction: {annotation}, expected a single annotation value")
66
+ instruction_name = annotation_values[0].name
67
+ names.append(instruction_name)
68
+ setattr(instance, name, InstructionText(i))
69
+ instance._instructions_ = names
70
+ instance._is_comptime_value_ = True
71
+ return instance
72
+
73
+
74
+ @dataclass_transform()
75
+ def instruction_icons[T](cls: type[T]) -> T | TutorialInstructionIcons:
76
+ if len(cls.__bases__) != 1:
77
+ raise ValueError("Instruction icons class must not inherit from any class (except object)")
78
+ instance = cls()
79
+ names = []
80
+ for i, (name, annotation) in enumerate(get_field_specifiers(cls).items()):
81
+ if get_origin(annotation) is not Annotated:
82
+ raise TypeError(f"Invalid annotation for instruction icon: {annotation}")
83
+ annotation_type = annotation.__args__[0]
84
+ annotation_values = annotation.__metadata__
85
+ if annotation_type is not InstructionIcon:
86
+ raise TypeError(
87
+ f"Invalid annotation for instruction icon: {annotation}, expected annotation of type InstructionIcon"
88
+ )
89
+ if len(annotation_values) != 1 or not isinstance(annotation_values[0], InstructionIconInfo):
90
+ raise TypeError(
91
+ f"Invalid annotation for instruction icon: {annotation}, expected a single annotation value"
92
+ )
93
+ icon_name = annotation_values[0].name
94
+ names.append(icon_name)
95
+ setattr(instance, name, InstructionIcon(i))
96
+ instance._instruction_icons_ = names
97
+ instance._is_comptime_value_ = True
98
+ return instance
99
+
100
+
101
+ class StandardInstruction:
102
+ TAP = Annotated[InstructionText, instruction(StandardText.TAP)]
103
+ TAP_HOLD = Annotated[InstructionText, instruction(StandardText.TAP_HOLD)]
104
+ TAP_RELEASE = Annotated[InstructionText, instruction(StandardText.TAP_RELEASE)]
105
+ TAP_FLICK = Annotated[InstructionText, instruction(StandardText.TAP_FLICK)]
106
+ TAP_SLIDE = Annotated[InstructionText, instruction(StandardText.TAP_SLIDE)]
107
+ HOLD = Annotated[InstructionText, instruction(StandardText.HOLD)]
108
+ HOLD_SLIDE = Annotated[InstructionText, instruction(StandardText.HOLD_SLIDE)]
109
+ HOLD_FOLLOW = Annotated[InstructionText, instruction(StandardText.HOLD_FOLLOW)]
110
+ RELEASE = Annotated[InstructionText, instruction(StandardText.RELEASE)]
111
+ FLICK = Annotated[InstructionText, instruction(StandardText.FLICK)]
112
+ SLIDE = Annotated[InstructionText, instruction(StandardText.SLIDE)]
113
+ SLIDE_FLICK = Annotated[InstructionText, instruction(StandardText.SLIDE_FLICK)]
114
+ AVOID = Annotated[InstructionText, instruction(StandardText.AVOID)]
115
+ JIGGLE = Annotated[InstructionText, instruction(StandardText.JIGGLE)]
116
+
117
+
118
+ class StandardInstructionIcon:
119
+ HAND = Annotated[InstructionIcon, instruction_icon("#HAND")]
120
+ ARROW = Annotated[InstructionIcon, instruction_icon("#ARROW")]
121
+
122
+
123
+ @instructions
124
+ class EmptyInstructions:
125
+ pass
126
+
127
+
128
+ @instruction_icons
129
+ class EmptyInstructionIcons:
130
+ pass
131
+
132
+
133
+ @native_function(Op.Paint)
134
+ def _paint(
135
+ icon_id: int,
136
+ x: float,
137
+ y: float,
138
+ size: float,
139
+ rotation: float,
140
+ z: float,
141
+ a: float,
142
+ ):
143
+ raise NotImplementedError()
144
+
145
+
146
+ def show_instruction(inst: InstructionText, /):
147
+ _TutorialInstruction.text_id = inst.id
148
+
149
+
150
+ def clear_instruction():
151
+ _TutorialInstruction.text_id = -1
@@ -1,5 +1,5 @@
1
- """Internal scripting details.
2
-
3
- These are internal details of scripting which typically should not be used directly
4
- in engine code.
5
- """
1
+ """Internal scripting details.
2
+
3
+ These are internal details of scripting which typically should not be used directly
4
+ in engine code.
5
+ """