Skip to content

Commit

Permalink
Merge pull request #3 from TurboWarp/return
Browse files Browse the repository at this point in the history
Allow custom blocks to return values - blocks part
  • Loading branch information
GarboMuffin authored Jul 29, 2023
2 parents bd60c63 + 1d71d94 commit 98462bf
Show file tree
Hide file tree
Showing 9 changed files with 392 additions and 4 deletions.
5 changes: 5 additions & 0 deletions blocks_vertical/default_toolbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ goog.require('Blockly.Blocks');
* @fileoverview Provide a default toolbox XML.
*/

/**
* NOTE: This is only used in the scratch-blocks development playground!
* The XML here is overridden by scratch-gui.
*/

Blockly.Blocks.defaultToolbox = '<xml id="toolbox-categories" style="display: none">' +
'<category name="%{BKY_CATEGORY_MOTION}" id="motion" colour="#4C97FF" secondaryColour="#3373CC">' +
'<block type="motion_movesteps" id="motion_movesteps">' +
Expand Down
82 changes: 80 additions & 2 deletions blocks_vertical/procedures.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ goog.require('Blockly.ScratchBlocks.VerticalExtensions');

// Serialization and deserialization.

Blockly.ScratchBlocks.ProcedureUtils.parseReturnMutation = function(xmlElement) {
if (xmlElement.hasAttribute('return')) {
var type = +xmlElement.getAttribute('return');
if (
type === Blockly.PROCEDURES_CALL_TYPE_STATEMENT ||
type === Blockly.PROCEDURES_CALL_TYPE_REPORTER ||
type === Blockly.PROCEDURES_CALL_TYPE_BOOLEAN
) {
return type;
}
}
return Blockly.PROCEDURES_CALL_TYPE_STATEMENT;
};

/**
* Create XML to represent the (non-editable) name and arguments of a procedure
* call block.
Expand All @@ -43,6 +57,9 @@ Blockly.ScratchBlocks.ProcedureUtils.callerMutationToDom = function() {
container.setAttribute('proccode', this.procCode_);
container.setAttribute('argumentids', JSON.stringify(this.argumentIds_));
container.setAttribute('warp', JSON.stringify(this.warp_));
if (this.return_ !== Blockly.PROCEDURES_CALL_TYPE_STATEMENT) {
container.setAttribute('return', this.return_);
}
return container;
};

Expand All @@ -58,6 +75,10 @@ Blockly.ScratchBlocks.ProcedureUtils.callerDomToMutation = function(xmlElement)
JSON.parse(xmlElement.getAttribute('generateshadows'));
this.argumentIds_ = JSON.parse(xmlElement.getAttribute('argumentids'));
this.warp_ = JSON.parse(xmlElement.getAttribute('warp'));
this.return_ = Blockly.ScratchBlocks.ProcedureUtils.parseReturnMutation(xmlElement);
if (this.return_ !== Blockly.PROCEDURES_CALL_TYPE_STATEMENT) {
this.workspace.enableProcedureReturns();
}
this.updateDisplay_();
};

Expand Down Expand Up @@ -138,6 +159,22 @@ Blockly.ScratchBlocks.ProcedureUtils.updateDisplay_ = function() {
this.createAllInputs_(connectionMap);
this.deleteShadows_(connectionMap);

if (!wasRendered && this.getReturn) {
this.setInputsInline(true);
if (this.getReturn() === Blockly.PROCEDURES_CALL_TYPE_STATEMENT) {
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
} else {
if (this.getReturn() === Blockly.PROCEDURES_CALL_TYPE_BOOLEAN) {
this.setOutput(true, null);
this.setOutputShape(Blockly.OUTPUT_SHAPE_HEXAGONAL);
} else {
this.setOutput(true, Blockly.Procedures.ENFORCE_TYPES ? 'Number' : null);
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
}
}
}

this.rendered = wasRendered;
if (wasRendered && !this.isInsertionMarker()) {
this.initSvg();
Expand Down Expand Up @@ -210,6 +247,7 @@ Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_ = function(connectionMap)
});
// Create arguments and labels as appropriate.
var argumentCount = 0;
var hasAnyField = false;
for (var i = 0, component; component = procComponents[i]; i++) {
var labelText;
if (component.substring(0, 1) == '%') {
Expand All @@ -228,11 +266,21 @@ Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_ = function(connectionMap)
}
this.populateArgument_(argumentType, argumentCount, connectionMap, id,
input);
hasAnyField = true;
argumentCount++;
} else {
labelText = component.trim();
}
this.addProcedureLabel_(labelText.replace(/\\%/, '%'));
labelText = labelText.replace(/\\%/, '%');
// don't add empty labels which will just waste space
if (labelText) {
this.addProcedureLabel_(labelText);
hasAnyField = true;
}
}
// Custom reporters will crash editor if they have no fields.
if (!hasAnyField) {
this.addProcedureLabel_(' ');
}
};

Expand Down Expand Up @@ -666,6 +714,14 @@ Blockly.ScratchBlocks.ProcedureUtils.setWarp = function(warp) {
this.warp_ = warp;
};

/**
* @this {BlockSvg}
* @returns {number} Value of the return_ property. See enum in constants.js
*/
Blockly.ScratchBlocks.ProcedureUtils.getReturn = function() {
return this.return_;
};

