/* 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 = { 'left': '', 'right': '', 'left-right': '', 'left-dot': '', 'right-dot': '' }; const darkArrowSvgCache: Record = { '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 = `
${diagramParamWrapper}${diagramPortWrapper}
`; return diagram; } function makeDiagramParamWrapper(params: HdlModuleParam[]): string { if (params.length === 0) { return ''; } let diagramParams = ''; for (const param of params) { let diagramParam = '
' + param.name; if (param.init && param.init.length > 0) { diagramParam += `(${param.init})`; } diagramParam += '
'; diagramParams += diagramParam; } const diagramParamWrapper = `
${diagramParams}
`; 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 = `
${leftDirection}${diagramPorts}${rightDirection}
`; 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 `
${port.width}
`; } 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 = `
${portCaption}${portArrow}
`; leftDirection += arrow; } return `
${leftDirection}
`; } 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 `
${port.name}
`; } 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 = `
${leftPortName}${rightPortName}
`; diagramePorts += diagramPortItem; } while (leftIndex < leftPorts.length) { const leftPortName = makePortName(leftPorts[leftIndex ++]); const diagramPortItem = `
${leftPortName}
`; diagramePorts += diagramPortItem; } while (rightIndex < rightPorts.length) { const rightPortName = makePortName(rightPorts[rightIndex ++]); const diagramPortItem = `
${rightPortName}
`; diagramePorts += diagramPortItem; } return `
${diagramePorts}
`; } 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 = `
${portCaption}${portArrow}
`; rightDirection += arrow; } return `
${rightDirection}
`; } export { makeDiagram };