[Networking] Doxygen

This commit is contained in:
Lukas Brübach 2026-07-01 09:21:59 -04:00
parent 05ae6f47a6
commit 98cb71ab29
17 changed files with 2179 additions and 122 deletions

View file

@ -0,0 +1,170 @@
@page game_event_handler GameEventHandler
## Overview
`GameEventHandler` is the central coordinator for **game-wide commands and events**.
It acts as the bridge between the networking layer (protobuf messages received from
the server) and the local game model and UI.
Unlike `PlayerEventHandler`, which is responsible for player-scoped state and zones,
`GameEventHandler` handles:
- Global game flow (turns, phases, host changes)
- Player and spectator lifecycle events
- Chat and logging events
- Dispatching incoming events to the appropriate subsystem
- Sending locally initiated commands to the server
In short, it is the **top-level event dispatcher** for an active game.
---
## Responsibilities
`GameEventHandler` has four primary responsibilities:
### 1. Sending game-wide commands
UI actions that affect the game as a whole (e.g. advancing the turn, changing phases,
sending chat messages) are translated into protobuf commands and sent to the server
via this class.
Examples include:
- Advancing or reversing the turn order
- Conceding or unconceding
- Changing the active phase
- Leaving the game
- Sending chat messages
These commands are wrapped in `PendingCommand` instances so their lifecycle and
responses can be tracked.
---
### 2. Processing incoming game events
Incoming server messages arrive as a `GameEventContainer`.
`GameEventHandler` is responsible for:
- Emitting lifecycle signals before and after processing
- Dispatching each event to the correct handler
- Forwarding player-scoped events to `PlayerEventHandler` instances
- Handling spectator-only and game-global events directly
This design keeps networking concerns isolated from game logic and UI code.
---
### 3. Managing global game state transitions
Certain events affect the entire game state and require coordinated updates across
multiple subsystems. Examples include:
- Full game state synchronization
- Active player or phase changes
- Game host changes
- Game closure
- Turn reversal
`GameEventHandler` ensures these events are processed in a consistent order and
that all interested systems are notified via Qt signals.
---
### 4. Emitting UI and logging signals
Rather than directly manipulating UI widgets, `GameEventHandler` emits
high-level signals that are consumed by:
- Game widgets
- Player and spectator lists
- Message and event logs
- Status indicators (ready state, deck selection, connection state)
This keeps the handler independent of concrete UI implementations.
---
## Relationship to PlayerEventHandler
`GameEventHandler` and `PlayerEventHandler` work together but have distinct roles:
| GameEventHandler | PlayerEventHandler |
|------------------|--------------------|
| Global game state | Per-player state |
| Turn / phase flow | Zones and cards |
| Player join/leave | Player actions |
| Spectator events | Player-specific events |
| Chat dispatch | Card and zone updates |
When a server event is associated with a specific player, `GameEventHandler`
routes it to the corresponding `PlayerEventHandler`. Events without a player
context are handled directly.
---
## Event Processing Flow
A typical incoming event flow looks like this:
1. `AbstractClient` receives a `GameEventContainer`
2. `GameEventHandler::processGameEventContainer()` is called
3. `containerProcessingStarted()` is emitted
4. Each event is:
- Handled directly **or**
- Forwarded to a `PlayerEventHandler`
5. Logging and UI signals are emitted as needed
6. `containerProcessingDone()` is emitted
This structured flow makes it easy to:
- Suppress UI updates during replays
- Handle reconnections cleanly
- Detect flood protection or error states
---
## Command Lifecycle
Outgoing commands follow a similar structured path:
1. UI action triggers a `handle*()` method
2. A protobuf command is constructed
3. The command is wrapped in a `PendingCommand`
4. `sendGameCommand()` sends it to the server
5. `commandFinished()` receives the response
6. Errors or flood conditions are handled centrally
This approach avoids duplicated error handling across UI code.
---
## Design Goals
`GameEventHandler` is designed to be:
- **Centralized** one entry point for all game-wide events
- **UI-agnostic** communicates via signals, not widgets
- **Predictable** well-defined event ordering and lifecycle
- **Composable** works in concert with `PlayerEventHandler`
- **Testable** logic is separated from rendering
---
## Related Classes
- @ref GameEventHandler
- @ref PlayerEventHandler
- `GameEventContainer`
- `PendingCommand`
- `AbstractClient`
- `AbstractGame`
---
## See Also
- @ref GameLogic
- @ref PlayerEventHandler
- @ref GameState

View file

@ -0,0 +1,11 @@
@page developer_reference_network_client Client Networking (Overview)
The clients response to various network protocol events and associated handling are described here.
For information about game scoped events, see:
- @subpage game_event_handler
Certain game scoped events may be forwarded to player based handlers. For more information, see:
- @subpage player_event_handler

