189 lines
5.4 KiB
JavaScript
189 lines
5.4 KiB
JavaScript
/**
|
||
* 用于维护所有的 波形容器视图
|
||
* 设计参考文档: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> ${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;
|
||
}
|
||
}
|
||
}
|
||
} |