73 lines
3.3 KiB
Python
73 lines
3.3 KiB
Python
from typing import Optional
|
|
|
|
from src.ezgg_lan_manager.services.DatabaseService import DatabaseService
|
|
from src.ezgg_lan_manager.services.UserService import UserService
|
|
from src.ezgg_lan_manager.types.Participant import Participant
|
|
from src.ezgg_lan_manager.types.Tournament import Tournament
|
|
from src.ezgg_lan_manager.types.TournamentBase import ParticipantType, TournamentError
|
|
from src.ezgg_lan_manager.types.User import User
|
|
|
|
|
|
class TournamentService:
|
|
def __init__(self, db_service: DatabaseService, user_service: UserService) -> None:
|
|
self._db_service = db_service
|
|
self._user_service = user_service
|
|
|
|
# Crude cache mechanism. If performance suffers, maybe implement a queue with Single-Owner-Pattern or a Lock
|
|
self._cache: dict[int, Tournament] = {}
|
|
self._cache_dirty: bool = True # Setting this flag invokes cache update on next read
|
|
|
|
async def _update_cache(self) -> None:
|
|
tournaments = await self._db_service.get_all_tournaments()
|
|
for tournament in tournaments:
|
|
self._cache[tournament.id] = tournament
|
|
self._cache_dirty = False
|
|
|
|
async def register_user_for_tournament(self, user_id: int, tournament_id: int) -> None:
|
|
tournament = await self.get_tournament_by_id(tournament_id)
|
|
if not tournament:
|
|
raise TournamentError(f"No tournament with ID {tournament_id} was found")
|
|
participant = Participant(id_=user_id, participant_type=ParticipantType.PLAYER)
|
|
tournament.add_participant(participant)
|
|
await self._db_service.add_participant_to_tournament(participant, tournament)
|
|
self._cache_dirty = True
|
|
|
|
async def unregister_user_from_tournament(self, user_id: int, tournament_id: int) -> None:
|
|
tournament = await self.get_tournament_by_id(tournament_id)
|
|
if not tournament:
|
|
raise TournamentError(f"No tournament with ID {tournament_id} was found")
|
|
participant = next(filter(lambda p: p.id == user_id, tournament.participants), None)
|
|
if participant is not None:
|
|
tournament.remove_participant(participant)
|
|
await self._db_service.remove_participant_from_tournament(participant, tournament)
|
|
self._cache_dirty = True
|
|
|
|
async def get_tournaments(self) -> list[Tournament]:
|
|
if self._cache_dirty:
|
|
await self._update_cache()
|
|
return list(self._cache.values())
|
|
|
|
async def get_tournament_by_id(self, tournament_id: int) -> Optional[Tournament]:
|
|
if self._cache_dirty:
|
|
await self._update_cache()
|
|
return self._cache.get(tournament_id, None)
|
|
|
|
async def get_users_from_participant_list(self, participants: list[Participant]) -> list[User]:
|
|
all_users = await self._db_service.get_all_users()
|
|
participant_ids = [p.id for p in participants]
|
|
return list(filter(lambda u: u.user_id in participant_ids, all_users))
|
|
|
|
async def start_tournament(self, tournament_id: int):
|
|
tournament = await self.get_tournament_by_id(tournament_id)
|
|
if tournament:
|
|
tournament.start()
|
|
# ToDo: Write matches/round to database
|
|
self._cache_dirty = True
|
|
|
|
async def cancel_tournament(self, tournament_id: int):
|
|
tournament = await self.get_tournament_by_id(tournament_id)
|
|
if tournament:
|
|
tournament.cancel()
|
|
# ToDo: Update to database
|
|
self._cache_dirty = True
|