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