Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions include/gui/GUIController.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ namespace gui
Q_PROPERTY(QString currentScheduler READ currentScheduler WRITE setCurrentScheduler NOTIFY currentSchedulerChanged)
Q_PROPERTY(bool isRunning READ isRunning NOTIFY isRunningChanged)
Q_PROPERTY(int timeQuantum READ timeQuantum WRITE setTimeQuantum NOTIFY timeQuantumChanged)
Q_PROPERTY(bool isDarkMode READ isDarkMode WRITE setIsDarkMode NOTIFY isDarkModeChanged)
Q_PROPERTY(bool animationsEnabled READ animationsEnabled WRITE setAnimationsEnabled NOTIFY animationsEnabledChanged)
Q_PROPERTY(QObject* ganttBlocksModel READ ganttBlocksModel CONSTANT)
Q_PROPERTY(QObject* readyQueueModel READ readyQueueModel CONSTANT)
Q_PROPERTY(QObject* threadListModel READ threadListModel CONSTANT)
Expand All @@ -40,6 +42,12 @@ namespace gui
int timeQuantum() const { return m_timeQuantum; }
void setTimeQuantum(int quantum);

bool isDarkMode() const { return m_isDarkMode; }
void setIsDarkMode(bool darkMode);

bool animationsEnabled() const { return m_animationsEnabled; }
void setAnimationsEnabled(bool enabled);

QObject* ganttBlocksModel() { return &m_ganttChartModel; }
QObject* readyQueueModel() { return &m_readyQueueModel; }
QObject* threadListModel() { return &m_threadListModel; }
Expand All @@ -64,6 +72,8 @@ namespace gui
void currentSchedulerChanged();
void isRunningChanged();
void timeQuantumChanged();
void isDarkModeChanged();
void animationsEnabledChanged();
void simulationUpdated();
void currentTimeChanged();

Expand All @@ -82,6 +92,8 @@ namespace gui
int m_timeQuantum{ 2 };
int m_currentTime{ 0 };
int m_nextThreadId{ 0 };
bool m_isDarkMode{ true };
bool m_animationsEnabled{ true };

ThreadListModel m_threadListModel;
ReadyQueueModel m_readyQueueModel;
Expand Down
111 changes: 64 additions & 47 deletions src/gui/GUIController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <QJsonArray>
#include <QFile>
#include <QTextStream>
#include <QCoreApplication>
#include <QEvent>

namespace gui
{
Expand Down Expand Up @@ -67,6 +69,25 @@ namespace gui
}
}

void GUIController::setIsDarkMode(bool darkMode)
{
if (m_isDarkMode != darkMode)
{
m_isDarkMode = darkMode;
emit isDarkModeChanged();
}
}

void GUIController::setAnimationsEnabled(bool enabled)
{
if (m_animationsEnabled != enabled)
{
m_animationsEnabled = enabled;
emit animationsEnabledChanged();
emit simulationUpdated(); // Ïðèíóäèòåëüíîå îáíîâëåíèå UI ïðè ïåðåêëþ÷åíèè àíèìàöèé
}
}

