sonolus.py 0.3.4__py3-none-any.whl → 0.4.1__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.
- sonolus/backend/excepthook.py +30 -0
- sonolus/backend/finalize.py +15 -1
- sonolus/backend/ops.py +4 -0
- sonolus/backend/optimize/allocate.py +5 -5
- sonolus/backend/optimize/constant_evaluation.py +124 -19
- sonolus/backend/optimize/copy_coalesce.py +15 -12
- sonolus/backend/optimize/dead_code.py +7 -6
- sonolus/backend/optimize/dominance.py +2 -2
- sonolus/backend/optimize/flow.py +54 -8
- sonolus/backend/optimize/inlining.py +137 -30
- sonolus/backend/optimize/liveness.py +2 -2
- sonolus/backend/optimize/optimize.py +15 -1
- sonolus/backend/optimize/passes.py +11 -3
- sonolus/backend/optimize/simplify.py +137 -8
- sonolus/backend/optimize/ssa.py +47 -13
- sonolus/backend/place.py +5 -4
- sonolus/backend/utils.py +44 -16
- sonolus/backend/visitor.py +288 -17
- sonolus/build/cli.py +47 -19
- sonolus/build/compile.py +12 -5
- sonolus/build/engine.py +70 -1
- sonolus/build/level.py +3 -3
- sonolus/build/project.py +2 -2
- sonolus/script/archetype.py +12 -9
- sonolus/script/array.py +23 -18
- sonolus/script/array_like.py +26 -29
- sonolus/script/bucket.py +1 -1
- sonolus/script/containers.py +22 -26
- sonolus/script/debug.py +20 -43
- sonolus/script/effect.py +1 -1
- sonolus/script/globals.py +3 -3
- sonolus/script/instruction.py +2 -2
- sonolus/script/internal/builtin_impls.py +155 -28
- sonolus/script/internal/constant.py +13 -3
- sonolus/script/internal/context.py +46 -15
- sonolus/script/internal/impl.py +9 -3
- sonolus/script/internal/introspection.py +8 -1
- sonolus/script/internal/native.py +2 -2
- sonolus/script/internal/range.py +8 -11
- sonolus/script/internal/simulation_context.py +1 -1
- sonolus/script/internal/transient.py +2 -2
- sonolus/script/internal/value.py +41 -3
- sonolus/script/interval.py +13 -13
- sonolus/script/iterator.py +53 -107
- sonolus/script/level.py +2 -2
- sonolus/script/maybe.py +241 -0
- sonolus/script/num.py +29 -14
- sonolus/script/options.py +1 -1
- sonolus/script/particle.py +1 -1
- sonolus/script/project.py +24 -5
- sonolus/script/quad.py +15 -15
- sonolus/script/record.py +48 -44
- sonolus/script/runtime.py +22 -18
- sonolus/script/sprite.py +1 -1
- sonolus/script/stream.py +66 -82
- sonolus/script/transform.py +35 -34
- sonolus/script/values.py +10 -10
- sonolus/script/vec.py +21 -18
- {sonolus_py-0.3.4.dist-info → sonolus_py-0.4.1.dist-info}/METADATA +1 -1
- sonolus_py-0.4.1.dist-info/RECORD +93 -0
- sonolus_py-0.3.4.dist-info/RECORD +0 -92
- {sonolus_py-0.3.4.dist-info → sonolus_py-0.4.1.dist-info}/WHEEL +0 -0
- {sonolus_py-0.3.4.dist-info → sonolus_py-0.4.1.dist-info}/entry_points.txt +0 -0
- {sonolus_py-0.3.4.dist-info → sonolus_py-0.4.1.dist-info}/licenses/LICENSE +0 -0
sonolus/script/quad.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Protocol
|
|
3
|
+
from typing import Protocol
|
|
4
4
|
|
|
5
5
|
from sonolus.script.record import Record
|
|
6
6
|
from sonolus.script.values import zeros
|
|
@@ -57,7 +57,7 @@ class Quad(Record):
|
|
|
57
57
|
"""The center of the quad."""
|
|
58
58
|
return (self.bl + self.tr + self.tl + self.br) / 4
|
|
59
59
|
|
|
60
|
-
def translate(self, translation: Vec2, /) ->
|
|
60
|
+
def translate(self, translation: Vec2, /) -> Quad:
|
|
61
61
|
"""Translate the quad by the given translation and return a new quad."""
|
|
62
62
|
return Quad(
|
|
63
63
|
bl=self.bl + translation,
|
|
@@ -66,7 +66,7 @@ class Quad(Record):
|
|
|
66
66
|
br=self.br + translation,
|
|
67
67
|
)
|
|
68
68
|
|
|
69
|
-
def scale(self, factor: Vec2, /) ->
|
|
69
|
+
def scale(self, factor: Vec2, /) -> Quad:
|
|
70
70
|
"""Scale the quad by the given factor about the origin and return a new quad."""
|
|
71
71
|
return Quad(
|
|
72
72
|
bl=self.bl * factor,
|
|
@@ -75,7 +75,7 @@ class Quad(Record):
|
|
|
75
75
|
br=self.br * factor,
|
|
76
76
|
)
|
|
77
77
|
|
|
78
|
-
def scale_about(self, factor: Vec2, /, pivot: Vec2) ->
|
|
78
|
+
def scale_about(self, factor: Vec2, /, pivot: Vec2) -> Quad:
|
|
79
79
|
"""Scale the quad by the given factor about the given pivot and return a new quad."""
|
|
80
80
|
return Quad(
|
|
81
81
|
bl=(self.bl - pivot) * factor + pivot,
|
|
@@ -84,7 +84,7 @@ class Quad(Record):
|
|
|
84
84
|
br=(self.br - pivot) * factor + pivot,
|
|
85
85
|
)
|
|
86
86
|
|
|
87
|
-
def scale_centered(self, factor: Vec2, /) ->
|
|
87
|
+
def scale_centered(self, factor: Vec2, /) -> Quad:
|
|
88
88
|
"""Scale the quad by the given factor about its center and return a new quad."""
|
|
89
89
|
return Quad(
|
|
90
90
|
bl=self.bl * factor,
|
|
@@ -93,7 +93,7 @@ class Quad(Record):
|
|
|
93
93
|
br=self.br * factor,
|
|
94
94
|
).translate(self.center * (Vec2(1, 1) - factor))
|
|
95
95
|
|
|
96
|
-
def rotate(self, angle: float, /) ->
|
|
96
|
+
def rotate(self, angle: float, /) -> Quad:
|
|
97
97
|
"""Rotate the quad by the given angle about the origin and return a new quad.
|
|
98
98
|
|
|
99
99
|
Args:
|
|
@@ -114,7 +114,7 @@ class Quad(Record):
|
|
|
114
114
|
angle: float,
|
|
115
115
|
/,
|
|
116
116
|
pivot: Vec2,
|
|
117
|
-
) ->
|
|
117
|
+
) -> Quad:
|
|
118
118
|
"""Rotate the quad by the given angle about the given pivot and return a new quad.
|
|
119
119
|
|
|
120
120
|
Args:
|
|
@@ -131,7 +131,7 @@ class Quad(Record):
|
|
|
131
131
|
br=self.br.rotate_about(angle, pivot),
|
|
132
132
|
)
|
|
133
133
|
|
|
134
|
-
def rotate_centered(self, angle: float, /) ->
|
|
134
|
+
def rotate_centered(self, angle: float, /) -> Quad:
|
|
135
135
|
"""Rotate the quad by the given angle about its center and return a new quad.
|
|
136
136
|
|
|
137
137
|
Args:
|
|
@@ -142,7 +142,7 @@ class Quad(Record):
|
|
|
142
142
|
"""
|
|
143
143
|
return self.rotate_about(angle, self.center)
|
|
144
144
|
|
|
145
|
-
def permute(self, count: int = 1, /) ->
|
|
145
|
+
def permute(self, count: int = 1, /) -> Quad:
|
|
146
146
|
"""Perform a cyclic permutation of the quad's vertices and return a new quad.
|
|
147
147
|
|
|
148
148
|
On a square, this operation is equivalent to rotating the square counterclockwise 90 degrees `count` times.
|
|
@@ -269,7 +269,7 @@ class Rect(Record):
|
|
|
269
269
|
br=self.br,
|
|
270
270
|
)
|
|
271
271
|
|
|
272
|
-
def translate(self, translation: Vec2, /) ->
|
|
272
|
+
def translate(self, translation: Vec2, /) -> Rect:
|
|
273
273
|
"""Translate the rectangle by the given translation and return a new rectangle."""
|
|
274
274
|
return Rect(
|
|
275
275
|
t=self.t + translation.y,
|
|
@@ -278,7 +278,7 @@ class Rect(Record):
|
|
|
278
278
|
l=self.l + translation.x,
|
|
279
279
|
)
|
|
280
280
|
|
|
281
|
-
def scale(self, factor: Vec2, /) ->
|
|
281
|
+
def scale(self, factor: Vec2, /) -> Rect:
|
|
282
282
|
"""Scale the rectangle by the given factor about the origin and return a new rectangle."""
|
|
283
283
|
return Rect(
|
|
284
284
|
t=self.t * factor.y,
|
|
@@ -287,7 +287,7 @@ class Rect(Record):
|
|
|
287
287
|
l=self.l * factor.x,
|
|
288
288
|
)
|
|
289
289
|
|
|
290
|
-
def scale_about(self, factor: Vec2, /, pivot: Vec2) ->
|
|
290
|
+
def scale_about(self, factor: Vec2, /, pivot: Vec2) -> Rect:
|
|
291
291
|
"""Scale the rectangle by the given factor about the given pivot and return a new rectangle."""
|
|
292
292
|
return Rect(
|
|
293
293
|
t=(self.t - pivot.y) * factor.y + pivot.y,
|
|
@@ -296,7 +296,7 @@ class Rect(Record):
|
|
|
296
296
|
l=(self.l - pivot.x) * factor.x + pivot.x,
|
|
297
297
|
)
|
|
298
298
|
|
|
299
|
-
def scale_centered(self, factor: Vec2, /) ->
|
|
299
|
+
def scale_centered(self, factor: Vec2, /) -> Rect:
|
|
300
300
|
"""Scale the rectangle by the given factor about its center and return a new rectangle."""
|
|
301
301
|
return Rect(
|
|
302
302
|
t=self.t * factor.y,
|
|
@@ -305,7 +305,7 @@ class Rect(Record):
|
|
|
305
305
|
l=self.l * factor.x,
|
|
306
306
|
).translate(self.center * (Vec2(1, 1) - factor))
|
|
307
307
|
|
|
308
|
-
def expand(self, expansion: Vec2, /) ->
|
|
308
|
+
def expand(self, expansion: Vec2, /) -> Rect:
|
|
309
309
|
"""Expand the rectangle by the given amount and return a new rectangle."""
|
|
310
310
|
return Rect(
|
|
311
311
|
t=self.t + expansion.y,
|
|
@@ -314,7 +314,7 @@ class Rect(Record):
|
|
|
314
314
|
l=self.l - expansion.x,
|
|
315
315
|
)
|
|
316
316
|
|
|
317
|
-
def shrink(self, shrinkage: Vec2, /) ->
|
|
317
|
+
def shrink(self, shrinkage: Vec2, /) -> Rect:
|
|
318
318
|
"""Shrink the rectangle by the given amount and return a new rectangle."""
|
|
319
319
|
return Rect(
|
|
320
320
|
t=self.t - shrinkage.y,
|
sonolus/script/record.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import inspect
|
|
4
|
+
from abc import ABCMeta
|
|
4
5
|
from collections.abc import Iterable
|
|
5
6
|
from inspect import getmro
|
|
6
7
|
from typing import Any, ClassVar, Self, TypeVar, dataclass_transform, get_origin
|
|
@@ -20,7 +21,7 @@ from sonolus.script.internal.value import BackingSource, DataValue, Value
|
|
|
20
21
|
from sonolus.script.num import Num
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
class RecordMeta(
|
|
24
|
+
class RecordMeta(ABCMeta):
|
|
24
25
|
@meta_fn
|
|
25
26
|
def __pos__[T](cls: type[T]) -> T:
|
|
26
27
|
"""Create a zero-initialized record instance."""
|
|
@@ -61,13 +62,13 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
61
62
|
```
|
|
62
63
|
"""
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
_value_: dict[str, Value]
|
|
66
|
+
_fields_: ClassVar[list[_RecordField] | None] = None
|
|
67
|
+
_constructor_signature_: ClassVar[inspect.Signature]
|
|
67
68
|
|
|
68
69
|
@classmethod
|
|
69
70
|
def _validate_type_args_(cls, args: tuple[Any, ...]) -> tuple[Any, ...]:
|
|
70
|
-
if cls.
|
|
71
|
+
if cls._fields_ is None:
|
|
71
72
|
raise TypeError("Base Record class cannot have type arguments")
|
|
72
73
|
return super()._validate_type_args_(args)
|
|
73
74
|
|
|
@@ -79,16 +80,16 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
79
80
|
if is_parameterizing:
|
|
80
81
|
fields = []
|
|
81
82
|
offset = 0
|
|
82
|
-
for generic_field in cls.
|
|
83
|
+
for generic_field in cls._fields_:
|
|
83
84
|
resolved_type = validate_and_resolve_type(generic_field.type, cls._type_vars_to_args_)
|
|
84
85
|
resolved_type = validate_concrete_type(resolved_type)
|
|
85
86
|
field = _RecordField(generic_field.name, resolved_type, generic_field.index, offset)
|
|
86
87
|
fields.append(field)
|
|
87
88
|
setattr(cls, field.name, field)
|
|
88
89
|
offset += resolved_type._size_()
|
|
89
|
-
cls.
|
|
90
|
+
cls._fields_ = fields
|
|
90
91
|
return
|
|
91
|
-
is_inheriting_from_existing_record_class = cls.
|
|
92
|
+
is_inheriting_from_existing_record_class = cls._fields_ is not None
|
|
92
93
|
if is_inheriting_from_existing_record_class and not is_parameterizing:
|
|
93
94
|
# The main reason this is disallowed is that subclasses wouldn't be substitutable for their parent classes
|
|
94
95
|
# Assignment of a subclass instance to a variable of the parent class would either be disallowed or would
|
|
@@ -123,8 +124,8 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
123
124
|
)
|
|
124
125
|
|
|
125
126
|
cls._parameterized_ = {}
|
|
126
|
-
cls.
|
|
127
|
-
cls.
|
|
127
|
+
cls._fields_ = fields
|
|
128
|
+
cls._constructor_signature_ = inspect.Signature(params)
|
|
128
129
|
|
|
129
130
|
_add_inplace_ops(cls)
|
|
130
131
|
|
|
@@ -138,13 +139,13 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
138
139
|
|
|
139
140
|
def __new__(cls, *args, **kwargs):
|
|
140
141
|
# We override __new__ to allow changing to the parameterized version
|
|
141
|
-
if cls.
|
|
142
|
+
if cls._constructor_signature_ is None:
|
|
142
143
|
raise TypeError(f"Cannot instantiate {cls.__name__}")
|
|
143
|
-
bound = cls.
|
|
144
|
+
bound = cls._constructor_signature_.bind(*args, **kwargs)
|
|
144
145
|
bound.apply_defaults()
|
|
145
146
|
values = {}
|
|
146
147
|
type_vars = {}
|
|
147
|
-
for field in cls.
|
|
148
|
+
for field in cls._fields_:
|
|
148
149
|
value = bound.arguments[field.name]
|
|
149
150
|
value = accept_and_infer_types(field.type, value, type_vars)
|
|
150
151
|
values[field.name] = value._get_()
|
|
@@ -157,7 +158,7 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
157
158
|
else:
|
|
158
159
|
parameterized = cls[type_args]
|
|
159
160
|
result: cls = object.__new__(parameterized) # type: ignore
|
|
160
|
-
result.
|
|
161
|
+
result._value_ = values
|
|
161
162
|
return result
|
|
162
163
|
|
|
163
164
|
def __init__(self, *args, **kwargs):
|
|
@@ -167,12 +168,12 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
167
168
|
@classmethod
|
|
168
169
|
def _raw(cls, **kwargs) -> Self:
|
|
169
170
|
result = object.__new__(cls)
|
|
170
|
-
result.
|
|
171
|
+
result._value_ = kwargs
|
|
171
172
|
return result
|
|
172
173
|
|
|
173
174
|
@classmethod
|
|
174
175
|
def _size_(cls) -> int:
|
|
175
|
-
return sum(field.type._size_() for field in cls.
|
|
176
|
+
return sum(field.type._size_() for field in cls._fields_)
|
|
176
177
|
|
|
177
178
|
@classmethod
|
|
178
179
|
def _is_value_type_(cls) -> bool:
|
|
@@ -181,18 +182,18 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
181
182
|
@classmethod
|
|
182
183
|
def _from_backing_source_(cls, source: BackingSource) -> Self:
|
|
183
184
|
result = object.__new__(cls)
|
|
184
|
-
result.
|
|
185
|
+
result._value_ = {
|
|
185
186
|
field.name: field.type._from_backing_source_(
|
|
186
|
-
lambda offset, field_offset=field.offset: source((Num(offset) + Num(field_offset)).ir())
|
|
187
|
+
lambda offset, field_offset=field.offset: source((Num(offset) + Num(field_offset)).ir()) # type: ignore
|
|
187
188
|
)
|
|
188
|
-
for field in cls.
|
|
189
|
+
for field in cls._fields_
|
|
189
190
|
}
|
|
190
191
|
return result
|
|
191
192
|
|
|
192
193
|
@classmethod
|
|
193
194
|
def _from_place_(cls, place: BlockPlace) -> Self:
|
|
194
195
|
result = object.__new__(cls)
|
|
195
|
-
result.
|
|
196
|
+
result._value_ = {field.name: field.type._from_place_(place.add_offset(field.offset)) for field in cls._fields_}
|
|
196
197
|
return result
|
|
197
198
|
|
|
198
199
|
@classmethod
|
|
@@ -206,7 +207,7 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
206
207
|
return value
|
|
207
208
|
|
|
208
209
|
def _is_py_(self) -> bool:
|
|
209
|
-
return all(value._is_py_() for value in self.
|
|
210
|
+
return all(value._is_py_() for value in self._value_.values())
|
|
210
211
|
|
|
211
212
|
def _as_py_(self) -> Self:
|
|
212
213
|
if not self._is_py_():
|
|
@@ -216,64 +217,64 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
216
217
|
@classmethod
|
|
217
218
|
def _from_list_(cls, values: Iterable[DataValue]) -> Self:
|
|
218
219
|
iterator = iter(values)
|
|
219
|
-
return cls(**{field.name: field.type._from_list_(iterator) for field in cls.
|
|
220
|
+
return cls(**{field.name: field.type._from_list_(iterator) for field in cls._fields_})
|
|
220
221
|
|
|
221
222
|
def _to_list_(self, level_refs: dict[Any, str] | None = None) -> list[DataValue | str]:
|
|
222
223
|
result = []
|
|
223
|
-
for field in self.
|
|
224
|
-
result.extend(self.
|
|
224
|
+
for field in self._fields_:
|
|
225
|
+
result.extend(self._value_[field.name]._to_list_(level_refs))
|
|
225
226
|
return result
|
|
226
227
|
|
|
227
228
|
@classmethod
|
|
228
229
|
def _flat_keys_(cls, prefix: str) -> list[str]:
|
|
229
230
|
result = []
|
|
230
|
-
for field in cls.
|
|
231
|
+
for field in cls._fields_:
|
|
231
232
|
result.extend(field.type._flat_keys_(f"{prefix}.{field.name}"))
|
|
232
233
|
return result
|
|
233
234
|
|
|
234
235
|
def _get_(self) -> Self:
|
|
235
236
|
return self
|
|
236
237
|
|
|
237
|
-
def _set_(self, value:
|
|
238
|
+
def _set_(self, value: Any):
|
|
238
239
|
raise TypeError("Record does not support _set_")
|
|
239
240
|
|
|
240
|
-
def _copy_from_(self, value:
|
|
241
|
+
def _copy_from_(self, value: Any):
|
|
241
242
|
value = self._accept_(value)
|
|
242
|
-
for field in self.
|
|
243
|
+
for field in self._fields_:
|
|
243
244
|
field.__set__(self, field.__get__(value))
|
|
244
245
|
|
|
245
246
|
def _copy_(self) -> Self:
|
|
246
|
-
return type(self)._raw(**{field.name: self.
|
|
247
|
+
return type(self)._raw(**{field.name: self._value_[field.name]._copy_() for field in self._fields_})
|
|
247
248
|
|
|
248
249
|
@classmethod
|
|
249
250
|
def _alloc_(cls) -> Self:
|
|
250
251
|
# Compared to using the constructor, this avoids unnecessary _get_ calls
|
|
251
252
|
result = object.__new__(cls)
|
|
252
|
-
result.
|
|
253
|
+
result._value_ = {field.name: field.type._alloc_() for field in cls._fields_}
|
|
253
254
|
return result
|
|
254
255
|
|
|
255
256
|
@classmethod
|
|
256
257
|
def _zero_(cls) -> Self:
|
|
257
258
|
result = object.__new__(cls)
|
|
258
|
-
result.
|
|
259
|
+
result._value_ = {field.name: field.type._zero_() for field in cls._fields_}
|
|
259
260
|
return result
|
|
260
261
|
|
|
261
262
|
def __str__(self):
|
|
262
|
-
return (
|
|
263
|
-
|
|
264
|
-
)
|
|
263
|
+
return f"{self.__class__.__name__}({
|
|
264
|
+
', '.join(f'{field.name}={field.get_internal(self)}' for field in self._fields_)
|
|
265
|
+
})"
|
|
265
266
|
|
|
266
267
|
def __repr__(self):
|
|
267
|
-
return (
|
|
268
|
-
|
|
269
|
-
)
|
|
268
|
+
return f"{self.__class__.__name__}({
|
|
269
|
+
', '.join(f'{field.name}={field.get_internal(self)!r}' for field in self._fields_)
|
|
270
|
+
})"
|
|
270
271
|
|
|
271
272
|
@meta_fn
|
|
272
273
|
def __eq__(self, other: Any) -> bool:
|
|
273
274
|
if not isinstance(other, type(self)):
|
|
274
275
|
return False
|
|
275
276
|
result: Num = Num._accept_(True)
|
|
276
|
-
for field in self.
|
|
277
|
+
for field in self._fields_:
|
|
277
278
|
result = result.and_(field.__get__(self) == field.__get__(other))
|
|
278
279
|
return result
|
|
279
280
|
|
|
@@ -282,12 +283,12 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
282
283
|
if not isinstance(other, type(self)):
|
|
283
284
|
return True
|
|
284
285
|
result: Num = Num._accept_(False)
|
|
285
|
-
for field in self.
|
|
286
|
+
for field in self._fields_:
|
|
286
287
|
result = result.or_(field.__get__(self) != field.__get__(other))
|
|
287
288
|
return result
|
|
288
289
|
|
|
289
290
|
def __hash__(self):
|
|
290
|
-
return hash(tuple(field.__get__(self) for field in self.
|
|
291
|
+
return hash(tuple(field.__get__(self) for field in self._fields_))
|
|
291
292
|
|
|
292
293
|
@meta_fn
|
|
293
294
|
def __pos__(self) -> Self:
|
|
@@ -309,16 +310,19 @@ class Record(GenericValue, metaclass=RecordMeta):
|
|
|
309
310
|
|
|
310
311
|
|
|
311
312
|
class _RecordField(SonolusDescriptor):
|
|
312
|
-
def __init__(self, name: str, type_: type[Value], index: int, offset: int):
|
|
313
|
+
def __init__(self, name: str, type_: type[Value] | Any, index: int, offset: int):
|
|
313
314
|
self.name = name
|
|
314
315
|
self.type = type_
|
|
315
316
|
self.index = index
|
|
316
317
|
self.offset = offset
|
|
317
318
|
|
|
319
|
+
def get_internal(self, instance: Record) -> Value:
|
|
320
|
+
return instance._value_[self.name]
|
|
321
|
+
|
|
318
322
|
def __get__(self, instance: Record | None, owner=None):
|
|
319
323
|
if instance is None:
|
|
320
324
|
return self
|
|
321
|
-
result = instance.
|
|
325
|
+
result = instance._value_[self.name]._get_readonly_()
|
|
322
326
|
if ctx():
|
|
323
327
|
return result
|
|
324
328
|
else:
|
|
@@ -327,9 +331,9 @@ class _RecordField(SonolusDescriptor):
|
|
|
327
331
|
def __set__(self, instance: Record, value):
|
|
328
332
|
value = self.type._accept_(value)
|
|
329
333
|
if self.type._is_value_type_():
|
|
330
|
-
instance.
|
|
334
|
+
instance._value_[self.name]._set_(value)
|
|
331
335
|
else:
|
|
332
|
-
instance.
|
|
336
|
+
instance._value_[self.name]._copy_from_(value)
|
|
333
337
|
|
|
334
338
|
|
|
335
339
|
_ops_to_inplace_ops = {
|
sonolus/script/runtime.py
CHANGED
|
@@ -698,7 +698,7 @@ class _TouchArray:
|
|
|
698
698
|
|
|
699
699
|
@_runtime_skin_transform
|
|
700
700
|
class _SkinTransform:
|
|
701
|
-
value: Array[Array[float, 4], 4]
|
|
701
|
+
value: Array[Array[float, 4], 4] # type: ignore
|
|
702
702
|
|
|
703
703
|
@property
|
|
704
704
|
@meta_fn
|
|
@@ -719,7 +719,7 @@ class _SkinTransform:
|
|
|
719
719
|
|
|
720
720
|
@_runtime_particle_transform
|
|
721
721
|
class _ParticleTransform:
|
|
722
|
-
value: Array[Array[float, 4], 4]
|
|
722
|
+
value: Array[Array[float, 4], 4] # type: ignore
|
|
723
723
|
|
|
724
724
|
@property
|
|
725
725
|
@meta_fn
|
|
@@ -857,25 +857,25 @@ def is_debug() -> bool:
|
|
|
857
857
|
@meta_fn
|
|
858
858
|
def is_play() -> bool:
|
|
859
859
|
"""Check if the game is running in play mode."""
|
|
860
|
-
return ctx() and ctx().global_state.mode == Mode.PLAY
|
|
860
|
+
return bool(ctx() and ctx().global_state.mode == Mode.PLAY)
|
|
861
861
|
|
|
862
862
|
|
|
863
863
|
@meta_fn
|
|
864
864
|
def is_preview() -> bool:
|
|
865
865
|
"""Check if the game is running in preview mode."""
|
|
866
|
-
return ctx() and ctx().global_state.mode == Mode.PREVIEW
|
|
866
|
+
return bool(ctx() and ctx().global_state.mode == Mode.PREVIEW)
|
|
867
867
|
|
|
868
868
|
|
|
869
869
|
@meta_fn
|
|
870
870
|
def is_watch() -> bool:
|
|
871
871
|
"""Check if the game is running in watch mode."""
|
|
872
|
-
return ctx() and ctx().global_state.mode == Mode.WATCH
|
|
872
|
+
return bool(ctx() and ctx().global_state.mode == Mode.WATCH)
|
|
873
873
|
|
|
874
874
|
|
|
875
875
|
@meta_fn
|
|
876
876
|
def is_tutorial() -> bool:
|
|
877
877
|
"""Check if the game is running in tutorial mode."""
|
|
878
|
-
return ctx() and ctx().global_state.mode == Mode.TUTORIAL
|
|
878
|
+
return bool(ctx() and ctx().global_state.mode == Mode.TUTORIAL)
|
|
879
879
|
|
|
880
880
|
|
|
881
881
|
@meta_fn
|
|
@@ -884,7 +884,7 @@ def is_preprocessing() -> bool:
|
|
|
884
884
|
|
|
885
885
|
Returns True if the current callback is one of preprocess, spawn_order, spawn_time, or despawn_time.
|
|
886
886
|
"""
|
|
887
|
-
return ctx() and ctx().callback in {"preprocess", "spawnOrder", "spawnTime", "despawnTime"}
|
|
887
|
+
return bool(ctx() and ctx().callback in {"preprocess", "spawnOrder", "spawnTime", "despawnTime"})
|
|
888
888
|
|
|
889
889
|
|
|
890
890
|
@meta_fn
|
|
@@ -1058,12 +1058,16 @@ def prev_time() -> float:
|
|
|
1058
1058
|
def touches() -> ArrayLike[Touch]:
|
|
1059
1059
|
"""Get the current touches of the game."""
|
|
1060
1060
|
if not ctx():
|
|
1061
|
-
return Array[Touch, 0]()
|
|
1061
|
+
return Array[Touch, 0]() # type: ignore
|
|
1062
1062
|
match ctx().global_state.mode:
|
|
1063
1063
|
case Mode.PLAY:
|
|
1064
|
-
return ArrayPointer[Touch]
|
|
1064
|
+
return ArrayPointer[Touch]._raw(
|
|
1065
|
+
size=Num._accept_(_PlayRuntimeUpdate.touch_count),
|
|
1066
|
+
block=Num._accept_(ctx().blocks.RuntimeTouchArray),
|
|
1067
|
+
offset=Num._accept_(0),
|
|
1068
|
+
)
|
|
1065
1069
|
case _:
|
|
1066
|
-
return Array[Touch, 0]()
|
|
1070
|
+
return Array[Touch, 0]() # type: ignore
|
|
1067
1071
|
|
|
1068
1072
|
|
|
1069
1073
|
@meta_fn
|
|
@@ -1098,24 +1102,24 @@ def navigation_direction() -> int:
|
|
|
1098
1102
|
|
|
1099
1103
|
def skin_transform() -> Transform2d:
|
|
1100
1104
|
"""Get the global skin transform."""
|
|
1101
|
-
return _SkinTransform.transform
|
|
1105
|
+
return _SkinTransform.transform # type: ignore
|
|
1102
1106
|
|
|
1103
1107
|
|
|
1104
1108
|
@meta_fn
|
|
1105
1109
|
def set_skin_transform(value: Transform2d):
|
|
1106
1110
|
"""Set the global skin transform."""
|
|
1107
|
-
_SkinTransform.transform._copy_from_(value)
|
|
1111
|
+
_SkinTransform.transform._copy_from_(value) # type: ignore
|
|
1108
1112
|
|
|
1109
1113
|
|
|
1110
1114
|
def particle_transform() -> Transform2d:
|
|
1111
1115
|
"""Get the global particle transform."""
|
|
1112
|
-
return _ParticleTransform.transform
|
|
1116
|
+
return _ParticleTransform.transform # type: ignore
|
|
1113
1117
|
|
|
1114
1118
|
|
|
1115
1119
|
@meta_fn
|
|
1116
1120
|
def set_particle_transform(value: Transform2d):
|
|
1117
1121
|
"""Set the global particle transform."""
|
|
1118
|
-
_ParticleTransform.transform._copy_from_(value)
|
|
1122
|
+
_ParticleTransform.transform._copy_from_(value) # type: ignore
|
|
1119
1123
|
|
|
1120
1124
|
|
|
1121
1125
|
def background() -> Quad:
|
|
@@ -1142,12 +1146,12 @@ _runtime_ui = RuntimeUi()
|
|
|
1142
1146
|
|
|
1143
1147
|
def runtime_ui() -> RuntimeUi:
|
|
1144
1148
|
"""Get the runtime UI configuration."""
|
|
1145
|
-
return _runtime_ui
|
|
1149
|
+
return _runtime_ui # type: ignore
|
|
1146
1150
|
|
|
1147
1151
|
|
|
1148
1152
|
def canvas() -> _PreviewRuntimeCanvas:
|
|
1149
1153
|
"""Get the preview canvas."""
|
|
1150
|
-
return _PreviewRuntimeCanvas
|
|
1154
|
+
return _PreviewRuntimeCanvas # type: ignore
|
|
1151
1155
|
|
|
1152
1156
|
|
|
1153
1157
|
def screen() -> Rect:
|
|
@@ -1157,9 +1161,9 @@ def screen() -> Rect:
|
|
|
1157
1161
|
|
|
1158
1162
|
def level_score() -> _LevelScore:
|
|
1159
1163
|
"""Get the level score configuration."""
|
|
1160
|
-
return _LevelScore
|
|
1164
|
+
return _LevelScore # type: ignore
|
|
1161
1165
|
|
|
1162
1166
|
|
|
1163
1167
|
def level_life() -> _LevelLife:
|
|
1164
1168
|
"""Get the level life configuration."""
|
|
1165
|
-
return _LevelLife
|
|
1169
|
+
return _LevelLife # type: ignore
|