1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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]
|