sonolus.py 0.1.6__py3-none-any.whl → 0.1.8__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/script/array.py CHANGED
@@ -60,7 +60,7 @@ class Array[T, Size](GenericValue, ArrayLike[T]):
60
60
  raise ValueError(f"{cls.__name__} constructor should be used with {cls.size()} values, got {len(args)}")
61
61
  parameterized_cls = cls
62
62
  if ctx():
63
- place = ctx().alloc(size=parameterized_cls.size())
63
+ place = ctx().alloc(size=parameterized_cls._size_())
64
64
  result: parameterized_cls = parameterized_cls._from_place_(place)
65
65
  result._copy_from_(parameterized_cls._with_value(values))
66
66
  return result
@@ -182,10 +182,18 @@ class Context:
182
182
  return
183
183
  assert len(self.outgoing) == 0
184
184
  self.outgoing[None] = header
185
+ values = {}
186
+ # First do a pass through and copy every value
185
187
  for name, target_value in header.loop_variables.items():
186
188
  with using_ctx(self):
187
189
  if type(target_value)._is_value_type_():
188
190
  value = self.scope.get_value(name)
191
+ values[name] = value._get_() # _get_() will make a copy on value types
192
+ # Then actually set them
193
+ for name, target_value in header.loop_variables.items():
194
+ with using_ctx(self):
195
+ if type(target_value)._is_value_type_():
196
+ value = values[name]
189
197
  value = type(target_value)._accept_(value)
190
198
  target_value._set_(value)
191
199
  else:
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, TypeIs, final, runtime_checkable
6
+ from typing import TYPE_CHECKING, Any, Self, final, runtime_checkable, TypeGuard
7
7
 
8
8
  from sonolus.backend.ir import IRConst, IRGet, IRPureInstr, IRSet
9
9
  from sonolus.backend.ops import Op
@@ -19,7 +19,7 @@ class _NumMeta(type):
19
19
  return isinstance(instance, float | int | bool) or _is_num(instance)
20
20
 
21
21
 
22
- def _is_num(value: Any) -> TypeIs[Num]:
22
+ def _is_num(value: Any) -> TypeGuard[Num]:
23
23
  """Check if a value is a precisely Num instance."""
24
24
  return type.__instancecheck__(Num, value) # type: ignore # noqa: PLC2801
25
25
 
sonolus/script/quad.py CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from typing import Protocol, Self
4
4
 
5
5
  from sonolus.script.record import Record
6
- from sonolus.script.vec import Vec2
6
+ from sonolus.script.vec import Vec2, pnpoly
7
7
 
8
8
 
9
9
  class Quad(Record):
@@ -95,6 +95,17 @@ class Quad(Record):
95
95
  """Rotate the quad by the given angle about its center and return a new quad."""
96
96
  return self.rotate_about(angle, self.center)
97
97
 
98
+ def contains_point(self, point: Vec2, /) -> bool:
99
+ """Check if the quad contains the given point.
100
+
101
+ Args:
102
+ point: The point to check.
103
+
104
+ Returns:
105
+ True if the point is inside the quad, False otherwise.
106
+ """
107
+ return pnpoly((self.bl, self.tl, self.tr, self.br), point)
108
+
98
109
 
99
110
  class Rect(Record):
100
111
  """A rectangle defined by its top, right, bottom, and left edges.
@@ -225,6 +236,17 @@ class Rect(Record):
225
236
  l=self.l + shrinkage.x,
226
237
  )
227
238
 
239
+ def contains_point(self, point: Vec2, /) -> bool:
240
+ """Check if the rectangle contains the given point.
241
+
242
+ Args:
243
+ point: The point to check.
244
+
245
+ Returns:
246
+ True if the point is inside the rectangle, False otherwise.
247
+ """
248
+ return self.l <= point.x <= self.r and self.b <= point.y <= self.t
249
+
228
250
 
229
251
  class QuadLike(Protocol):
230
252
  """A protocol for types that can be used as quads."""
sonolus/script/vec.py CHANGED
@@ -1,6 +1,8 @@
1
1
  from math import atan2, cos, sin
2
2
  from typing import Self
3
3
 
4
+ from sonolus.script.array import Array
5
+ from sonolus.script.array_like import ArrayLike
4
6
  from sonolus.script.num import Num
5
7
  from sonolus.script.record import Record
6
8
 
@@ -194,3 +196,30 @@ class Vec2(Record):
194
196
  A new vector with inverted direction.
195
197
  """
196
198
  return Vec2(x=-self.x, y=-self.y)
