[nostalgia/studio] Start on ImGui version of Studio

This commit is contained in:
2021-07-26 01:39:56 -05:00
parent 6160335af3
commit ddd63bc45f
46 changed files with 1005 additions and 2269 deletions
+54 -51
View File
@@ -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);
}
}