Navigation Menu

Skip to content

Commit

Permalink
implement simulator loading independent from the simulator editor
Browse files Browse the repository at this point in the history
  • Loading branch information
SillyFreak committed May 22, 2020
1 parent e225897 commit 3535456
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
42 changes: 36 additions & 6 deletions src/components/ide/Ide/Ide.js
Expand Up @@ -38,7 +38,8 @@ import FileTree, {
} from '../FileTree';
import Simulator from '../Simulator';
import VisualEditor from '../VisualEditor';
import SimulatorEditor from '../SimulatorEditor';
import SimulatorEditor, { generateSchemaFromXml } from '../SimulatorEditor';
import * as SimulationSchema from '../SimulatorEditor/SimulationSchema';

import {
type FilerRecursiveStatInfo,
Expand Down Expand Up @@ -161,6 +162,38 @@ function Ide({ projectName }: Props) {
})();
}, [projectInfo]);

// load the project's simulator schema if it or the simulator changes
const simulatorXml = projectInfo && projectInfo.simulatorXml;

function refreshSimulatorFromSchema(
schema: SimulationSchema.SimulatorJson | null,
) {
if (simulatorRef.current === null || schema === null) return;

simulatorRef.current.simulation.jsonInit(schema);
}

function refreshSimulator() {
if (simulatorXml === null) return;

const schema = generateSchemaFromXml(simulatorXml);
refreshSimulatorFromSchema(schema);
}

React.useEffect(() => {
refreshSimulator();
}, [simulatorXml]);

// uses useCallback because otherwise each render resets the ref.
// (the ref could be registered with a new callback,
// so the callback needs to be stable)
const attachSimulator = React.useCallback(
sim => {
simulatorRef.current = sim;
},
[simulatorRef],
);

function getFile(path: string): FileReference {
// eslint-disable-next-line no-throw-literal
if (projectInfo === null) throw 'unreachable';
Expand Down Expand Up @@ -766,7 +799,7 @@ function Ide({ projectName }: Props) {
case 'simulator': {
return (
<Simulator
ref={simulatorRef}
ref={attachSimulator}
width={600}
height={400}
onExecutionAction={handleExecutionAction}
Expand Down Expand Up @@ -796,10 +829,7 @@ function Ide({ projectName }: Props) {
project={projectInfo.project}
path={id}
{...bindEditorProps(id, 'simulator-editor')}
onSchemaChange={schema => {
if (simulatorRef.current && schema)
simulatorRef.current.simulation.jsonInit(schema);
}}
onSchemaChange={refreshSimulatorFromSchema}
/>
);
}
Expand Down
20 changes: 19 additions & 1 deletion src/components/ide/Ide/projectInfo.js
Expand Up @@ -2,6 +2,8 @@

import * as React from 'react';

import filer, { fs } from 'filer';

import {
type FilerRecursiveStatInfo,
Project,
Expand All @@ -11,6 +13,7 @@ type ProjectInfo = {|
project: Project,
files: FilerRecursiveStatInfo,
projectUid: string,
simulatorXml: string | null,
|};

export default function useProjectInfo(
Expand All @@ -19,13 +22,28 @@ export default function useProjectInfo(
const [state, setState] = React.useState<ProjectInfo | null>(null);

function refreshProject() {
async function loadSimulatorXml(project: Project): Promise<string | null> {
const absolutePath = project.resolve('./.metadata/simulator');
try {
const workspaceXml = await fs.promises.readFile(absolutePath, 'utf8');
if (workspaceXml === '') return null;
return workspaceXml;
} catch (ex) {
if (!(ex instanceof filer.Errors.ENOENT)) {
throw ex;
}
return null;
}
}

(async () => {
// load project from the file system
const project = await Project.getProject(projectName);
const files = await project.getFiles();
const projectUid = await project.getUid();
const simulatorXml = await loadSimulatorXml(project);

setState({ project, files, projectUid });
setState({ project, files, projectUid, simulatorXml });
})();
}

Expand Down
4 changes: 3 additions & 1 deletion src/components/ide/Simulator/Simulator.js
Expand Up @@ -328,7 +328,9 @@ function Simulator(
};
}, [renderTarget, simulation, width, height]);

React.useImperativeHandle(ref, () => ({ simulation }));
// Need to use a dependency array here, because Ide requires a stable ref.
// On each change to the Simulator ref, jsonInit is potentially called.
React.useImperativeHandle(ref, () => ({ simulation }), [simulation]);

useStyles(s);
return (
Expand Down

0 comments on commit 3535456

Please sign in to comment.