199
+
200
+
201
+ def pnpoly(vertices: ArrayLike[Vec2] | tuple[Vec2, ...], test: Vec2) -> bool:
202
+ """Check if a point is inside a polygon.
203
+
204
+ No guaranteed behavior for points on the edges or very close to the edges.
205
+
206
+ Args:
207
+ vertices: The vertices of the polygon.
208
+ test: The point to test.
209
+
210
+ Returns:
211
+ Whether the point is inside the polygon.
212
+ """
213
+ if isinstance(vertices, tuple):
214
+ vertices = Array(*vertices)
215
+ i = 0
216
+ j = len(vertices) - 1
217
+ c = False
218
+ while i < len(vertices):
219
+ if (vertices[i].y > test.y) != (vertices[j].y > test.y) and test.x < (vertices[j].x - vertices[i].x) * (
220
+ test.y - vertices[i].y
221
+ ) / (vertices[j].y - vertices[i].y) + vertices[i].x:
222
+ c = not c
223
+ j = i
224
+ i += 1
225
+ return c
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sonolus.py
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: Sonolus engine development in Python
5
- Requires-Python: >=3.13
5
+ Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
7
7
 
8
8
  # Sonolus.py
@@ -35,7 +35,7 @@ sonolus/build/node.py,sha256=jwsVWt6Brh4M9MypUt3Nqnxfm7fXrCMRWYQGwBTAszI,1162
35
35
  sonolus/build/project.py,sha256=QukkCVQBGxnp1F2jQjaAkTg3TutwhWqKGXAfQZDMk1c,5162
36
36
  sonolus/script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  sonolus/script/archetype.py,sha256=cQDoNVO7dUHYQ7RlAHiyoEnUYt0seCnFPD_bPzo0BNE,34114
38
- sonolus/script/array.py,sha256=KJxyL4I7A-CNFQW1RbZYQGVI527XZmoesDR-q6BurB8,9339
38
+ sonolus/script/array.py,sha256=rPAK3kdeL6A_a82DSnxDe6Cl99vjS2UVU97n1r8arsA,9341
39
39
  sonolus/script/array_like.py,sha256=OVOLMadS-Jj941S-EgoxlFPdaQLT6ZrHzaMnKtB6PfU,8346
40
40
  sonolus/script/bucket.py,sha256=ZNlNeBZ1FzRLQ49bTuuJDmnYZ-_sjQEvosySx3ESxQc,6944
41
41
  sonolus/script/containers.py,sha256=tf0-UUSq8NH6k9jIKq6qgXRxanFQ0f5olH6uHghTynk,13171
@@ -48,13 +48,13 @@ sonolus/script/instruction.py,sha256=PNfxC1dhT_hB0BxhDV3KXMn_kKxfI0t1iZmg8m6ddMU
48
48
  sonolus/script/interval.py,sha256=3wMy7YlL6XV0g7w3eIDQDXl1WfTjW4NunKtwRxRMnDQ,9004
49
49
  sonolus/script/iterator.py,sha256=ZErUmpRrXISe1xiT3VOjHzcqqLhpfT9FI7Kz2s2vUpk,4163
50
50
  sonolus/script/level.py,sha256=NuXr8SalXn4eMm00OOYfWPQ-EXhJIKVCtbiIKX2SGag,1872
51
- sonolus/script/num.py,sha256=-u1wwFkPJYrJCjD8yE2DArrH3SMVKqQaHQhgVpd8EeA,13911
51
+ sonolus/script/num.py,sha256=70dFsC5mcELiQoZk1Da1h1sHZ0Ed1D8oZzgX_hlPq9s,13917
52
52
  sonolus/script/options.py,sha256=nTOuoRC2p_qoMx4ngOVDY2WZDooTxwwGTGKyb994v2A,7516
53
53
  sonolus/script/particle.py,sha256=K06ArT9tstRNdbuGIviDmDDWcK3-ieA53LHg0Xvizow,8304
54
54
  sonolus/script/pointer.py,sha256=pOh5vCSl6xR7mDm5PMOhBc_wf4O-b938DE0LtZWBmPc,1119
55
55
  sonolus/script/print.py,sha256=mNYu9QWiacBBGZrnePZQMVwbbguoelUps9GiOK_aVRU,2096
56
56
  sonolus/script/project.py,sha256=DhmBuH0CkFKmF27o1V9XhIOsywXDi57i-Wpwyd-70LM,2040
57
- sonolus/script/quad.py,sha256=SVMcfRYx8Bv5t7A2vhus9QUiw-1V-qtRhldr3DnnNWw,7693
57
+ sonolus/script/quad.py,sha256=e2kXKSp9K46Q9qstLsGLFPxaW7Z2kfVfignA8Ka2-Pw,8375
58
58
  sonolus/script/record.py,sha256=rOVlo-eUUvFG_Ee-wKrgX_ZwOqWKWtS7s8m-juM70yE,11216
