digital-vcd-render/src/hook/wave-container-view.js
2024-10-22 21:28:02 +08:00

189 lines
5.4 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.

/**
* 用于维护所有的 波形容器视图
* 设计参考文档https://nc-ai-lab.feishu.cn/wiki/Fy3ZwtbYbiatmxkhOp2cyHSFnlw
*/
import { groupColorDispatcher } from "@/components/sidebar/manage-group";
import { globalLookup } from "./global";
import { getSmartCurrentSignalValue } from "./utils";
/**
* @typedef {Object} ViewIterConfig
* @property {boolean} returnGroup
*/
/**
* @namespace WaveContainerView
*/
export const WaveContainerView = {
/**
* @description 增加 一个信号,并创建它的若干个视图,并计算出它当前时刻的值
* @param {WireItem} signal
*/
add(signal) {
if (globalLookup.currentWires.has(signal)) {
return;
}
// 增加高效 CRUD 视图
globalLookup.currentWires.add(signal);
// 上面的 视图 的 string, signal 字典版本
globalLookup.link2CurrentWires.set(signal.link, signal);
// 增加 sidebar 渲染视图
// TODO : 支持更加复杂的视图加入
globalLookup.currentWiresRenderView.push({
signalInfo: {
name: signal.name,
link: signal.link,
size: signal.size,
},
groupInfo: {
name: '',
color: '',
collapse: false
},
renderType: 0,
children: []
});
// 增加当前波形值视图
const changoItem = globalLookup.chango[signal.link];
globalLookup.currentSignalValues[signal.link] = getSmartCurrentSignalValue(changoItem, globalLookup.currentTime);
},
/**
*
* @param {WireItem} signal
*/
delete(signal) {
const renderView = globalLookup.currentWiresRenderView;
globalLookup.currentWires.delete(signal);
globalLookup.link2CurrentWires.delete(signal.link);
delete globalLookup.currentSignalValues[signal.link];
// 从 currentWiresRenderView 中删除
// 此处需要考虑到处于 group 中的 link 的情况
const { index, childIndex } = findViewIndexTuple(signal.link);
function deleteElement(container, index) {
const tailElements = container.slice(index + 1);
container.length = index;
tailElements.forEach(el => container.push(el));
}
if (childIndex >= 0) {
// 删除 group 内元素
const view = renderView[index];
deleteElement(view.children, childIndex);
// 如果 group 空了,则也删除
if (view.children.length === 0) {
deleteElement(renderView, index);
groupColorDispatcher.put(view.groupInfo.color);
}
} else if (index >= 0) {
// 删除总体的元素
deleteElement(renderView, index);
}
},
/**
*
* @param {WireItem} signal
* @returns {boolean}
*/
has(signal) {
return globalLookup.currentWires.has(signal);
}
};
/**
* @description 找到位于嵌套结构中的索引
* @param {string} link
* @returns {{ index: number, childIndex: number }} index: 位于 renderView 的索引,位于 group 的 children 中的索引
*/
function findViewIndexTuple(link) {
const renderView = globalLookup.currentWiresRenderView;
for (let i = 0; i < renderView.length; ++ i) {
const view = renderView[i];
if (view.signalInfo.link === link) {
return { index: i, childIndex: -1 };
}
for (let j = 0; j < view.children.length; ++ j) {
const child = view.children[j];
if (child.signalInfo.link === link) {
return { index: i, childIndex: j };
}
}
}
return { index: -1, childIndex: -1 };
}
export function findViewIndexByLink(link) {
const renderView = globalLookup.currentWiresRenderView;
let i = 0;
while (i < renderView.length && renderView[i].signalInfo.link !== link) {
++ i;
}
if (i < renderView.length) {
return i;
} else {
return -1;
}
}
function makeFullSignalNameDeps(signal) {
const deps = [];
while (signal) {
if (signal.name && signal.type) {
deps.push(signal);
}
signal = signal.parent;
}
let htmlString = '';
for (let i = deps.length - 1; i >= 0; -- i) {
const mod = deps[i];
// const displayName = mod.name.length > 6 ? mod.name.substring(0, 6) + '...' : mod.name;
const iconClass = makeIconClass(mod);
const iconText = `<span class="iconfont ${iconClass}"></span>&ensp;${mod.name}`;
htmlString += iconText;
if (i > 0) {
htmlString += '<div class="dep-arrow"></div>';
}
}
htmlString = '<div class="signal-info-tooltip-wrapper">' + htmlString + '</div>';
return htmlString;
}
/**
*
* @param {ViewIterConfig} iterConfig
* @returns {Generator<string>}
*/
export function* genOrderedLinks(iterConfig) {
const iterGroup = (iterConfig || {}).iterGroup || false;
for (const view of globalLookup.currentWiresRenderView) {
if (view.renderType === 0) {
yield view.signalInfo.link;
} else {
if (iterGroup) {
// groupLink 都会以 -group 结尾
yield view.signalInfo.link;
}
for (const child of view.children) {
yield child.signalInfo.link;
}
}
}
}