for sub in get_args(components)
for e in components_type_iter(sub)
)
- elif issubclass(components, Component):
- yield components
+ elif issubclass(origin_or_cls(components), Component):
+ yield cast(type[Component], components)
else:
yield from cast(type[Bundle], components).components_type_iter(
components
raise Exception("More than one entity matches single query")
return res
+ def single_e(self) -> Items:
+ if (res := self.single()) is None:
+ raise Exception("single_e must contain exactly one matching item")
+ return res
+
class Resource(FromWorld, Component):
@override
query: Callable[[], Query[Self]] = cast(
Callable[[], Query[Self]], _query.extract_from_world(_query, world)
)
- default: Callable[[], Self | None] = cls.extract_default(ty, world)
+ def_cb: Callable[[], Self | None] = cls.extract_default(ty, world)
+
+ def default() -> Self | None:
+ if (val := def_cb()) is None:
+ return
+ world.spawn(cast(type[Self], ty), val)
+ return val
+
return lambda: (
res if (res := query().single()) is not None else default()
)
def spawn[T: Components](self, ty: type[T], comp: T) -> Entity:
return self.spawn_many(ty, [comp])[0]
+ def spawn_resource[T: Component](
+ self, comp: T, ty: type[T] | None = None
+ ) -> Entity:
+ if ty is None:
+ ty = type(comp)
+
+ type Ty = ty # type: ignore
+
+ def remove(query: Query[Entity, Ty], world: World) -> None:
+ world.remove_many(ty, list(query))
+
+ self.add_raw_system(remove)()
+ return self.spawn(ty, comp)
+
def spawn_many[T: Components](
self, ty: type[T], comps: list[T]
) -> list[Entity]: