This commit is contained in:
锦恢 2024-03-25 01:36:56 +08:00
parent 8598ba0a78
commit b2e4fb8a8a
9 changed files with 487 additions and 505 deletions

View File

@ -90,112 +90,4 @@ body::-webkit-scrollbar {
a {
color: var(--main-color);
}
.vcd-container {
--right-panel-width: 0px;
width: calc(100% - var(--right-panel-width));
transition: width .3s ease-out;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.vcd-vline {
position: absolute;
}
.vcd-view {
position: absolute;
top: 24px;
bottom: 24px;
}
.vcd-values {
position: absolute;
top: 24px;
bottom: 24px;
}
.wd-waveql {
position: absolute;
top: 24px;
bottom: 24px;
width: 100%;
transition: width .3s ease-out;
}
.vcd-cursor {
position: absolute;
pointer-events: none;
}
.vcd-values text {
font-size: 14px;
text-anchor: middle;
fill: #fff;
}
line.wd-cursor-line {
stroke-dasharray: 12 4;
stroke: var(--main-color);
stroke-width: 1px;
}
line.wd-grid-time {
stroke: #333;
stroke-width: 1px;
}
line.gap {
stroke: #fff;
stroke-dasharray: 4 3;
}
text.wd-grid-time {
text-anchor: middle;
fill: var(--sidebar-item-text);
}
text.wd-cursor-time {
font-size: 20px;
fill: var(--sidebar);
text-anchor: middle;
z-index: 55;
}
rect.wd-cursor-time {
fill: var(--main-color);
}
.wd-progress {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
text.xred {
fill: hsl(0, 100%, 50%);
}
text.zxviolet {
fill: hsl(287, 100%, 67%);
}
text.pc {
text-anchor: start;
}
tspan.pc-addr {
fill: hsl(202 100% 71%);
}
tspan.pc-opcode {
}

View File

@ -1,10 +1,8 @@
<template>
<!-- <VerticalCursor></VerticalCursor> -->
<!-- <TimeScale></TimeScale> -->
<div
class="vcd-render-wrapper"
>
<div class="vcd-render-wrapper" >
</div>
</template>
@ -23,10 +21,8 @@ export default {
// TimeScale
},
setup() {
const cursorX = ref(0);
return {
cursorX,
globalLookup
}
}
@ -43,8 +39,108 @@ export default {
transition: .3s ease-out;
}
.render-canvas {
.vcd-container {
--right-panel-width: 0px;
width: calc(100% - var(--right-panel-width));
transition: width .3s ease-out;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.vcd-vline {
position: absolute;
}
.vcd-view {
position: absolute;
top: 24px;
bottom: 24px;
}
.vcd-values {
position: absolute;
top: 24px;
bottom: 24px;
}
.wd-waveql {
position: absolute;
top: 24px;
bottom: 24px;
width: 100%;
transition: width .3s ease-out;
}
.vcd-cursor {
position: absolute;
pointer-events: none;
}
.vcd-values text {
font-size: 14px;
text-anchor: middle;
fill: #fff;
}
line.wd-cursor-line {
stroke-dasharray: 12 4;
stroke: var(--main-color);
stroke-width: 1px;
}
line.wd-grid-time {
stroke: #333;
stroke-width: 1px;
}
line.gap {
stroke: #fff;
stroke-dasharray: 4 3;
}
text.wd-grid-time {
text-anchor: middle;
fill: var(--sidebar-item-text);
}
text.wd-cursor-time {
font-size: 20px;
fill: var(--sidebar);
text-anchor: middle;
z-index: 55;
}
rect.wd-cursor-time {
fill: var(--main-color);
}
.wd-progress {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
text.xred {
fill: hsl(0, 100%, 50%);
}
text.zxviolet {
fill: hsl(287, 100%, 67%);
}
text.pc {
text-anchor: start;
}
tspan.pc-addr {
fill: hsl(202 100% 71%);
}
</style>

View File

@ -33,12 +33,6 @@ const globalLookup = reactive({
// 初始化时会被定义
render: () => {},
hasHistory: false,
isRO: false,
// 当前展示的波形
view: [],
xScale: 1,
// // 当前视图的左上角的坐标

View File

@ -274,8 +274,6 @@ function makeWaveView(parentElement) {
parentElement.appendChild(container.pstate.container);
container.start(globalLookup);
globalLookup.hasHistory = true;
globalLookup.isRO = true;
globalLookup.updater = () => {
console.log('updater');
};
@ -311,14 +309,9 @@ function makeWaveView(parentElement) {
function toggleRender(signal) {
if (globalLookup.currentWires.has(signal)) {
globalLookup.currentWires.delete(signal);
// removeWaveCanvas(signal);
globalLookup.render();
} else {
// makeWaveSvg(signal);
const lane = { ref: signal.link };
globalLookup.currentWires.add(signal);
globalLookup.view.push(lane);
globalLookup.render();
}
}

View File

@ -1,6 +1,4 @@
'use strict';
const genRenderWavesGL = require('./gen-render-waves-gl.js');
const WebGL2WaveRender = require('./gen-render-waves-gl.js');
const renderCursor = require('./render-cursor.js');
const genResizeHandler = require('./gen-resize-handler.js');
const mTree = require('./mount-tree.js');
@ -50,19 +48,6 @@ const getFullView = desc => {
}
console.error(ero);
throw new Error();
// Object.keys(obj).map(name => {
// const ref = obj[name];
// if (typeof ref === 'object') {
// arr.push(name);
// rec(ref);
// arr.push('..');
// return;
// }
// if (typeof ref !== 'string') {
// throw new Error();
// }
// arr.push(name);
// });
};
rec(desc.wires);
@ -111,12 +96,12 @@ class DomContainer {
const domContainer = (obj) => {
const sidebarWidth = 256;
const fontHeight = 16;
const sidebarWidth = 280;
const fontHeight = 20;
const elo = mTree.createElemento(obj.elemento);
const container = mTree.createContainer(elo, obj.layers);
elo.container.tabIndex = '0';
// elo.container.tabIndex = '0';
const pstate = {
fontHeight,
@ -127,9 +112,9 @@ const domContainer = (obj) => {
topBarHeight: fontHeight * 1.5, // [px]
botBarHeight: fontHeight * 1.5, // [px]
xOffset: sidebarWidth,
yOffset: 0, // [px]
yStep: fontHeight * 1.5, // = 24 // [px] wave lane height
yDuty: 0.7,
yOffset: -40, // [px]
yStep: 54, // = 24 // [px] wave lane height
yDuty: 0.6,
sidebarWidth,
container
};
@ -150,7 +135,7 @@ const domContainer = (obj) => {
tgcd: deso.tgcd,
timescale: deso.timescale,
xScale: deso.xScale || 8,
numLanes: deso.view.length,
numLanes: deso.currentWires.size,
t0: deso.t0,
time: deso.time
});
@ -169,15 +154,12 @@ const domContainer = (obj) => {
setTime(pstate, deso.timeOpt.value);
}
let render2 = genRenderWavesGL(elo);
let render1 = render2(deso);
let render = render1(pstate, obj.renderPlugins);
deso.render = render;
let waveRender = new WebGL2WaveRender(elo, deso, pstate, obj.renderPlugins);
deso.render = waveRender.render.bind(waveRender);
const resizeHandler = genResizeHandler(pstate);
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
// TODO : 使用更新的属性替换 contentRect
// 未来版本 contentRect 可能会被丢弃

View File

@ -4,8 +4,8 @@ const cColors = new Float32Array([
0, 0, 0, 0, // 0:
0, 0, 1, 1, // 1: (Z) high impedance
0, 1, 0, 1, // 2: strong 0
0, 1, 1, 1, // 3: strong 1
0.2, 0.847, 0.1, 1, // 2: strong 0
0.2, 0.847, 0.1, 1, // 3: strong 1
1, 0, 0, 1, // 4: (x X) strong unknown
.5, 1, 1, 1, // 5: vec
@ -69,39 +69,6 @@ void main() {
`);
/**
*
* @param {WebGL2RenderingContext} webgl2
* @returns {{
* colors: WebGLUniformLocation,
* tilts: WebGLUniformLocation,
* scale: WebGLUniformLocation,
* offset: WebGLUniformLocation,
* tilt: WebGLUniformLocation,
* pos: number,
* webgl2: WebGL2RenderingContext
* }}
*/
function initProgram(webgl2) {
const program = webgl2.createProgram();
webgl2.attachShader(program, vertexShaderScalar(webgl2));
webgl2.attachShader(program, fragmentShader(webgl2));
webgl2.linkProgram(program);
webgl2.useProgram(program);
const webglLocation = {
colors: webgl2.getUniformLocation(program, 'colors'),
tilts: webgl2.getUniformLocation(program, 'tilts'),
scale: webgl2.getUniformLocation(program, 'scale'),
offset: webgl2.getUniformLocation(program, 'offset'),
tilt: webgl2.getUniformLocation(program, 'tilt'),
pos: webgl2.getAttribLocation(program, 'pos'),
webgl2
};
return webglLocation;
}
const bar = [
(f, t, a, b, c0, c1) => [].concat( // 0
(f === 1) ? [a, 2, c1] : [],
@ -153,206 +120,6 @@ const brick = [
)
];
const wave2vertex = globalLookup => {
Object.keys(globalLookup.chango).map(ref => {
const chang = globalLookup.chango[ref];
const { kind, wave } = chang;
// globalLookup.view.map(lane => {
// if (!lane || lane.ref === undefined) { return; }
// const chang = globalLookup.chango[lane.ref];
// if (chang === undefined) { return; }
// const {kind, wave} = chang;
// lane.kind = kind;
// lane.wave = wave;
if (kind === 'bit') {
const vertices = [];
const ilen = wave.length;
for (let i = 0; i < ilen; i++) {
const f = wave[(i === 0) ? 0 : (i - 1)];
const [tim, val] = wave[i];
const t = wave[(i === (ilen - 1)) ? i : (i + 1)];
const tt = (i === (ilen - 1)) ? globalLookup.time : wave[i + 1][0];
switch (val) {
case 0: case 1: // 0 1
vertices.push(...bar[val](f[1], t[1], tim, tt, 2, 3));
break;
case 2: case 3: // x X
vertices.push(...bar[2](f[1], t[1], tim, tt, 4, 4));
break;
case 4: case 5: // z Z
vertices.push(...bar[2](f[1], t[1], tim, tt, 1, 1));
break;
case 6: case 7: // u U uninitialized
vertices.push(...bar[2](f[1], t[1], tim, tt, 6, 6));
break;
case 8: case 9: // w W weak unknown
vertices.push(...bar[2](f[1], t[1], tim, tt, 10, 10));
break;
case 10: case 11: // l L
vertices.push(...bar[0](f[1], t[1], tim, tt, 8, 9));
break;
case 12: case 13: // h H
vertices.push(...bar[1](f[1], t[1], tim, tt, 8, 9));
break;
default:
vertices.push(...bar[2](f[1], t[1], tim, tt, 7, 7));
// throw new Error('val is: ' + val);
}
}
chang.vertices = new Uint32Array(vertices); // Uint16Array // 16bit
// lane.vertices = new Uint16Array(vertices);
}
if (kind === 'vec') {
const vertices = [];
const ilen = wave.length;
for (let i = 0; i < ilen; i++) {
// const f = wave[(i === 0) ? 0 : (i - 1)];
const [tim, val, msk] = wave[i];
// const t = wave[(i === (ilen - 1)) ? i : (i + 1)];
const tt = (i === (ilen - 1)) ? globalLookup.time : wave[i + 1][0];
if (val) {
if (msk) {
vertices.push(...brick[2](2, 2, tim, tt, 4, 4)); // x,z?
} else {
// vertices.push(...brick[2](2, 2, tim, tt, 5, 5)); // 2
vertices.push(
tim, 0, 0,
tt, 0, 0, tt, 0, 5, tt, 4, 5,
tim, 6, 5, tim, 0, 5, tim, 3, 5,
tt, 1, 5, tt, 0, 5
);
}
} else {
if (msk) {
vertices.push(...brick[2](2, 2, tim, tt, 4, 4)); // x
} else {
// vertices.push(...brick[0](2, 2, tim, tt, 2, 3)); // 0
vertices.push(tim, 6, 2, tt, 4, 2);
}
}
}
chang.vertices = new Uint32Array(vertices); // Uint16Array // 16bit
// lane.vertices = new Uint16Array(vertices);
}
});
};
/**
*
* @param {{
* colors: WebGLUniformLocation,
* tilts: WebGLUniformLocation,
* scale: WebGLUniformLocation,
* offset: WebGLUniformLocation,
* tilt: WebGLUniformLocation,
* pos: number,
* webgl2: WebGL2RenderingContext
* }} webglLocation
* @param {{
* chango: Record<string, {
* vertices: Uint32Array,
* kind: string,
* wave: Array<number | string>,
* vao: WebGLVertexArrayObject
* }>
* }} globalLookup
*/
function initData(webglLocation, globalLookup) {
for (const id of Reflect.ownKeys(globalLookup.chango)) {
const signalItem = globalLookup.chango[id];
const vertices = signalItem.vertices;
const webgl2 = webglLocation.webgl2;
const vertexBuffer = webgl2.createBuffer();
webgl2.bindBuffer(webgl2.ARRAY_BUFFER, vertexBuffer);
// 将初始化的顶点数据复制到 buffer 区域
webgl2.bufferData(webgl2.ARRAY_BUFFER, vertices, webgl2.STATIC_DRAW);
signalItem.vao = webgl2.createVertexArray();
webgl2.bindVertexArray(signalItem.vao);
webgl2.vertexAttribIPointer(webglLocation.pos, 3, webgl2.UNSIGNED_INT, 0, 0);
webgl2.enableVertexAttribArray(webglLocation.pos);
webgl2.uniform4fv(webglLocation.colors, cColors);
webgl2.uniform2fv(webglLocation.tilts, cTilts);
}
}
const genRenderWavesGL = (els) => {
const canvas = document.createElement('canvas');
els.view.replaceChildren(canvas);
const webgl2 = canvas.getContext('webgl2', {
premultipliedAlpha: false,
alpha: true,
antialias: false,
depth: false
});
const webglLocation = initProgram(webgl2);
return globalLookup => {
wave2vertex(globalLookup);
initData(webglLocation, globalLookup);
return (pstate, plugins) => {
let aReq;
return () => {
if (aReq !== undefined) {
cancelAnimationFrame(aReq);
}
aReq = window.requestAnimationFrame(() => {
const { width, height, xScale, xOffset, yOffset, yStep, yDuty } = pstate;
const cHeight = height - 40; // FIXME 40
// console.log(pstate);
canvas.width = width;
canvas.height = cHeight;
// const xs = pstate.scale;
// const xo = -1;
webgl2.uniform1f(webglLocation.tilt, 3 / width);
webgl2.uniform2f(webglLocation.scale, 2 * xScale / width, yStep * yDuty / cHeight); // FIXME 40
webgl2.viewport(0, 0, width, cHeight);
webgl2.clear(webgl2.COLOR_BUFFER_BIT);
globalLookup.view.map((lane, idx) => {
// console.log(lane, idx);
if (!lane) { // || lane.vertices === undefined) {
return;
}
const ref = lane.ref;
if (ref === undefined) {
return;
}
const chang = globalLookup.chango[ref];
if (chang === undefined) {
return;
}
// console.log(chang);
webgl2.bindVertexArray(chang.vao);
webgl2.uniform2f(webglLocation.offset,
(2 * xOffset / width) - 1,
(2 * yOffset - 2 * yStep * (idx + .7)) / cHeight + 1
);
webgl2.drawArrays(
webgl2.LINE_STRIP, // mode
0, // first
chang.vertices.length / 3 // count
);
});
plugins.map(fn => fn(globalLookup, pstate, els));
aReq = undefined;
});
};
};
};
};
class WebGL2WaveRender {
/**
@ -361,15 +128,268 @@ class WebGL2WaveRender {
* grid: HTMLDivElement,
* view: HTMLDivElement,
* values: HTMLDivElement
* }}} elements
* }} elements
* @param {{
* chango: Record<string, {
* kind: string,
* wave: Array<number | string>,
* vao: WebGLVertexArrayObject
* }>
* view: Array<{ ref: string }>,
* currentWires: Set<{
* kind: string,
* link: string,
* name: string,
* size: number,
* parent: object,
* type: string
* }>,
* time: number
* }} globalLookup
* @param {{
* width: number,
* height: number,
* xScale: number,
* xOffset: number,
* yOffset: number,
* yStep: number,
* yDuty: number
* }} pstate
* @param { Array } plugins
*/
constructor(elements) {
constructor(elements, globalLookup, pstate, plugins) {
const canvas = document.createElement('canvas');
elements.view.replaceChildren(canvas);
this.elements = elements;
this.globalLookup = globalLookup;
this.canvas = canvas;
this.pstate = pstate;
this.plugins = plugins;
const webgl2 = canvas.getContext('webgl2', {
premultipliedAlpha: false,
alpha: true,
antialias: false,
depth: false
});
this.webglLocation = this.initProgram(webgl2);
this.verticesMap = this.makeVertex();
this.initData();
this.animationHandler = undefined;
}
/**
*
* @param {WebGL2RenderingContext} webgl2
* @returns {{
* colors: WebGLUniformLocation,
* tilts: WebGLUniformLocation,
* scale: WebGLUniformLocation,
* offset: WebGLUniformLocation,
* tilt: WebGLUniformLocation,
* pos: number,
* webgl2: WebGL2RenderingContext
* }}
*/
initProgram(webgl2) {
const program = webgl2.createProgram();
webgl2.attachShader(program, vertexShaderScalar(webgl2));
webgl2.attachShader(program, fragmentShader(webgl2));
webgl2.linkProgram(program);
webgl2.useProgram(program);
const webglLocation = {
colors: webgl2.getUniformLocation(program, 'colors'),
tilts: webgl2.getUniformLocation(program, 'tilts'),
scale: webgl2.getUniformLocation(program, 'scale'),
offset: webgl2.getUniformLocation(program, 'offset'),
tilt: webgl2.getUniformLocation(program, 'tilt'),
pos: webgl2.getAttribLocation(program, 'pos'),
webgl2
};
return webglLocation;
}
/**
*
* @returns {Map<string, Uint32Array>}
*/
makeVertex() {
const globalLookup = this.globalLookup;
const time = globalLookup.time;
const verticesMap = new Map();
for (const id of Reflect.ownKeys(globalLookup.chango)) {
const signalItem = globalLookup.chango[id];
const { kind, wave } = signalItem;
if (kind === 'bit') {
const vertices = this.makeBitVertex(wave, time);
verticesMap.set(id, vertices);
} else if (kind === 'vec') {
const vertices = this.makeVecVertex(wave, time);
verticesMap.set(id, vertices);
}
}
return verticesMap;
}
/**
*
* @param {Array<string | number>} wave
* @param { number } time
* @returns {Uint32Array}
*/
makeBitVertex(wave, time) {
const vertices = [];
const ilen = wave.length;
for (let i = 0; i < ilen; i++) {
const f = wave[(i === 0) ? 0 : (i - 1)];
const [tim, val] = wave[i];
const t = wave[(i === (ilen - 1)) ? i : (i + 1)];
const tt = (i === (ilen - 1)) ? time : wave[i + 1][0];
switch (val) {
case 0: case 1: // 0 1
vertices.push(...bar[val](f[1], t[1], tim, tt, 2, 3));
break;
case 2: case 3: // x X
vertices.push(...bar[2](f[1], t[1], tim, tt, 4, 4));
break;
case 4: case 5: // z Z
vertices.push(...bar[2](f[1], t[1], tim, tt, 1, 1));
break;
case 6: case 7: // u U uninitialized
vertices.push(...bar[2](f[1], t[1], tim, tt, 6, 6));
break;
case 8: case 9: // w W weak unknown
vertices.push(...bar[2](f[1], t[1], tim, tt, 10, 10));
break;
case 10: case 11: // l L
vertices.push(...bar[0](f[1], t[1], tim, tt, 8, 9));
break;
case 12: case 13: // h H
vertices.push(...bar[1](f[1], t[1], tim, tt, 8, 9));
break;
default:
vertices.push(...bar[2](f[1], t[1], tim, tt, 7, 7));
}
}
return new Uint32Array(vertices);
}
/**
*
* @param {Array<string | number>} wave
* @param { number } time
* @returns {Uint32Array}
*/
makeVecVertex(wave, time) {
const vertices = [];
const ilen = wave.length;
for (let i = 0; i < ilen; i++) {
const [tim, val, msk] = wave[i];
const tt = (i === (ilen - 1)) ? time : wave[i + 1][0];
if (val) {
if (msk) {
vertices.push(...brick[2](2, 2, tim, tt, 4, 4)); // x,z?
} else {
vertices.push(
tim, 0, 0,
tt, 0, 0, tt, 0, 5, tt, 4, 5,
tim, 6, 5, tim, 0, 5, tim, 3, 5,
tt, 1, 5, tt, 0, 5
);
}
} else {
if (msk) {
vertices.push(...brick[2](2, 2, tim, tt, 4, 4)); // x
} else {
vertices.push(tim, 6, 2, tt, 4, 2);
}
}
}
return new Uint32Array(vertices);
}
initData() {
const webglLocation = this.webglLocation;
const webgl2 = webglLocation.webgl2;
const globalLookup = this.globalLookup;
const verticesMap = this.verticesMap;
for (const id of Reflect.ownKeys(globalLookup.chango)) {
const signalItem = globalLookup.chango[id];
const vertices = verticesMap.get(id);
const vertexBuffer = webgl2.createBuffer();
webgl2.bindBuffer(webgl2.ARRAY_BUFFER, vertexBuffer);
// 将初始化的顶点数据复制到 buffer 区域
webgl2.bufferData(webgl2.ARRAY_BUFFER, vertices, webgl2.STATIC_DRAW);
signalItem.vao = webgl2.createVertexArray();
webgl2.bindVertexArray(signalItem.vao);
webgl2.vertexAttribIPointer(webglLocation.pos, 3, webgl2.UNSIGNED_INT, 0, 0);
webgl2.enableVertexAttribArray(webglLocation.pos);
webgl2.uniform4fv(webglLocation.colors, cColors);
webgl2.uniform2fv(webglLocation.tilts, cTilts);
}
}
render() {
if (this.animationHandler !== undefined) {
cancelAnimationFrame(this.animationHandler);
}
const canvas = this.canvas;
const webglLocation = this.webglLocation;
const webgl2 = webglLocation.webgl2;
const globalLookup = this.globalLookup;
const verticesMap = this.verticesMap;
const elements = this.elements;
this.animationHandler = window.requestAnimationFrame(() => {
const { width, height, xScale, xOffset, yOffset, yStep, yDuty } = this.pstate;
const canvasHeight = height - 40;
canvas.width = width;
canvas.height = canvasHeight;
// 设置 glsl 变量
webgl2.uniform1f(webglLocation.tilt, 3 / width);
webgl2.uniform2f(webglLocation.scale, 2 * xScale / width, yStep * yDuty / canvasHeight);
// 设置 webgl 和 canvas 大小位置一致
webgl2.viewport(0, 0, width, canvasHeight);
// 清楚颜色缓冲区,也就是删除上一次的渲染结果
webgl2.clear(webgl2.COLOR_BUFFER_BIT);
// 根据 globalLookup 当前激活的需要渲染的信号进行渲染
let index = 0;
for (const signal of globalLookup.currentWires) {
const signalItem = globalLookup.chango[signal.link];
if (!signalItem) {
return;
}
webgl2.bindVertexArray(signalItem.vao);
webgl2.uniform2f(webglLocation.offset,
(2 * xOffset / width) - 1,
(2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1
);
// 根据 vao 进行绘制
const vertices = verticesMap.get(signal.link);
// console.log(vertices);
webgl2.drawArrays(webgl2.LINE_STRIP, 0, vertices.length / 3);
index ++;
}
this.plugins.map(fn => fn(globalLookup, this.pstate, elements));
this.animationHandler = undefined;
});
}
}
module.exports = genRenderWavesGL;
/* eslint-env browser */
/* eslint complexity: [1, 30] */
module.exports = WebGL2WaveRender;

View File

@ -2,15 +2,15 @@
const renderValues = require('./render-values.js');
const pluginRenderValues = (desc, pstate, els) => {
const gen = renderValues(desc, pstate);
for (let i = 0; i < 1e6; i++) {
const iter = gen.next();
if (iter.done) {
els.values.innerHTML = iter.value;
break;
function pluginRenderValues(desc, pstate, els) {
const gen = renderValues(desc, pstate);
for (let i = 0; i < 1e6; i++) {
const iter = gen.next();
if (iter.done) {
els.values.innerHTML = iter.value;
break;
}
}
}
};
}
module.exports = pluginRenderValues;

View File

@ -41,6 +41,8 @@ const renderCursor = (cfg, pstate) => {
class: 'wd-cursor-time',
x: xmargin - lWidth / 2,
y: height - fontHeight * 1.25,
rx: 9,
ry: 9,
width: lWidth,
height: fontHeight * 1.25
}],

View File

@ -12,116 +12,119 @@ const vlineStylo = require('./vline-stylo.js');
const getLabel = require('./get-label.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'}]
];
})
['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' }]
];
})
];
const renderValues = function* (desc, pstate) {
const { width, height, sidebarWidth, yOffset, yStep, topBarHeight, botBarHeight } = pstate;
const { view } = desc;
function* renderValues(desc, pstate) {
const { width, height, sidebarWidth, yOffset, yStep, topBarHeight, botBarHeight } = pstate;
const ilen = height / yStep;
const iskip = yOffset / yStep;
// console.log(iskip, ilen, view.length);
const ml = genSVG(width, height - topBarHeight - botBarHeight);
let ifirst = 0;
for (let i = 0; i < ilen; i += 1) {
const lane = view[i];
if (lane && (lane.name || lane.kind)) {
if (i > iskip) {
break;
}
ifirst = i;
const currentWires = desc.currentWires;
const view = [];
for (const signal of currentWires) {
view.push({
kind: signal.kind,
name: signal.name,
ref: signal.link
});
}
}
ml.push(defs);
yield;
const markers = ['g'];
ml.push(markers);
const ilen = height / yStep;
const iskip = yOffset / yStep;
for (let i = 0; i < (iskip + ilen); i++) {
const lane = view[i + (ifirst |0)];
const ml = genSVG(width, height - topBarHeight - botBarHeight);
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') {
const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + .9) * 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);
if (vPre || mPre) {
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);
mLane.push(labeler(vPre, mPre, x, w));
}
}
let ifirst = 0;
for (let i = 0; i < ilen; i += 1) {
const lane = view[i];
if (lane && (lane.name || lane.kind)) {
if (i > iskip) {
break;
}
xPre = xCur;
vPre = vCur;
mPre = mCur;
}
ifirst = i;
}
ml.push(mLane);
}
yield;
}
}
ml.push(defs);
yield;
// console.log(view);
for (let i = 0; i < view.length; i++) {
const lane = view[i];
if (lane && lane.vlines) {
markers.push(...vline(lane, pstate, i));
const markers = ['g'];
ml.push(markers);
for (let i = 0; i < (iskip + ilen); i++) {
const lane = view[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') {
const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + .8) * 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);
if (vPre || mPre) {
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);
mLane.push(labeler(vPre, mPre, x, w));
}
}
}
xPre = xCur;
vPre = vCur;
mPre = mCur;
}
}
ml.push(mLane);
}
yield;
}
}
}
yield;
return stringify(ml);
};
// console.log(view);
for (let i = 0; i < view.length; i++) {
const lane = view[i];
if (lane && lane.vlines) {
markers.push(...vline(lane, pstate, i));
}
}
yield;
return stringify(ml);
}
module.exports = renderValues;
/* eslint complexity: [1, 55] */