• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import {SpSystemTrace} from "./SpSystemTrace";
17import {ThreadStruct, ThreadStructOnClick} from "../database/ui-worker/ProcedureWorkerThread";
18import {TraceRow} from "./trace/base/TraceRow";
19import {JankStruct, JankStructOnClick} from "../database/ui-worker/ProcedureWorkerJank";
20import {HeapSnapshotStruct, HeapSnapshotStructOnClick} from "../database/ui-worker/ProcedureWorkerHeapSnapshot";
21import {FuncStructOnClick} from "../database/ui-worker/ProcedureWorkerFunc";
22import {CpuFreqStructOnClick} from "../database/ui-worker/ProcedureWorkerFreq";
23import {ClockStructOnClick} from "../database/ui-worker/ProcedureWorkerClock";
24import {SnapshotStructOnClick} from "../database/ui-worker/ProcedureWorkerSnapshot";
25import {IrqStructOnClick} from "../database/ui-worker/ProcedureWorkerIrq";
26import {HeapStructOnClick} from "../database/ui-worker/ProcedureWorkerHeap";
27import {JsCpuProfilerStructOnClick} from "../database/ui-worker/ProcedureWorkerCpuProfiler";
28import {AppStartupStructOnClick} from "../database/ui-worker/ProcedureWorkerAppStartup";
29import {SoStructOnClick} from "../database/ui-worker/ProcedureWorkerSoInit";
30import {FrameAnimationStructOnClick} from "../database/ui-worker/ProcedureWorkerFrameAnimation";
31import {FrameDynamicStructOnClick} from "../database/ui-worker/ProcedureWorkerFrameDynamic";
32import {FrameSpacingStructOnClick} from "../database/ui-worker/ProcedureWorkerFrameSpacing";
33import {SportRuler} from "./trace/timer-shaft/SportRuler";
34import {SpStatisticsHttpUtil} from "../../statistics/util/SpStatisticsHttpUtil";
35import {LitSearch} from "./trace/search/Search";
36import {TabPaneCurrent} from "./trace/sheet/TabPaneCurrent";
37import type {SpKeyboard} from "./SpKeyboard";
38import {enableVSync} from "./chart/VSync";
39import {CpuStruct, CpuStructOnClick} from "../database/ui-worker/cpu/ProcedureWorkerCPU";
40import {CpuStateStructOnClick} from "../database/ui-worker/cpu/ProcedureWorkerCpuState";
41import {CpuFreqLimitsStructOnClick} from "../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits";
42
43function timeoutJudge(sp: SpSystemTrace) {
44  let timeoutJudge = setTimeout(() => {
45    if (SpSystemTrace.wakeupList.length && CpuStruct.selectCpuStruct) {
46      let checkHandlerKey: boolean = true;
47      let saveSelectCpuStruct: any = JSON.parse(sessionStorage.getItem('saveselectcpustruct')!);
48      for (const item of SpSystemTrace.wakeupList) {
49        if (item.ts === CpuStruct.selectCpuStruct.startTime && item.dur === CpuStruct.selectCpuStruct.dur) {
50          checkHandlerKey = false;
51          if (SpSystemTrace.wakeupList[0].schedulingDesc) {
52            SpSystemTrace.wakeupList.unshift(saveSelectCpuStruct);
53          }
54          sp.refreshCanvas(true);
55          break;
56        } else if (
57          saveSelectCpuStruct.startTime === CpuStruct.selectCpuStruct.startTime &&
58          saveSelectCpuStruct.dur === CpuStruct.selectCpuStruct.dur
59        ) {
60          // 如果点击的是第一层,保持唤醒树不变
61          checkHandlerKey = false;
62          sp.refreshCanvas(true);
63          break;
64        }
65      }
66      // 点击线程在唤醒树内
67      if (!checkHandlerKey) {
68        // 查询获取tab表格数据
69        window.publish(window.SmartEvent.UI.WakeupList, SpSystemTrace.wakeupList);
70      } else {
71        // 不在唤醒树内,清空数组
72        sp.wakeupListNull();
73        sp.refreshCanvas(true);
74      }
75    } else {
76      sp.wakeupListNull();
77      sp.refreshCanvas(true);
78    }
79    clearTimeout(timeoutJudge);
80  }, 10);
81  return timeoutJudge;
82}
83
84function threadClickHandlerFunc(sp: SpSystemTrace) {
85  let threadClickHandler = (d: ThreadStruct) => {
86    sp.observerScrollHeightEnable = false;
87    sp.scrollToProcess(`${d.cpu}`, '', 'cpu-data', true);
88    let cpuRow = sp.queryAllTraceRow<TraceRow<CpuStruct>>(
89      `trace-row[row-id='${d.cpu}'][row-type='cpu-data']`,
90      (row) => row.rowId === `${d.cpu}` && row.rowType === 'cpu-data'
91    )[0];
92    sp.currentRow = cpuRow;
93    cpuRow.fixedList = [
94      {
95        startTime: d.startTime,
96        dur: d.dur,
97        tid: d.tid,
98        id: d.id,
99        processId: d.pid,
100        cpu: d.cpu,
101        argSetID: d.argSetID,
102      },
103    ];
104    let findEntry = cpuRow!.fixedList[0];
105    sp.rechargeCpuData(
106      findEntry,
107      cpuRow.dataListCache.find((it) => it.startTime > findEntry.startTime)
108    );
109    if (
110      findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS ||
111      findEntry!.startTime! > TraceRow.range!.endNS
112    ) {
113      sp.timerShaftEL?.setRangeNS(
114        findEntry!.startTime! - findEntry!.dur! * 2,
115        findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2
116      );
117    }
118    sp.hoverStructNull().selectStructNull().wakeupListNull();
119    CpuStruct.hoverCpuStruct = findEntry;
120    CpuStruct.selectCpuStruct = findEntry;
121    sp.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted');
122    sp.traceSheetEL?.displayCpuData(
123      CpuStruct.selectCpuStruct!,
124      (wakeUpBean) => {
125        sp.removeLinkLinesByBusinessType('thread');
126        CpuStruct.wakeupBean = wakeUpBean;
127        sp.refreshCanvas(true);
128      },
129      cpuClickHandlerFunc(sp)
130    );
131  };
132  return threadClickHandler;
133}
134
135function scrollToFuncHandlerFunc(sp: SpSystemTrace) {
136  return function (funcStruct: any) {
137    sp.observerScrollHeightEnable = true;
138    sp.moveRangeToCenter(funcStruct.startTs!, funcStruct.dur!);
139    sp.scrollToActFunc(funcStruct, false);
140  };
141}
142
143function jankClickHandlerFunc(sp: SpSystemTrace) {
144  let jankClickHandler = (d: any) => {
145    sp.observerScrollHeightEnable = true;
146    let jankRowParent: any;
147    if (d.rowId === 'actual frameTime') {
148      jankRowParent = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>("trace-row[row-id='frameTime']");
149    } else {
150      jankRowParent = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>(`trace-row[row-id='${d.pid}']`);
151    }
152    jankRowParent!.expansion = true;
153    let jankRow: any;
154    jankRowParent.childrenList.forEach((item: TraceRow<JankStruct>) => {
155      if (item.rowId === `${d.rowId}` && item.rowType === 'janks') {
156        jankRow = item;
157      }
158    });
159    if (jankRow) {
160      JankStruct.selectJankStructList.length = 0;
161      let findJankEntry = jankRow!.dataListCache!.find((dat: any) => dat.name == d.name && dat.pid == d.pid);
162      if (findJankEntry) {
163        if (findJankEntry!.ts! + findJankEntry!.dur! < TraceRow.range!.startNS ||
164          findJankEntry!.ts! > TraceRow.range!.endNS) {
165          sp.timerShaftEL?.setRangeNS(
166            findJankEntry!.ts! - findJankEntry!.dur! * 2,
167            findJankEntry!.ts! + findJankEntry!.dur! + findJankEntry!.dur! * 2
168          );
169        }
170        sp.hoverStructNull().selectStructNull().wakeupListNull();
171        JankStruct.hoverJankStruct = findJankEntry;
172        JankStruct.selectJankStruct = findJankEntry;
173        sp.timerShaftEL?.drawTriangle(findJankEntry!.ts || 0, 'inverted');
174        sp.traceSheetEL?.displayJankData(JankStruct.selectJankStruct!, (datas) => {
175            sp.removeLinkLinesByBusinessType('janks');
176            // 绘制跟自己关联的线
177            datas.forEach((data) => {
178              let endParentRow = sp.shadowRoot?.querySelector<TraceRow<any>>(
179                `trace-row[row-id='${data.pid}'][folder]`
180              );
181              sp.drawJankLine(endParentRow, JankStruct.selectJankStruct!, data);
182            });
183          },
184          jankClickHandler
185        );
186      }
187      sp.scrollToProcess(jankRow.rowId!, jankRow.rowParentId!, jankRow.rowType!, true);
188    }
189  };
190  return jankClickHandler;
191}
192
193function snapshotClickHandlerFunc(sp: SpSystemTrace) {
194  let snapshotClickHandler = (d: HeapSnapshotStruct) => {
195    sp.observerScrollHeightEnable = true;
196    let snapshotRow = sp.shadowRoot?.querySelector<TraceRow<HeapSnapshotStruct>>(
197      `trace-row[row-id='heapsnapshot']`
198    );
199    let task = () => {
200      if (snapshotRow) {
201        let findEntry = snapshotRow!.dataListCache!.find((dat) => dat.startTs === d.startTs);
202        sp.hoverStructNull();
203        sp.selectStructNull();
204        sp.wakeupListNull();
205        HeapSnapshotStruct.hoverSnapshotStruct = findEntry;
206        HeapSnapshotStruct.selectSnapshotStruct = findEntry;
207      }
208    };
209    if (snapshotRow) {
210      if (snapshotRow!.isComplete) {
211        task();
212      } else {
213        snapshotRow!.onComplete = task;
214      }
215    }
216  };
217  return snapshotClickHandler;
218}
219
220function cpuClickHandlerTask(threadRow: TraceRow<any>, sp: SpSystemTrace, d: CpuStruct) {
221  if (threadRow) {
222    let findEntry = threadRow!.fixedList[0];
223    if (
224      findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS ||
225      findEntry!.startTime! > TraceRow.range!.endNS
226    ) {
227      sp.timerShaftEL?.setRangeNS(
228        findEntry!.startTime! - findEntry!.dur! * 2,
229        findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2
230      );
231    }
232    sp.hoverStructNull().selectStructNull().wakeupListNull();
233    ThreadStruct.hoverThreadStruct = findEntry;
234    ThreadStruct.selectThreadStruct = findEntry;
235    sp.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted');
236    sp.traceSheetEL?.displayThreadData(
237      ThreadStruct.selectThreadStruct!,
238      threadClickHandlerFunc(sp),
239      cpuClickHandlerFunc(sp),
240      (datas) => sp.removeLinkLinesByBusinessType('thread')
241    );
242    sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true);
243  }
244}
245
246function cpuClickHandlerFunc(sp: SpSystemTrace) {
247  return function (d: CpuStruct) {
248    let traceRow = sp.shadowRoot?.querySelector<TraceRow<any>>(
249      `trace-row[row-id='${d.processId}'][row-type='process']`
250    );
251    if (traceRow) {
252      traceRow.expansion = true;
253    }
254    sp.observerScrollHeightEnable = true;
255    let threadRow = sp.queryAllTraceRow<TraceRow<ThreadStruct>>(
256      `trace-row[row-id='${d.tid}'][row-type='thread']`,
257      (row) => row.rowId === `${d.tid}` && row.rowType === 'thread'
258    )[0];
259    sp.currentRow = threadRow;
260    if (threadRow) {
261      threadRow.fixedList = [
262        {
263          startTime: d.startTime,
264          dur: d.dur,
265          cpu: d.cpu,
266          id: d.id,
267          tid: d.tid,
268          state: d.state,
269          pid: d.processId,
270          argSetID: d.argSetID,
271        },
272      ];
273      if (threadRow!.isComplete) {
274        cpuClickHandlerTask(threadRow, sp, d);
275      } else {
276        sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'process', false);
277        sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true);
278        threadRow!.onComplete = () => cpuClickHandlerTask(threadRow, sp, d);
279      }
280    }
281  };
282}
283
284function AllStructOnClick(clickRowType:string,sp:SpSystemTrace,row?:TraceRow<any>) {
285  CpuStructOnClick(clickRowType, sp, cpuClickHandlerFunc(sp))
286    .then(() => ThreadStructOnClick(clickRowType, sp, threadClickHandlerFunc(sp), cpuClickHandlerFunc(sp)))
287    .then(() => FuncStructOnClick(clickRowType, sp, row, scrollToFuncHandlerFunc(sp)))
288    .then(() => CpuFreqStructOnClick(clickRowType, sp))
289    .then(() => CpuStateStructOnClick(clickRowType, sp))
290    .then(() => CpuFreqLimitsStructOnClick(clickRowType, sp))
291    .then(() => ClockStructOnClick(clickRowType, sp))
292    .then(() => SnapshotStructOnClick(clickRowType, sp))
293    .then(() => IrqStructOnClick(clickRowType, sp))
294    .then(() => HeapStructOnClick(clickRowType, sp, row))
295    .then(() => JankStructOnClick(clickRowType, sp, jankClickHandlerFunc(sp)))
296    .then(() => HeapSnapshotStructOnClick(clickRowType, sp, snapshotClickHandlerFunc(sp)))
297    .then(() => JsCpuProfilerStructOnClick(clickRowType, sp))
298    .then(() => AppStartupStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp)))
299    .then(() => SoStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp)))
300    .then(() => FrameAnimationStructOnClick(clickRowType, sp))
301    .then(() => FrameDynamicStructOnClick(clickRowType, sp, row))
302    .then(() => FrameSpacingStructOnClick(clickRowType, sp))
303    .then(() => {
304      if (!JankStruct.hoverJankStruct && JankStruct.delJankLineFlag) {
305        sp.removeLinkLinesByBusinessType('janks');
306      }
307      sp.observerScrollHeightEnable = false;
308      sp.selectFlag = null;
309      sp.timerShaftEL?.removeTriangle('inverted');
310      if (!SportRuler.isMouseInSportRuler) {
311        sp.traceSheetEL?.setAttribute('mode', 'hidden');
312        sp.refreshCanvas(true);
313      }
314    }).catch(e => {});
315}
316export default function spSystemTraceOnClickHandler(sp: SpSystemTrace, clickRowType: string, row?: TraceRow<any>) {
317  if (row) {
318    sp.currentRow = row;
319    sp.setAttribute('clickRow', clickRowType);
320    sp.setAttribute('rowName', row.name!);
321    sp.setAttribute('rowId', row.rowId!);
322  }
323  if (!sp.loadTraceCompleted) return;
324  sp.queryAllTraceRow().forEach((it) => (it.rangeSelect = false));
325  sp.selectStructNull();
326  // 判断点击的线程是否在唤醒树内
327  timeoutJudge(sp);
328  AllStructOnClick(clickRowType,sp,row);
329  if (!JankStruct.selectJankStruct) {
330    sp.removeLinkLinesByBusinessType('janks');
331  }
332  if (!ThreadStruct.selectThreadStruct) {
333    sp.removeLinkLinesByBusinessType('thread');
334  }
335  if (row) {
336    let pointEvent = sp.createPointEvent(row);
337    SpStatisticsHttpUtil.addOrdinaryVisitAction({
338      action: 'trace_row',
339      event: pointEvent,
340    });
341  }
342}
343
344function handleActions(sp: SpSystemTrace, rows: Array<TraceRow<any>>, ev: MouseEvent) {
345  sp.rangeSelect.mouseMove(rows, ev);
346  if (sp.rangeSelect.rangeTraceRow!.length > 0) {
347    sp.tabCpuFreq!.rangeTraceRow = sp.rangeSelect.rangeTraceRow;
348    sp.tabCpuState!.rangeTraceRow = sp.rangeSelect.rangeTraceRow;
349  }
350  let search = document.querySelector('body > sp-application')!.shadowRoot!.querySelector<LitSearch>('#lit-search');
351  if (sp.rangeSelect.isMouseDown && search?.isClearValue) {
352    SpSystemTraceDocumentOnMouseMoveMouseDown(sp, search);
353  } else {
354    SpSystemTraceDocumentOnMouseMoveMouseUp(sp, rows, ev);
355  }
356}
357
358function handleMouseInTimeShaft(sp: SpSystemTrace, ev: MouseEvent) {
359  let isMouseInTimeShaft = sp.timerShaftEL?.containPoint(ev);
360  if (isMouseInTimeShaft) {
361    sp.tipEL!.style.display = 'none';
362    sp.hoverStructNull();
363  }
364  return isMouseInTimeShaft;
365}
366
367export function spSystemTraceDocumentOnMouseMove(sp: SpSystemTrace, ev: MouseEvent) {
368  if (!sp.loadTraceCompleted || (window as any).flagInputFocus || !sp.mouseEventEnable) {
369    return;
370  }
371  if ((window as any).collectResize) {
372    sp.style.cursor = 'row-resize';
373    sp.cancelDrag();
374    return;
375  }
376  if (sp.isWASDKeyPress()) {
377    sp.hoverFlag = null;
378    ev.preventDefault();
379    return;
380  }
381  if (ev.ctrlKey && ev.button === 0 && sp.isMouseLeftDown) {
382    sp.translateByMouseMove(ev);
383  }
384  sp.inFavoriteArea = sp.favoriteChartListEL?.containPoint(ev);
385  if ((window as any).isSheetMove || sp.isMouseInSheet(ev)) {
386    sp.hoverStructNull();
387    sp.tipEL!.style.display = 'none';
388    return;
389  }
390  let isMouseInTimeShaft = handleMouseInTimeShaft(sp, ev);
391  let rows = sp.visibleRows;
392  if (sp.timerShaftEL?.isScaling()) {
393    return;
394  }
395  sp.timerShaftEL?.documentOnMouseMove(ev, sp);
396  if (isMouseInTimeShaft) {
397    return;
398  }
399  handleActions(sp, rows, ev);
400}
401
402function SpSystemTraceDocumentOnMouseMoveMouseDown(sp: SpSystemTrace, search: LitSearch) {
403  sp.refreshCanvas(true);
404  if (TraceRow.rangeSelectObject) {
405    if (search && search.searchValue !== '') {
406      search.clear();
407      search.valueChangeHandler?.('');
408    }
409  }
410}
411
412function SpSystemTraceDocumentOnMouseMoveMouseUp(sp: SpSystemTrace, rows: Array<TraceRow<any>>, ev: MouseEvent) {
413  if (!sp.rowsPaneEL!.containPoint(ev, {left: 248})) {
414    sp.hoverStructNull();
415  }
416  rows
417    .filter((it) => it.focusContain(ev, sp.inFavoriteArea!) && it.collect === sp.inFavoriteArea)
418    .filter((it) => {
419      if (it.collect) {
420        return true;
421      } else {
422        return (
423          it.getBoundingClientRect().bottom + it.getBoundingClientRect().height >
424          sp.favoriteChartListEL!.getBoundingClientRect().bottom
425        );
426      }
427    })
428    .forEach((tr) => {
429      sp.hoverStructNull();
430      if (sp.currentRowType != tr.rowType) {
431        sp.currentRowType = tr.rowType || '';
432      }
433      tr.findHoverStruct?.();
434      tr.focusHandler?.(ev);
435    });
436  requestAnimationFrame(() => sp.refreshCanvas(true));
437}
438
439export function spSystemTraceDocumentOnMouseOut(sp: SpSystemTrace, ev: MouseEvent) {
440  if (!sp.loadTraceCompleted) {
441    return;
442  }
443  TraceRow.isUserInteraction = false;
444  sp.isMouseLeftDown = false;
445  if (sp.isMouseInSheet(ev)) {
446    return;
447  }
448  if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) {
449    sp.rangeSelect.mouseOut(ev);
450    sp.timerShaftEL?.documentOnMouseOut(ev);
451  }
452}
453
454export function SpSystemTraceDocumentOnKeyPress(sp: SpSystemTrace, ev: KeyboardEvent) {
455  if (!sp.loadTraceCompleted) {
456    return;
457  }
458  let keyPress = ev.key.toLocaleLowerCase();
459  TraceRow.isUserInteraction = true;
460  if (sp.isMousePointInSheet) {
461    return;
462  }
463  sp.observerScrollHeightEnable = false;
464  if (sp.keyboardEnable) {
465    if (keyPress === 'm') {
466      sp.slicestime = sp.setSLiceMark(ev.shiftKey);
467      if (sp.slicestime) {
468        if (TraceRow.rangeSelectObject) {
469          let showTab = sp.getShowTab();
470          sp.traceSheetEL
471            ?.displayTab<TabPaneCurrent>('tabpane-current', ...showTab)
472            .setCurrentSlicesTime(sp.slicestime);
473        } else {
474          sp.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current').setCurrentSlicesTime(sp.slicestime);
475        }
476      }
477    }
478    if (keyPress === 'f') {
479      // 设置当前的slicesTime
480      sp.setCurrentSlicesTime();
481    }
482    let keyPressWASD = keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd';
483    if (keyPressWASD) {
484      sp.keyPressMap.set(keyPress, true);
485      sp.hoverFlag = null;
486    }
487    sp.timerShaftEL!.documentOnKeyPress(ev, sp.currentSlicesTime);
488    if (keyPress === 'f') {
489      sp.verticalScrollToRow();
490    }
491  } else {
492    sp.stopWASD();
493  }
494}
495
496export function spSystemTraceDocumentOnMouseDown(sp: SpSystemTrace, ev: MouseEvent) {
497  if (!sp.loadTraceCompleted || !sp.mouseEventEnable) {
498    return;
499  }
500  if (sp.isWASDKeyPress()) {
501    ev.preventDefault();
502    ev.stopPropagation();
503    return;
504  }
505  if (ev.button === 0) {
506    sp.isMouseLeftDown = true;
507    if (ev.ctrlKey) {
508      ev.preventDefault();
509      sp.style.cursor = 'move';
510      sp.mouseCurrentPosition = ev.clientX;
511      return;
512    }
513  }
514
515  TraceRow.isUserInteraction = true;
516  if (sp.isMouseInSheet(ev)) {
517    return;
518  }
519  sp.observerScrollHeightEnable = false;
520  if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) {
521    let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft;
522    let y = ev.offsetY;
523    sp.timerShaftEL?.documentOnMouseDown(ev);
524    if (
525      !(
526        sp.timerShaftEL!.sportRuler!.frame.contains(x, y) &&
527        x > (TraceRow.rangeSelectObject?.startX || 0) &&
528        x < (TraceRow.rangeSelectObject?.endX || 0)
529      )
530    ) {
531      sp.rangeSelect.mouseDown(ev);
532      sp.rangeSelect.drag = true;
533    }
534    //  如果鼠标摁下事件发生在traceRow范围或时间轴(sportRuler除外)范围内,清除上次点击调用栈产生的所有的三角旗子
535    // ev.offsetY:鼠标在SpSystemTrace元素的y轴偏移量
536    if (
537      ev.offsetY > sp.timerShaftEL!.clientHeight ||
538      ev.offsetY < sp.timerShaftEL!.clientHeight - sp.timerShaftEL!.sportRuler!.frame.height
539    ) {
540      sp.clearTriangle(sp.timerShaftEL!.sportRuler!.flagList);
541    }
542  } else {
543    sp.rangeSelect.drag = false;
544  }
545}
546
547function handleTimerShaftActions(ev: MouseEvent, sp: SpSystemTrace) {
548  if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) {
549    let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft;
550    let y = ev.offsetY;
551    if (sp.timerShaftEL!.sportRuler!.frame.contains(x, y) &&
552      x > (TraceRow.rangeSelectObject?.startX || 0) &&
553      x < (TraceRow.rangeSelectObject?.endX || 0)) {
554      let findSlicestime = sp.timerShaftEL!.sportRuler?.findSlicesTime(x, y); // 查找帽子
555      if (!findSlicestime) {
556        // 如果没有找到帽子,则绘制一个旗子
557        let time = Math.round(
558          (x * (TraceRow.range?.endNS! - TraceRow.range?.startNS!)) / sp.timerShaftEL!.canvas!.offsetWidth +
559          TraceRow.range?.startNS!
560        );
561        sp.timerShaftEL!.sportRuler!.drawTriangle(time, 'squre');
562      }
563    }
564  }
565}
566
567export function spSystemTraceDocumentOnMouseUp(sp: SpSystemTrace, ev: MouseEvent) {
568  if ((window as any).collectResize) {
569    return;
570  }
571  if (!sp.loadTraceCompleted || !sp.mouseEventEnable) {
572    return;
573  }
574  if (sp.isWASDKeyPress()) {
575    ev.preventDefault();
576    ev.stopPropagation();
577    return;
578  }
579  sp.isMouseLeftDown = false;
580  if (ev.ctrlKey) {
581    ev.preventDefault();
582    sp.offsetMouse = 0;
583    sp.mouseCurrentPosition = 0;
584    sp.style.cursor = 'default';
585    return;
586  }
587  TraceRow.isUserInteraction = false;
588  sp.rangeSelect.isMouseDown = false;
589  if ((window as any).isSheetMove) {
590    return;
591  }
592  if (sp.isMouseInSheet(ev)) {
593    return;
594  }
595  handleTimerShaftActions(ev, sp);
596  if (!SportRuler.isMouseInSportRuler) {
597    sp.rangeSelect.mouseUp(ev);
598  }
599  sp.timerShaftEL?.documentOnMouseUp(ev);
600}
601
602export function spSystemTraceDocumentOnKeyUp(sp: SpSystemTrace, ev: KeyboardEvent) {
603  if (sp.times.size > 0) {
604    for (let timerId of sp.times) {
605      clearTimeout(timerId);
606    }
607  }
608  if (ev.key.toLocaleLowerCase() === '?') {
609    document.querySelector('body > sp-application')!
610      .shadowRoot!.querySelector<SpKeyboard>('#sp-keyboard')!.style.visibility = 'visible';
611  }
612  if (!sp.loadTraceCompleted) return;
613  sp.keyboardEnable && enableVSync(false, ev, () => sp.refreshCanvas(true));
614  let keyPress = ev.key.toLocaleLowerCase();
615  if (keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd') {
616    sp.keyPressMap.set(keyPress, false);
617  }
618  TraceRow.isUserInteraction = false;
619  sp.observerScrollHeightEnable = false;
620  sp.keyboardEnable && sp.timerShaftEL!.documentOnKeyUp(ev);
621  if (ev.code === 'Enter') {
622    document.removeEventListener('keydown', sp.documentOnKeyDown);
623    if (ev.shiftKey) {
624      sp.dispatchEvent(
625        new CustomEvent('trace-previous-data', {
626          detail: {},
627          composed: false,
628        })
629      );
630    } else {
631      sp.dispatchEvent(
632        new CustomEvent('trace-next-data', {
633          detail: {},
634          composed: false,
635        })
636      );
637    }
638    document.addEventListener('keydown', sp.documentOnKeyDown);
639  }
640  if (ev.ctrlKey) {
641    spSystemTraceDocumentOnKeyUpCtrlKey(keyPress, sp);
642  }
643}
644
645function spSystemTraceDocumentOnKeyUpCtrlKey(keyPress: string, sp: SpSystemTrace) {
646  if (keyPress === '[' && sp._slicesList.length > 1) {
647    sp.MarkJump(sp._slicesList, 'slice', 'previous');
648  } else if (keyPress === ',' && sp._flagList.length > 1) {
649    sp.MarkJump(sp._flagList, 'flag', 'previous');
650  } else if (keyPress === ']' && sp._slicesList.length > 1) {
651    sp.MarkJump(sp._slicesList, 'slice', 'next');
652  } else if (keyPress === '.' && sp._flagList.length > 1) {
653    sp.MarkJump(sp._flagList, 'flag', 'next');
654  } else {
655    return;
656  }
657}
658
659function handleClickActions(sp: SpSystemTrace, x: number, y: number, ev: MouseEvent) {
660  if (
661    !(sp.timerShaftEL!.sportRuler!.frame.contains(x, y) &&
662      x > (TraceRow.rangeSelectObject?.startX || 0) &&
663      x < (TraceRow.rangeSelectObject?.endX || 0))
664  ) {
665    let inFavoriteArea = sp.favoriteChartListEL?.containPoint(ev);
666    let rows = sp.visibleRows.filter((it) => it.focusContain(ev, inFavoriteArea!) && it.collect === inFavoriteArea);
667    if (JankStruct.delJankLineFlag) {
668      sp.removeLinkLinesByBusinessType('janks');
669    }
670    if (rows && rows[0] && sp.traceRowClickJudgmentConditions.get(rows[0]!.rowType!)?.()) {
671      sp.onClickHandler(rows[0]!.rowType!, rows[0]);
672      sp.documentOnMouseMove(ev);
673    } else {
674      sp.clickEmptyArea();
675    }
676  }
677}
678
679export function spSystemTraceDocumentOnClick(sp: SpSystemTrace, ev: MouseEvent) {
680  if (!sp.loadTraceCompleted) {
681    return;
682  }
683  if (sp.isWASDKeyPress()) {
684    sp.hoverFlag = null;
685    ev.preventDefault();
686    ev.stopPropagation();
687    return;
688  }
689  if ((window as any).isSheetMove) {
690    return;
691  }
692  if (sp.isMouseInSheet(ev)) {
693    return;
694  }
695  if ((window as any).isPackUpTable) {
696    (window as any).isPackUpTable = false;
697    return;
698  }
699  let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft;
700  let y = ev.offsetY;
701  if (sp.timerShaftEL?.getRangeRuler()?.frame.contains(x, y)) {
702    sp.clickEmptyArea();
703    return;
704  }
705  if (sp.rangeSelect.isDrag()) {
706    return;
707  }
708  handleClickActions(sp, x, y, ev);
709  ev.preventDefault();
710}
711
712export function spSystemTraceDocumentOnKeyDown(sp: SpSystemTrace, ev: KeyboardEvent) {
713  document.removeEventListener('keyup', sp.documentOnKeyUp);
714  sp.debounce(sp.continueSearch, 250, ev)();
715  document.addEventListener('keyup', sp.documentOnKeyUp);
716}
717