feat(core): отдельный класс для каждого состояния приложения

This commit is contained in:
2026-08-09 02:05:53 +03:00
parent f38539f3c8
commit f80a9b4098
3 changed files with 176 additions and 35 deletions
+4 -2
View File
@@ -1,5 +1,7 @@
from mind_reader.core.game_state import GameState
from .state import AppState, LobbyState, SessionState
__all__ = [
"GameState",
"AppState",
"LobbyState",
"SessionState",
]
-33
View File
@@ -1,33 +0,0 @@
class GameState:
def __init__(self, local_player_name: str):
self.local_player_name: str = local_player_name
self.remote_player_name: str | None = None
self.lobby_players: dict[str, str] = {self.local_player_name: "NONE"}
def add_remote_player(self, player_name: str):
self.remote_player_name = player_name
self.lobby_players[self.remote_player_name] = "NONE"
def delete_remote_player(self):
if self.remote_player_name in self.lobby_players:
del self.lobby_players[self.remote_player_name]
self.remote_player_name = None
def set_player_role(self, player_name: str, role: str) -> bool:
current_role = self.lobby_players.get(player_name)
if current_role == role:
return False
if role in ["NONE", "SETTER", "GUESSER"]:
self.lobby_players[player_name] = role
return True
return False
@property
def local_player_role(self) -> str:
return self.lobby_players[self.local_player_name]
def is_session_ready(self) -> bool:
roles = list(self.lobby_players.values())
return ("SETTER" in roles) and ("GUESSER" in roles)
+172
View File
@@ -0,0 +1,172 @@
from typing import Callable, Optional
from wx.lib.pubsub import pub
from ..network import NetworkController, NetworkMesssage
OnNetworkEventCallback = Callable[[dict[str, str]], None]
class BaseState:
def __init__(self, app_state: "AppState"):
self.app_state = app_state
def handle_network_message(self, message: NetworkMesssage) -> None:
pass
class LobbyState(BaseState):
def __init__(self, app_state: "AppState", local_player_name: str):
super().__init__(app_state)
self.local_player_name: str = local_player_name
self.remote_player_name: Optional[str] = None
self.players: dict[str, str] = {self.local_player_name: "NONE"}
def handle_network_message(self, message: NetworkMesssage) -> None:
callbacks: dict[str, OnNetworkEventCallback] = {
"add_player": self.handle_add_player,
"get_player": self.handle_get_player,
"set_role": self.handle_set_player_role,
"disconnect": self.handle_disconnect,
"server_stop": self.handle_server_stop,
}
callback = callbacks.get(message.event, None)
if callback:
callback(message.payload)
pub.sendMessage("lobby.refresh", state=self)
def send_local_player(self) -> None:
player_name = self.local_player_name
player_role = self.players.get(player_name, "NONE")
self.app_state.network.send(
"add_player",
{
"player_name": player_name,
"player_role": player_role,
},
)
def get_remote_player(self) -> None:
self.app_state.network.send("get_player")
def set_player_role(self, role: str) -> bool:
current_role = self.players[self.local_player_name]
result = False
if current_role == role:
result = False
if role in ["NONE", "SETTER", "GUESSER"]:
self.players[self.local_player_name] = role
result = True
if result:
if self.app_state.network.conn:
self.app_state.network.send(
"set_role",
{
"player_name": self.local_player_name,
"player_role": role,
},
)
return result
def send_client_disconnect(self) -> None:
self.app_state.network.send(
"disconnect", {"player_name": self.local_player_name}
)
def send_server_stop(self) -> None:
self.app_state.network.send("server_stop")
def handle_add_player(self, payload: dict[str, str]) -> None:
player_name = payload["player_name"]
player_role = payload["player_role"]
self.remote_player_name = player_name
self.players[self.remote_player_name] = player_role
def handle_get_player(self, payload: dict[str, str]) -> None:
self.send_local_player()
def handle_set_player_role(self, payload: dict[str, str]) -> None:
player_name = payload["player_name"]
player_role = payload["player_role"]
self.players[player_name] = player_role
def handle_disconnect(self, payload: dict[str, str]) -> None:
player_name = payload["player_name"]
self.players.pop(player_name)
self.remote_player_name = None
def handle_server_stop(self, payload: dict[str, str]) -> None:
pub.sendMessage("mainframe.remote_server_stop", state=self.app_state)
@property
def local_player_role(self) -> str:
return self.players[self.local_player_name]
def is_ready(self) -> bool:
roles = list(self.players.values())
return ("SETTER" in roles) and ("GUESSER" in roles)
class SessionState(BaseState):
def __init__(self, app_state: "AppState"):
super().__init__(app_state)
class AppState:
def __init__(self):
self.network = NetworkController(
self.handle_network_message,
self.handle_network_notice,
)
self.lobby: Optional[LobbyState] = None
self.session: Optional[SessionState] = None
def handle_network_message(self, message: NetworkMesssage) -> None:
if self.lobby:
self.lobby.handle_network_message(message)
if self.session:
self.session.handle_network_message(message)
def handle_network_notice(self, notice: str) -> None:
pub.sendMessage("mainframe.statusbar", notice=notice)
def recreate_network_controller(self) -> None:
self.network.stop()
self.network = NetworkController(
self.handle_network_message,
self.handle_network_notice,
)
def connect(self, player_name: str, host: str, port: int = 8994) -> bool:
if self.network.connect(host, port):
self.lobby = LobbyState(self, player_name)
self.lobby.send_local_player()
self.lobby.get_remote_player()
return True
else:
self.recreate_network_controller()
return False
def serve(self, player_name: str, host: str, port: int = 8994) -> None:
self.network.serve(host, port)
self.lobby = LobbyState(self, player_name)
def disconnect(self) -> None:
if self.lobby:
if self.network.is_server:
self.lobby.send_server_stop()
else:
self.lobby.send_client_disconnect()
self.lobby = None
self.recreate_network_controller()