mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 17:38:10 +00:00
Make 3D cache save cancellable with flag
This commit is contained in:
1 parent
3de468389e
commit
72f960a5d4
3 files changed
+56
-30
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
faGear,
|
||||
faImages,
|
||||
@@ -23,19 +23,21 @@ import {
|
||||
MenuIconSelector,
|
||||
MenuIconItem,
|
||||
} from "@storyteller/ui-menu-icon-selector";
|
||||
import { signal } from "@preact/signals-react";
|
||||
import { signal } from "@preact/signals-react";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { setLogoutStates } from "~/signals/authentication/utilities";
|
||||
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useTabStore } from "~/pages/Stores/TabState";
|
||||
import { set3DPageMounted } from "~/pages/PageEnigma/Editor/editor";
|
||||
import {
|
||||
is3DEditorInitialized,
|
||||
is3DSceneLoaded,
|
||||
set3DPageMounted,
|
||||
} from "~/pages/PageEnigma/Editor/editor";
|
||||
interface Props {
|
||||
pageName: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const appMenuTabs: MenuIconItem[] = [
|
||||
{
|
||||
id: "2D",
|
||||
@@ -62,9 +64,7 @@ const appMenuTabs: MenuIconItem[] = [
|
||||
export const topNavMediaId = signal<string>("");
|
||||
export const topNavMediaUrl = signal<string>("");
|
||||
|
||||
export const TopBar = ({
|
||||
pageName
|
||||
}: Props) => {
|
||||
export const TopBar = ({ pageName }: Props) => {
|
||||
useSignals();
|
||||
|
||||
const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false);
|
||||
@@ -73,9 +73,19 @@ export const TopBar = ({
|
||||
galleryModalVisibleViewMode.value = true;
|
||||
galleryModalVisibleDuringDrag.value = true;
|
||||
};
|
||||
|
||||
|
||||
const tabStore = useTabStore();
|
||||
|
||||
const is3DSceneReady = is3DSceneLoaded.value;
|
||||
const is3DEditorReady = is3DEditorInitialized.value;
|
||||
const disableTabSwitcher = () => {
|
||||
return (
|
||||
useTabStore.getState().activeTabId === "3D" &&
|
||||
!is3DEditorReady &&
|
||||
!is3DSceneReady
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="fixed left-0 top-0 z-[60] w-full border-b border-white/5 bg-ui-background">
|
||||
@@ -95,7 +105,7 @@ export const TopBar = ({
|
||||
<MenuIconSelector
|
||||
menuItems={appMenuTabs}
|
||||
activeMenu={tabStore.activeTabId}
|
||||
disabled={false}
|
||||
disabled={disableTabSwitcher()}
|
||||
onMenuChange={(tabId) => {
|
||||
// Disable 3d engine to prevent memory leak.
|
||||
if (tabId === "3D") {
|
||||
@@ -103,9 +113,7 @@ export const TopBar = ({
|
||||
} else {
|
||||
set3DPageMounted(false);
|
||||
}
|
||||
useTabStore
|
||||
.getState()
|
||||
.setActiveTab(tabId);
|
||||
useTabStore.getState().setActiveTab(tabId);
|
||||
}}
|
||||
className="w-fit"
|
||||
/>
|
||||
@@ -158,10 +166,7 @@ export const TopBar = ({
|
||||
globalAccountLogoutCallback={() => setLogoutStates()}
|
||||
/>
|
||||
|
||||
<GalleryModal
|
||||
mode="view"
|
||||
onDownloadClicked={downloadFileFromUrl}
|
||||
/>
|
||||
<GalleryModal mode="view" onDownloadClicked={downloadFileFromUrl} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -63,15 +63,24 @@ export type EditorInitializeConfig = {
|
||||
};
|
||||
|
||||
// ONLY USED IN THIS CLASS
|
||||
// Need this one to ensure the canvas is inflated and non-zero sized
|
||||
const is3DPageMounted = signal(false);
|
||||
export const set3DPageMounted = (isMounted: boolean) => {
|
||||
is3DPageMounted.value = isMounted;
|
||||
};
|
||||
|
||||
// Need this one to know when the engine has initialized (but not necessarily loaded saves)
|
||||
export const is3DEditorInitialized = signal(false);
|
||||
export const setIs3DEditorInitialized = (isInitialized: boolean) => {
|
||||
is3DEditorInitialized.value = isInitialized;
|
||||
};
|
||||
|
||||
// Need this one to know when the engine is done loading stuff into the scene for display
|
||||
export const is3DSceneLoaded = signal(false);
|
||||
export const setIs3DSceneLoaded = (isLoaded: boolean) => {
|
||||
is3DSceneLoaded.value = isLoaded;
|
||||
};
|
||||
|
||||
class Editor {
|
||||
version: number;
|
||||
activeScene: Scene;
|
||||
@@ -660,10 +669,15 @@ class Editor {
|
||||
// Attach freecam state controller
|
||||
this.mouseOverEventHandler = this.mouseOverEventHandler.bind(this);
|
||||
|
||||
const onloadCallback = () => {
|
||||
console.log("Setting Scene is loaded");
|
||||
setIs3DSceneLoaded(true);
|
||||
};
|
||||
|
||||
if (!this.utils.isEmpty(cacheJson)) {
|
||||
this.loadCache(cacheJson);
|
||||
this.loadCache(cacheJson).then(onloadCallback);
|
||||
} else if (!this.utils.isEmpty(sceneToken)) {
|
||||
this.loadScene(sceneToken);
|
||||
this.loadScene(sceneToken).then(onloadCallback);
|
||||
} else {
|
||||
signalScene({
|
||||
title: "Untitled New Scene",
|
||||
@@ -671,6 +685,7 @@ class Editor {
|
||||
ownerToken: authentication.userInfo.value?.user_token,
|
||||
isModified: false,
|
||||
});
|
||||
onloadCallback();
|
||||
}
|
||||
|
||||
this._configurePostProcessingRaw();
|
||||
@@ -1484,6 +1499,7 @@ class Editor {
|
||||
}
|
||||
|
||||
unmountEngine() {
|
||||
setIs3DSceneLoaded(false);
|
||||
this.stopRenderLoop();
|
||||
this.sceneManager?.detachEventListeners();
|
||||
this.disableFreeCamControls();
|
||||
@@ -1496,6 +1512,7 @@ class Editor {
|
||||
this.rawRenderer?.dispose();
|
||||
|
||||
this.isMounted = false;
|
||||
setIs3DEditorInitialized(false);
|
||||
console.log("3D Editor Engine unmounted");
|
||||
}
|
||||
|
||||
|
||||
+15
-11
@@ -1,7 +1,7 @@
|
||||
import { ReactNode, useEffect, useRef, useState } from "react";
|
||||
import { EngineContext } from "./EngineContext";
|
||||
|
||||
import Editor from "~/pages/PageEnigma/Editor/editor";
|
||||
import Editor, { is3DSceneLoaded } from "~/pages/PageEnigma/Editor/editor";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
|
||||
import { signal } from "@preact/signals-react";
|
||||
@@ -59,16 +59,20 @@ export const EngineProvider = ({ sceneToken, children }: Props) => {
|
||||
}
|
||||
|
||||
// If the tab is changed, cache state, unmount the editor and clear all input params
|
||||
const sceneGenerationMetadata = getSceneGenerationMetaData(
|
||||
activeEditorRef.current,
|
||||
);
|
||||
const cacheJson = activeEditorRef.current.cacheScene({
|
||||
sceneTitle: "",
|
||||
sceneToken: "",
|
||||
sceneGenerationMetadata: sceneGenerationMetadata,
|
||||
});
|
||||
const cacheString = JSON.stringify(cacheJson);
|
||||
tabStore.updateTabData("3D", cacheString);
|
||||
// This condition makes sure the editor saves a fully loaded scene so it doesn't lose data
|
||||
// If the load was incomplete, we'll preserve the last cache anyway.
|
||||
if (is3DSceneLoaded.peek()) {
|
||||
const sceneGenerationMetadata = getSceneGenerationMetaData(
|
||||
activeEditorRef.current,
|
||||
);
|
||||
const cacheJson = activeEditorRef.current.cacheScene({
|
||||
sceneTitle: "",
|
||||
sceneToken: "",
|
||||
sceneGenerationMetadata: sceneGenerationMetadata,
|
||||
});
|
||||
const cacheString = JSON.stringify(cacheJson);
|
||||
tabStore.updateTabData("3D", cacheString);
|
||||
}
|
||||
|
||||
// Unmount/Destructor flow
|
||||
activeEditorRef.current?.unmountEngine();
|
||||
|
||||
Reference in new issue
Block a user