sonolus.py 0.4.2__py3-none-any.whl → 0.5.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.

@@ -124,6 +124,8 @@ class SparseConditionalConstantPropagation(CompilerPass):
124
124
  new_values.add(arg)
125
125
  if len(new_values) == 1:
126
126
  new_value = next(iter(new_values))
127
+ elif len(new_values) > 100:
128
+ new_value = NAC # Give up to save performance
127
129
  else:
128
130
  new_value = frozenset(new_values)
129
131
  else:
@@ -13,7 +13,7 @@ from typing import Any, Never
13
13
  from sonolus.backend.excepthook import install_excepthook
14
14
  from sonolus.backend.utils import get_function, scan_writes
15
15
  from sonolus.script.debug import assert_true
16
- from sonolus.script.internal.builtin_impls import BUILTIN_IMPLS, _bool, _float, _int, _len
16
+ from sonolus.script.internal.builtin_impls import BUILTIN_IMPLS, _bool, _float, _int, _len, _super
17
17
  from sonolus.script.internal.constant import ConstantValue
18
18
  from sonolus.script.internal.context import Context, EmptyBinding, Scope, ValueBinding, ctx, set_ctx, using_ctx
19
19
  from sonolus.script.internal.descriptor import SonolusDescriptor
@@ -1113,6 +1113,19 @@ class Visitor(ast.NodeVisitor):
1113
1113
  kwargs.update(value.value)
1114
1114
  else:
1115
1115
  raise ValueError("Starred keyword arguments (**kwargs) must be dictionaries")
1116
+ if fn._is_py_() and fn._as_py_() is _super and not args and not kwargs and "__class__" in self.globals:
1117
+ class_value = self.get_name("__class__")
1118
+ first_param_name = next(
1119
+ (
1120
+ name
1121
+ for name, param in self.bound_args.signature.parameters.items()
1122
+ if param.kind in {inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD}
1123
+ ),
1124
+ None,
1125
+ )
1126
+ if first_param_name is not None:
1127
+ first_param_value = self.get_name(first_param_name)
1128
+ args = (validate_value(class_value), validate_value(first_param_value))
1116
1129
  return self.handle_call(node, fn, *args, **kwargs)
1117
1130
 
1118
1131
  def visit_FormattedValue(self, node):
@@ -1136,23 +1149,26 @@ class Visitor(ast.NodeVisitor):
1136
1149
  raise NotImplementedError("Starred expressions are not supported")
1137
1150
 
1138
1151
  def visit_Name(self, node):
1139
- if node.id in self.used_parent_binding_values:
1140
- return self.used_parent_binding_values[node.id]
1152
+ return self.get_name(node.id)
1153
+
1154
+ def get_name(self, name: str):
1155
+ if name in self.used_parent_binding_values:
1156
+ return self.used_parent_binding_values[name]
1141
1157
  self.active_ctx = ctx()
1142
1158
  v = self
1143
1159
  while v:
1144
- if not isinstance(v.active_ctx.scope.get_binding(node.id), EmptyBinding):
1145
- result = v.active_ctx.scope.get_value(node.id)
1160
+ if not isinstance(v.active_ctx.scope.get_binding(name), EmptyBinding):
1161
+ result = v.active_ctx.scope.get_value(name)
1146
1162
  if v is not self:
1147
- self.used_parent_binding_values[node.id] = result
1163
+ self.used_parent_binding_values[name] = result
1148
1164
  return result
1149
1165
  v = v.parent
1150
- if node.id in self.globals:
1151
- value = self.globals[node.id]
1166
+ if name in self.globals:
1167
+ value = self.globals[name]
1152
1168
  if value is ctx:
1153
1169
  raise ValueError("Unexpected use of ctx in non meta-function")
1154
1170
  return validate_value(BUILTIN_IMPLS.get(id(value), value))
1155
- raise NameError(f"Name {node.id} is not defined")
1171
+ raise NameError(f"Name {name} is not defined")
1156
1172
 
1157
1173
  def visit_List(self, node):
1158
1174
  raise NotImplementedError("List literals are not supported")
