209 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import tt from 'onml/tt.js';
import genSVG from 'onml/gen-svg.js';
import stringify from 'onml/stringify.js';
import water from './water.js';
import bracer from './bracer';
import vline from './vline';
import getX from './get-x';
import vlineStylo from './vline-stylo';
import getLabel from './get-label';
import { globalLookup, globalSetting } from '../global.js';
const defs = ['defs',
['linearGradient', { id: 'valid' },
['stop', { offset: '30%', 'stop-color': 'hsla(100, 100%, 100%, 0)' }],
['stop', { offset: '90%', 'stop-color': 'hsla(100, 100%, 100%, .3)' }]
],
['linearGradient', { id: 'valid&ready' },
['stop', { offset: '30%', 'stop-color': 'hsla(100, 100%, 50%, 0)' }],
['stop', { offset: '90%', 'stop-color': 'hsla(100, 100%, 50%, .5)' }]
],
['linearGradient', { id: 'valid&~ready' },
['stop', { offset: '30%', 'stop-color': 'hsla(50, 100%, 50%, 0)' }],
['stop', { offset: '90%', 'stop-color': 'hsla(50, 100%, 50%, .5)' }]
],
...Object.keys(vlineStylo).map(key => {
const e = vlineStylo[key];
return ['filter', { id: 'neonGlow-' + key, width: 7, x: -3 },
['feGaussianBlur', { stdDeviation: 3, in: 'SourceAlpha', result: 'ablur' }],
['feFlood', { 'flood-color': `hsl(${e.h},100%,${e.l}%)`, result: 'xf' }],
['feComposite', { in: 'xf', in2: 'ablur', operator: 'in' }]
];
})
];
/**
* @param {string} link
* @returns {number}
*/
function getVecRenderModal(link) {
const renderOptions = globalLookup.currentSignalRenderOptions;
if (renderOptions.has(link)) {
const option = renderOptions.get(link);
if (typeof option.renderModal === 'number') {
return option.renderModal;
}
}
return 0;
}
/**
* @description 根据 link 得到对应的 value 渲染模式
* @param {*} link
*/
function addVecRenderItem(link) {
const link2CurrentWires = globalLookup.link2CurrentWires;
const modal = getVecRenderModal(link);
if (modal === 0) {
const signal = link2CurrentWires.get(link);
return {
name: signal.name,
kind: signal.kind,
ref: signal.link
}
} else if (modal === 1) {
return {
name: '',
kind: '',
ref: ''
}
} else {
return {
name: '',
kind: '',
ref: ''
}
}
}
/**
*
* @param {GlobalLookup} desc
* @param {*} pstate
* @returns
*/
function* renderValues(desc, pstate) {
const { width, height, yOffset, yStep, topBarHeight, botBarHeight } = pstate;
// TODO: 对齐参数
const sidebarWidth = 230;
// 根据 currentWiresRenderView 视图渲染
// 此处应该和 render-wave 的相同注释的地方保持逻辑上的一致render-wave.js 约 646 行)
const currentWires = desc.currentWires;
const renderSignals = [];
for (const view of globalLookup.currentWiresRenderView) {
if (view.renderType === 0) {
const realSignal = addVecRenderItem(view.signalInfo.link);
renderSignals.push(realSignal);
} else {
// 如果是组,需要渲染空白的一行
renderSignals.push({
name: '',
kind: '',
ref: ''
});
// 如果没有关闭,把所有子节点加入其中
if (view.groupInfo.collapse === false) {
for (const child of view.children) {
const realSignal = addVecRenderItem(view.signalInfo.link);
renderSignals.push(realSignal);
}
}
}
}
const lineHeightExtra = (globalSetting.displaySignalHeight - 30) / 2;
const ilen = height / yStep;
const iskip = (yOffset - lineHeightExtra) / yStep;
const ml = genSVG(width, height - topBarHeight - botBarHeight);
let ifirst = 0;
for (let i = 0; i < ilen; ++ i) {
const lane = renderSignals[i];
if (lane && (lane.name || lane.kind)) {
if (i > iskip) {
break;
}
ifirst = i;
}
}
ml.push(defs);
yield;
const markers = ['g'];
ml.push(markers);
for (let i = 0; i < (iskip + ilen); i++) {
const lane = renderSignals[i + (ifirst | 0)];
if (lane && lane.kind === 'DIZ') {
markers.push(['g', tt(0, Math.round((i - (iskip - ifirst) + 1.18) * yStep))].concat(water(lane, desc, pstate)));
} else if (lane && lane.kind === 'brace') {
markers.push(['g', tt(0, Math.round((i - (iskip - ifirst) + 1.18) * yStep))].concat(bracer(lane, desc, pstate)));
} else if (lane && lane.ref) {
const chango = desc.chango[lane.ref];
if (chango && chango.kind === 'vec') {
// tt: 计算出当前这一行的所有 值 svg 在 Y 方向的偏移
const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + 0.15) * yStep))];
const { wave } = chango;
const jlen = wave.length;
perLane: {
let [tPre, vPre, mPre] = wave[0];
let xPre = getX(pstate, tPre);
const labeler = getLabel(lane);
for (let j = 1; j <= jlen; j++) {
const mark = wave[j];
const [tCur, vCur, mCur] = (mark || [desc.time, 0, 0]);
const xCur = getX(pstate, tCur);
// console.log(mark, vPre, mPre, vCur, mCur);
if (vPre !== undefined || mPre !== undefined) {
if (xPre > width && xCur > width) { // both time stamps to the right
break perLane;
}
if (!((xPre < sidebarWidth) && (xCur < sidebarWidth))) { // both time stamps to the left
const xPreNorm = ((xPre > sidebarWidth) ? xPre : sidebarWidth) | 0;
const xCurNorm = ((xCur < width) ? xCur : width) | 0;
const w = xCurNorm - xPreNorm;
// 宽度太小不画了
if (w > 8) {
const x = Math.round((xPreNorm + xCurNorm) / 2);
// 计算 当前这一个 值 在 X 方向上的偏移
mLane.push(labeler(vPre, mPre, x, w));
}
}
}
xPre = xCur;
vPre = vCur;
mPre = mCur;
}
}
ml.push(mLane);
}
yield;
}
}
// console.log(view);
for (let i = 0; i < renderSignals.length; i++) {
const lane = renderSignals[i];
if (lane && lane.vlines) {
markers.push(...vline(lane, pstate, i));
}
}
yield;
return stringify(ml);
}
export default renderValues;
/* eslint complexity: [1, 55] */