diff options
| author | David Shah <davey1576@gmail.com> | 2018-06-22 12:57:38 +0200 | 
|---|---|---|
| committer | David Shah <davey1576@gmail.com> | 2018-06-22 12:57:38 +0200 | 
| commit | 0448bed85901454280d56e7de132c3b16da39e6d (patch) | |
| tree | 15bd5d08118375b5a5b33aacd73164d5ce61e8cd | |
| parent | 63baa10032ecf301523e4cb1fca198d8a8b79e23 (diff) | |
| parent | 11d99853ab4514b1f6b87c5beb87c91f50e702a6 (diff) | |
| download | nextpnr-0448bed85901454280d56e7de132c3b16da39e6d.tar.gz nextpnr-0448bed85901454280d56e7de132c3b16da39e6d.tar.bz2 nextpnr-0448bed85901454280d56e7de132c3b16da39e6d.zip  | |
Merge branch 'master' of gitlab.com:SymbioticEDA/nextpnr
| -rw-r--r-- | gui/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | gui/base.qrc (renamed from gui/nextpnr.qrc) | 0 | ||||
| -rw-r--r-- | gui/basewindow.cc | 2 | ||||
| -rw-r--r-- | gui/dummy/nextpnr.qrc | 2 | ||||
| -rw-r--r-- | gui/ice40/mainwindow.cc | 41 | ||||
| -rw-r--r-- | gui/ice40/nextpnr.qrc | 7 | ||||
| -rw-r--r-- | gui/ice40/resources/control_pause.png | bin | 0 -> 598 bytes | |||
| -rw-r--r-- | gui/ice40/resources/control_play.png | bin | 0 -> 592 bytes | |||
| -rw-r--r-- | gui/ice40/resources/control_stop.png | bin | 0 -> 403 bytes | |||
| -rw-r--r-- | gui/ice40/worker.cc | 64 | ||||
| -rw-r--r-- | gui/ice40/worker.h | 17 | 
11 files changed, 122 insertions, 13 deletions
diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index b4dcde11..f19d2d20 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)  aux_source_directory(. GUI_SOURCE_FILES)  aux_source_directory(${family}/ GUI_SOURCE_FILES) -set(_RESOURCES nextpnr.qrc) +set(_RESOURCES base.qrc ${family}/nextpnr.qrc)  qt5_add_resources(GUI_RESOURCE_FILES ${_RESOURCES}) diff --git a/gui/nextpnr.qrc b/gui/base.qrc index b9e2f237..b9e2f237 100644 --- a/gui/nextpnr.qrc +++ b/gui/base.qrc diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 9020a719..b7258dd3 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -13,7 +13,7 @@  BaseMainWindow::BaseMainWindow(Context *_ctx, QWidget *parent)
          : QMainWindow(parent), ctx(_ctx)
  {
 -    Q_INIT_RESOURCE(nextpnr);
 +    Q_INIT_RESOURCE(base);
      qRegisterMetaType<std::string>();
      log_files.clear();
 diff --git a/gui/dummy/nextpnr.qrc b/gui/dummy/nextpnr.qrc new file mode 100644 index 00000000..03585ec0 --- /dev/null +++ b/gui/dummy/nextpnr.qrc @@ -0,0 +1,2 @@ +<RCC> +</RCC> diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index 934798bb..9ce7f41e 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -14,21 +14,54 @@  MainWindow::MainWindow(Context *_ctx, QWidget *parent)
          : BaseMainWindow(_ctx, parent)
  {
 +    Q_INIT_RESOURCE(nextpnr);
 + 
      std::string title = "nextpnr-ice40 - " + ctx->getChipName();
      setWindowTitle(title.c_str());
 -    createMenu();
 -
      task = new TaskManager(_ctx);
      connect(task, SIGNAL(log(std::string)), this, SLOT(writeInfo(std::string)));
 +
 +    createMenu();
  }
 -MainWindow::~MainWindow() {}
 +MainWindow::~MainWindow() { delete task; }
  void MainWindow::createMenu()
  {
      QMenu *menu_Custom = new QMenu("&ICE 40", menuBar);
      menuBar->addAction(menu_Custom->menuAction());
 +
 +    QAction *actionPlay = new QAction("Play", this);
 +    QIcon icon1;
 +    icon1.addFile(QStringLiteral(":/icons/resources/control_play.png"));
 +    actionPlay->setIcon(icon1);
 +    actionPlay->setStatusTip("Continue running task");
 +    connect(actionPlay, SIGNAL(triggered()), task,
 +            SLOT(continue_thread()));
 +
 +    QAction *actionPause = new QAction("Pause", this);
 +    QIcon icon2;
 +    icon2.addFile(QStringLiteral(":/icons/resources/control_pause.png"));
 +    actionPause->setIcon(icon2);
 +    actionPause->setStatusTip("Pause running task");
 +    connect(actionPause, SIGNAL(triggered()), task,
 +            SLOT(pause_thread()));
 +
 +    QAction *actionStop = new QAction("Stop", this);
 +    QIcon icon3;
 +    icon3.addFile(QStringLiteral(":/icons/resources/control_stop.png"));
 +    actionStop->setIcon(icon3);
 +    actionStop->setStatusTip("Stop running task");
 +    connect(actionStop, SIGNAL(triggered()), task,
 +            SLOT(terminate_thread()));
 +
 +    QToolBar *taskToolBar = new QToolBar();
 +    addToolBar(Qt::TopToolBarArea, taskToolBar);
 +
 +    taskToolBar->addAction(actionPlay);
 +    taskToolBar->addAction(actionPause);
 +    taskToolBar->addAction(actionStop);
  }
  void MainWindow::open()
 @@ -39,7 +72,7 @@ void MainWindow::open()          tabWidget->setCurrentWidget(info);
          std::string fn = fileName.toStdString();
 -        task->parsejson(fn);
 +        Q_EMIT task->parsejson(fn);
      }
  }
  bool MainWindow::save() { return false; }
