Mulligan crash fix, multi-column screen alignment for multiplayer, Server Win32 compile fix

This commit is contained in:
unknown 2011-06-05 19:45:37 +02:00
parent a03bf8884f
commit 1bc05562cc
8 changed files with 93 additions and 57 deletions

View file

@ -3,6 +3,7 @@
#include "zoneviewwidget.h" #include "zoneviewwidget.h"
#include "zoneviewzone.h" #include "zoneviewzone.h"
#include "phasestoolbar.h" #include "phasestoolbar.h"
#include <math.h>
#include <QAction> #include <QAction>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QSet> #include <QSet>
@ -31,7 +32,6 @@ void GameScene::addPlayer(Player *player)
qDebug("GameScene::addPlayer"); qDebug("GameScene::addPlayer");
players << player; players << player;
addItem(player); addItem(player);
rearrange();
connect(player, SIGNAL(sizeChanged()), this, SLOT(rearrange())); connect(player, SIGNAL(sizeChanged()), this, SLOT(rearrange()));
connect(player, SIGNAL(gameConceded()), this, SLOT(rearrange())); connect(player, SIGNAL(gameConceded()), this, SLOT(rearrange()));
} }
@ -46,43 +46,62 @@ void GameScene::removePlayer(Player *player)
void GameScene::rearrange() void GameScene::rearrange()
{ {
struct PlayerProcessor { playersByColumn.clear();
static void processPlayer(Player *p, qreal &w, QPointF &b, bool singlePlayer)
{
if (p->getConceded())
return;
const QRectF br = p->boundingRect(); QList<Player *> playersPlaying;
if (br.width() > w) int firstPlayer = -1;
w = br.width();
p->setPos(b);
p->setMirrored((b.y() < playerAreaSpacing) && !singlePlayer);
b += QPointF(0, br.height() + playerAreaSpacing);
}
};
qreal sceneHeight = -playerAreaSpacing;
for (int i = 0; i < players.size(); ++i) for (int i = 0; i < players.size(); ++i)
if (!players[i]->getConceded()) if (!players[i]->getConceded()) {
sceneHeight += players[i]->boundingRect().height() + playerAreaSpacing; playersPlaying.append(players[i]);
if ((firstPlayer == -1) && (players[i]->getLocal()))
firstPlayer = playersPlaying.size() - 1;
}
if (firstPlayer == -1)
firstPlayer = 0;
const int playersCount = playersPlaying.size();
const int columns = playersCount < 4 ? 1 : 2;
const int rows = ceil((qreal) playersCount / columns);
qreal sceneHeight = 0, sceneWidth = -playerAreaSpacing;
QList<int> columnWidth;
int firstPlayerOfColumn = firstPlayer;
for (int col = 0; col < columns; ++col) {
playersByColumn.append(QList<Player *>());
columnWidth.append(0);
qreal thisColumnHeight = -playerAreaSpacing;
const int rowsInColumn = rows - (playersCount % columns);
for (int j = 0; j < rowsInColumn; ++j) {
Player *player = playersPlaying[(firstPlayerOfColumn + j) % playersCount];
if (col == 0)
playersByColumn[col].prepend(player);
else
playersByColumn[col].append(player);
thisColumnHeight += player->boundingRect().height() + playerAreaSpacing;
if (player->boundingRect().width() > columnWidth[col])
columnWidth[col] = player->boundingRect().width();
}
if (thisColumnHeight > sceneHeight)
sceneHeight = thisColumnHeight;
sceneWidth += columnWidth[col] + playerAreaSpacing;
firstPlayerOfColumn += rowsInColumn;
}
phasesToolbar->setHeight(sceneHeight); phasesToolbar->setHeight(sceneHeight);
qreal phasesWidth = phasesToolbar->getWidth(); qreal phasesWidth = phasesToolbar->getWidth();
QPointF base(phasesWidth, 0);
qreal sceneWidth;
QList<Player *> localPlayers;
for (int i = 0; i < players.size(); ++i)
if (!players[i]->getLocal())
PlayerProcessor::processPlayer(players[i], sceneWidth, base, players.size() == 1);
else
localPlayers.append(players[i]);
for (int i = 0; i < localPlayers.size(); ++i)
PlayerProcessor::processPlayer(localPlayers[i], sceneWidth, base, players.size() == 1);
sceneWidth += phasesWidth; sceneWidth += phasesWidth;
playersRect = QRectF(0, 0, sceneWidth, sceneHeight);
qreal x = phasesWidth;
for (int col = 0; col < columns; ++col) {
qreal y = 0;
for (int row = 0; row < playersByColumn[col].size(); ++row) {
Player *player = playersByColumn[col][row];
player->setPos(x, y);
player->setMirrored(row != rows - 1);
y += player->boundingRect().height() + playerAreaSpacing;
}
x += columnWidth[col] + playerAreaSpacing;
}
setSceneRect(sceneRect().x(), sceneRect().y(), sceneWidth, sceneHeight); setSceneRect(sceneRect().x(), sceneRect().y(), sceneWidth, sceneHeight);
processViewSizeChange(viewSize); processViewSizeChange(viewSize);
@ -139,24 +158,33 @@ void GameScene::processViewSizeChange(const QSize &newSize)
qreal newRatio = ((qreal) newSize.width()) / newSize.height(); qreal newRatio = ((qreal) newSize.width()) / newSize.height();
qreal minWidth = 0; qreal minWidth = 0;
for (int i = 0; i < players.size(); ++i) { QList<qreal> minWidthByColumn;
qreal w = players[i]->getMinimumWidth(); for (int col = 0; col < playersByColumn.size(); ++col) {
if (w > minWidth) minWidthByColumn.append(0);
minWidth = w; for (int row = 0; row < playersByColumn[col].size(); ++row) {
qreal w = playersByColumn[col][row]->getMinimumWidth();
if (w > minWidthByColumn[col])
minWidthByColumn[col] = w;
}
minWidth += minWidthByColumn[col];
} }
minWidth += phasesToolbar->getWidth(); minWidth += phasesToolbar->getWidth();
qreal minRatio = minWidth / sceneRect().height(); qreal minRatio = minWidth / sceneRect().height();
qreal newWidth;
if (minRatio > newRatio) { if (minRatio > newRatio) {
// Aspect ratio is dominated by table width. // Aspect ratio is dominated by table width.
setSceneRect(0, 0, minWidth, sceneRect().height()); newWidth = minWidth;
} else { } else {
// Aspect ratio is dominated by window dimensions. // Aspect ratio is dominated by window dimensions.
setSceneRect(0, 0, newRatio * sceneRect().height(), sceneRect().height()); newWidth = newRatio * sceneRect().height();
} }
setSceneRect(0, 0, newWidth, sceneRect().height());
for (int i = 0; i < players.size(); ++i) qreal extraWidthPerColumn = (newWidth - minWidth) / playersByColumn.size();
players[i]->processSceneSizeChange(sceneRect().size() - QSizeF(phasesToolbar->getWidth(), 0)); for (int col = 0; col < playersByColumn.size(); ++col)
for (int row = 0; row < playersByColumn[col].size(); ++row)
playersByColumn[col][row]->processSceneSizeChange(minWidthByColumn[col] + extraWidthPerColumn);
} }
void GameScene::updateHover(const QPointF &scenePos) void GameScene::updateHover(const QPointF &scenePos)

