Skip to content

Commit

Permalink
Add ability to right click a scene to "Run From Here" allowing quick …
Browse files Browse the repository at this point in the history
…preview of a specific scene
  • Loading branch information
chrismaltby committed Oct 16, 2024
1 parent d911e5c commit 89d4c35
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add ability to select all scenes with Ctrl/Cmd + A from Game World view
- Add plugin manager for installing plugins from the official plugin repository, accessible from the menu at `Plugins / Plugin Manager`
- Add support for theme, localization and project template plugins
- Add ability to right click a scene to "Run From Here" allowing quick preview of a specific scene. Optionally can only include the selected scenes for faster build previews in large projects.

### Changed

Expand Down
14 changes: 12 additions & 2 deletions src/components/world/NavigatorScenes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ export const NavigatorScenes: FC<NavigatorScenesProps> = ({
const sceneSelectionIds = useAppSelector(
(state) => state.editor.sceneSelectionIds
);

const runSceneSelectionOnly = useAppSelector(
(state) => state.project.present.settings.runSceneSelectionOnly
);
const [folderId, setFolderId] = useState("");

const dispatch = useAppDispatch();
Expand Down Expand Up @@ -240,6 +242,7 @@ export const NavigatorScenes: FC<NavigatorScenesProps> = ({
hoverX: 0,
hoverY: 0,
onRename: () => setRenameId(item.id),
runSceneSelectionOnly,
onClose,
});
} else if (item.type === "actor") {
Expand All @@ -265,7 +268,14 @@ export const NavigatorScenes: FC<NavigatorScenesProps> = ({
assertUnreachable(item);
}
},
[dispatch, sceneSelectionIds, scenes, startDirection, startSceneId]
[
dispatch,
runSceneSelectionOnly,
sceneSelectionIds,
scenes,
startDirection,
startSceneId,
]
);

const renderLabel = useCallback(
Expand Down
6 changes: 5 additions & 1 deletion src/components/world/SceneView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,9 @@ const SceneView = memo(
const { x: hoverX, y: hoverY } = useAppSelector(
(state) => state.editor.hover
);

const runSceneSelectionOnly = useAppSelector(
(state) => state.project.present.settings.runSceneSelectionOnly
);
const selected = useAppSelector((state) => state.editor.scene === id);
const sceneSelectionIds = useAppSelector(
(state) => state.editor.sceneSelectionIds
Expand Down Expand Up @@ -586,6 +588,7 @@ const SceneView = memo(
startDirection,
hoverX,
hoverY,
runSceneSelectionOnly,
onClose: onContextMenuClose,
});
}, [
Expand All @@ -596,6 +599,7 @@ const SceneView = memo(
sceneSelectionIds,
startDirection,
startSceneId,
runSceneSelectionOnly,
onContextMenuClose,
]);

Expand Down
41 changes: 41 additions & 0 deletions src/components/world/renderSceneContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import React, { Dispatch } from "react";
import { UnknownAction } from "redux";
import { ActorDirection } from "shared/lib/entities/entitiesTypes";
import l10n from "shared/lib/lang/l10n";
import buildGameActions from "store/features/buildGame/buildGameActions";
import entitiesActions from "store/features/entities/entitiesActions";
import settingsActions from "store/features/settings/settingsActions";
import { LabelButton } from "ui/buttons/LabelButton";
import { BlankIcon, CheckIcon } from "ui/icons/Icons";
import { MenuDivider, MenuItem, MenuSection } from "ui/menu/Menu";

interface SceneContextMenuProps {
Expand All @@ -16,6 +18,7 @@ interface SceneContextMenuProps {
startDirection: ActorDirection;
hoverX: number;
hoverY: number;
runSceneSelectionOnly: boolean;
onRename?: () => void;
onClose?: () => void;
}
Expand All @@ -29,6 +32,7 @@ const renderSceneContextMenu = ({
startDirection,
hoverX,
hoverY,
runSceneSelectionOnly,
onClose,
}: SceneContextMenuProps) => {
return [
Expand Down Expand Up @@ -122,6 +126,43 @@ const renderSceneContextMenu = ({
/>
</div>
</MenuSection>,
<MenuDivider key="div-preview" />,
<MenuItem
key="preview"
subMenu={[
<MenuItem
key="preview-here"
icon={<BlankIcon />}
onClick={() =>
dispatch(
buildGameActions.buildGame({
startSceneId: sceneId,
startX: hoverX,
startY: hoverY,
})
)
}
>
{l10n("FIELD_RUN_FROM_HERE")}
</MenuItem>,
<MenuDivider key="div-preview-sub" />,
<MenuItem
key="preview-selection"
icon={runSceneSelectionOnly ? <CheckIcon /> : <BlankIcon />}
onClick={() => {
dispatch(
settingsActions.editSettings({
runSceneSelectionOnly: !runSceneSelectionOnly,
})
);
}}
>
{l10n("FIELD_INCLUDE_SELECTION_ONLY")}
</MenuItem>,
]}
>
{l10n("FIELD_RUN_SCENE")}
</MenuItem>,
...(onRename
? [
<MenuDivider key="div-rename" />,
Expand Down
1 change: 1 addition & 0 deletions src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export const defaultProjectSettings: Settings = {
compilerPreset: 3000,
scriptEventPresets: {},
scriptEventDefaultPresets: {},
runSceneSelectionOnly: false,
};

export const defaultPalettes: Palette[] = [
Expand Down
3 changes: 3 additions & 0 deletions src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,9 @@
"FIELD_ADDING": "Adding...",
"FIELD_CLOSE": "Close",
"FIELD_LICENSE": "License",
"FIELD_RUN_SCENE": "Run Scene",
"FIELD_RUN_FROM_HERE": "Run From Here",
"FIELD_INCLUDE_SELECTION_ONLY": "Include Selection Only",

"// 7": "Asset Viewer ---------------------------------------------",
"ASSET_SEARCH": "Search...",
Expand Down
1 change: 1 addition & 0 deletions src/shared/lib/resources/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ export const SettingsResource = Type.Object({
Type.Record(Type.String(), ScriptEventPreset)
),
scriptEventDefaultPresets: Type.Record(Type.String(), Type.String()),
runSceneSelectionOnly: Type.Boolean(),
});

export type SettingsResource = Static<typeof SettingsResource>;
Expand Down
12 changes: 12 additions & 0 deletions src/store/features/buildGame/buildGameActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ const buildGame = createAction(
buildType = "web",
exportBuild = false,
debugEnabled = false,
startSceneId,
startX,
startY,
onlySelection,
}: {
buildType?: BuildType;
exportBuild?: boolean;
debugEnabled?: boolean;
startSceneId?: string;
startX?: number;
startY?: number;
onlySelection?: boolean;
} = {
buildType: "web",
exportBuild: false,
Expand All @@ -25,6 +33,10 @@ const buildGame = createAction(
buildType,
exportBuild,
debugEnabled,
startSceneId,
startX,
startY,
onlySelection,
},
};
}
Expand Down
43 changes: 35 additions & 8 deletions src/store/features/buildGame/buildGameMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ const buildGameMiddleware: Middleware<Dispatch, RootState> =
const state = store.getState();
const dispatch = store.dispatch.bind(store);

const { buildType, exportBuild, debugEnabled } = action.payload;
const {
buildType,
exportBuild,
debugEnabled,
startSceneId,
startX,
startY,
} = action.payload;

if (state.console.status === "cancelled") {
// Wait until cancel is complete before allowing another build
Expand All @@ -32,15 +39,35 @@ const buildGameMiddleware: Middleware<Dispatch, RootState> =
const project = denormalizeProject(state.project.present);
const engineFields = state.engine.fields;
const sceneTypes = state.engine.sceneTypes;
const selectionIds = state.editor.sceneSelectionIds;

try {
await API.project.build(project, {
buildType,
engineFields,
exportBuild,
debugEnabled,
sceneTypes,
});
await API.project.build(
{
...project,
scenes:
startSceneId && project.settings.runSceneSelectionOnly
? project.scenes.filter(
(scene) =>
scene.id === startSceneId ||
selectionIds.includes(scene.id)
)
: project.scenes,
settings: {
...project.settings,
startSceneId: startSceneId ?? project.settings.startSceneId,
startX: startX ?? project.settings.startX,
startY: startY ?? project.settings.startY,
},
},
{
buildType,
engineFields,
exportBuild,
debugEnabled,
sceneTypes,
}
);
} catch (e) {
dispatch(settingsActions.editSettings({ debuggerEnabled: true }));
dispatch(navigationActions.setSection("world"));
Expand Down
3 changes: 3 additions & 0 deletions test/dummydata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ export const dummyProjectData: ProjectData = {
compilerPreset: 3000,
scriptEventPresets: {},
scriptEventDefaultPresets: {},
runSceneSelectionOnly: false,
},
};

Expand Down Expand Up @@ -623,6 +624,7 @@ export const dummySettingsResource: SettingsResource = {
compilerPreset: 3000,
scriptEventPresets: {},
scriptEventDefaultPresets: {},
runSceneSelectionOnly: false,
};

export const dummyVariablesResource: VariablesResource = {
Expand Down Expand Up @@ -731,6 +733,7 @@ export const dummyProjectResources: ProjectResources = {
compilerPreset: 3000,
scriptEventPresets: {},
scriptEventDefaultPresets: {},
runSceneSelectionOnly: false,
},
};

Expand Down
1 change: 1 addition & 0 deletions test/resources/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@ describe("TypeBox Schemas", () => {
compilerPreset: 3000,
scriptEventPresets: {},
scriptEventDefaultPresets: {},
runSceneSelectionOnly: false,
};
const invalidSettings = {
_resourceType: "settings",
Expand Down

0 comments on commit 89d4c35

Please sign in to comment.