Skip to content

Commit d972fb9

Browse files
committed
Merge branch 'main' of github.com:wpilibsuite/systemcore-blocks-interface into pr_expansion_hub_components
2 parents 2c0dabc + 485a6a7 commit d972fb9

17 files changed

+551
-352
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,39 @@
11
# This is the class all mechanisms derive from
22

3+
from typing import Callable
4+
35
class Mechanism:
46
def __init__(self):
57
self.hardware = []
8+
# In self.event_handlers, the keys are the event names, the values are a list of handlers.
9+
self.event_handlers = {}
10+
11+
def register_event_handler(self, event_name: str, event_handler: Callable) -> None:
12+
if event_name in self.event_handlers:
13+
self.event_handlers[event_name].append(event_handler)
14+
else:
15+
self.event_handlers[event_name] = [event_handler]
16+
17+
def unregister_event_handler(self, event_name: str, event_handler: Callable) -> None:
18+
if event_name in self.event_handlers:
19+
if event_handler in self.event_handlers[event_name]:
20+
self.event_handlers[event_name].remove(event_handler)
21+
if not self.event_handlers[event_name]:
22+
del self.event_handlers[event_name]
23+
24+
def fire_event(self, event_name: str, *args) -> None:
25+
if event_name in self.event_handlers:
26+
for event_handler in self.event_handlers[event_name]:
27+
event_handler(*args)
28+
629
def start(self) -> None:
730
for hardware in self.hardware:
831
hardware.start()
32+
933
def update(self) -> None:
1034
for hardware in self.hardware:
1135
hardware.update()
36+
1237
def stop(self) -> None:
1338
for hardware in self.hardware:
1439
hardware.stop()

src/App.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
418418
generatorContext.current.setModule(currentModule);
419419
}
420420
if (blocksEditor.current) {
421-
blocksEditor.current.loadModuleBlocks(currentModule);
421+
blocksEditor.current.loadModuleBlocks(currentModule, project);
422422
}
423423
}, [currentModule]);
424424

@@ -436,11 +436,15 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
436436
generatorContext.current.setModule(currentModule);
437437
}
438438

439+
if (blocksEditor.current) {
440+
blocksEditor.current.abandon();
441+
}
439442
blocksEditor.current = new editor.Editor(newWorkspace, generatorContext.current, storage);
443+
blocksEditor.current.makeCurrent();
440444

441445
// Set the current module in the editor after creating it
442446
if (currentModule) {
443-
blocksEditor.current.loadModuleBlocks(currentModule);
447+
blocksEditor.current.loadModuleBlocks(currentModule, project);
444448
}
445449

446450
blocksEditor.current.updateToolbox(shownPythonToolboxCategories);

