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.

Files changed (72) hide show
  1. sonolus/backend/allocate.py +125 -51
  2. sonolus/backend/blocks.py +756 -756
  3. sonolus/backend/coalesce.py +85 -0
  4. sonolus/backend/constant_evaluation.py +374 -0
  5. sonolus/backend/dead_code.py +80 -0
  6. sonolus/backend/dominance.py +111 -0
  7. sonolus/backend/excepthook.py +37 -37
  8. sonolus/backend/finalize.py +69 -69
  9. sonolus/backend/flow.py +121 -92
  10. sonolus/backend/inlining.py +150 -0
  11. sonolus/backend/ir.py +5 -3
  12. sonolus/backend/liveness.py +173 -0
  13. sonolus/backend/mode.py +24 -24
  14. sonolus/backend/node.py +40 -40
  15. sonolus/backend/ops.py +197 -197
  16. sonolus/backend/optimize.py +37 -9
  17. sonolus/backend/passes.py +52 -6
  18. sonolus/backend/simplify.py +47 -30
  19. sonolus/backend/ssa.py +187 -0
  20. sonolus/backend/utils.py +48 -48
  21. sonolus/backend/visitor.py +892 -880
  22. sonolus/build/cli.py +7 -1
  23. sonolus/build/compile.py +88 -90
  24. sonolus/build/engine.py +55 -5
  25. sonolus/build/level.py +24 -23
  26. sonolus/build/node.py +43 -43
  27. sonolus/script/archetype.py +23 -6
  28. sonolus/script/array.py +2 -2
  29. sonolus/script/bucket.py +191 -191
  30. sonolus/script/callbacks.py +127 -115
  31. sonolus/script/comptime.py +1 -1
  32. sonolus/script/containers.py +23 -0
  33. sonolus/script/debug.py +19 -3
  34. sonolus/script/easing.py +323 -0
  35. sonolus/script/effect.py +131 -131
  36. sonolus/script/engine.py +37 -1
  37. sonolus/script/globals.py +269 -269
  38. sonolus/script/graphics.py +200 -150
  39. sonolus/script/instruction.py +151 -0
  40. sonolus/script/internal/__init__.py +5 -5
  41. sonolus/script/internal/builtin_impls.py +144 -144
  42. sonolus/script/internal/context.py +12 -4
  43. sonolus/script/internal/descriptor.py +17 -17
  44. sonolus/script/internal/introspection.py +14 -14
  45. sonolus/script/internal/native.py +40 -38
  46. sonolus/script/internal/value.py +3 -3
  47. sonolus/script/interval.py +120 -112
  48. sonolus/script/iterator.py +214 -211
  49. sonolus/script/math.py +30 -1
  50. sonolus/script/num.py +1 -1
  51. sonolus/script/options.py +191 -191
  52. sonolus/script/particle.py +157 -157
  53. sonolus/script/pointer.py +30 -30
  54. sonolus/script/{preview.py → print.py} +81 -81
  55. sonolus/script/random.py +14 -0
  56. sonolus/script/range.py +58 -58
  57. sonolus/script/record.py +3 -3
  58. sonolus/script/runtime.py +45 -6
  59. sonolus/script/sprite.py +333 -333
  60. sonolus/script/text.py +407 -407
  61. sonolus/script/timing.py +42 -42
  62. sonolus/script/transform.py +77 -23
  63. sonolus/script/ui.py +160 -160
  64. sonolus/script/vec.py +81 -72
  65. {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/METADATA +1 -2
  66. sonolus_py-0.1.4.dist-info/RECORD +84 -0
  67. {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/WHEEL +1 -1
  68. {sonolus_py-0.1.2.dist-info → sonolus_py-0.1.4.dist-info}/licenses/LICENSE +21 -21
  69. sonolus/build/defaults.py +0 -32
  70. sonolus/script/icon.py +0 -73
  71. sonolus_py-0.1.2.dist-info/RECORD +0 -76
  72. {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() -> float:
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