Example #1
0
 def __init__(self, stop_event: Event, port: int):
     super().__init__()
     self.setDaemon(True)
     self.stop_event = stop_event
     self.queue_to_ui = Queue()
     self.peer_pool = PeerPool(port, stop_event, self.queue_to_ui)
     self.status_monitor = ClientStatusMonitor(stop_event, self.peer_pool)
     # Lista klientów
     self.clients = ClientsTable()
     self.clients.add(own_id)
     self.om = OwnershipManager(self.clients, self.peer_pool)
     self.sd_ui = SharedrawUI(self.peer_pool, self.om)
     self._update_clients_info()
Example #2
0
 def update_clients_info(self, clients: ClientsTable):
     # Aktualizacja listy klientów
     for ch in self.clients_table.get_children():
         self.clients_table.delete(ch)
     for client in clients.clients:
         self.clients_table.insert('',
                                   'end',
                                   text=client.id,
                                   values=(client.requested, client.granted,
                                           client.received_from_id))
     # Aktualizacja info o właścicielu tokena i blokadzie
     self.locked_label.update_text(clients.locked)
     self.token_owner_label.update_text(clients.token_owner)
     # Aktualizacja blokady
     has_token = clients.token_owner == own_id
     self.__set_lock_state(clients.locked, has_token)
     # Aktualizacja przycisków
     # jeśli zablokowaliśmy, to nie możemy tego zrobić drugi raz
     is_locker = (has_token and clients.locked)
     # tak samo jeśli już zażądaliśmy
     has_requested = clients.find_self().has_requested()
     self.__set_button_enabled(self.req_btn,
                               not (is_locker or has_requested))
     # jeśli nie zablokowaliśmy, to nie możemy rezygnować
     self.__set_button_enabled(self.resign_btn, is_locker)
     # Możemy się podłączyć, tylko, jeśli nie jesteśmy do nikogo podłączeni
     self.__set_button_enabled(self.connect_btn, len(clients.clients) <= 1)
     # Przycisk czyść aktywny jeśli możemy rysować
     self.__set_button_enabled(self.clean_btn, has_token
                               or not clients.locked)
Example #3
0
 def update_clients_info(self, clients: ClientsTable):
     # Aktualizacja listy klientów
     for ch in self.clients_table.get_children():
         self.clients_table.delete(ch)
     for client in clients.clients:
         self.clients_table.insert('', 'end', text=client.id,
                                   values=(client.requested, client.granted, client.received_from_id))
     # Aktualizacja info o właścicielu tokena i blokadzie
     self.locked_label.update_text(clients.locked)
     self.token_owner_label.update_text(clients.token_owner)
     # Aktualizacja blokady
     has_token = clients.token_owner == own_id
     self.__set_lock_state(clients.locked, has_token)
     # Aktualizacja przycisków
     # jeśli zablokowaliśmy, to nie możemy tego zrobić drugi raz
     is_locker = (has_token and clients.locked)
     # tak samo jeśli już zażądaliśmy
     has_requested = clients.find_self().has_requested()
     self.__set_button_enabled(self.req_btn, not (is_locker or has_requested))
     # jeśli nie zablokowaliśmy, to nie możemy rezygnować
     self.__set_button_enabled(self.resign_btn, is_locker)
     # Możemy się podłączyć, tylko, jeśli nie jesteśmy do nikogo podłączeni
     self.__set_button_enabled(self.connect_btn, len(clients.clients) <= 1)
     # Przycisk czyść aktywny jeśli możemy rysować
     self.__set_button_enabled(self.clean_btn, has_token or not clients.locked)
Example #4
0
class Controller(Thread):
    """ Kontroler
    """

    def __init__(self, stop_event: Event, port: int):
        super().__init__()
        self.setDaemon(True)
        self.stop_event = stop_event
        self.queue_to_ui = Queue()
        self.peer_pool = PeerPool(port, stop_event, self.queue_to_ui)
        self.status_monitor = ClientStatusMonitor(stop_event, self.peer_pool)
        # Lista klientów
        self.clients = ClientsTable()
        self.clients.add(own_id)
        self.om = OwnershipManager(self.clients, self.peer_pool)
        self.sd_ui = SharedrawUI(self.peer_pool, self.om)
        self._update_clients_info()

    def run(self):
        while not self.stop_event.is_set():
            sm = self.queue_to_ui.get()
            action = {
                PaintMessage: self.sd_ui.paint,
                ImageMessage: self._handle_image_msg,
                JoinMessage: self._handle_join_msg,
                QuitMessage: self._remove_remote_client,
                CleanMessage: lambda m: self.sd_ui.clean(),
                PassTokenMessage: self._handle_pass_token_message,
                RequestTableMessage: self._handle_request_message,
                ResignMessage: self._handle_resign_message,
                InternalReloadMessage: lambda m: self._update_clients_info(),
                InternalQuitMessage: self._remove_neighbour_client
            }.get(type(sm.message))

            if action:
                action(sm.message)

            if not isinstance(sm.message, InternalMessage):
                # Przesłanie komunikatu do pozostałych klientów
                self.peer_pool.send(sm.message, sm.client_id)

    def _handle_image_msg(self, msg: ImageMessage):
        self.clients.update_with_id_list(msg.client_ids, msg.client_id)
        self.clients.locked = msg.locked
        self.clients.token_owner = msg.token_owner
        self._add_client(msg.client_id)
        self.sd_ui.update_image(msg)

    def _handle_join_msg(self, msg: JoinMessage):
        if msg.received_from_id:
            # Przeproxowany klient - dodajemy do listy z informacją, kto wysłał
            self._add_client(msg.client_id, msg.received_from_id)
        else:
            # Odsyłamy ImageMessage, jeśli to klient, który podłączył się do nas
            img_msg = ImageMessage(own_id, self.sd_ui.get_png(), self.clients.get_client_ids(),
                                   self.clients.token_owner, self.clients.locked)
            self._add_client(msg.client_id)
            self.peer_pool.send_to_client(img_msg, msg.client_id)

    def _add_client(self, client_id: str, received_from_id=None):
        self.clients.add(client_id, received_from_id)
        self._update_clients_info()

    def _remove_remote_client(self, msg: QuitMessage):
        self.clients.remove_remote(msg.client_ids, msg.detected_by)
        self._update_clients_info()

    def _remove_neighbour_client(self, msg: InternalQuitMessage):
        # Usuwamy klienta i wszystkich z jego podsieci
        removed_ids = self.clients.remove(msg.client_id)
        # Generujemy Quit i wysyłamy do pozostałych
        quit_msg = QuitMessage(removed_ids, own_id)
        self.peer_pool.send(quit_msg)
        self._update_clients_info()

    def _handle_request_message(self, msg: RequestTableMessage):
        self.om.process_others_request(msg)
        self._update_clients_info()

    def _handle_resign_message(self, msg: ResignMessage):
        self.om.register_others_resign()
        self._update_clients_info()

    def _handle_pass_token_message(self, msg: PassTokenMessage):
        self.om.process_pass_token_msg(msg)
        self._update_clients_info()

    def _update_clients_info(self):
        self.sd_ui.update_clients_info(self.clients)