aboutsummaryrefslogtreecommitdiff
path: root/kennel/engine/systems/network.py
diff options
context:
space:
mode:
Diffstat (limited to 'kennel/engine/systems/network.py')
-rw-r--r--kennel/engine/systems/network.py88
1 files changed, 88 insertions, 0 deletions
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]