sonolus.py 0.1.3__py3-none-any.whl → 0.1.4__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/allocate.py +125 -51
- sonolus/backend/blocks.py +756 -756
- sonolus/backend/coalesce.py +85 -0
- sonolus/backend/constant_evaluation.py +374 -0
- sonolus/backend/dead_code.py +80 -0
- sonolus/backend/dominance.py +111 -0
- sonolus/backend/excepthook.py +37 -37
- sonolus/backend/finalize.py +69 -69
- sonolus/backend/flow.py +121 -92
- sonolus/backend/inlining.py +150 -0
- sonolus/backend/ir.py +5 -3
- sonolus/backend/liveness.py +173 -0
- sonolus/backend/mode.py +24 -24
- sonolus/backend/node.py +40 -40
- sonolus/backend/ops.py +197 -197
- sonolus/backend/optimize.py +37 -9
- sonolus/backend/passes.py +52 -6
- sonolus/backend/simplify.py +47 -30
- sonolus/backend/ssa.py +187 -0
- sonolus/backend/utils.py +48 -48
- sonolus/backend/visitor.py +892 -882
- sonolus/build/cli.py +7 -1
- sonolus/build/compile.py +88 -90
- sonolus/build/level.py +24 -23
- sonolus/build/node.py +43 -43
- sonolus/script/archetype.py +23 -6
- sonolus/script/array.py +2 -2
- sonolus/script/bucket.py +191 -191
- sonolus/script/callbacks.py +127 -127
- sonolus/script/comptime.py +1 -1
- sonolus/script/containers.py +23 -0
- sonolus/script/debug.py +19 -3
- sonolus/script/easing.py +323 -0
- sonolus/script/effect.py +131 -131
- sonolus/script/globals.py +269 -269
- sonolus/script/graphics.py +200 -150
- sonolus/script/instruction.py +151 -151
- sonolus/script/internal/__init__.py +5 -5
- sonolus/script/internal/builtin_impls.py +144 -144
- sonolus/script/internal/context.py +12 -4
- sonolus/script/internal/descriptor.py +17 -17
- sonolus/script/internal/introspection.py +14 -14
- sonolus/script/internal/native.py +40 -38
- sonolus/script/internal/value.py +3 -3
- sonolus/script/interval.py +120 -112
- sonolus/script/iterator.py +214 -214
- sonolus/script/math.py +30 -1
- sonolus/script/num.py +1 -1
- sonolus/script/options.py +191 -191
- sonolus/script/particle.py +157 -157
- sonolus/script/pointer.py +30 -30
- sonolus/script/print.py +81 -81
- sonolus/script/random.py +14 -0
- sonolus/script/range.py +58 -58
- sonolus/script/record.py +3 -3
- sonolus/script/runtime.py +2 -0
- sonolus/script/sprite.py +333 -333
- sonolus/script/text.py +407 -407
- sonolus/script/timing.py +42 -42
- sonolus/script/transform.py +77 -23
- sonolus/script/ui.py +160 -160
- sonolus/script/vec.py +81 -78
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.4.dist-info}/METADATA +1 -1
- sonolus_py-0.1.4.dist-info/RECORD +84 -0
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.4.dist-info}/WHEEL +1 -1
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.4.dist-info}/licenses/LICENSE +21 -21
- sonolus_py-0.1.3.dist-info/RECORD +0 -75
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.4.dist-info}/entry_points.txt +0 -0
sonolus/build/cli.py
CHANGED
|
@@ -7,6 +7,7 @@ import socket
|
|
|
7
7
|
import socketserver
|
|
8
8
|
import sys
|
|
9
9
|
from pathlib import Path
|
|
10
|
+
from time import perf_counter
|
|
10
11
|
|
|
11
12
|
from sonolus.build.engine import package_engine
|
|
12
13
|
from sonolus.build.level import package_level_data
|
|
@@ -163,8 +164,13 @@ def main():
|
|
|
163
164
|
build_dir = Path(args.build_dir)
|
|
164
165
|
|
|
165
166
|
if args.command == "build":
|
|
167
|
+
start_time = perf_counter()
|
|
166
168
|
build_project(project, build_dir)
|
|
167
|
-
|
|
169
|
+
end_time = perf_counter()
|
|
170
|
+
print(f"Project built successfully to '{build_dir.resolve()}' in {end_time - start_time:.2f}s")
|
|
168
171
|
elif args.command == "dev":
|
|
172
|
+
start_time = perf_counter()
|
|
169
173
|
build_collection(project, build_dir)
|
|
174
|
+
end_time = perf_counter()
|
|
175
|
+
print(f"Build finished in {end_time - start_time:.2f}s")
|
|
170
176
|
run_server(build_dir / "site", port=args.port)
|
sonolus/build/compile.py
CHANGED
|
@@ -1,90 +1,88 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
|
|
3
|
-
from sonolus.backend.finalize import cfg_to_engine_node
|
|
4
|
-
from sonolus.backend.flow import BasicBlock
|
|
5
|
-
from sonolus.backend.ir import IRConst, IRInstr
|
|
6
|
-
from sonolus.backend.mode import Mode
|
|
7
|
-
from sonolus.backend.ops import Op
|
|
8
|
-
from sonolus.backend.optimize import optimize_and_allocate
|
|
9
|
-
from sonolus.backend.visitor import compile_and_call
|
|
10
|
-
from sonolus.build.node import OutputNodeGenerator
|
|
11
|
-
from sonolus.script.archetype import BaseArchetype
|
|
12
|
-
from sonolus.script.callbacks import CallbackInfo
|
|
13
|
-
from sonolus.script.internal.context import (
|
|
14
|
-
CallbackContextState,
|
|
15
|
-
Context,
|
|
16
|
-
GlobalContextState,
|
|
17
|
-
ReadOnlyMemory,
|
|
18
|
-
context_to_cfg,
|
|
19
|
-
ctx,
|
|
20
|
-
using_ctx,
|
|
21
|
-
)
|
|
22
|
-
from sonolus.script.num import is_num
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def compile_mode(
|
|
26
|
-
mode: Mode,
|
|
27
|
-
rom: ReadOnlyMemory,
|
|
28
|
-
archetypes: list[type[BaseArchetype]] | None,
|
|
29
|
-
global_callbacks: list[tuple[CallbackInfo, Callable]] | None,
|
|
30
|
-
) -> dict:
|
|
31
|
-
global_state = GlobalContextState(
|
|
32
|
-
mode, {a: i for i, a in enumerate(archetypes)} if archetypes is not None else None, rom
|
|
33
|
-
)
|
|
34
|
-
nodes = OutputNodeGenerator()
|
|
35
|
-
results = {}
|
|
36
|
-
if archetypes is not None:
|
|
37
|
-
archetype_entries = []
|
|
38
|
-
for archetype in archetypes:
|
|
39
|
-
archetype_data = {
|
|
40
|
-
"name": archetype.name,
|
|
41
|
-
"hasInput": archetype.is_scored,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
result = compile_and_call(callback
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
ctx().add_statements(IRInstr(Op.Break, [IRConst(1), result.ir()]))
|
|
90
|
-
return context_to_cfg(context)
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
|
|
3
|
+
from sonolus.backend.finalize import cfg_to_engine_node
|
|
4
|
+
from sonolus.backend.flow import BasicBlock
|
|
5
|
+
from sonolus.backend.ir import IRConst, IRInstr
|
|
6
|
+
from sonolus.backend.mode import Mode
|
|
7
|
+
from sonolus.backend.ops import Op
|
|
8
|
+
from sonolus.backend.optimize import optimize_and_allocate
|
|
9
|
+
from sonolus.backend.visitor import compile_and_call
|
|
10
|
+
from sonolus.build.node import OutputNodeGenerator
|
|
11
|
+
from sonolus.script.archetype import BaseArchetype
|
|
12
|
+
from sonolus.script.callbacks import CallbackInfo
|
|
13
|
+
from sonolus.script.internal.context import (
|
|
14
|
+
CallbackContextState,
|
|
15
|
+
Context,
|
|
16
|
+
GlobalContextState,
|
|
17
|
+
ReadOnlyMemory,
|
|
18
|
+
context_to_cfg,
|
|
19
|
+
ctx,
|
|
20
|
+
using_ctx,
|
|
21
|
+
)
|
|
22
|
+
from sonolus.script.num import is_num
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def compile_mode(
|
|
26
|
+
mode: Mode,
|
|
27
|
+
rom: ReadOnlyMemory,
|
|
28
|
+
archetypes: list[type[BaseArchetype]] | None,
|
|
29
|
+
global_callbacks: list[tuple[CallbackInfo, Callable]] | None,
|
|
30
|
+
) -> dict:
|
|
31
|
+
global_state = GlobalContextState(
|
|
32
|
+
mode, {a: i for i, a in enumerate(archetypes)} if archetypes is not None else None, rom
|
|
33
|
+
)
|
|
34
|
+
nodes = OutputNodeGenerator()
|
|
35
|
+
results = {}
|
|
36
|
+
if archetypes is not None:
|
|
37
|
+
archetype_entries = []
|
|
38
|
+
for archetype in archetypes:
|
|
39
|
+
archetype_data = {
|
|
40
|
+
"name": archetype.name,
|
|
41
|
+
"hasInput": archetype.is_scored,
|
|
42
|
+
"imports": [{"name": name, "index": index} for name, index in archetype._imported_keys_.items()],
|
|
43
|
+
}
|
|
44
|
+
if mode == Mode.PLAY:
|
|
45
|
+
archetype_data["exports"] = [
|
|
46
|
+
{"name": name, "index": index} for name, index in archetype._exported_keys_.items()
|
|
47
|
+
]
|
|
48
|
+
for cb_name, cb_info in archetype._supported_callbacks_.items():
|
|
49
|
+
cb = getattr(archetype, cb_name)
|
|
50
|
+
if cb in archetype._default_callbacks_:
|
|
51
|
+
continue
|
|
52
|
+
cb_order = getattr(cb, "_callback_order_", 0)
|
|
53
|
+
if not cb_info.supports_order and cb_order != 0:
|
|
54
|
+
raise ValueError(f"Callback '{cb_name}' does not support a non-zero order")
|
|
55
|
+
cfg = callback_to_cfg(global_state, cb, cb_info.name, archetype)
|
|
56
|
+
cfg = optimize_and_allocate(cfg)
|
|
57
|
+
node = cfg_to_engine_node(cfg)
|
|
58
|
+
node_index = nodes.add(node)
|
|
59
|
+
archetype_data[cb_info.name] = {
|
|
60
|
+
"index": node_index,
|
|
61
|
+
"order": cb_order,
|
|
62
|
+
}
|
|
63
|
+
archetype_entries.append(archetype_data)
|
|
64
|
+
results["archetypes"] = archetype_entries
|
|
65
|
+
if global_callbacks is not None:
|
|
66
|
+
for cb_info, cb in global_callbacks:
|
|
67
|
+
cfg = callback_to_cfg(global_state, cb, cb_info.name)
|
|
68
|
+
cfg = optimize_and_allocate(cfg)
|
|
69
|
+
node = cfg_to_engine_node(cfg)
|
|
70
|
+
node_index = nodes.add(node)
|
|
71
|
+
results[cb_info.name] = node_index
|
|
72
|
+
results["nodes"] = nodes.get()
|
|
73
|
+
return results
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def callback_to_cfg(
|
|
77
|
+
global_state: GlobalContextState, callback: Callable, name: str, archetype: type[BaseArchetype] | None = None
|
|
78
|
+
) -> BasicBlock:
|
|
79
|
+
callback_state = CallbackContextState(name)
|
|
80
|
+
context = Context(global_state, callback_state)
|
|
81
|
+
with using_ctx(context):
|
|
82
|
+
if archetype is not None:
|
|
83
|
+
result = compile_and_call(callback, archetype._for_compilation())
|
|
84
|
+
else:
|
|
85
|
+
result = compile_and_call(callback)
|
|
86
|
+
if is_num(result):
|
|
87
|
+
ctx().add_statements(IRInstr(Op.Break, [IRConst(1), result.ir()]))
|
|
88
|
+
return context_to_cfg(context)
|
sonolus/build/level.py
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
from sonolus.build.engine import package_output
|
|
2
|
-
from sonolus.script.level import LevelData
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def package_level_data(
|
|
6
|
-
level_data: LevelData,
|
|
7
|
-
):
|
|
8
|
-
return package_output(build_level_data(level_data))
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def build_level_data(
|
|
12
|
-
level_data: LevelData,
|
|
13
|
-
):
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
from sonolus.build.engine import package_output
|
|
2
|
+
from sonolus.script.level import LevelData
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def package_level_data(
|
|
6
|
+
level_data: LevelData,
|
|
7
|
+
):
|
|
8
|
+
return package_output(build_level_data(level_data))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def build_level_data(
|
|
12
|
+
level_data: LevelData,
|
|
13
|
+
):
|
|
14
|
+
level_refs = {entity: i for i, entity in enumerate(level_data.entities)}
|
|
15
|
+
return {
|
|
16
|
+
"bgmOffset": level_data.bgm_offset,
|
|
17
|
+
"entities": [
|
|
18
|
+
{
|
|
19
|
+
"archetype": entity.name,
|
|
20
|
+
"data": entity._level_data_entries(level_refs),
|
|
21
|
+
}
|
|
22
|
+
for entity in level_data.entities
|
|
23
|
+
],
|
|
24
|
+
}
|
sonolus/build/node.py
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
from typing import TypedDict
|
|
2
|
-
|
|
3
|
-
from sonolus.backend.node import ConstantNode, EngineNode, FunctionNode
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ValueOutputNode(TypedDict):
|
|
7
|
-
value: float
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class FunctionOutputNode(TypedDict):
|
|
11
|
-
func: str
|
|
12
|
-
args: list[int]
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class OutputNodeGenerator:
|
|
16
|
-
nodes: list[ValueOutputNode | FunctionOutputNode]
|
|
17
|
-
indexes: dict[EngineNode, int]
|
|
18
|
-
|
|
19
|
-
def __init__(self):
|
|
20
|
-
self.nodes = []
|
|
21
|
-
self.indexes = {}
|
|
22
|
-
|
|
23
|
-
def add(self, node: EngineNode):
|
|
24
|
-
if node in self.indexes:
|
|
25
|
-
return self.indexes[node]
|
|
26
|
-
|
|
27
|
-
match node:
|
|
28
|
-
case ConstantNode(value):
|
|
29
|
-
index = len(self.nodes)
|
|
30
|
-
self.nodes.append({"value": value})
|
|
31
|
-
self.indexes[node] = index
|
|
32
|
-
return index
|
|
33
|
-
case FunctionNode(func, args):
|
|
34
|
-
arg_indexes = [self.add(arg) for arg in args]
|
|
35
|
-
index = len(self.nodes)
|
|
36
|
-
self.nodes.append({"func": func.value, "args": arg_indexes})
|
|
37
|
-
self.indexes[node] = index
|
|
38
|
-
return index
|
|
39
|
-
case _:
|
|
40
|
-
raise ValueError("Invalid node")
|
|
41
|
-
|
|
42
|
-
def get(self):
|
|
43
|
-
return self.nodes
|
|
1
|
+
from typing import TypedDict
|
|
2
|
+
|
|
3
|
+
from sonolus.backend.node import ConstantNode, EngineNode, FunctionNode
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ValueOutputNode(TypedDict):
|
|
7
|
+
value: float
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FunctionOutputNode(TypedDict):
|
|
11
|
+
func: str
|
|
12
|
+
args: list[int]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OutputNodeGenerator:
|
|
16
|
+
nodes: list[ValueOutputNode | FunctionOutputNode]
|
|
17
|
+
indexes: dict[EngineNode, int]
|
|
18
|
+
|
|
19
|
+
def __init__(self):
|
|
20
|
+
self.nodes = []
|
|
21
|
+
self.indexes = {}
|
|
22
|
+
|
|
23
|
+
def add(self, node: EngineNode):
|
|
24
|
+
if node in self.indexes:
|
|
25
|
+
return self.indexes[node]
|
|
26
|
+
|
|
27
|
+
match node:
|
|
28
|
+
case ConstantNode(value):
|
|
29
|
+
index = len(self.nodes)
|
|
30
|
+
self.nodes.append({"value": value})
|
|
31
|
+
self.indexes[node] = index
|
|
32
|
+
return index
|
|
33
|
+
case FunctionNode(func, args):
|
|
34
|
+
arg_indexes = [self.add(arg) for arg in args]
|
|
35
|
+
index = len(self.nodes)
|
|
36
|
+
self.nodes.append({"func": func.value, "args": arg_indexes})
|
|
37
|
+
self.indexes[node] = index
|
|
38
|
+
return index
|
|
39
|
+
case _:
|
|
40
|
+
raise ValueError("Invalid node")
|
|
41
|
+
|
|
42
|
+
def get(self):
|
|
43
|
+
return self.nodes
|
sonolus/script/archetype.py
CHANGED
|
@@ -10,6 +10,7 @@ from typing import Annotated, Any, ClassVar, Self, get_origin
|
|
|
10
10
|
from sonolus.backend.ir import IRConst, IRInstr
|
|
11
11
|
from sonolus.backend.mode import Mode
|
|
12
12
|
from sonolus.backend.ops import Op
|
|
13
|
+
from sonolus.backend.place import BlockPlace
|
|
13
14
|
from sonolus.script.bucket import Bucket, Judgment
|
|
14
15
|
from sonolus.script.callbacks import PLAY_CALLBACKS, PREVIEW_CALLBACKS, WATCH_ARCHETYPE_CALLBACKS, CallbackInfo
|
|
15
16
|
from sonolus.script.internal.context import ctx
|
|
@@ -80,7 +81,7 @@ class ArchetypeField(SonolusDescriptor):
|
|
|
80
81
|
case ArchetypeReferenceData(index=index):
|
|
81
82
|
result = deref(
|
|
82
83
|
ctx().blocks.EntitySharedMemoryArray,
|
|
83
|
-
self.offset + index * ENTITY_SHARED_MEMORY_SIZE,
|
|
84
|
+
Num._accept_(self.offset) + index * ENTITY_SHARED_MEMORY_SIZE,
|
|
84
85
|
self.type,
|
|
85
86
|
)
|
|
86
87
|
case ArchetypeLevelData():
|
|
@@ -135,7 +136,7 @@ class ArchetypeField(SonolusDescriptor):
|
|
|
135
136
|
case ArchetypeReferenceData(index=index):
|
|
136
137
|
target = deref(
|
|
137
138
|
ctx().blocks.EntitySharedMemoryArray,
|
|
138
|
-
self.offset + index * ENTITY_SHARED_MEMORY_SIZE,
|
|
139
|
+
Num._accept_(self.offset) + index * ENTITY_SHARED_MEMORY_SIZE,
|
|
139
140
|
self.type,
|
|
140
141
|
)
|
|
141
142
|
case ArchetypeLevelData():
|
|
@@ -257,7 +258,7 @@ class BaseArchetype:
|
|
|
257
258
|
@meta_fn
|
|
258
259
|
def at(cls, index: Num) -> Self:
|
|
259
260
|
result = cls._new()
|
|
260
|
-
result._data_ = ArchetypeReferenceData(index=index)
|
|
261
|
+
result._data_ = ArchetypeReferenceData(index=Num._accept_(index))
|
|
261
262
|
return result
|
|
262
263
|
|
|
263
264
|
@classmethod
|
|
@@ -283,13 +284,13 @@ class BaseArchetype:
|
|
|
283
284
|
data.extend(field.type._accept_(bound.arguments[field.name] or zeros(field.type))._to_list_())
|
|
284
285
|
native_call(Op.Spawn, archetype_id, *(Num(x) for x in data))
|
|
285
286
|
|
|
286
|
-
def _level_data_entries(self):
|
|
287
|
+
def _level_data_entries(self, level_refs: dict[Any, int] | None = None):
|
|
287
288
|
if not isinstance(self._data_, ArchetypeLevelData):
|
|
288
289
|
raise RuntimeError("Entity is not level data")
|
|
289
290
|
entries = []
|
|
290
291
|
for name, value in self._data_.values.items():
|
|
291
292
|
field_info = self._imported_fields_.get(name)
|
|
292
|
-
for k, v in value._to_flat_dict_(field_info.data_name).items():
|
|
293
|
+
for k, v in value._to_flat_dict_(field_info.data_name, level_refs).items():
|
|
293
294
|
entries.append({"name": k, "value": v})
|
|
294
295
|
return entries
|
|
295
296
|
|
|
@@ -484,6 +485,13 @@ class PlayArchetype(BaseArchetype):
|
|
|
484
485
|
case _:
|
|
485
486
|
raise RuntimeError("Result is only accessible from the entity itself")
|
|
486
487
|
|
|
488
|
+
def ref(self):
|
|
489
|
+
if not isinstance(self._data_, ArchetypeLevelData):
|
|
490
|
+
raise RuntimeError("Entity is not level data")
|
|
491
|
+
result = EntityRef[type(self)](index=-1)
|
|
492
|
+
result._ref_ = self
|
|
493
|
+
return result
|
|
494
|
+
|
|
487
495
|
|
|
488
496
|
class WatchArchetype(BaseArchetype):
|
|
489
497
|
_supported_callbacks_ = WATCH_ARCHETYPE_CALLBACKS
|
|
@@ -674,7 +682,16 @@ class EntityRef[A: BaseArchetype](Record):
|
|
|
674
682
|
return cls._get_type_arg_(A)
|
|
675
683
|
|
|
676
684
|
def get(self) -> A:
|
|
677
|
-
return self.archetype().at(
|
|
685
|
+
return self.archetype().at(self.index)
|
|
686
|
+
|
|
687
|
+
def _to_list_(self, level_refs: dict[Any, int] | None = None) -> list[float | BlockPlace]:
|
|
688
|
+
ref = getattr(self, "_ref_", None)
|
|
689
|
+
if ref is None:
|
|
690
|
+
return [self.index]
|
|
691
|
+
else:
|
|
692
|
+
if ref not in level_refs:
|
|
693
|
+
raise KeyError("Reference to entity not in level data")
|
|
694
|
+
return [level_refs[ref]]
|
|
678
695
|
|
|
679
696
|
|
|
680
697
|
class StandardArchetypeName(StrEnum):
|
sonolus/script/array.py
CHANGED
|
@@ -97,10 +97,10 @@ class Array[T, Size](GenericValue, ArrayLike[T]):
|
|
|
97
97
|
iterator = iter(values)
|
|
98
98
|
return cls(*(cls.element_type()._from_list_(iterator) for _ in range(cls.size())))
|
|
99
99
|
|
|
100
|
-
def _to_list_(self) -> list[float | BlockPlace]:
|
|
100
|
+
def _to_list_(self, level_refs: dict[Any, int] | None = None) -> list[float | BlockPlace]:
|
|
101
101
|
match self._value:
|
|
102
102
|
case list():
|
|
103
|
-
return [entry for value in self._value for entry in value._to_list_()]
|
|
103
|
+
return [entry for value in self._value for entry in value._to_list_(level_refs)]
|
|
104
104
|
case BlockPlace():
|
|
105
105
|
return [
|
|
106
106
|
entry
|