\ No newline at end of file diff --git a/gui/ice40/nextpnr.qrc b/gui/ice40/nextpnr.qrc new file mode 100644 index 00000000..cbdb8b26 --- /dev/null +++ b/gui/ice40/nextpnr.qrc @@ -0,0 +1,7 @@ +<RCC> +    <qresource prefix="/icons"> +        <file>resources/control_play.png</file> +        <file>resources/control_pause.png</file> +        <file>resources/control_stop.png</file> +    </qresource> +</RCC> diff --git a/gui/ice40/resources/control_pause.png b/gui/ice40/resources/control_pause.png Binary files differnew file mode 100644 index 00000000..2d9ce9c4 --- /dev/null +++ b/gui/ice40/resources/control_pause.png diff --git a/gui/ice40/resources/control_play.png b/gui/ice40/resources/control_play.png Binary files differnew file mode 100644 index 00000000..0846555d --- /dev/null +++ b/gui/ice40/resources/control_play.png diff --git a/gui/ice40/resources/control_stop.png b/gui/ice40/resources/control_stop.png Binary files differnew file mode 100644 index 00000000..893bb60e --- /dev/null +++ b/gui/ice40/resources/control_stop.png diff --git a/gui/ice40/worker.cc b/gui/ice40/worker.cc index 5702137b..3854c67f 100644 --- a/gui/ice40/worker.cc +++ b/gui/ice40/worker.cc @@ -10,9 +10,22 @@  #include "route.h"  #include "timing.h" -Worker::Worker(Context *_ctx) : ctx(_ctx) +struct WorkerInterruptionRequested  { -    log_write_function = [this](std::string text) { Q_EMIT log(text); }; +}; + +Worker::Worker(Context *_ctx, TaskManager *parent) : ctx(_ctx) +{ +    log_write_function = [this, parent](std::string text) { +        Q_EMIT log(text); +        if (parent->shouldTerminate()) { +            parent->clearTerminate(); +            throw WorkerInterruptionRequested(); +        } +        while (parent->isPaused()){ +            QThread::sleep(1); +        } +    };  }  void Worker::parsejson(const std::string &filename) @@ -32,14 +45,16 @@ void Worker::parsejson(const std::string &filename)              log_error("Placing design failed.\n");          if (!route_design(ctx))              log_error("Routing design failed.\n"); -        Q_EMIT log("done"); +        Q_EMIT log("DONE\n");      } catch (log_execution_error_exception) { +    } catch (WorkerInterruptionRequested) { +        Q_EMIT log("CANCELED\n");      }  } -TaskManager::TaskManager(Context *ctx) +TaskManager::TaskManager(Context *ctx) : toTerminate(false), toPause(false)  { -    Worker *worker = new Worker(ctx); +    Worker *worker = new Worker(ctx, this);      worker->moveToThread(&workerThread);      connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);      connect(this, &TaskManager::parsejson, worker, &Worker::parsejson); @@ -49,8 +64,45 @@ TaskManager::TaskManager(Context *ctx)  TaskManager::~TaskManager()  { +    if (workerThread.isRunning())  +        terminate_thread();      workerThread.quit();      workerThread.wait();  } -void TaskManager::info(const std::string &result) { Q_EMIT log(result); }
\ No newline at end of file +void TaskManager::info(const std::string &result) { Q_EMIT log(result); } + +void TaskManager::terminate_thread() +{ +    QMutexLocker locker(&mutex); +    toTerminate = true; +} + +bool TaskManager::shouldTerminate() +{ +    QMutexLocker locker(&mutex); +    return toTerminate; +} + +void TaskManager::clearTerminate() +{ +    QMutexLocker locker(&mutex); +    toTerminate = false; +} + +void TaskManager::pause_thread() +{ +    QMutexLocker locker(&mutex); +    toPause = true; +} + +void TaskManager::continue_thread() +{ +    QMutexLocker locker(&mutex); +    toPause = false; +} +bool TaskManager::isPaused() +{ +    QMutexLocker locker(&mutex); +    return toPause; +}
\ No newline at end of file diff --git a/gui/ice40/worker.h b/gui/ice40/worker.h index 12d740dd..49d1df4d 100644 --- a/gui/ice40/worker.h +++ b/gui/ice40/worker.h @@ -1,17 +1,20 @@  #ifndef WORKER_H  #define WORKER_H +#include <QMutex>  #include <QThread>  #include "nextpnr.h"  // FIXME  USING_NEXTPNR_NAMESPACE +class TaskManager; +  class Worker : public QObject  {      Q_OBJECT    public: -    Worker(Context *ctx); +    Worker(Context *ctx, TaskManager *parent);    public Q_SLOTS:      void parsejson(const std::string &filename);    Q_SIGNALS: @@ -29,11 +32,23 @@ class TaskManager : public QObject    public:      TaskManager(Context *ctx);      ~TaskManager(); +    bool shouldTerminate(); +    void clearTerminate(); +    bool isPaused();    public Q_SLOTS:      void info(const std::string &text); +    void terminate_thread(); +    void pause_thread(); +    void continue_thread();    Q_SIGNALS: +    void terminate();      void parsejson(const std::string &);      void log(const std::string &text); + +  private: +    QMutex mutex; +    bool toTerminate; +    bool toPause;  };  #endif // WORKER_H  | 
