Skip to content

Commit 21c7680

Browse files
committed
Set current version to 0.0.2.
Added privateComponents to module content. We can use this to get the private components from a mechanism without having to use a headless blockly workspace to process the blocks. Added code to upgrade projects to version 0.0.2, which involves updating the mrc_mechanism_component_holder block in the robot and adding privateComponents in module content.
1 parent f0f0bf7 commit 21c7680

File tree

3 files changed

+90
-10
lines changed

3 files changed

+90
-10
lines changed

src/storage/module_content.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,18 @@ export type Event = {
6060
};
6161

6262
function startingBlocksToModuleContentText(
63-
module: storageModule.Module, startingBlocks: { [key: string]: any }): string {
63+
module: storageModule.Module, startingBlocks: {[key: string]: any}): string {
6464
const mechanisms: MechanismInRobot[] = [];
6565
const components: Component[] = [];
66+
const privateComponents: Component[] = [];
6667
const events: Event[] = [];
6768
const methods: Method[] = [];
6869
return makeModuleContentText(
6970
module,
7071
startingBlocks,
7172
mechanisms,
7273
components,
74+
privateComponents,
7375
events,
7476
methods);
7577
}
@@ -125,9 +127,10 @@ export function newOpModeContent(projectName: string, opModeClassName: string):
125127
*/
126128
export function makeModuleContentText(
127129
module: storageModule.Module,
128-
blocks: { [key: string]: any },
130+
blocks: {[key: string]: any},
129131
mechanisms: MechanismInRobot[],
130132
components: Component[],
133+
privateComponents: Component[],
131134
events: Event[],
132135
methods: Method[]): string {
133136
if (!module.moduleId) {
@@ -139,6 +142,7 @@ export function makeModuleContentText(
139142
blocks,
140143
mechanisms,
141144
components,
145+
privateComponents,
142146
events,
143147
methods);
144148
return moduleContent.getModuleContentText();
@@ -151,6 +155,7 @@ export function parseModuleContentText(moduleContentText: string): ModuleContent
151155
!('blocks' in parsedContent) ||
152156
!('mechanisms' in parsedContent) ||
153157
!('components' in parsedContent) ||
158+
!('privateComponents' in parsedContent) ||
154159
!('events' in parsedContent) ||
155160
!('methods' in parsedContent)) {
156161
throw new Error('Module content text is not valid.');
@@ -161,6 +166,7 @@ export function parseModuleContentText(moduleContentText: string): ModuleContent
161166
parsedContent.blocks,
162167
parsedContent.mechanisms,
163168
parsedContent.components,
169+
parsedContent.privateComponents,
164170
parsedContent.events,
165171
parsedContent.methods);
166172
}
@@ -169,9 +175,10 @@ export class ModuleContent {
169175
constructor(
170176
private moduleType: storageModule.ModuleType,
171177
private moduleId: string,
172-
private blocks : { [key: string]: any },
178+
private blocks : {[key: string]: any},
173179
private mechanisms: MechanismInRobot[],
174180
private components: Component[],
181+
private privateComponents: Component[],
175182
private events: Event[],
176183
private methods: Method[]) {
177184
}
@@ -188,10 +195,14 @@ export class ModuleContent {
188195
return this.moduleId;
189196
}
190197

191-
getBlocks(): { [key: string]: any } {
198+
getBlocks(): {[key: string]: any} {
192199
return this.blocks;
193200
}
194201

202+
setBlocks(blocks: {[key: string]: any}): void {
203+
this.blocks = blocks;
204+
}
205+
195206
getMechanisms(): MechanismInRobot[] {
196207
return this.mechanisms;
197208
}
@@ -200,6 +211,10 @@ export class ModuleContent {
200211
return this.components;
201212
}
202213

214+
getPrivateComponents(): Component[] {
215+
return this.privateComponents;
216+
}
217+
203218
getEvents(): Event[] {
204219
return this.events;
205220
}
@@ -252,3 +267,15 @@ export class ModuleContent {
252267
}
253268
}
254269
}
270+
271+
/**
272+
* Add privateComponents field.
273+
* This function should only called when upgrading old projects.
274+
*/
275+
export function addPrivateComponents(moduleContentText: string): string {
276+
const parsedContent = JSON.parse(moduleContentText);
277+
if (!('privateComponents' in parsedContent)) {
278+
parsedContent.privateComponents = [];
279+
}
280+
return JSON.stringify(parsedContent, null, 2);
281+
}

