implements PLN-0017
This commit is contained in:
parent
c678fe6f49
commit
c6b711f3fa
@ -10,4 +10,4 @@
|
|||||||
{"type":"discussion","id":"DSC-0009","status":"open","ticket":"studio-debugger-workspace-integration","title":"Integrate ../debugger into Studio as a dedicated workspace","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","debugger","workspace","integration","shell"],"agendas":[{"id":"AGD-0009","file":"AGD-0009-studio-debugger-workspace-integration.md","status":"open","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[],"plans":[],"lessons":[]}
|
{"type":"discussion","id":"DSC-0009","status":"open","ticket":"studio-debugger-workspace-integration","title":"Integrate ../debugger into Studio as a dedicated workspace","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","debugger","workspace","integration","shell"],"agendas":[{"id":"AGD-0009","file":"AGD-0009-studio-debugger-workspace-integration.md","status":"open","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[],"plans":[],"lessons":[]}
|
||||||
{"type":"discussion","id":"DSC-0010","status":"done","ticket":"studio-code-editor-workspace-foundations","title":"Establish Code Editor workspace foundations in Studio without LSP","created_at":"2026-03-30","updated_at":"2026-03-31","tags":["studio","editor","workspace","multi-frontend","lsp-deferred"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0026","file":"discussion/lessons/DSC-0010-studio-code-editor-workspace-foundations/LSN-0026-read-only-editor-foundations-and-semantic-deferral.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31"}]}
|
{"type":"discussion","id":"DSC-0010","status":"done","ticket":"studio-code-editor-workspace-foundations","title":"Establish Code Editor workspace foundations in Studio without LSP","created_at":"2026-03-30","updated_at":"2026-03-31","tags":["studio","editor","workspace","multi-frontend","lsp-deferred"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0026","file":"discussion/lessons/DSC-0010-studio-code-editor-workspace-foundations/LSN-0026-read-only-editor-foundations-and-semantic-deferral.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31"}]}
|
||||||
{"type":"discussion","id":"DSC-0011","status":"done","ticket":"compiler-analyze-compile-build-pipeline-split","title":"Split compiler pipeline into analyze, compile, and build entrypoints","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["compiler","pipeline","artifacts","build","analysis"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0025","file":"discussion/lessons/DSC-0011-compiler-analyze-compile-build-pipeline-split/LSN-0025-compiler-pipeline-entrypoints-and-result-boundaries.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]}
|
{"type":"discussion","id":"DSC-0011","status":"done","ticket":"compiler-analyze-compile-build-pipeline-split","title":"Split compiler pipeline into analyze, compile, and build entrypoints","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["compiler","pipeline","artifacts","build","analysis"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0025","file":"discussion/lessons/DSC-0011-compiler-analyze-compile-build-pipeline-split/LSN-0025-compiler-pipeline-entrypoints-and-result-boundaries.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]}
|
||||||
{"type":"discussion","id":"DSC-0012","status":"open","ticket":"studio-editor-document-vfs-boundary","title":"Definir um boundary de VFS documental para tree/view/open files no Code Editor do Studio","created_at":"2026-03-31","updated_at":"2026-03-31","tags":["studio","editor","workspace","vfs","filesystem","boundary"],"agendas":[{"id":"AGD-0012","file":"AGD-0012-studio-editor-document-vfs-boundary.md","status":"in_progress","created_at":"2026-03-31","updated_at":"2026-03-31"}],"decisions":[{"id":"DEC-0009","file":"DEC-0009-studio-prometeu-vfs-project-document-boundary.md","status":"in_progress","created_at":"2026-03-31","updated_at":"2026-03-31","ref_agenda":"AGD-0012"}],"plans":[{"id":"PLN-0015","file":"PLN-0015-propagate-dec-0009-into-studio-specs.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0016","file":"PLN-0016-build-prometeu-vfs-filesystem-backed-core.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0017","file":"PLN-0017-add-studio-project-session-ownership-for-prometeu-vfs.md","status":"review","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0018","file":"PLN-0018-migrate-code-editor-to-prometeu-vfs.md","status":"review","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]}],"lessons":[]}
|
{"type":"discussion","id":"DSC-0012","status":"open","ticket":"studio-editor-document-vfs-boundary","title":"Definir um boundary de VFS documental para tree/view/open files no Code Editor do Studio","created_at":"2026-03-31","updated_at":"2026-03-31","tags":["studio","editor","workspace","vfs","filesystem","boundary"],"agendas":[{"id":"AGD-0012","file":"AGD-0012-studio-editor-document-vfs-boundary.md","status":"in_progress","created_at":"2026-03-31","updated_at":"2026-03-31"}],"decisions":[{"id":"DEC-0009","file":"DEC-0009-studio-prometeu-vfs-project-document-boundary.md","status":"in_progress","created_at":"2026-03-31","updated_at":"2026-03-31","ref_agenda":"AGD-0012"}],"plans":[{"id":"PLN-0015","file":"PLN-0015-propagate-dec-0009-into-studio-specs.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0016","file":"PLN-0016-build-prometeu-vfs-filesystem-backed-core.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0017","file":"PLN-0017-add-studio-project-session-ownership-for-prometeu-vfs.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0018","file":"PLN-0018-migrate-code-editor-to-prometeu-vfs.md","status":"review","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]}],"lessons":[]}
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
id: PLN-0017
|
id: PLN-0017
|
||||||
ticket: studio-editor-document-vfs-boundary
|
ticket: studio-editor-document-vfs-boundary
|
||||||
title: Add Studio project-session ownership for `prometeu-vfs`
|
title: Add Studio project-session ownership for `prometeu-vfs`
|
||||||
status: review
|
status: done
|
||||||
created: 2026-03-31
|
created: 2026-03-31
|
||||||
completed:
|
completed: 2026-03-31
|
||||||
tags:
|
tags:
|
||||||
- studio
|
- studio
|
||||||
- vfs
|
- vfs
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import p.studio.events.StudioEventBus;
|
|||||||
import p.studio.events.StudioPackerEventAdapter;
|
import p.studio.events.StudioPackerEventAdapter;
|
||||||
import p.studio.utilities.ThemeService;
|
import p.studio.utilities.ThemeService;
|
||||||
import p.studio.utilities.i18n.I18nService;
|
import p.studio.utilities.i18n.I18nService;
|
||||||
|
import p.studio.vfs.FilesystemProjectDocumentVfsFactory;
|
||||||
|
import p.studio.vfs.ProjectDocumentVfsFactory;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@ -17,6 +19,7 @@ public final class AppContainer implements Container {
|
|||||||
private final ThemeService themeService;
|
private final ThemeService themeService;
|
||||||
private final StudioEventBus studioEventBus;
|
private final StudioEventBus studioEventBus;
|
||||||
private final ObjectMapper mapper;
|
private final ObjectMapper mapper;
|
||||||
|
private final ProjectDocumentVfsFactory projectDocumentVfsFactory;
|
||||||
private final EmbeddedPacker embeddedPacker;
|
private final EmbeddedPacker embeddedPacker;
|
||||||
private final StudioBackgroundTasks backgroundTasks;
|
private final StudioBackgroundTasks backgroundTasks;
|
||||||
|
|
||||||
@ -25,6 +28,7 @@ public final class AppContainer implements Container {
|
|||||||
this.themeService = new ThemeService();
|
this.themeService = new ThemeService();
|
||||||
this.studioEventBus = new StudioEventBus();
|
this.studioEventBus = new StudioEventBus();
|
||||||
this.mapper = new ObjectMapper();
|
this.mapper = new ObjectMapper();
|
||||||
|
this.projectDocumentVfsFactory = new FilesystemProjectDocumentVfsFactory();
|
||||||
final ExecutorService backgroundExecutor = Executors.newFixedThreadPool(2, new StudioWorkerThreadFactory());
|
final ExecutorService backgroundExecutor = Executors.newFixedThreadPool(2, new StudioWorkerThreadFactory());
|
||||||
this.backgroundTasks = new StudioBackgroundTasks(backgroundExecutor);
|
this.backgroundTasks = new StudioBackgroundTasks(backgroundExecutor);
|
||||||
final Packer packer = Packer.bootstrap(this.mapper, new StudioPackerEventAdapter(studioEventBus));
|
final Packer packer = Packer.bootstrap(this.mapper, new StudioPackerEventAdapter(studioEventBus));
|
||||||
@ -51,6 +55,11 @@ public final class AppContainer implements Container {
|
|||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProjectDocumentVfsFactory getProjectDocumentVfsFactory() {
|
||||||
|
return projectDocumentVfsFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmbeddedPacker getPacker() {
|
public EmbeddedPacker getPacker() {
|
||||||
return embeddedPacker;
|
return embeddedPacker;
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import p.studio.events.StudioEventBus;
|
import p.studio.events.StudioEventBus;
|
||||||
import p.studio.utilities.ThemeService;
|
import p.studio.utilities.ThemeService;
|
||||||
import p.studio.utilities.i18n.I18nService;
|
import p.studio.utilities.i18n.I18nService;
|
||||||
|
import p.studio.vfs.ProjectDocumentVfsFactory;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@ -17,6 +18,8 @@ public interface Container {
|
|||||||
|
|
||||||
ObjectMapper getMapper();
|
ObjectMapper getMapper();
|
||||||
|
|
||||||
|
ProjectDocumentVfsFactory getProjectDocumentVfsFactory();
|
||||||
|
|
||||||
EmbeddedPacker getPacker();
|
EmbeddedPacker getPacker();
|
||||||
|
|
||||||
StudioBackgroundTasks getBackgroundTasks();
|
StudioBackgroundTasks getBackgroundTasks();
|
||||||
@ -60,6 +63,10 @@ public interface Container {
|
|||||||
return current().getMapper();
|
return current().getMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ProjectDocumentVfsFactory projectDocumentVfsFactory() {
|
||||||
|
return current().getProjectDocumentVfsFactory();
|
||||||
|
}
|
||||||
|
|
||||||
static EmbeddedPacker packer() {
|
static EmbeddedPacker packer() {
|
||||||
return current().getPacker();
|
return current().getPacker();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package p.studio.projects;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import p.packer.messages.PackerProjectContext;
|
import p.packer.messages.PackerProjectContext;
|
||||||
|
import p.studio.vfs.VfsProjectContext;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
@ -35,4 +36,8 @@ public record ProjectReference(
|
|||||||
public PackerProjectContext toPackerProjectContext() {
|
public PackerProjectContext toPackerProjectContext() {
|
||||||
return new PackerProjectContext(name, absoluteRootPath());
|
return new PackerProjectContext(name, absoluteRootPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VfsProjectContext toVfsProjectContext() {
|
||||||
|
return new VfsProjectContext(name, languageId, absoluteRootPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,36 @@
|
|||||||
|
package p.studio.projectsessions;
|
||||||
|
|
||||||
|
import p.studio.projects.ProjectReference;
|
||||||
|
import p.studio.vfs.ProjectDocumentVfs;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class StudioProjectSession implements AutoCloseable {
|
||||||
|
private final ProjectReference projectReference;
|
||||||
|
private final ProjectDocumentVfs projectDocumentVfs;
|
||||||
|
private boolean closed;
|
||||||
|
|
||||||
|
public StudioProjectSession(
|
||||||
|
final ProjectReference projectReference,
|
||||||
|
final ProjectDocumentVfs projectDocumentVfs) {
|
||||||
|
this.projectReference = Objects.requireNonNull(projectReference, "projectReference");
|
||||||
|
this.projectDocumentVfs = Objects.requireNonNull(projectDocumentVfs, "projectDocumentVfs");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectReference projectReference() {
|
||||||
|
return projectReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectDocumentVfs projectDocumentVfs() {
|
||||||
|
return projectDocumentVfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (closed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closed = true;
|
||||||
|
projectDocumentVfs.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package p.studio.projectsessions;
|
||||||
|
|
||||||
|
import p.studio.projects.ProjectReference;
|
||||||
|
import p.studio.vfs.ProjectDocumentVfsFactory;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class StudioProjectSessionFactory {
|
||||||
|
private final ProjectDocumentVfsFactory projectDocumentVfsFactory;
|
||||||
|
|
||||||
|
public StudioProjectSessionFactory(final ProjectDocumentVfsFactory projectDocumentVfsFactory) {
|
||||||
|
this.projectDocumentVfsFactory = Objects.requireNonNull(projectDocumentVfsFactory, "projectDocumentVfsFactory");
|
||||||
|
}
|
||||||
|
|
||||||
|
public StudioProjectSession open(final ProjectReference projectReference) {
|
||||||
|
final ProjectReference target = Objects.requireNonNull(projectReference, "projectReference");
|
||||||
|
return new StudioProjectSession(
|
||||||
|
target,
|
||||||
|
projectDocumentVfsFactory.open(target.toVfsProjectContext()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import p.studio.Container;
|
|||||||
import p.studio.controls.shell.*;
|
import p.studio.controls.shell.*;
|
||||||
import p.studio.events.StudioWorkspaceSelectedEvent;
|
import p.studio.events.StudioWorkspaceSelectedEvent;
|
||||||
import p.studio.projects.ProjectReference;
|
import p.studio.projects.ProjectReference;
|
||||||
|
import p.studio.projectsessions.StudioProjectSession;
|
||||||
import p.studio.utilities.i18n.I18n;
|
import p.studio.utilities.i18n.I18n;
|
||||||
import p.studio.workspaces.WorkspaceHost;
|
import p.studio.workspaces.WorkspaceHost;
|
||||||
import p.studio.workspaces.WorkspaceId;
|
import p.studio.workspaces.WorkspaceId;
|
||||||
@ -17,9 +18,11 @@ import java.util.List;
|
|||||||
public final class MainView extends BorderPane {
|
public final class MainView extends BorderPane {
|
||||||
private final WorkspaceHost host = new WorkspaceHost();
|
private final WorkspaceHost host = new WorkspaceHost();
|
||||||
private final ProjectReference projectReference;
|
private final ProjectReference projectReference;
|
||||||
|
private final StudioProjectSession projectSession;
|
||||||
|
|
||||||
public MainView(final ProjectReference projectReference) {
|
public MainView(final StudioProjectSession projectSession) {
|
||||||
this.projectReference = projectReference;
|
this.projectSession = projectSession;
|
||||||
|
this.projectReference = projectSession.projectReference();
|
||||||
final var menuBar = new StudioShellMenuBarControl();
|
final var menuBar = new StudioShellMenuBarControl();
|
||||||
final var runSurface = new StudioRunSurfaceControl();
|
final var runSurface = new StudioRunSurfaceControl();
|
||||||
setTop(new StudioShellTopBarControl(menuBar));
|
setTop(new StudioShellTopBarControl(menuBar));
|
||||||
@ -53,6 +56,10 @@ public final class MainView extends BorderPane {
|
|||||||
return projectReference;
|
return projectReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StudioProjectSession projectSession() {
|
||||||
|
return projectSession;
|
||||||
|
}
|
||||||
|
|
||||||
private void loadWorkspace(WorkspaceId workspaceId) {
|
private void loadWorkspace(WorkspaceId workspaceId) {
|
||||||
host.change(workspaceId);
|
host.change(workspaceId);
|
||||||
Container.eventBus().publish(new StudioWorkspaceSelectedEvent(workspaceId));
|
Container.eventBus().publish(new StudioWorkspaceSelectedEvent(workspaceId));
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import p.studio.events.*;
|
|||||||
import p.studio.projects.KnownProjectsService;
|
import p.studio.projects.KnownProjectsService;
|
||||||
import p.studio.projects.ProjectCatalogService;
|
import p.studio.projects.ProjectCatalogService;
|
||||||
import p.studio.projects.ProjectReference;
|
import p.studio.projects.ProjectReference;
|
||||||
|
import p.studio.projectsessions.StudioProjectSession;
|
||||||
|
import p.studio.projectsessions.StudioProjectSessionFactory;
|
||||||
import p.studio.utilities.i18n.I18n;
|
import p.studio.utilities.i18n.I18n;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -28,12 +30,14 @@ public final class StudioWindowCoordinator {
|
|||||||
private final KnownProjectsService knownProjectsService;
|
private final KnownProjectsService knownProjectsService;
|
||||||
private final WindowStateService windowStateService;
|
private final WindowStateService windowStateService;
|
||||||
private final ProjectLauncherView launcherView;
|
private final ProjectLauncherView launcherView;
|
||||||
|
private final StudioProjectSessionFactory projectSessionFactory;
|
||||||
|
|
||||||
public StudioWindowCoordinator(Stage launcherStage) {
|
public StudioWindowCoordinator(Stage launcherStage) {
|
||||||
this.launcherStage = Objects.requireNonNull(launcherStage, "launcherStage");
|
this.launcherStage = Objects.requireNonNull(launcherStage, "launcherStage");
|
||||||
this.projectCatalogService = new ProjectCatalogService(resolveDefaultProjectsRoot());
|
this.projectCatalogService = new ProjectCatalogService(resolveDefaultProjectsRoot());
|
||||||
this.knownProjectsService = new KnownProjectsService(resolveKnownProjectsStorage(), projectCatalogService);
|
this.knownProjectsService = new KnownProjectsService(resolveKnownProjectsStorage(), projectCatalogService);
|
||||||
this.windowStateService = new WindowStateService(resolveWindowStateStorage());
|
this.windowStateService = new WindowStateService(resolveWindowStateStorage());
|
||||||
|
this.projectSessionFactory = new StudioProjectSessionFactory(Container.projectDocumentVfsFactory());
|
||||||
this.launcherView = new ProjectLauncherView(
|
this.launcherView = new ProjectLauncherView(
|
||||||
knownProjectsService,
|
knownProjectsService,
|
||||||
projectCatalogService,
|
projectCatalogService,
|
||||||
@ -111,6 +115,7 @@ public final class StudioWindowCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeProjectAndOpenWindow(ProjectReference projectReference, Stage loadingStage) {
|
private void initializeProjectAndOpenWindow(ProjectReference projectReference, Stage loadingStage) {
|
||||||
|
StudioProjectSession projectSession = null;
|
||||||
try {
|
try {
|
||||||
Container.eventBus().publish(new StudioProjectLoadingProgressEvent(
|
Container.eventBus().publish(new StudioProjectLoadingProgressEvent(
|
||||||
StudioProjectLoadingPhase.INITIALIZING_SERVICES,
|
StudioProjectLoadingPhase.INITIALIZING_SERVICES,
|
||||||
@ -125,21 +130,28 @@ public final class StudioWindowCoordinator {
|
|||||||
Container.i18n().text(I18n.SHIELD_STATUS_RESTORING),
|
Container.i18n().text(I18n.SHIELD_STATUS_RESTORING),
|
||||||
Progress.RESTORING_WORKSPACES,
|
Progress.RESTORING_WORKSPACES,
|
||||||
false));
|
false));
|
||||||
Platform.runLater(() -> finishProjectOpen(projectReference, loadingStage));
|
projectSession = projectSessionFactory.open(projectReference);
|
||||||
|
final StudioProjectSession readySession = projectSession;
|
||||||
|
Platform.runLater(() -> finishProjectOpen(readySession, loadingStage));
|
||||||
} catch (RuntimeException exception) {
|
} catch (RuntimeException exception) {
|
||||||
|
if (projectSession != null) {
|
||||||
|
projectSession.close();
|
||||||
|
}
|
||||||
Platform.runLater(() -> failProjectOpen(projectReference, loadingStage, exception));
|
Platform.runLater(() -> failProjectOpen(projectReference, loadingStage, exception));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finishProjectOpen(ProjectReference projectReference, Stage loadingStage) {
|
private void finishProjectOpen(StudioProjectSession projectSession, Stage loadingStage) {
|
||||||
|
final ProjectReference projectReference = projectSession.projectReference();
|
||||||
final Stage projectStage = new Stage();
|
final Stage projectStage = new Stage();
|
||||||
final Scene scene = new Scene(new MainView(projectReference), PROJECT_WIDTH, PROJECT_HEIGHT);
|
final Scene scene = new Scene(new MainView(projectSession), PROJECT_WIDTH, PROJECT_HEIGHT);
|
||||||
scene.getStylesheets().add(Container.theme().getDefaultTheme());
|
scene.getStylesheets().add(Container.theme().getDefaultTheme());
|
||||||
|
|
||||||
projectStage.setTitle(Container.i18n().format(I18n.APP_PROJECT_TITLE, projectReference.name()));
|
projectStage.setTitle(Container.i18n().format(I18n.APP_PROJECT_TITLE, projectReference.name()));
|
||||||
projectStage.setScene(scene);
|
projectStage.setScene(scene);
|
||||||
windowStateService.installProjectShellState(projectStage, projectReference, PROJECT_WIDTH, PROJECT_HEIGHT);
|
windowStateService.installProjectShellState(projectStage, projectReference, PROJECT_WIDTH, PROJECT_HEIGHT);
|
||||||
projectStage.setOnHidden(ignored -> {
|
projectStage.setOnHidden(ignored -> {
|
||||||
|
projectSession.close();
|
||||||
launcherView.reloadProjects();
|
launcherView.reloadProjects();
|
||||||
launcherStage.show();
|
launcherStage.show();
|
||||||
launcherStage.centerOnScreen();
|
launcherStage.centerOnScreen();
|
||||||
|
|||||||
@ -0,0 +1,75 @@
|
|||||||
|
package p.studio.projectsessions;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import p.studio.projects.ProjectReference;
|
||||||
|
import p.studio.vfs.ProjectDocumentVfs;
|
||||||
|
import p.studio.vfs.ProjectDocumentVfsFactory;
|
||||||
|
import p.studio.vfs.VfsDocumentOpenResult;
|
||||||
|
import p.studio.vfs.VfsProjectContext;
|
||||||
|
import p.studio.vfs.VfsProjectSnapshot;
|
||||||
|
import p.studio.vfs.VfsRefreshRequest;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
|
|
||||||
|
final class StudioProjectSessionFactoryTest {
|
||||||
|
@Test
|
||||||
|
void openCreatesProjectSessionBackedByProjectScopedVfs() {
|
||||||
|
final RecordingVfsFactory vfsFactory = new RecordingVfsFactory();
|
||||||
|
final StudioProjectSessionFactory sessionFactory = new StudioProjectSessionFactory(vfsFactory);
|
||||||
|
final ProjectReference projectReference = new ProjectReference(
|
||||||
|
"Example",
|
||||||
|
"1.0.0",
|
||||||
|
"pbs",
|
||||||
|
1,
|
||||||
|
Path.of("/tmp/example"));
|
||||||
|
|
||||||
|
final StudioProjectSession session = sessionFactory.open(projectReference);
|
||||||
|
|
||||||
|
assertSame(projectReference, session.projectReference());
|
||||||
|
assertSame(vfsFactory.vfs, session.projectDocumentVfs());
|
||||||
|
assertEquals("Example", vfsFactory.capturedContext.projectName());
|
||||||
|
assertEquals("pbs", vfsFactory.capturedContext.languageId());
|
||||||
|
assertEquals(projectReference.rootPath().toAbsolutePath().normalize(), vfsFactory.capturedContext.rootPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class RecordingVfsFactory implements ProjectDocumentVfsFactory {
|
||||||
|
private VfsProjectContext capturedContext;
|
||||||
|
private final ProjectDocumentVfs vfs = new NoOpProjectDocumentVfs();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProjectDocumentVfs open(VfsProjectContext projectContext) {
|
||||||
|
this.capturedContext = projectContext;
|
||||||
|
return vfs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class NoOpProjectDocumentVfs implements ProjectDocumentVfs {
|
||||||
|
@Override
|
||||||
|
public VfsProjectContext projectContext() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsProjectSnapshot snapshot() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsProjectSnapshot refresh() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsProjectSnapshot refresh(VfsRefreshRequest request) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsDocumentOpenResult openDocument(Path path) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package p.studio.projectsessions;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import p.studio.projects.ProjectReference;
|
||||||
|
import p.studio.vfs.ProjectDocumentVfs;
|
||||||
|
import p.studio.vfs.VfsDocumentOpenResult;
|
||||||
|
import p.studio.vfs.VfsProjectContext;
|
||||||
|
import p.studio.vfs.VfsProjectSnapshot;
|
||||||
|
import p.studio.vfs.VfsRefreshRequest;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
final class StudioProjectSessionTest {
|
||||||
|
@Test
|
||||||
|
void closeDelegatesToUnderlyingVfsOnlyOnce() {
|
||||||
|
final CountingProjectDocumentVfs vfs = new CountingProjectDocumentVfs();
|
||||||
|
final StudioProjectSession session = new StudioProjectSession(projectReference(), vfs);
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
assertEquals(1, vfs.closeCalls);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProjectReference projectReference() {
|
||||||
|
return new ProjectReference("Example", "1.0.0", "pbs", 1, Path.of("/tmp/example"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class CountingProjectDocumentVfs implements ProjectDocumentVfs {
|
||||||
|
private int closeCalls;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsProjectContext projectContext() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsProjectSnapshot snapshot() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsProjectSnapshot refresh() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsProjectSnapshot refresh(VfsRefreshRequest request) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VfsDocumentOpenResult openDocument(Path path) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
closeCalls++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user