[nostalgia/studio] Start on ImGui version of Studio
This commit is contained in:
@@ -10,13 +10,13 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <qnamespace.h>
|
||||
|
||||
#include <ox/claw/claw.hpp>
|
||||
#include <ox/claw/read.hpp>
|
||||
#include <ox/claw/write.hpp>
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/mc/mc.hpp>
|
||||
#include <ox/model/descwrite.hpp>
|
||||
#include <ox/event/signal.hpp>
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
#include "nostalgiastudio_export.h"
|
||||
@@ -24,6 +24,7 @@
|
||||
namespace nostalgia::studio {
|
||||
|
||||
enum class ProjectEvent {
|
||||
None,
|
||||
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.
|
||||
@@ -33,112 +34,114 @@ enum class ProjectEvent {
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
QString filePathToName(const QString &path, const QString &prefix, const QString &suffix);
|
||||
|
||||
class NOSTALGIASTUDIO_EXPORT Project: public QObject {
|
||||
Q_OBJECT
|
||||
ox::String filePathToName(const ox::String &path, const ox::String &prefix, const ox::String &suffix) noexcept;
|
||||
|
||||
class NOSTALGIASTUDIO_EXPORT Project {
|
||||
private:
|
||||
QString m_path = "";
|
||||
mutable std::unique_ptr<ox::FileSystem> m_fs;
|
||||
ox::String m_path = "";
|
||||
mutable ox::UniquePtr<ox::FileSystem> m_fs;
|
||||
|
||||
public:
|
||||
explicit Project(const QString &path);
|
||||
explicit Project(const ox::String &path) noexcept;
|
||||
|
||||
~Project() override = default;
|
||||
ox::Error create() noexcept;
|
||||
|
||||
void create();
|
||||
[[nodiscard]]
|
||||
ox::FileSystem *romFs() noexcept;
|
||||
|
||||
ox::FileSystem *romFs();
|
||||
|
||||
void mkdir(const QString &path) const;
|
||||
ox::Error mkdir(const ox::String &path) const noexcept;
|
||||
|
||||
/**
|
||||
* Writes a MetalClaw object to the project at the given path.
|
||||
*/
|
||||
template<typename T>
|
||||
void writeObj(const QString &path, T *obj) const;
|
||||
ox::Error writeObj(const ox::String &path, T *obj) const noexcept;
|
||||
|
||||
template<typename T>
|
||||
std::unique_ptr<T> loadObj(const QString &path) const;
|
||||
ox::Result<ox::UniquePtr<T>> loadObj(const ox::String &path) const noexcept;
|
||||
|
||||
ox::FileStat stat(const QString &path) const;
|
||||
ox::Result<ox::FileStat> stat(const ox::String &path) const noexcept;
|
||||
|
||||
bool exists(const QString& path) const;
|
||||
[[nodiscard]]
|
||||
bool exists(const ox::String& path) const noexcept;
|
||||
|
||||
template<typename Functor>
|
||||
void subscribe(ProjectEvent e, QObject *tgt, Functor &&slot) const;
|
||||
ox::Error subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&slot) const noexcept;
|
||||
|
||||
private:
|
||||
void writeBuff(const QString &path, uint8_t *buff, size_t buffLen) const;
|
||||
ox::Error writeBuff(const ox::String &path, const ox::Buffer &buff) const noexcept;
|
||||
|
||||
ox::Buffer loadBuff(const QString &path) const;
|
||||
ox::Result<ox::Buffer> loadBuff(const ox::String &path) const noexcept;
|
||||
|
||||
void lsProcDir(QStringList *paths, const QString &path) const;
|
||||
ox::Error lsProcDir(ox::Vector<ox::String> *paths, const ox::String &path) const noexcept;
|
||||
|
||||
QStringList listFiles(const QString &path = "") const;
|
||||
ox::Result<ox::Vector<ox::String>> listFiles(const ox::String &path = "") const noexcept;
|
||||
|
||||
signals:
|
||||
void fileEvent(ProjectEvent, QString path) const;
|
||||
void fileAdded(QString) const;
|
||||
// signals
|
||||
public:
|
||||
ox::Signal<ox::Error(ProjectEvent, const ox::String&)> fileEvent;
|
||||
ox::Signal<ox::Error(const ox::String&)> 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.
|
||||
void fileRecognized(QString) const;
|
||||
void fileDeleted(QString) const;
|
||||
void fileUpdated(QString) const;
|
||||
ox::Signal<ox::Error(const ox::String&)> fileRecognized;
|
||||
ox::Signal<ox::Error(const ox::String&)> fileDeleted;
|
||||
ox::Signal<ox::Error(const ox::String&)> fileUpdated;
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void Project::writeObj(const QString &path, T *obj) const {
|
||||
ox::Error Project::writeObj(const ox::String &path, T *obj) const noexcept {
|
||||
// write MetalClaw
|
||||
oxRequireMT(buff, ox::writeClaw(obj, ox::ClawFormat::Metal));
|
||||
oxRequireM(buff, ox::writeClaw(obj, ox::ClawFormat::Metal));
|
||||
// write to FS
|
||||
writeBuff(path, ox::bit_cast<uint8_t*>(buff.data()), buff.size());
|
||||
|
||||
oxReturnError(writeBuff(path, buff));
|
||||
// write type descriptor
|
||||
oxRequireT(type, ox::buildTypeDef(obj));
|
||||
oxRequireMT(typeOut, ox::writeClaw(type.get(), ox::ClawFormat::Organic));
|
||||
oxRequire(type, ox::buildTypeDef(obj));
|
||||
oxRequireM(typeOut, ox::writeClaw(type.get(), ox::ClawFormat::Organic));
|
||||
// replace garbage last character with new line
|
||||
typeOut.back().value = '\n';
|
||||
// write to FS
|
||||
QString descPath = "/.nostalgia/type_descriptors/";
|
||||
ox::String descPath = "/.nostalgia/type_descriptors/";
|
||||
const auto typePath = descPath + type->typeName.c_str();
|
||||
mkdir(descPath);
|
||||
writeBuff(typePath, ox::bit_cast<uint8_t*>(typeOut.data()), typeOut.size());
|
||||
emit fileUpdated(path);
|
||||
oxReturnError(mkdir(descPath));
|
||||
oxReturnError(writeBuff(typePath, typeOut));
|
||||
fileUpdated.emit(path);
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::unique_ptr<T> Project::loadObj(const QString &path) const {
|
||||
auto obj = std::make_unique<T>();
|
||||
auto buff = loadBuff(path);
|
||||
oxThrowError(ox::readClaw<T>(buff.data(), buff.size(), obj.get()));
|
||||
return obj;
|
||||
ox::Result<ox::UniquePtr<T>> Project::loadObj(const ox::String &path) const noexcept {
|
||||
auto obj = ox::make_unique<T>();
|
||||
oxRequire(buff, loadBuff(path));
|
||||
return ox::readClaw<T>(buff);
|
||||
}
|
||||
|
||||
template<typename Functor>
|
||||
void Project::subscribe(ProjectEvent e, QObject *tgt, Functor &&slot) const {
|
||||
ox::Error Project::subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&slot) const noexcept {
|
||||
switch (e) {
|
||||
case ProjectEvent::None:
|
||||
break;
|
||||
case ProjectEvent::FileAdded:
|
||||
connect(this, &Project::fileAdded, tgt, (slot));
|
||||
connect(this, &Project::fileAdded, tgt, slot);
|
||||
break;
|
||||
case ProjectEvent::FileRecognized:
|
||||
{
|
||||
for (auto f : listFiles()) {
|
||||
oxRequire(fileList, listFiles());
|
||||
for (auto f : fileList) {
|
||||
slot(f);
|
||||
}
|
||||
connect(this, &Project::fileRecognized, tgt, (slot));
|
||||
connect(this, &Project::fileRecognized, tgt, slot);
|
||||
break;
|
||||
}
|
||||
case ProjectEvent::FileDeleted:
|
||||
connect(this, &Project::fileDeleted, tgt, (slot));
|
||||
connect(this, &Project::fileDeleted, tgt, slot);
|
||||
break;
|
||||
case ProjectEvent::FileUpdated:
|
||||
connect(this, &Project::fileUpdated, tgt, (slot));
|
||||
connect(this, &Project::fileUpdated, tgt, slot);
|
||||
break;
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user