View file

@ -22,7 +22,7 @@ private:
PhasesToolbar *phasesToolbar; PhasesToolbar *phasesToolbar;
QList<Player *> players; QList<Player *> players;
QRectF playersRect; QList<QList<Player *> > playersByColumn;
QList<ZoneViewWidget *> views; QList<ZoneViewWidget *> views;
QSize viewSize; QSize viewSize;
QPointer<CardItem> hoveredCard; QPointer<CardItem> hoveredCard;
@ -33,7 +33,6 @@ public:
GameScene(PhasesToolbar *_phasesToolbar, QObject *parent = 0); GameScene(PhasesToolbar *_phasesToolbar, QObject *parent = 0);
~GameScene(); ~GameScene();
void retranslateUi(); void retranslateUi();
const QRectF &getPlayersRect() const { return playersRect; }
void processViewSizeChange(const QSize &newSize); void processViewSizeChange(const QSize &newSize);
void startRubberBand(const QPointF &selectionOrigin); void startRubberBand(const QPointF &selectionOrigin);

View file

@ -4,7 +4,6 @@
#include "cardinfowidget.h" #include "cardinfowidget.h"
#include "protocol_items.h" #include "protocol_items.h"
#include "soundengine.h" #include "soundengine.h"
#include <QDebug>
#include <QMouseEvent> #include <QMouseEvent>
#include <QTextBlock> #include <QTextBlock>
@ -264,6 +263,9 @@ void MessageLogWidget::logMoveCard(Player *player, CardItem *card, CardZone *sta
void MessageLogWidget::logMulligan(Player *player, int number) void MessageLogWidget::logMulligan(Player *player, int number)
{ {
if (!player)
return;
if (number > -1) if (number > -1)
append(tr("%1 takes a mulligan to %n.", "", number).arg(sanitizeHtml(player->getName()))); append(tr("%1 takes a mulligan to %n.", "", number).arg(sanitizeHtml(player->getName())));
else else
@ -468,6 +470,7 @@ void MessageLogWidget::containerProcessingStarted(GameEventContext *_context)
currentContext = MessageContext_MoveCard; currentContext = MessageContext_MoveCard;
else if (qobject_cast<Context_Mulligan *>(_context)) { else if (qobject_cast<Context_Mulligan *>(_context)) {
currentContext = MessageContext_Mulligan; currentContext = MessageContext_Mulligan;
mulliganPlayer = 0;
mulliganNumber = static_cast<Context_Mulligan *>(_context)->getNumber(); mulliganNumber = static_cast<Context_Mulligan *>(_context)->getNumber();
} }
} }
@ -482,6 +485,7 @@ void MessageLogWidget::containerProcessingDone()
moveCardTapped.clear(); moveCardTapped.clear();
} else if (currentContext == MessageContext_Mulligan) { } else if (currentContext == MessageContext_Mulligan) {
logMulligan(mulliganPlayer, mulliganNumber); logMulligan(mulliganPlayer, mulliganNumber);
mulliganPlayer = 0;
mulliganNumber = 0; mulliganNumber = 0;
} }

