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 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)
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)