Change Parser and Runner to singletons
I caved in - since both the parser and runner are needed in various locations in the program, and where these two objects are unique and present throughout the lifetime of the program, there is no reason to not make them singletons. Simplifies a lot of stuff!
MODIFY
src/cachetab.cpp
src/cachetab.cpp
#include "cachetab.h"
+#include <QComboBox>
#include "cachesetupwidget.h"
#include "ui_cachesetupwidget.h"
#include "ui_cachetab.h"
-#include <QComboBox>
CacheTab::CacheTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::CacheTab) {
m_ui->setupUi(this);
@@ -73,12 +73,6 @@ void CacheTab::cacheCountChanged(bool state) {
}
}
-void CacheTab::setRunnerCachePtr(RunnerCache* ptr) {
- // Setup connection between RunnerCache and CacheTab
- m_runnerCachePtr = const_cast<RunnerCache*>(ptr);
- m_runnerCachePtr->m_cacheTabPtr = this;
-}
-
CacheTab::~CacheTab() {
delete m_ui;
}

MODIFY
src/cachetab.h
src/cachetab.h
#ifndef CACHETAB_H
#define CACHETAB_H
-#include "runnercache.h"
#include <QWidget>
+#include "runnercache.h"
namespace Ui {
class CacheTab;
@@ -18,8 +18,6 @@ public:
explicit CacheTab(QWidget* parent = 0);
~CacheTab();
- void setRunnerCachePtr(RunnerCache* ptr);
-
private:
Ui::CacheTab* m_ui;

MODIFY
src/main.cpp
src/main.cpp
@@ -15,15 +15,16 @@ int main(int argc, char** argv) {
return 1;
}
+ /*
Parser parser;
// For now, initialize parser with input argument
if (parser.init(argv[1])) {
return 1;
}
+*/
- Runner runner(&parser);
QApplication app(argc, argv);
- MainWindow m(&runner, &parser);
+ MainWindow m;
m.show();
// execute runner

MODIFY
src/mainwindow.cpp
src/mainwindow.cpp
#include "defines.h"
-MainWindow::MainWindow(Runner* runnerPtr, Parser* parserPtr, QWidget* parent)
- : QMainWindow(parent), m_ui(new Ui::MainWindow) {
+MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::MainWindow) {
m_ui->setupUi(this);
setWindowTitle("RISC-V-SIM");
setWindowIcon(QIcon(QPixmap(":/logos/logo.png")));
showMaximized();
- m_runnerPtr = runnerPtr;
- m_parserPtr = parserPtr;
+ m_runnerPtr = Runner::getRunner();
+ m_parserPtr = Parser::getParser();
// Setup tab bar
m_ui->tabbar->addFancyTab(QIcon(QPixmap(":/logos/binary-code.svg")), "Code");
@@ -40,14 +39,9 @@ MainWindow::MainWindow(Runner* runnerPtr, Parser* parserPtr, QWidget* parent)
<< (m_ui->consoles->minimumHeight() + 1));
// Setup tab pointers
- m_ui->cachetab->setRunnerCachePtr(m_runnerPtr->getRunnerCachePtr());
- m_ui->memorytab->setMemoryPtr(m_runnerPtr->getMemoryPtr());
- m_ui->memorytab->setRegPtr(m_runnerPtr->getRegPtr());
- m_ui->processortab->initRegWidget(m_runnerPtr->getRegPtr());
- m_ui->processortab->initInstructionView(m_runnerPtr->getMemoryPtr(), m_runnerPtr->getStagePCS(), m_parserPtr,
- m_runnerPtr->getTextSize());
-
- m_ui->memorytab->init();
+ m_ui->processortab->initRegWidget();
+ m_ui->processortab->initInstructionView();
+ m_ui->memorytab->initMemoryTab();
// setup example projects
setupExamples();

MODIFY
src/mainwindow.h
src/mainwindow.h
@@ -14,7 +14,7 @@ class MainWindow : public QMainWindow {
Q_OBJECT
public:
- explicit MainWindow(Runner* runnerPtr, Parser* parserPtr, QWidget* parent = 0);
+ explicit MainWindow(QWidget* parent = 0);
~MainWindow();
private slots:

MODIFY
src/memorytab.cpp
src/memorytab.cpp
#include <QWheelEvent>
#include <algorithm>
+#include "runner.h"
+
MemoryTab::MemoryTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::MemoryTab) {
m_ui->setupUi(this);
@@ -16,8 +18,9 @@ MemoryTab::MemoryTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::MemoryTab)
m_ui->memorydisplaytype->setCurrentIndex(displayTypeN::Hex);
}
-void MemoryTab::init() {
- Q_ASSERT(m_memoryPtr != nullptr && m_regPtr != nullptr);
+void MemoryTab::initMemoryTab() {
+ m_memoryPtr = Runner::getRunner()->getMemoryPtr();
+ m_regPtr = Runner::getRunner()->getRegPtr();
initializeMemoryView();
m_ui->registerContainer->setRegPtr(m_regPtr);
m_ui->registerContainer->init();

MODIFY
src/memorytab.h
src/memorytab.h
@@ -22,10 +22,7 @@ class MemoryTab : public QWidget {
public:
explicit MemoryTab(QWidget* parent = 0);
~MemoryTab();
-
- void setMemoryPtr(memory* ptr) { m_memoryPtr = ptr; }
- void setRegPtr(std::vector<uint32_t>* ptr) { m_regPtr = ptr; }
- void init();
+ void initMemoryTab();
public slots:
void saveAddress();

MODIFY
src/parser.h
src/parser.h
@@ -12,8 +12,10 @@ typedef std::function<std::vector<uint32_t>(uint32_t)> decode_functor;
class Parser {
public:
- Parser();
- ~Parser();
+ static Parser* getParser() {
+ static Parser parser;
+ return &parser;
+ }
int getFileSize() { return m_fileSize; }
QString genStringRepr(uint32_t instr) const;
@@ -26,11 +28,12 @@ public:
std::vector<uint32_t> decodeRInstr(uint32_t instr) const { return m_decodeRInstr(instr); }
std::vector<uint32_t> decodeBInstr(uint32_t instr) const { return m_decodeBInstr(instr); }
-public:
bool init(char* filename);
void parseFile(memory* memoryPtr);
private:
+ Parser();
+ ~Parser();
ifstream m_fileStream;
istreambuf_iterator<char> m_fileIter;
int m_fileSize;

MODIFY
src/processortab.cpp
src/processortab.cpp
@@ -20,17 +20,17 @@ ProcessorTab::ProcessorTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::Proc
connect(m_ui->reset, &QPushButton::clicked, [=] { m_ui->start->setChecked(false); });
}
-void ProcessorTab::initRegWidget(std::vector<uint32_t>* regPtr) {
+void ProcessorTab::initRegWidget() {
// Setup register widget
- m_ui->registerContainer->setRegPtr(regPtr);
+ m_ui->registerContainer->setRegPtr(Runner::getRunner()->getRegPtr());
m_ui->registerContainer->init();
}
-void ProcessorTab::initInstructionView(memory* mem, const StagePCS& pcsptr, Parser* parser, int textSize) {
+void ProcessorTab::initInstructionView() {
// Setup instruction view
- m_instrModel = new InstructionModel(pcsptr, parser);
+ m_instrModel = new InstructionModel(Runner::getRunner()->getStagePCS(), Parser::getParser());
m_ui->instructionView->setEditTriggers(QAbstractItemView::NoEditTriggers);
- m_instrModel->setMemory(mem, textSize);
+ m_instrModel->setMemory(Runner::getRunner()->getMemoryPtr(), Runner::getRunner()->getTextSize());
m_ui->instructionView->setModel(m_instrModel);
m_ui->instructionView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
m_ui->instructionView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);

MODIFY
src/processortab.h
src/processortab.h
@@ -18,8 +18,8 @@ public:
explicit ProcessorTab(QWidget* parent = 0);
~ProcessorTab();
- void initRegWidget(std::vector<uint32_t>* regPtr);
- void initInstructionView(memory* mem, const StagePCS& pcsptr, Parser* parser, int textSize);
+ void initRegWidget();
+ void initInstructionView();
private slots:
void on_expandView_clicked();

MODIFY
src/runner.cpp
src/runner.cpp
@@ -48,7 +48,7 @@ int Runner::exec() {
int Runner::step() {
getInstruction(m_pc);
- err = execInstruction(m_currentInstruction);
+ execInstruction(m_currentInstruction);
return 0;
}

MODIFY
src/runner.h
src/runner.h
#include "defines.h"
#include "runnercache.h"
-class Parser;
+#include "parser.h"
+
class Runner {
public:
- Runner(Parser* parser);
- ~Runner();
-
int exec();
int step();
+ static Runner* getRunner() {
+ static Runner runner(Parser::getParser());
+ return &runner;
+ }
RunnerCache* getRunnerCachePtr() { return &m_cache; }
memory* getMemoryPtr() { return &m_memory; }
@@ -25,6 +27,8 @@ public:
const StagePCS& getStagePCS() const { return m_stagePCS; }
private:
+ Runner(Parser* parser);
+ ~Runner();
instrState execInstruction(Instruction instr);
void handleError(instrState err) const;

Change Parser and Runner to singletons

I caved in - since both the parser and runner are needed in various locations in the program, and where these two objects are unique and present throughout the lifetime of the program, there is no reason to not make them singletons. Simplifies a lot of stuff!