aboutsummaryrefslogtreecommitdiff
path: root/kennel/engine/systems
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth@simponic.xyz>2024-08-20 17:34:18 -0700
committerElizabeth Hunt <elizabeth@simponic.xyz>2024-08-20 17:34:18 -0700
commitb4140460014d1fc134df9127600f6da2346376e3 (patch)
tree5bee11079f3ab9e3fd5d2a68cee483c2c33557f4 /kennel/engine/systems
parent6f223d2462df5e08856fb83fd76773a8af33acf9 (diff)
downloadkennel.hatecomputers.club-b4140460014d1fc134df9127600f6da2346376e3.tar.gz
kennel.hatecomputers.club-b4140460014d1fc134df9127600f6da2346376e3.zip
init commit with base ECS and Network System
Diffstat (limited to 'kennel/engine/systems')
-rw-r--r--kennel/engine/systems/__init__.py0
-rw-r--r--kennel/engine/systems/network.py88
-rw-r--r--kennel/engine/systems/system.py31
3 files changed, 119 insertions, 0 deletions
diff --git a/kennel/engine/systems/__init__.py b/kennel/engine/systems/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kennel/engine/systems/__init__.py
diff --git a/kennel/engine/systems/network.py b/kennel/engine/systems/network.py
new file mode 100644
index 0000000..7df8088
--- /dev/null
+++ b/kennel/engine/systems/network.py
@@ -0,0 +1,88 @@
+from enum import Enum
+from kennel.engine.entities.entity import EntityManager
+from .system import System, SystemType
+from abc import abstractmethod
+import asyncio
+
+
+class EventType(str, Enum):
+ ENTITY_BORN = "ENTITY_BORN"
+ ENTITY_POSITION_UPDATE = "ENTITY_POSITION_UPDATE"
+ ENTITY_DEATH = "ENTITY_DEATH"
+
+
+class Event:
+ def __init__(self, event_type: EventType, data: dict):
+ self.event_type = event_type
+ self.data = data
+
+ def __str__(self):
+ return f"Event({self.event_type}, {self.data})"
+
+ def dict(self):
+ return {"event_type": self.event_type, "data": self.data}
+
+ @staticmethod
+ def from_dict(data: dict):
+ return Event(EventType(data["event_type"]), data["data"])
+
+
+class Publishable:
+ @abstractmethod
+ async def publish(self, event: Event):
+ pass
+
+
+class ClientEventTransformer:
+ @abstractmethod
+ def apply(self, event: Event) -> Event:
+ pass
+
+
+class EventProcessor:
+ @abstractmethod
+ def accept(self, entity_manager: EntityManager, event: Event) -> None:
+ pass
+
+
+class NetworkSystem(System):
+ def __init__(
+ self,
+ event_processor: EventProcessor,
+ client_event_transformer: ClientEventTransformer,
+ ):
+ super().__init__(SystemType.NETWORK)
+ self.event_processor = event_processor
+ self.client_event_transformer = client_event_transformer
+
+ self.events = []
+ self.clients = {}
+
+ async def update(self, entity_manager: EntityManager, delta_time: float) -> None:
+ for event in self.events:
+ self.event_processor.accept(entity_manager, event)
+ client_events = [
+ self.client_event_transformer.apply(entity_manager, event)
+ for event in self.events
+ ]
+ await asyncio.gather(
+ *[
+ client.publish(event)
+ for client in self.clients.values()
+ for event in client_events
+ ]
+ )
+ self.events = []
+
+ def client_event(self, client_id: str, event: Event) -> None:
+ event.data["client_id"] = client_id
+ self.events.append(event)
+
+ def add_event(self, event: Event) -> None:
+ self.events.append(event)
+
+ def add_client(self, client_id: str, client: Publishable) -> None:
+ self.clients[client_id] = client
+
+ def remove_client(self, client_id: str) -> None:
+ del self.clients[client_id]
diff --git a/kennel/engine/systems/system.py b/kennel/engine/systems/system.py
new file mode 100644
index 0000000..0e51f3a
--- /dev/null
+++ b/kennel/engine/systems/system.py
@@ -0,0 +1,31 @@
+from enum import Enum
+from kennel.engine.entities.entity import EntityManager
+from abc import abstractmethod
+
+
+class SystemType(str, Enum):
+ NETWORK = "NETWORK"
+
+
+class System:
+ def __init__(self, system_type: SystemType):
+ self.system_type = system_type
+
+ @abstractmethod
+ async def update(self, entity_manager: EntityManager, delta_time: float):
+ pass
+
+
+class SystemManager:
+ def __init__(self):
+ self.systems = {}
+
+ def add_system(self, system: System) -> None:
+ self.systems[system.system_type] = system
+
+ def get_system(self, system_type: SystemType) -> System:
+ return self.systems.get(system_type)
+
+ async def update(self, entity_manager: EntityManager, delta_time: float) -> None:
+ for system in self.systems.values():
+ await system.update(entity_manager, delta_time)