diff --git a/src/mind_reader/ui/main_frame.py b/src/mind_reader/ui/main_frame.py index b1a7f37..a1be193 100644 --- a/src/mind_reader/ui/main_frame.py +++ b/src/mind_reader/ui/main_frame.py @@ -1,10 +1,12 @@ -import wx +from typing import Optional -from mind_reader.core import GameState -from mind_reader.network import NetworkController, NetworkMesssage -from mind_reader.ui.dialogs import ClientConnectDialog, ServerStartDialog -from mind_reader.ui.menu_bar import AppMenuBar -from mind_reader.ui.views import LobbyPanel +import wx +from wx.lib.pubsub import pub + +from ..core import AppState +from ..ui.dialogs import ClientConnectDialog, ServerStartDialog +from ..ui.menu_bar import AppMenuBar +from ..ui.views import LobbyPanel class MainFrame(wx.Frame): @@ -16,12 +18,9 @@ class MainFrame(wx.Frame): size=wx.Size(700, 500), style=wx.DEFAULT_FRAME_STYLE, ) - self.state: GameState | None = None - self.network = NetworkController( - self._handle_network_message, - self._handle_network_notice, - ) - self.lobby_panel: LobbyPanel | None = None + self.state: AppState = AppState() + + self.lobby_panel: Optional[LobbyPanel] = None self.Center() @@ -32,7 +31,8 @@ class MainFrame(wx.Frame): self.SetMenuBar(self.menu_bar) self.CreateStatusBar(1) - # self.SetStatusText("Подключение отсутствует") + pub.subscribe(self.set_statusbar_text, "mainframe.statusbar") + pub.subscribe(self.remote_server_stop, "mainframe.remote_server_stop") self._bind_menu_events() @@ -45,11 +45,17 @@ class MainFrame(wx.Frame): wx.EVT_MENU, self.on_disconnect, self.menu_bar.item_disconnect ) + def set_statusbar_text(self, notice: str): + self.SetStatusText(notice) + + def remote_server_stop(self, state: AppState): + self.on_disconnect(None) + def _show_lobby(self): self._destroy_lobby() - if self.state: - self.lobby_panel = LobbyPanel(self, self.state) + if self.state.lobby: + self.lobby_panel = LobbyPanel(self, self.state.lobby) self.main_sizer.Add(self.lobby_panel, 1, wx.EXPAND) self.Layout() @@ -60,51 +66,29 @@ class MainFrame(wx.Frame): self.lobby_panel = None self.Layout() - def _handle_network_message(self, m: NetworkMesssage): - pass - - def _handle_network_notice(self, notice: str): - self.SetStatusText(notice) - - def _recreate_network_controller(self): - self.network.stop() - self.network = NetworkController( - self._handle_network_message, - self._handle_network_notice, - ) - def on_client_connect(self, event): d = ClientConnectDialog(self) + if d.ShowModal() == wx.ID_OK: - name, ip = d.get_data() - if self.network.connect(ip): - self.state = GameState(name) - self._show_lobby() + player_name, ip = d.get_data() + if self.state.connect(player_name, ip): self.menu_bar.set_connected_state(True) - else: - self._recreate_network_controller() - # self.SetStatusText(f"Подключено к {ip} | Ваше имя {name}") + self._show_lobby() + d.Destroy() def on_server_start(self, event): d = ServerStartDialog(self) - if d.ShowModal() == wx.ID_OK: - name, ip = d.get_data() - self.network.serve(ip) - self.state = GameState(name) + if d.ShowModal() == wx.ID_OK: + player_name, ip = d.get_data() + self.state.serve(player_name, ip) + self.menu_bar.set_connected_state(True) self._show_lobby() - self.menu_bar.set_connected_state(True) - # self.SetStatusText(f"Сервер запущен на {ip} | Ваше имя {name}") d.Destroy() def on_disconnect(self, event): - self._recreate_network_controller() - self._destroy_lobby() - - self.state = None - + self.state.disconnect() self.menu_bar.set_connected_state(False) - # self.SetStatusText("Подключение отсутствует") diff --git a/src/mind_reader/ui/views/lobby_view.py b/src/mind_reader/ui/views/lobby_view.py index f38beec..da76cf3 100644 --- a/src/mind_reader/ui/views/lobby_view.py +++ b/src/mind_reader/ui/views/lobby_view.py @@ -1,8 +1,9 @@ -from typing import Callable, Optional, cast +from typing import Callable, Optional import wx +from wx.lib.pubsub import pub -from mind_reader.core import GameState +from ...core import LobbyState class RoleColumn(wx.Panel): @@ -48,12 +49,13 @@ class RoleColumn(wx.Panel): class LobbyPanel(wx.Panel): - def __init__(self, parent, state: GameState): + def __init__(self, parent, state: LobbyState): super().__init__(parent) self.state = state - self._init_ui() + self.Bind(wx.EVT_WINDOW_DESTROY, self._on_destroy) + def _init_ui(self): main_sizer = wx.BoxSizer(wx.VERTICAL) @@ -83,12 +85,12 @@ class LobbyPanel(wx.Panel): self.SetSizer(main_sizer) - self.refresh_from_state() + pub.subscribe(self.refresh, "lobby.refresh") + + self.refresh(self.state) def _on_role_click(self, target_role: str): - success = self.state.set_player_role( - self.state.local_player_name, target_role - ) + success = self.state.set_player_role(target_role) if not success: wx.MessageBox( @@ -98,15 +100,19 @@ class LobbyPanel(wx.Panel): ) return - self.refresh_from_state() + self.refresh(self.state) def _on_start_click(self, event): wx.MessageBox("Сессия запущена!", "Старт", wx.OK | wx.ICON_INFORMATION) - def refresh_from_state(self): + def _on_destroy(self, event): + pub.unsubscribe(self.refresh, "lobby.refresh") + event.Skip() + + def refresh(self, state: LobbyState): players_by_role = {"NONE": [], "SETTER": [], "GUESSER": []} - for player, role in self.state.lobby_players.items(): + for player, role in state.players.items(): if role in players_by_role: players_by_role[role].append(player) @@ -114,9 +120,9 @@ class LobbyPanel(wx.Panel): self.column_setter.set_players(players_by_role["SETTER"]) self.column_guesser.set_players(players_by_role["GUESSER"]) - local_player_role = self.state.local_player_role + local_player_role = state.local_player_role self.column_none.set_role_state(local_player_role) self.column_setter.set_role_state(local_player_role) self.column_guesser.set_role_state(local_player_role) - self.button_start.Enable(self.state.is_session_ready()) + self.button_start.Enable(state.is_ready())