sonolus.py 0.1.2__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 -880
- sonolus/build/cli.py +7 -1
- sonolus/build/compile.py +88 -90
- sonolus/build/engine.py +55 -5
- 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 -115
- 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/engine.py +37 -1
- sonolus/script/globals.py +269 -269
- sonolus/script/graphics.py +200 -150
- sonolus/script/instruction.py +151 -0
- 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 -211
- 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/{preview.py → 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 +45 -6
- 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 -72
- {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/METADATA +1 -2
- sonolus_py-0.1.4.dist-info/RECORD +84 -0
- {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/WHEEL +1 -1
- {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/licenses/LICENSE +21 -21
- sonolus/build/defaults.py +0 -32
- sonolus/script/icon.py +0 -73
- sonolus_py-0.1.2.dist-info/RECORD +0 -76
- {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/entry_points.txt +0 -0
sonolus/script/engine.py
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from collections.abc import Callable
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
5
6
|
from sonolus.build.collection import Asset
|
|
6
7
|
from sonolus.script.archetype import BaseArchetype, PlayArchetype, PreviewArchetype, WatchArchetype
|
|
7
8
|
from sonolus.script.bucket import Buckets, EmptyBuckets
|
|
8
9
|
from sonolus.script.effect import Effects, EmptyEffects
|
|
10
|
+
from sonolus.script.instruction import (
|
|
11
|
+
EmptyInstructionIcons,
|
|
12
|
+
EmptyInstructions,
|
|
13
|
+
TutorialInstructionIcons,
|
|
14
|
+
TutorialInstructions,
|
|
15
|
+
)
|
|
9
16
|
from sonolus.script.options import EmptyOptions, Options
|
|
10
17
|
from sonolus.script.particle import EmptyParticles, Particles
|
|
11
18
|
from sonolus.script.sprite import EmptySkin, Skin
|
|
@@ -41,7 +48,7 @@ class Engine:
|
|
|
41
48
|
self.data = data
|
|
42
49
|
|
|
43
50
|
|
|
44
|
-
def default_callback() ->
|
|
51
|
+
def default_callback() -> Any:
|
|
45
52
|
return 0.0
|
|
46
53
|
|
|
47
54
|
|
|
@@ -104,6 +111,29 @@ class PreviewMode:
|
|
|
104
111
|
raise ValueError(f"archetype {archetype} is not a BaseArchetype")
|
|
105
112
|
|
|
106
113
|
|
|
114
|
+
class TutorialMode:
|
|
115
|
+
def __init__(
|
|
116
|
+
self,
|
|
117
|
+
*,
|
|
118
|
+
skin: Skin = EmptySkin,
|
|
119
|
+
effects: Effects = EmptyEffects,
|
|
120
|
+
particles: Particles = EmptyParticles,
|
|
121
|
+
instructions: TutorialInstructions = EmptyInstructions,
|
|
122
|
+
instruction_icons: TutorialInstructionIcons = EmptyInstructionIcons,
|
|
123
|
+
preprocess: Callable[[], None],
|
|
124
|
+
navigate: Callable[[], None],
|
|
125
|
+
update: Callable[[], None],
|
|
126
|
+
) -> None:
|
|
127
|
+
self.skin = skin
|
|
128
|
+
self.effects = effects
|
|
129
|
+
self.particles = particles
|
|
130
|
+
self.instructions = instructions
|
|
131
|
+
self.instruction_icons = instruction_icons
|
|
132
|
+
self.preprocess = preprocess
|
|
133
|
+
self.navigate = navigate
|
|
134
|
+
self.update = update
|
|
135
|
+
|
|
136
|
+
|
|
107
137
|
class EngineData:
|
|
108
138
|
def __init__(
|
|
109
139
|
self,
|
|
@@ -113,9 +143,15 @@ class EngineData:
|
|
|
113
143
|
play: PlayMode | None = None,
|
|
114
144
|
watch: WatchMode | None = None,
|
|
115
145
|
preview: PreviewMode | None = None,
|
|
146
|
+
tutorial: TutorialMode | None = None,
|
|
116
147
|
) -> None:
|
|
117
148
|
self.ui = ui or UiConfig()
|
|
118
149
|
self.options = options
|
|
119
150
|
self.play = play or PlayMode()
|
|
120
151
|
self.watch = watch or WatchMode(update_spawn=default_callback)
|
|
121
152
|
self.preview = preview or PreviewMode()
|
|
153
|
+
self.tutorial = tutorial or TutorialMode(
|
|
154
|
+
preprocess=default_callback,
|
|
155
|
+
navigate=default_callback,
|
|
156
|
+
update=default_callback,
|
|
157
|
+
)
|
sonolus/script/globals.py
CHANGED
|
@@ -1,269 +1,269 @@
|
|
|
1
|
-
import inspect
|
|
2
|
-
from typing import dataclass_transform
|
|
3
|
-
|
|
4
|
-
from sonolus.backend.blocks import Block, PlayBlock, PreviewBlock, TutorialBlock, WatchBlock
|
|
5
|
-
from sonolus.backend.mode import Mode
|
|
6
|
-
from sonolus.script.internal.descriptor import SonolusDescriptor
|
|
7
|
-
from sonolus.script.internal.generic import validate_concrete_type
|
|
8
|
-
from sonolus.script.internal.value import Value
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class GlobalInfo:
|
|
12
|
-
def __init__(self, name: str, size: int, blocks: dict[Mode, Block], offset: int | None):
|
|
13
|
-
self.name = name
|
|
14
|
-
self.size = size
|
|
15
|
-
self.blocks = blocks
|
|
16
|
-
self.offset = offset
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class GlobalField(SonolusDescriptor):
|
|
20
|
-
def __init__(self, name: str, type_: type[Value], index: int, offset: int):
|
|
21
|
-
self.name = name
|
|
22
|
-
self.type = type_
|
|
23
|
-
self.index = index
|
|
24
|
-
self.offset = offset
|
|
25
|
-
|
|
26
|
-
def __get__(self, instance, owner):
|
|
27
|
-
if instance is None:
|
|
28
|
-
return self
|
|
29
|
-
|
|
30
|
-
from sonolus.script.internal.context import ctx
|
|
31
|
-
|
|
32
|
-
info = owner._global_info_
|
|
33
|
-
if not ctx():
|
|
34
|
-
raise RuntimeError("Global field access outside of compilation")
|
|
35
|
-
base = ctx().get_global_base(info)
|
|
36
|
-
return self.type._from_place_(base.add_offset(self.offset))._get_()
|
|
37
|
-
|
|
38
|
-
def __set__(self, instance, value):
|
|
39
|
-
from sonolus.script.internal.context import ctx
|
|
40
|
-
|
|
41
|
-
info = instance._global_info_
|
|
42
|
-
if not ctx():
|
|
43
|
-
raise RuntimeError("Global field access outside of compilation")
|
|
44
|
-
base = ctx().get_global_base(info)
|
|
45
|
-
target = self.type._from_place_(base.add_offset(self.offset))
|
|
46
|
-
if self.type._is_value_type_():
|
|
47
|
-
target._set_(value)
|
|
48
|
-
else:
|
|
49
|
-
target._copy_from_(value)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class GlobalPlaceholder:
|
|
53
|
-
def __init__(self, type_: type[Value], blocks: dict[Mode, Block], offset: int | None):
|
|
54
|
-
self.type = type_
|
|
55
|
-
self.blocks = blocks
|
|
56
|
-
self.offset = offset
|
|
57
|
-
self.size = type_._size_()
|
|
58
|
-
|
|
59
|
-
def get(self):
|
|
60
|
-
from sonolus.script.internal.context import ctx
|
|
61
|
-
|
|
62
|
-
if not ctx():
|
|
63
|
-
raise RuntimeError("Global access outside of compilation")
|
|
64
|
-
base = ctx().get_global_base(self)
|
|
65
|
-
return self.type._from_place_(base)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def create_global(cls: type, blocks: dict[Mode, Block], offset: int | None):
|
|
69
|
-
if issubclass(cls, Value):
|
|
70
|
-
cls = validate_concrete_type(cls)
|
|
71
|
-
return GlobalPlaceholder(cls, blocks, offset)
|
|
72
|
-
if len(cls.__bases__) != 1:
|
|
73
|
-
raise TypeError("Expected a class with no bases or a Value subclass")
|
|
74
|
-
field_offset = 0
|
|
75
|
-
for i, (
|
|
76
|
-
name,
|
|
77
|
-
annotation,
|
|
78
|
-
) in enumerate(inspect.get_annotations(cls, eval_str=True).items()):
|
|
79
|
-
type_ = validate_concrete_type(annotation)
|
|
80
|
-
setattr(cls, name, GlobalField(name, type_, i, field_offset))
|
|
81
|
-
field_offset += type_._size_()
|
|
82
|
-
cls._global_info_ = GlobalInfo(cls.__name__, field_offset, blocks, offset)
|
|
83
|
-
cls._is_comptime_value_ = True
|
|
84
|
-
return cls()
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@dataclass_transform()
|
|
88
|
-
def _play_runtime_environment[T](cls: type[T]) -> T:
|
|
89
|
-
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeEnvironment}, 0)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
@dataclass_transform()
|
|
93
|
-
def _watch_runtime_environment[T](cls: type[T]) -> T:
|
|
94
|
-
return create_global(cls, {Mode.WATCH: WatchBlock.RuntimeEnvironment}, 0)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@dataclass_transform()
|
|
98
|
-
def _tutorial_runtime_environment[T](cls: type[T]) -> T:
|
|
99
|
-
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.RuntimeEnvironment}, 0)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
@dataclass_transform()
|
|
103
|
-
def _preview_runtime_environment[T](cls: type[T]) -> T:
|
|
104
|
-
return create_global(cls, {Mode.PREVIEW: PreviewBlock.RuntimeEnvironment}, 0)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@dataclass_transform()
|
|
108
|
-
def _play_runtime_update[T](cls: type[T]) -> T:
|
|
109
|
-
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeUpdate}, 0)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
@dataclass_transform()
|
|
113
|
-
def _watch_runtime_update[T](cls: type[T]) -> T:
|
|
114
|
-
return create_global(cls, {Mode.WATCH: WatchBlock.RuntimeUpdate}, 0)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
@dataclass_transform()
|
|
118
|
-
def _preview_runtime_canvas[T](cls: type[T]) -> T:
|
|
119
|
-
return create_global(cls, {Mode.PREVIEW: PreviewBlock.RuntimeCanvas}, 0)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
@dataclass_transform()
|
|
123
|
-
def _tutorial_runtime_update[T](cls: type[T]) -> T:
|
|
124
|
-
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.RuntimeUpdate}, 0)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
@dataclass_transform()
|
|
128
|
-
def _runtime_touch_array[T](cls: type[T]) -> T:
|
|
129
|
-
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeTouchArray}, 0)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
@dataclass_transform()
|
|
133
|
-
def _runtime_skin_transform[T](cls: type[T]) -> T:
|
|
134
|
-
return create_global(
|
|
135
|
-
cls,
|
|
136
|
-
{
|
|
137
|
-
Mode.PLAY: PlayBlock.RuntimeSkinTransform,
|
|
138
|
-
Mode.WATCH: WatchBlock.RuntimeSkinTransform,
|
|
139
|
-
Mode.PREVIEW: PreviewBlock.RuntimeSkinTransform,
|
|
140
|
-
Mode.TUTORIAL: TutorialBlock.RuntimeSkinTransform,
|
|
141
|
-
},
|
|
142
|
-
0,
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
@dataclass_transform()
|
|
147
|
-
def _runtime_particle_transform[T](cls: type[T]) -> T:
|
|
148
|
-
return create_global(
|
|
149
|
-
cls,
|
|
150
|
-
{
|
|
151
|
-
Mode.PLAY: PlayBlock.RuntimeParticleTransform,
|
|
152
|
-
Mode.WATCH: WatchBlock.RuntimeParticleTransform,
|
|
153
|
-
Mode.TUTORIAL: TutorialBlock.RuntimeParticleTransform,
|
|
154
|
-
},
|
|
155
|
-
0,
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@dataclass_transform()
|
|
160
|
-
def _runtime_background[T](cls: type[T]) -> T:
|
|
161
|
-
return create_global(
|
|
162
|
-
cls,
|
|
163
|
-
{
|
|
164
|
-
Mode.PLAY: PlayBlock.RuntimeBackground,
|
|
165
|
-
Mode.WATCH: WatchBlock.RuntimeBackground,
|
|
166
|
-
Mode.TUTORIAL: TutorialBlock.RuntimeBackground,
|
|
167
|
-
},
|
|
168
|
-
0,
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
@dataclass_transform()
|
|
173
|
-
def _play_runtime_ui[T](cls: type[T]) -> T:
|
|
174
|
-
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeUI}, 0)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
@dataclass_transform()
|
|
178
|
-
def _watch_runtime_ui[T](cls: type[T]) -> T:
|
|
179
|
-
return create_global(cls, {Mode.WATCH: WatchBlock.RuntimeUI}, 0)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
@dataclass_transform()
|
|
183
|
-
def _tutorial_runtime_ui[T](cls: type[T]) -> T:
|
|
184
|
-
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.RuntimeUI}, 0)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
@dataclass_transform()
|
|
188
|
-
def _preview_runtime_ui[T](cls: type[T]) -> T:
|
|
189
|
-
return create_global(cls, {Mode.PREVIEW: PreviewBlock.RuntimeUI}, 0)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
@dataclass_transform()
|
|
193
|
-
def _play_runtime_ui_configuration[T](cls: type[T]) -> T:
|
|
194
|
-
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeUIConfiguration}, 0)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
@dataclass_transform()
|
|
198
|
-
def _watch_runtime_ui_configuration[T](cls: type[T]) -> T:
|
|
199
|
-
return create_global(cls, {Mode.WATCH: WatchBlock.RuntimeUIConfiguration}, 0)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
@dataclass_transform()
|
|
203
|
-
def _tutorial_runtime_ui_configuration[T](cls: type[T]) -> T:
|
|
204
|
-
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.RuntimeUIConfiguration}, 0)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
@dataclass_transform()
|
|
208
|
-
def _preview_runtime_ui_configuration[T](cls: type[T]) -> T:
|
|
209
|
-
return create_global(cls, {Mode.PREVIEW: PreviewBlock.RuntimeUIConfiguration}, 0)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
@dataclass_transform()
|
|
213
|
-
def _tutorial_instruction[T](cls: type[T]) -> T:
|
|
214
|
-
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.TutorialInstruction}, 0)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
@dataclass_transform()
|
|
218
|
-
def level_memory[T](cls: type[T]) -> T:
|
|
219
|
-
return create_global(
|
|
220
|
-
cls,
|
|
221
|
-
{
|
|
222
|
-
Mode.PLAY: PlayBlock.LevelMemory,
|
|
223
|
-
Mode.WATCH: WatchBlock.LevelMemory,
|
|
224
|
-
Mode.TUTORIAL: TutorialBlock.TutorialMemory,
|
|
225
|
-
},
|
|
226
|
-
None,
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
@dataclass_transform()
|
|
231
|
-
def level_data[T](cls: type[T]) -> T:
|
|
232
|
-
return create_global(
|
|
233
|
-
cls,
|
|
234
|
-
{
|
|
235
|
-
Mode.PLAY: PlayBlock.LevelData,
|
|
236
|
-
Mode.WATCH: WatchBlock.LevelData,
|
|
237
|
-
Mode.PREVIEW: PreviewBlock.PreviewData,
|
|
238
|
-
Mode.TUTORIAL: TutorialBlock.TutorialData,
|
|
239
|
-
},
|
|
240
|
-
None,
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
# level_option is handled by the options decorator
|
|
245
|
-
# level_bucket is handled by the bucket decorator
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
@dataclass_transform()
|
|
249
|
-
def _level_score[T](cls: type[T]) -> T:
|
|
250
|
-
return create_global(cls, {Mode.PLAY: PlayBlock.LevelScore, Mode.WATCH: WatchBlock.LevelScore}, 0)
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
@dataclass_transform()
|
|
254
|
-
def _level_life[T](cls: type[T]) -> T:
|
|
255
|
-
return create_global(cls, {Mode.PLAY: PlayBlock.LevelLife, Mode.WATCH: WatchBlock.LevelLife}, 0)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
# engine_rom is handled by the compiler
|
|
259
|
-
# entity memory is handled by the archetype
|
|
260
|
-
# entity data is handled by the archetype
|
|
261
|
-
# entity shared memory is handled by the archetype
|
|
262
|
-
# entity info is handled by the archetype
|
|
263
|
-
# entity despawn is handled by the archetype
|
|
264
|
-
# entity input is handled by the archetype
|
|
265
|
-
# entity data array is handled by the archetype
|
|
266
|
-
# entity shared memory array is handled by the archetype
|
|
267
|
-
# entity info array is handled by the archetype
|
|
268
|
-
# archetype life is handled by the archetype
|
|
269
|
-
# temporary memory is handled by the compiler
|
|
1
|
+
import inspect
|
|
2
|
+
from typing import dataclass_transform
|
|
3
|
+
|
|
4
|
+
from sonolus.backend.blocks import Block, PlayBlock, PreviewBlock, TutorialBlock, WatchBlock
|
|
5
|
+
from sonolus.backend.mode import Mode
|
|
6
|
+
from sonolus.script.internal.descriptor import SonolusDescriptor
|
|
7
|
+
from sonolus.script.internal.generic import validate_concrete_type
|
|
8
|
+
from sonolus.script.internal.value import Value
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GlobalInfo:
|
|
12
|
+
def __init__(self, name: str, size: int, blocks: dict[Mode, Block], offset: int | None):
|
|
13
|
+
self.name = name
|
|
14
|
+
self.size = size
|
|
15
|
+
self.blocks = blocks
|
|
16
|
+
self.offset = offset
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GlobalField(SonolusDescriptor):
|
|
20
|
+
def __init__(self, name: str, type_: type[Value], index: int, offset: int):
|
|
21
|
+
self.name = name
|
|
22
|
+
self.type = type_
|
|
23
|
+
self.index = index
|
|
24
|
+
self.offset = offset
|
|
25
|
+
|
|
26
|
+
def __get__(self, instance, owner):
|
|
27
|
+
if instance is None:
|
|
28
|
+
return self
|
|
29
|
+
|
|
30
|
+
from sonolus.script.internal.context import ctx
|
|
31
|
+
|
|
32
|
+
info = owner._global_info_
|
|
33
|
+
if not ctx():
|
|
34
|
+
raise RuntimeError("Global field access outside of compilation")
|
|
35
|
+
base = ctx().get_global_base(info)
|
|
36
|
+
return self.type._from_place_(base.add_offset(self.offset))._get_()
|
|
37
|
+
|
|
38
|
+
def __set__(self, instance, value):
|
|
39
|
+
from sonolus.script.internal.context import ctx
|
|
40
|
+
|
|
41
|
+
info = instance._global_info_
|
|
42
|
+
if not ctx():
|
|
43
|
+
raise RuntimeError("Global field access outside of compilation")
|
|
44
|
+
base = ctx().get_global_base(info)
|
|
45
|
+
target = self.type._from_place_(base.add_offset(self.offset))
|
|
46
|
+
if self.type._is_value_type_():
|
|
47
|
+
target._set_(value)
|
|
48
|
+
else:
|
|
49
|
+
target._copy_from_(value)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class GlobalPlaceholder:
|
|
53
|
+
def __init__(self, type_: type[Value], blocks: dict[Mode, Block], offset: int | None):
|
|
54
|
+
self.type = type_
|
|
55
|
+
self.blocks = blocks
|
|
56
|
+
self.offset = offset
|
|
57
|
+
self.size = type_._size_()
|
|
58
|
+
|
|
59
|
+
def get(self):
|
|
60
|
+
from sonolus.script.internal.context import ctx
|
|
61
|
+
|
|
62
|
+
if not ctx():
|
|
63
|
+
raise RuntimeError("Global access outside of compilation")
|
|
64
|
+
base = ctx().get_global_base(self)
|
|
65
|
+
return self.type._from_place_(base)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def create_global(cls: type, blocks: dict[Mode, Block], offset: int | None):
|
|
69
|
+
if issubclass(cls, Value):
|
|
70
|
+
cls = validate_concrete_type(cls)
|
|
71
|
+
return GlobalPlaceholder(cls, blocks, offset)
|
|
72
|
+
if len(cls.__bases__) != 1:
|
|
73
|
+
raise TypeError("Expected a class with no bases or a Value subclass")
|
|
74
|
+
field_offset = 0
|
|
75
|
+
for i, (
|
|
76
|
+
name,
|
|
77
|
+
annotation,
|
|
78
|
+
) in enumerate(inspect.get_annotations(cls, eval_str=True).items()):
|
|
79
|
+
type_ = validate_concrete_type(annotation)
|
|
80
|
+
setattr(cls, name, GlobalField(name, type_, i, field_offset))
|
|
81
|
+
field_offset += type_._size_()
|
|
82
|
+
cls._global_info_ = GlobalInfo(cls.__name__, field_offset, blocks, offset)
|
|
83
|
+
cls._is_comptime_value_ = True
|
|
84
|
+
return cls()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@dataclass_transform()
|
|
88
|
+
def _play_runtime_environment[T](cls: type[T]) -> T:
|
|
89
|
+
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeEnvironment}, 0)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass_transform()
|
|
93
|
+
def _watch_runtime_environment[T](cls: type[T]) -> T:
|
|
94
|
+
return create_global(cls, {Mode.WATCH: WatchBlock.RuntimeEnvironment}, 0)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass_transform()
|
|
98
|
+
def _tutorial_runtime_environment[T](cls: type[T]) -> T:
|
|
99
|
+
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.RuntimeEnvironment}, 0)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass_transform()
|
|
103
|
+
def _preview_runtime_environment[T](cls: type[T]) -> T:
|
|
104
|
+
return create_global(cls, {Mode.PREVIEW: PreviewBlock.RuntimeEnvironment}, 0)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@dataclass_transform()
|
|
108
|
+
def _play_runtime_update[T](cls: type[T]) -> T:
|
|
109
|
+
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeUpdate}, 0)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@dataclass_transform()
|
|
113
|
+
def _watch_runtime_update[T](cls: type[T]) -> T:
|
|
114
|
+
return create_global(cls, {Mode.WATCH: WatchBlock.RuntimeUpdate}, 0)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@dataclass_transform()
|
|
118
|
+
def _preview_runtime_canvas[T](cls: type[T]) -> T:
|
|
119
|
+
return create_global(cls, {Mode.PREVIEW: PreviewBlock.RuntimeCanvas}, 0)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@dataclass_transform()
|
|
123
|
+
def _tutorial_runtime_update[T](cls: type[T]) -> T:
|
|
124
|
+
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.RuntimeUpdate}, 0)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@dataclass_transform()
|
|
128
|
+
def _runtime_touch_array[T](cls: type[T]) -> T:
|
|
129
|
+
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeTouchArray}, 0)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@dataclass_transform()
|
|
133
|
+
def _runtime_skin_transform[T](cls: type[T]) -> T:
|
|
134
|
+
return create_global(
|
|
135
|
+
cls,
|
|
136
|
+
{
|
|
137
|
+
Mode.PLAY: PlayBlock.RuntimeSkinTransform,
|
|
138
|
+
Mode.WATCH: WatchBlock.RuntimeSkinTransform,
|
|
139
|
+
Mode.PREVIEW: PreviewBlock.RuntimeSkinTransform,
|
|
140
|
+
Mode.TUTORIAL: TutorialBlock.RuntimeSkinTransform,
|
|
141
|
+
},
|
|
142
|
+
0,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@dataclass_transform()
|
|
147
|
+
def _runtime_particle_transform[T](cls: type[T]) -> T:
|
|
148
|
+
return create_global(
|
|
149
|
+
cls,
|
|
150
|
+
{
|
|
151
|
+
Mode.PLAY: PlayBlock.RuntimeParticleTransform,
|
|
152
|
+
Mode.WATCH: WatchBlock.RuntimeParticleTransform,
|
|
153
|
+
Mode.TUTORIAL: TutorialBlock.RuntimeParticleTransform,
|
|
154
|
+
},
|
|
155
|
+
0,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@dataclass_transform()
|
|
160
|
+
def _runtime_background[T](cls: type[T]) -> T:
|
|
161
|
+
return create_global(
|
|
162
|
+
cls,
|
|
163
|
+
{
|
|
164
|
+
Mode.PLAY: PlayBlock.RuntimeBackground,
|
|
165
|
+
Mode.WATCH: WatchBlock.RuntimeBackground,
|
|
166
|
+
Mode.TUTORIAL: TutorialBlock.RuntimeBackground,
|
|
167
|
+
},
|
|
168
|
+
0,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@dataclass_transform()
|
|
173
|
+
def _play_runtime_ui[T](cls: type[T]) -> T:
|
|
174
|
+
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeUI}, 0)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@dataclass_transform()
|
|
178
|
+
def _watch_runtime_ui[T](cls: type[T]) -> T:
|
|
179
|
+
return create_global(cls, {Mode.WATCH: WatchBlock.RuntimeUI}, 0)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@dataclass_transform()
|
|
183
|
+
def _tutorial_runtime_ui[T](cls: type[T]) -> T:
|
|
184
|
+
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.RuntimeUI}, 0)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@dataclass_transform()
|
|
188
|
+
def _preview_runtime_ui[T](cls: type[T]) -> T:
|
|
189
|
+
return create_global(cls, {Mode.PREVIEW: PreviewBlock.RuntimeUI}, 0)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@dataclass_transform()
|
|
193
|
+
def _play_runtime_ui_configuration[T](cls: type[T]) -> T:
|
|
194
|
+
return create_global(cls, {Mode.PLAY: PlayBlock.RuntimeUIConfiguration}, 0)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@dataclass_transform()
|
|
198
|
+
def _watch_runtime_ui_configuration[T](cls: type[T]) -> T:
|
|
199
|
+
return create_global(cls, {Mode.WATCH: WatchBlock.RuntimeUIConfiguration}, 0)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@dataclass_transform()
|
|
203
|
+
def _tutorial_runtime_ui_configuration[T](cls: type[T]) -> T:
|
|
204
|
+
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.RuntimeUIConfiguration}, 0)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@dataclass_transform()
|
|
208
|
+
def _preview_runtime_ui_configuration[T](cls: type[T]) -> T:
|
|
209
|
+
return create_global(cls, {Mode.PREVIEW: PreviewBlock.RuntimeUIConfiguration}, 0)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
@dataclass_transform()
|
|
213
|
+
def _tutorial_instruction[T](cls: type[T]) -> T:
|
|
214
|
+
return create_global(cls, {Mode.TUTORIAL: TutorialBlock.TutorialInstruction}, 0)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@dataclass_transform()
|
|
218
|
+
def level_memory[T](cls: type[T]) -> T:
|
|
219
|
+
return create_global(
|
|
220
|
+
cls,
|
|
221
|
+
{
|
|
222
|
+
Mode.PLAY: PlayBlock.LevelMemory,
|
|
223
|
+
Mode.WATCH: WatchBlock.LevelMemory,
|
|
224
|
+
Mode.TUTORIAL: TutorialBlock.TutorialMemory,
|
|
225
|
+
},
|
|
226
|
+
None,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@dataclass_transform()
|
|
231
|
+
def level_data[T](cls: type[T]) -> T:
|
|
232
|
+
return create_global(
|
|
233
|
+
cls,
|
|
234
|
+
{
|
|
235
|
+
Mode.PLAY: PlayBlock.LevelData,
|
|
236
|
+
Mode.WATCH: WatchBlock.LevelData,
|
|
237
|
+
Mode.PREVIEW: PreviewBlock.PreviewData,
|
|
238
|
+
Mode.TUTORIAL: TutorialBlock.TutorialData,
|
|
239
|
+
},
|
|
240
|
+
None,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
# level_option is handled by the options decorator
|
|
245
|
+
# level_bucket is handled by the bucket decorator
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@dataclass_transform()
|
|
249
|
+
def _level_score[T](cls: type[T]) -> T:
|
|
250
|
+
return create_global(cls, {Mode.PLAY: PlayBlock.LevelScore, Mode.WATCH: WatchBlock.LevelScore}, 0)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
@dataclass_transform()
|
|
254
|
+
def _level_life[T](cls: type[T]) -> T:
|
|
255
|
+
return create_global(cls, {Mode.PLAY: PlayBlock.LevelLife, Mode.WATCH: WatchBlock.LevelLife}, 0)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
# engine_rom is handled by the compiler
|
|
259
|
+
# entity memory is handled by the archetype
|
|
260
|
+
# entity data is handled by the archetype
|
|
261
|
+
# entity shared memory is handled by the archetype
|
|
262
|
+
# entity info is handled by the archetype
|
|
263
|
+
# entity despawn is handled by the archetype
|
|
264
|
+
# entity input is handled by the archetype
|
|
265
|
+
# entity data array is handled by the archetype
|
|
266
|
+
# entity shared memory array is handled by the archetype
|
|
267
|
+
# entity info array is handled by the archetype
|
|
268
|
+
# archetype life is handled by the archetype
|
|
269
|
+
# temporary memory is handled by the compiler
|