یک فیلد افزونه به Block Factory اضافه کنید

Blockly Developer Tools به شما امکان می دهد بلوک های سفارشی را با استفاده از بلوک ها ایجاد کنید! این برنامه از فیلدهایی که به عنوان افزونه منتشر می شوند، علاوه بر فیلدهایی که با هسته Blockly ارائه می شوند، پشتیبانی می کند. اگر یک فیلد سفارشی ایجاد کرده اید، می توانید با دنبال کردن این راهنما، پشتیبانی از آن را به Block Factory اضافه کنید. قبل از اینکه بتوانید برای آن پشتیبانی اضافه کنید، فیلد سفارشی باید در npm منتشر شود. همچنین باید متعهد شوید که فیلد خود را به روز کنید تا با تغییرات در Blockly همگام باشید، در غیر این صورت ممکن است در آینده لازم باشد آن را از Block Factory حذف کنیم.

توسعه در کارخانه بلوک

کد منبع برای Block Factory در مخزن blockly-samples در پوشه examples/developer-tools قرار دارد.

برای ارسال تغییر در ابزارهای برنامه‌نویس در نمونه‌های بلوکی، باید مراحل معمولی را برای توسعه در نمونه‌های بلوکی دنبال کنید. برخلاف کار با افزونه‌ها، باید npm install مستقیماً از دایرکتوری examples/developer-tools اجرا کنید، نه در سطح root نمونه‌های بلوکی.

افزونه را نصب کنید

برای اینکه Block Factory فیلد سفارشی شما را در پیش نمایش نشان دهد، باید فیلد سفارشی را نصب کند. فیلد خود را به عنوان یک وابستگی npm از ابزارهای توسعه دهنده اضافه کنید. سپس، آن را ثبت کنید یا هر کار راه اندازی دیگری را که در developer-tools/src/blocks/index.ts لازم است انجام دهید.

یک بلوک برای فیلد ایجاد کنید

از آنجایی که Block Factory از بلوک‌ها برای ایجاد بلوک‌های سفارشی استفاده می‌کند، به بلوکی نیاز دارید که نمایانگر فیلد سفارشی شما باشد.

تعریف بلوک را ایجاد کنید

شما باید بلوک را برای رشته خود طراحی کنید. اگر می خواهید متا دریافت کنید، حتی می توانید آن را با استفاده از Block Factory طراحی کنید! بلوک باید به کاربر اجازه دهد تا تنظیمات مورد نیاز فیلد شما، مانند مقادیر پیش‌فرض و یک نام را پیکربندی کند. این تعریف بلوک را به developer-tools/src/blocks/fields.ts اضافه کنید و آن را در developer-tools/src/blocks/index.ts وارد کنید.

بلوک را به جعبه ابزار اضافه کنید

در مرحله بعد، باید این بلوک را به تعریف جعبه ابزار اضافه کنید تا برای کاربران قابل دسترسی باشد. تعریف جعبه ابزار در developer-tools/src/toolbox.ts قرار دارد. بلوک شما باید به دسته "فیلدها" اضافه شود.

مولدهای کد

Block Factory با استفاده از سیستم Code Generator که قبلاً از Blockly با آن آشنا هستید کار می کند. هر بلوک برای هر نوع خروجی تولید شده توسط Block Factory یک مولد کد بلوک دارد و بلوک های والد کد بلوک های فرزند را در خروجی صحیح جمع می کنند. برای افزودن پشتیبانی برای یک فیلد سفارشی، باید توابع تولید کننده کد بلوک را برای هر یک از کلاس های Code Generator اضافه کنید.

یک فایل برای بلوک فیلد خود در دایرکتوری output-generators/fields ایجاد کنید. شما مولدهای بلوک کد را برای هر یک از ژنراتورهای زیر به این فایل اضافه خواهید کرد. این فایل را در فایل blocks/index.ts وارد کنید تا توابع تولید کننده کد بلوک در برنامه بارگذاری شوند.

تعریف جاوا اسکریپت

javascriptDefinitionGenerator کدی را ایجاد می کند که در تعریف جاوا اسکریپت برای بلوکی که شامل فیلد سفارشی شما می شود، قرار می گیرد. معمولاً، این بدان معناست که تولیدکننده کد بلوک باید خطی از کد را برگرداند که شبیه به .appendField(new YourFieldConstructor(arg1, arg2), 'userSpecifiedName') . توجه داشته باشید که این خط کد شامل نقطه ویرگول نمی شود، زیرا ورودی که حاوی چندین فیلد است، چندین فراخوانی برای appendField خواهد داشت که با هم زنجیر شده اند. آرگومان های سازنده از مقادیری که کاربر در بلوک فیلد تنظیم کرده است، استخراج می شود. در اینجا نمونه ای از این مولد کد بلوک برای FieldAngle آمده است:

javascriptDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JavascriptDefinitionGenerator,
): string {
  const name = generator.quote_(block.getFieldValue('FIELDNAME'));
  const angle = block.getFieldValue('ANGLE');
  return `.appendField(new FieldAngle(${angle}), ${name})`;
};

بلوک زاویه ای که کاربر از دسته "Fields" جعبه ابزار Block Factory کشیده است، دارای دو فیلد روی آن است:

  • FIELDNAME : کاربر می تواند نام فیلد را در بلوک سفارشی خود تنظیم کند
  • ANGLE : کاربر می تواند مقدار زاویه پیش فرض را تنظیم کند

