[Tutorial] Fix review blockers: null VDS guard, overlay QPointer, bounded fill, upgrade seeding

This commit is contained in:
Lukas Brübach 2026-10-11 15:10:43 +02:00
parent 89ef10c862
commit bfc970b6a9
6 changed files with 33 additions and 5 deletions

View file

@ -98,7 +98,7 @@ private:
QWidget *tutorializedWidget;
TutorialOverlay *tutorialOverlay;
QVector<TutorialSequence> sequences;
QList<TutorialSequence> sequences;
bool tutorialCompleted = false;

View file

@ -1,6 +1,7 @@
#ifndef TUTORIAL_OVERLAY_H
#define TUTORIAL_OVERLAY_H
#include <QPointer>
#include <QWidget>
class QFrame;
@ -49,7 +50,9 @@ private:
void recomputeLayout();
QRect computeBubbleRect(const QRect &hole, const QSize &bubbleSize) const;
QWidget *targetWidget = nullptr;
// QPointer: the target can be deleted while the overlay lives on (e.g. toggling
// the in-game VDS setting deleteLater()s it), so never hold a raw pointer across steps.
QPointer<QWidget> targetWidget;
QFrame *controlBar = nullptr;
QLabel *titleLabel = nullptr;
QPushButton *nextButton = nullptr;

View file

@ -172,6 +172,11 @@ void TabGame::finishTutorialInitialization()
tutorialInitialized = true;
}
// No sequence building (and no widget access) once the tutorial is done.
if (SettingsCache::instance().userInterface().getTutorialCompleted()) {
return;
}
auto deckViewSequence = deckViewContainers.first()->generateTutorialSequence();
tutorialController->addSequence(deckViewSequence);
@ -328,7 +333,7 @@ void TabGame::finishTutorialInitialization()
tutorialController->addSequence(gamePlaySequence);
if (tutorialStarted || SettingsCache::instance().userInterface().getTutorialCompleted()) {
if (tutorialStarted) {
return;
}
// The tab may have been shown before the local player joined; start now that

View file

@ -507,8 +507,14 @@ TutorialSequence VisualDeckEditorWidget::addTutorialSteps()
organizationStep.text = "Let's look at how cards are organized and displayed now.\n\nWe'll add some random cards "
"from the database to your deck, so you can see it in action properly.";
organizationStep.onExit = [this]() {
while (deckListModel->getDeckList()->getCardList().size() < 60) {
// getCardList() counts distinct card nodes, not copies, so once every random pick only bumps an
// existing node's count the size never grows. With fewer than ~60 distinct cards in the database
// this would loop forever, so bound the attempts to always terminate.
static constexpr int MaxFillAttempts = 600;
int attempts = 0;
while (deckListModel->getDeckList()->getCardList().size() < 60 && attempts < MaxFillAttempts) {
deckListModel->addCard(CardDatabaseManager::query()->getRandomCard(), DECK_ZONE_MAIN);
++attempts;
}
};