sonolus.py 0.2.1__tar.gz → 0.3.1__tar.gz
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_py-0.2.1 → sonolus_py-0.3.1}/PKG-INFO +1 -1
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/concepts/builtins.md +2 -1
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/concepts/constructs.md +4 -4
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/concepts/project.md +34 -2
- sonolus_py-0.3.1/docs/concepts/resources.md +304 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/concepts/types.md +45 -28
- sonolus_py-0.3.1/docs/reference/sonolus.script.stream.md +3 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/mkdocs.yml +2 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/pyproject.toml +1 -1
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/ops.py +6 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/archetype.py +1 -1
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/array.py +56 -27
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/array_like.py +1 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/bucket.py +5 -3
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/constant.py +3 -1
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/generic.py +7 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/impl.py +10 -9
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/value.py +13 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/num.py +7 -4
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/particle.py +1 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/quad.py +3 -3
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/record.py +13 -2
- sonolus_py-0.3.1/sonolus/script/stream.py +553 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/transform.py +3 -3
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/values.py +11 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/uv.lock +1 -1
- sonolus_py-0.2.1/docs/concepts/resources.md +0 -244
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/.github/workflows/publish.yaml +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/.gitignore +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/.python-version +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/.run/Python tests in tests.run.xml +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/LICENSE +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/README.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/doc_stubs/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/doc_stubs/builtins.pyi +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/doc_stubs/math.pyi +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/doc_stubs/num.pyi +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/doc_stubs/random.pyi +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/CNAME +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/concepts/cli.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/concepts/index.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/index.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/builtins.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/index.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/math.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/random.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.archetype.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.array.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.array_like.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.bucket.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.containers.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.debug.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.easing.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.effect.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.engine.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.globals.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.instruction.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.interval.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.iterator.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.level.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.metadata.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.num.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.options.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.particle.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.printing.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.project.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.quad.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.record.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.runtime.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.sprite.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.text.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.timing.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.transform.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.ui.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.values.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/docs/reference/sonolus.script.vec.md +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/scripts/generate.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/scripts/runtimes/Engine/Tutorial/Blocks.json +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/scripts/runtimes/Functions.json +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/scripts/runtimes/Level/Play/Blocks.json +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/scripts/runtimes/Level/Preview/Blocks.json +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/scripts/runtimes/Level/Watch/Blocks.json +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/blocks.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/excepthook.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/finalize.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/interpret.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/ir.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/mode.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/node.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/allocate.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/constant_evaluation.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/copy_coalesce.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/dead_code.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/dominance.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/flow.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/inlining.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/liveness.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/optimize.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/passes.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/simplify.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/optimize/ssa.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/place.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/utils.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/backend/visitor.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/build/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/build/cli.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/build/collection.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/build/compile.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/build/engine.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/build/level.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/build/node.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/build/project.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/py.typed +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/containers.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/debug.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/easing.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/effect.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/engine.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/globals.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/instruction.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/builtin_impls.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/callbacks.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/context.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/descriptor.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/dict_impl.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/error.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/introspection.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/math_impls.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/native.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/random.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/range.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/transient.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/internal/tuple_impl.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/interval.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/iterator.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/level.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/metadata.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/options.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/pointer.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/printing.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/project.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/runtime.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/sprite.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/text.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/timing.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/ui.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/sonolus/script/vec.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/__init__.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/conftest.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_array.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_array_map.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_array_set.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_assert.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_dict.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_flow.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_functions.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_helpers.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_interval.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_match.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_num.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_operator.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_quad.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_random.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_range.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_record.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_transform.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_tuple.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_var_array.py +0 -0
- {sonolus_py-0.2.1 → sonolus_py-0.3.1}/tests/script/test_vec.py +0 -0
|
@@ -11,7 +11,8 @@ Sonolus.py comes with support for a number of built-in functions.
|
|
|
11
11
|
- `isinstance(object, classinfo)`
|
|
12
12
|
- `issubclass(class, classinfo)`
|
|
13
13
|
- `len(s)`
|
|
14
|
-
- `map(function, iterable)`
|
|
14
|
+
- `map(function, iterable)` (note: may differ from standard Python behavior, see
|
|
15
|
+
[`map`](../reference/builtins.md#doc_stubs.builtins.map))
|
|
15
16
|
- `max(iterable, *, key=None)`, `max(arg1, arg2, *args, key=None)`
|
|
16
17
|
- `min(iterable, *, key=None)`, `min(arg1, arg2, *args, key=None)`
|
|
17
18
|
- `range(stop)`, `range(start, stop[, step])`
|
|
@@ -30,8 +30,8 @@ The following constructs are supported in Sonolus.py:
|
|
|
30
30
|
- Unary: `+`, `-`, `not`, `~`
|
|
31
31
|
- Binary: `+`, `-`, `*`, `/`, `//`, `%`, `**`, `&`, `|`, `^`, `<<`, `>>`
|
|
32
32
|
- Comparison: `==`, `!=`, `>`, `<`, `>=`, `<=`, `is`, `is not`, `in`, `not in`
|
|
33
|
-
- Logical: `and`, `or` (for `Num` arguments only)
|
|
34
|
-
- Ternary: `a if <condition> else b` (for `Num` conditions only)
|
|
33
|
+
- Logical: `and`, `or` (for [`Num`](types.md#num) arguments only)
|
|
34
|
+
- Ternary: `a if <condition> else b` (for [`Num`](types.md#num) conditions only)
|
|
35
35
|
- Attribute: `a.b`
|
|
36
36
|
- Indexing: `a[b]`
|
|
37
37
|
- Call: `f(a, b, c)`
|
|
@@ -185,7 +185,7 @@ h = g[0] + g[1] + g[2]
|
|
|
185
185
|
(i := 1)
|
|
186
186
|
```
|
|
187
187
|
|
|
188
|
-
The ternary operator is supported for, but the condition must be a `Num
|
|
188
|
+
The ternary operator is supported for, but the condition must be a [`Num`](types.md#num). If the operands are not nums,
|
|
189
189
|
the condition must be a compile-time constant or this will be considered an error:
|
|
190
190
|
|
|
191
191
|
```python
|
|
@@ -448,7 +448,7 @@ Outside of functions returning `None` or a num, most functions should have a sin
|
|
|
448
448
|
|
|
449
449
|
### Classes
|
|
450
450
|
|
|
451
|
-
Classes are supported at the module level. User defined classes should subclass `Record` or have a supported
|
|
451
|
+
Classes are supported at the module level. User defined classes should subclass [`Record`][sonolus.script.record.Record] or have a supported
|
|
452
452
|
Sonolus.py decorator such as `@level_memory`.
|
|
453
453
|
|
|
454
454
|
Methods may have the `@staticmethod`, `@classmethod`, or `@property` decorators.
|
|
@@ -54,7 +54,9 @@ resources/
|
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
## Modes
|
|
57
|
-
Modes are defined using the `PlayMode
|
|
57
|
+
Modes are defined using the [`PlayMode`][sonolus.script.engine.PlayMode], [`WatchMode`][sonolus.script.engine.WatchMode], [`PreviewMode`][sonolus.script.engine.PreviewMode], and [`TutorialMode`][sonolus.script.engine.TutorialMode] classes.
|
|
58
|
+
|
|
59
|
+
### Play Mode
|
|
58
60
|
|
|
59
61
|
```python
|
|
60
62
|
from sonolus.script.engine import PlayMode
|
|
@@ -78,6 +80,14 @@ play_mode = PlayMode(
|
|
|
78
80
|
|
|
79
81
|
```
|
|
80
82
|
|
|
83
|
+
Play mode archetypes subclass [`PlayArchetype`][sonolus.script.archetype.PlayArchetype] and should implement the [`should_spawn`][sonolus.script.archetype.PlayArchetype.should_spawn] callback. They may also implement
|
|
84
|
+
the [`preprocess`][sonolus.script.archetype.PlayArchetype.preprocess], [`spawn_order`][sonolus.script.archetype.PlayArchetype.spawn_order], [`initialize`][sonolus.script.archetype.PlayArchetype.initialize], [`update_sequential`][sonolus.script.archetype.PlayArchetype.update_sequential], [`update_parallel`][sonolus.script.archetype.PlayArchetype.update_parallel], [`touch`][sonolus.script.archetype.PlayArchetype.touch], and
|
|
85
|
+
[`terminate`][sonolus.script.archetype.PlayArchetype.terminate] callbacks.
|
|
86
|
+
|
|
87
|
+
Archetypes for scored notes should have the [`is_scored`][sonolus.script.archetype.PlayArchetype.is_scored] class variable set to `True`.
|
|
88
|
+
|
|
89
|
+
### Watch Mode
|
|
90
|
+
|
|
81
91
|
```python
|
|
82
92
|
from sonolus.script.engine import WatchMode
|
|
83
93
|
|
|
@@ -100,6 +110,16 @@ watch_mode = WatchMode(
|
|
|
100
110
|
)
|
|
101
111
|
```
|
|
102
112
|
|
|
113
|
+
Watch mode archetypes subclass [`WatchArchetype`][sonolus.script.archetype.WatchArchetype] and should implement the [`spawn_time`][sonolus.script.archetype.WatchArchetype.spawn_time] and [`despawn_time`][sonolus.script.archetype.WatchArchetype.despawn_time] callbacks.
|
|
114
|
+
They may also implement the [`preprocess`][sonolus.script.archetype.WatchArchetype.preprocess], [`initialize`][sonolus.script.archetype.WatchArchetype.initialize], [`update_sequential`][sonolus.script.archetype.WatchArchetype.update_sequential], [`update_parallel`][sonolus.script.archetype.WatchArchetype.update_parallel], and
|
|
115
|
+
[`terminate`][sonolus.script.archetype.WatchArchetype.terminate] callbacks.
|
|
116
|
+
|
|
117
|
+
Watch mode also has the `update_spawn` global callback, which is invoked every frame and should return the reference
|
|
118
|
+
time to compare against spawn and despawn times of archetypes. Typically, this can be either the current time or the
|
|
119
|
+
current scaled time.
|
|
120
|
+
|
|
121
|
+
### Preview Mode
|
|
122
|
+
|
|
103
123
|
```python
|
|
104
124
|
from sonolus.script.engine import PreviewMode
|
|
105
125
|
|
|
@@ -115,6 +135,10 @@ preview_mode = PreviewMode(
|
|
|
115
135
|
)
|
|
116
136
|
```
|
|
117
137
|
|
|
138
|
+
Preview mode archetypes subclass [`PreviewArchetype`][sonolus.script.archetype.PreviewArchetype] and may implement the [`preprocess`][sonolus.script.archetype.PreviewArchetype.preprocess] and [`render`][sonolus.script.archetype.PreviewArchetype.render] callbacks.
|
|
139
|
+
|
|
140
|
+
### Tutorial Mode
|
|
141
|
+
|
|
118
142
|
```python
|
|
119
143
|
from sonolus.script.engine import TutorialMode
|
|
120
144
|
|
|
@@ -138,8 +162,16 @@ tutorial_mode = TutorialMode(
|
|
|
138
162
|
)
|
|
139
163
|
```
|
|
140
164
|
|
|
165
|
+
Tutorial mode does not have archetypes, but it has `preprocess`, `navigate`, and `update` global callbacks.
|
|
166
|
+
|
|
167
|
+
`preprocess` is invoked once before the tutorial starts.
|
|
168
|
+
|
|
169
|
+
`navigate` is invoked when the player navigates forward or backward in the tutorial.
|
|
170
|
+
|
|
171
|
+
`update` is invoked every frame and should handle most of the drawing logic.
|
|
172
|
+
|
|
141
173
|
## Levels
|
|
142
|
-
Levels are defined using the `Level` class:
|
|
174
|
+
Levels are defined using the [`Level`][sonolus.script.level.Level] class:
|
|
143
175
|
|
|
144
176
|
```python
|
|
145
177
|
from sonolus.script.level import LevelData, BpmChange, Level, TimescaleChange
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# Resources & Declarations
|
|
2
|
+
|
|
3
|
+
## Level Memory & Level Data
|
|
4
|
+
Level memory and level data are defined with the [`@level_memory`][sonolus.script.globals.level_memory] and [`@level_data`][sonolus.script.globals.level_data] class decorators, respectively:
|
|
5
|
+
|
|
6
|
+
```python
|
|
7
|
+
from sonolus.script.globals import level_memory, level_data
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@level_memory
|
|
11
|
+
class LevelMemory:
|
|
12
|
+
value: int
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@level_data
|
|
16
|
+
class LevelData:
|
|
17
|
+
value: int
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Alternatively, they may be called as functions as well by passing the type as an argument:
|
|
21
|
+
```python
|
|
22
|
+
from sonolus.script.globals import level_memory, level_data
|
|
23
|
+
from sonolus.script.vec import Vec2
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
level_memory_value = level_memory(Vec2)
|
|
27
|
+
level_data_value = level_data(Vec2)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Streams
|
|
31
|
+
Streams are defined with the [`@streams`][sonolus.script.stream.streams] decorator:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from sonolus.script.stream import streams, Stream, StreamGroup
|
|
35
|
+
from sonolus.script.num import Num
|
|
36
|
+
from sonolus.script.vec import Vec2
|
|
37
|
+
|
|
38
|
+
@streams
|
|
39
|
+
class Streams:
|
|
40
|
+
stream_1: Stream[Num] # A stream of Num values
|
|
41
|
+
stream_2: Stream[Vec2] # A stream of Vec2 values
|
|
42
|
+
group_1: StreamGroup[Num, 10] # A group of 10 Num streams
|
|
43
|
+
group_2: StreamGroup[Vec2, 5] # A group of 5 Vec2 streams
|
|
44
|
+
|
|
45
|
+
data_field_1: Num # A data field of type Num
|
|
46
|
+
data_field_2: Vec2 # A data field of type Vec2
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Streams and stream groups are declared by annotating class attributes with [`Stream`][sonolus.script.stream.Stream] or [`StreamGroup`][sonolus.script.stream.StreamGroup].
|
|
50
|
+
|
|
51
|
+
Other types are also supported in the form of data fields. They may be used to store additional data to export from
|
|
52
|
+
Play to Watch mode.
|
|
53
|
+
|
|
54
|
+
In either case, data is write-only in Play mode and read-only in Watch mode.
|
|
55
|
+
|
|
56
|
+
This should only be used once in most projects, as multiple decorated classes will overlap with each other and
|
|
57
|
+
interfere when both are used at the same time.
|
|
58
|
+
|
|
59
|
+
For backwards compatibility, new streams and stream groups should be added to the end of existing ones, and
|
|
60
|
+
lengths and element types of existing streams and stream groups should not be changed. Otherwise, old replays may
|
|
61
|
+
not work on new versions of the engine.
|
|
62
|
+
|
|
63
|
+
## Skins
|
|
64
|
+
Skins are defined with the [`@skin`][sonolus.script.sprite.skin] decorator:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from sonolus.script.sprite import skin, StandardSprite, sprite, Sprite, RenderMode
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@skin
|
|
71
|
+
class Skin:
|
|
72
|
+
render_mode: RenderMode = RenderMode.DEFAULT
|
|
73
|
+
|
|
74
|
+
note: StandardSprite.NOTE_HEAD_RED
|
|
75
|
+
other: Sprite = sprite("other")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Standard sprites are defined by annotating the field with the corresponding value from [`StandardSprite`][sonolus.script.sprite.StandardSprite].
|
|
79
|
+
|
|
80
|
+
Custom sprites are defined by annotating the field with [`Sprite`][sonolus.script.sprite.Sprite] and calling [`sprite`][sonolus.script.sprite.sprite] with the sprite name.
|
|
81
|
+
|
|
82
|
+
To set the render mode for the skin, set the `render_mode` field to the desired value from [`RenderMode`][sonolus.script.sprite.RenderMode].
|
|
83
|
+
|
|
84
|
+
## Sound Effects
|
|
85
|
+
Sound effects are defined with the [`@effects`][sonolus.script.effect.effects] decorator:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from sonolus.script.effect import effects, StandardEffect, Effect, effect
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@effects
|
|
92
|
+
class Effects:
|
|
93
|
+
tap_perfect: StandardEffect.PERFECT
|
|
94
|
+
other: Effect = effect("other")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Standard sound effects are defined by annotating the field with the corresponding value from [`StandardEffect`][sonolus.script.effect.StandardEffect].
|
|
98
|
+
|
|
99
|
+
Custom sound effects are defined by annotating the field with [`Effect`][sonolus.script.effect.Effect] and calling [`effect`][sonolus.script.effect.effect] with the effect name.
|
|
100
|
+
|
|
101
|
+
## Particles
|
|
102
|
+
Particles are defined with the [`@particles`][sonolus.script.particle.particles] decorator:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from sonolus.script.particle import particles, StandardParticle, Particle, particle
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@particles
|
|
109
|
+
class Particles:
|
|
110
|
+
tap: StandardParticle.NOTE_CIRCULAR_TAP_RED
|
|
111
|
+
other: Particle = particle("other")
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Standard particles are defined by annotating the field with the corresponding value from [`StandardParticle`][sonolus.script.particle.StandardParticle].
|
|
115
|
+
|
|
116
|
+
Custom particles are defined by annotating the field with [`Particle`][sonolus.script.particle.Particle] and calling [`particle`][sonolus.script.particle.particle] with the particle name.
|
|
117
|
+
|
|
118
|
+
## Buckets
|
|
119
|
+
Buckets are defined with the [`@buckets`][sonolus.script.bucket.buckets] decorator:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from sonolus.script.bucket import buckets, bucket_sprite, bucket, Bucket
|
|
123
|
+
from sonolus.script.text import StandardText
|
|
124
|
+
from my_engine.common.skin import Skin
|
|
125
|
+
|
|
126
|
+
@buckets
|
|
127
|
+
class Buckets:
|
|
128
|
+
note: Bucket = bucket(
|
|
129
|
+
sprites=[
|
|
130
|
+
bucket_sprite(
|
|
131
|
+
sprite=Skin.note,
|
|
132
|
+
x=0,
|
|
133
|
+
y=0,
|
|
134
|
+
w=2,
|
|
135
|
+
h=2,
|
|
136
|
+
)
|
|
137
|
+
],
|
|
138
|
+
unit=StandardText.MILLISECOND_UNIT,
|
|
139
|
+
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Buckets are defined by annotating the field with [`Bucket`][sonolus.script.bucket.Bucket] and calling [`bucket`][sonolus.script.bucket.bucket] with the bucket name.
|
|
143
|
+
|
|
144
|
+
## Tutorial Instructions
|
|
145
|
+
Tutorial instructions are defined with the [`@instructions`][sonolus.script.instruction.instructions] decorator:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from sonolus.script.instruction import instructions, StandardInstruction, Instruction, instruction
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@instructions
|
|
152
|
+
class Instructions:
|
|
153
|
+
tap: StandardInstruction.TAP
|
|
154
|
+
other: Instruction = instruction("other")
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Standard instructions are defined by annotating the field with the corresponding value from [`StandardInstruction`][sonolus.script.instruction.StandardInstruction].
|
|
158
|
+
|
|
159
|
+
Custom instructions are defined by annotating the field with [`Instruction`][sonolus.script.instruction.Instruction] and calling [`instruction`][sonolus.script.instruction.instruction] with the instruction name.
|
|
160
|
+
|
|
161
|
+
## Tutorial Instruction Icons
|
|
162
|
+
Tutorial instruction icons are defined with the [`@instruction_icons`][sonolus.script.instruction.instruction_icons] decorator:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from sonolus.script.instruction import instruction_icons, StandardInstructionIcon, InstructionIcon, instruction_icon
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@instruction_icons
|
|
169
|
+
class InstructionIcons:
|
|
170
|
+
hand: StandardInstructionIcon.HAND
|
|
171
|
+
other: InstructionIcon = instruction_icon("other")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Standard instruction icons are defined by annotating the field with the corresponding value from [`StandardInstructionIcon`][sonolus.script.instruction.StandardInstructionIcon].
|
|
175
|
+
|
|
176
|
+
Custom instruction icons are defined by annotating the field with [`InstructionIcon`][sonolus.script.instruction.InstructionIcon] and calling [`instruction_icon`][sonolus.script.instruction.instruction_icon] with the icon name.
|
|
177
|
+
|
|
178
|
+
## Options
|
|
179
|
+
Engine options are defined with the [`@options`][sonolus.script.options.options] decorator:
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from sonolus.script.options import options, select_option, slider_option, toggle_option
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@options
|
|
186
|
+
class Options:
|
|
187
|
+
slider_option: float = slider_option(
|
|
188
|
+
name="Slider Option",
|
|
189
|
+
standard=True,
|
|
190
|
+
advanced=False,
|
|
191
|
+
default=0.5,
|
|
192
|
+
min=0,
|
|
193
|
+
max=1,
|
|
194
|
+
step=0.1,
|
|
195
|
+
unit="unit",
|
|
196
|
+
scope="scope",
|
|
197
|
+
)
|
|
198
|
+
toggle_option: bool = toggle_option(
|
|
199
|
+
name="Toggle Option",
|
|
200
|
+
standard=True,
|
|
201
|
+
advanced=False,
|
|
202
|
+
default=True,
|
|
203
|
+
scope="scope",
|
|
204
|
+
)
|
|
205
|
+
select_option: int = select_option(
|
|
206
|
+
name="Select Option",
|
|
207
|
+
standard=True,
|
|
208
|
+
advanced=False,
|
|
209
|
+
default="value",
|
|
210
|
+
values=["value"],
|
|
211
|
+
scope="scope",
|
|
212
|
+
)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
There are three types of options available:
|
|
216
|
+
|
|
217
|
+
1. [`slider_option`][sonolus.script.options.slider_option]: A slider control for numeric values
|
|
218
|
+
2. [`toggle_option`][sonolus.script.options.toggle_option]: A toggle switch for boolean values
|
|
219
|
+
3. [`select_option`][sonolus.script.options.select_option]: A dropdown menu for selecting from predefined values
|
|
220
|
+
|
|
221
|
+
## UI
|
|
222
|
+
Ui configuration is defined with the [`UiConfig`][sonolus.script.ui.UiConfig] class:
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
from sonolus.script.ui import (
|
|
226
|
+
EaseType,
|
|
227
|
+
UiAnimation,
|
|
228
|
+
UiAnimationTween,
|
|
229
|
+
UiConfig,
|
|
230
|
+
UiJudgmentErrorPlacement,
|
|
231
|
+
UiJudgmentErrorStyle,
|
|
232
|
+
UiMetric,
|
|
233
|
+
UiVisibility,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
ui_config = UiConfig(
|
|
237
|
+
scope="my_engine",
|
|
238
|
+
primary_metric=UiMetric.ARCADE,
|
|
239
|
+
secondary_metric=UiMetric.LIFE,
|
|
240
|
+
menu_visibility=UiVisibility(
|
|
241
|
+
scale=1.0,
|
|
242
|
+
alpha=1.0,
|
|
243
|
+
),
|
|
244
|
+
judgment_visibility=UiVisibility(
|
|
245
|
+
scale=1.0,
|
|
246
|
+
alpha=1.0,
|
|
247
|
+
),
|
|
248
|
+
combo_visibility=UiVisibility(
|
|
249
|
+
scale=1.0,
|
|
250
|
+
alpha=1.0,
|
|
251
|
+
),
|
|
252
|
+
primary_metric_visibility=UiVisibility(
|
|
253
|
+
scale=1.0,
|
|
254
|
+
alpha=1.0,
|
|
255
|
+
),
|
|
256
|
+
secondary_metric_visibility=UiVisibility(
|
|
257
|
+
scale=1.0,
|
|
258
|
+
alpha=1.0,
|
|
259
|
+
),
|
|
260
|
+
progress_visibility=UiVisibility(
|
|
261
|
+
scale=1.0,
|
|
262
|
+
alpha=1.0,
|
|
263
|
+
),
|
|
264
|
+
tutorial_navigation_visibility=UiVisibility(
|
|
265
|
+
scale=1.0,
|
|
266
|
+
alpha=1.0,
|
|
267
|
+
),
|
|
268
|
+
tutorial_instruction_visibility=UiVisibility(
|
|
269
|
+
scale=1.0,
|
|
270
|
+
alpha=1.0,
|
|
271
|
+
),
|
|
272
|
+
judgment_animation=UiAnimation(
|
|
273
|
+
scale=UiAnimationTween(
|
|
274
|
+
start=1.0,
|
|
275
|
+
end=1.0,
|
|
276
|
+
duration=0.0,
|
|
277
|
+
ease=EaseType.NONE,
|
|
278
|
+
),
|
|
279
|
+
alpha=UiAnimationTween(
|
|
280
|
+
start=1.0,
|
|
281
|
+
end=1.0,
|
|
282
|
+
duration=0.0,
|
|
283
|
+
ease=EaseType.NONE,
|
|
284
|
+
),
|
|
285
|
+
),
|
|
286
|
+
combo_animation=UiAnimation(
|
|
287
|
+
scale=UiAnimationTween(
|
|
288
|
+
start=1.2,
|
|
289
|
+
end=1.0,
|
|
290
|
+
duration=0.2,
|
|
291
|
+
ease=EaseType.IN_CUBIC,
|
|
292
|
+
),
|
|
293
|
+
alpha=UiAnimationTween(
|
|
294
|
+
start=1.0,
|
|
295
|
+
end=1.0,
|
|
296
|
+
duration=0.0,
|
|
297
|
+
ease=EaseType.NONE,
|
|
298
|
+
),
|
|
299
|
+
),
|
|
300
|
+
judgment_error_style=UiJudgmentErrorStyle.LATE,
|
|
301
|
+
judgment_error_placement=UiJudgmentErrorPlacement.TOP,
|
|
302
|
+
judgment_error_min=0.0,
|
|
303
|
+
)
|
|
304
|
+
```
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
from sonolus.script.archetype import PlayArchetype
|
|
2
|
+
|
|
1
3
|
# Types
|
|
2
|
-
Sonolus.py has 3 core types: `Num
|
|
4
|
+
Sonolus.py has 3 core types: [`Num`](#num), [`Array`](#array), and [`Record`](#record). representing numeric values, fixed-size arrays,
|
|
3
5
|
and custom data structures, respectively. Arrays and records can be nested within each other to create complex data
|
|
4
6
|
structures.
|
|
5
7
|
|
|
@@ -89,13 +91,14 @@ Details:
|
|
|
89
91
|
|
|
90
92
|
## Array
|
|
91
93
|
|
|
92
|
-
`Array[T, Size]` stores a fixed number of elements of the same type.
|
|
94
|
+
[`Array[T, Size]`][sonolus.script.array.Array] stores a fixed number of elements of the same type.
|
|
93
95
|
|
|
94
96
|
It has two type parameters:
|
|
97
|
+
|
|
95
98
|
- `T`: The type of the elements.
|
|
96
99
|
- `Size`: The number of elements.
|
|
97
100
|
|
|
98
|
-
You can import `Array` from `sonolus.script.array`:
|
|
101
|
+
You can import [`Array`][sonolus.script.array.Array] from `sonolus.script.array`:
|
|
99
102
|
|
|
100
103
|
```python
|
|
101
104
|
from sonolus.script.array import Array
|
|
@@ -116,7 +119,7 @@ If at least one element is provided, the element type and size can be inferred:
|
|
|
116
119
|
a3 = Array(1, 2, 3)
|
|
117
120
|
```
|
|
118
121
|
|
|
119
|
-
Since `Array` takes type parameters, it is considered a generic type. A version of `Array` with type parameters provided
|
|
122
|
+
Since [`Array`][sonolus.script.array.Array] takes type parameters, it is considered a generic type. A version of [`Array`][sonolus.script.array.Array] with type parameters provided
|
|
120
123
|
is considered a concrete type.
|
|
121
124
|
|
|
122
125
|
```python
|
|
@@ -184,7 +187,7 @@ assert a == Array(4, 2, 3)
|
|
|
184
187
|
```
|
|
185
188
|
|
|
186
189
|
!!! warning
|
|
187
|
-
If a value in an array is not a `Num
|
|
190
|
+
If a value in an array is not a [`Num`](#num), updating it will copy the given value into the corresponding element
|
|
188
191
|
of the array. However, that element remains independent of the original value, which may lead to unexpected
|
|
189
192
|
results when updating either value.
|
|
190
193
|
|
|
@@ -200,7 +203,7 @@ assert a == Array(4, 2, 3)
|
|
|
200
203
|
```
|
|
201
204
|
|
|
202
205
|
For clarity, it's recommended to use the copy from operator (`@=`) when updating elements that are known to be
|
|
203
|
-
an array or record
|
|
206
|
+
an array or record.
|
|
204
207
|
|
|
205
208
|
```python
|
|
206
209
|
a[0] @= pair
|
|
@@ -223,18 +226,18 @@ for element in a:
|
|
|
223
226
|
|
|
224
227
|
Other functionality:
|
|
225
228
|
|
|
226
|
-
`Array` inherits from [ArrayLike][sonolus.script.array_like.ArrayLike] and supports all of its methods.
|
|
229
|
+
[`Array`][sonolus.script.array.Array] inherits from [`ArrayLike`][sonolus.script.array_like.ArrayLike] and supports all of its methods.
|
|
227
230
|
|
|
228
231
|
### Instance Checks
|
|
229
232
|
|
|
230
|
-
Any array is considered an instance of the generic `Array` type.
|
|
233
|
+
Any array is considered an instance of the generic [`Array`][sonolus.script.array.Array] type.
|
|
231
234
|
|
|
232
235
|
```python
|
|
233
236
|
a = Array(1, 2, 3)
|
|
234
237
|
assert isinstance(a, Array)
|
|
235
238
|
```
|
|
236
239
|
|
|
237
|
-
Only an array with the exact element type and size is considered an instance of a concrete `Array[T, Size]` type.
|
|
240
|
+
Only an array with the exact element type and size is considered an instance of a concrete [`Array[T, Size]`][sonolus.script.array.Array] type.
|
|
238
241
|
|
|
239
242
|
```python
|
|
240
243
|
a = Array(1, 2, 3)
|
|
@@ -245,8 +248,8 @@ assert not isinstance(a, Array[Pair, 3])
|
|
|
245
248
|
|
|
246
249
|
### Enums
|
|
247
250
|
|
|
248
|
-
There is limited support for enums containing `Num` values. Methods on enums are not supported.
|
|
249
|
-
When used as a type, any enum class is treated as `Num` and no enforcement is done on the values.
|
|
251
|
+
There is limited support for enums containing [`Num`](#num) values. Methods on enums are not supported.
|
|
252
|
+
When used as a type, any enum class is treated as [`Num`](#num) and no enforcement is done on the values.
|
|
250
253
|
|
|
251
254
|
```python
|
|
252
255
|
class MyEnum(IntEnum):
|
|
@@ -259,9 +262,9 @@ b = Array[MyEnum, 2](1, 2)
|
|
|
259
262
|
|
|
260
263
|
## Record
|
|
261
264
|
|
|
262
|
-
`Record` is the base class for user-defined types in Sonolus.py. It functions similarly to dataclasses.
|
|
265
|
+
[`Record`][sonolus.script.record.Record] is the base class for user-defined types in Sonolus.py. It functions similarly to dataclasses.
|
|
263
266
|
|
|
264
|
-
You can import `Record` from `sonolus.script.record`:
|
|
267
|
+
You can import [`Record`][sonolus.script.record.Record] from `sonolus.script.record`:
|
|
265
268
|
|
|
266
269
|
```python
|
|
267
270
|
from sonolus.script.record import Record
|
|
@@ -269,7 +272,7 @@ from sonolus.script.record import Record
|
|
|
269
272
|
|
|
270
273
|
### Declaration
|
|
271
274
|
|
|
272
|
-
A record can be defined by inheriting from `Record` and defining zero or more fields as class attributes:
|
|
275
|
+
A record can be defined by inheriting from [`Record`][sonolus.script.record.Record] and defining zero or more fields as class attributes:
|
|
273
276
|
|
|
274
277
|
```python
|
|
275
278
|
class MyPair(Record):
|
|
@@ -277,7 +280,7 @@ class MyPair(Record):
|
|
|
277
280
|
second: int
|
|
278
281
|
```
|
|
279
282
|
|
|
280
|
-
Fields must be annotated by `Num` (or equivalently `int`, `float`, or `bool`),
|
|
283
|
+
Fields must be annotated by [`Num`](#num) (or equivalently `int`, `float`, or `bool`),
|
|
281
284
|
a concrete array type, or a concrete record type.
|
|
282
285
|
|
|
283
286
|
```python
|
|
@@ -286,7 +289,7 @@ class MyRecord(Record):
|
|
|
286
289
|
array: Array # Array is not concrete since it has unspecified type parameters
|
|
287
290
|
```
|
|
288
291
|
|
|
289
|
-
A `Record` subclass cannot be further subclassed.
|
|
292
|
+
A [`Record`][sonolus.script.record.Record] subclass cannot be further subclassed.
|
|
290
293
|
|
|
291
294
|
```python
|
|
292
295
|
# Not ok:
|
|
@@ -296,7 +299,7 @@ class MyPairSubclass(MyPair):
|
|
|
296
299
|
|
|
297
300
|
### Instantiation
|
|
298
301
|
|
|
299
|
-
A constructor is automatically generated for the `Record` class:
|
|
302
|
+
A constructor is automatically generated for the [`Record`][sonolus.script.record.Record] class:
|
|
300
303
|
|
|
301
304
|
```python
|
|
302
305
|
pair_1 = MyPair(1, 2)
|
|
@@ -305,7 +308,7 @@ pair_2 = MyPair(first=1, second=2)
|
|
|
305
308
|
|
|
306
309
|
### Generics
|
|
307
310
|
|
|
308
|
-
`Record` supports generics. If at least one type parameter is provided in the class definition, a generic
|
|
311
|
+
[`Record`][sonolus.script.record.Record] supports generics. If at least one type parameter is provided in the class definition, a generic
|
|
309
312
|
record type is created.
|
|
310
313
|
|
|
311
314
|
```python
|
|
@@ -324,7 +327,7 @@ pair_1 = MyGenericPair[int, int](1, 2)
|
|
|
324
327
|
pair_2 = MyGenericPair(1, 2)
|
|
325
328
|
```
|
|
326
329
|
|
|
327
|
-
The value of a type parameter can be accessed via the `type_var_value()` classmethod.
|
|
330
|
+
The value of a type parameter can be accessed via the [`type_var_value()`][sonolus.script.record.Record.type_var_value] classmethod.
|
|
328
331
|
|
|
329
332
|
```python
|
|
330
333
|
class MyGenericRecord[T](Record):
|
|
@@ -368,7 +371,7 @@ class MyAddablePair(Record):
|
|
|
368
371
|
```
|
|
369
372
|
|
|
370
373
|
If a dunder method has an in-place variant and the in-place method is not explicitly implemented
|
|
371
|
-
(e.g. `__iadd__` is the in-place variant of `__add__`), `Record` will automatically generate one that
|
|
374
|
+
(e.g. `__iadd__` is the in-place variant of `__add__`), [`Record`][sonolus.script.record.Record] will automatically generate one that
|
|
372
375
|
modifies the instance in place:
|
|
373
376
|
|
|
374
377
|
```python
|
|
@@ -378,7 +381,7 @@ pair += MyAddablePair(3, 4)
|
|
|
378
381
|
assert pair == reference == MyAddablePair(4, 6) # The instance is modified in place
|
|
379
382
|
```
|
|
380
383
|
|
|
381
|
-
Regular methods, properties, classmethods, and staticmethods can also be defined in a `Record` subclass.
|
|
384
|
+
Regular methods, properties, classmethods, and staticmethods can also be defined in a [`Record`][sonolus.script.record.Record] subclass.
|
|
382
385
|
|
|
383
386
|
```python
|
|
384
387
|
class MyRecord(Record):
|
|
@@ -414,7 +417,7 @@ assert pair == MyPair(3, 2)
|
|
|
414
417
|
```
|
|
415
418
|
|
|
416
419
|
!!! warning
|
|
417
|
-
If a value in a record is not a `Num
|
|
420
|
+
If a value in a record is not a [`Num`](#num), updating it will copy the given value into the corresponding field
|
|
418
421
|
of the record. However, that field remains independent of the original value.
|
|
419
422
|
|
|
420
423
|
```python
|
|
@@ -437,7 +440,7 @@ assert pair == MyPair(3, 2)
|
|
|
437
440
|
|
|
438
441
|
### Instance Checks
|
|
439
442
|
|
|
440
|
-
Any record is considered an instance of the generic `Record` type:
|
|
443
|
+
Any record is considered an instance of the generic [`Record`][sonolus.script.record.Record] type:
|
|
441
444
|
|
|
442
445
|
```python
|
|
443
446
|
pair = MyPair(1, 2)
|
|
@@ -451,7 +454,7 @@ pair = MyGenericPair[int, int](1, 2)
|
|
|
451
454
|
assert isinstance(pair, MyGenericPair)
|
|
452
455
|
```
|
|
453
456
|
|
|
454
|
-
Only an instance of a record with the exact field types is considered an instance of a concrete `Record` type:
|
|
457
|
+
Only an instance of a record with the exact field types is considered an instance of a concrete [`Record`][sonolus.script.record.Record] type:
|
|
455
458
|
|
|
456
459
|
```python
|
|
457
460
|
pair = MyPair(1, 2)
|
|
@@ -460,10 +463,24 @@ assert not isinstance(pair, MyPair[int, Array[int, 2]])
|
|
|
460
463
|
```
|
|
461
464
|
|
|
462
465
|
## Transient Types
|
|
463
|
-
In addition to the
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
466
|
+
In addition to the core types, the following transient types are available.
|
|
467
|
+
There are some restrictions on how they can be used:
|
|
468
|
+
|
|
469
|
+
- They cannot be used as type arguments:
|
|
470
|
+
```python
|
|
471
|
+
# Not ok:
|
|
472
|
+
Array[str, 3]
|
|
473
|
+
```
|
|
474
|
+
- They cannot be used as a field types:
|
|
475
|
+
```python
|
|
476
|
+
# Not ok:
|
|
477
|
+
class MyRecord(Record):
|
|
478
|
+
field: str
|
|
479
|
+
|
|
480
|
+
# Not ok:
|
|
481
|
+
class MyArchetype(PlayArchetype):
|
|
482
|
+
field: str = imported()
|
|
483
|
+
```
|
|
467
484
|
|
|
468
485
|
### tuple
|
|
469
486
|
|
|
@@ -9,6 +9,7 @@ theme:
|
|
|
9
9
|
- navigation.expand
|
|
10
10
|
- navigation.path
|
|
11
11
|
- navigation.indexes
|
|
12
|
+
- navigation.footer
|
|
12
13
|
- toc.follow
|
|
13
14
|
- navigation.top
|
|
14
15
|
palette:
|
|
@@ -106,6 +107,7 @@ nav:
|
|
|
106
107
|
- reference/sonolus.script.record.md
|
|
107
108
|
- reference/sonolus.script.runtime.md
|
|
108
109
|
- reference/sonolus.script.sprite.md
|
|
110
|
+
- reference/sonolus.script.stream.md
|
|
109
111
|
- reference/sonolus.script.text.md
|
|
110
112
|
- reference/sonolus.script.timing.md
|
|
111
113
|
- reference/sonolus.script.transform.md
|
|
@@ -180,6 +180,12 @@ class Op(StrEnum):
|
|
|
180
180
|
StackSetPointer = ("StackSetPointer", True, False, False)
|
|
181
181
|
StopLooped = ("StopLooped", True, False, False)
|
|
182
182
|
StopLoopedScheduled = ("StopLoopedScheduled", True, False, False)
|
|
183
|
+
# Streams are immutable when they're readable, so we can treat read operations as pure.
|
|
184
|
+
StreamGetNextKey = ("StreamGetNextKey", False, True, False)
|
|
185
|
+
StreamGetPreviousKey = ("StreamGetPreviousKey", False, True, False)
|
|
186
|
+
StreamGetValue = ("StreamGetValue", False, True, False)
|
|
187
|
+
StreamHas = ("StreamHas", False, True, False)
|
|
188
|
+
StreamSet = ("StreamSet", True, False, False)
|
|
183
189
|
Subtract = ("Subtract", False, True, False)
|
|
184
190
|
Switch = ("Switch", False, True, True)
|
|
185
191
|
SwitchInteger = ("SwitchInteger", False, True, True)
|