/* * Copyright 2016 - 2019 gtalent2@gmail.com * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include #include #include #include #include #include "ox/claw/claw.hpp" #include #include "nostalgiastudio_export.h" 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, }; [[nodiscard]] QString filePathToName(QString path, QString prefix, QString suffix); class NOSTALGIASTUDIO_EXPORT Project: public QObject { Q_OBJECT private: QString m_path = ""; mutable ox::PassThroughFS m_fs; public: Project(QString path); ~Project(); void create(); ox::PassThroughFS *romFs(); void mkdir(QString path) const; /** * Writes a MetalClaw object to the project at the given path. */ template void writeObj(QString path, T *obj) const; template std::unique_ptr loadObj(QString path) const; ox::FileStat stat(QString path) const; bool exists(QString path) const; void subscribe(ProjectEvent e, QObject *tgt, const char *slot) const; template void subscribe(ProjectEvent e, QObject *tgt, Functor &&slot) const; private: void writeBuff(QString path, uint8_t *buff, size_t buffLen) const; std::vector loadBuff(QString path) const; void procDir(QStringList &paths, QString path) const; QStringList listFiles(QString path = "") const; signals: 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; }; template void Project::writeObj(QString path, T *obj) const { // write MetalClaw auto [buff, err] = ox::writeClaw(obj, ox::ClawFormat::Metal); oxThrowError(err); // write to FS writeBuff(path, ox::bit_cast(buff.data()), buff.size()); emit fileUpdated(path); } template std::unique_ptr Project::loadObj(QString path) const { auto obj = std::make_unique(); auto buff = loadBuff(path); oxThrowError(ox::readClaw(buff.data(), buff.size(), obj.get())); return obj; } template 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; } } }