This commit is contained in:
@@ -47,3 +47,5 @@ install(
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
|
||||
add_subdirectory(subcommands)
|
||||
@@ -14,24 +14,68 @@
|
||||
#include <studio/context.hpp>
|
||||
#include <studioapp/studioapp.hpp>
|
||||
|
||||
#include "subcommands/change-format/change-format.hpp"
|
||||
|
||||
#include "configfile.hpp"
|
||||
#include "studioui.hpp"
|
||||
|
||||
namespace studio {
|
||||
|
||||
static ox::Error convertStudioConfigV1ToStudioConfigV2(
|
||||
keel::Context&,
|
||||
StudioConfigV1 &src,
|
||||
StudioConfigV2 &dst) noexcept {
|
||||
dst.projects.emplace_back(StudioConfigV2::ProjectConfig{
|
||||
.projectPath = std::move(src.projectPath),
|
||||
.activeTabItemName = std::move(src.activeTabItemName),
|
||||
.openFiles = std::move(src.openFiles),
|
||||
});
|
||||
dst.showProjectExplorer = src.showProjectExplorer;
|
||||
return {};
|
||||
}
|
||||
|
||||
static struct: Module {
|
||||
ox::String id() const noexcept final {
|
||||
return ox::String{"net.drinkingtea.studio"};
|
||||
}
|
||||
|
||||
ox::Vector<Command> commands() const final {
|
||||
return {
|
||||
{
|
||||
"change-format",
|
||||
cmdChangeFormat,
|
||||
}
|
||||
};
|
||||
}
|
||||
} constexpr mod;
|
||||
|
||||
static struct: keel::Module {
|
||||
ox::String id() const noexcept override {
|
||||
return ox::String{"net.drinkingtea.studio"};
|
||||
}
|
||||
|
||||
ox::Vector<keel::Converter> converters() const noexcept override {
|
||||
return {
|
||||
keel::Converter::make<convertStudioConfigV1ToStudioConfigV2>(),
|
||||
};
|
||||
}
|
||||
} constexpr kmod;
|
||||
|
||||
|
||||
class StudioUIDrawer: public turbine::gl::Drawer {
|
||||
private:
|
||||
StudioUI &m_ui;
|
||||
public:
|
||||
explicit StudioUIDrawer(StudioUI &ui) noexcept: m_ui(ui) {
|
||||
}
|
||||
protected:
|
||||
|
||||
void draw(turbine::Context&) noexcept final {
|
||||
m_ui.draw();
|
||||
}
|
||||
};
|
||||
|
||||
static void keyEventHandler(turbine::Context &ctx, turbine::Key key, bool down) noexcept {
|
||||
auto const sctx = turbine::applicationData<studio::Context>(ctx);
|
||||
static void keyEventHandler(turbine::Context &ctx, turbine::Key const key, bool const down) noexcept {
|
||||
auto const sctx = turbine::applicationData<Context>(ctx);
|
||||
sctx->ui.handleKeyEvent(key, down);
|
||||
}
|
||||
|
||||
@@ -65,6 +109,8 @@ static ox::Error run(
|
||||
ox::StringViewCR appName,
|
||||
ox::StringViewCR projectDataDir,
|
||||
ox::SpanView<ox::CString> const &args) {
|
||||
keel::registerModule(kmod);
|
||||
registerModule(&mod);
|
||||
// seed UUID generator
|
||||
auto const time = std::time(nullptr);
|
||||
ox::UUID::seedGenerator({
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/std/vector.hpp>
|
||||
|
||||
#include <ox/model/def.hpp>
|
||||
|
||||
namespace studio {
|
||||
|
||||
struct StudioConfigV1 {
|
||||
static constexpr auto TypeName = "net.drinkingtea.studio.StudioConfig";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
ox::String projectPath;
|
||||
ox::String activeTabItemName;
|
||||
ox::Vector<ox::String> openFiles;
|
||||
bool showProjectExplorer = true;
|
||||
};
|
||||
|
||||
OX_MODEL_BEGIN(StudioConfigV1)
|
||||
OX_MODEL_FIELD_RENAME(activeTabItemName, active_tab_item_name)
|
||||
OX_MODEL_FIELD_RENAME(projectPath, project_path)
|
||||
OX_MODEL_FIELD_RENAME(openFiles, open_files)
|
||||
OX_MODEL_FIELD_RENAME(showProjectExplorer, show_project_explorer)
|
||||
OX_MODEL_END()
|
||||
|
||||
|
||||
struct StudioConfigV2 {
|
||||
static constexpr auto TypeName = "net.drinkingtea.studio.StudioConfig";
|
||||
static constexpr auto TypeVersion = 2;
|
||||
struct ProjectConfig {
|
||||
static constexpr auto TypeName = "net.drinkingtea.studio.ProjectConfig";
|
||||
static constexpr auto TypeVersion = 2;
|
||||
ox::String projectPath;
|
||||
ox::String activeTabItemName;
|
||||
ox::Vector<ox::String> openFiles;
|
||||
};
|
||||
ox::Vector<ProjectConfig> projects;
|
||||
bool showProjectExplorer = true;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr ProjectConfig const *project() const {
|
||||
return projects.empty() ? nullptr : &projects[0];
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr ProjectConfig *project() {
|
||||
return projects.empty() ? nullptr : &projects[0];
|
||||
}
|
||||
};
|
||||
|
||||
OX_MODEL_BEGIN(StudioConfigV2::ProjectConfig)
|
||||
OX_MODEL_FIELD_RENAME(activeTabItemName, active_tab_item_name)
|
||||
OX_MODEL_FIELD_RENAME(projectPath, project_path)
|
||||
OX_MODEL_FIELD_RENAME(openFiles, open_files)
|
||||
OX_MODEL_END()
|
||||
|
||||
OX_MODEL_BEGIN(StudioConfigV2)
|
||||
OX_MODEL_FIELD(projects)
|
||||
OX_MODEL_FIELD_RENAME(showProjectExplorer, show_project_explorer)
|
||||
OX_MODEL_END()
|
||||
|
||||
using StudioConfig = StudioConfigV2;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
target_sources(
|
||||
StudioAppLib PRIVATE
|
||||
change-format/change-format.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
StudioAppLib PUBLIC
|
||||
OxClArgs
|
||||
)
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2016 - 2026 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/clargs/clargs.hpp>
|
||||
#include <ox/std/trace.hpp>
|
||||
|
||||
#include <studio/project.hpp>
|
||||
|
||||
#include "change-format.hpp"
|
||||
|
||||
namespace studio {
|
||||
|
||||
static ox::Error convertFile(
|
||||
ox::FileSystem &fs,
|
||||
ox::TypeStore &ts,
|
||||
ox::StringViewCR path,
|
||||
ox::ClawFormat const fmt) noexcept {
|
||||
ox::Buffer buff;
|
||||
ox::ModelObject obj;
|
||||
OX_RETURN_ERROR(fs.read(path).moveTo(buff).reoriginate(1, "unable to read file"));
|
||||
OX_RETURN_ERROR(keel::readAsset(ts, buff).moveTo(obj).reoriginate(1, "unable to parse file"));
|
||||
OX_RETURN_ERROR(ox::writeClaw(obj, fmt).moveTo(buff));
|
||||
OX_RETURN_ERROR(fs.write(path, buff).reoriginate(1, "unable to write file"));
|
||||
return {};
|
||||
}
|
||||
|
||||
static void printUsage() noexcept {
|
||||
oxErr(R"(usage: convert-file {mc,oc} [files...]\n)");
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr ox::Result<ox::ClawFormat> getFmt(ox::StringViewCR fmtStr) noexcept {
|
||||
if (fmtStr == "mc") {
|
||||
return ox::ClawFormat::Metal;
|
||||
} else if (fmtStr == "oc") {
|
||||
return ox::ClawFormat::Metal;
|
||||
}
|
||||
return ox::Error(1, "invalid format");
|
||||
}
|
||||
|
||||
ox::Error cmdChangeFormat(Project &project, ox::SpanView<ox::CString> const args) noexcept {
|
||||
if (args.size() < 2) {
|
||||
printUsage();
|
||||
return ox::Error{1, "invalid input"};
|
||||
}
|
||||
auto const [fmt, fmtErr] = getFmt(args[0]);
|
||||
if (fmtErr) {
|
||||
printUsage();
|
||||
}
|
||||
auto &fs = project.romFs();
|
||||
auto &ts = project.typeStore();
|
||||
for (auto const &file : args + 1) {
|
||||
auto const err = convertFile(fs, ts, file, fmt);
|
||||
if (err) {
|
||||
oxErrf("Failed to convert {}: {}\n", file, err.msg);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2016 - 2026 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace studio {
|
||||
|
||||
ox::Error cmdChangeFormat(Project &project, ox::SpanView<ox::CString> args) noexcept;
|
||||
|
||||
}
|
||||
@@ -122,6 +122,16 @@ class Project: public ox::SignalHandler {
|
||||
|
||||
ox::Error writeTypeStore() noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr ox::TypeStore &typeStore() noexcept {
|
||||
return m_typeStore;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr ox::TypeStore const &typeStore() const noexcept {
|
||||
return m_typeStore;
|
||||
}
|
||||
|
||||
private:
|
||||
void buildFileIndex() noexcept;
|
||||
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
namespace studio {
|
||||
|
||||
static_assert(fileExt("main.c").value == "c");
|
||||
static_assert(fileExt("main.cc").value == "cc");
|
||||
static_assert(fileExt("main.cpp").value == "cpp");
|
||||
static_assert(fileExt("a.b.c").value == "c");
|
||||
static_assert(parentDir("/a/b/c") == "/a/b");
|
||||
static_assert(parentDir("/a/b/c/") == "/a/b");
|
||||
|
||||
static void generateTypes(ox::TypeStore &ts) noexcept {
|
||||
for (auto const mod : keel::modules()) {
|
||||
for (auto gen : mod->types()) {
|
||||
for (auto const gen : mod->types()) {
|
||||
oxLogError(gen(ts));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user