View file

@ -0,0 +1,199 @@
@page player_event_handler PlayerEventHandler
## Overview
`PlayerEventHandler` is responsible for applying **player-scoped game events**
to a single `Player` instance. These events modify the players board state,
zones, cards, counters, arrows, and associated UI and logging output.
Each `PlayerEventHandler` instance is bound **1:1 to a Player** and is invoked
exclusively by @ref GameEventHandler after basic routing and validation of
incoming server events.
This class represents the lowest-level authoritative application of game state
changes on the client.
---
## Scope and Authority
`PlayerEventHandler` operates under the following guarantees:
- All incoming events are **authoritative** and already validated by the server
- Events refer to valid players, zones, and card identifiers
- Ordering is guaranteed by the server and preserved by `GameEventHandler`
As a result, the handler does **not** perform rule validation or permission
checks. Its responsibility is to *apply* state, not *decide* legality.
---
## Responsibilities
### 1. Applying player-specific state changes
The primary responsibility of `PlayerEventHandler` is to mutate player-owned
state, including:
- Cards (`CardItem`)
- Zones (`CardZoneLogic`)
- Counters (card-level and player-level)
- Attachments and arrows
- Zone configuration flags (reveal / peek behavior)
Many handlers update both **logical state** and **visual/UI state** in tandem.
---
### 2. Coordinating complex card movement
Some events—most notably card movement—require coordinated updates across
multiple systems. For example, `eventMoveCard()`:
- Removes the card from the source zone
- Updates ownership, visibility, and identity
- Handles attachments and arrow cleanup
- Emits undo-draw or move logs
- Inserts the card into the destination zone
- Updates menus, hover state, and graphics
This makes `PlayerEventHandler` intentionally stateful and tightly coupled to
the board implementation.
---
### 3. Emitting logging signals
Rather than writing directly to logs or widgets, `PlayerEventHandler` emits
structured Qt signals describing *what happened*, including:
- Chat messages
- Card movement
- Shuffles and randomization
- Reveals and peeks
- Counter and attribute changes
These signals are consumed by logging systems and UI components, keeping
presentation concerns out of the handler.
Logging signals may be emitted **before or after mutation**, depending on
whether later changes would invalidate log data (e.g. card identity).
---
### 4. Handling cross-player interactions
Although bound to a single player, some events necessarily affect other
players state, including:
- Moving cards between players
- Attaching cards to another players permanents
- Creating arrows targeting other players or cards
In these cases, `PlayerEventHandler` performs the minimal required mutation
while respecting ownership boundaries enforced elsewhere.
---
## Event Dispatch Model
`PlayerEventHandler` exposes a single public entry point:
- `processGameEvent()`
This method:
1. Receives a generic `GameEvent`
2. Switches on `GameEventType`
3. Extracts the appropriate protobuf extension
4. Forwards the event to a typed handler
This keeps the event routing centralized and makes it easy to audit coverage
when new game events are introduced.
Unhandled events are logged as warnings.
---
## Event Categories
For clarity, event handlers are grouped conceptually into:
- **Chat and randomization**
- Chat messages
- Shuffles
- Dice rolls
- **Arrows and targeting**
- Create / delete arrows
- **Card and token creation**
- Token generation
- Counter creation
- **Card attributes and counters**
- Tapped state
- Power/toughness
- Annotations
- Card- and player-level counters
- **Zone-level operations**
- Card movement
- Zone dumps
- Card destruction
- Attachments
- **Draw and reveal**
- Drawing cards
- Reveals, peeks, and reveal windows
- **Zone configuration**
- Always-reveal and always-look-at-top-card flags
This grouping mirrors the structure of the header file and reflects the
conceptual responsibilities of the class.
---
## Relationship to GameEventHandler
`PlayerEventHandler` is never instantiated or invoked directly by UI code.
Instead:
1. `GameEventHandler` receives a `GameEventContainer`
2. Player-scoped events are routed to the appropriate `PlayerEventHandler`
3. Global or spectator events are handled elsewhere
This separation keeps game-wide logic decoupled from player board state and
makes reconnection and replay handling simpler.
---
## Design Intent
`PlayerEventHandler` is designed to be:
- **Authoritative** applies server state exactly as received
- **Stateful** maintains consistency across cards, zones, and UI
- **Explicit** one handler per event type
- **UI-aware** updates views and menus as part of state mutation
- **Auditable** easy to trace what code handles which event
---
## Related Classes
- @ref PlayerEventHandler
- @ref GameEventHandler
- `Player`
- `CardItem`
- `CardZoneLogic`
- `GameEvent`
- `GameEventContext`
---
## See Also
- @ref GameLogicPlayers
- @ref GameLogic