Amélioration du système
This commit is contained in:
parent
9d80c111e9
commit
ac19222744
85
ecs.py
85
ecs.py
|
@ -3,55 +3,66 @@ from typing import Iterator
|
||||||
|
|
||||||
class World:
|
class World:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.to_apply: set[Entity] = set()
|
||||||
self.entities: set[Entity] = set()
|
self.entities: set[Entity] = set()
|
||||||
self.mapping: dict[type, set[Entity]] = {}
|
self.mapping: dict[type, set[Entity]] = {}
|
||||||
|
|
||||||
|
def create_entity(self, *components):
|
||||||
|
return Entity(self, *components)
|
||||||
|
|
||||||
|
def remove_entity(self, entity: 'Entity'):
|
||||||
|
entity._deleted = True
|
||||||
|
self.to_apply.add(entity)
|
||||||
|
|
||||||
|
def apply(self):
|
||||||
|
for entity in self.to_apply:
|
||||||
|
if entity._deleted:
|
||||||
|
self.entities.remove(entity)
|
||||||
|
for component_type in entity._components:
|
||||||
|
self.mapping[component_type].remove(entity)
|
||||||
|
else:
|
||||||
|
self.entities.add(entity)
|
||||||
|
for component_type, component in entity._to_apply:
|
||||||
|
if component is None:
|
||||||
|
del entity._components[component_type]
|
||||||
|
self.mapping[component_type].remove(entity)
|
||||||
|
else:
|
||||||
|
entity._components[component_type] = component
|
||||||
|
self.mapping.setdefault(component_type, set()).add(entity)
|
||||||
|
entity._to_apply.clear()
|
||||||
|
|
||||||
def query(self, *needed: type, without: tuple[type] = []) -> Iterator['Entity']:
|
def query(self, *needed: type, without: tuple[type] = []) -> Iterator['Entity']:
|
||||||
if not needed:
|
if not needed:
|
||||||
for entity in self.entities:
|
for entity in self.entities:
|
||||||
for without_type in without:
|
if all(without_type not in entity for without_type in without):
|
||||||
if without_type in entity:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
yield entity
|
yield entity
|
||||||
else:
|
else:
|
||||||
first_component = needed[0]
|
for entity in self.mapping.get(needed[0], set()):
|
||||||
for entity in self.mapping.get(first_component, set()):
|
if all(entity in self.mapping.get(component_type, set()) for component_type in needed[1:]) and \
|
||||||
for component_type in needed[1:]:
|
all(without_type not in entity for without_type in without):
|
||||||
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
|
yield entity
|
||||||
|
|
||||||
class Entity:
|
class Entity:
|
||||||
def __init__(self, world: World):
|
def __init__(self, world: World, *components):
|
||||||
self.world = world
|
self._world = world
|
||||||
self.world.entities.add(self)
|
self._to_apply: list[tuple[type, object]] = [(type(component), component) for component in components]
|
||||||
self.components: dict[type, object] = {}
|
self._components: dict[type, object] = {}
|
||||||
|
self._deleted = False
|
||||||
|
self._world.to_apply.add(self)
|
||||||
|
|
||||||
def __getitem__(self, component_type):
|
def set(self, *components):
|
||||||
return self.components[component_type]
|
for component in components:
|
||||||
|
self._to_apply.append((type(component), component))
|
||||||
|
self._world.to_apply.add(self)
|
||||||
|
|
||||||
def __setitem__(self, component_type, component):
|
def remove(self, *component_types: type):
|
||||||
self.components[component_type] = component
|
for component_type in component_types:
|
||||||
self.world.mapping.setdefault(component_type, set()).add(self)
|
if component_type in self._components:
|
||||||
|
self._to_apply.append((component_type, None))
|
||||||
|
self._world.to_apply.add(self)
|
||||||
|
|
||||||
def __delitem__(self, component_type):
|
def __getitem__(self, component_type: type) -> object:
|
||||||
del self.components[component_type]
|
return 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):
|
def __contains__(self, component_type: type) -> bool:
|
||||||
return component_type in self.components
|
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]
|
|
45
main.py
45
main.py
|
@ -1,31 +1,20 @@
|
||||||
from ecs import World, Entity
|
from ecs import World
|
||||||
|
|
||||||
# Création de composants pouvant être ajouté a des entitées
|
# Création de composants pouvant être ajouté a des entitées
|
||||||
class Name(str):
|
class Name(str): pass
|
||||||
pass
|
class Age(int): pass
|
||||||
class Age(int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Création d'un monde
|
# Création d'un monde
|
||||||
world = World()
|
world = World()
|
||||||
|
|
||||||
# Création d'une entité
|
# Création de plusieurs entités
|
||||||
david = Entity(world)
|
david = world.create_entity(Name("David"), Age(25))
|
||||||
david[Name] = Name("David")
|
fred = world.create_entity(Name("Fred"), Age(30))
|
||||||
david[Age] = Age(25)
|
paul_sans_age = world.create_entity(Name("Paul"))
|
||||||
|
age_tout_cour = world.create_entity(Age(14))
|
||||||
|
|
||||||
# Création d'une autre entité
|
# On applique les moddifications
|
||||||
fred = Entity(world)
|
world.apply()
|
||||||
fred[Name] = Name("Fred")
|
|
||||||
fred[Age] = Age(30)
|
|
||||||
|
|
||||||
# Création d'une autre entité
|
|
||||||
paul_sans_age = Entity(world)
|
|
||||||
paul_sans_age[Name] = Name("Paul")
|
|
||||||
|
|
||||||
# Création d'une autre entité
|
|
||||||
age_tout_cour = Entity(world)
|
|
||||||
age_tout_cour[Age] = Age(14)
|
|
||||||
|
|
||||||
print("Récupération de toutes les entitées qui ont un nom")
|
print("Récupération de toutes les entitées qui ont un nom")
|
||||||
for entity in world.query(Name):
|
for entity in world.query(Name):
|
||||||
|
@ -35,6 +24,12 @@ print("Récupération de toutes les entitées qui ont un age")
|
||||||
for entity in world.query(Age):
|
for entity in world.query(Age):
|
||||||
print(entity[Age])
|
print(entity[Age])
|
||||||
|
|
||||||
|
# On change l'age de Fred
|
||||||
|
fred.set(Age(45))
|
||||||
|
|
||||||
|
# On applique les moddifications
|
||||||
|
world.apply()
|
||||||
|
|
||||||
print("Récupération de toutes les entités qui ont un nom et un age")
|
print("Récupération de toutes les entités qui ont un nom et un age")
|
||||||
for entity in world.query(Name, Age):
|
for entity in world.query(Name, Age):
|
||||||
print(entity[Name], entity[Age])
|
print(entity[Name], entity[Age])
|
||||||
|
@ -47,3 +42,11 @@ print("Récupération de toutes les entités qui ont un age mais pas de nom")
|
||||||
for entity in world.query(Age, without=(Name,)):
|
for entity in world.query(Age, without=(Name,)):
|
||||||
print(entity[Age])
|
print(entity[Age])
|
||||||
|
|
||||||
|
print("Récupération de toutes les entités")
|
||||||
|
for entity in world.query():
|
||||||
|
if Name in entity:
|
||||||
|
print(entity[Name], end=" ")
|
||||||
|
if Age in entity:
|
||||||
|
print(entity[Age], end=" ")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue