216 lines
7.7 KiB
TypeScript
216 lines
7.7 KiB
TypeScript
/* eslint-disable @typescript-eslint/naming-convention */
|
|
|
|
import { opeParam } from "../../global";
|
|
import { ThemeType } from "../../global/enum";
|
|
import { hdlFile, hdlPath } from "../../hdlFs";
|
|
import { HdlModuleParam, HdlModulePort, HdlModulePortType } from "../../hdlParser/common";
|
|
import { getThemeColorKind } from "./common";
|
|
|
|
|
|
const lightArrowSvgCache: Record<string, string> = {
|
|
'left': '',
|
|
'right': '',
|
|
'left-right': '',
|
|
'left-dot': '',
|
|
'right-dot': ''
|
|
};
|
|
|
|
const darkArrowSvgCache: Record<string, string> = {
|
|
'left': '',
|
|
'right': '',
|
|
'left-right': '',
|
|
'left-dot': '',
|
|
'right-dot': ''
|
|
};
|
|
|
|
|
|
function getArrowSvgString(name: 'left' | 'right' | 'left-right' | 'left-dot' | 'right-dot'): string {
|
|
const themeType = getThemeColorKind();
|
|
const arrowSvgCache = (themeType === ThemeType.Light) ? lightArrowSvgCache: darkArrowSvgCache;
|
|
|
|
let svgString = arrowSvgCache[name];
|
|
if (svgString.length === 0) {
|
|
const iconFile = name + '-arrow.svg';
|
|
const svgDir = hdlPath.join(opeParam.extensionPath, 'images', 'svg');
|
|
const svgPath = hdlPath.join(svgDir, themeType, iconFile);
|
|
const readSvgString = hdlFile.readFile(svgPath);
|
|
if (readSvgString) {
|
|
svgString = readSvgString;
|
|
arrowSvgCache[name] = readSvgString;
|
|
}
|
|
}
|
|
return svgString;
|
|
}
|
|
|
|
/**
|
|
* @description 生成文档化中用于描述一个 module 的简易 diagram
|
|
* @param params
|
|
* @param ports
|
|
* @returns
|
|
*/
|
|
function makeDiagram(params: HdlModuleParam[], ports: HdlModulePort[]): string {
|
|
// make params block
|
|
const diagramParamWrapper = makeDiagramParamWrapper(params);
|
|
|
|
// make ports block
|
|
const diagramPortWrapper = makeDiagramPortWrapper(ports);
|
|
|
|
const diagram = `<div class="diagram-container"><div class="diagram">${diagramParamWrapper}${diagramPortWrapper}</div></div>`;
|
|
return diagram;
|
|
}
|
|
|
|
|
|
function makeDiagramParamWrapper(params: HdlModuleParam[]): string {
|
|
if (params.length === 0) {
|
|
return '';
|
|
}
|
|
let diagramParams = '';
|
|
for (const param of params) {
|
|
let diagramParam = '<div>' + param.name;
|
|
if (param.init && param.init.length > 0) {
|
|
diagramParam += `(${param.init})`;
|
|
}
|
|
diagramParam += '</div>';
|
|
diagramParams += diagramParam;
|
|
}
|
|
const diagramParamWrapper = `<div class="diagram-ports-wrapper"><div style="width: 55px;"></div><div class="diagram-params"><div></div><div align="left">${diagramParams}</div></div></div>`;
|
|
return diagramParamWrapper;
|
|
}
|
|
|
|
|
|
function makeDiagramPortWrapper(ports: HdlModulePort[]): string {
|
|
if (ports.length === 0) {
|
|
return '';
|
|
}
|
|
|
|
const leftPorts = ports.filter(port =>
|
|
port.type === HdlModulePortType.Input ||
|
|
port.type === HdlModulePortType.Inout ||
|
|
port.type === HdlModulePortType.VhdlInput
|
|
);
|
|
const rightPorts = ports.filter(port =>
|
|
port.type === HdlModulePortType.Output ||
|
|
port.type === HdlModulePortType.VhdlOutput
|
|
);
|
|
|
|
const leftDirection = makeLeftDirection(leftPorts);
|
|
const diagramPorts = makeDiagramPorts(leftPorts, rightPorts);
|
|
const rightDirection = makeRightDirection(rightPorts);
|
|
|
|
const diagramPortWrapper = `<div class="diagram-ports-wrapper">${leftDirection}${diagramPorts}${rightDirection}</div>`;
|
|
return diagramPortWrapper;
|
|
}
|
|
|
|
function isValidWidth(portWidth: string | undefined): boolean {
|
|
if (portWidth === undefined || portWidth === '' || portWidth === '1') {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function makePortCaption(port: HdlModulePort, direction: 'left' | 'right'): string {
|
|
if (!isValidWidth(port.width)) {
|
|
return '';
|
|
}
|
|
return `<div class="port-width-${direction}-caption">${port.width}</div>`;
|
|
}
|
|
|
|
function makePortArrow(port: HdlModulePort, direction: 'left' | 'right'): string {
|
|
if (port.type === HdlModulePortType.Inout) {
|
|
return getArrowSvgString('left-right');
|
|
}
|
|
if (direction === 'left') {
|
|
if (port.type === HdlModulePortType.Input || port.type === HdlModulePortType.VhdlInput) {
|
|
if (isValidWidth(port.width)) {
|
|
return getArrowSvgString('right-dot');
|
|
} else {
|
|
return getArrowSvgString('right');
|
|
}
|
|
} else if (port.type === HdlModulePortType.Output || port.type === HdlModulePortType.VhdlOutput) {
|
|
if (isValidWidth(port.width)) {
|
|
return getArrowSvgString('left-dot');
|
|
} else {
|
|
return getArrowSvgString('left');
|
|
}
|
|
}
|
|
} else if (direction === 'right') {
|
|
if (port.type === HdlModulePortType.Input || port.type === HdlModulePortType.VhdlInput) {
|
|
if (isValidWidth(port.width)) {
|
|
return getArrowSvgString('left-dot');
|
|
} else {
|
|
return getArrowSvgString('left');
|
|
}
|
|
} else if (port.type === HdlModulePortType.Output || port.type === HdlModulePortType.VhdlOutput) {
|
|
if (isValidWidth(port.width)) {
|
|
return getArrowSvgString('right-dot');
|
|
} else {
|
|
return getArrowSvgString('right');
|
|
}
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
function makeLeftDirection(leftPorts: HdlModulePort[]): string {
|
|
let leftDirection = '';
|
|
for (const port of leftPorts) {
|
|
const portCaption = makePortCaption(port, 'left');
|
|
const portArrow = makePortArrow(port, 'left');
|
|
const arrow = `<div class="arrow-wrapper">${portCaption}${portArrow}</div>`;
|
|
leftDirection += arrow;
|
|
}
|
|
return `<div class="left-direction">${leftDirection}</div>`;
|
|
}
|
|
|
|
function makePortName(port: HdlModulePort): string {
|
|
let portClass = '';
|
|
if (port.type === HdlModulePortType.Input || port.type === HdlModulePortType.VhdlInput) {
|
|
portClass = 'i-port-name';
|
|
} else if (port.type === HdlModulePortType.Output || port.type === HdlModulePortType.VhdlOutput) {
|
|
portClass = 'o-port-name';
|
|
} else {
|
|
portClass = 'io-port-name';
|
|
}
|
|
return `<div class="${portClass}">${port.name}</div>`;
|
|
}
|
|
|
|
function makeDiagramPorts(leftPorts: HdlModulePort[], rightPorts: HdlModulePort[]): string {
|
|
let leftIndex = 0;
|
|
let rightIndex = 0;
|
|
let diagramePorts = '';
|
|
while (leftIndex < leftPorts.length && rightIndex < rightPorts.length) {
|
|
const leftPortName = makePortName(leftPorts[leftIndex ++]);
|
|
const rightPortName = makePortName(rightPorts[rightIndex ++]);
|
|
const diagramPortItem = `<div class="digrame-port-item">${leftPortName}${rightPortName}</div>`;
|
|
diagramePorts += diagramPortItem;
|
|
}
|
|
while (leftIndex < leftPorts.length) {
|
|
const leftPortName = makePortName(leftPorts[leftIndex ++]);
|
|
const diagramPortItem = `<div class="digrame-port-item">${leftPortName}<div></div></div>`;
|
|
diagramePorts += diagramPortItem;
|
|
}
|
|
while (rightIndex < rightPorts.length) {
|
|
const rightPortName = makePortName(rightPorts[rightIndex ++]);
|
|
const diagramPortItem = `<div class="digrame-port-item"><div></div>${rightPortName}</div>`;
|
|
diagramePorts += diagramPortItem;
|
|
}
|
|
return `<div class="diagram-ports">${diagramePorts}</div>`;
|
|
}
|
|
|
|
function makeRightDirection(rightPorts: HdlModulePort[]): string {
|
|
let rightDirection = '';
|
|
for (const port of rightPorts) {
|
|
const portCaption = makePortCaption(port, 'right');
|
|
let portArrow = makePortArrow(port, 'right');
|
|
portArrow = portArrow.replace('-0.5 -0.5 125 45', '20 -0.5 125 45');
|
|
|
|
const arrow = `<div class="arrow-wrapper">${portCaption}${portArrow}</div>`;
|
|
rightDirection += arrow;
|
|
}
|
|
|
|
return `<div class="right-direction">${rightDirection}</div>`;
|
|
}
|
|
|
|
export {
|
|
makeDiagram
|
|
}; |