Skip to content

Commit 6a48d51

Browse files
authored
Pr simplify (#370)
* Remove unneeded currentEditor * Removed modulePathToContentText cache
1 parent 8807560 commit 6a48d51

File tree

4 files changed

+39
-82
lines changed

4 files changed

+39
-82
lines changed

src/App.tsx

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
139139
const [alertErrorMessage, setAlertErrorMessage] = React.useState('');
140140
const [messageApi, contextHolder] = Antd.message.useMessage();
141141
const [toolboxSettingsModalIsOpen, setToolboxSettingsModalIsOpen] = React.useState(false);
142-
const [modulePathToContentText, setModulePathToContentText] = React.useState<{[modulePath: string]: string}>({});
143142
const [tabItems, setTabItems] = React.useState<Tabs.TabItem[]>([]);
144143
const [isLoadingTabs, setIsLoadingTabs] = React.useState(false);
145144
const [shownPythonToolboxCategories, setShownPythonToolboxCategories] = React.useState<Set<string>>(new Set());
@@ -269,46 +268,6 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
269268
initializeShownPythonToolboxCategories();
270269
}, [storage]);
271270

272-
// Fetch any unfetched modules when project changes.
273-
React.useEffect(() => {
274-
fetchModules();
275-
}, [project]);
276-
277-
const fetchModules = async () => {
278-
if (!project || !storage) {
279-
return;
280-
}
281-
const promises: {[modulePath: string]: Promise<string>} = {}; // value is promise of module content.
282-
const updatedModulePathToContentText: {[modulePath: string]: string} = {}; // value is module content text
283-
if (project.robot.modulePath in modulePathToContentText) {
284-
updatedModulePathToContentText[project.robot.modulePath] = modulePathToContentText[project.robot.modulePath];
285-
} else {
286-
promises[project.robot.modulePath] = storage.fetchFileContentText(project.robot.modulePath);
287-
}
288-
project.mechanisms.forEach(mechanism => {
289-
if (mechanism.modulePath in modulePathToContentText) {
290-
updatedModulePathToContentText[mechanism.modulePath] = modulePathToContentText[mechanism.modulePath];
291-
} else {
292-
promises[mechanism.modulePath] = storage.fetchFileContentText(mechanism.modulePath);
293-
}
294-
});
295-
project.opModes.forEach(opmode => {
296-
if (opmode.modulePath in modulePathToContentText) {
297-
updatedModulePathToContentText[opmode.modulePath] = modulePathToContentText[opmode.modulePath];
298-
} else {
299-
promises[opmode.modulePath] = storage.fetchFileContentText(opmode.modulePath);
300-
}
301-
});
302-
if (Object.keys(promises).length) {
303-
await Promise.all(
304-
Object.entries(promises).map(async ([modulePath, promise]) => {
305-
updatedModulePathToContentText[modulePath] = await promise;
306-
})
307-
);
308-
setModulePathToContentText(updatedModulePathToContentText);
309-
}
310-
};
311-
312271
// Load saved tabs when project changes
313272
React.useEffect(() => {
314273
const loadSavedTabs = async () => {
@@ -438,7 +397,7 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
438397
setTabItems(updatedTabs);
439398
}
440399
}
441-
}, [modulePathToContentText]);
400+
}, [project, tabItems]);
442401

443402
// Save tabs when tab list changes (but not during initial loading)
444403
React.useEffect(() => {
@@ -461,7 +420,7 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
461420
}, [tabItems, project?.projectName, isLoadingTabs]);
462421

463422
const onProjectChanged = async (): Promise<void> => {
464-
await fetchModules();
423+
// No need to fetch modules anymore - each editor fetches what it needs
465424
};
466425