59
59
  sonolus/script/runtime.py,sha256=xeiLJFeqkCev1x6pBiM5afyvi3GWdpLJ5OYRg9M9nwo,18562
60
60
  sonolus/script/sprite.py,sha256=FOozsPtaQnInnm-QshtYznnC66_8jb1D2sHmo7nFEsY,15718
@@ -63,12 +63,12 @@ sonolus/script/timing.py,sha256=ZR0ypV2PIoDCMHHGOMfCeezStCsBQdzomdqaz5VKex0,2981
63
63
  sonolus/script/transform.py,sha256=hH6KSRQC8vV-Z10CRCrGewMYqQwUMH3mQIEmniuC2Zw,10760
64
64
  sonolus/script/ui.py,sha256=kyuP88sLRJPT-Yx-7fx8Xu9Wdegyw_CJNslcP4WnDUs,7268
65
65
  sonolus/script/values.py,sha256=JuvJknskuY6FPprUp9R-6Gj2TDJLu4ppbVcYedG5dG0,1049
66
- sonolus/script/vec.py,sha256=Uph6Z9xofwbKGZu0H7rl6fzlO4bj5i0cnWu4LQeIL4I,5270
66
+ sonolus/script/vec.py,sha256=looCsmYpt6jlasdBqddtkC0hA1exZ3lxPP3_BL8cPXw,6148
67
67
  sonolus/script/internal/__init__.py,sha256=T6rzLoiOUaiSQtaHMZ88SNO-ijSjSSv33TKtUwu-Ms8,136
68
68
  sonolus/script/internal/builtin_impls.py,sha256=w27aKMhLX4Ivd7uKz1ZgVy1lC5scSSJ23-VfsbCfIb0,7731
69
69
  sonolus/script/internal/callbacks.py,sha256=vWzJG8uiJoEtsNnbeZPqOHogCwoLpz2D1MnHY2wVV8s,2801
70
70
  sonolus/script/internal/constant.py,sha256=lIBBR84Rfw0rBSZU2reCrUnB3yEMEdOX6A7_LgptYz8,3776
71
- sonolus/script/internal/context.py,sha256=evLOXcOqskK5Gh5Je86ghKlMaon-Opi7dDoMtkCjEh8,13533
71
+ sonolus/script/internal/context.py,sha256=I9X89aTWgoY-_jgnJHEnzzVLAvILACtPfgdE4ipxjOc,13930
72
72
  sonolus/script/internal/descriptor.py,sha256=XRFey-EjiAm_--KsNl-8N0Mi_iyQwlPh68gDp0pKf3E,392
73
73
  sonolus/script/internal/dict_impl.py,sha256=alu_wKGSk1kZajNf64qbe7t71shEzD4N5xNIATH8Swo,1885
74
74
  sonolus/script/internal/error.py,sha256=ZNnsvQVQAnFKzcvsm6-sste2lo-tP5pPI8sD7XlAZWc,490
@@ -82,8 +82,8 @@ sonolus/script/internal/range.py,sha256=lrTanQFHU7RuQxSSPwDdoC30Y8FnHGxcP1Ahditu
82
82
  sonolus/script/internal/transient.py,sha256=pSDFGu0m26zVsp6owmNTeSPue-osDd1JahjJSijW8t0,1520
83
83
  sonolus/script/internal/tuple_impl.py,sha256=vjXmScLVdeTkDn3t9fgIRqtW31iwngnaP2rmA6nlsLw,3431
84
84
  sonolus/script/internal/value.py,sha256=ik9sMKl0TbsH_C6QNxD4WfpAnmBFISgmmlazWwh3kY0,4308
85
- sonolus_py-0.1.6.dist-info/METADATA,sha256=FBVX2Rg8O7Z0tikPOsj5wEziwbk4MSLsRxxBhJeTDrY,216
86
- sonolus_py-0.1.6.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
87
- sonolus_py-0.1.6.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
88
- sonolus_py-0.1.6.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
89
- sonolus_py-0.1.6.dist-info/RECORD,,
85
+ sonolus_py-0.1.8.dist-info/METADATA,sha256=cfD6gibjNFF16Xw5L4tIe_cUX5WYG_HFt4Tl8fVGkK8,216
86
+ sonolus_py-0.1.8.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
87
+ sonolus_py-0.1.8.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
88
+ sonolus_py-0.1.8.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
89
+ sonolus_py-0.1.8.dist-info/RECORD,,