bartbutenaers / node-red-contrib-blockly

A Node Red node for visual programming a function using Blockly
Apache License 2.0
88 stars 22 forks source link

buffer_set_index block #121

Open cymplecy opened 9 months ago

cymplecy commented 9 months ago

I must have been on drugs when I mainly re-wrote your original code to be this unholy mess

Blockly.JavaScript['buffer_set_index'] = function(block) {
  var   index = Blockly.JavaScript.valueToCode(block, 'INDEX', Blockly.JavaScript.ORDER_ATOMIC) || 1;
  //console.log(index);
  const buffer = Blockly.JavaScript.valueToCode(block, 'BUFFER', Blockly.JavaScript.ORDER_ATOMIC);
  var   value = Blockly.JavaScript.valueToCode(block, 'VALUE', Blockly.JavaScript.ORDER_ATOMIC);

  // Get the data type checks offered by the block that is connected to our VALUE field 
  var targetCheck = block.getInput('VALUE').connection.targetConnection.getCheck();

  // Find the type of value that has been used as input.
  // See https://groups.google.com/g/blockly/c/9fEPSGFarNM
 // Find the type of value that has been used as input.
  // See https://groups.google.com/g/blockly/c/9fEPSGFarNM
  var dataType = null;
  if (targetCheck && Array.isArray(targetCheck) && targetCheck.length === 1) {
     dataType = targetCheck[0];
  }

  if ((dataType === null) || ((dataType == 'String') && (value.charAt(0) == '(') && (value.charAt(value.length - 1) == ')') )) {
    // We assume the input is a variable

    // Let Blockly generate a function 'convertValueToByte' (shared by all buffer_set_index blocks that have a variable as input).
    // Blockly will generate this function once, since all buffer_set_byte blocks will register the same name, thus overwriting each others function...
    var functionName = Blockly.JavaScript.provideFunction_(
      'convertValueToByte',
      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(value) {',
       '  if (isNaN(value)) {',
       '    return value.charCodeAt(0);',
       '  } else {',
       '    if (Buffer.isBuffer(value)) {',
       '      return value[0];',
       '    } else {',
       //JS thinks a single " " is !isNan so we need to treat it as a special case
       '      if (value == " ") {',
       '        return value.charCodeAt(0);',
       '      } else {',
       '        return Math.min(Math.max(value, 0),255);',
       '      }',
       '    }',
       '  }',
       '}']);

    // Call the same function for every buffer_set_byte block
    var code = buffer + '[' + index + ' - 1] = ' + functionName + '(' + value + ');\n';
    return code;
  }

And what's even worse, it turns out that it doesn't cope with a numeric value of 0 !!!!!!!!

I'm going to re-write it based on your previous clear and much simpler code

But not going to rush - I'm going to get it RIGHT this time :)

cymplecy commented 9 months ago

I've decided that I have too many things going on and this is acting as road-block for my MQTT project so I'm just going to do a PR for the simple fix

and change

(value == " ") { to if (value === " ") {

:)