233 lines
6.4 KiB
JavaScript
233 lines
6.4 KiB
JavaScript
import mitt from 'mitt';
|
||
import { reactive } from 'vue';
|
||
import WebGL2WaveRender from './wave-view/render-wave';
|
||
|
||
export const emitter = mitt();
|
||
|
||
|
||
/**
|
||
* @description 用于记载全局的一些对象,以便在不同组件中比较 ID
|
||
*
|
||
*/
|
||
export const globalLookup = reactive({
|
||
/**
|
||
* @description 读取的文件的路径
|
||
*/
|
||
originVcdFile: '',
|
||
|
||
/**
|
||
* @description 读取文件的 view 路径
|
||
*/
|
||
originVcdViewFile: '',
|
||
|
||
/**
|
||
* @description 所有的顶层文件
|
||
* @type {ScopeItem[]}
|
||
*/
|
||
topModules: [],
|
||
|
||
/**
|
||
* @description 当前选中的 信号,也就是 tree-view 左列的,默认是第一个。不可复选。
|
||
* @type {WireItem | undefined}
|
||
*/
|
||
currentModule: undefined,
|
||
|
||
/**
|
||
* @description 当前被选中的波形,用于进行高效的增删改查
|
||
* @type {Set<WireItem>}
|
||
*/
|
||
currentWires: new Set(),
|
||
|
||
/**
|
||
* @description 当前被选中的波形,是 currentWires 的字典版本
|
||
* @type {Map<string, WireItem>}
|
||
*/
|
||
link2CurrentWires: new Map(),
|
||
|
||
/**
|
||
* @description 当前被选中的波形,用于 sidebar 的渲染视图
|
||
* 详细请见设计文档:https://nc-ai-lab.feishu.cn/wiki/Fy3ZwtbYbiatmxkhOp2cyHSFnlw
|
||
* @type {WaveRenderSidebarItem[]}
|
||
*/
|
||
currentWiresRenderView: [],
|
||
|
||
/**
|
||
* @description 用于存储当前时间点的波形的值,Key 为 波形的 link,值为 当前左侧渲染的值,没有就是 x
|
||
* @type {Record<string, BigInt | string>}
|
||
*/
|
||
currentSignalValues: {},
|
||
|
||
/**
|
||
* @description 侧边栏中当前被选中的波形,一定是 currentWires 的子集
|
||
* 内部存储的是 wire 的 link,所以是 string
|
||
* @type {Set<string>}
|
||
*/
|
||
sidebarSelectedWireLinks: new Set(),
|
||
|
||
/**
|
||
* @description 当前渲染的信号的基本选项,比如高度,颜色,format,modal 等等
|
||
* @type {Map<string, IRenderOption>}
|
||
*/
|
||
currentSignalRenderOptions: new Map(),
|
||
|
||
// 当前 ns 数(或者 ps)
|
||
currentTime: 0,
|
||
|
||
// 模拟器的版本,比如如果使用 iverilog 那么就是 Icarus Verilog
|
||
version: '',
|
||
// 创建时间
|
||
date: '',
|
||
// 状态 默认是 simulation
|
||
status: '',
|
||
// 单位时间
|
||
timescale: '',
|
||
// 初始时间,一般都是 0
|
||
t0: 0,
|
||
// 最长持续时间
|
||
maxTime: 0n,
|
||
time: 0,
|
||
|
||
// 优化视图的最大公约数
|
||
tgcd: null,
|
||
|
||
/**
|
||
* @description 就是 signalValues
|
||
* @type {Record<string, ChangoItem>}
|
||
*/
|
||
chango: {},
|
||
|
||
/**
|
||
* @description 【核心】接入渲染管线,重新渲染,该函数必须在 domContainer 初始化完成后再去调用
|
||
* @param {RenderConfig} renderConfig 渲染的类型,默认为重新渲染所有可视项
|
||
*/
|
||
render: (renderConfig) => {},
|
||
|
||
/**
|
||
* @description 非常核心的用于操控 webgl 进行渲染和动画的核心类
|
||
* @type {WebGL2WaveRender}
|
||
*/
|
||
waveRender: undefined,
|
||
|
||
|
||
/**
|
||
* @description 描述描述当前渲染区的一些基本几何状态
|
||
* @type {Pstate | undefined}
|
||
*/
|
||
pstate: undefined,
|
||
|
||
xScale: 1,
|
||
|
||
/**
|
||
* @description 初始化 module,为每一个 module 配上 parent 并给出对应的 nameClass
|
||
* @param {ScopeItem} module
|
||
*/
|
||
initcurrentModule(module) {
|
||
if (this.currentModule === undefined && module) {
|
||
this.currentModule = module;
|
||
}
|
||
if (module.nameClass === undefined) {
|
||
module.nameClass = module.name;
|
||
}
|
||
// 创造 parent,当然,这一步也可能在 recoverSession 中被实现了
|
||
if (module.body && module.body instanceof Array) {
|
||
for (const childModule of module.body) {
|
||
// 计算 nameClass
|
||
childModule.parent = module;
|
||
childModule.nameClass = module.nameClass + '.' + childModule.name;
|
||
}
|
||
}
|
||
},
|
||
|
||
/**
|
||
* @returns {WebGL2WaveRender}
|
||
*/
|
||
getWaveRender() {
|
||
return this.waveRender;
|
||
},
|
||
|
||
/**
|
||
*
|
||
* @param {string} link
|
||
* @param {'height' | 'color' | 'valueFormat' | 'renderModal' | 'highlight'} option
|
||
* @param {any} value
|
||
* @returns {boolean} true 代表改变了值,否则则没有,可以用来判断是否需要重复塑造 Vertices
|
||
*/
|
||
setRenderOption(link, option, value) {
|
||
if (!this.currentSignalRenderOptions.has(link)) {
|
||
this.currentSignalRenderOptions.set(link, {});
|
||
}
|
||
const renderOption = this.currentSignalRenderOptions.get(link);
|
||
if (renderOption[option] === value) {
|
||
return false;
|
||
}
|
||
renderOption[option] = value;
|
||
return true;
|
||
}
|
||
});
|
||
|
||
export const globalStyle = reactive({
|
||
/**
|
||
* @description 这个值代表 sidebar 的上侧的空间,但是 sidebar 本身有一个 10px 的 padding,所以真实的 sidebar 上侧
|
||
* 空出来的空间等于 timeScaleHeight + 10,需要注意, timeScaleHeight 需要等于 pstate.yOffset 的初始值的相反数,
|
||
* pstate.yOffset 的初始值请参考 dom-container.js 这个文件
|
||
* @type {number}
|
||
*/
|
||
timeScaleHeight: 20,
|
||
|
||
sideBarPadding: 10,
|
||
sideBarItemMargin: 2,
|
||
vcdRenderPadding: 24,
|
||
yOffset: 0,
|
||
});
|
||
|
||
export const globalSetting = reactive({
|
||
language: 'zh',
|
||
caseSensitivity: false,
|
||
displayParentOnly: false,
|
||
displaySignalHeight: 30,
|
||
searchMode: 'so', // so, mo, sm
|
||
searchScope: ['wire', 'reg', 'integer'],
|
||
displaySignalInfoScope: ['width'],
|
||
HorizontalScalingRatio: 1,
|
||
HorizontalRollRatio: 1,
|
||
VerticalRollRario: 1,
|
||
minGridWidth: 300,
|
||
prerender: false,
|
||
renderAnimation: false,
|
||
autoSaveView: true
|
||
});
|
||
|
||
function loadSetting() {
|
||
const settingString = localStorage.getItem('setting')
|
||
try {
|
||
const setting = JSON.parse(settingString);
|
||
return setting;
|
||
} catch (error) {
|
||
return undefined;
|
||
}
|
||
}
|
||
|
||
export const storedSetting = loadSetting();
|
||
if (storedSetting) {
|
||
for (const key of Reflect.ownKeys(storedSetting)) {
|
||
const value = storedSetting[key];
|
||
if (value !== undefined) {
|
||
globalSetting[key] = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
*
|
||
* @returns {WaveRenderSidebarItem[]}
|
||
*/
|
||
function getCurrentWiresRenderView() {
|
||
return globalLookup.currentWiresRenderView;
|
||
}
|
||
|
||
export const VcdInfo = reactive({
|
||
topModules: [],
|
||
values: [],
|
||
});
|