sonolus.py 0.3.1__py3-none-any.whl → 0.3.3__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/finalize.py +16 -4
- sonolus/backend/node.py +13 -5
- sonolus/backend/optimize/allocate.py +41 -4
- sonolus/backend/optimize/flow.py +24 -7
- sonolus/backend/optimize/optimize.py +2 -9
- sonolus/backend/utils.py +6 -1
- sonolus/backend/visitor.py +72 -23
- sonolus/build/cli.py +6 -1
- sonolus/build/engine.py +1 -1
- sonolus/script/archetype.py +52 -24
- sonolus/script/array.py +20 -8
- sonolus/script/array_like.py +30 -3
- sonolus/script/containers.py +27 -7
- sonolus/script/debug.py +66 -8
- sonolus/script/globals.py +17 -0
- sonolus/script/internal/builtin_impls.py +12 -8
- sonolus/script/internal/context.py +55 -1
- sonolus/script/internal/range.py +25 -2
- sonolus/script/internal/simulation_context.py +131 -0
- sonolus/script/internal/tuple_impl.py +18 -11
- sonolus/script/interval.py +60 -2
- sonolus/script/iterator.py +3 -2
- sonolus/script/num.py +11 -2
- sonolus/script/options.py +24 -1
- sonolus/script/quad.py +41 -3
- sonolus/script/record.py +24 -3
- sonolus/script/runtime.py +411 -0
- sonolus/script/stream.py +133 -16
- sonolus/script/transform.py +291 -2
- sonolus/script/values.py +9 -3
- sonolus/script/vec.py +14 -2
- {sonolus_py-0.3.1.dist-info → sonolus_py-0.3.3.dist-info}/METADATA +1 -1
- {sonolus_py-0.3.1.dist-info → sonolus_py-0.3.3.dist-info}/RECORD +36 -35
- {sonolus_py-0.3.1.dist-info → sonolus_py-0.3.3.dist-info}/WHEEL +0 -0
- {sonolus_py-0.3.1.dist-info → sonolus_py-0.3.3.dist-info}/entry_points.txt +0 -0
- {sonolus_py-0.3.1.dist-info → sonolus_py-0.3.3.dist-info}/licenses/LICENSE +0 -0
sonolus/script/runtime.py
CHANGED
|
@@ -259,6 +259,382 @@ class _TutorialRuntimeUi:
|
|
|
259
259
|
instruction: BasicRuntimeUiLayout
|
|
260
260
|
|
|
261
261
|
|
|
262
|
+
class UiLayout[T](Record):
|
|
263
|
+
"""The layout of a UI element."""
|
|
264
|
+
|
|
265
|
+
_underlying: T
|
|
266
|
+
|
|
267
|
+
def update(
|
|
268
|
+
self,
|
|
269
|
+
anchor: Vec2 | None = None,
|
|
270
|
+
pivot: Vec2 | None = None,
|
|
271
|
+
dimensions: Vec2 | None = None,
|
|
272
|
+
rotation: float | None = None,
|
|
273
|
+
alpha: float | None = None,
|
|
274
|
+
horizontal_align: HorizontalAlign | None = None,
|
|
275
|
+
background: bool | None = None,
|
|
276
|
+
):
|
|
277
|
+
"""Update the layout properties if it's available in the current mode and do nothing otherwise."""
|
|
278
|
+
match self._underlying:
|
|
279
|
+
case RuntimeUiLayout():
|
|
280
|
+
self._underlying.update(
|
|
281
|
+
anchor=anchor,
|
|
282
|
+
pivot=pivot,
|
|
283
|
+
dimensions=dimensions,
|
|
284
|
+
rotation=rotation,
|
|
285
|
+
alpha=alpha,
|
|
286
|
+
horizontal_align=horizontal_align,
|
|
287
|
+
background=background,
|
|
288
|
+
)
|
|
289
|
+
case BasicRuntimeUiLayout():
|
|
290
|
+
self._underlying.update(
|
|
291
|
+
anchor=anchor,
|
|
292
|
+
pivot=pivot,
|
|
293
|
+
dimensions=dimensions,
|
|
294
|
+
rotation=rotation,
|
|
295
|
+
alpha=alpha,
|
|
296
|
+
background=background,
|
|
297
|
+
)
|
|
298
|
+
case _:
|
|
299
|
+
pass # do nothing
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def is_available(self) -> bool:
|
|
303
|
+
"""Check if the layout is available in the current mode."""
|
|
304
|
+
return self._underlying is not None
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
class UiConfig[T](Record):
|
|
308
|
+
"""The user configuration for a UI element."""
|
|
309
|
+
|
|
310
|
+
_underlying: T
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
def scale(self) -> float:
|
|
314
|
+
"""The scale of the UI element."""
|
|
315
|
+
match self._underlying:
|
|
316
|
+
case RuntimeUiConfig():
|
|
317
|
+
return self._underlying.scale
|
|
318
|
+
case _:
|
|
319
|
+
return 1.0 # Default scale if not available
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def alpha(self) -> float:
|
|
323
|
+
"""The alpha (opacity) of the UI element."""
|
|
324
|
+
match self._underlying:
|
|
325
|
+
case RuntimeUiConfig():
|
|
326
|
+
return self._underlying.alpha
|
|
327
|
+
case _:
|
|
328
|
+
return 1.0 # Default alpha if not available
|
|
329
|
+
|
|
330
|
+
@property
|
|
331
|
+
def is_available(self) -> bool:
|
|
332
|
+
"""Check if the config is available in the current mode."""
|
|
333
|
+
return self._underlying is not None
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
class RuntimeUi(Record):
|
|
337
|
+
"""Holds the layouts for different UI elements across all modes."""
|
|
338
|
+
|
|
339
|
+
@property
|
|
340
|
+
@meta_fn
|
|
341
|
+
def menu(self) -> UiLayout:
|
|
342
|
+
"""The configuration for the menu UI element.
|
|
343
|
+
|
|
344
|
+
Available in play, watch, preview, and tutorial mode.
|
|
345
|
+
"""
|
|
346
|
+
match ctx().global_state.mode:
|
|
347
|
+
case Mode.PLAY:
|
|
348
|
+
return UiLayout(_PlayRuntimeUi.menu)
|
|
349
|
+
case Mode.WATCH:
|
|
350
|
+
return UiLayout(_WatchRuntimeUi.menu)
|
|
351
|
+
case Mode.PREVIEW:
|
|
352
|
+
return UiLayout(_PreviewRuntimeUi.menu)
|
|
353
|
+
case Mode.TUTORIAL:
|
|
354
|
+
return UiLayout(_TutorialRuntimeUi.menu)
|
|
355
|
+
case _:
|
|
356
|
+
raise RuntimeError("Unsupported mode for menu UI layout")
|
|
357
|
+
|
|
358
|
+
@property
|
|
359
|
+
@meta_fn
|
|
360
|
+
def menu_config(self) -> UiConfig:
|
|
361
|
+
"""The configuration for the menu UI element.
|
|
362
|
+
|
|
363
|
+
Available in play, watch, preview, and tutorial mode.
|
|
364
|
+
"""
|
|
365
|
+
match ctx().global_state.mode:
|
|
366
|
+
case Mode.PLAY:
|
|
367
|
+
return UiConfig(_PlayRuntimeUiConfigs.menu)
|
|
368
|
+
case Mode.WATCH:
|
|
369
|
+
return UiConfig(_WatchRuntimeUiConfigs.menu)
|
|
370
|
+
case Mode.PREVIEW:
|
|
371
|
+
return UiConfig(_PreviewRuntimeUiConfigs.menu)
|
|
372
|
+
case Mode.TUTORIAL:
|
|
373
|
+
return UiConfig(_TutorialRuntimeUiConfigs.menu)
|
|
374
|
+
case _:
|
|
375
|
+
raise RuntimeError("Unsupported mode for menu UI configuration")
|
|
376
|
+
|
|
377
|
+
@property
|
|
378
|
+
@meta_fn
|
|
379
|
+
def judgment(self) -> UiLayout:
|
|
380
|
+
"""The configuration for the judgment UI element.
|
|
381
|
+
|
|
382
|
+
Available in play and watch mode.
|
|
383
|
+
"""
|
|
384
|
+
match ctx().global_state.mode:
|
|
385
|
+
case Mode.PLAY:
|
|
386
|
+
return UiLayout(_PlayRuntimeUi.judgment)
|
|
387
|
+
case Mode.WATCH:
|
|
388
|
+
return UiLayout(_WatchRuntimeUi.judgment)
|
|
389
|
+
case _:
|
|
390
|
+
return UiLayout(None)
|
|
391
|
+
|
|
392
|
+
@property
|
|
393
|
+
@meta_fn
|
|
394
|
+
def judgment_config(self) -> UiConfig:
|
|
395
|
+
"""The configuration for the judgment UI element.
|
|
396
|
+
|
|
397
|
+
Available in play and watch mode.
|
|
398
|
+
"""
|
|
399
|
+
match ctx().global_state.mode:
|
|
400
|
+
case Mode.PLAY:
|
|
401
|
+
return UiConfig(_PlayRuntimeUiConfigs.judgment)
|
|
402
|
+
case Mode.WATCH:
|
|
403
|
+
return UiConfig(_WatchRuntimeUiConfigs.judgment)
|
|
404
|
+
case _:
|
|
405
|
+
return UiConfig(None)
|
|
406
|
+
|
|
407
|
+
@property
|
|
408
|
+
@meta_fn
|
|
409
|
+
def combo_value(self) -> UiLayout:
|
|
410
|
+
"""The configuration for the combo value UI element.
|
|
411
|
+
|
|
412
|
+
Available in play and watch mode.
|
|
413
|
+
"""
|
|
414
|
+
match ctx().global_state.mode:
|
|
415
|
+
case Mode.PLAY:
|
|
416
|
+
return UiLayout(_PlayRuntimeUi.combo_value)
|
|
417
|
+
case Mode.WATCH:
|
|
418
|
+
return UiLayout(_WatchRuntimeUi.combo_value)
|
|
419
|
+
case _:
|
|
420
|
+
return UiLayout(None)
|
|
421
|
+
|
|
422
|
+
@property
|
|
423
|
+
@meta_fn
|
|
424
|
+
def combo_text(self) -> UiLayout:
|
|
425
|
+
"""The configuration for the combo text UI element.
|
|
426
|
+
|
|
427
|
+
Available in play and watch mode.
|
|
428
|
+
"""
|
|
429
|
+
match ctx().global_state.mode:
|
|
430
|
+
case Mode.PLAY:
|
|
431
|
+
return UiLayout(_PlayRuntimeUi.combo_text)
|
|
432
|
+
case Mode.WATCH:
|
|
433
|
+
return UiLayout(_WatchRuntimeUi.combo_text)
|
|
434
|
+
case _:
|
|
435
|
+
return UiLayout(None)
|
|
436
|
+
|
|
437
|
+
@property
|
|
438
|
+
@meta_fn
|
|
439
|
+
def combo_config(self) -> UiConfig:
|
|
440
|
+
"""The configuration for the combo UI element.
|
|
441
|
+
|
|
442
|
+
Available in play and watch mode.
|
|
443
|
+
"""
|
|
444
|
+
match ctx().global_state.mode:
|
|
445
|
+
case Mode.PLAY:
|
|
446
|
+
return UiConfig(_PlayRuntimeUiConfigs.combo)
|
|
447
|
+
case Mode.WATCH:
|
|
448
|
+
return UiConfig(_WatchRuntimeUiConfigs.combo)
|
|
449
|
+
case _:
|
|
450
|
+
return UiConfig(None)
|
|
451
|
+
|
|
452
|
+
@property
|
|
453
|
+
@meta_fn
|
|
454
|
+
def primary_metric_bar(self) -> UiLayout:
|
|
455
|
+
"""The configuration for the primary metric bar UI element.
|
|
456
|
+
|
|
457
|
+
Available in play and watch mode.
|
|
458
|
+
"""
|
|
459
|
+
match ctx().global_state.mode:
|
|
460
|
+
case Mode.PLAY:
|
|
461
|
+
return UiLayout(_PlayRuntimeUi.primary_metric_bar)
|
|
462
|
+
case Mode.WATCH:
|
|
463
|
+
return UiLayout(_WatchRuntimeUi.primary_metric_bar)
|
|
464
|
+
case _:
|
|
465
|
+
return UiLayout(None)
|
|
466
|
+
|
|
467
|
+
@property
|
|
468
|
+
@meta_fn
|
|
469
|
+
def primary_metric_value(self) -> UiLayout:
|
|
470
|
+
"""The configuration for the primary metric value UI element.
|
|
471
|
+
|
|
472
|
+
Available in play and watch mode.
|
|
473
|
+
"""
|
|
474
|
+
match ctx().global_state.mode:
|
|
475
|
+
case Mode.PLAY:
|
|
476
|
+
return UiLayout(_PlayRuntimeUi.primary_metric_value)
|
|
477
|
+
case Mode.WATCH:
|
|
478
|
+
return UiLayout(_WatchRuntimeUi.primary_metric_value)
|
|
479
|
+
case _:
|
|
480
|
+
return UiLayout(None)
|
|
481
|
+
|
|
482
|
+
@property
|
|
483
|
+
@meta_fn
|
|
484
|
+
def primary_metric_config(self) -> UiConfig:
|
|
485
|
+
"""The configuration for the primary metric UI element.
|
|
486
|
+
|
|
487
|
+
Available in play and watch mode.
|
|
488
|
+
"""
|
|
489
|
+
match ctx().global_state.mode:
|
|
490
|
+
case Mode.PLAY:
|
|
491
|
+
return UiConfig(_PlayRuntimeUiConfigs.primary_metric)
|
|
492
|
+
case Mode.WATCH:
|
|
493
|
+
return UiConfig(_WatchRuntimeUiConfigs.primary_metric)
|
|
494
|
+
case _:
|
|
495
|
+
return UiConfig(None)
|
|
496
|
+
|
|
497
|
+
@property
|
|
498
|
+
@meta_fn
|
|
499
|
+
def secondary_metric_bar(self) -> UiLayout:
|
|
500
|
+
"""The configuration for the secondary metric bar UI element.
|
|
501
|
+
|
|
502
|
+
Available in play and watch mode.
|
|
503
|
+
"""
|
|
504
|
+
match ctx().global_state.mode:
|
|
505
|
+
case Mode.PLAY:
|
|
506
|
+
return UiLayout(_PlayRuntimeUi.secondary_metric_bar)
|
|
507
|
+
case Mode.WATCH:
|
|
508
|
+
return UiLayout(_WatchRuntimeUi.secondary_metric_bar)
|
|
509
|
+
case _:
|
|
510
|
+
return UiLayout(None)
|
|
511
|
+
|
|
512
|
+
@property
|
|
513
|
+
@meta_fn
|
|
514
|
+
def secondary_metric_value(self) -> UiLayout:
|
|
515
|
+
"""The configuration for the secondary metric value UI element.
|
|
516
|
+
|
|
517
|
+
Available in play and watch mode.
|
|
518
|
+
"""
|
|
519
|
+
match ctx().global_state.mode:
|
|
520
|
+
case Mode.PLAY:
|
|
521
|
+
return UiLayout(_PlayRuntimeUi.secondary_metric_value)
|
|
522
|
+
case Mode.WATCH:
|
|
523
|
+
return UiLayout(_WatchRuntimeUi.secondary_metric_value)
|
|
524
|
+
case _:
|
|
525
|
+
return UiLayout(None)
|
|
526
|
+
|
|
527
|
+
@property
|
|
528
|
+
@meta_fn
|
|
529
|
+
def secondary_metric_config(self) -> UiConfig:
|
|
530
|
+
"""The configuration for the secondary metric UI element.
|
|
531
|
+
|
|
532
|
+
Available in play and watch mode.
|
|
533
|
+
"""
|
|
534
|
+
match ctx().global_state.mode:
|
|
535
|
+
case Mode.PLAY:
|
|
536
|
+
return UiConfig(_PlayRuntimeUiConfigs.secondary_metric)
|
|
537
|
+
case Mode.WATCH:
|
|
538
|
+
return UiConfig(_WatchRuntimeUiConfigs.secondary_metric)
|
|
539
|
+
case _:
|
|
540
|
+
return UiConfig(None)
|
|
541
|
+
|
|
542
|
+
@property
|
|
543
|
+
@meta_fn
|
|
544
|
+
def progress(self) -> UiLayout:
|
|
545
|
+
"""The configuration for the progress UI element.
|
|
546
|
+
|
|
547
|
+
Available in watch and preview mode.
|
|
548
|
+
"""
|
|
549
|
+
match ctx().global_state.mode:
|
|
550
|
+
case Mode.WATCH:
|
|
551
|
+
return UiLayout(_WatchRuntimeUi.progress)
|
|
552
|
+
case Mode.PREVIEW:
|
|
553
|
+
return UiLayout(_PreviewRuntimeUi.progress)
|
|
554
|
+
case _:
|
|
555
|
+
return UiLayout(None)
|
|
556
|
+
|
|
557
|
+
@property
|
|
558
|
+
@meta_fn
|
|
559
|
+
def progress_config(self) -> UiConfig:
|
|
560
|
+
"""The configuration for the progress UI element.
|
|
561
|
+
|
|
562
|
+
Available in watch and preview mode.
|
|
563
|
+
"""
|
|
564
|
+
match ctx().global_state.mode:
|
|
565
|
+
case Mode.WATCH:
|
|
566
|
+
return UiConfig(_WatchRuntimeUiConfigs.progress)
|
|
567
|
+
case Mode.PREVIEW:
|
|
568
|
+
return UiConfig(_PreviewRuntimeUiConfigs.progress)
|
|
569
|
+
case _:
|
|
570
|
+
return UiConfig(None)
|
|
571
|
+
|
|
572
|
+
@property
|
|
573
|
+
@meta_fn
|
|
574
|
+
def previous(self) -> UiLayout:
|
|
575
|
+
"""The configuration for the previous navigation UI element.
|
|
576
|
+
|
|
577
|
+
Available in tutorial mode.
|
|
578
|
+
"""
|
|
579
|
+
match ctx().global_state.mode:
|
|
580
|
+
case Mode.TUTORIAL:
|
|
581
|
+
return UiLayout(_TutorialRuntimeUi.previous)
|
|
582
|
+
case _:
|
|
583
|
+
return UiLayout(None)
|
|
584
|
+
|
|
585
|
+
@property
|
|
586
|
+
@meta_fn
|
|
587
|
+
def next(self) -> UiLayout:
|
|
588
|
+
"""The configuration for the next navigation UI element.
|
|
589
|
+
|
|
590
|
+
Available in tutorial mode.
|
|
591
|
+
"""
|
|
592
|
+
match ctx().global_state.mode:
|
|
593
|
+
case Mode.TUTORIAL:
|
|
594
|
+
return UiLayout(_TutorialRuntimeUi.next)
|
|
595
|
+
case _:
|
|
596
|
+
return UiLayout(None)
|
|
597
|
+
|
|
598
|
+
@property
|
|
599
|
+
@meta_fn
|
|
600
|
+
def navigation_config(self) -> UiConfig:
|
|
601
|
+
"""The configuration for the navigation UI element.
|
|
602
|
+
|
|
603
|
+
Available in tutorial mode.
|
|
604
|
+
"""
|
|
605
|
+
match ctx().global_state.mode:
|
|
606
|
+
case Mode.TUTORIAL:
|
|
607
|
+
return UiConfig(_TutorialRuntimeUiConfigs.navigation)
|
|
608
|
+
case _:
|
|
609
|
+
return UiConfig(None)
|
|
610
|
+
|
|
611
|
+
@property
|
|
612
|
+
@meta_fn
|
|
613
|
+
def instruction(self) -> UiLayout:
|
|
614
|
+
"""The configuration for the instruction UI element.
|
|
615
|
+
|
|
616
|
+
Available in tutorial mode.
|
|
617
|
+
"""
|
|
618
|
+
match ctx().global_state.mode:
|
|
619
|
+
case Mode.TUTORIAL:
|
|
620
|
+
return UiLayout(_TutorialRuntimeUi.instruction)
|
|
621
|
+
case _:
|
|
622
|
+
return UiLayout(None)
|
|
623
|
+
|
|
624
|
+
@property
|
|
625
|
+
@meta_fn
|
|
626
|
+
def instruction_config(self) -> UiConfig:
|
|
627
|
+
"""The configuration for the instruction UI element.
|
|
628
|
+
|
|
629
|
+
Available in tutorial mode.
|
|
630
|
+
"""
|
|
631
|
+
match ctx().global_state.mode:
|
|
632
|
+
case Mode.TUTORIAL:
|
|
633
|
+
return UiConfig(_TutorialRuntimeUiConfigs.instruction)
|
|
634
|
+
case _:
|
|
635
|
+
return UiConfig(None)
|
|
636
|
+
|
|
637
|
+
|
|
262
638
|
class Touch(Record):
|
|
263
639
|
"""Data of a touch event."""
|
|
264
640
|
|
|
@@ -612,6 +988,25 @@ def time() -> float:
|
|
|
612
988
|
return 0
|
|
613
989
|
|
|
614
990
|
|
|
991
|
+
@meta_fn
|
|
992
|
+
def offset_adjusted_time() -> float:
|
|
993
|
+
"""Get the current time of the game adjusted by the input offset.
|
|
994
|
+
|
|
995
|
+
Returns 0 in preview mode and tutorial mode.
|
|
996
|
+
"""
|
|
997
|
+
if not ctx():
|
|
998
|
+
return 0
|
|
999
|
+
match ctx().global_state.mode:
|
|
1000
|
+
case Mode.PLAY:
|
|
1001
|
+
return _PlayRuntimeUpdate.time - _PlayRuntimeEnvironment.input_offset
|
|
1002
|
+
case Mode.WATCH:
|
|
1003
|
+
return _WatchRuntimeUpdate.time - _WatchRuntimeEnvironment.input_offset
|
|
1004
|
+
case Mode.TUTORIAL:
|
|
1005
|
+
return _TutorialRuntimeUpdate.time
|
|
1006
|
+
case _:
|
|
1007
|
+
return 0
|
|
1008
|
+
|
|
1009
|
+
|
|
615
1010
|
@meta_fn
|
|
616
1011
|
def delta_time() -> float:
|
|
617
1012
|
"""Get the time elapsed since the last frame.
|
|
@@ -650,6 +1045,15 @@ def scaled_time() -> float:
|
|
|
650
1045
|
return 0
|
|
651
1046
|
|
|
652
1047
|
|
|
1048
|
+
@meta_fn
|
|
1049
|
+
def prev_time() -> float:
|
|
1050
|
+
"""Get the time of the previous frame.
|
|
1051
|
+
|
|
1052
|
+
Returns 0 in preview mode.
|
|
1053
|
+
"""
|
|
1054
|
+
return time() - delta_time()
|
|
1055
|
+
|
|
1056
|
+
|
|
653
1057
|
@meta_fn
|
|
654
1058
|
def touches() -> ArrayLike[Touch]:
|
|
655
1059
|
"""Get the current touches of the game."""
|
|
@@ -733,6 +1137,13 @@ preview_ui_configs = _PreviewRuntimeUiConfigs
|
|
|
733
1137
|
tutorial_ui = _TutorialRuntimeUi
|
|
734
1138
|
tutorial_ui_configs = _TutorialRuntimeUiConfigs
|
|
735
1139
|
|
|
1140
|
+
_runtime_ui = RuntimeUi()
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
def runtime_ui() -> RuntimeUi:
|
|
1144
|
+
"""Get the runtime UI configuration."""
|
|
1145
|
+
return _runtime_ui
|
|
1146
|
+
|
|
736
1147
|
|
|
737
1148
|
def canvas() -> _PreviewRuntimeCanvas:
|
|
738
1149
|
"""Get the preview canvas."""
|