/**
* Callback to remove a field, only for the declaration block.
* @param {Blockly.Field} field The field being removed.
Expand Down Expand Up @@ -794,11 +850,12 @@ Blockly.Blocks['procedures_call'] = {
*/
init: function() {
this.jsonInit({
"extensions": ["colours_more", "shape_statement", "procedure_call_contextmenu"]
"extensions": ["colours_more", "procedure_call_contextmenu"]
});
this.procCode_ = '';
this.argumentIds_ = [];
this.warp_ = false;
this.return_ = Blockly.PROCEDURES_CALL_TYPE_STATEMENT;
},
// Shared.
getProcCode: Blockly.ScratchBlocks.ProcedureUtils.getProcCode,
Expand All @@ -807,6 +864,7 @@ Blockly.Blocks['procedures_call'] = {
deleteShadows_: Blockly.ScratchBlocks.ProcedureUtils.deleteShadows_,
createAllInputs_: Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_,
updateDisplay_: Blockly.ScratchBlocks.ProcedureUtils.updateDisplay_,
getReturn: Blockly.ScratchBlocks.ProcedureUtils.getReturn,

// Exist on all three blocks, but have different implementations.
mutationToDom: Blockly.ScratchBlocks.ProcedureUtils.callerMutationToDom,
Expand Down Expand Up @@ -969,3 +1027,23 @@ Blockly.Blocks['argument_editor_string_number'] = {
// Exist on declaration and arguments editors, with different implementations.
removeFieldCallback: Blockly.ScratchBlocks.ProcedureUtils.removeArgumentCallback_
};

Blockly.Blocks['procedures_return'] = {
/**
* Point towards drop-down menu.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.PROCEDURES_RETURN,
"args0": [
{
"type": "input_value",
"name": "VALUE"
}
],
"extensions": ["colours_more", "shape_end"]
});
this.workspace.enableProcedureReturns();
}
};
7 changes: 7 additions & 0 deletions blocks_vertical/vertical_extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,13 @@ Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU = {
*/
customContextMenu: function(menuOptions) {
menuOptions.push(Blockly.Procedures.makeEditOption(this));
if (
!this.isInFlyout &&
Blockly.Procedures.USER_CAN_CHANGE_CALL_TYPE &&
this.workspace.procedureReturnsEnabled
) {
menuOptions.push(Blockly.Procedures.makeChangeTypeOption(this));
}
}
};

Expand Down
10 changes: 10 additions & 0 deletions core/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ Blockly.Connection.prototype.connect_ = function(childConnection) {
if (parentConnection == parentBlock.getFirstStatementConnection()) {
isSurroundingC = true;
}

if (Blockly.Events.isEnabled() && !childBlock.isInsertionMarker()) {
childBlock.workspace.procedureReturnsWillChange();
}

// Disconnect any existing parent on the child connection.
if (childConnection.isConnected()) {
// Scratch-specific behaviour:
Expand Down Expand Up @@ -584,10 +589,15 @@ Blockly.Connection.prototype.disconnect = function() {
*/
Blockly.Connection.prototype.disconnectInternal_ = function(parentBlock,
childBlock) {
if (Blockly.Events.isEnabled() && !childBlock.isInsertionMarker()) {
childBlock.workspace.procedureReturnsWillChange();
}

var event;
if (Blockly.Events.isEnabled()) {
event = new Blockly.Events.BlockMove(childBlock);
}

var otherConnection = this.targetConnection;
otherConnection.targetConnection = null;
this.targetConnection = null;
Expand Down
21 changes: 21 additions & 0 deletions core/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,27 @@ Blockly.PROCEDURES_PROTOTYPE_BLOCK_TYPE = 'procedures_prototype';
*/
Blockly.PROCEDURES_CALL_BLOCK_TYPE = 'procedures_call';

/**
* Enum for procedure call statements.
*/
Blockly.PROCEDURES_CALL_TYPE_STATEMENT = 0;

/**
* Enum for procedure call round reporters.
*/
Blockly.PROCEDURES_CALL_TYPE_REPORTER = 1;

/**
* Enum for procedure call booleans.
*/
Blockly.PROCEDURES_CALL_TYPE_BOOLEAN = 2;

/**
* The type of all procedure return blocks.
* @const {string}
*/
Blockly.PROCEDURES_RETURN_BLOCK_TYPE = 'procedures_return';

/**
* ENUM for flyout status button states.
* @const
Expand Down
Loading

0 comments on commit 98462bf

Please sign in to comment.