467426
const gotoTab = (tabKey: string): void => {
@@ -543,7 +502,6 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
543502
storage={storage}
544503
theme={theme}
545504
shownPythonToolboxCategories={shownPythonToolboxCategories}
546-
modulePathToContentText={modulePathToContentText}
547505
messageApi={messageApi}
548506
/>
549507
</Antd.Layout>

src/editor/editor.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ const MRC_ON_MUTATOR_OPEN = 'mrcOnMutatorOpen';
5151

5252
export class Editor {
5353
private static workspaceIdToEditor: { [workspaceId: string]: Editor } = {};
54-
private static currentEditor: Editor | null = null;
5554

5655
private readonly blocklyWorkspace: Blockly.WorkspaceSvg;
5756
private readonly module: storageModule.Module;
@@ -74,16 +73,16 @@ export class Editor {
7473
module: storageModule.Module,
7574
project: storageProject.Project,
7675
storage: commonStorage.Storage,
77-
modulePathToContentText: {[modulePath: string]: string}) {
76+
moduleContentText: string) {
7877
workspaces.addWorkspace(blocklyWorkspace, module.moduleType);
7978
this.blocklyWorkspace = blocklyWorkspace;
8079
this.module = module;
8180
this.projectName = project.projectName;
8281
this.storage = storage;
8382
this.modulePath = module.modulePath;
8483
this.robotPath = project.robot.modulePath;
85-
this.moduleContentText = modulePathToContentText[module.modulePath];
86-
this.parseModules(project, modulePathToContentText);
84+
this.moduleContentText = moduleContentText;
85+
// parseModules will be called async after construction
8786
Editor.workspaceIdToEditor[blocklyWorkspace.id] = this;
8887
}
8988

@@ -205,13 +204,9 @@ export class Editor {
205204
}
206205
}
207206

208-
public makeCurrent(
209-
project: storageProject.Project,
210-
modulePathToContentText: {[modulePath: string]: string}): void {
211-
Editor.currentEditor = this;
212-
207+
public async makeCurrent(project: storageProject.Project): Promise<void> {
213208
// Parse modules since they might have changed.
214-
this.parseModules(project, modulePathToContentText);
209+
await this.parseModules(project);
215210
this.updateToolboxImpl();
216211

217212
// Go through all the blocks in the workspace and call their mrcOnModuleCurrent method.
@@ -234,17 +229,26 @@ export class Editor {
234229

235230
public abandon(): void {
236231
workspaces.removeWorkspace(this.blocklyWorkspace);
237-
if (Editor.currentEditor === this) {
238-
Editor.currentEditor = null;
239-
}
240232
if (this.blocklyWorkspace.id in Editor.workspaceIdToEditor) {
241233
delete Editor.workspaceIdToEditor[this.blocklyWorkspace.id];
242234
}
243235
}
244236

245-
private parseModules(
246-
project: storageProject.Project,
247-
modulePathToContentText: {[modulePath: string]: string}): void {
237+
private async parseModules(project: storageProject.Project): Promise<void> {
238+
// Fetch all module content from storage
239+
const modulePaths: string[] = [
240+
project.robot.modulePath,
241+
...project.mechanisms.map(m => m.modulePath),
242+
...project.opModes.map(o => o.modulePath),
243+
];
244+
245+
const modulePathToContentText: {[modulePath: string]: string} = {};
246+
await Promise.all(
247+
modulePaths.map(async (modulePath) => {
248+
modulePathToContentText[modulePath] = await this.storage.fetchFileContentText(modulePath);
249+
})
250+
);
251+
248252
// Parse the modules.
249253
this.modulePathToModuleContent = {}
250254
for (const modulePath in modulePathToContentText) {
@@ -645,10 +649,6 @@ export class Editor {
645649
return workspace ? Editor.getEditorForBlocklyWorkspace(workspace) : null;
646650
}
647651

648-
public static getCurrentEditor(): Editor | null {
649-
return Editor.currentEditor;
650-
}
651-
652652
private setPasteLocation(): void {
653653
const copyData = Blockly.clipboard.getLastCopiedData();
654654
if (copyData && copyData.paster === 'block') {

src/reactComponents/TabContent.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ export interface TabContentProps {
5353
storage: commonStorage.Storage;
5454
theme: string;
5555
shownPythonToolboxCategories: Set<string>;
56-
modulePathToContentText: {[modulePath: string]: string};
5756
messageApi: MessageInstance;
5857
setAlertErrorMessage: (message: string) => void;
5958
isActive: boolean;
@@ -70,7 +69,6 @@ export const TabContent = React.forwardRef<TabContentRef, TabContentProps>(({
7069
storage,
7170
theme,
7271
shownPythonToolboxCategories,
73-
modulePathToContentText,
7472
messageApi,
7573
setAlertErrorMessage,
7674
isActive,
@@ -90,11 +88,7 @@ export const TabContent = React.forwardRef<TabContentRef, TabContentProps>(({
9088
React.useImperativeHandle(ref, () => ({
9189
saveModule: async () => {
9290
if (editorInstance) {
93-
const moduleContentText = await editorInstance.saveModule();
94-
// Update modulePathToContentText.
95-
// modulePathToContentText is passed to Editor.makeCurrent so the active editor will know
96-
// about changes to other modules.
97-
modulePathToContentText[modulePath] = moduleContentText;
91+
await editorInstance.saveModule();
9892
// Mark as saved after successful save
9993
autosave.markAsSaved();
10094
}
@@ -138,23 +132,29 @@ export const TabContent = React.forwardRef<TabContentRef, TabContentProps>(({
138132
}, [isActive]);
139133

140134
/** Called when workspace is created. */
141-
const setupWorkspace = React.useCallback((_modulePath: string, newWorkspace: Blockly.WorkspaceSvg) => {
135+
const setupWorkspace = React.useCallback(async (_modulePath: string, newWorkspace: Blockly.WorkspaceSvg) => {
142136
newWorkspace.addChangeListener(handleBlocksChanged);
143137
classMethodDef.registerToolboxButton(newWorkspace, messageApi);
144138
eventHandler.registerToolboxButton(newWorkspace, messageApi);
145139

140+
// Fetch the module content from storage
141+
const moduleContentText = await storage.fetchFileContentText(modulePath);
142+
146143
const newEditor = new editor.Editor(
147144
newWorkspace,
148145
module,
149146
project,
150147
storage,
151-
modulePathToContentText
148+
moduleContentText
152149
);
153150

151+
// Parse modules after editor is created
152+
await newEditor.makeCurrent(project);
153+
154154
setEditorInstance(newEditor);
155155
newEditor.loadModuleBlocks();
156156
newEditor.updateToolbox(shownPythonToolboxCategories);
157-
}, [module, project, storage, modulePathToContentText, shownPythonToolboxCategories, messageApi, handleBlocksChanged]);
157+
}, [module, project, storage, modulePath, shownPythonToolboxCategories, messageApi, handleBlocksChanged]);
158158

159159
/** Update editor toolbox when categories change. */
160160
React.useEffect(() => {
@@ -171,13 +171,14 @@ export const TabContent = React.forwardRef<TabContentRef, TabContentProps>(({
171171
if (editorInstance && isActive) {
172172
// Set flag to ignore changes during activation
173173
isInitialActivation.current = true;
174-
editorInstance.makeCurrent(project, modulePathToContentText);
175-
// Clear the flag after a brief delay to allow workspace to settle
176-
setTimeout(() => {
177-
isInitialActivation.current = false;
178-
}, 100);
174+
editorInstance.makeCurrent(project).then(() => {
175+
// Clear the flag after a brief delay to allow workspace to settle
176+
setTimeout(() => {
177+
isInitialActivation.current = false;
178+
}, 100);
179+
});
179180
}
180-
}, [isActive, blocklyComponent, editorInstance, project, modulePathToContentText]);
181+
}, [isActive, blocklyComponent, editorInstance, project]);
181182

182183
/** Generate code when regeneration is triggered. */
183184
React.useEffect(() => {

src/reactComponents/Tabs.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ export interface TabsProps {
6262
storage: commonStorage.Storage | null;
6363
theme: string;
6464
shownPythonToolboxCategories: Set<string>;
65-
modulePathToContentText: {[modulePath: string]: string};
6665
messageApi: MessageInstance;
6766
}
6867

@@ -429,7 +428,6 @@ export const Component = React.forwardRef<TabsRef, TabsProps>((props, ref): Reac
429428
storage={props.storage}
430429
theme={props.theme}
431430
shownPythonToolboxCategories={props.shownPythonToolboxCategories}
432-
modulePathToContentText={props.modulePathToContentText}
433431
messageApi={props.messageApi}
434432
setAlertErrorMessage={props.setAlertErrorMessage}
435433
isActive={activeKey === tab.key}

0 commit comments

Comments
 (0)