[Client] Drop dead player event handler extension points

The second PlayerLogic constructor taking a custom PlayerEventHandler was UB
(converting this to PlayerLogic* in the base initializer, and connecting a
freshly-built handler against a not-yet-constructed object), and its abstract
extension surface — virtual initializeZones, virtual getPlayerEventHandler,
virtual processGameEvent, protected player member — has no subclass consumer in
the stack. Revert to the single primary constructor.

Also:
- Drop the unused GameMetaInfo::setIsTournament setter. Tournament status is
  authoritative from Event_GameJoined's ServerInfo_Game; the redundant
  is_tournament field on Event_GameStateChanged is removed in [Protocol].
- Gate the parent-game routing on has_parent_game_id() instead of comparing the
  proto default, so a future drop of the default keeps working.
This commit is contained in:
Lukas Brübach 2026-09-02 10:27:44 +02:00 committed by GitHub
parent 2d5734de21
commit 8f6d18df10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 9 additions and 49 deletions

View file

@ -268,8 +268,9 @@ void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event
const GameEventContext & /*context*/)
{
// Sub-games of a tournament report their parent hub game so the client can
// route "close game" back to the parent tab.
if (event.parent_game_id() != -1) {
// route "close game" back to the parent tab. Use has_parent_game_id rather
// than comparing the default so a future drop of the proto default still works.
if (event.has_parent_game_id()) {
game->getGameMetaInfo()->setParentGameId(event.parent_game_id());
}

View file

@ -89,11 +89,6 @@ public:
return gameInfo_.is_tournament();
}
void setIsTournament(bool t)
{
gameInfo_.set_is_tournament(t);
}
int parentGameId() const
{
return parentGameId_;

View file

@ -90,7 +90,7 @@ public:
* @param context Additional context (undo, judge, etc.).
* @param options Processing options (UI suppression, reveal behavior).
*/
virtual void processGameEvent(GameEvent::GameEventType type,
void processGameEvent(GameEvent::GameEventType type,
const GameEvent &event,
const GameEventContext &context,
EventProcessingOptions options);
@ -266,7 +266,7 @@ signals:
void cardZoneChanged(CardItem *card, bool sameZone);
void requestCardMenuUpdate(const CardItem *card);
protected:
private:
/** Owning player instance. */
PlayerLogic *player;

View file

@ -37,19 +37,6 @@ PlayerLogic::PlayerLogic(const ServerInfo_User &info, int _id, bool _local, bool
initializeZones();
}
PlayerLogic::PlayerLogic(const ServerInfo_User &info,
int _id,
bool _local,
bool _judge,
AbstractGame *_parent,
PlayerEventHandler *customEventHandler)
: QObject(_parent), game(_parent), playerInfo(new PlayerInfo(info, _id, _local, _judge)),
playerEventHandler(customEventHandler), playerActions(new PlayerActions(this)), active(false), conceded(false),
zoneId(0), dialogSemaphore(false)
{
initializeZones();
}
void PlayerLogic::initializeZones()
{
addZone(new PileZoneLogic(this, ZoneNames::DECK, false, true, false, this));

View file

@ -99,30 +99,7 @@ public:
PlayerLogic(const ServerInfo_User &info, int _id, bool _local, bool _judge, AbstractGame *_parent);
~PlayerLogic() override;
protected:
/**
* @brief Constructor for subclasses that need a custom event handler (e.g. DraftPlayerLogic).
*
* @p customEventHandler must be non-null and either QObject-parented to this PlayerLogic
* or deleted externally; it is not owned by PlayerLogic. The handler connects to @c player
* during its own constructor, so passing a freshly built subclass handler from an
* initializer list is safe.
*/
PlayerLogic(const ServerInfo_User &info,
int _id,
bool _local,
bool _judge,
AbstractGame *_parent,
PlayerEventHandler *customEventHandler);
public:
/**
* @brief Creates the standard zone set.
*
* Not virtually dispatched from constructors subclasses overriding this must add
* their extra zones in their own constructor body.
*/
virtual void initializeZones();
void initializeZones();
void updateZones();
void clear();