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 { BaseStruct } from './BaseStruct';
17import { Utils } from '../component/trace/base/Utils';
18import { drawString } from '../database/ui-worker/ProcedureWorkerCommon';
19
20const padding = 1;
21
22export class ThreadStruct extends BaseStruct {
23  static runningColor: string = '#467b3b';
24  static rColor = '#a0b84d';
25  static uninterruptibleSleepColor = '#f19d38';
26  static sColor = '#FBFBFB';
27  static hoverThreadStruct: ThreadStruct | undefined;
28  static selectThreadStruct: ThreadStruct | undefined;
29  static selectThreaStructList: Array<ThreadStruct> = [];
30  hasSched: number | undefined;
31  pid: number | undefined;
32  processName: string | undefined;
33  threadName: string | undefined;
34  tid: number | undefined;
35  upid: number | undefined;
36  utid: number | undefined;
37  switchCount: number | undefined;
38  cpu: number | undefined;
39  dur: number | undefined;
40  end_ts: number | undefined;
41  id: number | undefined;
42  is_main_thread: number | undefined;
43  name: string | undefined;
44  startTime: number | undefined;
45  start_ts: number | undefined;
46  state: string | undefined;
47  type: string | undefined;
48  prio: number | undefined;
49  curveFloatY: number | undefined;
50
51  static draw(threadBeanCanvasCtx: CanvasRenderingContext2D, threadBeanStructData: ThreadStruct): void {
52    if (threadBeanStructData.frame) {
53      threadBeanCanvasCtx.globalAlpha = 1;
54      let stateText = threadBeanStructData.state || '';
55      if ('S' === threadBeanStructData.state) {
56        threadBeanCanvasCtx.fillStyle = ThreadStruct.sColor;
57        threadBeanCanvasCtx.globalAlpha = 0.2; // transparency
58        threadBeanCanvasCtx.fillRect(
59          threadBeanStructData.frame.x,
60          threadBeanStructData.frame.y + padding,
61          threadBeanStructData.frame.width,
62          threadBeanStructData.frame.height - padding * 2
63        );
64        threadBeanCanvasCtx.globalAlpha = 1; // transparency
65      } else if ('R' === threadBeanStructData.state) {
66        threadBeanCanvasCtx.fillStyle = ThreadStruct.rColor;
67        this.drawRectAndString(threadBeanCanvasCtx, threadBeanStructData);
68      } else if ('D' === threadBeanStructData.state) {
69        threadBeanCanvasCtx.fillStyle = ThreadStruct.uninterruptibleSleepColor;
70        this.drawRectAndString(threadBeanCanvasCtx, threadBeanStructData);
71      } else if ('Running' === threadBeanStructData.state) {
72        threadBeanCanvasCtx.fillStyle = ThreadStruct.runningColor;
73        this.drawRectAndString(threadBeanCanvasCtx, threadBeanStructData);
74      } else {
75        threadBeanCanvasCtx.fillStyle = ThreadStruct.rColor;
76        this.drawRectAndString(threadBeanCanvasCtx, threadBeanStructData);
77      }
78      if (
79        ThreadStruct.selectThreadStruct &&
80        ThreadStruct.equals(ThreadStruct.selectThreadStruct, threadBeanStructData) &&
81        ThreadStruct.selectThreadStruct.state !== 'S'
82      ) {
83        threadBeanCanvasCtx.strokeStyle = '#232c5d';
84        threadBeanCanvasCtx.lineWidth = 2;
85        threadBeanCanvasCtx.strokeRect(
86          threadBeanStructData.frame.x,
87          threadBeanStructData.frame.y + padding,
88          threadBeanStructData.frame.width - 2,
89          threadBeanStructData.frame.height - padding * 2
90        );
91      }
92    }
93  }
94
95  private static drawRectAndString(
96    threadBeanCanvasCtx: CanvasRenderingContext2D,
97    threadBeanStructData: ThreadStruct
98  ): void {
99    // @ts-ignore
100    threadBeanCanvasCtx.fillRect(
101      threadBeanStructData.frame!.x,
102      threadBeanStructData.frame!.y + padding,
103      threadBeanStructData.frame!.width,
104      threadBeanStructData.frame!.height - padding * 2
105    );
106    threadBeanCanvasCtx.fillStyle = '#fff';
107    // @ts-ignore
108    drawString(
109      threadBeanCanvasCtx,
110      ThreadStruct.getEndState(threadBeanStructData.state || ''),
111      2,
112      threadBeanStructData.frame!,
113      threadBeanStructData
114    );
115  }
116
117  static getEndState(state: string): string {
118    let statusMapElement = Utils.getEndState(state);
119    if (statusMapElement) {
120      return statusMapElement;
121    } else {
122      if ('' === statusMapElement || statusMapElement === null) {
123        return '';
124      }
125      return 'Unknown State';
126    }
127  }
128
129  static equals(d1: ThreadStruct, d2: ThreadStruct): boolean {
130    return (
131      d1 &&
132      d2 &&
133      d1.cpu === d2.cpu &&
134      d1.tid === d2.tid &&
135      d1.state === d2.state &&
136      d1.startTime === d2.startTime &&
137      d1.dur === d2.dur
138    );
139  }
140  static contrast(d1: ThreadStruct, d2: string | undefined | null, d3: string | undefined | null): boolean {
141    return d1.pid === Number(d2) && d1.tid === Number(d3);
142  }
143}
144