src/blocks/mrc_call_python_function.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,8 @@ const CALL_PYTHON_FUNCTION = {
465465
}
466466
return components;
467467
},
468-
onLoad: function(this: CallPythonFunctionBlock): void {
469-
// onLoad is called for each CallPythonFunctionBlock when the blocks are loaded in the blockly workspace.
468+
mrcOnLoad: function(this: CallPythonFunctionBlock): void {
469+
// mrcOnLoad is called for each CallPythonFunctionBlock when the blocks are loaded in the blockly workspace.
470470
const warnings: string[] = [];
471471

472472
// If this block is calling a component method, check that the component
@@ -476,8 +476,13 @@ const CALL_PYTHON_FUNCTION = {
476476
// visible warning on it.
477477
if (this.mrcFunctionKind === FunctionKind.INSTANCE_COMPONENT) {
478478
let foundComponent = false;
479-
const components = this.getComponentsFromRobot();
480-
for (const component of components) {
479+
const componentsInScope: commonStorage.Component[] = [];
480+
componentsInScope.push(...this.getComponentsFromRobot());
481+
const editor = Editor.getEditorForBlocklyWorkspace(this.workspace);
482+
if (editor && editor.getCurrentModuleType() === commonStorage.MODULE_TYPE_MECHANISM) {
483+
componentsInScope.push(...editor.getComponentsFromWorkspace());
484+
}
485+
for (const component of componentsInScope) {
481486
if (component.blockId === this.mrcOtherBlockId) {
482487
foundComponent = true;
483488

@@ -495,7 +500,7 @@ const CALL_PYTHON_FUNCTION = {
495500
}
496501
if (indexOfComponentName != -1) {
497502
const componentNameChoices : string[] = [];
498-
components.forEach(component => componentNameChoices.push(component.name));
503+
componentsInScope.forEach(component => componentNameChoices.push(component.name));
499504
titleInput.removeField(FIELD_COMPONENT_NAME);
500505
titleInput.insertFieldAt(indexOfComponentName,
501506
createFieldDropdown(componentNameChoices), FIELD_COMPONENT_NAME);

src/blocks/mrc_class_method_def.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ const CLASS_METHOD_DEF = {
103103
this.updateBlock_();
104104
},
105105
/**
106-
* Returns the state of this block as a JSON serializable object.
107-
*/
106+
* Returns the state of this block as a JSON serializable object.
107+
*/
108108
saveExtraState: function (
109109
this: ClassMethodDefBlock): ClassMethodDefExtraState {
110110
const extraState: ClassMethodDefExtraState = {
@@ -424,8 +424,11 @@ export const pythonFromBlock = function (
424424

425425
let params = block.mrcParameters;
426426
let paramString = "self";
427-
if (block.mrcPythonMethodName == '__init__') {
428-
paramString += generator.getListOfPorts(false);
427+
if (generator.getModuleType() == commonStorage.MODULE_TYPE_MECHANISM && block.mrcPythonMethodName == '__init__') {
428+
const ports: string[] = generator.getComponentPortParameters();
429+
if (ports.length) {
430+
paramString += ', ' + ports.join(', ');
431+
}
429432
}
430433

431434
if (params.length != 0) {

src/blocks/mrc_component.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,13 @@ const COMPONENT = {
140140
getComponent: function (this: ComponentBlock): commonStorage.Component | null {
141141
const componentName = this.getFieldValue(FIELD_NAME);
142142
const componentType = this.getFieldValue(FIELD_TYPE);
143+
const ports: {[port: string]: string} = {};
144+
this.getComponentPorts(ports);
143145
return {
144146
blockId: this.id,
145147
name: componentName,
146148
className: componentType,
149+
ports: ports,
147150
};
148151
},
149152
getNewPort: function (this: ComponentBlock, i: number): string {
@@ -153,14 +156,12 @@ const COMPONENT = {
153156
}
154157
return this.getFieldValue(FIELD_NAME) + extension + '_port';
155158
},
156-
getHardwarePorts: function (this: ComponentBlock, ports: {[key: string]: string}): void {
157-
// Collect the hardware ports for this component block that are needed to generate
158-
// the define_hardware method. (The key is the port, the value is the type.)
159-
if (this.hideParams) {
160-
for (let i = 0; i < this.mrcArgs.length; i++) {
161-
const newPort = this.getNewPort(i);
162-
ports[newPort] = this.mrcArgs[i].type;
163-
}
159+
getComponentPorts: function (this: ComponentBlock, ports: {[key: string]: string}): void {
160+
// Collect the ports for this component block.
161+
for (let i = 0; i < this.mrcArgs.length; i++) {
162+
const newPort = this.getNewPort(i);
163+
// The key is the port, the value is the type.
164+
ports[newPort] = this.mrcArgs[i].type;
164165
}
165166
},
166167
}
@@ -197,7 +198,7 @@ export const pythonFromBlock = function (
197198
return code;
198199
}
199200

200-
export function getAllPossibleComponents(hideParams: boolean): toolboxItems.ContentsType[] {
201+
export function getAllPossibleComponents(moduleType: string): toolboxItems.ContentsType[] {
201202
const contents: toolboxItems.ContentsType[] = [];
202203
// Iterate through all the components subclasses and add definition blocks.
203204
const componentTypes = getSubclassNames('component.Component');
@@ -215,7 +216,7 @@ export function getAllPossibleComponents(hideParams: boolean): toolboxItems.Cont
215216

216217
classData.staticMethods.forEach(staticFunctionData => {
217218
if (staticFunctionData.returnType === componentType) {
218-
contents.push(createComponentBlock(componentName, classData, staticFunctionData, hideParams));
219+
contents.push(createComponentBlock(componentName, classData, staticFunctionData, moduleType));
219220
}
220221
});
221222
});
@@ -224,12 +225,12 @@ export function getAllPossibleComponents(hideParams: boolean): toolboxItems.Cont
224225
}
225226

226227
function createComponentBlock(
227-
componentName: string, classData: ClassData, staticFunctionData: FunctionData, hideParams: boolean): toolboxItems.Block {
228+
componentName: string, classData: ClassData, staticFunctionData: FunctionData, moduleType: string): toolboxItems.Block {
228229
const extraState: ComponentExtraState = {
229230
importModule: classData.moduleName,
230231
staticFunctionName: staticFunctionData.functionName,
231232
params: [],
232-
hideParams: hideParams,
233+
hideParams: (moduleType == commonStorage.MODULE_TYPE_MECHANISM),
233234
};
234235
const fields: {[key: string]: any} = {};
235236
fields[FIELD_NAME] = componentName;
@@ -241,7 +242,7 @@ function createComponentBlock(
241242
'name': argData.name,
242243
'type': argData.type,
243244
});
244-
if (!hideParams) {
245+
if (moduleType == commonStorage.MODULE_TYPE_ROBOT) {
245246
if (argData.type === 'int') {
246247
const portType = getPortTypeForArgument(argData.name);
247248
if (portType) {

src/blocks/mrc_event_handler.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export type EventHandlerBlock = Blockly.Block & EventHandlerMixin & Blockly.Bloc
5353

5454
interface EventHandlerMixin extends EventHandlerMixinType {
5555
mrcPathOfSender: string;
56-
mrcTypeOfSender: SenderType;
56+
mrcSenderType: SenderType;
5757
mrcParameters: Parameter[];
5858
mrcOtherBlockId: string,
5959
}
@@ -63,7 +63,7 @@ type EventHandlerMixinType = typeof EVENT_HANDLER;
6363
/** Extra state for serialising event handler blocks. */
6464
export interface EventHandlerExtraState {
6565
pathOfSender: string;
66-
typeOfSender: SenderType;
66+
senderType: SenderType;
6767
/** The parameters of the event handler. */
6868
params: Parameter[];
6969
/** The id of the mrc_event block that defines the event. */
@@ -95,7 +95,7 @@ const EVENT_HANDLER = {
9595
saveExtraState(this: EventHandlerBlock): EventHandlerExtraState {
9696
const extraState: EventHandlerExtraState = {
9797
pathOfSender: this.mrcPathOfSender,
98-
typeOfSender: this.mrcTypeOfSender,
98+
senderType: this.mrcSenderType,
9999
params: [],
100100
otherBlockId: this.mrcOtherBlockId,
101101
};
@@ -115,7 +115,7 @@ const EVENT_HANDLER = {
115115
*/
116116
loadExtraState(this: EventHandlerBlock, extraState: EventHandlerExtraState): void {
117117
this.mrcPathOfSender = extraState.pathOfSender;
118-
this.mrcTypeOfSender = extraState.typeOfSender;
118+
this.mrcSenderType = extraState.senderType;
119119
this.mrcParameters = [];
120120
this.mrcOtherBlockId = extraState.otherBlockId;
121121

@@ -158,16 +158,16 @@ const EVENT_HANDLER = {
158158
input.removeField(fieldName);
159159
});
160160
},
161-
onLoad: function(this: EventHandlerBlock): void {
162-
// onLoad is called for each EventHandlerBlock when the blocks are loaded in the blockly workspace.
161+
mrcOnLoad: function(this: EventHandlerBlock): void {
162+
// mrcOnLoad is called for each EventHandlerBlock when the blocks are loaded in the blockly workspace.
163163
const warnings: string[] = [];
164164

165165
// If this block is an event handler for a robot event, check that the robot event
166166
// still exists and hasn't been changed.
167167
// If the robot event doesn't exist, put a visible warning on this block.
168168
// If the robot event has changed, update the block if possible or put a
169169
// visible warning on it.
170-
if (this.mrcTypeOfSender === SenderType.ROBOT) {
170+
if (this.mrcSenderType === SenderType.ROBOT) {
171171
let foundRobotEvent = false;
172172
const editor = Editor.getEditorForBlocklyWorkspace(this.workspace);
173173
if (editor) {
@@ -301,7 +301,7 @@ function createRobotEventHandlerBlock(
301301
const extraState: EventHandlerExtraState = {
302302
// TODO(lizlooney): ask Alan what pathOfSender is for.
303303
pathOfSender: '',
304-
typeOfSender: SenderType.ROBOT,
304+
senderType: SenderType.ROBOT,
305305
params: [],
306306
otherBlockId: event.blockId,
307307
};

0 commit comments

Comments
 (0)