How to check if Statement input is empty

254 views
Skip to first unread message

algotn

unread,
Jul 6, 2022, 5:43:25 PM7/6/22
to Blockly
Lets say i use the default 'controls_if' block. Where the user is able to mutate the block by adding multiple elseif and a else input for statement blocks.

If i run

let statements = MyJsonGenerator.statementToCode(block, "ELSE")

And I have not added an else input, I get an empty string as the return value.
And if I have added an else input, but not added any statement blocks, I also get an empty string as the return value.

And the problem is that I want to do different things depending the state it is in. Which I haven't found a way to do.

When the workspace is serialized I can see that an extraState.hasElse = true property gets added. But I haven't found a way to access that from the generator. (aside from saving and reading from the saved workspace)

I don't know if it changes anything in this context, but since I generate JSON I have added
myJsonGenerator.scrub_ = function (block: Blockly.Block, code: String, opt_thisOnly: boolean) {
  const nextBlock =
    block.nextConnection && block.nextConnection.targetBlock();
  if (nextBlock && !opt_thisOnly) {
    return code + ',\n' + testSequenceGenerator.blockToCode(nextBlock)
  }
  return code;
};

Mark Friedman

unread,
Jul 6, 2022, 8:22:21 PM7/6/22
to blo...@googlegroups.com
  One approach at answering your question is by looking at the JavaScript generator for the "controls_if" block.  It should give you an idea of what to do, given that it generates different code based on the existence of any "else" or "else if" inputs.  So looking at the generator for the "controls_if" block you can see here where it generates those clauses based on the existence of an input named ELSE and inputs named IFn and DOn for n from 0 to the number of "else if" inputs.  So you see code that looks like the following (with some details elided):

  let n = 0;
  do {
    const conditionCode =
        JavaScript.valueToCode(block, 'IF' + n, JavaScript.ORDER_NONE) ||
        'false';
    let branchCode = JavaScript.statementToCode(block, 'DO' + n);
    ...
    code += (n > 0 ? ' else ' : '') + 'if (' + conditionCode + ') {\n' +
        branchCode + '}';
    n++;
  } while (block.getInput('IF' + n));

  if (block.getInput('ELSE') || JavaScript.STATEMENT_SUFFIX) {
    let branchCode = JavaScript.statementToCode(block, 'ELSE');
    ...
    code += ' else {\n' + branchCode + '}';
  }

  The question that might still remain is how do those ELSE, IFn and DOn inputs get created?  That basically happens in the updateShape_() function of the "controls_if" block type definition (right around here).  That code looks like this:

    for (let i = 1; i <= this.elseifCount_; i++) {
      this.appendValueInput('IF' + i).setCheck('Boolean').appendField(
          Msg['CONTROLS_IF_MSG_ELSEIF']);
      this.appendStatementInput('DO' + i).appendField(
          Msg['CONTROLS_IF_MSG_THEN']);
    }
    if (this.elseCount_) {
      this.appendStatementInput('ELSE').appendField(
          Msg['CONTROLS_IF_MSG_ELSE']);
    }












  From that you can see that the block is keeping track of two relevant properties, namely this.elseCount_ and this.elseifCount_.  And, of course, there is a connection between those properties and properties like the extraState.hasElse = true that you saw in the serialized state.  You can see that connection in the loadExtraState() and saveExtraState() serialization functions (defined here and here):

  saveExtraState: function() {
    if (!this.elseifCount_ && !this.elseCount_) {
      return null;
    }
    const state = Object.create(null);
    if (this.elseifCount_) {
      state['elseIfCount'] = this.elseifCount_;
    }
    if (this.elseCount_) {
      state['hasElse'] = true;
    }
    return state;
  },
   
 loadExtraState: function(state) {
    this.elseifCount_ = state['elseIfCount'] || 0;
    this.elseCount_ = state['hasElse'] ? 1 : 0;
    this.updateShape_();
  },

I hope this helps.

-Mark


--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/f9304c85-f6b6-43e0-a2a5-bcd9849c46ban%40googlegroups.com.

algotn

unread,
Jul 7, 2022, 4:24:02 AM7/7/22
to Blockly
Ahh, yeah. Totally missed block.getInput(<input>), tried it and it works great.
Returns null if it doesn't exist, and an object if it does.
Thanks!
Reply all
Reply to author
Forward
0 new messages