circuit-logic-simulator/FileHandler.cpp
2020-03-24 20:18:39 +01:00

140 lines
3.9 KiB
C++

#include "FileHandler.h"
#include <QFileInfo>
#include <QTextStream>
#include <QFile>
#include <QDir>
#include "Scene.h"
#include "Part.h"
#include "Wire.h"
#include "Connector.h"
#include "Logic.h"
#include "MainWindow.h"
#include "Parts/IntegratedCircuit.h"
#include <QDebug>
FileHandler::FileHandler(Logic* logic)
:m_logic(logic)
{
}
bool FileHandler::exists(QString filename)
{
QFile file(filename);
return file.exists();
}
bool FileHandler::save(QString filename)
{
QFile file(filename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return false;
QTextStream fOut(&file);
fOut << "[parts]\n";
for(auto part : m_logic->m_parts)
{
fOut << part << " " << part->m_partType << " " << part->pos().x() << " " << part->pos().y();
if(part->m_partType == PartType::IntegratedCircuit)
{
// Strip out IC file path
QFileInfo fileInfo(((IntegratedCircuit*)part)->filename());
QString icFile(fileInfo.fileName());
fOut << " " << icFile;
}
fOut << "\n";
}
fOut << "[wires]\n";
for(auto wire : m_logic->m_wires)
{
auto wireInputPart = (Part*)wire->m_connectorInput->parentItem();
auto wireOutputPart = (Part*)wire->m_connectorOutput->parentItem();
fOut << wireInputPart << " " << wireInputPart->m_outputs.indexOf(wire->m_connectorInput) << " " << wireOutputPart << " " << wireOutputPart->m_inputs.indexOf(wire->m_connectorOutput) << "\n";
}
return true;
}
bool FileHandler::open(QString filename)
{
//TODO: Make it possible to load IC filenames with spaces
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
enum Sector
{
Parts,
Wires
};
Sector currentSector;
// A .csim file stores all parts with IDs, this map simply keeps track of which ID was given which pointer
QMap<QString, Part*> idPartPointerMap;
while (!file.atEnd()) {
QString line = file.readLine();
if(line.contains("[parts]"))
currentSector = Parts;
else if(line.contains("[wires]"))
currentSector = Wires;
else
{
QVector<QString> words;
QString currWord;
for(QChar c : line)
{
if(c == QChar::Space)
{
words.append(currWord);
currWord.clear();
}
else
currWord.append(c);
}
words.append(currWord);
// Remove the \n from last word
words.last().remove(words.last().length() - 1, 1);
if(words.length() < 4)
return false;
if(currentSector == Parts)
{
PartType::PartType type = (PartType::PartType)words[1].toInt();
QPointF pos = QPointF(words[2].toFloat(), words[3].toFloat());
Part* part;
if(type == PartType::IntegratedCircuit)
{
QDir icDir(filename);
icDir.cdUp();
QString icFilename = icDir.filePath(words[4]);
if(!QFile(icFilename).exists())
{
qFatal("Failed to open IC file: " + icFilename.toUtf8());
}
part = m_logic->createIC(icFilename, pos);
}
else
part = m_logic->createPart(type, pos);
idPartPointerMap.insert(words[0], part);
}
else
{
auto inputConnector = idPartPointerMap[words[0]]->m_outputs[words[1].toInt()];
auto outputConnector = idPartPointerMap[words[2]]->m_inputs[words[3].toInt()];
m_logic->createWire(inputConnector, outputConnector);
}
}
}
return true;
}