Skip to content

Commit f9cb123

Browse files
authored
Separate the concepts of project and robot. (#143)
* Separate the concepts of project (which is not a module) and a robot, which is a module. Renamed project to robot where appropriate. Renamed module to project where appropriate. * Make the robot's className be "Robot" everywhere, not just in the generated python code. Added userVisibleName to the commonStorage.Project definition. * Fixed a few errors and warnings shown in vscode.
1 parent 4795aaa commit f9cb123

25 files changed

+364
-277
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,3 @@ WARNING! This is not ready for use and is under heavy development of basic featu
1515
1. Mechanisms aren't limited to init
1616
2. Mechanisms aren't limited to only Robot or Mechanism class
1717
3. No way to specify whether an opmode is auto or teleop
18-
4. Since we changed the "Workspace" terminology to "Project", existing Workspaces are no longer supported. They can be deleted via the browser's Developer Tools - Application tab.

public/locales/en/translation.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
2-
"mechanism_delete": "Delete Project",
3-
"mechanism_rename": "Rename Project",
4-
"mechanism_copy": "Copy Project",
5-
"opmode_delete": "Delete Project",
6-
"opmode_rename": "Rename Project",
7-
"opmode_copy": "Copy Project",
2+
"mechanism_delete": "Delete Mechanism",
3+
"mechanism_rename": "Rename Mechanism",
4+
"mechanism_copy": "Copy Mechanism",
5+
"opmode_delete": "Delete OpMode",
6+
"opmode_rename": "Rename OpMode",
7+
"opmode_copy": "Copy OpMode",
88
"project_delete": "Delete Project",
99
"project_rename": "Rename Project",
1010
"project_copy": "Copy Project",
11-
"fail_list_modules": "Failed to load the list of modules.",
11+
"fail_list_projects": "Failed to load the list of projects.",
1212
"mechanism": "Mechanism",
1313
"opmode": "OpMode",
1414
"class_rule_description": "No spaces are allowed in the name. Each word in the name should start with a capital letter.",
@@ -21,4 +21,4 @@
2121
"search": "Search..."
2222

2323
}
24-
}
24+
}

