custom-command
本文回答:写一条自定义命令分四步——①
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