void GUIController::startSimulation()
{
if (!m_isRunning)
Expand All @@ -92,19 +113,48 @@ namespace gui

void GUIController::resetSimulation()
{
// 1. Îñòàíàâëèâàåì òàéìåð, ÷òîáû íå ïîðîæäàòü íîâûå stepSimulation.
if (m_timer->isActive())
{
m_timer->stop();
}
m_nextThreadId = 0;
m_lastLoadedThreads.clear();

// 2. Ñèíõðîííûé reset âîðêåðà. Áëîêèðóþùèé âûçîâ ãàðàíòèðóåò, ÷òî
// âñå ðàíåå ïîñòàâëåííûå â î÷åðåäü stepSimulation() óæå
// âûïîëíèëèñü, è èõ ñèãíàëû (QueuedConnection) óæå ëåæàò
// â î÷åðåäè ñîáûòèé GUI-ïîòîêà.
QMetaObject::invokeMethod(m_worker, "resetSimulation", Qt::BlockingQueuedConnection);

// 3. Óäàëÿåì èç î÷åðåäè GUI-ïîòîêà âñå îòëîæåííûå MetaCall-ñîáûòèÿ,
// àäðåñîâàííûå ýòîìó îáúåêòó. Ýòî «óñòàðåâøèå» ñèãíàëû îò
// óæå îòðàáîòàâøèõ step'îâ — áåç ýòîé î÷èñòêè îíè áû
// ïîâòîðíî íàïîëíèëè ìîäåëè ñðàçó ïîñëå èõ î÷èñòêè íèæå.
QCoreApplication::removePostedEvents(this, QEvent::MetaCall);

// 4. Î÷èùàåì âñå ìîäåëè.
m_ganttChartModel.clear();
m_readyQueueModel.clear();
m_threadListModel.clear();
m_benchmarkResultsModel.clear();

QMetaObject::invokeMethod(m_worker, "resetSimulation", Qt::QueuedConnection);
// 5. Ñáðàñûâàåì âíóòðåííåå ñîñòîÿíèå.
m_nextThreadId = 0;
m_lastLoadedThreads.clear();

// 6. ßâíî ñáðàñûâàåì ñâîéñòâà ñèìóëÿöèè — íå ïîëàãàåìñÿ íà ñèãíàëû
// âîðêåðà, ïîòîìó ÷òî îíè áûëè óäàëåíû íà øàãå 3.
if (m_currentTime != 0)
{
m_currentTime = 0;
emit currentTimeChanged();
}
if (m_isRunning)
{
m_isRunning = false;
emit isRunningChanged();
}

emit simulationUpdated();
}

void GUIController::addThread(int id, int burstTime, int priority)
Expand Down Expand Up @@ -191,14 +241,8 @@ namespace gui
void GUIController::saveToJson(const QString& filePath)
{
QString path = filePath;
if (path.startsWith("file:///"))
{
path = path.mid(8);
}
else if (path.startsWith("file://"))
{
path = path.mid(7);
}
if (path.startsWith("file:///")) path = path.mid(8);
else if (path.startsWith("file://")) path = path.mid(7);

QJsonObject rootObj;
rootObj["scheduler"] = m_currentScheduler;
Expand Down Expand Up @@ -228,40 +272,22 @@ namespace gui
void GUIController::loadFromJson(const QString& filePath)
{
QString path = filePath;
if (path.startsWith("file:///"))
{
path = path.mid(8);
}
else if (path.startsWith("file://"))
{
path = path.mid(7);
}
if (path.startsWith("file:///")) path = path.mid(8);
else if (path.startsWith("file://")) path = path.mid(7);

QFile file(path);
if (!file.open(QIODevice::ReadOnly))
{
return;
}
if (!file.open(QIODevice::ReadOnly)) return;

QByteArray data = file.readAll();
file.close();

QJsonDocument doc = QJsonDocument::fromJson(data);
if (doc.isNull() || !doc.isObject())
{
return;
}
if (doc.isNull() || !doc.isObject()) return;

QJsonObject rootObj = doc.object();

if (rootObj.contains("scheduler"))
{
setCurrentScheduler(rootObj["scheduler"].toString());
}
if (rootObj.contains("timeQuantum"))
{
setTimeQuantum(rootObj["timeQuantum"].toInt());
}
if (rootObj.contains("scheduler")) setCurrentScheduler(rootObj["scheduler"].toString());
if (rootObj.contains("timeQuantum")) setTimeQuantum(rootObj["timeQuantum"].toInt());

resetSimulation();

Expand All @@ -282,20 +308,11 @@ namespace gui
void GUIController::exportCsv(const QString& filePath)
{
QString path = filePath;
if (path.startsWith("file:///"))
{
path = path.mid(8);
}
else if (path.startsWith("file://"))
{
path = path.mid(7);
}
if (path.startsWith("file:///")) path = path.mid(8);
else if (path.startsWith("file://")) path = path.mid(7);

QFile file(path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
return;
}
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return;

QTextStream out(&file);
out << "Algorithm,TotalTicks,Throughput,ContextSwitches,JainsFairness,AvgWaiting,AvgTurnaround\n";
Expand Down
Loading
Loading