Özel prosedür blokları oluşturun

Özel prosedür blokları oluşturmak için şunları yapmanız gerekir:

  1. @blockly/block-shareable-procedures'u yükleyin. eklentisine (kullanım prosedürlerinde açıklandığı gibi) öğrenin.
  2. Genel bakış bölümünde açıklandığı gibi, JSON serileştirme sistemini kullanın. öğrenin.
ziyaret edin.

Çalışma alanına veri modelleri ekleme

Hem prosedür tanımı hem de prosedür arayan engellemeleri bir yedekleme verilerine başvuruda bulunuyor sürecin imzasını tanımlayan model (ad, parametreler ve dönüş). Bu, uygulamanızı tasarlama konusunda daha fazla esneklik sağlar (ör. prosedürlerin tek bir çalışma alanında tanımlanmasına ve başka bir) bakın.

Bu, prosedür veri modellerini çalışma alanına eklemeniz gerektiği anlamına gelir. düzgün şekilde çalışmasını sağlayın. Bunu yapmanın birçok yolu vardır (ör. kullanıcı arayüzleri).

@blockly/block-shareable-procedures, bunu prosedür tanımlama bloklarına sahip olmak, yedek veri modellerini dinamik olarak oluşturur. oluşturulduğundan daha kolay olur. Bunu kendiniz uygulamak için modeli init üzerinde oluşturup destroy ürününde silin.

import {ObservableProcedureModel} from '@blockly/block-shareable-procedures';

Blockly.Blocks['my_procedure_def'] = {
  init: function() {
    this.model = new ObservableProcedureModel('default name');
    this.workspace.getProcedureMap().add(model);
    // etc...
  }

  destroy: function() {
    // (Optionally) Destroy the model when the definition block is deleted.

    // Insertion markers reference the model of the original block.
    if (this.isInsertionMarker()) return;
    this.workpace.getProcedureMap().delete(model.getId());
  }
}

Bloklarla ilgili bilgileri döndür

Prosedür tanımınız ve prosedür çağrı bloklarınızın getProcedureModel, isProcedureDef ve getVarModels yöntemleri. Bunlar, Blockly kodunun prosedür bloklarınız hakkında bilgi almak için kullandığı kancalar.

Blockly.Blocks['my_procedure_def'] = {
  getProcedureModel() {
    return this.model;
  },

  isProcedureDef() {
    return true;
  },

  getVarModels() {
    // If your procedure references variables
    // then you should return those models here.
    return [];
  },
};

Blockly.Blocks['my_procedure_call'] = {
  getProcedureModel() {
    return this.model;
  },

  isProcedureDef() {
    return false;
  },

  getVarModels() {
    // If your procedure references variables
    // then you should return those models here.
    return [];
  },
};

Güncellemelerde yeniden oluşturmayı tetikle

Prosedür tanımınız ve prosedür çağrı bloklarınızın doProcedureUpdate yöntemini çağırın. Bu, veri modellerinin sizi kendilerini yeniden oluşturacak prosedür blokları bulunur.