sonolus/build/compile.py CHANGED
@@ -74,10 +74,12 @@ def compile_mode(
74
74
  return cb_info.name, node_index
75
75
 
76
76
  all_futures = {}
77
- archetype_entries = []
77
+ base_archetype_entries = {}
78
78
 
79
79
  if archetypes is not None:
80
- for archetype in archetypes:
80
+ base_archetypes = {getattr(a, "_derived_base_", a) for a in archetypes}
81
+
82
+ for archetype in base_archetypes:
81
83
  archetype._init_fields()
82
84
 
83
85
  archetype_data = {
@@ -109,7 +111,7 @@ def compile_mode(
109
111
  cb_name, result_data = process_callback(cb_info, cb, archetype)
110
112
  archetype_data[cb_name] = result_data
111
113
 
112
- archetype_entries.append(archetype_data)
114
+ base_archetype_entries[archetype] = archetype_data
113
115
 
114
116
  if global_callbacks is not None and thread_pool is not None:
115
117
  for cb_info, cb in global_callbacks:
@@ -129,7 +131,10 @@ def compile_mode(
129
131
  results[cb_name] = node_index
130
132
 
131
133
  if archetypes is not None:
132
- results["archetypes"] = archetype_entries
134
+ results["archetypes"] = [
135
+ {**base_archetype_entries[getattr(a, "_derived_base_", a)], "name": a.name, "hasInput": a.is_scored}
136
+ for a in archetypes
137
+ ]
133
138
 
134
139
  results["nodes"] = nodes.get()
135
140
  return results
@@ -183,6 +183,68 @@ class _ArchetypeField(SonolusDescriptor):
183
183
  target._copy_from_(value)
184
184
 
185
185
 
186
+ class _NameDescriptor(SonolusDescriptor):
187
+ def __init__(self, name: str):
188
+ self.name = name
189
+
190
+ def __get__(self, instance, owner):
191
+ if instance is None:
192
+ return self.name
193
+ elif ctx():
194
+ raise RuntimeError("Cannot access archetype name in from self in a callback, use ArchetypeClass.name")
195
+ else:
196
+ return self.name
197
+
198
+ def __set__(self, instance, value):
199
+ raise AttributeError("Archetype name is read-only and cannot be set")
200
+
201
+
202
+ class _IsScoredDescriptor(SonolusDescriptor):
203
+ def __init__(self, value: bool):
204
+ self.value = value
205
+
206
+ def __get__(self, instance, owner):
207
+ if instance is None:
208
+ return self.value
209
+ elif ctx():
210
+ raise RuntimeError("Cannot access is_scored from self in a callback, use ArchetypeClass.is_scored")
211
+ else:
212
+ return self.value
213
+
214
+ def __set__(self, instance, value):
215
+ raise AttributeError("is_scored is read-only and cannot be set")
216
+
217
+
218
+ class _IdDescriptor(SonolusDescriptor):
219
+ def __get__(self, instance, owner):
220
+ if not ctx():
221
+ raise RuntimeError("Archetype id is only available during compilation")
222
+ if instance is None:
223
+ result = ctx().global_state.archetypes.get(owner)
224
+ if result is None:
225
+ raise RuntimeError("Archetype is not registered")
226
+ return result
227
+ else:
228
+ return instance._info.archetype_id
229
+
230
+ def __set__(self, instance, value):
231
+ raise AttributeError("Archetype id is read-only and cannot be set")
232
+
233
+
234
+ class _KeyDescriptor(SonolusDescriptor):
235
+ def __init__(self, value: int | float):
236
+ self.value = value
237
+
238
+ def __get__(self, instance, owner):
239
+ if instance is not None and ctx():
240
+ return ctx().global_state.keys[instance.id]
241
+ else:
242
+ return self.value
243
+
244
+ def __set__(self, instance, value):
245
+ raise AttributeError("Archetype key is read-only and cannot be set")
246
+
247
+
186
248
  def imported(*, name: str | None = None) -> Any:
187
249
  """Declare a field as imported.
188
250
 
@@ -387,6 +449,28 @@ class _BaseArchetype:
387
449
 
388
450
  _data_: _ArchetypeData
389
451
 
452
+ id: int = 0
453
+ """The id of the archetype or entity.
454
+
455
+ If accessed on an entity, always returns the runtime archetype id of the entity, even if it doesn't match the type
456
+ that was used to access it.
457
+
458
+ E.g. if an entity of archetype `A` is accessed via [`EntityRef[B]`][sonolus.script.archetype.EntityRef], the id will
459
+ still be the id of `A`.
460
+ """
461
+
462
+ key: int = -1
463
+ """An optional key for the archetype.
464
+
465
+ May be useful to identify an archetype in an inheritance hierarchy without needing to check id.
466
+
467
+ If accessed on an entity, always returns the runtime key of the entity, even if it doesn't match the type
468
+ that was used to access it.
469
+
470
+ E.g. if an entity of archetype `A` is accessed via [`EntityRef[B]`][sonolus.script.archetype.EntityRef], the key
471
+ will still be the key of `A`.
472
+ """
473
+
390
474
  name: ClassVar[str | None] = None
391
475
  """The name of the archetype.
392
476
 
@@ -433,17 +517,7 @@ class _BaseArchetype:
433
517
  def is_at(cls, index: int) -> bool:
434
518
  if not ctx():
435
519
  raise RuntimeError("is_at is only available during compilation")
436
- return entity_info_at(index).archetype_id == cls.id()
437
-
438
- @classmethod
439
- @meta_fn
440
- def id(cls) -> int:
441
- if not ctx():
442
- raise RuntimeError("Archetype id is only available during compilation")
443
- result = ctx().global_state.archetypes.get(cls)
444
- if result is None:
445
- raise RuntimeError("Archetype is not registered")
446
- return result
520
+ return entity_info_at(index).archetype_id == cls.id
447
521
 
448
522
  @classmethod
449
523
  @meta_fn
@@ -465,7 +539,7 @@ class _BaseArchetype:
465
539
  cls._init_fields()
466
540
  if not ctx():
467
541
  raise RuntimeError("Spawn is only allowed within a callback")
468
- archetype_id = cls.id()
542
+ archetype_id = cls.id
469
543
  bound = cls._spawn_signature_.bind_partial(**kwargs)
470
544
  bound.apply_defaults()
471
545
  data = []
@@ -497,7 +571,7 @@ class _BaseArchetype:
497
571
  return entries
498
572
 
499
573
  def __init_subclass__(cls, **kwargs):
500
- if cls.__module__ == _BaseArchetype.__module__:
574
+ if cls.__module__ == _BaseArchetype.__module__ and not getattr(cls, "_is_derived_", False):
501
575
  if cls._supported_callbacks_ is None:
502
576
  raise TypeError("Cannot directly subclass Archetype, use the Archetype subclass for your mode")
503
577
  cls._default_callbacks_ = {getattr(cls, cb_info.py_name) for cb_info in cls._supported_callbacks_.values()}
@@ -511,6 +585,11 @@ class _BaseArchetype:
511
585
  continue
512
586
  cls._callbacks_.append(cb)
513
587
  cls._field_init_done = False
588
+ cls.id = _IdDescriptor()
589
+ cls._key_ = cls.key
590
+ cls.key = _KeyDescriptor(cls.key)
591
+ cls.name = _NameDescriptor(cls.name)
592
+ cls.is_scored = _IsScoredDescriptor(cls.is_scored)
514
593
 
515
594
  @classmethod
516
595
  def _init_fields(cls):
@@ -521,7 +600,19 @@ class _BaseArchetype:
521
600
  if hasattr(mro_entry, "_field_init_done"):
522
601
  mro_entry._init_fields()
523
602
  field_specifiers = get_field_specifiers(
524
- cls, skip={"name", "is_scored", "_callbacks_", "_field_init_done"}
603
+ cls,
604
+ skip={
605
+ "id",
606
+ "key",
607
+ "name",
608
+ "is_scored",
609
+ "_key_",
610
+ "_derived_base_",
611
+ "_is_derived_",
612
+ "_default_callbacks_",
613
+ "_callbacks_",
614
+ "_field_init_done",
615
+ },
525
616
  ).items()
526
617
  if not hasattr(cls, "_imported_fields_"):
527
618
  cls._imported_fields_ = {}
@@ -656,6 +747,32 @@ class _BaseArchetype:
656
747
  def _post_init_fields(cls):
657
748
  pass
658
749
 
750
+ @classmethod
751
+ def derive[T](cls: type[T], name: str, is_scored: bool, key: int | float | None = None) -> type[T]:
752
+ """Derive a new archetype class from this archetype.
753
+
754
+ This is used to create a new archetype with the same fields and callbacks, but with a different name and
755
+ whether it is scored.
756
+
757
+ Args:
758
+ name: The name of the new archetype.
759
+ is_scored: Whether the new archetype is scored.
760
+ key: A key that can be accessed via the `key` property of the new archetype.
761
+
762
+ Returns:
763
+ A new archetype class with the same fields and callbacks as this archetype, but with the given name and
764
+ whether it is scored.
765
+ """
766
+ if getattr(cls, "_is_derived_", False):
767
+ raise RuntimeError("Cannot derive from a derived archetype")
768
+ cls_dict = {"name": name, "is_scored": is_scored, "_is_derived_": True, "_derived_base_": cls}
769
+ if key is not None:
770
+ if not isinstance(key, (int, float)):
771
+ raise TypeError(f"Key must be an int or float, got {type(key)}")
772
+ cls_dict["key"] = key
773
+ new_cls = type(name, (cls,), cls_dict)
774
+ return new_cls
775
+
659
776
 
660
777
  class PlayArchetype(_BaseArchetype):
661
778
  """Base class for play mode archetypes.
@@ -807,7 +924,7 @@ class PlayArchetype(_BaseArchetype):
807
924
  raise RuntimeError("Calling life is only allowed within a callback")
808
925
  match self._data_:
809
926
  case _ArchetypeSelfData() | _ArchetypeReferenceData():
810
- return _deref(ctx().blocks.ArchetypeLife, self.id() * ArchetypeLife._size_(), ArchetypeLife)
927
+ return _deref(ctx().blocks.ArchetypeLife, self.id * ArchetypeLife._size_(), ArchetypeLife)
811
928
  case _:
812
929
  raise RuntimeError("Life is not available in level data")
813
930
 
@@ -920,7 +1037,7 @@ class WatchArchetype(_BaseArchetype):
920
1037
  raise RuntimeError("Calling life is only allowed within a callback")
921
1038
  match self._data_:
922
1039
  case _ArchetypeSelfData() | _ArchetypeReferenceData():
923
- return _deref(ctx().blocks.ArchetypeLife, self.id() * ArchetypeLife._size_(), ArchetypeLife)
1040
+ return _deref(ctx().blocks.ArchetypeLife, self.id * ArchetypeLife._size_(), ArchetypeLife)
924
1041
  case _:
925
1042
  raise RuntimeError("Life is not available in level data")
926
1043
 
@@ -1032,7 +1149,7 @@ def archetype_life_of(archetype: type[_BaseArchetype] | _BaseArchetype) -> Arche
1032
1149
  raise RuntimeError("Calling archetype_life_of is only allowed within a callback")
1033
1150
  match ctx().global_state.mode:
1034
1151
  case Mode.PLAY | Mode.WATCH:
1035
- return _deref(ctx().blocks.ArchetypeLife, archetype.id() * ArchetypeLife._size_(), ArchetypeLife)
1152
+ return _deref(ctx().blocks.ArchetypeLife, archetype.id * ArchetypeLife._size_(), ArchetypeLife)
1036
1153
  case _:
1037
1154
  raise RuntimeError(f"Archetype life is not available in mode '{ctx().global_state.mode}'")
1038
1155
 
sonolus/script/bucket.py CHANGED
@@ -103,9 +103,16 @@ class Judgment(IntEnum):
103
103
  """The judgment of a hit."""
104
104
 
105
105
  MISS = 0
106
+ """A miss. Breaks combo."""
107
+
106
108
  PERFECT = 1
109
+ """A perfect hit."""
110
+
107
111
  GREAT = 2
112
+ """A great hit."""
113
+
108
114
  GOOD = 3
115
+ """A good hit. Breaks combo."""
109
116
 
110
117
 
111
118
  @native_function(Op.Judge)
@@ -377,6 +377,12 @@ def _iter(iterable):
377
377
  return iterable.__iter__() # type: ignore # noqa: PLC2801
378
378
 
379
379
 
380
+ @meta_fn
381
+ def _super(*args):
382
+ """Get the super class of a class or instance."""
383
+ return super(*(arg._as_py_() if arg._is_py_() else arg for arg in args))
384
+
385
+
380
386
  # classmethod, property, staticmethod are supported as decorators, but not within functions
381
387
 
382
388
  BUILTIN_IMPLS = {
@@ -399,6 +405,7 @@ BUILTIN_IMPLS = {
399
405
  id(next): _next,
400
406
  id(range): Range,
401
407
  id(reversed): _reversed,
408
+ id(super): _super,
402
409
  id(zip): _zip,
403
410
  **MATH_BUILTIN_IMPLS, # Includes round
404
411
  **RANDOM_BUILTIN_IMPLS,
@@ -1,11 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable
3
+ from collections.abc import Iterable, Sequence
4
4
  from contextlib import contextmanager
5
5
  from contextvars import ContextVar
6
6
  from dataclasses import dataclass
7
7
  from threading import Lock
8
- from typing import Any, Self
8
+ from typing import Any, Literal, Self
9
9
 
10
10
  from sonolus.backend.blocks import BlockData, PlayBlock
11
11
  from sonolus.backend.ir import IRConst, IRExpr, IRStmt
@@ -41,6 +41,7 @@ debug_var = ContextVar("debug_var", default=_disabled_debug_config)
41
41
 
42
42
  class GlobalContextState:
43
43
  archetypes: dict[type, int]
44
+ keys: Sequence[int] | None
44
45
  rom: ReadOnlyMemory
45
46
  const_mappings: dict[Any, int]
46
47
  environment_mappings: dict[_GlobalInfo, int]
@@ -49,7 +50,14 @@ class GlobalContextState:
49
50
  lock: Lock
50
51
 
51
52
  def __init__(self, mode: Mode, archetypes: dict[type, int] | None = None, rom: ReadOnlyMemory | None = None):
53
+ from sonolus.script.array import Array
54
+
52
55
  self.archetypes = archetypes or {}
56
+ self.keys = (
57
+ Array(*((getattr(a, "_key_", -1)) for a in sorted(self.archetypes, key=lambda a: archetypes[a])))
58
+ if archetypes
59
+ else Array[int, Literal[0]]()
60
+ )
53
61
  self.rom = ReadOnlyMemory() if rom is None else rom
54
62
  self.const_mappings = {}
55
63
  self.environment_mappings = {}
@@ -83,6 +83,7 @@ def try_validate_value(value: Any) -> Value | None:
83
83
  | NoneType()
84
84
  | NotImplementedType()
85
85
  | EllipsisType()
86
+ | super()
86
87
  ):
87
88
  return BasicConstantValue.of(value)
88
89
  case special_form if value in {
@@ -28,4 +28,7 @@ def get_field_specifiers(
28
28
  and not isinstance(value, property)
29
29
  ):
30
30
  raise ValueError(f"Missing annotation for {cls.__name__}.{key}")
31
+ for skipped_key in skip:
32
+ if skipped_key in results:
33
+ del results[skipped_key]
31
34
  return results
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sonolus.py
3
- Version: 0.4.2
3
+ Version: 0.5.1
4
4
  Summary: Sonolus engine development in Python
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -11,10 +11,10 @@ sonolus/backend/node.py,sha256=eEzPP14jzWJp2xrZCAaPlNtokxdoqg0bSM7xQiwx1j8,1254
11
11
  sonolus/backend/ops.py,sha256=5weB_vIxbkwCSJuzYZyKUk7vVXsSIEDJYRlvE-2ke8A,10572
12
12
  sonolus/backend/place.py,sha256=7qwV732hZ4WP-9GNN8FQSEKssPJZELip1wLXTWfop7Y,4717
13
13
  sonolus/backend/utils.py,sha256=DDgYUVHh4h_eSY65v2KcxUaLSBYGYS6oHar5gTdV7QU,2356
14
- sonolus/backend/visitor.py,sha256=6QjQ9tYOCP2a8-8WPgm8EB-hzwV5pcwLap3eDDrFG8I,62364
14
+ sonolus/backend/visitor.py,sha256=Dz_3w3gvmJraNC2fMMlkYthEmT0AkZfHGFsrracELuo,63121
15
15
  sonolus/backend/optimize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  sonolus/backend/optimize/allocate.py,sha256=CuumoMphkpQlGRNeKLHT4FBGE0XVj5pwhfNdrqiLFSs,7535
17
- sonolus/backend/optimize/constant_evaluation.py,sha256=OyjlgHIT6oPKCyBtNzEpo1nWYjr-_mwYUo8FrNV4eO4,21331
17
+ sonolus/backend/optimize/constant_evaluation.py,sha256=U--9moGsXFzrgweWWwHIiEuuMzwetd1IOjjtrCscoNM,21450
18
18
  sonolus/backend/optimize/copy_coalesce.py,sha256=45YL7QmRLL-FiQX4sDs56o4hyP7lX8KIJ0lIbyVw8h8,4549
19
19
  sonolus/backend/optimize/dead_code.py,sha256=ZRJ95zJ49R-wZTzJtcSSbl5LYKHWI-byHM3n6jOyAqc,8307
20
20
  sonolus/backend/optimize/dominance.py,sha256=3jAgXqXTbuYLpXvIm8UB06NkIOLtaoVp7pBVPcLb5vY,3259
@@ -28,16 +28,16 @@ sonolus/backend/optimize/ssa.py,sha256=raQO0furQQRPYb8iIBKfNrJlj-_5wqtI4EWNfLZ8Q
28
28
  sonolus/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  sonolus/build/cli.py,sha256=-_lTN8zT7nQB2lySM8itAEPVutcEQI-TJ13BcPIfGb4,10113
30
30
  sonolus/build/collection.py,sha256=kOVnpQC_KHAsyTM4nAplSh6QE16CgO-H6PP1GItWm78,12187
31
- sonolus/build/compile.py,sha256=B7w6Uqa4HlZPNklNhhjJoq9ncXMVXLCYabGLxtxWGV4,6521
31
+ sonolus/build/compile.py,sha256=Yex-ZbSZmv9ujyAOVaMcfq-0NnZzFIqtmNYYaplF4Uc,6761
32
32
  sonolus/build/engine.py,sha256=zUl0KfRygqNhIM8BABNJkKG-0zXFwcYwck-5hJy59yk,13338
33
33
  sonolus/build/level.py,sha256=yXsQtnabkJK0vuVmZ_Wr1jx37jFLgInCS7lTlXjkv9Q,706
34
34
  sonolus/build/node.py,sha256=gnX71RYDUOK_gYMpinQi-bLWO4csqcfiG5gFmhxzSec,1330
35
35
  sonolus/build/project.py,sha256=mv2OuzgIDG-E9G4SIRiUDL5XiPCd1i81wVl1p7itFHA,6329
36
36
  sonolus/script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- sonolus/script/archetype.py,sha256=HJeKJ_vj7xUYaCAmNdGYO45rhFMSLMwOLyvpKjulfVY,42418
37
+ sonolus/script/archetype.py,sha256=jhxyH-Lic-ZfOzD4H7-rPu9OChp900mTD_HpkA00FoY,46638
38
38
  sonolus/script/array.py,sha256=9uOUHZIDMyMT9q3APcXJWXWt97yG-AZoRlxwrvSY6SU,12367
39
39
  sonolus/script/array_like.py,sha256=jFOfXkniTLrIK4ER6HO_tUyKn_TvwjyM4B3SDd9cUS8,9678
40
- sonolus/script/bucket.py,sha256=5VU-Bh7qYifl6NcgZFCo7eAEgi3iGTX-PUTmXiPCJaQ,7535
40
+ sonolus/script/bucket.py,sha256=VxsSgHidYhY_Y5UXpBZY_tzjQff0TRgNJVj4Al8LVec,7654
41
41
  sonolus/script/containers.py,sha256=WX0qRnr6gNtn3C0q7MwMyrzvY-C0Bd1tzLGxSkUwL9U,18680
42
42
  sonolus/script/debug.py,sha256=_Hg1cXQJ8fBXMiwhmoPb2X9CKcQ8QO26WNa59K518og,4305
43
43
  sonolus/script/easing.py,sha256=txf0OPFP5v7cOFDvJKCyKLK-d2uKIOu56ntLEHfD9QI,11377
@@ -68,16 +68,16 @@ sonolus/script/ui.py,sha256=DYPGWIjHj1IFPxW1zaEuIUQx0b32FJPXtiwCvrtJ6oo,7528
68
68
  sonolus/script/values.py,sha256=6iJG6h4IDlbcK8FH4GENSHOQc7C_7fCGa34wM80qToA,1629
69
69
  sonolus/script/vec.py,sha256=oVx5C5zGj8gX37F7y1FEJOrTYzb7EWfQWQuKU8KGLdc,7486
70
70
  sonolus/script/internal/__init__.py,sha256=T6rzLoiOUaiSQtaHMZ88SNO-ijSjSSv33TKtUwu-Ms8,136
71
- sonolus/script/internal/builtin_impls.py,sha256=vzyaSTsxoZoE6a-aBBHn4aIfjGxxYzojEnOog3-HETI,12686
71
+ sonolus/script/internal/builtin_impls.py,sha256=POmWRyTQa-9mpQ_jATDYlFWo_n0a65vXAgqitkKYzGY,12870
72
72
  sonolus/script/internal/callbacks.py,sha256=vWzJG8uiJoEtsNnbeZPqOHogCwoLpz2D1MnHY2wVV8s,2801
73
73
  sonolus/script/internal/constant.py,sha256=3ycbGkDJVUwcrCZ96vLjAoAARgsvaqDM8rJ_YCrLrvo,4289
74
- sonolus/script/internal/context.py,sha256=qn8xp5BB1C3IaUS8jsSUfkMUJgPzeaIV7K4FY9mHHQo,16903
74
+ sonolus/script/internal/context.py,sha256=JtKyjFlt7t2YwR1qFUGGjzYrE8v0yfsP-7XA196gtaQ,17211
75
75
  sonolus/script/internal/descriptor.py,sha256=XRFey-EjiAm_--KsNl-8N0Mi_iyQwlPh68gDp0pKf3E,392
76
76
  sonolus/script/internal/dict_impl.py,sha256=alu_wKGSk1kZajNf64qbe7t71shEzD4N5xNIATH8Swo,1885
77
77
  sonolus/script/internal/error.py,sha256=ZNnsvQVQAnFKzcvsm6-sste2lo-tP5pPI8sD7XlAZWc,490
78
78
  sonolus/script/internal/generic.py,sha256=F0-cCiRNGTaUJvYlpmkiOsU3Xge_XjoBpBwBhH_qS_s,7577
79
- sonolus/script/internal/impl.py,sha256=I3IlPZZZtXVJb044cpULg5FDYUjiLtAucnsA6w_0xUk,3233
80
- sonolus/script/internal/introspection.py,sha256=MfdXo3GFHNZT2-vAKuvsE54V-5TOfbg4vU9dBI6sLqo,1032
79
+ sonolus/script/internal/impl.py,sha256=alcFJs1yDx9ixEOxg-r_1IvWG2arMSUKSc-Eg9nAHOw,3255
80
+ sonolus/script/internal/introspection.py,sha256=guL9_NR2D3OJAnNpeFdyYkO_vVXk-3KQr2-y4YielM0,1133
81
81
  sonolus/script/internal/math_impls.py,sha256=nHSLgA7Tcx7jY1p07mYBCeSRmVx713bwdNayCIcaXSE,2652
82
82
  sonolus/script/internal/native.py,sha256=DQxmzxgLG_UsLpXhIEtBdO7eIeDFprU78UBDC4OZzw0,1597
83
83
  sonolus/script/internal/random.py,sha256=6Ku5edRcDUh7rtqEEYCJz0BQavw69RALsVHS25z50pI,1695
@@ -86,8 +86,8 @@ sonolus/script/internal/simulation_context.py,sha256=LGxLTvxbqBIhoe1R-SfwGajNIDw
86
86
  sonolus/script/internal/transient.py,sha256=y2AWABqF1aoaP6H4_2u4MMpNioC4OsZQCtPyNI0txqo,1634
87
87
  sonolus/script/internal/tuple_impl.py,sha256=DPNdmmRmupU8Ah4_XKq6-PdT336l4nt15_uCJKQGkkk,3587
88
88
  sonolus/script/internal/value.py,sha256=OngrCdmY_h6mV2Zgwqhuo4eYFad0kTk6263UAxctZcY,6963
89
- sonolus_py-0.4.2.dist-info/METADATA,sha256=rV2d-Y0jxrhlOQfcrYRAVAKiuobluI5omhDztt5mmLo,302
90
- sonolus_py-0.4.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
91
- sonolus_py-0.4.2.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
92
- sonolus_py-0.4.2.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
93
- sonolus_py-0.4.2.dist-info/RECORD,,
89
+ sonolus_py-0.5.1.dist-info/METADATA,sha256=RqZZ8ZVpQV4cKUJ2tVZQcdlBxMGbyoJjURrCYn9CSAc,302
90
+ sonolus_py-0.5.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
91
+ sonolus_py-0.5.1.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
92
+ sonolus_py-0.5.1.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
93
+ sonolus_py-0.5.1.dist-info/RECORD,,