src/storage/project.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ export type Project = {
3737
};
3838

3939
const NO_VERSION = '0.0.0';
40-
export const CURRENT_VERSION = '0.0.1';
40+
export const CURRENT_VERSION = '0.0.2';
4141

42-
type ProjectInfo = {
42+
export type ProjectInfo = {
4343
version: string,
4444
};
4545

src/storage/upgrade_project.ts

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,13 @@
2020
*/
2121

2222
import * as semver from 'semver';
23+
import * as Blockly from 'blockly/core';
2324

25+
import * as mechanismComponentHolder from '../blocks/mrc_mechanism_component_holder';
2426
import * as commonStorage from './common_storage';
27+
import * as storageModule from './module';
28+
import * as storageModuleContent from './module_content';
29+
import * as storageNames from './names';
2530
import * as storageProject from './project';
2631

2732

@@ -30,12 +35,60 @@ export async function upgradeProjectIfNecessary(
3035
const projectInfo = await storageProject.fetchProjectInfo(storage, projectName);
3136
if (semver.lt(projectInfo.version, storageProject.CURRENT_VERSION)) {
3237
switch (projectInfo.version) {
38+
// @ts-ignore
3339
case '0.0.0':
34-
// Project was saved without a project.info.json file.
35-
// Nothing needs to be done to upgrade to '0.0.1';
36-
projectInfo.version = '0.0.1';
37-
break;
40+
upgradeFrom_000_to_001(storage, projectName, projectInfo)
41+
// Intentional fallthrough
42+
case '0.0.1':
43+
upgradeFrom_001_to_002(storage, projectName, projectInfo);
3844
}
3945
await storageProject.saveProjectInfo(storage, projectName);
4046
}
4147
}
48+
49+
async function upgradeFrom_000_to_001(
50+
_storage: commonStorage.Storage,
51+
_projectName: string,
52+
projectInfo: storageProject.ProjectInfo): Promise<void> {
53+
// Project was saved without a project.info.json file.
54+
// Nothing needs to be done to upgrade to '0.0.1';
55+
projectInfo.version = '0.0.1';
56+
}
57+
58+
async function upgradeFrom_001_to_002(
59+
storage: commonStorage.Storage,
60+
projectName: string,
61+
projectInfo: storageProject.ProjectInfo): Promise<void> {
62+
// Modules were saved without private components.
63+
// The Robot's mrc_mechanism_component_holder block was saved without hidePrivateComponents.
64+
const projectFileNames: string[] = await storage.list(
65+
storageNames.makeProjectDirectoryPath(projectName));
66+
for (const projectFileName of projectFileNames) {
67+
const modulePath = storageNames.makeFilePath(projectName, projectFileName);
68+
let moduleContentText = await storage.fetchFileContentText(modulePath);
69+
70+
// Add private components to the module content.
71+
moduleContentText = storageModuleContent.addPrivateComponents(moduleContentText);
72+
73+
if (storageNames.getModuleType(modulePath) === storageModule.ModuleType.ROBOT) {
74+
// If this module is the robot, hide the private components part of the
75+
// mrc_mechanism_component_holder block.
76+
const moduleContent = storageModuleContent.parseModuleContentText(moduleContentText);
77+
let blocks = moduleContent.getBlocks();
78+
// Create a temporary workspace to upgrade the blocks.
79+
const headlessWorkspace = new Blockly.Workspace();
80+
try {
81+
Blockly.serialization.workspaces.load(blocks, headlessWorkspace);
82+
mechanismComponentHolder.hidePrivateComponents(headlessWorkspace);
83+
blocks = Blockly.serialization.workspaces.save(headlessWorkspace);
84+
} finally {
85+
headlessWorkspace.dispose();
86+
}
87+
moduleContent.setBlocks(blocks);
88+
moduleContentText = moduleContent.getModuleContentText();
89+
}
90+
91+
await storage.saveFile(modulePath, moduleContentText);
92+
}
93+
projectInfo.version = '0.0.2';
94+
}

0 commit comments

Comments
 (0)