自定义生成器
你可以使用system.registercanonicalgenerator()注册一个标准生成器。但是,如果你想要标准生成器以外的功能,你可以自定义生成器。 Generator是一个带有若干个函数的接口,所以任何带有这些函数的对象都可以注册为Generator。 更多关于Generator的介绍,详见Generator接口。
// in plugin/my-generator/index.js
import {systemInstance as system} from 'norma-core';
system.registerGenerator({
    name: "generator-name",
    ui: [],
    onInit(e) {
        e.state.positions = [];
    },
    onAddPosition(e) {
        e.state.positions.push(e.position);
    },
    onAddBlockType(e) { /* no-op */ },
    onAddDirection(e) { /* no-op */ },
    onRemovePoistion(e) { /* no-op */ },
    onRemoveBlockType(e) { /* no-op */ },
    onRemoveDirection(e) { /* no-op */ },
    isValidParameter(e) { /* no-op */ },
    generate(e) { /* no-op */ },
    UIHandler(e) { /* no-op */ },
    onExit(e) { /* no-op */ },
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
所有这些函数都接受e。对于onInit、isValidParameter、generate、onExit,e 只包含state 和runtime。对于onAddPosition、onAddBlockType和onAddDirection,e分别包含position、blockType或direction,当然也包含state和runtime。对于onRemovePoistion、onRemoveBlockType 和onRemoveDirection,e 包含state、runtime 和index。
还有三个函数onBlur、onFocus和onItemUsed,它们是可选的。 onBlur、onFocus 将在每次切换生成器时被调用。如果这些函数不存在,它们不会被调用。
注意:remove_last_position、remove_last_direction 和remove_last_blocktype 项会以index 为undefined 调用它们,实际上目前还没有以number为index 的方式调用这些函数,但请注意每次都要小心测试index,以防我们添加这样的方式。
经典生成器和自定义生成器的区别
编写经典生成器和自定义生成器是非常不同的。经典生成器和自定义生成器之间的主要区别:
- 自定义生成器没有
description,只有name和ui,即经典生成器中的description.name和description.usage.optionUsage。 - 自定义生成器没有 
option,你应该编写onInit来初始化你的state。 - 自定义生成器在 
state上没有"positions", "blockTypes" 和 "directions"。如果你愿意,你可以自己使用这些key。请注意,你仍然不能使用以双下划线开头的key。如果onAddPosition、onAddBlockType、onAddDirection、onRemovePoistion、onRemoveBlockType和onRemoveDirection之一失败,你最好使用runtime.logger记录一些信息给用户纠正。使用logger的方式通常是logger.log("error", "Some message");。 - 自定义生成器有 
isValidParameter,它应该返回一个boolean。每次使用物品execute时都会调用它。如果它返回true,execute将继续并调用generate,否则它将停止。你最好使用runtime.logger来记录一些信息给用户纠正。 - 经典生成器在调用
generate后删除所有"positions", "blockTypes" 和 "directions",如果你自己编写"positions", "blockTypes" 和 "directions",你应该自己删除它们。 
norma-core还提供了canonicalGeneratorFactory,如果你用配置经典生成器的参数对象调用它,它会为你创建一个经典生成器。
实际上,system.registerCanonicalGenerator(o)是system.registerGenerator(canonicalGeneratorFactory(o))的简写。