src/App.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ const App: React.FC = (): React.JSX.Element => {
134134

135135
try {
136136
const value = await storage.fetchEntry(SHOWN_TOOLBOX_CATEGORIES_KEY, DEFAULT_TOOLBOX_CATEGORIES_JSON);
137-
const shownCategories: string[] = JSON.parse(value);
138-
setShownPythonToolboxCategories(new Set(shownCategories));
137+
const shownCategories: Set<string> = new Set(JSON.parse(value));
138+
setShownPythonToolboxCategories(shownCategories);
139139
} catch (e) {
140140
console.error(TOOLBOX_FETCH_ERROR_MESSAGE);
141141
console.error(e);
@@ -231,7 +231,7 @@ const App: React.FC = (): React.JSX.Element => {
231231
const createTabItemsFromProject = (projectData: commonStorage.Project): Tabs.TabItem[] => {
232232
const tabs: Tabs.TabItem[] = [
233233
{
234-
key: projectData.modulePath,
234+
key: projectData.robot.modulePath,
235235
title: 'Robot',
236236
type: TabType.ROBOT,
237237
},
@@ -278,6 +278,10 @@ const App: React.FC = (): React.JSX.Element => {
278278
initializeBlocks();
279279
}, []);
280280

281+
React.useEffect(() => {
282+
initializeShownPythonToolboxCategories();
283+
}, [storage]);
284+
281285
// Update generator context and load module blocks when current module changes
282286
React.useEffect(() => {
283287
if (generatorContext.current) {
@@ -334,7 +338,7 @@ const App: React.FC = (): React.JSX.Element => {
334338
if (project) {
335339
const tabs = createTabItemsFromProject(project);
336340
setTabItems(tabs);
337-
setActiveTab(project.modulePath);
341+
setActiveTab(project.robot.modulePath);
338342
}
339343
}, [project]);
340344

src/blocks/mrc_call_python_function.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import { getClassData, getAllowedTypesForSetCheck, getOutputCheck } from './util
2828
import { FunctionData, findSuperFunctionData } from './utils/python_json_types';
2929
import * as value from './utils/value';
3030
import * as variable from './utils/variable';
31-
import { Editor } from '../editor/editor';
3231
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
3332
import { createFieldDropdown } from '../fields/FieldDropdown';
3433
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
@@ -224,9 +223,15 @@ export function addInstanceComponentBlocks(
224223
contents: toolboxItems.ContentsType[]) {
225224

226225
const classData = getClassData(componentType);
226+
if (!classData) {
227+
throw new Error('Could not find classData for ' + componentType);
228+
}
227229
const functions = classData.instanceMethods;
228230

229231
const componentClassData = getClassData('component.Component');
232+
if (!componentClassData) {
233+
throw new Error('Could not find classData for component.Component');
234+
}
230235
const componentFunctions = componentClassData.instanceMethods;
231236

232237
for (const functionData of functions) {
@@ -331,8 +336,7 @@ type CallPythonFunctionExtraState = {
331336
*/
332337
actualFunctionName?: string,
333338
/**
334-
* True if this blocks refers to an exported function (for example, from a
335-
* user's Project).
339+
* True if this blocks refers to an exported function (for example, from the Robot).
336340
*/
337341
exportedFunction?: boolean,
338342
/**
@@ -540,7 +544,7 @@ const CALL_PYTHON_FUNCTION = {
540544
case FunctionKind.INSTANCE_COMPONENT: {
541545
// TODO: We need the list of component names for this.mrcComponentClassName so we can
542546
// create a dropdown that has the appropriate component names.
543-
const componentNames = [];
547+
const componentNames: string[] = [];
544548
const componentName = this.getComponentName();
545549
if (!componentNames.includes(componentName)) {
546550
componentNames.push(componentName);
@@ -679,7 +683,7 @@ export const pythonFromBlock = function(
679683
: block.getFieldValue(FIELD_FUNCTION_NAME);
680684
// Generate the correct code depending on the module type.
681685
switch (generator.getModuleType()) {
682-
case commonStorage.MODULE_TYPE_PROJECT:
686+
case commonStorage.MODULE_TYPE_ROBOT:
683687
case commonStorage.MODULE_TYPE_MECHANISM:
684688
code = 'self.';
685689
break;

src/blocks/mrc_get_python_variable.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,7 @@ type GetPythonVariableExtraState = {
228228
*/
229229
actualVariableName?: string,
230230
/**
231-
* True if this blocks refers to an exported variable (for example, from a
232-
* user's Project).
231+
* True if this blocks refers to an exported variable (for example, from the Robot).
233232
*/
234233
exportedVariable?: boolean,
235234
};

src/blocks/mrc_set_python_variable.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@ type SetPythonVariableExtraState = {
178178
*/
179179
actualVariableName?: string,
180180
/**
181-
* True if this blocks refers to an exported variable (for example, from a
182-
* user's Project).
181+
* True if this blocks refers to an exported variable (for example, from the Robot).
183182
*/
184183
exportedVariable?: boolean,
185184
};

src/blocks/utils/external_samples_data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* @author [email protected] (Liz Looney)
2020
*/
2121

22-
import { PythonData, ClassData } from './python_json_types';
22+
import { PythonData } from './python_json_types';
2323
import generatedExternalSamplesData from './generated/external_samples_data.json';
2424

2525
export const externalSamplesData = generatedExternalSamplesData as PythonData;

src/blocks/utils/python.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* @author [email protected] (Liz Looney)
2020
*/
2121

22-
import { PythonData, organizeVarDataByType, VariableGettersAndSetters } from './python_json_types';
22+
import { ClassData, PythonData, organizeVarDataByType, VariableGettersAndSetters } from './python_json_types';
2323
import { robotPyData } from './robotpy_data';
2424
import { externalSamplesData } from './external_samples_data';
2525

src/blocks/utils/python_json_types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ function isSuperFunction(f1: FunctionData, f2: FunctionData): boolean {
123123
return true;
124124
}
125125

126-
export function findSuperFunctionData(functionData: FunctionData, superClassFunctions: FunctionData): FunctionData | null {
126+
export function findSuperFunctionData(functionData: FunctionData, superClassFunctions: FunctionData[]): FunctionData | null {
127127
for (const superClassFunctionData of superClassFunctions) {
128128
if (isSuperFunction(superClassFunctionData, functionData)) {
129129
return superClassFunctionData;

src/editor/editor.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ export class Editor {
4545
private eventsCategory: EventsCategory;
4646
private currentModule: commonStorage.Module | null = null;
4747
private modulePath: string = '';
48-
private projectPath: string = '';
48+
private robotPath: string = '';
4949
private moduleContent: string = '';
50-
private projectContent: string = '';
50+
private robotContent: string = '';
5151
private bindedOnChange: any = null;
5252
private toolbox: Blockly.utils.toolbox.ToolboxDefinition = EMPTY_TOOLBOX;
5353

@@ -73,11 +73,11 @@ export class Editor {
7373

7474
// TODO(lizlooney): As blocks are loaded, determine whether any blocks
7575
// are accessing variable or calling functions thar are defined in another
76-
// blocks file (like a Project) and check whether the variable or function
76+
// blocks file (like the Robot) and check whether the variable or function
7777
// definition has changed. This might happen if the user defines a variable
78-
// or function in the Project, uses the variable or function in the
78+
// or function in the Robot, uses the variable or function in the
7979
// OpMode, and then removes or changes the variable or function in the
80-
// Project.
80+
// Robot.
8181

8282
// TODO(lizlooney): We will need a way to identify which variable or
8383
// function, other than by the variable name or function name, because the
@@ -88,15 +88,15 @@ export class Editor {
8888
// TODO(lizlooney): Look at blocks with type 'mrc_get_python_variable' or
8989
// 'mrc_set_python_variable', and where block.mrcExportedVariable === true.
9090
// Look at block.mrcImportModule and get the exported blocks for that module.
91-
// (It should be the project and we already have the project content.)
91+
// It could be from the Robot (or a Mechanism?) and we already have the Robot content.
9292
// Check whether block.mrcActualVariableName matches any exportedBlock's
9393
// extraState.actualVariableName. If there is no match, put a warning on the
9494
// block.
9595

9696
// TODO(lizlooney): Look at blocks with type 'mrc_call_python_function' and
9797
// where block.mrcExportedFunction === true.
9898
// Look at block.mrcImportModule and get the exported blocks for that module.
99-
// (It should be the project and we already have the project content.)
99+
// It could be from the Robot (or a Mechanism?) and we already have the Robot content.
100100
// Check whether block.mrcActualFunctionName matches any exportedBlock's
101101
// extraState.actualFunctionName. If there is no match, put a warning on the block.
102102
// If there is a match, check whether
@@ -124,21 +124,23 @@ export class Editor {
124124

125125
if (currentModule) {
126126
this.modulePath = currentModule.modulePath;
127-
this.projectPath = commonStorage.makeProjectPath(currentModule.projectName);
127+
this.robotPath = commonStorage.makeRobotPath(currentModule.projectName);
128128
} else {
129129
this.modulePath = '';
130-
this.projectPath = '';
130+
this.robotPath = '';
131131
}
132132
this.moduleContent = '';
133-
this.projectContent = '';
133+
this.robotContent = '';
134134
this.clearBlocklyWorkspace();
135135

136136
if (currentModule) {
137+
// Fetch the content for the current module and the robot.
138+
// TODO: Also fetch the content for the mechanisms?
137139
const promises: {[key: string]: Promise<string>} = {}; // key is module path, value is promise of module content.
138140
promises[this.modulePath] = this.storage.fetchModuleContent(this.modulePath);
139-
if (this.projectPath !== this.modulePath) {
140-
// Also fetch the project module content. It contains exported blocks that can be used.
141-
promises[this.projectPath] = this.storage.fetchModuleContent(this.projectPath)
141+
if (this.robotPath !== this.modulePath) {
142+
// Also fetch the robot module content. It contains components, etc, that can be used.
143+
promises[this.robotPath] = this.storage.fetchModuleContent(this.robotPath)
142144
}
143145

144146
const moduleContents: {[key: string]: string} = {}; // key is module path, value is module content
@@ -148,10 +150,10 @@ export class Editor {
148150
})
149151
);
150152
this.moduleContent = moduleContents[this.modulePath];
151-
if (this.projectPath === this.modulePath) {
152-
this.projectContent = this.moduleContent
153+
if (this.robotPath === this.modulePath) {
154+
this.robotContent = this.moduleContent
153155
} else {
154-
this.projectContent = moduleContents[this.projectPath];
156+
this.robotContent = moduleContents[this.robotPath];
155157
}
156158
this.loadBlocksIntoBlocklyWorkspace();
157159
}
@@ -187,8 +189,8 @@ export class Editor {
187189

188190
public updateToolbox(shownPythonToolboxCategories: Set<string>): void {
189191
if (this.currentModule) {
190-
if (!this.projectContent) {
191-
// The Project content hasn't been fetched yet. Try again in a bit.
192+
if (!this.robotContent) {
193+
// The Robot content hasn't been fetched yet. Try again in a bit.
192194
setTimeout(() => {
193195
this.updateToolbox(shownPythonToolboxCategories)
194196
}, 50);
@@ -229,7 +231,8 @@ export class Editor {
229231

230232
private getComponents(): commonStorage.Component[] {
231233
const components: commonStorage.Component[] = [];
232-
if (this.currentModule?.moduleType === commonStorage.MODULE_TYPE_PROJECT) {
234+
if (this.currentModule?.moduleType === commonStorage.MODULE_TYPE_ROBOT ||
235+
this.currentModule?.moduleType === commonStorage.MODULE_TYPE_MECHANISM) {
233236
// TODO(lizlooney): Fill the components array.
234237
}
235238
return components;

0 commit comments

Comments
 (0)