Eulergraph
    Preparing search index...

    Создание библиотеки

    Для кого: авторы shapes и библиотек Stencil (внутри engine или во внешнем модуле).

    Что получите: два способа создания библиотеки — классы и JSON — с end-to-end примерами.

    Предварительные знания: Архитектура движка, typeName и сериализация cell-классов.


    Библиотеки можно создавать двумя способами:

    • Классы элементов — гибко, parametric, своя логика отрисовки
    • JSON (StencilLibItem) — быстро, на базе CustomCell и существующих прототипов

    libs/yourlib/
    shapes/
    MyShape.ts
    index.ts
    YourLib.ts

    Каждый класс фигуры объявляет static readonly typeName. Подробно: typeName и сериализация cell-классов.

    import { CellParametric } from "@engine/entities/cell/CellParametric"
    import { CellOptions } from "@etypes/Cell"

    export class MyShape extends CellParametric {
    static readonly typeName: string = "MyShape"

    constructor(options?: CellOptions) {
    super({ name: "Мой элемент", ...options })
    }
    }
    import { Library } from "@engine/services/Stencil/libs/Library"
    import * as Shapes from "./shapes"

    export const yourlib = new Library("Имя вашей библиотеки", Object.values(Shapes))

    Внутри engine — экспорт из libs/index.ts; библиотека попадает в registerStandardLibs().

    Во внешнем модуле:

    engine.services.Stencil?.register(yourlib)
    engine.services.Stencil?.loadLibs()

    При Library.register(eulerGraph) каждый shape регистрируется в elementsLib через registerElement.

    Смотрите src/engine/services/Stencil/libs/electric/:

    • ElectricElement — база для электрических элементов
    • Battery.ts — parametric _drawRules, typeName: "Battery"
    • ElectricWire.ts — extends Segment
    • ElectricLib.tsnew Library(..., Object.values(Shapes))

    Для CellParametric:

    export class GaugeShape extends CellParametric {
    static readonly typeName: string = "GaugeShape"

    _drawRules = {
    rect: () => ({
    name: "rect",
    args: [0, 0, this.width, this.height],
    }),
    }

    getParamData() {
    return [
    { name: "radius", label: "Радиус", type: "number", value: 10 },
    ]
    }

    onParamChange(paramName: string, value: number) {
    if (paramName === "radius") {
    this.recalcDrawPaths()
    }
    }
    }

    Изменения param для undo — через engine.services.Editor?.changeCustomParam(param, value), где param — объект ParamData из cell.paramData.


    src/engine/services/Stencil/libsJSON/yourlib.ts:

    import { StencilLib } from "@etypes/StencilItem"

    export const yourlib: StencilLib = {
    name: "Имя вашей библиотеки",
    items: [],
    }
    type StencilLibItem = {
    options: CellOptions | LinkOptions
    name: string
    customParams?: CustomParams
    cellPrototype?: string // typeName базового класса, напр. "CustomCell"
    }

    Эталон: src/engine/services/Stencil/libsJSON/fastening/bolt.ts

    export const bolt: StencilLibItem = {
    name: "Болт ГОСТ 7798-70",
    options: {
    name: "Болт",
    width: 100,
    height: 100,
    },
    cellPrototype: "CustomCell",
    customParams: {
    param: { viewName: "top", diameter: 20 },
    paramData: [
    { type: "select", name: "viewName", label: "Вид", items: [...], value: "top" },
    ],
    },
    }

    Регистрация cell-классов не нужна для JSON-items — используются уже зарегистрированные прототипы (CustomCell, Cell, …).


    Library JsonLibrary
    Элементы Классы (constructors) StencilLibItem[]
    registerElement Да, для каждого shape Нет
    Пример electricLib fastening через JsonLibrary

    registerStandardLibs() регистрирует оба типа из libs/ и libsJSON/.


    • [ ] У каждого класса shape есть уникальный typeName
    • [ ] Shapes зарегистрированы до загрузки сцен с этими className
    • [ ] Library.register + loadLibs вызваны при старте
    • [ ] Roundtrip: new Shape()toJSON()fromJSON() → те же поля
    • [ ] JSON-items с cellPrototype указывают на зарегистрированный typeName

    • Shape без typeNameassertCellTypeName при регистрации
    • loadLibs без register — пустая панель Stencil
    • cellPrototype: "MyShape" для несуществующего typeName — элемент не создаётся