[olympic/studio] Fix several crashes

This commit is contained in:
Gary Talent 2023-12-14 21:34:46 -06:00
parent 2167a46266
commit db961739ad
3 changed files with 51 additions and 36 deletions

View File

@ -53,7 +53,7 @@ static ox::Error runApp(
turbine::setConstantRefresh(*ctx, false);
studio::StudioContext studioCtx;
turbine::setApplicationData(*ctx, &studioCtx);
StudioUI ui(ctx.get(), projectDataDir);
StudioUI ui(*ctx, projectDataDir);
studioCtx.ui = &ui;
StudioUIDrawer drawer(ui);
turbine::gl::addDrawer(*ctx, &drawer);

View File

@ -15,7 +15,12 @@
namespace studio {
ox::Vector<const studio::Module*> modules;
static ox::Vector<const studio::Module*> modules;
void registerModule(studio::Module const*mod) noexcept {
modules.emplace_back(mod);
}
struct StudioConfig {
static constexpr auto TypeName = "net.drinkingtea.studio.StudioConfig";
@ -33,23 +38,25 @@ oxModelBegin(StudioConfig)
oxModelFieldRename(show_project_explorer, showProjectExplorer)
oxModelEnd()
StudioUI::StudioUI(turbine::Context *ctx, ox::StringView projectDir) noexcept:
m_ctx(*ctx),
m_projectDir(projectDir),
m_projectExplorer(ox::make_unique<ProjectExplorer>(m_ctx)),
m_aboutPopup(*ctx) {
StudioUI::StudioUI(turbine::Context &ctx, ox::StringView projectDataDir) noexcept:
m_ctx(ctx),
m_projectDataDir(projectDataDir),
m_projectExplorer(ox::make_unique<ProjectExplorer>(m_ctx)),
m_aboutPopup(m_ctx) {
m_projectExplorer->fileChosen.connect(this, &StudioUI::openFile);
ImGui::GetIO().IniFilename = nullptr;
loadModules();
// open project and files
const auto [config, err] = studio::readConfig<StudioConfig>(keelCtx(*ctx));
auto const [config, err] = studio::readConfig<StudioConfig>(keelCtx(m_ctx));
m_showProjectExplorer = config.showProjectExplorer;
if (!err) {
oxIgnoreError(openProject(config.projectPath));
for (const auto &f : config.openFiles) {
auto openFileErr = openFileActiveTab(f, config.activeTabItemName == f);
if (openFileErr) {
oxErrorf("\nCould not open editor for file:\n\t{}\nReason:\n\t{}\n", f, toStr(openFileErr));
auto const openProjErr = openProject(config.projectPath);
if (!openProjErr) {
for (const auto &f: config.openFiles) {
auto openFileErr = openFileActiveTab(f, config.activeTabItemName == f);
if (openFileErr) {
oxErrorf("\nCould not open editor for file:\n\t{}\nReason:\n\t{}\n", f, toStr(openFileErr));
}
}
}
} else {
@ -83,7 +90,9 @@ void StudioUI::handleKeyEvent(turbine::Key key, bool down) noexcept {
toggleProjectExplorer();
break;
case turbine::Key::Alpha_C:
m_activeEditor->copy();
if (m_activeEditor && m_activeEditor->copyEnabled()) {
m_activeEditor->copy();
}
break;
case turbine::Key::Alpha_N:
m_newMenu.open();
@ -98,10 +107,14 @@ void StudioUI::handleKeyEvent(turbine::Key key, bool down) noexcept {
save();
break;
case turbine::Key::Alpha_V:
m_activeEditor->paste();
if (m_activeEditor && m_activeEditor->pasteEnabled()) {
m_activeEditor->paste();
}
break;
case turbine::Key::Alpha_X:
m_activeEditor->cut();
if (m_activeEditor && m_activeEditor->cutEnabled()) {
m_activeEditor->cut();
}
break;
case turbine::Key::Alpha_Y:
redo();
@ -169,19 +182,19 @@ void StudioUI::drawMenu() noexcept {
if (ImGui::BeginMenu("Edit")) {
auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr;
if (ImGui::MenuItem("Undo", "Ctrl+Z", false, undoStack && undoStack->canUndo())) {
m_activeEditor->undoStack()->undo();
undoStack->undo();
}
if (ImGui::MenuItem("Redo", "Ctrl+Y", false, undoStack && undoStack->canRedo())) {
m_activeEditor->undoStack()->redo();
undoStack->redo();
}
ImGui::Separator();
if (ImGui::MenuItem("Copy", "Ctrl+C")) {
if (ImGui::MenuItem("Copy", "Ctrl+C", false, m_activeEditor && m_activeEditor->copyEnabled())) {
m_activeEditor->copy();
}
if (ImGui::MenuItem("Cut", "Ctrl+X")) {
if (ImGui::MenuItem("Cut", "Ctrl+X", false, m_activeEditor && m_activeEditor->cutEnabled())) {
m_activeEditor->cut();
}
if (ImGui::MenuItem("Paste", "Ctrl+V")) {
if (ImGui::MenuItem("Paste", "Ctrl+V", false, m_activeEditor && m_activeEditor->pasteEnabled()) && m_activeEditor) {
m_activeEditor->paste();
}
ImGui::EndMenu();
@ -240,6 +253,9 @@ void StudioUI::drawTabs() noexcept {
}
if (!open) {
e->close();
if (m_activeEditor == (*it).get()) {
m_activeEditor = nullptr;
}
try {
oxThrowError(m_editors.erase(it).moveTo(&it));
} catch (const ox::Exception &ex) {
@ -305,7 +321,7 @@ ox::Error StudioUI::openProject(ox::CRStringView path) noexcept {
oxRequireM(fs, keel::loadRomFs(path));
oxReturnError(keel::setRomFs(keelCtx(m_ctx), std::move(fs)));
turbine::setWindowTitle(m_ctx, ox::sfmt("{} - {}", keelCtx(m_ctx).appName, path));
m_project = ox::make_unique<studio::Project>(keelCtx(m_ctx), ox::String(path), m_projectDir);
m_project = ox::make_unique<studio::Project>(keelCtx(m_ctx), ox::String(path), m_projectDataDir);
auto sctx = applicationData<studio::StudioContext>(m_ctx);
sctx->project = m_project.get();
m_project->fileAdded.connect(m_projectExplorer.get(), &ProjectExplorer::refreshProjectTreeModel);
@ -324,6 +340,9 @@ ox::Error StudioUI::openFile(ox::CRStringView path) noexcept {
}
ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab) noexcept {
if (!m_project) {
return OxError(1, "No project open to open a file from");
}
if (m_openFiles.contains(path)) {
for (auto &e : m_editors) {
if (makeActiveTab && e->itemPath() == path) {
@ -332,7 +351,7 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab)
break;
}
}
return OxError(0);
return {};
}
oxRequire(ext, studio::fileExt(path).to<ox::String>([](auto const&v) {return ox::String(v);}));
// create Editor
@ -372,18 +391,14 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab)
ox::Error StudioUI::closeFile(ox::CRStringView path) noexcept {
if (!m_openFiles.contains(path)) {
return OxError(0);
return {};
}
oxIgnoreError(m_openFiles.erase(std::remove(m_openFiles.begin(), m_openFiles.end(), path)));
// save to config
studio::editConfig<StudioConfig>(keelCtx(m_ctx), [&](StudioConfig *config) {
oxIgnoreError(config->openFiles.erase(std::remove(config->openFiles.begin(), config->openFiles.end(), path)));
});
return OxError(0);
}
void registerModule(const studio::Module *mod) noexcept {
modules.emplace_back(mod);
return {};
}
}

View File

@ -24,27 +24,27 @@ class StudioUI: public ox::SignalHandler {
private:
turbine::Context &m_ctx;
ox::String m_projectDir;
ox::UniquePtr<studio::Project> m_project;
ox::String m_projectDataDir;
ox::UPtr<studio::Project> m_project;
studio::TaskRunner m_taskRunner;
ox::Vector<ox::UniquePtr<studio::BaseEditor>> m_editors;
ox::Vector<ox::UniquePtr<studio::Widget>> m_widgets;
ox::Vector<ox::UPtr<studio::BaseEditor>> m_editors;
ox::Vector<ox::UPtr<studio::Widget>> m_widgets;
ox::HashMap<ox::String, studio::EditorMaker::Func> m_editorMakers;
ox::UniquePtr<ProjectExplorer> m_projectExplorer;
ox::UPtr<ProjectExplorer> m_projectExplorer;
ox::Vector<ox::String> m_openFiles;
studio::BaseEditor *m_activeEditorOnLastDraw = nullptr;
studio::BaseEditor *m_activeEditor = nullptr;
studio::BaseEditor *m_activeEditorUpdatePending = nullptr;
NewMenu m_newMenu;
AboutPopup m_aboutPopup;
const ox::Array<studio::Popup*, 2> m_popups = {
ox::Array<studio::Popup*, 2> const m_popups = {
&m_newMenu,
&m_aboutPopup
};
bool m_showProjectExplorer = true;
public:
explicit StudioUI(turbine::Context *ctx, ox::StringView projectDir) noexcept;
explicit StudioUI(turbine::Context &ctx, ox::StringView projectDataDir) noexcept;
void update() noexcept;