Проблема с блочными мутаторами. Переподключенные блоки, когда снова открывается меню с блоками - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь создать блок с мутаторами. Но у меня проблема с сохранением подключений. Когда я добавляю блоки AND и OR, и связываю с этим блоки vars. После я закрыл и открыл меню. первый пи c второй пи c

public gnAndOrTest(Blockly: any, _nameBlock: string, _discretePoint: DiscreteIoPoint[], _color: number): boolean {
    Blockly.Blocks[_nameBlock] = {
      init: function () {
        this.setColour(230);
        this.appendValueInput("VAR0").setCheck("Boolean")
          .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
        this.appendStatementInput("DO0").appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
        this.setPreviousStatement(0);
        this.setNextStatement(0);
        this.setMutator(new Blockly.Mutator(["library_stdio_scanf_and", "library_stdio_scanf_or", "controls_if_elseif", "controls_if_else"]));
        this.setTooltip('');
        this.scanAddCount_ = 0
        this._arrBlocks = new Array();
        this.__folder = new Array();
        this.__folder[0] = new Array();
        this.__folder[0].push({
          name: "DO0",
          align: Blockly.ALIGN_RIGHT,
          msg: Blockly.Msg.CONTROLS_REPEAT_INPUT_DO,
          type: 4
        });
      },
      mutationToDom: function () {
        if (this._arrBlocks.length == 0) return null;
        var container = document.createElement("mutation");
        this.scanAddCount_ && container.setAttribute("scanadd", this.scanAddCount_);
        return container
      },
      domToMutation: function (xmlElement) {
        this.scanAddCount_ = parseInt(xmlElement.getAttribute("scanadd"), 10);
        for (var i = 1; i <= this.scanAddCount_; i++)

          this.appendValueInput("VAR" + i)
            .setCheck("Boolean".split(" ")).appendField("")
      },
      /** Выполняется, когда открывается меню мутатора */
      decompose: function (workspace) {
        var decompose;
        var containerBlock = Blockly.Block.obtain(workspace, 'scanf_scanf');
        //var b = a.newBlock('scanf_scanf');
        containerBlock.initSvg();
        if (this._arrBlocks.length) {
          for (var connection = containerBlock.getInput("STACK").connection, e = 0; e < this._arrBlocks.length; e++) {
            if (this._arrBlocks[e] == 0) {
              console.log("creating and");
              // d = a.newBlock("library_stdio_scanf_and");
              var andBlock = Blockly.Block.obtain(workspace, 'library_stdio_scanf_and');
              andBlock.initSvg();
              connection.connect(andBlock.previousConnection);
              connection = andBlock.nextConnection;
            } else if (this._arrBlocks[e] == 1) {
              //d = a.newBlock("library_stdio_scanf_or");
              var orBlock = Blockly.Block.obtain(workspace, 'library_stdio_scanf_or');
              orBlock.initSvg();
              connection.connect(orBlock.previousConnection);
              connection = orBlock.nextConnection;
            } else if (this._arrBlocks[e] == 2) {
              var ifBlock = Blockly.Block.obtain(workspace, 'controls_if_else');
              ifBlock.initSvg();
              connection.connect(ifBlock.previousConnection);
              connection = ifBlock.nextConnection;
              //d = a.newBlock("controls_if_else");
            } else {
              var elseBlock = Blockly.Block.obtain(workspace, 'controls_if_elseif');
              elseBlock.initSvg();
              connection.connect(elseBlock.previousConnection);
              connection = elseBlock.nextConnection;
              //d = a.newBlock("controls_if_elseif");
            }
          }
        }
        console.log('containerBlock', containerBlock)
        return containerBlock
      },
      /** Когда диалог мутатора сохраняет свое содержимое, compose вызывается функция 
       * блока для изменения исходного блока в соответствии с новыми настройками */
      compose: function (containerBlock) {
        for (var i = 0; i < this.__folder.length; i++) {
          console.log('compose' + this.__folder[i])
          var list = this.__folder[i];
          for (var z = 0; z < list.length; z++) {
            var ob = list[z];
            console.log('compose ob' + ob.name)
            this.removeInput(ob.name);
          }

        }
        this.scanAddCount_ = 0;
        this._arrBlocks = [];
        var folder = 0;
        this.__folder = new Array();
        this.__folder[folder] = new Array();
        this._arrBlocks.length = 0;

        var clauseBlock = containerBlock.getInputTargetBlock('STACK');
        var i = 0;
        while (clauseBlock) {
          console.log('compose clauseBlock', clauseBlock.type )
          switch (clauseBlock.type) {
            case 'library_stdio_scanf_and':
              console.log('found and');
              this._arrBlocks.push(0);
              this.scanAddCount_++;
              this.__folder[folder].push({
                name: "VAR" + this.scanAddCount_,
                align: Blockly.ALIGN_RIGHT,
                msg: Blockly.Msg.LOGIC_OPERATION_AND,
                type: 0
              });
              break;
            case "library_stdio_scanf_or":
              this.scanAddCount_++;
              this._arrBlocks.push(1);
              this.__folder[folder].push({
                name: "VAR" + this.scanAddCount_,
                align: Blockly.ALIGN_RIGHT,
                msg: Blockly.Msg.LOGIC_OPERATION_OR,
                type: 1
              });

              break;
            case "controls_if_else":
              this.scanAddCount_++;
              folder++;
              this.__folder[folder] = new Array();
              this._arrBlocks.push(2);
              this.__folder[folder].push({
                name: "VAR" + this.scanAddCount_,
                align: Blockly.ALIGN_LEFT,
                msg: Blockly.Msg.CONTROLS_IF_MSG_ELSE,
                type: 2
              });
              break;
            case "controls_if_elseif":
              this.scanAddCount_++;
              folder++;
              this.__folder[folder] = new Array();
              this._arrBlocks.push(3);
              this.__folder[folder].push({
                name: "VAR" + this.scanAddCount_,
                align: Blockly.ALIGN_LEFT,
                msg: Blockly.Msg.CONTROLS_IF_MSG_ELSEIF,
                type: 3
              });
              break;
            default:
              throw 'Unknown block type.';
          }
          clauseBlock = clauseBlock.nextConnection &&
            clauseBlock.nextConnection.targetBlock();
          i++;

        }
        for (var i = 0; i < this.__folder.length; i++) {
          var list = this.__folder[i];
          for (var z = 0; z < list.length; z++) {
            var ob = list[z];
            console.log('object', ob)
            if (list[z].type != 2) {
              var b = this.appendValueInput(ob.name)
                .setAlign(ob.align)
                .setCheck("Boolean").appendField(ob.msg);
            } else {
              this.appendDummyInput(ob.name).setAlign(ob.align).appendField(ob.msg);
            }
          }
          list.push({
            name: "DO" + i,
            align: Blockly.ALIGN_RIGHT,
            msg: Blockly.Msg.CONTROLS_REPEAT_INPUT_DO,
            type: 4
          });
          this.appendStatementInput("DO" + i).appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
        }
      },
      /**В идеале composeфункция должна гарантировать, что любые блоки, уже подключенные к исходному блоку, 
       * остаются подключенными к правильным входам, даже если входы переупорядочены */
      saveConnections: function (containerBlock) {
        var clauseBlock = containerBlock.getInputTargetBlock('STACK');
        console.log('saveConnections', clauseBlock);
        var i = 1;
        var w = 1;
        var r = 1;
        var t = 1;
        while (clauseBlock) {
          console.log('saveConnections Type', clauseBlock.type);
          switch (clauseBlock.type) {
            case "library_stdio_scanf_and":
                    var inputIfAnd = this.getInput("VAR" + i);
                        clauseBlock.valueConnection_ = 
                        inputIfAnd && inputIfAnd.connection.targetConnection;
                        console.log('var connect and', inputIfAnd)
                    break;
                case "library_stdio_scanf_or":
                    var ifInputOr = this.getInput("VAR" + i);
                        clauseBlock.valueConnection_ = 
                        ifInputOr && ifInputOr.connection.targetConnection;
                        console.log('var connect or', ifInputOr)
                    break;
                case "controls_if_else":
                    var c = this.getInput("VAR" + i);
                    // a.valueConnection_ = c && c.connection.targetConnection;
                    // a.statementConnection_ = b++;
                    break;
                case "controls_if_elseif":
                    var c = this.getInput("VAR" + i);
                        clauseBlock.valueConnection_ = c && c.connection.targetConnection;
                    break;
            default:
              throw 'Unknown block type.';
          }
          clauseBlock = clauseBlock.nextConnection &&
            clauseBlock.nextConnection.targetBlock();
            i++;
        }
      },
      onchange: Blockly.Blocks.requireInFunction
    };

Я попытался отобразить все соединения и сохранить их в консоли. Я думаю, что все шло хорошо. Но после того, как поток пошел в библиотеку, было трудно понять, в чем проблема. Почему переподключенные блоки? Может быть, кто-нибудь может мне помочь. Пожалуйста.

...