refactor(gameplay): delegate host transition events from service
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import GameSession, Guess, LieAnswer, Player, Question, RoundConfig, RoundQuestion, ScoreEvent
|
||||
from .payloads import build_finish_game_phase_event, build_start_next_round_phase_event
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -13,12 +15,16 @@ class RoundTransitionResult:
|
||||
round_config: RoundConfig
|
||||
round_question: RoundQuestion
|
||||
should_broadcast: bool
|
||||
phase_event_name: str | None = None
|
||||
phase_event_payload: dict[str, Any] | None = None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FinishGameResult:
|
||||
session: GameSession
|
||||
should_broadcast: bool
|
||||
phase_event_name: str | None = None
|
||||
phase_event_payload: dict[str, Any] | None = None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -110,6 +116,9 @@ def start_next_round(session: GameSession) -> RoundTransitionResult:
|
||||
round_question = None
|
||||
should_broadcast = False
|
||||
|
||||
phase_event_name = None
|
||||
phase_event_payload = None
|
||||
|
||||
if locked_session.status == GameSession.Status.SCOREBOARD:
|
||||
previous_round_config = RoundConfig.objects.filter(
|
||||
session=locked_session,
|
||||
@@ -137,6 +146,9 @@ def start_next_round(session: GameSession) -> RoundTransitionResult:
|
||||
locked_session.status = GameSession.Status.LIE
|
||||
locked_session.save(update_fields=["current_round", "status"])
|
||||
should_broadcast = True
|
||||
phase_event = build_start_next_round_phase_event(locked_session, next_round_config, round_question)
|
||||
phase_event_name = phase_event["name"]
|
||||
phase_event_payload = phase_event["payload"]
|
||||
elif locked_session.status == GameSession.Status.LIE:
|
||||
if locked_session.current_round <= 1:
|
||||
raise ValueError("next_round_invalid_phase")
|
||||
@@ -160,6 +172,8 @@ def start_next_round(session: GameSession) -> RoundTransitionResult:
|
||||
round_config=next_round_config,
|
||||
round_question=round_question,
|
||||
should_broadcast=should_broadcast,
|
||||
phase_event_name=phase_event_name,
|
||||
phase_event_payload=phase_event_payload,
|
||||
)
|
||||
|
||||
|
||||
@@ -168,15 +182,25 @@ def finish_game(session: GameSession) -> FinishGameResult:
|
||||
with transaction.atomic():
|
||||
locked_session = GameSession.objects.select_for_update().get(pk=session.pk)
|
||||
should_broadcast = False
|
||||
phase_event_name = None
|
||||
phase_event_payload = None
|
||||
|
||||
if locked_session.status == GameSession.Status.SCOREBOARD:
|
||||
locked_session.status = GameSession.Status.FINISHED
|
||||
locked_session.save(update_fields=["status"])
|
||||
should_broadcast = True
|
||||
phase_event = build_finish_game_phase_event(locked_session)
|
||||
phase_event_name = phase_event["name"]
|
||||
phase_event_payload = phase_event["payload"]
|
||||
elif locked_session.status != GameSession.Status.FINISHED:
|
||||
raise ValueError("finish_game_invalid_phase")
|
||||
|
||||
return FinishGameResult(session=locked_session, should_broadcast=should_broadcast)
|
||||
return FinishGameResult(
|
||||
session=locked_session,
|
||||
should_broadcast=should_broadcast,
|
||||
phase_event_name=phase_event_name,
|
||||
phase_event_payload=phase_event_payload,
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user