Première version de l'ECS (pas terminée)

This commit is contained in:
Tipragot 2023-10-22 19:26:06 +02:00
parent 52dfe54562
commit 9d80c111e9
5 changed files with 119 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
__pycache__

12
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,12 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Module",
"type": "python",
"request": "launch",
"module": "main",
"justMyCode": true
}
]
}

57
ecs.py Normal file
View file

@ -0,0 +1,57 @@
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]

49
main.py Normal file
View file

@ -0,0 +1,49 @@
from ecs import World, Entity
# Création de composants pouvant être ajouté a des entitées
class Name(str):
pass
class Age(int):
pass
# Création d'un monde
world = World()
# Création d'une entité
david = Entity(world)
david[Name] = Name("David")
david[Age] = Age(25)
# Création d'une autre entité
fred = Entity(world)
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")
for entity in world.query(Name):
print(entity[Name])
print("Récupération de toutes les entitées qui ont un age")
for entity in world.query(Age):
print(entity[Age])
print("Récupération de toutes les entités qui ont un nom et un age")
for entity in world.query(Name, Age):
print(entity[Name], entity[Age])
print("Récupération de toutes les entitées qui ont un nom mais pas d'age")
for entity in world.query(Name, without=(Age,)):
print(entity[Name])
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,)):
print(entity[Age])

0
requirements.txt Normal file
View file