logic: made parsing interruptable by introducing TaskScheduler

This change introduces the TaskScheduler, which queues and processes Tasks on a separate thread. The Task class provides
a common interface for deriving all specific tasks. A task can split it's processing into multiple update calls. The
TaskScheduler will update a task until it is finished or interrupt it when necessary. TaskGroups can be used to bundle
multiple Tasks together. So far only TaskGroupSequential was implemented which runs the Tasks in the set order.

TaskParseCxx utilizes the CxxParser to parse each source file in a single update call. Parsing can be interrupted using
the ESC key. The Statusbar shows the parsing progress.
This commit is contained in:
Eberhard Graether
2015-04-23 18:57:38 +02:00
parent a18213d172
commit 3c7c3da527
34 changed files with 1000 additions and 221 deletions
+103 -89
View File
@@ -12,6 +12,7 @@
#include "qt/view/QtViewWidgetWrapper.h"
#include "utility/logging/logging.h"
#include "utility/messaging/type/MessageFind.h"
#include "utility/messaging/type/MessageInterruptTasks.h"
#include "utility/messaging/type/MessageLoadProject.h"
#include "utility/messaging/type/MessageLoadSource.h"
#include "utility/messaging/type/MessageRedo.h"
@@ -36,7 +37,9 @@ QtMainWindow::QtMainWindow()
setupFindMenu();
setupHelpMenu();
// Need to call loadLayout here for right DockWidgetsize on Linux
setupShortcuts();
// Need to call loadLayout here for right DockWidget size on Linux
// Seconde call is in Application.cpp
loadLayout();
}
@@ -45,94 +48,6 @@ QtMainWindow::~QtMainWindow()
{
}
void QtMainWindow::about()
{
QMessageBox::about(
this,
tr("About"),
tr(
"Developed by:\n\n"
"Manuel Dobusch\n"
"Eberhard Gräther\n"
"Malte Langkabel\n"
"Victoria Pfausler\n"
"Andreas Stallinger\n"
)
);
}
void QtMainWindow::newProject()
{
QString sourceDir = QFileDialog::getExistingDirectory(this, tr("Open Directory"));
if (!sourceDir.isEmpty())
{
MessageLoadSource(sourceDir.toStdString()).dispatch();
}
}
void QtMainWindow::openProject(const QString &path)
{
QString fileName = path;
if (fileName.isNull())
{
fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", "XML Files (*.xml)");
}
if (!fileName.isEmpty())
{
MessageLoadProject(fileName.toStdString()).dispatch();
}
}
void QtMainWindow::undo()
{
MessageUndo().dispatch();
}
void QtMainWindow::redo()
{
MessageRedo().dispatch();
}
void QtMainWindow::saveProject()
{
MessageSaveProject("").dispatch();
}
void QtMainWindow::saveAsProject()
{
QString filename = "";
filename = QFileDialog::getSaveFileName(this, "Save File as", "", "XML Files(*.xml)");
if(!filename.isEmpty())
{
MessageSaveProject(filename.toStdString()).dispatch();
}
}
void QtMainWindow::find()
{
MessageFind().dispatch();
}
void QtMainWindow::closeWindow()
{
QApplication* app = dynamic_cast<QApplication*>(QCoreApplication::instance());
QWidget* activeWindow = app->activeWindow();
if (activeWindow)
{
activeWindow->close();
}
}
void QtMainWindow::refresh()
{
MessageRefresh().dispatch();
}
void QtMainWindow::addView(View* view)
{
QDockWidget* dock = new QDockWidget(tr(view->getName().c_str()), this);
@@ -207,6 +122,99 @@ bool QtMainWindow::event(QEvent* event)
return QMainWindow::event(event);
}
void QtMainWindow::about()
{
QMessageBox::about(
this,
tr("About"),
tr(
"Developed by:\n\n"
"Manuel Dobusch\n"
"Eberhard Gräther\n"
"Malte Langkabel\n"
"Victoria Pfausler\n"
"Andreas Stallinger\n"
)
);
}
void QtMainWindow::newProject()
{
QString sourceDir = QFileDialog::getExistingDirectory(this, tr("Open Directory"));
if (!sourceDir.isEmpty())
{
MessageLoadSource(sourceDir.toStdString()).dispatch();
}
}
void QtMainWindow::openProject(const QString &path)
{
QString fileName = path;
if (fileName.isNull())
{
fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", "XML Files (*.xml)");
}
if (!fileName.isEmpty())
{
MessageLoadProject(fileName.toStdString()).dispatch();
}
}
void QtMainWindow::find()
{
MessageFind().dispatch();
}
void QtMainWindow::closeWindow()
{
QApplication* app = dynamic_cast<QApplication*>(QCoreApplication::instance());
QWidget* activeWindow = app->activeWindow();
if (activeWindow)
{
activeWindow->close();
}
}
void QtMainWindow::refresh()
{
MessageRefresh().dispatch();
}
void QtMainWindow::saveProject()
{
MessageSaveProject("").dispatch();
}
void QtMainWindow::saveAsProject()
{
QString filename = "";
filename = QFileDialog::getSaveFileName(this, "Save File as", "", "XML Files(*.xml)");
if(!filename.isEmpty())
{
MessageSaveProject(filename.toStdString()).dispatch();
}
}
void QtMainWindow::undo()
{
MessageUndo().dispatch();
}
void QtMainWindow::redo()
{
MessageRedo().dispatch();
}
void QtMainWindow::handleEscapeShortcut()
{
MessageInterruptTasks().dispatch();
}
void QtMainWindow::setupProjectMenu()
{
QMenu *menu = new QMenu(tr("&Project"), this);
@@ -254,6 +262,12 @@ void QtMainWindow::setupHelpMenu()
menu->addAction(tr("About &Qt"), QCoreApplication::instance(), SLOT(aboutQt()));
}
void QtMainWindow::setupShortcuts()
{
m_escapeShortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
connect(m_escapeShortcut, SIGNAL(activated()), SLOT(handleEscapeShortcut()));
}
QDockWidget* QtMainWindow::getDockWidgetForView(View* view) const
{
for (size_t i = 0; i < m_dockWidgets.size(); i++)
+7
View File
@@ -4,6 +4,7 @@
#include <utility>
#include <vector>
#include <QShortcut>
#include <QtWidgets/QMainWindow>
class QDockWidget;
@@ -41,6 +42,8 @@ public slots:
void undo();
void redo();
void handleEscapeShortcut();
private:
void setupEditMenu();
void setupProjectMenu();
@@ -48,9 +51,13 @@ private:
void setupFindMenu();
void setupHelpMenu();
void setupShortcuts();
QDockWidget* getDockWidgetForView(View* view) const;
std::vector<std::pair<View*, QDockWidget*>> m_dockWidgets;
QShortcut* m_escapeShortcut;
};
#endif // QT_MAIN_WINDOW_H