Blockly.Blocks['my_procedure_def'] = {
  doProcedureUpdate() {
    this.setFieldValue('NAME', this.model.getName());
    this.setFieldValue(
        'PARAMS',
        this.model.getParameters()
            .map((p) => p.getName())
            .join(','));
    this.setFieldValue(
        'RETURN', this.model.getReturnTypes().join(',');
  }
};

Blockly.Blocks['my_procedure_call'] = {
  doProcedureUpdate() {
    // Similar to the def block above...
  }
};

Özel serileştirme ekleme

Prosedür bloklarının serileştirilmesi iki ayrı şey yapmalıdır.

  1. JSON'dan yükleme yaparken bloklarınızın destekler.
  2. Bir prosedür bloğunu kopyalayıp yapıştırırken bloğun serileştirilmesi gerekir. kopyalanabilmesi için prosedür modelinin tüm durumunu değiştirebilirsiniz.

Bu özelliklerin ikisi de saveExtraState ve loadExtraState aracılığıyla işlenir. Özel prosedür bloklarının yalnızca JSON kullanılırken desteklendiğini unutmayın olduğundan, yalnızca JSON serileştirme kancaları tanımlamamız gerekir.

import {
    ObservableProcedureModel,
    ObservableParameterModel,
    isProcedureBlock
} from '@blockly/block-shareable-procedures';

Blockly.Blocks['my_procedure_def'] = {
  // When doFullSerialization is true, we should serialize the full state of
  // the model.
  saveExtraState(doFullSerialization) {
    const state = Object.create(null);
    state['procedureId']: this.model.getId();

    if (doFullSerialization) {
      state['name'] = this.model.getName();
      state['parameters'] = this.model.getParameters().map((p) => {
        return {name: p.getName(), p.getId()};
      });
      state['returnTypes'] = this.model.getReturnTypes();

      // Flag for deserialization.
      state['createNewModel'] = true;
    }

    return state;
  },

  loadExtraState(state) {
    const id = state['procedureId']
    const map = this.workspace.getProcedureMap();

    if (map.has(id) && !state['createNewModel']) {
      // Delete the existing model (created in init).
      map.delete(this.model.getId());
      // Grab a reference to the model we're supposed to reference.
      this.model = map.get(id);
      this.doProcedureUpdate();
      return;
    }

    // There is no existing procedure model (we are likely pasting), so
    // generate it from JSON.
    this.model
        .setName(state['name'])
        .setReturnTypes(state['returnTypes']);
    for (const [i, param] of state['parameters'].entries()) {
      this.model.insertParameter(
          i,
          new ObservableParameterModel(
              this.workspace, param['name'], param['id']));
    }
    this.doProcedureUpdate();
  },
};

Blockly.Blocks['my_procedure_call'] = {
  saveExtraState() {
    return {
      'procedureId': this.model.getId(),
    };
  },

  loadExtraState(state) {
    // Delete our existing model (created in init).
    this.workspace.getProcedureMap().delete(model.getId());
    // Grab a reference to the new model.
    this.model = this.workspace.getProcedureMap()
        .get(state['procedureId']);
    if (this.model) this.doProcedureUpdate();
  },

  // Handle pasting after the procedure definition has been deleted.
  onchange(event) {
    if (event.type === Blockly.Events.BLOCK_CREATE &&
        event.blockId === this.id) {
      if(!this.model) { // Our procedure definition doesn't exist =(
        this.dispose();
      }
    }
  }
};

İsteğe bağlı olarak prosedür modelini değiştirin

Kullanıcılara prosedür modelini değiştirme olanağı da ekleyebilirsiniz. Telefon etme insertParameter, deleteParameter veya setReturnTypes yöntemler yeniden oluşturulması için engellemelerinizi otomatik olarak tetikler (doProcedureUpdate aracılığıyla).

Prosedür modelini değiştirmek için kullanıcı arayüzleri oluşturma seçenekleri arasında mutatörler (ve yerleşik prosedür blokları kullanılır), tıklama işleyicilere sahip resim alanları, tamamen dışarıdadır.

Araç kutusuna blok ekleyin

Blockly'nin yerleşik dinamik prosedür kategorisi, Blockly'nin yerleşik özelliklerine özgüdür. prosedür blokları. Bloklarınıza erişmek için engellemeleri tanımlamanız gerekir. kendi özel dinamik kategorisi ve bunu ekleyin uygulayın.

const proceduresFlyoutCallback = function(workspace) {
  const blockList = [];
  blockList.push({
    'kind': 'block',
    'type': 'my_procedure_def',
  });
  for (const model of
        workspace.getProcedureMap().getProcedures()) {
    blockList.push({
      'kind': 'block',
      'type': 'my_procedure_call',
      'extraState': {
        'procedureId': model.getId(),
      },
    });
  }
  return blockList;
};

myWorkspace.registerToolboxCategoryCallback(
    'MY_PROCEDURES', proceduresFlyoutCallback);