View file

@ -1007,7 +1007,6 @@ void Player::eventDrawCards(Event_DrawCards *event)
hand->reorganizeCards(); hand->reorganizeCards();
deck->reorganizeCards(); deck->reorganizeCards();
emit logDrawCards(this, event->getNumberCards()); emit logDrawCards(this, event->getNumberCards());
} }
@ -1545,12 +1544,9 @@ void Player::setMirrored(bool _mirrored)
} }
} }
void Player::processSceneSizeChange(const QSizeF &newSize) void Player::processSceneSizeChange(int newPlayerWidth)
{ {
// This will need to be changed if player areas are displayed side by side (e.g. 2x2 for a 4-player game) qreal tableWidth = newPlayerWidth - CARD_HEIGHT - 15 - counterAreaWidth - stack->boundingRect().width();
qreal fullPlayerWidth = newSize.width();
qreal tableWidth = fullPlayerWidth - CARD_HEIGHT - 15 - counterAreaWidth - stack->boundingRect().width();
if (!settingsCache->getHorizontalHand()) if (!settingsCache->getHorizontalHand())
tableWidth -= hand->boundingRect().width(); tableWidth -= hand->boundingRect().width();

View file

@ -245,7 +245,7 @@ public:
qreal getMinimumWidth() const; qreal getMinimumWidth() const;
void setMirrored(bool _mirrored); void setMirrored(bool _mirrored);
void processSceneSizeChange(const QSizeF &newSize); void processSceneSizeChange(int newPlayerWidth);
void processPlayerInfo(ServerInfo_Player *info); void processPlayerInfo(ServerInfo_Player *info);
void processCardAttachment(ServerInfo_Player *info); void processCardAttachment(ServerInfo_Player *info);

View file

@ -73,6 +73,7 @@ void myMessageOutput(QtMsgType /*type*/, const char *msg)
logger->logMessage(msg); logger->logMessage(msg);
} }
#ifdef Q_OS_UNIX
void sigSegvHandler(int sig) void sigSegvHandler(int sig)
{ {
if (sig == SIGSEGV) if (sig == SIGSEGV)
@ -82,6 +83,7 @@ void sigSegvHandler(int sig)
delete loggerThread; delete loggerThread;
raise(sig); raise(sig);
} }
#endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {

View file

@ -3,8 +3,10 @@
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
#include <QDateTime> #include <QDateTime>
#ifdef Q_OS_UNIX
# include <sys/types.h> # include <sys/types.h>
# include <sys/socket.h> # include <sys/socket.h>
#endif
ServerLogger::ServerLogger(const QString &logFileName, QObject *parent) ServerLogger::ServerLogger(const QString &logFileName, QObject *parent)
: QObject(parent), flushRunning(false) : QObject(parent), flushRunning(false)
@ -14,9 +16,10 @@ ServerLogger::ServerLogger(const QString &logFileName, QObject *parent)
logFile->open(QIODevice::Append); logFile->open(QIODevice::Append);
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD); ::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD);
#endif
snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this); snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this);
connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup())); connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
#endif
} else } else
logFile = 0; logFile = 0;
@ -62,6 +65,7 @@ void ServerLogger::flushBuffer()
} }
} }
#ifdef Q_OS_UNIX
void ServerLogger::hupSignalHandler(int /*unused*/) void ServerLogger::hupSignalHandler(int /*unused*/)
{ {
if (!logFile) if (!logFile)
@ -85,6 +89,7 @@ void ServerLogger::handleSigHup()
snHup->setEnabled(true); snHup->setEnabled(true);
} }
#endif
QFile *ServerLogger::logFile; QFile *ServerLogger::logFile;
int ServerLogger::sigHupFD[2]; int ServerLogger::sigHupFD[2];

View file

@ -19,7 +19,9 @@ public:
public slots: public slots:
void logMessage(QString message); void logMessage(QString message);
private slots: private slots:
#ifdef Q_OS_UNIX
void handleSigHup(); void handleSigHup();
#endif
void flushBuffer(); void flushBuffer();
signals: signals:
void sigFlushBuffer(); void sigFlushBuffer();