sonolus.py 0.1.8__py3-none-any.whl → 0.2.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 (48) hide show
  1. sonolus/backend/finalize.py +2 -1
  2. sonolus/backend/optimize/constant_evaluation.py +2 -2
  3. sonolus/backend/optimize/copy_coalesce.py +16 -7
  4. sonolus/backend/optimize/optimize.py +12 -4
  5. sonolus/backend/optimize/passes.py +2 -1
  6. sonolus/backend/place.py +95 -14
  7. sonolus/backend/visitor.py +83 -12
  8. sonolus/build/cli.py +60 -9
  9. sonolus/build/collection.py +68 -26
  10. sonolus/build/compile.py +87 -30
  11. sonolus/build/engine.py +166 -40
  12. sonolus/build/level.py +2 -1
  13. sonolus/build/node.py +8 -1
  14. sonolus/build/project.py +30 -11
  15. sonolus/script/archetype.py +169 -51
  16. sonolus/script/array.py +12 -1
  17. sonolus/script/bucket.py +26 -8
  18. sonolus/script/debug.py +2 -2
  19. sonolus/script/effect.py +2 -2
  20. sonolus/script/engine.py +123 -15
  21. sonolus/script/internal/builtin_impls.py +21 -2
  22. sonolus/script/internal/constant.py +6 -2
  23. sonolus/script/internal/context.py +30 -25
  24. sonolus/script/internal/introspection.py +8 -1
  25. sonolus/script/internal/math_impls.py +2 -1
  26. sonolus/script/internal/transient.py +5 -1
  27. sonolus/script/internal/value.py +10 -2
  28. sonolus/script/interval.py +16 -0
  29. sonolus/script/iterator.py +17 -0
  30. sonolus/script/level.py +130 -8
  31. sonolus/script/metadata.py +32 -0
  32. sonolus/script/num.py +11 -2
  33. sonolus/script/options.py +5 -3
  34. sonolus/script/pointer.py +2 -0
  35. sonolus/script/project.py +41 -5
  36. sonolus/script/record.py +8 -3
  37. sonolus/script/runtime.py +61 -10
  38. sonolus/script/sprite.py +18 -1
  39. sonolus/script/ui.py +7 -3
  40. sonolus/script/values.py +8 -5
  41. sonolus/script/vec.py +28 -0
  42. {sonolus_py-0.1.8.dist-info → sonolus_py-0.2.0.dist-info}/METADATA +3 -2
  43. sonolus_py-0.2.0.dist-info/RECORD +90 -0
  44. {sonolus_py-0.1.8.dist-info → sonolus_py-0.2.0.dist-info}/WHEEL +1 -1
  45. sonolus_py-0.1.8.dist-info/RECORD +0 -89
  46. /sonolus/script/{print.py → printing.py} +0 -0
  47. {sonolus_py-0.1.8.dist-info → sonolus_py-0.2.0.dist-info}/entry_points.txt +0 -0
  48. {sonolus_py-0.1.8.dist-info → sonolus_py-0.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,32 @@
1
+ from typing import Any
2
+
3
+ type LocalizationText = dict[str, str]
4
+ type AnyText = str | LocalizationText
5
+
6
+
7
+ def as_localization_text(text: AnyText) -> LocalizationText:
8
+ if isinstance(text, str):
9
+ return {"en": text}
10
+ return text
11
+
12
+
13
+ class Tag:
14
+ """A tag for an engine or level.
15
+
16
+ Args:
17
+ title: The title of the tag.
18
+ icon: The icon of the tag.
19
+ """
20
+
21
+ title: LocalizationText
22
+ icon: str | None
23
+
24
+ def __init__(self, title: AnyText, icon: str | None = None) -> None:
25
+ self.title = as_localization_text(title)
26
+ self.icon = icon
27
+
28
+ def as_dict(self) -> dict[str, Any]:
29
+ result = {"title": self.title}
30
+ if self.icon is not None:
31
+ result["icon"] = self.icon
32
+ return result
sonolus/script/num.py CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
 
4
4
  import operator
5
5
  from collections.abc import Callable, Iterable
6
- from typing import TYPE_CHECKING, Any, Self, final, runtime_checkable, TypeGuard
6
+ from typing import TYPE_CHECKING, Any, Self, TypeGuard, final, runtime_checkable
7
7
 
8
8
  from sonolus.backend.ir import IRConst, IRGet, IRPureInstr, IRSet
9
9
  from sonolus.backend.ops import Op
@@ -92,7 +92,7 @@ class _Num(Value, metaclass=_NumMeta):
92
92
  value = next(iter(values))
93
93
  return Num(value)
94
94
 
95
- def _to_list_(self, level_refs: dict[Any, int] | None = None) -> list[float | BlockPlace]:
95
+ def _to_list_(self, level_refs: dict[Any, str] | None = None) -> list[float | str | BlockPlace]:
96
96
  return [self.data]
97
97
 
98
98
  @classmethod
@@ -134,6 +134,15 @@ class _Num(Value, metaclass=_NumMeta):
134
134
  else:
135
135
  return Num(-1)
136
136
 
137
+ @classmethod
138
+ def _zero_(cls) -> Self:
139
+ if ctx():
140
+ result_place = ctx().alloc(size=1)
141
+ ctx().add_statements(IRSet(result_place, IRConst(0)))
142
+ return cls(result_place)
143
+ else:
144
+ return cls(0)
145
+
137
146
  def ir(self):
138
147
  if isinstance(self.data, BlockPlace):
139
148
  return IRGet(self.data)
sonolus/script/options.py CHANGED
@@ -69,7 +69,7 @@ class _SelectOption:
69
69
  standard: bool
70
70
  advanced: bool
71
71
  scope: str | None
72
- default: str
72
+ default: int
73
73
  values: list[str]
74
74
 
75
75
  def to_dict(self):
@@ -78,7 +78,7 @@ class _SelectOption:
78
78
  "name": self.name,
79
79
  "standard": self.standard,
80
80
  "advanced": self.advanced,
81
- "def": self.values.index(self.default),
81
+ "def": self.default,
82
82
  "values": self.values,
83
83
  }
