[nostalgia/studio] Add ability to subscribe to updates to files
This commit is contained in:
parent
4273e72e74
commit
e1d3fe0d6b
@ -13,11 +13,12 @@
|
|||||||
|
|
||||||
namespace nostalgia::studio {
|
namespace nostalgia::studio {
|
||||||
|
|
||||||
struct Context {
|
class Context {
|
||||||
QString appName;
|
public:
|
||||||
QString orgName;
|
QString appName;
|
||||||
QWidget* tabParent = nullptr;
|
QString orgName;
|
||||||
const class Project* project = nullptr;
|
QWidget* tabParent = nullptr;
|
||||||
|
const class Project* project = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,12 @@
|
|||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
|
||||||
#include "project.hpp"
|
#include "project.hpp"
|
||||||
|
|
||||||
namespace nostalgia::studio {
|
namespace nostalgia::studio {
|
||||||
|
|
||||||
using namespace ox;
|
|
||||||
|
|
||||||
Project::Project(QString path): m_fs(path.toUtf8()) {
|
Project::Project(QString path): m_fs(path.toUtf8()) {
|
||||||
qDebug() << "Project:" << path;
|
qDebug() << "Project:" << path;
|
||||||
m_path = path;
|
m_path = path;
|
||||||
@ -27,13 +26,13 @@ void Project::create() {
|
|||||||
QDir().mkpath(m_path);
|
QDir().mkpath(m_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
PassThroughFS *Project::romFs() {
|
ox::PassThroughFS *Project::romFs() {
|
||||||
return &m_fs;
|
return &m_fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::mkdir(QString path) const {
|
void Project::mkdir(QString path) const {
|
||||||
oxThrowError(m_fs.mkdir(path.toUtf8().data(), true));
|
oxThrowError(m_fs.mkdir(path.toUtf8().data(), true));
|
||||||
emit updated(path);
|
emit fileUpdated(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::FileStat Project::stat(QString path) const {
|
ox::FileStat Project::stat(QString path) const {
|
||||||
@ -48,7 +47,7 @@ bool Project::exists(QString path) const {
|
|||||||
|
|
||||||
void Project::writeBuff(QString path, uint8_t *buff, size_t buffLen) const {
|
void Project::writeBuff(QString path, uint8_t *buff, size_t buffLen) const {
|
||||||
oxThrowError(m_fs.write(path.toUtf8().data(), buff, buffLen));
|
oxThrowError(m_fs.write(path.toUtf8().data(), buff, buffLen));
|
||||||
emit updated(path);
|
emit fileUpdated(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> Project::loadBuff(QString path) const {
|
std::vector<uint8_t> Project::loadBuff(QString path) const {
|
||||||
@ -58,4 +57,27 @@ std::vector<uint8_t> Project::loadBuff(QString path) const {
|
|||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Project::procDir(QStringList &paths, QString path) const {
|
||||||
|
oxThrowError(m_fs.ls(path.toUtf8(), [&](QString name, ox::InodeId_t) {
|
||||||
|
auto fullPath = path + "/" + name;
|
||||||
|
auto [stat, err] = m_fs.stat(fullPath.toUtf8().data());
|
||||||
|
oxReturnError(err);
|
||||||
|
switch (stat.fileType) {
|
||||||
|
case ox::FileType_NormalFile:
|
||||||
|
paths.push_back(fullPath);
|
||||||
|
break;
|
||||||
|
case ox::FileType_Directory:
|
||||||
|
procDir(paths, fullPath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return OxError(0);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList Project::listFiles(QString path) const {
|
||||||
|
QStringList paths;
|
||||||
|
procDir(paths, path);
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,22 @@
|
|||||||
|
|
||||||
#include <ox/fs/fs.hpp>
|
#include <ox/fs/fs.hpp>
|
||||||
#include <ox/mc/mc.hpp>
|
#include <ox/mc/mc.hpp>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
|
||||||
#include "nostalgiastudio_export.h"
|
#include "nostalgiastudio_export.h"
|
||||||
|
#include "ox/fs/filesystem/passthroughfs.hpp"
|
||||||
|
|
||||||
namespace nostalgia::studio {
|
namespace nostalgia::studio {
|
||||||
|
|
||||||
|
enum class ProjectEvent {
|
||||||
|
FileAdded,
|
||||||
|
// FileRecognized is triggered for all matching files upon a new
|
||||||
|
// subscription to a section of the project and upon the addition of a file.
|
||||||
|
FileRecognized,
|
||||||
|
FileDeleted,
|
||||||
|
FileUpdated,
|
||||||
|
};
|
||||||
|
|
||||||
class NOSTALGIASTUDIO_EXPORT Project: public QObject {
|
class NOSTALGIASTUDIO_EXPORT Project: public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -50,13 +61,29 @@ class NOSTALGIASTUDIO_EXPORT Project: public QObject {
|
|||||||
|
|
||||||
bool exists(QString path) const;
|
bool exists(QString path) const;
|
||||||
|
|
||||||
|
void subscribe(ProjectEvent e, QObject *tgt, const char *slot) const;
|
||||||
|
|
||||||
|
template<typename Functor>
|
||||||
|
void subscribe(ProjectEvent e, QObject *tgt, Functor &&slot) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void writeBuff(QString path, uint8_t *buff, size_t buffLen) const;
|
void writeBuff(QString path, uint8_t *buff, size_t buffLen) const;
|
||||||
|
|
||||||
std::vector<uint8_t> loadBuff(QString path) const;
|
std::vector<uint8_t> loadBuff(QString path) const;
|
||||||
|
|
||||||
|
void procDir(QStringList &paths, QString path) const;
|
||||||
|
|
||||||
|
QStringList listFiles(QString path = "") const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void updated(QString path) const;
|
void fileEvent(ProjectEvent, QString path) const;
|
||||||
|
void fileAdded(QString) const;
|
||||||
|
// FileRecognized is triggered for all matching files upon a new
|
||||||
|
// subscription to a section of the project and upon the addition of a
|
||||||
|
// file.
|
||||||
|
void fileRecognized(QString) const;
|
||||||
|
void fileDeleted(QString) const;
|
||||||
|
void fileUpdated(QString) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,7 +95,7 @@ void Project::writeObj(QString path, T *obj) const {
|
|||||||
oxThrowError(ox::writeMC(buff.data(), buff.size(), obj, &mcSize));
|
oxThrowError(ox::writeMC(buff.data(), buff.size(), obj, &mcSize));
|
||||||
// write to FS
|
// write to FS
|
||||||
writeBuff(path, buff.data(), mcSize);
|
writeBuff(path, buff.data(), mcSize);
|
||||||
emit updated(path);
|
emit fileUpdated(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -79,4 +106,27 @@ std::unique_ptr<T> Project::loadObj(QString path) const {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Functor>
|
||||||
|
void Project::subscribe(ProjectEvent e, QObject *tgt, Functor &&slot) const {
|
||||||
|
switch (e) {
|
||||||
|
case ProjectEvent::FileAdded:
|
||||||
|
connect(this, &Project::fileAdded, tgt, (slot));
|
||||||
|
break;
|
||||||
|
case ProjectEvent::FileRecognized:
|
||||||
|
{
|
||||||
|
for (auto f : listFiles()) {
|
||||||
|
slot(f);
|
||||||
|
}
|
||||||
|
connect(this, &Project::fileRecognized, tgt, (slot));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ProjectEvent::FileDeleted:
|
||||||
|
connect(this, &Project::fileDeleted, tgt, (slot));
|
||||||
|
break;
|
||||||
|
case ProjectEvent::FileUpdated:
|
||||||
|
connect(this, &Project::fileUpdated, tgt, (slot));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ void MainWindow::openProject(QString projectPath) {
|
|||||||
m_ctx.project = project;
|
m_ctx.project = project;
|
||||||
m_oxfsView = new OxFSModel(project->romFs());
|
m_oxfsView = new OxFSModel(project->romFs());
|
||||||
m_projectExplorer->setModel(m_oxfsView);
|
m_projectExplorer->setModel(m_oxfsView);
|
||||||
connect(m_ctx.project, &Project::updated, m_oxfsView, &OxFSModel::updateFile);
|
connect(m_ctx.project, &Project::fileUpdated, m_oxfsView, &OxFSModel::updateFile);
|
||||||
m_importAction->setEnabled(true);
|
m_importAction->setEnabled(true);
|
||||||
m_state.projectPath = projectPath;
|
m_state.projectPath = projectPath;
|
||||||
// reopen tabs
|
// reopen tabs
|
||||||
@ -306,7 +306,11 @@ void MainWindow::openProject(QString projectPath) {
|
|||||||
try {
|
try {
|
||||||
openFile(t, true);
|
openFile(t, true);
|
||||||
} catch (ox::Error err) {
|
} catch (ox::Error err) {
|
||||||
oxTrace("nostalgia::studio::MainWindow::openProject") << "Error opening tab:" << err;
|
qInfo() << "Error opening tab:" << static_cast<int>(err);
|
||||||
|
oxTrace("nostalgia::studio::MainWindow::openProject") << "Error opening tab:" << static_cast<int>(err);
|
||||||
|
} catch (...) {
|
||||||
|
qInfo() << "Error opening tab";
|
||||||
|
oxTrace("nostalgia::studio::MainWindow::openProject") << "Error opening tab";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qInfo() << "Open project:" << projectPath;
|
qInfo() << "Open project:" << projectPath;
|
||||||
@ -322,7 +326,7 @@ void MainWindow::closeProject() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_ctx.project) {
|
if (m_ctx.project) {
|
||||||
disconnect(m_ctx.project, SIGNAL(updated(QString)), m_oxfsView, SLOT(updateFile(QString)));
|
disconnect(m_ctx.project, &Project::fileUpdated, m_oxfsView, &OxFSModel::updateFile);
|
||||||
|
|
||||||
delete m_ctx.project;
|
delete m_ctx.project;
|
||||||
m_ctx.project = nullptr;
|
m_ctx.project = nullptr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user