Move logic to wait for pending page loads into a decorator

This commit is contained in:
Joe Ferris 2012-03-23 16:34:39 -04:00
parent 312156ea6f
commit 4531f65dc3
5 changed files with 94 additions and 38 deletions

View File

@ -3,6 +3,7 @@
#include "UnsupportedContentHandler.h"
#include "CommandParser.h"
#include "CommandFactory.h"
#include "PageLoadingCommand.h"
#include "Command.h"
#include <QTcpSocket>
@ -13,12 +14,8 @@ Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
m_page = page;
m_commandFactory = new CommandFactory(page, this);
m_commandParser = new CommandParser(socket, m_commandFactory, this);
m_runningCommand = NULL;
m_queuedCommand = NULL;
m_pageSuccess = true;
m_commandWaiting = false;
m_pageLoadingFromCommand = false;
m_pendingResponse = NULL;
connect(m_socket, SIGNAL(readyRead()), m_commandParser, SLOT(checkNext()));
connect(m_commandParser, SIGNAL(commandReady(Command *)), this, SLOT(commandReady(Command *)));
connect(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
@ -35,37 +32,18 @@ void Connection::commandReady(Command *command) {
void Connection::startCommand() {
m_commandWaiting = false;
if (m_pageSuccess) {
m_runningCommand = m_queuedCommand;
m_queuedCommand = NULL;
connect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
connect(m_runningCommand,
SIGNAL(finished(Response *)),
this,
SLOT(finishCommand(Response *)));
m_runningCommand = new PageLoadingCommand(m_queuedCommand, m_page, this);
connect(m_runningCommand, SIGNAL(finished(Response *)), this, SLOT(finishCommand(Response *)));
m_runningCommand->start();
} else {
writePageLoadFailure();
}
}
void Connection::pageLoadingFromCommand() {
m_pageLoadingFromCommand = true;
}
void Connection::pendingLoadFinished(bool success) {
m_pageSuccess = success;
if (m_commandWaiting)
startCommand();
if (m_pageLoadingFromCommand) {
m_pageLoadingFromCommand = false;
if (m_pendingResponse) {
if (m_pageSuccess) {
writeResponse(m_pendingResponse);
} else {
writePageLoadFailure();
}
}
}
}
void Connection::writePageLoadFailure() {
@ -75,15 +53,8 @@ void Connection::writePageLoadFailure() {
}
void Connection::finishCommand(Response *response) {
disconnect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
m_runningCommand->deleteLater();
m_runningCommand = NULL;
delete m_queuedCommand;
m_queuedCommand = NULL;
if (m_pageLoadingFromCommand)
m_pendingResponse = response;
else
writeResponse(response);
writeResponse(response);
}
void Connection::writeResponse(Response *response) {
@ -97,6 +68,5 @@ void Connection::writeResponse(Response *response) {
m_socket->write(messageLength.toAscii());
m_socket->write(messageUtf8);
delete response;
m_pendingResponse = NULL;
}

View File

@ -7,6 +7,7 @@ class Command;
class Response;
class CommandParser;
class CommandFactory;
class PageLoadingCommand;
class Connection : public QObject {
Q_OBJECT
@ -18,7 +19,6 @@ class Connection : public QObject {
void commandReady(Command *command);
void finishCommand(Response *response);
void pendingLoadFinished(bool success);
void pageLoadingFromCommand();
private:
void startCommand();
@ -26,14 +26,12 @@ class Connection : public QObject {
void writePageLoadFailure();
QTcpSocket *m_socket;
Command *m_runningCommand;
Command *m_queuedCommand;
WebPage *m_page;
CommandParser *m_commandParser;
CommandFactory *m_commandFactory;
PageLoadingCommand *m_runningCommand;
bool m_pageSuccess;
bool m_commandWaiting;
bool m_pageLoadingFromCommand;
Response *m_pendingResponse;
};

View File

@ -0,0 +1,46 @@
#include "PageLoadingCommand.h"
#include "Command.h"
#include "WebPage.h"
PageLoadingCommand::PageLoadingCommand(Command *command, WebPage *page, QObject *parent) : QObject(parent) {
m_page = page;
m_command = command;
m_pageLoadingFromCommand = false;
m_pageSuccess = true;
m_pendingResponse = NULL;
connect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
connect(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
}
void PageLoadingCommand::start() {
connect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *)));
m_command->start();
};
void PageLoadingCommand::pendingLoadFinished(bool success) {
m_pageSuccess = success;
if (m_pageLoadingFromCommand) {
m_pageLoadingFromCommand = false;
if (m_pendingResponse) {
if (m_pageSuccess) {
emit finished(m_pendingResponse);
} else {
QString message = m_page->failureString();
emit finished(new Response(false, message));
}
}
}
}
void PageLoadingCommand::pageLoadingFromCommand() {
m_pageLoadingFromCommand = true;
}
void PageLoadingCommand::commandFinished(Response *response) {
disconnect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
m_command->deleteLater();
if (m_pageLoadingFromCommand)
m_pendingResponse = response;
else
emit finished(response);
}

40
src/PageLoadingCommand.h Normal file
View File

@ -0,0 +1,40 @@
#include <QObject>
#include <QStringList>
class Command;
class Response;
class WebPage;
/*
* Decorates a Command by deferring the finished() signal until any pending
* page loads are complete.
*
* If a Command starts a page load, no signal will be emitted until the page
* load is finished.
*
* If a pending page load fails, the command's response will be discarded and a
* failure response will be emitted instead.
*/
class PageLoadingCommand : public QObject {
Q_OBJECT
public:
PageLoadingCommand(Command *command, WebPage *page, QObject *parent = 0);
void start();
public slots:
void pageLoadingFromCommand();
void pendingLoadFinished(bool success);
void commandFinished(Response *response);
signals:
void finished(Response *response);
private:
WebPage *m_page;
Command *m_command;
Response *m_pendingResponse;
bool m_pageSuccess;
bool m_pageLoadingFromCommand;
};

View File

@ -35,6 +35,7 @@ HEADERS = \
CommandFactory.h \
SetProxy.h \
NullCommand.h \
PageLoadingCommand.h \
SOURCES = \
CurrentUrl.cpp \
@ -71,6 +72,7 @@ SOURCES = \
CommandFactory.cpp \
SetProxy.cpp \
NullCommand.cpp \
PageLoadingCommand.cpp \
RESOURCES = webkit_server.qrc
QT += network webkit