mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-29 17:32:17 -07:00
[Networking] Doxygen
Took 49 seconds
This commit is contained in:
parent
d4ac4837b7
commit
f5d4d08b15
3 changed files with 372 additions and 4 deletions
|
|
@ -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
|
||||||
|
|
@ -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 player’s 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 player’s 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
|
||||||
|
|
@ -1629,10 +1629,9 @@ void Server_AbstractPlayer::getInfo(ServerInfo_Player *info,
|
||||||
bool withUserInfo)
|
bool withUserInfo)
|
||||||
{
|
{
|
||||||
getProperties(*info->mutable_properties(), withUserInfo);
|
getProperties(*info->mutable_properties(), withUserInfo);
|
||||||
if (recipient == this) {
|
|
||||||
if (deck) {
|
if (deck) {
|
||||||
info->set_deck_list(deck->writeToString_Native().toStdString());
|
info->set_deck_list(deck->writeToString_Native().toStdString());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Server_Arrow *arrow : arrows) {
|
for (Server_Arrow *arrow : arrows) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue