58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
|
from typing import Iterator
|
||
|
|
||
|
|
||
|
class World:
|
||
|
def __init__(self):
|
||
|
self.entities: set[Entity] = set()
|
||
|
self.mapping: dict[type, set[Entity]] = {}
|
||
|
|
||
|
def query(self, *needed: type, without: tuple[type] = []) -> Iterator['Entity']:
|
||
|
if not needed:
|
||
|
for entity in self.entities:
|
||
|
for without_type in without:
|
||
|
if without_type in entity:
|
||
|
break
|
||
|
else:
|
||
|
yield entity
|
||
|
else:
|
||
|
first_component = needed[0]
|
||
|
for entity in self.mapping.get(first_component, set()):
|
||
|
for component_type in needed[1:]:
|
||
|
if entity not in self.mapping.get(component_type, set()):
|
||
|
break
|
||
|
else:
|
||
|
for without_type in without:
|
||
|
if without_type in entity:
|
||
|
break
|
||
|
else:
|
||
|
yield entity
|
||
|
|
||
|
class Entity:
|
||
|
def __init__(self, world: World):
|
||
|
self.world = world
|
||
|
self.world.entities.add(self)
|
||
|
self.components: dict[type, object] = {}
|
||
|
|
||
|
def __getitem__(self, component_type):
|
||
|
return self.components[component_type]
|
||
|
|
||
|
def __setitem__(self, component_type, component):
|
||
|
self.components[component_type] = component
|
||
|
self.world.mapping.setdefault(component_type, set()).add(self)
|
||
|
|
||
|
def __delitem__(self, component_type):
|
||
|
del self.components[component_type]
|
||
|
self.world.mapping[component_type].remove(self)
|
||
|
if len(self.world.mapping[component_type]) == 0:
|
||
|
del self.world.mapping[component_type]
|
||
|
|
||
|
def __contains__(self, component_type):
|
||
|
return component_type in self.components
|
||
|
|
||
|
def __del__(self): # TODO: Réparer ça marche pas car il n'est pas détruit car il est toujours dans World
|
||
|
self.world.entities.remove(self)
|
||
|
for component_type in self.components:
|
||
|
self.world.mapping[component_type].remove(self)
|
||
|
if len(self.world.mapping[component_type]) == 0:
|
||
|
del self.world.mapping[component_type]
|