1.0.1 • Published 9 months ago

longto-block v1.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

SCRATCH-BLOCK

前置知识

在blockly里面,一个基本的block的构成,包括下面三个部分:

  1. block定义

    // 如下定义了一个motion_stop的block
    Blockly.defineBlocksWithJsonArray([{
     type: 'motion_stop',
     lastDummyAlign0: 'RIGHT',
     message0: '停止',
     previousStatement: null,
     colour: COLOR.MOTION,
     tooltip: '停止一切动作',
     helpUrl: '',
     }])
  2. 注册到toolbox

    Blockly.inject('blockHTML', {
     toolbox: {
       "type": "block",
       "type": "motion_stop"
     },
    })
  3. 编写对应的代码生成规则

    // jsonGenerator为我们自定义的json代码生成器
    jsonGenerator['motion_stop'] = function () {
       const code = {
       cmd: 'stop',
       token: 'token'
       }
       return JSON.stringify(code)
    }

Block组件文件结构

📦Blockly

┣ 📂blocks 所有的block定义

┃ ┣ 📜condition.ts 情况类型的block的定义

┃ ┣ 📜controls.ts 控制类型的block定义

┃ ┣ 📜index.ts 所有类型的block,都会通过这个文件导出

┃ ┣ 📜input.ts 输入类型的block定义

┃ ┗ 📜motion.ts 运动类型的blcok定义

┣ 📜constants.ts 该组件内部用到的所有的常量

┣ 📜extensions.ts 所有的block拓展(主要用于自定义验证规则)

┣ 📜index.vue 组件入口

┣ 📜jsonGenerator.ts 所有block对应的代码生成规则

┣ 📜toolbox.json 侧边栏(toolbox)

┣ 📜typing.d.ts 数据类型

┗ 📜utils.ts 工具函数

如何自定义一个block(以前往目标点(motion_goto_goal)为例)

  1. constants.ts定义block名称

    export const BLOCKKIND: { [property: string]: Opcode } = {
      MOTION_GOTO_GOAL: 'motion_goto_goal',
    }
  2. 在blocks文件夹里面,定义相关的block

    // motion.ts
    import { COLOR } from '../constants';
    import { BLOCKKIND } from '../constants';
    
     export default [
       {
         type: BLOCKKIND.MOTION_GOTO_GOAL,
         message0: '前往目标点: %1',
         args0: [
           {
             type: 'field_input',
             name: 'target',
             text: ''
           }
         ],
         previousStatement: null,
         nextStatement: null,
         colour: COLOR.MOTION,
         tooltip: '前往某一个目标点',
         helpUrl: ''
       },
     ]
  3. 在jsonGenerator文件里面,定义相关的代码生成规则

     jsonGenerator[BLOCKKIND.MOTION_GOTO_GOAL] = function (block: Blockly.Block) {
       const code: BlockOutput = {
         kind: 'motion',
         opcode: BLOCKKIND.MOTION_GOTO_GOAL,
         id: block.id,
         nextId: block.getNextBlock()?.id || null,
         previousId: block.getPreviousBlock()?.id || null,
         parentId: block.getParent()?.id || null,
         inputs: {},
         mqttTopic: '/robot/action'
         output: {
           cmd: 'goto',
           target: 'goal',
           goal: valueToCode(block, 'target') || ''
         },
         topLevel: !block.getPreviousBlock() && !block.getParent() ? true : false
       }
       return JSON.stringify(code)
     }

输出JSON数据类型

/**
 * * 拖拽block生成的单个JSON。生成的完整的json为:JsonBlockForList[]
 * kind: block分类。所有的block都归属于某一个分类下。
 * opcode: 对应生成当前json的block类型(如motion_stop对应【停止】block)
 * id: 当前对象的唯一标识符
 * nextId: 当前块相邻的下一个块的id
 * previousId: 当前块的前一个块的id
 * parentId: 当前块的父块的id(如,如果当前块为if类型的块,里面包含判断和执行两个块,那么if块就是判断和执行这两个块的父块)。该属性已移除。
 * inputs?.condition:if块的判断块的id。可选。
 * inputs?.doStack: if块的判断为真,需要执行的块的集合。数组形式,每一项为一个id
 * inputs?.elseStack: if块的判断为假,执行的块。数组形式,每一个项都为一个id
 * output: 发送给mqtt的数据
 * mqttTopic: mqtt 发送消息的时候的topic
 * isTopLevel: 当前块是否为最顶层的块。当前版本只有一个根节点,对应isTopLevel只有一个为true,其他的都为false
*/
export type JsonBlockForList = {
  kind: 'motion' | 'controls' | 'condition' | 'status' | 'message'
  opcode: OpcodeForEmbed
  id: string
  nextId: string
  previousId: string
  mqttTopic: string
  // parentId: string | null
  inputs: {
    type?: 'if' | 'repeat' | 'if_else'
    times?: number
    condition?: string
    doStack?: string[]
    elseStack?: string[]
  }
  output: OutputForEmbed | null
  isTopLevel: boolean
}

新增块

一、typing.d.ts

  1. 添加相关的块的输出,如:type xxxOutput
  2. 给OutputForEmbed 添加相关xxxOutput
  3. 给OpcodeForEmbed添加相关的类型,通常为新增的xxxOutput中刨去Output的小写下横线连接的单词。如MotionGotoGoalOutput,对应这个地方的值为motion_goto_goal。
  4. 如果这个值为一个新增的大类,JsonBlockForList添加相关的kind

二、constants.ts

根据实际添加的block,修改COLOR和BLOCKKIND

三、/blocks文件夹下添加需要的block

如:

{
    type: BLOCKKIND.CONTROLS_MAP_BUILD_ON,
    message0: locale.controls_map_build_on.message0,
    previousStatement: null,
    nextStatement: null,
    colour: COLOR.CONTROLS,
    tooltip: locale.controls_map_build_on.tooltip,
    helpUrl: ''
  },
  • type 的BLOCKKIND为第二步增加的constants
  • message0为/locale下增加的中英文翻译
  • colour 的BLOCKKIND为第二步增加的constants
  • tooltip为/locale下增加的中英文翻译

toolbox.ts 添加对应的块

jsonGenerator.ts,编写相应的代码生成