唯杰地图 logo唯杰地图
VJMAP
EN

custom-command

vjcad/references/command/custom-command.md 3.6 KB116 行
原文

本文回答:写一条自定义命令分四步——① class { async main() {...} };② new CommandOptions() 配置;③ CommandRegistry.regist(new CommandDefinition('MYCMD', '描述', MyCommand, options));④ await Engine.editor.executerWithOp('MYCMD') 触发;命令体内必须用撤销分组包裹,并在 finally 中清理预览。

一、最小完整命令

const { CommandRegistry, CommandDefinition, CommandOptions, writeMessage,
        Engine, CircleEnt, message } = vjcad;

class HelloCommand {
  async main() {
    writeMessage('<br/>Hello WebCAD! 这是一个简单的自定义命令。');
    const circle = new CircleEnt([50, 50], 30);
    circle.setDefaults();
    circle.color = 1;
    Engine.addEntities(circle);
    Engine.zoomExtents();
    writeMessage('<br/>已在画布中心创建一个红色圆形。');
  }
}

const options = new CommandOptions();
options.useAutoComplete = true;

CommandRegistry.regist(new CommandDefinition(
  'HELLO',
  '简单示例命令',
  HelloCommand,
  options
));

await Engine.editor.executerWithOp('HELLO');

MCP 参考:vjcad/example/command/01simple.js。

二、批量注册(典型工程做法)

const commands = [
  { name: 'MYINFO',  desc: '显示文档信息', cls: InfoCommand    },
  { name: 'MYCLEAR', desc: '清空画布',    cls: ClearAllCommand },
  { name: 'MYZOOM',  desc: '缩放全图',    cls: ZoomAllCommand  }
];

commands.forEach(cmd => {
  const o = new CommandOptions();
  o.useAutoComplete = true;
  CommandRegistry.regist(new CommandDefinition(cmd.name, cmd.desc, cmd.cls, o));
});

// 查询已注册命令
const infoCmd = CommandRegistry.item('MYINFO');
console.log(infoCmd.name, infoCmd.description);

MCP 参考:vjcad/example/command/02register.js。

CommandRegistry 关键 API(来源 vjcad/doc/command/api-reference.md):

CommandRegistry.regist(definition)        // 注册命令
CommandRegistry.item('MYCMD')             // 查询单个
CommandRegistry.items                     // 所有命令

三、带撤销分组的命令体

class SafeCommand {
  async main() {
    Engine.undoManager.start_undoMark('我的命令');
    try {
      // 1. 取输入
      // 2. 创建/修改实体(每个 Engine.addEntities 已在该 mark 内合并)
    } finally {
      Engine.undoManager.end_undoMark();
      Engine.clearPreview();
    }
  }
}

MCP 参考:vjcad/example/command/03withpreview.js、vjcad/example/command/04statemachine.js。

也可以用快捷形式:

Engine.startUndoRecord('我的命令');
try { ... } finally { Engine.endUndoRecord(); }

MCP 参考:vjcad/doc/command/api-reference.md。

四、在插件里注册

// onActivate(context)
context.registerCommand('MYCMD', '命令描述', MyCommand);

// onDeactivate(context)
context.unregisterCommand('MYCMD');

MCP 参考:vjcad/doc/command/api-reference.md。详见 plugin/context-api。

反例

  • 没 setDefaults() 直接 Engine.addEntities(ent):颜色 / 图层 / 线型 等不会被默认填充。
  • 把 await Engine.editor.executerWithOp('LINE') 写在 await cadView.onLoad() 之前:编辑器还没就绪。
  • 在 main() 体内 throw 了异常但没 finally:撤销组没关、预览图没清。

参考(官方文档 MCP)

  • 文档:vjcad/doc/command/index.md、vjcad/doc/command/api-reference.md
  • 示例:vjcad/example/command/01simple.js、02register.js、03withpreview.js、04statemachine.js