feat!: Invalid Blocks (#7958)

* feat: Invalid Blocks

* Rename the new json property from invalid to invalidReasons.

* Merged isValid into isEnabled.

* Minor fixes.

* More minor fixes.

* Reverting some stuff that didn't need to change.

* Addressing PR feedback.

* Update the BlockInfo interface to match State.

* Make BlockChange.disabledReason private.
This commit is contained in:
John Nesky
2024-04-17 19:47:51 -07:00
committed by GitHub
parent 7d8f88a4f1
commit cee7f916bb
26 changed files with 492 additions and 97 deletions

View File

@@ -334,6 +334,11 @@ export type ControlFlowInLoopBlock = Block & ControlFlowInLoopMixin;
interface ControlFlowInLoopMixin extends ControlFlowInLoopMixinType {}
type ControlFlowInLoopMixinType = typeof CONTROL_FLOW_IN_LOOP_CHECK_MIXIN;
/**
* The language-neutral ID for when the reason why a block is disabled is
* because the block is only valid inside of a loop.
*/
const CONTROL_FLOW_NOT_IN_LOOP_DISABLED_REASON = 'CONTROL_FLOW_NOT_IN_LOOP';
/**
* This mixin adds a check to make sure the 'controls_flow_statements' block
* is contained in a loop. Otherwise a warning is added to the block.
@@ -365,7 +370,11 @@ const CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
// Don't change state if:
// * It's at the start of a drag.
// * It's not a move event.
if (!ws.isDragging || ws.isDragging() || e.type !== Events.BLOCK_MOVE) {
if (
!ws.isDragging ||
ws.isDragging() ||
(e.type !== Events.BLOCK_MOVE && e.type !== Events.BLOCK_CREATE)
) {
return;
}
const enabled = !!this.getSurroundLoop();
@@ -376,7 +385,10 @@ const CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
const group = Events.getGroup();
// Makes it so the move and the disable event get undone together.
Events.setGroup(e.group);
this.setEnabled(enabled);
this.setDisabledReason(
!enabled,
CONTROL_FLOW_NOT_IN_LOOP_DISABLED_REASON,
);
Events.setGroup(group);
}
},

View File

@@ -754,7 +754,6 @@ interface CallMixin extends CallMixinType {
defType_: string;
quarkIds_: string[] | null;
quarkConnections_: {[id: string]: Connection};
previousEnabledState_: boolean;
}
type CallMixinType = typeof PROCEDURE_CALL_COMMON;
@@ -764,6 +763,13 @@ type CallExtraState = {
params?: string[];
};
/**
* The language-neutral ID for when the reason why a block is disabled is
* because the block's corresponding procedure definition is disabled.
*/
const DISABLED_PROCEDURE_DEFINITION_DISABLED_REASON =
'DISABLED_PROCEDURE_DEFINITION';
/**
* Common properties for the procedure_callnoreturn and
* procedure_callreturn blocks.
@@ -1124,12 +1130,16 @@ const PROCEDURE_CALL_COMMON = {
);
}
Events.setGroup(event.group);
if (blockChangeEvent.newValue) {
this.previousEnabledState_ = this.isEnabled();
this.setEnabled(false);
} else {
this.setEnabled(this.previousEnabledState_);
}
const valid = def.isEnabled();
this.setDisabledReason(
!valid,
DISABLED_PROCEDURE_DEFINITION_DISABLED_REASON,
);
this.setWarningText(
valid
? null
: Msg['PROCEDURES_CALL_DISABLED_DEF_WARNING'].replace('%1', name),
);
Events.setGroup(oldGroup);
}
}
@@ -1181,7 +1191,6 @@ blocks['procedures_callnoreturn'] = {
this.argumentVarModels_ = [];
this.quarkConnections_ = {};
this.quarkIds_ = null;
this.previousEnabledState_ = true;
},
defType_: 'procedures_defnoreturn',
@@ -1202,7 +1211,6 @@ blocks['procedures_callreturn'] = {
this.argumentVarModels_ = [];
this.quarkConnections_ = {};
this.quarkIds_ = null;
this.previousEnabledState_ = true;
},
defType_: 'procedures_defreturn',
@@ -1219,6 +1227,12 @@ interface IfReturnMixin extends IfReturnMixinType {
}
type IfReturnMixinType = typeof PROCEDURES_IFRETURN;
/**
* The language-neutral ID for when the reason why a block is disabled is
* because the block is only valid inside of a procedure body.
*/
const UNPARENTED_IFRETURN_DISABLED_REASON = 'UNPARENTED_IFRETURN';
const PROCEDURES_IFRETURN = {
/**
* Block for conditionally returning a value from a procedure.
@@ -1279,7 +1293,7 @@ const PROCEDURES_IFRETURN = {
if (
((this.workspace as WorkspaceSvg).isDragging &&
(this.workspace as WorkspaceSvg).isDragging()) ||
e.type !== Events.BLOCK_MOVE
(e.type !== Events.BLOCK_MOVE && e.type !== Events.BLOCK_CREATE)
) {
return; // Don't change state at the start of a drag.
}
@@ -1319,7 +1333,7 @@ const PROCEDURES_IFRETURN = {
const group = Events.getGroup();
// Makes it so the move and the disable event get undone together.
Events.setGroup(e.group);
this.setEnabled(legal);
this.setDisabledReason(!legal, UNPARENTED_IFRETURN_DISABLED_REASON);
Events.setGroup(group);
}
},