84
84
  if self.scope is not None:
@@ -139,7 +139,7 @@ def select_option(
139
139
  name: str | None = None,
140
140
  standard: bool = False,
141
141
  advanced: bool = False,
142
- default: str,
142
+ default: str | int,
143
143
  values: list[str],
144
144
  scope: str | None = None,
145
145
  ) -> Any:
@@ -153,6 +153,8 @@ def select_option(
153
153
  values: The values of the option.
154
154
  scope: The scope of the option.
155
155
  """
156
+ if isinstance(default, str):
157
+ default = values.index(default)
156
158
  return _SelectOption(name, standard, advanced, scope, default, values)
157
159
 
158
160
 
sonolus/script/pointer.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from sonolus.backend.place import BlockPlace
2
+ from sonolus.script.internal.context import ctx
2
3
  from sonolus.script.internal.impl import meta_fn, validate_value
3
4
  from sonolus.script.internal.value import Value
4
5
  from sonolus.script.num import Num, _is_num
@@ -13,6 +14,7 @@ def _deref[T: Value](block: Num, offset: Num, type_: type[T]) -> T:
13
14
  block = block._as_py_()
14
15
  if not isinstance(block, int):
15
16
  raise TypeError("block must be an integer")
17
+ block = ctx().blocks(block)
16
18
  else:
17
19
  if not _is_num(block):
18
20
  raise TypeError("block must be a Num")
sonolus/script/project.py CHANGED
@@ -1,9 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Sequence
4
+ from dataclasses import dataclass
3
5
  from os import PathLike
4
6
  from pathlib import Path
5
- from typing import Self, TypedDict
7
+ from typing import ClassVar, Self, TypedDict
6
8
 
9
+ from sonolus.backend.optimize import optimize
10
+ from sonolus.backend.optimize.passes import CompilerPass
7
11
  from sonolus.script.archetype import ArchetypeSchema
8
12
  from sonolus.script.engine import Engine
9
13
  from sonolus.script.level import Level
@@ -39,27 +43,30 @@ class Project:
39
43
  """
40
44
  return Project(self.engine, levels, self.resources)
41
45
 
42
- def dev(self, build_dir: PathLike, port: int = 8080):
46
+ def dev(self, build_dir: PathLike, port: int = 8080, config: BuildConfig | None = None):
43
47
  """Start a development server for the project.
44
48
 
45
49
  Args:
46
50
  build_dir: The path to the build directory.
47
51
  port: The port of the development server.
52
+ config: The build configuration.
48
53
  """
49
54
  from sonolus.build.cli import build_collection, run_server
50
55
 
51
- build_collection(self, Path(build_dir))
56
+ build_collection(self, Path(build_dir), config)
52
57
  run_server(Path(build_dir) / "site", port=port)
53
58
 
54
- def build(self, build_dir: PathLike):
59
+ def build(self, build_dir: PathLike, config: BuildConfig | None = None):
55
60
  """Build the project.
56
61
 
57
62
  Args:
58
63
  build_dir: The path to the build directory.
64
+ config: The build configuration.
59
65
  """
60
66
  from sonolus.build.cli import build_project
61
67
 
62
- build_project(self, Path(build_dir))
68
+ config = config or BuildConfig()
69
+ build_project(self, Path(build_dir), config)
63
70
 
64
71
  def schema(self) -> ProjectSchema:
65
72
  """Generate the schema of the project.
@@ -74,3 +81,32 @@ class Project:
74
81
 
75
82
  class ProjectSchema(TypedDict):
76
83
  archetypes: list[ArchetypeSchema]
84
+
85
+
86
+ @dataclass
87
+ class BuildConfig:
88
+ """A configuration for building an engine package."""
89
+
90
+ MINIMAL_PASSES: ClassVar[Sequence[CompilerPass]] = optimize.MINIMAL_PASSES
91
+ """The minimal list of compiler passes."""
92
+
93
+ FAST_PASSES: ClassVar[Sequence[CompilerPass]] = optimize.FAST_PASSES
94
+ """The list of compiler passes for faster builds."""
95
+
96
+ STANDARD_PASSES: ClassVar[Sequence[CompilerPass]] = optimize.STANDARD_PASSES
97
+ """The standard list of compiler passes."""
98
+
99
+ passes: Sequence[CompilerPass] = optimize.STANDARD_PASSES
100
+ """The list of compiler passes to use."""
101
+
102
+ build_play: bool = True
103
+ """Whether to build the play package."""
104
+
105
+ build_watch: bool = True
106
+ """Whether to build the watch package."""
107
+
108
+ build_preview: bool = True
109
+ """Whether to build the preview package."""
110
+
111
+ build_tutorial: bool = True
112
+ """Whether to build the tutorial package."""
sonolus/script/record.py CHANGED
@@ -186,7 +186,7 @@ class Record(GenericValue):
186
186
  iterator = iter(values)
187
187
  return cls(**{field.name: field.type._from_list_(iterator) for field in cls._fields})
188
188
 
189
- def _to_list_(self, level_refs: dict[Any, int] | None = None) -> list[float | BlockPlace]:
189
+ def _to_list_(self, level_refs: dict[Any, str] | None = None) -> list[float | str | BlockPlace]:
190
190
  result = []
191
191
  for field in self._fields:
192
192
  result.extend(self._value[field.name]._to_list_(level_refs))
@@ -206,8 +206,7 @@ class Record(GenericValue):
206
206
  raise TypeError("Record does not support set_")
207
207
 
208
208
  def _copy_from_(self, value: Self):
209
- if not isinstance(value, type(self)):
210
- raise TypeError("Cannot copy from different type")
209
+ value = self._accept_(value)
211
210
  for field in self._fields:
212
211
  field.__set__(self, field.__get__(value))
213
212
 
@@ -221,6 +220,12 @@ class Record(GenericValue):
221
220
  result._value = {field.name: field.type._alloc_() for field in cls._fields}
222
221
  return result
223
222
 
223
+ @classmethod
224
+ def _zero_(cls) -> Self:
225
+ result = object.__new__(cls)
226
+ result._value = {field.name: field.type._zero_() for field in cls._fields}
227
+ return result
228
+
224
229
  def __str__(self):
225
230
  return (
226
231
  f"{self.__class__.__name__}({", ".join(f"{field.name}={field.__get__(self)}" for field in self._fields)})"
sonolus/script/runtime.py CHANGED
@@ -103,6 +103,12 @@ class _PreviewRuntimeCanvas:
103
103
  scroll_direction: ScrollDirection
104
104
  size: float
105
105
 
106
+ def update(self, scroll_direction: ScrollDirection | None = None, size: float | None = None):
107
+ if scroll_direction is not None:
108
+ self.scroll_direction = scroll_direction
109
+ if size is not None:
110
+ self.size = size
111
+
106
112
 
107
113
  class RuntimeUiConfig(Record):
108
114
  scale: float
@@ -253,36 +259,57 @@ class _TutorialRuntimeUi:
253
259
 
254
260
 
255
261
  class Touch(Record):
262
+ """Data of a touch event."""
263
+
256
264
  id: int
265
+ """The unique identifier of the touch."""
266
+
257
267
  started: bool
268
+ """Whether the touch has started this frame."""
269
+
258
270
  ended: bool
271
+ """Whether the touch has ended this frame."""
272
+
259
273
  time: float
274
+ """The time of the touch event.
275
+
276
+ May remain constant while there is no movement.
277
+ """
278
+
260
279
  start_time: float
280
+ """The time the touch started."""
281
+
261
282
  position: Vec2
283
+ """The current position of the touch."""
284
+
262
285
  start_position: Vec2
286
+ """The position the touch started."""
287
+
263
288
  delta: Vec2
289
+ """The change in position of the touch."""
290
+
264
291
  velocity: Vec2
292
+ """The velocity of the touch."""
293
+
265
294
  speed: float
295
+ """The speed of the touch's movement."""
296
+
266
297
  angle: float
298
+ """The angle of the touch's movement."""
267
299
 
268
300
  @property
269
- def total_time(self) -> float:
270
- return self.time - self.start_time
301
+ def prev_position(self) -> Vec2:
302
+ """The previous position of the touch."""
303
+ return self.position - self.delta
271
304
 
272
305
  @property
273
306
  def total_delta(self) -> Vec2:
307
+ """The total change in position of the touch."""
274
308
  return self.position - self.start_position
275
309
 
276
- @property
277
- def total_velocity(self) -> Vec2:
278
- return self.total_delta / self.total_time if self.total_time > 0 else Vec2(0, 0)
279
-
280
- @property
281
- def total_speed(self) -> float:
282
- return self.total_velocity.magnitude
283
-
284
310
  @property
285
311
  def total_angle(self) -> float:
312
+ """The total angle of the touch's movement."""
286
313
  return self.total_delta.angle
287
314
 
288
315
 
@@ -449,6 +476,30 @@ def is_debug() -> bool:
449
476
  return False
450
477
 
451
478
 
479
+ @meta_fn
480
+ def is_play() -> bool:
481
+ """Check if the game is running in play mode."""
482
+ return ctx() and ctx().global_state.mode == Mode.PLAY
483
+
484
+
485
+ @meta_fn
486
+ def is_preview() -> bool:
487
+ """Check if the game is running in preview mode."""
488
+ return ctx() and ctx().global_state.mode == Mode.PREVIEW
489
+
490
+
491
+ @meta_fn
492
+ def is_watch() -> bool:
493
+ """Check if the game is running in watch mode."""
494
+ return ctx() and ctx().global_state.mode == Mode.WATCH
495
+
496
+
497
+ @meta_fn
498
+ def is_tutorial() -> bool:
499
+ """Check if the game is running in tutorial mode."""
500
+ return ctx() and ctx().global_state.mode == Mode.TUTORIAL
501
+
502
+
452
503
  @meta_fn
453
504
  def aspect_ratio() -> float:
454
505
  """Get the aspect ratio of the game."""
sonolus/script/sprite.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from dataclasses import dataclass
2
+ from enum import StrEnum
2
3
  from typing import Annotated, Any, NewType, dataclass_transform, get_origin
3
4
 
4
5
  from sonolus.backend.ops import Op
@@ -269,6 +270,19 @@ def sprite(name: str) -> Any:
269
270
  type Skin = NewType("Skin", Any)
270
271
 
271
272
 
273
+ class RenderMode(StrEnum):
274
+ """Render mode for sprites."""
275
+
276
+ DEFAULT = "default"
277
+ """Use the user's preferred render mode."""
278
+
279
+ STANDARD = "standard"
280
+ """Use the standard render mode with bilinear interpolation of textures."""
281
+
282
+ LIGHTWEIGHT = "lightweight"
283
+ """Use the lightweight render mode with projective interpolation of textures."""
284
+
285
+
272
286
  @dataclass_transform()
273
287
  def skin[T](cls: type[T]) -> T | Skin:
274
288
  """Decorator to define a skin.
@@ -277,6 +291,8 @@ def skin[T](cls: type[T]) -> T | Skin:
277
291
  ```python
278
292
  @skin
279
293
  class Skin:
294
+ render_mode: RenderMode
295
+
280
296
  note: StandardSprite.NOTE_HEAD_RED
281
297
  other: Sprite = skin_sprite("other")
282
298
  ```
@@ -285,7 +301,7 @@ def skin[T](cls: type[T]) -> T | Skin:
285
301
  raise ValueError("Skin class must not inherit from any class (except object)")
286
302
  instance = cls()
287
303
  names = []
288
- for i, (name, annotation) in enumerate(get_field_specifiers(cls).items()):
304
+ for i, (name, annotation) in enumerate(get_field_specifiers(cls, skip={"render_mode"}).items()):
289
305
  if get_origin(annotation) is not Annotated:
290
306
  raise TypeError(f"Invalid annotation for skin: {annotation}")
291
307
  annotation_type = annotation.__args__[0]
@@ -298,6 +314,7 @@ def skin[T](cls: type[T]) -> T | Skin:
298
314
  names.append(sprite_name)
299
315
  setattr(instance, name, Sprite(i))
300
316
  instance._sprites_ = names
317
+ instance.render_mode = RenderMode(getattr(instance, "render_mode", RenderMode.DEFAULT))
301
318
  instance._is_comptime_value_ = True
302
319
  return instance
303
320
 
sonolus/script/ui.py CHANGED
@@ -120,8 +120,8 @@ class UiAnimation:
120
120
  alpha: The animation applied to alpha.
121
121
  """
122
122
 
123
- scale: UiAnimationTween = field(default_factory=lambda: UiAnimationTween(1, 1, 0, "none"))
124
- alpha: UiAnimationTween = field(default_factory=lambda: UiAnimationTween(1, 0, 0.2, "outCubic"))
123
+ scale: UiAnimationTween
124
+ alpha: UiAnimationTween
125
125
 
126
126
  def to_dict(self):
127
127
  return {
@@ -183,7 +183,11 @@ class UiConfig:
183
183
  progress_visibility: UiVisibility = field(default_factory=UiVisibility)
184
184
  tutorial_navigation_visibility: UiVisibility = field(default_factory=UiVisibility)
185
185
  tutorial_instruction_visibility: UiVisibility = field(default_factory=UiVisibility)
186
- judgment_animation: UiAnimation = field(default_factory=UiAnimation)
186
+ judgment_animation: UiAnimation = field(
187
+ default_factory=lambda: UiAnimation(
188
+ scale=UiAnimationTween(0, 1, 0.1, EaseType.OUT_CUBIC), alpha=UiAnimationTween(1, 0, 0.3, EaseType.NONE)
189
+ )
190
+ )
187
191
  combo_animation: UiAnimation = field(
188
192
  default_factory=lambda: UiAnimation(
189
193
  scale=UiAnimationTween(1.2, 1, 0.2, EaseType.IN_CUBIC), alpha=UiAnimationTween(1, 1, 0, EaseType.NONE)
sonolus/script/values.py CHANGED
@@ -19,11 +19,7 @@ def alloc[T](type_: type[T]) -> T:
19
19
  @meta_fn
20
20
  def zeros[T](type_: type[T]) -> T:
21
21
  """Make a new instance of the given type initialized with zeros."""
22
- type_ = validate_concrete_type(type_)
23
- if ctx():
24
- return copy(type_._from_list_([0] * type_._size_()))
25
- else:
26
- return type_._from_list_([0] * type_._size_())._as_py_()
22
+ return validate_concrete_type(type_)._zero_()
27
23
 
28
24
 
29
25
  @meta_fn
@@ -34,3 +30,10 @@ def copy[T](value: T) -> T:
34
30
  return value._copy_()
35
31
  else:
36
32
  return value._copy_()._as_py_()
33
+
34
+
35
+ def swap[T](a: T, b: T):
36
+ """Swap the values of the given variables."""
37
+ temp = copy(a)
38
+ a @= b
39
+ b @= temp
sonolus/script/vec.py CHANGED
@@ -128,6 +128,25 @@ class Vec2(Record):
128
128
  """
129
129
  return (self - pivot).rotate(angle) + pivot
130
130
 
131
+ def normalize(self) -> Self:
132
+ """Normalize the vector (set the magnitude to 1) and return a new vector.
133
+
134
+ Returns:
135
+ A new vector with magnitude 1.
136
+ """
137
+ magnitude = self.magnitude
138
+ return Vec2(x=self.x / magnitude, y=self.y / magnitude)
139
+
140
+ def orthogonal(self) -> Self:
141
+ """Return a vector orthogonal to this vector.
142
+
143
+ The orthogonal vector is rotated 90 degrees counter-clockwise from this vector.
144
+
145
+ Returns:
146
+ A new vector orthogonal to this vector.
147
+ """
148
+ return Vec2(x=-self.y, y=self.x)
149
+
131
150
  @property
132
151
  def tuple(self) -> tuple[float, float]:
133
152
  """Return the vector as a tuple (x, y).
@@ -173,6 +192,15 @@ class Vec2(Record):
173
192
  return Vec2(x=self.x * x, y=self.y * y)
174
193
  case Num(factor):
175
194
  return Vec2(x=self.x * factor, y=self.y * factor)
195
+ case _:
196
+ return NotImplemented
197
+
198
+ def __rmul__(self, other):
199
+ match other:
200
+ case Num(factor):
201
+ return Vec2(x=self.x * factor, y=self.y * factor)
202
+ case _:
203
+ return NotImplemented
176
204
 
177
205
  def __truediv__(self, other: Self | float) -> Self:
178
206
  """Divide this vector by another vector or a scalar and return a new vector.
@@ -1,7 +1,8 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: sonolus.py
3
- Version: 0.1.8
3
+ Version: 0.2.0
4
4
  Summary: Sonolus engine development in Python
5
+ License-File: LICENSE
5
6
  Requires-Python: >=3.12
6
7
  Description-Content-Type: text/markdown
7
8
 
@@ -0,0 +1,90 @@
1
+ sonolus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ sonolus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ sonolus/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ sonolus/backend/blocks.py,sha256=3peyb9eYBy0s53xNVJ1KmK4IgoyVkkwG-lqDQ_VZTHc,18531
5
+ sonolus/backend/excepthook.py,sha256=pqI9gtPBh0mlTgMNqul8bEVO1ARzKb8pNE9EN_CyDpk,994
6
+ sonolus/backend/finalize.py,sha256=vNUGLCUDxNqXGxweNRA1NpRvtij7Tks9to1V_JTs7Jo,4020
7
+ sonolus/backend/interpret.py,sha256=B0jqlLmEGoyO2mxpcvwRwV17Tq_gOE9wLNt26Q5QOfs,14306
8
+ sonolus/backend/ir.py,sha256=TCDLMvlX2S8emFDQwFVeD2OUC4fnhbrMObgYtoa_7PQ,2845
9
+ sonolus/backend/mode.py,sha256=NkcPZJm8dn83LX35uP24MtQOCnfRDFZ280dHeEEfauE,613
10
+ sonolus/backend/node.py,sha256=H8qgnNyIseR-DhfgtcbDX03SUmhAJSSrYAlUEJTkkUo,999
11
+ sonolus/backend/ops.py,sha256=ekkHSdgRubIYLSYFk0wTUuBvyf3TKdApM4AyR_koTQ8,10122
12
+ sonolus/backend/place.py,sha256=jABvLNNE-2pklTcb9WnyfHK8c-tYxn0ObsoLp5LYd5I,4703
13
+ sonolus/backend/utils.py,sha256=9-mmCUwGlNdjp51jKrNBN2dGxCAXVV2PdJn031kaXHM,1717
14
+ sonolus/backend/visitor.py,sha256=GvAEx8D3_YijTMUYBmir0IvDPAEpK1ObAuQOAcAMKm0,48157
15
+ sonolus/backend/optimize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ sonolus/backend/optimize/allocate.py,sha256=LCqxvT8YsVGTaVAu58fb6lrrytVLWx1LNbcOfx8CqL8,5671
17
+ sonolus/backend/optimize/constant_evaluation.py,sha256=ozYB__haE2A_L2NBh2H3IT__Z65FBBtbjh6BJfQRC_A,15988
18
+ sonolus/backend/optimize/copy_coalesce.py,sha256=4vUe-y2w8sGyrguSlp8O_p0uy9rEUu5M-smI0F5UMQw,4404
19
+ sonolus/backend/optimize/dead_code.py,sha256=qYmUqBmAp-O5mUpNusOoMEJVkbc9YIHx6Ynrg6dyNGY,8077
20
+ sonolus/backend/optimize/dominance.py,sha256=oTFUqN8twrw6lTzqr1nlYs-Gk1NzIa-4qGdEQvDGzlM,3217
21
+ sonolus/backend/optimize/flow.py,sha256=mMf5Um2uxwF65nw13UiIv7dFMHZZHnyWv2WaOVnGw2c,4266
22
+ sonolus/backend/optimize/inlining.py,sha256=jwTiuHivSq9bB7FfVbD9Wd_Ztaz8ml_5CRnikr2d6yU,5719
23
+ sonolus/backend/optimize/liveness.py,sha256=c0ejVf1LNcYBlByf3rxkNs18IoXmiOdCFwEk3Afv8DE,7121
24
+ sonolus/backend/optimize/optimize.py,sha256=It_z8fAaTsG8bRNrvR5mQzVjmwZT5I1whBvy4F-Xoos,1473
25
+ sonolus/backend/optimize/passes.py,sha256=BQy-BovGu234Y12c-vpBmTaNNl9oeW4qZ8A3q5y5nLs,1684
26
+ sonolus/backend/optimize/simplify.py,sha256=Tz4RftjH5TpIxoIOwiZuLchsrwzI9GaS_exdjAW6HKk,7927
27
+ sonolus/backend/optimize/ssa.py,sha256=D3CQm3s3gcuU0_k_0pXVrwirm4xjAZsX6corrTDS1Co,9013
28
+ sonolus/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ sonolus/build/cli.py,sha256=zWkiY2frHHIk3nqP8XrzV1ez1zU67deNZ7WeFR5SfVo,8801
30
+ sonolus/build/collection.py,sha256=kOVnpQC_KHAsyTM4nAplSh6QE16CgO-H6PP1GItWm78,12187
31
+ sonolus/build/compile.py,sha256=nWtQRao_k-ChJhjmYFpPMRlPgxFI0t9wtMWSRHQcnbQ,5586
32
+ sonolus/build/engine.py,sha256=AYzJHRcYaR-PidR9eG6Tbr4Xz5-spHTOp4S9F4nm-UY,11178
33
+ sonolus/build/level.py,sha256=AjvK4725nqDcg7oGn5kWocBdG-AcirXpku74T7c2epA,673
34
+ sonolus/build/node.py,sha256=gnX71RYDUOK_gYMpinQi-bLWO4csqcfiG5gFmhxzSec,1330
35
+ sonolus/build/project.py,sha256=DhNqgHnm73qKUOhrg1JPlWEL0Vg7VxcGUbNokpMWzVE,6315
36
+ sonolus/script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ sonolus/script/archetype.py,sha256=UbIAn6xmCOUpp6Aa8Y_Bd85LhWglinG6o-TE0sRdLPw,38716
38
+ sonolus/script/array.py,sha256=mUOY0cbjbSBssQNwmJ4EbySmyUGg2I-lnLmqDKu8Vh8,9798
39
+ sonolus/script/array_like.py,sha256=OVOLMadS-Jj941S-EgoxlFPdaQLT6ZrHzaMnKtB6PfU,8346
40
+ sonolus/script/bucket.py,sha256=oaaB7OXtBWzr8sLzPOpm8-GMhs7FzEhYrI1uVcM0DHM,7453
41
+ sonolus/script/containers.py,sha256=tf0-UUSq8NH6k9jIKq6qgXRxanFQ0f5olH6uHghTynk,13171
42
+ sonolus/script/debug.py,sha256=-rFPOgtmGLjfBsCPzPKObb4t-x5VN3QYb2BznZGDMgI,2457
43
+ sonolus/script/easing.py,sha256=7zaDKIfM_whUpb4FBz1DAF4NNG2vk_nDjl8kL2Y90aU,11396
44
+ sonolus/script/effect.py,sha256=V9bJvMzs1O4C1PjTOKgsAXov-l4AnDb2h38-DzmeWpI,5838
45
+ sonolus/script/engine.py,sha256=_5ZYPT4irTePjki16sFI7A8dzdm3kXAS7tvrp_ocG7Y,10661
46
+ sonolus/script/globals.py,sha256=Z8RfLkgDuXPIKiq-aOqblP0s__ALGmvcKdlyWZH21EM,9166
47
+ sonolus/script/instruction.py,sha256=PNfxC1dhT_hB0BxhDV3KXMn_kKxfI0t1iZmg8m6ddMU,6725
48
+ sonolus/script/interval.py,sha256=H-xedXbiLia-JU-Tafxq2rSoQ7pBOAeNOnyovrQyp14,9462
49
+ sonolus/script/iterator.py,sha256=OHnIOKRchzVCMaN33Tubo6EzqV61ZYUxDWIJ2S5G6iQ,4590
50
+ sonolus/script/level.py,sha256=wR23xk-NOcW_JMRb3R12sqIXCLSZL-7cM3y7IpMF1J0,6333
51
+ sonolus/script/metadata.py,sha256=ttRK27eojHf3So50KQJ-8yj3udZoN1bli5iD-knaeLw,753
52
+ sonolus/script/num.py,sha256=5PmfugfKtQ8Mobt9Ul_agv4XyqZr_EtNNPYMQcL14xQ,14178
53
+ sonolus/script/options.py,sha256=AljmjEyWH_Aquv_Jj-sx3GA3l5ZoOSl9acDv19FMHNA,7576
54
+ sonolus/script/particle.py,sha256=K06ArT9tstRNdbuGIviDmDDWcK3-ieA53LHg0Xvizow,8304
55
+ sonolus/script/pointer.py,sha256=Rlu3fW4odvJzZRFNwk6pGA8JLrp4J-PlONBOg3mSA8A,1203
56
+ sonolus/script/printing.py,sha256=mNYu9QWiacBBGZrnePZQMVwbbguoelUps9GiOK_aVRU,2096
57
+ sonolus/script/project.py,sha256=jLndgGJHdkqFYe-lDl_IzTjQ4gOSuy80en8WoSWXnB8,3340
58
+ sonolus/script/quad.py,sha256=e2kXKSp9K46Q9qstLsGLFPxaW7Z2kfVfignA8Ka2-Pw,8375
59
+ sonolus/script/record.py,sha256=jHt2RjDD7FZ_eWAukEOZePu9VJaH-rwRqHdoEJpxCNY,11339
60
+ sonolus/script/runtime.py,sha256=xmf4HLShrcAqQ8qK3N-hGyVzEolgp34j_JSJH9orwIY,19930
61
+ sonolus/script/sprite.py,sha256=CMcRAZ2hejXnaBmY2_n1_rj6hGOgPP5zEW-BpyaEVOY,16256
62
+ sonolus/script/text.py,sha256=IsoINZJXefjReYDjJFwVaFsUCdgeQvPBDeywljM2dWo,13025
63
+ sonolus/script/timing.py,sha256=ZR0ypV2PIoDCMHHGOMfCeezStCsBQdzomdqaz5VKex0,2981
64
+ sonolus/script/transform.py,sha256=hH6KSRQC8vV-Z10CRCrGewMYqQwUMH3mQIEmniuC2Zw,10760
65
+ sonolus/script/ui.py,sha256=R5J1QSvul-cFCUCjuEHbnzp4-CA2I8u608_wfJRr80s,7277
66
+ sonolus/script/values.py,sha256=GWl_gmNzwEBwm5fqj2LErfwOz8iWTJEAoFyOUnkBRS0,1028
67
+ sonolus/script/vec.py,sha256=4ntfJ96zxKR-nVZluUgHd-Ud4vNfButfiv7EsroZxfE,7002
68
+ sonolus/script/internal/__init__.py,sha256=T6rzLoiOUaiSQtaHMZ88SNO-ijSjSSv33TKtUwu-Ms8,136
69
+ sonolus/script/internal/builtin_impls.py,sha256=w9QqxJQ2YR5pVy820qWmAy0utbsW4hcSzMvA_yNgsvg,8186
70
+ sonolus/script/internal/callbacks.py,sha256=vWzJG8uiJoEtsNnbeZPqOHogCwoLpz2D1MnHY2wVV8s,2801
71
+ sonolus/script/internal/constant.py,sha256=4kJpLek7PcdB0aTL8ygV4GYDZSDuHoWHljaIZpTtRrY,3842
72
+ sonolus/script/internal/context.py,sha256=xW7yFWr13yf77Uk4C_F7v9Kp4ZP1o30uZuBkvK1KyLA,14157
73
+ sonolus/script/internal/descriptor.py,sha256=XRFey-EjiAm_--KsNl-8N0Mi_iyQwlPh68gDp0pKf3E,392
74
+ sonolus/script/internal/dict_impl.py,sha256=alu_wKGSk1kZajNf64qbe7t71shEzD4N5xNIATH8Swo,1885
75
+ sonolus/script/internal/error.py,sha256=ZNnsvQVQAnFKzcvsm6-sste2lo-tP5pPI8sD7XlAZWc,490
76
+ sonolus/script/internal/generic.py,sha256=YU1hUJoBcGc0OSrFStK5JI6CikOwSmd_IR20pCuT82k,7310
77
+ sonolus/script/internal/impl.py,sha256=HKQVoHknw5t43Wmj_G1vFjGSmnFpOj1FUYnhbUM3rHc,2969
78
+ sonolus/script/internal/introspection.py,sha256=SL2zaYjid0kkcj6ZbFLIwhgh7WKZBaAHhlbSJGr6PWs,974
79
+ sonolus/script/internal/math_impls.py,sha256=Xk7tLMnV2npzPJWtHlspONQHt09Gh2YLdHhAjx4jkdE,2320
80
+ sonolus/script/internal/native.py,sha256=XKlNnWSJ-lxbwVGWhGj_CSSoWsVN18imqT5sAsDJT1w,1551
81
+ sonolus/script/internal/random.py,sha256=6Ku5edRcDUh7rtqEEYCJz0BQavw69RALsVHS25z50pI,1695
82
+ sonolus/script/internal/range.py,sha256=lrTanQFHU7RuQxSSPwDdoC30Y8FnHGxcP1Ahditu3zU,2297
83
+ sonolus/script/internal/transient.py,sha256=c_Jg4yJJ_xvxMGNx9XECHCdiDlMhjfClf5ntzrPr6uc,1643
84
+ sonolus/script/internal/tuple_impl.py,sha256=vjXmScLVdeTkDn3t9fgIRqtW31iwngnaP2rmA6nlsLw,3431
85
+ sonolus/script/internal/value.py,sha256=hEq0YhXMj4uaGQA-r_W8PDOp_MY97nW30JKlpj-aZLM,4496
86
+ sonolus_py-0.2.0.dist-info/METADATA,sha256=LOjlu1hCu6r3VgzL7DbplSaBsjabZ2GWzsDsilNdSFc,238
87
+ sonolus_py-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
88
+ sonolus_py-0.2.0.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
89
+ sonolus_py-0.2.0.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
90
+ sonolus_py-0.2.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.26.3
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any