splitted the manager into an event and role manager
This commit is contained in:
parent
c825ef8bef
commit
2286375bae
12 changed files with 125 additions and 38 deletions
|
@ -1,15 +1,5 @@
|
|||
import threading
|
||||
|
||||
from source.managers import Manager
|
||||
|
||||
|
||||
manager = Manager("wlp1s0")
|
||||
|
||||
thread_receive = threading.Thread(target=manager.receiveLoop)
|
||||
thread_send = threading.Thread(target=manager.sendLoop)
|
||||
|
||||
thread_receive.start()
|
||||
thread_send.start()
|
||||
|
||||
thread_receive.join()
|
||||
thread_send.join()
|
||||
manager.loop()
|
||||
|
|
|
@ -3,5 +3,5 @@ from source import packets
|
|||
|
||||
|
||||
class DiscoveryEvent(base.BaseEvent):
|
||||
def handle(self, packet: packets.DiscoveryPacket):
|
||||
pass
|
||||
def handle(self, packet: packets.DiscoveryPacket, address: tuple):
|
||||
print("discovery event !")
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
from . import base
|
||||
|
||||
from .DiscoveryEvent import DiscoveryEvent
|
|
@ -1,5 +1,13 @@
|
|||
import abc
|
||||
|
||||
from source import packets
|
||||
|
||||
|
||||
class BaseEvent(abc.ABC):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def handle(self, packet: packets.base.BasePacket, address: tuple) -> None:
|
||||
"""
|
||||
Handle a packet
|
||||
:param packet: the packet to handle
|
||||
:param address: the address of the machine that sent the packet
|
||||
"""
|
||||
|
|
|
@ -4,6 +4,6 @@ from source import managers, packets
|
|||
|
||||
|
||||
class UndefinedRole(base.BaseRole):
|
||||
def run(self, manager: "managers.Manager"):
|
||||
def handle(self, manager: "managers.Manager"):
|
||||
packet = packets.DiscoveryPacket()
|
||||
manager.communication.broadcast(packet)
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
from . import base
|
||||
from .UndefinedRole import UndefinedRole
|
||||
|
|
|
@ -5,7 +5,7 @@ from source import managers
|
|||
|
||||
class BaseRole(abc.ABC):
|
||||
@abc.abstractmethod
|
||||
def run(self, manager: "managers.Manager") -> None:
|
||||
def handle(self, manager: "managers.Manager") -> None:
|
||||
"""
|
||||
Behavior of the role
|
||||
"""
|
||||
|
|
|
@ -5,6 +5,7 @@ import zlib
|
|||
import bidict
|
||||
|
||||
from source import packets
|
||||
from source.managers import Manager
|
||||
from source.utils.crypto.type import CipherType
|
||||
|
||||
|
||||
|
@ -13,7 +14,9 @@ class CommunicationManager:
|
|||
Manage everything about communication
|
||||
"""
|
||||
|
||||
def __init__(self, interface: str, broadcast_address: str = "ff02::1", port: int = 5555):
|
||||
def __init__(self, manager: "Manager", interface: str, broadcast_address: str = "ff02::1", port: int = 5555):
|
||||
self.manager = manager
|
||||
|
||||
self.broadcast_address = broadcast_address
|
||||
self.port = port
|
||||
|
||||
|
@ -59,7 +62,7 @@ class CommunicationManager:
|
|||
# get the header identifier of the type of this packet
|
||||
header: typing.Optional[bytes] = self.packet_types.inverse.get(type(packet))
|
||||
if header is None:
|
||||
raise Exception(f"Unrecognised packet type: {type(packet)}. Has it been registered ?")
|
||||
raise KeyError(f"Unrecognised packet type: {type(packet)}. Has it been registered ?")
|
||||
|
||||
# get the encoded packet data
|
||||
data = packet.pack()
|
||||
|
@ -88,7 +91,7 @@ class CommunicationManager:
|
|||
# get the type of the packet from its header
|
||||
packet_type: typing.Optional[typing.Type[packets.base.BasePacket]] = self.packet_types.get(header)
|
||||
if header is None:
|
||||
raise Exception(f"Unrecognised packet header: {header}. Has it been registered ?")
|
||||
raise KeyError(f"Unrecognised packet header: {header}. Has it been registered ?")
|
||||
|
||||
# unpack the packet
|
||||
return packet_type.unpack(data)
|
||||
|
|
53
source/managers/EventManager.py
Normal file
53
source/managers/EventManager.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
import typing
|
||||
import warnings
|
||||
|
||||
from source import packets
|
||||
from source.behaviors import events
|
||||
from source.managers import Manager
|
||||
|
||||
|
||||
class EventManager:
|
||||
def __init__(self, manager: "Manager"):
|
||||
self.manager = manager
|
||||
|
||||
# events
|
||||
self.event_handlers: dict[typing.Type[packets.base.BasePacket], events.base.BaseEvent] = {}
|
||||
|
||||
def register_event_handler(self, packet_type: typing.Type[packets.base.BasePacket], event: events.base.BaseEvent) -> None:
|
||||
"""
|
||||
Register a new event to react to a specific packet type
|
||||
:param packet_type: the type of packet to listen to
|
||||
:param event: the event handler
|
||||
"""
|
||||
|
||||
self.event_handlers[packet_type] = event
|
||||
|
||||
def handle(self, packet: packets.base.BasePacket, address: tuple) -> None:
|
||||
"""
|
||||
Handle the packet received
|
||||
:param packet: the packet to handle
|
||||
:param address: the address of the machine that sent the packet
|
||||
"""
|
||||
|
||||
# get the event handler of this kind of packet
|
||||
event_handler = self.event_handlers.get(type(packet))
|
||||
if event_handler is None:
|
||||
raise KeyError(f"Unrecognised packet type: {type(packet)}. Has it been registered ?")
|
||||
|
||||
# use the event handler on the packet
|
||||
event_handler.handle(packet, address)
|
||||
|
||||
def loop(self):
|
||||
while True:
|
||||
try:
|
||||
# wait for a new packet
|
||||
packet, address = self.manager.communication.receive()
|
||||
print(f"Received message from {address}: {packet}")
|
||||
# give it to the event handler
|
||||
self.manager.event.handle(packet, address)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Stopping listener.")
|
||||
|
||||
except Exception as exception:
|
||||
warnings.warn(str(exception))
|
|
@ -1,30 +1,31 @@
|
|||
from . import CommunicationManager
|
||||
import threading
|
||||
|
||||
from source import packets
|
||||
from source.behaviors import roles
|
||||
from source.behaviors import events
|
||||
|
||||
|
||||
class Manager:
|
||||
def __init__(self, interface: str):
|
||||
self.communication = CommunicationManager(interface)
|
||||
from . import CommunicationManager, EventManager, RoleManager
|
||||
|
||||
# communication manager
|
||||
self.communication = CommunicationManager(self, interface)
|
||||
self.communication.register_packet_type(b"DISC", packets.DiscoveryPacket)
|
||||
|
||||
# define the role of our machine
|
||||
# TODO(Faraphel): give the manager to the role directly ? register ?
|
||||
self.role = roles.UndefinedRole()
|
||||
# event manager
|
||||
self.event = EventManager(self)
|
||||
self.event.register_event_handler(packets.DiscoveryPacket, events.DiscoveryEvent())
|
||||
|
||||
# role manager
|
||||
self.role = RoleManager(self)
|
||||
|
||||
def sendLoop(self):
|
||||
while True:
|
||||
self.role.run(self)
|
||||
def loop(self):
|
||||
# run a thread for the event and the role manager
|
||||
event_thread = threading.Thread(target=self.event.loop)
|
||||
role_thread = threading.Thread(target=self.role.loop)
|
||||
|
||||
def receiveLoop(self):
|
||||
try:
|
||||
while True:
|
||||
packet, address = self.communication.receive()
|
||||
print(f"Received message from {address}: {packet}")
|
||||
event_thread.start()
|
||||
role_thread.start()
|
||||
|
||||
# get corresponding event
|
||||
# handle it
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Stopping listener.")
|
||||
event_thread.join()
|
||||
role_thread.join()
|
25
source/managers/RoleManager.py
Normal file
25
source/managers/RoleManager.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
from source.behaviors import roles
|
||||
from source.managers import Manager
|
||||
|
||||
|
||||
class RoleManager:
|
||||
def __init__(self, manager: "Manager"):
|
||||
self.manager = manager
|
||||
|
||||
# the currently used role
|
||||
self.current: roles.base.BaseRole = roles.UndefinedRole()
|
||||
|
||||
def handle(self) -> None:
|
||||
"""
|
||||
Run the role
|
||||
"""
|
||||
|
||||
self.current.handle(self.manager)
|
||||
|
||||
def loop(self) -> None:
|
||||
"""
|
||||
Handle forever
|
||||
"""
|
||||
|
||||
while True:
|
||||
self.handle()
|
|
@ -1,2 +1,5 @@
|
|||
from .CommunicationManager import CommunicationManager
|
||||
from .EventManager import EventManager
|
||||
from .RoleManager import RoleManager
|
||||
|
||||
from .Manager import Manager
|
||||
|
|
Loading…
Reference in a new issue