Convert classicube to isolated app

This commit is contained in:
Dustin Brett
2025-01-20 19:53:23 -08:00
parent 3236492485
commit 734bfb4407
4 changed files with 59 additions and 38 deletions

View File

@@ -3,11 +3,6 @@ import styled from "styled-components";
const StyledClassiCube = styled.div`
height: ${({ theme }) => `calc(100% - ${theme.sizes.titleBar.height}px)`};
width: 100%;
canvas {
height: 100%;
width: 100%;
}
`;
export default StyledClassiCube;

View File

@@ -2,16 +2,13 @@ import StyledClassiCube from "components/apps/ClassiCube/StyledClassiCube";
import useClassiCube from "components/apps/ClassiCube/useClassiCube";
import AppContainer from "components/system/Apps/AppContainer";
import { type ComponentProcessProps } from "components/system/Apps/RenderComponent";
import { haltEvent } from "utils/functions";
const ClassiCube: FC<ComponentProcessProps> = ({ id }) => (
<AppContainer
StyledComponent={StyledClassiCube}
id={id}
useHook={useClassiCube}
>
<canvas onContextMenu={haltEvent} />
</AppContainer>
/>
);
export default ClassiCube;

View File

@@ -1,12 +1,13 @@
import { useTheme } from "styled-components";
import { useCallback, useEffect } from "react";
import { useEffect, useState } from "react";
import { type ContainerHookProps } from "components/system/Apps/AppContainer";
import useEmscriptenMount from "components/system/Files/FileManager/useEmscriptenMount";
import { type EmscriptenFS } from "contexts/fileSystem/useAsyncFs";
import { useProcesses } from "contexts/process";
import { useSession } from "contexts/session";
import { TRANSITIONS_IN_MILLISECONDS } from "utils/constants";
import { loadFiles, pxToNum } from "utils/functions";
import { haltEvent, loadFiles, pxToNum } from "utils/functions";
import useIsolatedContentWindow from "hooks/useIsolatedContentWindow";
declare global {
interface Window {
@@ -18,6 +19,7 @@ declare global {
print: () => void;
setCanvasSize?: (width: number, height: number) => void;
setStatus: () => void;
windowElement: HTMLElement;
};
}
}
@@ -26,6 +28,7 @@ const useClassiCube = ({
containerRef,
id,
setLoading,
loading,
}: ContainerHookProps): void => {
const { processes: { [id]: process } = {} } = useProcesses();
const mountEmFs = useEmscriptenMount();
@@ -33,41 +36,66 @@ const useClassiCube = ({
windowStates: { [id]: windowState },
} = useSession();
const { size } = windowState || {};
const { libs } = process || {};
const { componentWindow, libs, maximized } = process || {};
const {
sizes: { titleBar },
} = useTheme();
const getCanvas = useCallback(
() =>
(containerRef.current as HTMLElement)?.querySelector(
"canvas"
) as HTMLCanvasElement,
[containerRef]
const getContentWindow = useIsolatedContentWindow(
id,
containerRef,
undefined,
"canvas { height: 100%; width: 100%; }",
true
);
const [contentWindow, setContentWindow] = useState<Window>();
useEffect(() => {
if (size) {
window.CCModule.setCanvasSize?.(
pxToNum(size.width),
pxToNum(size.height) - titleBar.height
);
window.CCModule.OnResize?.();
}
}, [size, titleBar.height]);
useEffect(() => {
if (window.CCModule) return;
setTimeout(() => {
const canvas = getCanvas();
let currentSize = size;
window.CCModule = {
if (!currentSize && componentWindow) {
const { height, width } = componentWindow.getBoundingClientRect();
currentSize = { height, width };
}
if (currentSize) {
contentWindow?.CCModule.setCanvasSize?.(
pxToNum(currentSize.width),
pxToNum(currentSize.height) - titleBar.height
);
contentWindow?.CCModule.OnResize?.();
}
}, TRANSITIONS_IN_MILLISECONDS.WINDOW);
// eslint-disable-next-line react-hooks-addons/no-unused-deps
}, [
componentWindow,
contentWindow?.CCModule,
maximized,
size,
titleBar.height,
]);
useEffect(() => {
if (loading) {
const newContentWindow = getContentWindow?.();
if (!newContentWindow) return;
const canvas = newContentWindow?.document.querySelector(
"canvas"
) as HTMLCanvasElement;
canvas.addEventListener("contextmenu", haltEvent);
newContentWindow.CCModule = {
arguments: ["Singleplayer"],
canvas,
postRun: [
() => {
setLoading(false);
mountEmFs(window.FS as EmscriptenFS, "ClassiCube");
setContentWindow(newContentWindow);
mountEmFs(newContentWindow.FS as EmscriptenFS, "ClassiCube");
},
() => {
const { width, height } = canvas.getBoundingClientRect() || {};
@@ -78,11 +106,12 @@ const useClassiCube = ({
],
print: console.info,
setStatus: console.info,
windowElement: newContentWindow.document.body,
};
loadFiles(libs);
}, TRANSITIONS_IN_MILLISECONDS.WINDOW);
}, [getCanvas, libs, mountEmFs, setLoading]);
loadFiles(libs, undefined, undefined, undefined, newContentWindow);
}
}, [getContentWindow, libs, loading, mountEmFs, setLoading]);
};
export default useClassiCube;

View File

@@ -2379,7 +2379,7 @@ function copyTempDouble(ptr) {
JSEvents.eventHandlers.splice(i, 1);
},registerOrRemoveHandler:function (eventHandler) {
var jsEventHandler = function jsEventHandler(event) {
var windowElement = CCModule["canvas"]?.closest("section");
var windowElement = CCModule["windowElement"];
if (!windowElement || (document.activeElement !== windowElement && !windowElement?.contains(document.activeElement))) {
return;
}
@@ -3458,7 +3458,7 @@ function copyTempDouble(ptr) {
var ctx =
(canvas.getContext("webgl", webGLContextAttributes) || canvas.getContext("experimental-webgl", webGLContextAttributes));
(canvas.getContext("webgl", {...webGLContextAttributes,alpha:false,desynchronized:true,preserveDrawingBuffer:true,willReadFrequently:true}) || canvas.getContext("experimental-webgl", webGLContextAttributes));
return ctx && GL.registerContext(ctx, webGLContextAttributes);