কাস্টম পদ্ধতি ব্লক তৈরি করা

কাস্টম পদ্ধতি ব্লক তৈরি করার জন্য আপনার প্রয়োজন:

  1. @blockly/block-shareable-procedures প্লাগইনটি ইনস্টল করুন, যেমনটি ব্যবহার পদ্ধতি পৃষ্ঠায় বর্ণিত আছে।
  2. JSON সিরিয়ালাইজেশন সিস্টেম ব্যবহার করুন, যেমন ওভারভিউ পৃষ্ঠায় ব্যাখ্যা করা হয়েছে।

কর্মক্ষেত্রে ডেটা মডেল যোগ করুন

পদ্ধতির সংজ্ঞা এবং পদ্ধতি কলার ব্লক উভয়ই একটি ব্যাকিং ডেটা মডেল উল্লেখ করে যা পদ্ধতির স্বাক্ষর (নাম, পরামিতি এবং রিটার্ন) সংজ্ঞায়িত করে। এটি আপনি কীভাবে আপনার অ্যাপ্লিকেশন ডিজাইন করেন তাতে আরও নমনীয়তা সক্ষম করে (যেমন আপনি পদ্ধতিগুলিকে একটি কর্মক্ষেত্রে সংজ্ঞায়িত করার অনুমতি দিতে পারেন এবং অন্যটিতে উল্লেখ করতে পারেন)।

এর মানে হল যে আপনার ব্লকগুলি কাজ করার জন্য আপনাকে কর্মক্ষেত্রে পদ্ধতি ডেটা মডেলগুলি যোগ করতে হবে। আপনি এটি করতে পারেন এমন অনেক উপায় রয়েছে (যেমন কাস্টম UI)।

@blockly/block-shareable-প্রক্রিয়া -সংজ্ঞা ব্লক থাকার মাধ্যমে এটি গতিশীলভাবে তাদের ব্যাকিং ডেটা মডেল তৈরি করে যখন তারা ওয়ার্কস্পেসে ইনস্ট্যান্টিয়েট করা হয়। এটি নিজেই বাস্তবায়ন করার জন্য, আপনি init এ মডেল তৈরি করুন এবং destroy এ এটি মুছুন।

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.
    this.workpace.getProcedureMap().delete(model.getId());
  }
}

ব্লক সম্পর্কে তথ্য ফেরত

আপনার পদ্ধতির সংজ্ঞা এবং পদ্ধতি কল ব্লকগুলিকে getProcedureModel , isProcedureDef , এবং getVarModels পদ্ধতিগুলি বাস্তবায়ন করতে হবে৷ এই হল হুকগুলি ব্লকলি কোড আপনার পদ্ধতি ব্লক সম্পর্কে তথ্য পেতে ব্যবহার করে।

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 [];
  },
};

আপডেটে রিরেন্ডারিং ট্রিগার করুন

আপনার পদ্ধতির সংজ্ঞা এবং পদ্ধতি কল ব্লকগুলিকে doProcedureUpdate পদ্ধতি প্রয়োগ করতে হবে। এটি সেই হুক যা ডেটা মডেল আপনার পদ্ধতি ব্লকগুলিকে নিজেদেরকে পুনরায় রেন্ডার করার জন্য কল করে।

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...
  }
};

কাস্টম সিরিয়ালাইজেশন যোগ করুন

পদ্ধতি ব্লকের জন্য সিরিয়ালাইজেশন দুটি পৃথক জিনিস করতে হবে।

  1. JSON থেকে লোড করার সময় আপনার ব্লকগুলিকে তাদের ব্যাকিং ডেটা মডেলের একটি রেফারেন্স নিতে হবে, কারণ ব্লক এবং মডেলগুলি আলাদাভাবে ক্রমিক করা হয়৷
  2. একটি পদ্ধতি ব্লক কপি এবং পেস্ট করার সময়, ব্লকটিকে তার পদ্ধতির মডেলের সমগ্র অবস্থাকে সিরিয়ালাইজ করতে হবে, যাতে এটি প্রতিলিপি/ডুপ্লিকেট করা যায়।

এই দুটি জিনিসই saveExtraState এবং loadExtraState এর মাধ্যমে পরিচালিত হয়। আবার নোট করুন যে কাস্টম পদ্ধতি ব্লকগুলি শুধুমাত্র JSON সিরিয়ালাইজেশন সিস্টেম ব্যবহার করার সময় সমর্থিত হয়, তাই আমাদের শুধুমাত্র JSON সিরিয়ালাইজেশন হুকগুলিকে সংজ্ঞায়িত করতে হবে।

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

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

      // These properties are only necessary for pasting.
      'name': this.model.getName(),
      'parameters': this.model.getParameters().map((p) => {
        return {name: p.getName(), p.getId()};
      }),
      'returnTypes': this.model.getReturnTypes(),
    };
  },

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

    // Grab a reference to the existing procedure model.
    if (this.model.getId() != id && map.has(id) &&
        (this.isInsertionMarker || this.noBlockHasClaimedModel_(id))) {
      // Delete the 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']);
      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']));
    }
  },

  // We don't want to reference a model that some other procedure definition
  // is already referencing.
  noBlockHasClaimedModel_(procedureId) {
    const model =
      this.workspace.getProcedureMap().get(procedureId);
    return this.workspace.getAllBlocks(false).every(
      (block) =>
        !isProcedureBlock(block) ||
        !block.isProcedureDef() ||
        block.getProcedureModel() !== model);
  },
};

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();
      }
    }
  }
};

ঐচ্ছিকভাবে পদ্ধতির মডেল/স্বাক্ষর পরিবর্তন করুন

আপনি ব্যবহারকারীদের পদ্ধতি মডেল/স্বাক্ষর সংশোধন করার ক্ষমতাও যোগ করতে পারেন। insertParameter , deleteParameter , বা setReturnTypes পদ্ধতিতে কল করা স্বয়ংক্রিয়ভাবে আপনার ব্লকগুলিকে পুনরায় রেন্ডার করতে ট্রিগার করবে ( doProcedureUpdate এর মাধ্যমে)।

পদ্ধতির মডেলটি পরিবর্তন করার জন্য UI তৈরির বিকল্পগুলির মধ্যে রয়েছে মিউটেটর ব্যবহার করা (যা অন্তর্নির্মিত পদ্ধতি ব্লক ব্যবহার করে), ক্লিক হ্যান্ডলার সহ চিত্র ক্ষেত্র, ব্লকলি থেকে সম্পূর্ণ বাহ্যিক কিছু ইত্যাদি।

টুলবক্সে ব্লক যোগ করুন

Blockly এর অন্তর্নির্মিত গতিশীল পদ্ধতি বিভাগ Blockly এর অন্তর্নির্মিত পদ্ধতি ব্লকের জন্য নির্দিষ্ট। তাই আপনার ব্লকগুলি অ্যাক্সেস করতে সক্ষম হওয়ার জন্য, আপনাকে আপনার নিজস্ব কাস্টম ডায়নামিক বিভাগ নির্ধারণ করতে হবে এবং এটি আপনার টুলবক্সে যুক্ত করতে হবে

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);