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
|
from source.managers import Manager
|
||||||
|
|
||||||
|
|
||||||
manager = Manager("wlp1s0")
|
manager = Manager("wlp1s0")
|
||||||
|
manager.loop()
|
||||||
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()
|
|
||||||
|
|
|
@ -3,5 +3,5 @@ from source import packets
|
||||||
|
|
||||||
|
|
||||||
class DiscoveryEvent(base.BaseEvent):
|
class DiscoveryEvent(base.BaseEvent):
|
||||||
def handle(self, packet: packets.DiscoveryPacket):
|
def handle(self, packet: packets.DiscoveryPacket, address: tuple):
|
||||||
pass
|
print("discovery event !")
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
from . import base
|
||||||
|
|
||||||
|
from .DiscoveryEvent import DiscoveryEvent
|
|
@ -1,5 +1,13 @@
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
|
from source import packets
|
||||||
|
|
||||||
|
|
||||||
class BaseEvent(abc.ABC):
|
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):
|
class UndefinedRole(base.BaseRole):
|
||||||
def run(self, manager: "managers.Manager"):
|
def handle(self, manager: "managers.Manager"):
|
||||||
packet = packets.DiscoveryPacket()
|
packet = packets.DiscoveryPacket()
|
||||||
manager.communication.broadcast(packet)
|
manager.communication.broadcast(packet)
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
|
from . import base
|
||||||
from .UndefinedRole import UndefinedRole
|
from .UndefinedRole import UndefinedRole
|
||||||
|
|
|
@ -5,7 +5,7 @@ from source import managers
|
||||||
|
|
||||||
class BaseRole(abc.ABC):
|
class BaseRole(abc.ABC):
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def run(self, manager: "managers.Manager") -> None:
|
def handle(self, manager: "managers.Manager") -> None:
|
||||||
"""
|
"""
|
||||||
Behavior of the role
|
Behavior of the role
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,6 +5,7 @@ import zlib
|
||||||
import bidict
|
import bidict
|
||||||
|
|
||||||
from source import packets
|
from source import packets
|
||||||
|
from source.managers import Manager
|
||||||
from source.utils.crypto.type import CipherType
|
from source.utils.crypto.type import CipherType
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +14,9 @@ class CommunicationManager:
|
||||||
Manage everything about communication
|
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.broadcast_address = broadcast_address
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
|
@ -59,7 +62,7 @@ class CommunicationManager:
|
||||||
# get the header identifier of the type of this packet
|
# get the header identifier of the type of this packet
|
||||||
header: typing.Optional[bytes] = self.packet_types.inverse.get(type(packet))
|
header: typing.Optional[bytes] = self.packet_types.inverse.get(type(packet))
|
||||||
if header is None:
|
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
|
# get the encoded packet data
|
||||||
data = packet.pack()
|
data = packet.pack()
|
||||||
|
@ -88,7 +91,7 @@ class CommunicationManager:
|
||||||
# get the type of the packet from its header
|
# get the type of the packet from its header
|
||||||
packet_type: typing.Optional[typing.Type[packets.base.BasePacket]] = self.packet_types.get(header)
|
packet_type: typing.Optional[typing.Type[packets.base.BasePacket]] = self.packet_types.get(header)
|
||||||
if header is None:
|
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
|
# unpack the packet
|
||||||
return packet_type.unpack(data)
|
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 import packets
|
||||||
from source.behaviors import roles
|
from source.behaviors import events
|
||||||
|
|
||||||
|
|
||||||
class Manager:
|
class Manager:
|
||||||
def __init__(self, interface: str):
|
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)
|
self.communication.register_packet_type(b"DISC", packets.DiscoveryPacket)
|
||||||
|
|
||||||
# define the role of our machine
|
# event manager
|
||||||
# TODO(Faraphel): give the manager to the role directly ? register ?
|
self.event = EventManager(self)
|
||||||
self.role = roles.UndefinedRole()
|
self.event.register_event_handler(packets.DiscoveryPacket, events.DiscoveryEvent())
|
||||||
|
|
||||||
|
# role manager
|
||||||
|
self.role = RoleManager(self)
|
||||||
|
|
||||||
def sendLoop(self):
|
def loop(self):
|
||||||
while True:
|
# run a thread for the event and the role manager
|
||||||
self.role.run(self)
|
event_thread = threading.Thread(target=self.event.loop)
|
||||||
|
role_thread = threading.Thread(target=self.role.loop)
|
||||||
|
|
||||||
def receiveLoop(self):
|
event_thread.start()
|
||||||
try:
|
role_thread.start()
|
||||||
while True:
|
|
||||||
packet, address = self.communication.receive()
|
|
||||||
print(f"Received message from {address}: {packet}")
|
|
||||||
|
|
||||||
# get corresponding event
|
event_thread.join()
|
||||||
# handle it
|
role_thread.join()
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Stopping listener.")
|
|
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 .CommunicationManager import CommunicationManager
|
||||||
|
from .EventManager import EventManager
|
||||||
|
from .RoleManager import RoleManager
|
||||||
|
|
||||||
from .Manager import Manager
|
from .Manager import Manager
|
||||||
|
|
Loading…
Reference in a new issue