در این مولد کد بلوک، مقدار زاویه پیش فرض را دریافت کرده و آن را به عنوان تنها آرگومان به سازنده FieldAngle ارسال می کنیم. نام فیلد همیشه به عنوان آرگومان دوم به appendField ارسال می شود.

تعریف JSON

jsonDefinitionGenerator مشابه است، اما بخشی از تعریف بلوک JSON را که با فیلد شما مطابقت دارد، خروجی می دهد. به طور معمول، این کد یک شی JSON است که شامل موارد زیر است:

  • type : مربوط به نام فیلد شما در رجیستری فیلد Blockly است
  • name : کاربر می تواند نام فیلد را در بلوک سفارشی خود تنظیم کند
  • هر ویژگی سفارشی دیگری که توسط روش مقداردهی اولیه json فیلد شما مورد نیاز است.

در اینجا یک مثال از FieldAngle دوباره آورده شده است:

jsonDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JsonDefinitionGenerator,
): string {
  const code = {
    type: 'field_angle',
    name: block.getFieldValue('FIELDNAME'),
    angle: block.getFieldValue('ANGLE'),
  };
  return JSON.stringify(code);
};

سرصفحه های کد

Code Header Generator خروجی Code Header نشان داده شده در Block Factory را ایجاد می کند. این خروجی را می‌توان بین واردات esmodule و برچسب‌های اسکریپت جابه‌جا کرد، بسته به اینکه کاربر چگونه می‌خواهد کد را بارگیری کند، بنابراین در واقع دو نمونه تولیدکننده مختلف وجود دارد: یکی برای هر مورد. شما باید برای هر یک از آنها یک تولید کننده کد بلوک اضافه کنید. در اینجا یک مثال برای FieldAngle آورده شده است:

importHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `import {registerFieldAngle, FieldAngle} from '@blockly/field-angle';`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

scriptHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `<script src="https://unpkg.com/@blockly/field-angle"></script>`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

این ژنراتورها متدی به نام addHeaderLine دارند که به شما امکان می دهد خط کدی را مشخص کنید که باید قبل از استفاده از فیلد شما در کد فراخوانی شود. معمولاً، این شامل کارهایی مانند وارد کردن فیلد یا بارگیری آن از طریق یک تگ اسکریپت و شاید فراخوانی تابعی است که فیلد را در رجیستری فیلد Blockly ثبت می کند.

برای این دو مولد کد بلوک، تمام کدها باید از طریق فراخوانی به addHeaderLine اضافه شوند. این تابع تضمین می کند که هر خط سرصفحه فقط یک بار نشان داده می شود، حتی اگر بلوک فیلد سفارشی شما چندین بار در یک بلوک سفارشی استفاده شود. مولد بلاک کد باید رشته خالی را برگرداند.

خرد ژنراتور

در نهایت، ما ژنراتوری را داریم که خرد ژنراتور را برای فیلد ایجاد می کند. در این مولد کد بلوک، شما کدی را می نویسید که کدی را تولید می کند که به کاربر کمک می کند کدی را بنویسد که کد تولید می کند. هنوز گیج شده اید؟ ساده تر از آن چیزی است که به نظر می رسد!

خرد مولد برای یک بلوک سفارشی شامل یک متغیر از پیش ساخته شده است که هر فیلد روی بلوک را نشان می دهد. سپس یک TODO وجود دارد که کاربر باید تمام این متغیرها را در رشته کد نهایی جمع‌آوری کند که بلوک سفارشی او برمی‌گردد. این بدان معناست که معمولاً تنها کاری که مولد کد بلاک شما باید انجام دهد این است که خطی را که این متغیر سفارشی را ایجاد می کند، برگرداند. بگویید کاربر در حال ساخت یک بلوک سفارشی است که پرتوهای نور خورشید را به بوم خود اضافه می کند. آنها یک فیلد زاویه ای به بلوک اضافه می کنند و نام آن را "SUN_DIRECTION" گذارند. خرد مولد برای این بلوک شامل خط const angle_sun_direction = block.getFieldValue("SUN_DIRECTION"); . این خط کدی است که مولد کد بلوک ما برای فیلد زاویه باید برگرداند:

generatorStubGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: GeneratorStubGenerator,
): string {
  const name = block.getFieldValue('FIELDNAME');
  const fieldVar = generator.createVariableName('angle', name);
  return `const ${fieldVar} = block.getFieldValue(${generator.quote_(
    name,
  )});\n`;
};

برای دریافت یک نام استاندارد برای متغیر، می‌توانید generator.createVariableName فراخوانی کنید و نوع فیلد خود (مانند angle ، number و غیره) را به همراه آنچه کاربر فیلد خود را نامگذاری کرده است، ارسال کنید.

تستش کن

بعد از اینکه همه این قطعات را نوشتید، باید بتوانید با اجرای npm start در فهرست blockly-samples/examples/developer-tools Block Factory را راه اندازی کنید. باید بتوانید بلوک خود را از دسته فیلد بکشید، آن را به ورودی یک بلوک اضافه کنید و تغییرات خروجی را تماشا کنید. بررسی کنید که پیش‌نمایش بلوک درست به نظر می‌رسد و کد هر یک از بخش‌های خروجی درست است.