• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 package ohos.devtools.views.trace;
17 
18 import com.intellij.ui.JBColor;
19 import com.intellij.util.ui.JBUI;
20 import ohos.devtools.views.trace.util.Utils;
21 
22 import javax.swing.SwingUtilities;
23 import javax.swing.border.LineBorder;
24 import java.awt.Graphics;
25 import java.awt.Graphics2D;
26 import java.awt.Point;
27 import java.util.Arrays;
28 import java.util.List;
29 import java.util.Objects;
30 import java.util.concurrent.CompletableFuture;
31 import java.util.function.Supplier;
32 
33 import static java.util.Objects.nonNull;
34 
35 /**
36  * TraceThreadRow
37  *
38  * @since 2021/5/18 13:56
39  */
40 public class TraceThreadRow<T extends AbstractNode, R extends AbstractNode> extends AbstractRow {
41     private final Integer tid;
42     private IRender render;
43     private List<T> data;
44     private List<R> data2;
45     private T currentData;
46     private R currentData2;
47     private Supplier<List<T>> supplier;
48     private Supplier<List<R>> supplier2;
49     private Long rangeStartNS;
50     private Long rangeEndNS;
51     private Integer x1;
52     private Integer x2;
53     private String threadName;
54 
55     /**
56      * structure
57      *
58      * @param name name
59      * @param tid tid
60      */
TraceThreadRow(String name, Integer tid)61     public TraceThreadRow(String name, Integer tid) {
62         super(name + "(Tid:" + tid + ")", true, false);
63         this.tid = tid;
64         this.threadName = name;
65         layout.setComponentConstraints(expandBtn, "split 2,gapleft 15,gaptop 3,gapbottom push");
66         layout.setComponentConstraints(nameLabel, "gapleft 5,gaptop 3,gapbottom push,w 70!");
67         loadData();
68         nameLabelClickConsumer = (event) -> {
69             setSelect(true, null, null);
70         };
71     }
72 
73     /**
74      * getTid
75      *
76      * @return Integer tid
77      */
getTid()78     public Integer getTid() {
79         return tid;
80     }
81 
82     /**
83      * setRender
84      *
85      * @param render set current render
86      */
setRender(IRender<T, R> render)87     public void setRender(IRender<T, R> render) {
88         this.render = render;
89     }
90 
91     /**
92      * set thread Supplier
93      *
94      * @param supplier set thread supplier
95      */
setSupplier(Supplier<List<T>> supplier)96     public void setSupplier(Supplier<List<T>> supplier) {
97         this.supplier = supplier;
98     }
99 
100     /**
101      * set thread function Supplier
102      *
103      * @param supplier set thread function supplier
104      */
setSupplier2(Supplier<List<R>> supplier)105     public void setSupplier2(Supplier<List<R>> supplier) {
106         this.supplier2 = supplier;
107     }
108 
109     @Override
contentPaint(Graphics graphics)110     public void contentPaint(Graphics graphics) {
111         if (render != null && graphics instanceof Graphics2D) {
112             Graphics2D g2 = (Graphics2D) graphics;
113             if (data != null || data2 != null) {
114                 render.paint(g2, data, data2);
115             } else {
116                 g2.setColor(JBColor.foreground());
117                 g2.drawString("Loading...", 10, 10 + 12);
118                 loadData();
119             }
120             if (nonNull(x1) && nonNull(x2)) {
121                 int xMin = Math.min(x1, x2);
122                 int xMax = Math.max(x1, x2);
123                 int width = Math.abs(x2 - x1);
124                 Common.setAlpha(g2, 0.5F);
125                 g2.setColor(JBColor.foreground().darker());
126                 g2.fillRect(0, 0, xMin, getHeight());
127                 g2.fillRect(xMax, 0, getWidth() - xMax, getHeight());
128                 Common.setAlpha(g2, 1F);
129             }
130         }
131     }
132 
133     @Override
mouseMoveHandler(Point point)134     public void mouseMoveHandler(Point point) {
135         super.mouseMoveHandler(point);
136         if (nonNull(data)) {
137             if (data.stream().filter(it -> contains(it)).anyMatch(it -> it.getRect().contains(point))) {
138                 data.stream().filter(it -> contains(it) && it.getRect().contains(point)).forEach(it -> {
139                     List<String> stringList = it.getStringList(getTimeByX(Utils.getX(point)));
140                     Tip.getInstance().display(content, point, stringList);
141                     if (Objects.nonNull(currentData)) {
142                         currentData.moveOut(point, content);
143                     }
144                     it.moveIn(point, content);
145                     currentData = it;
146                 });
147                 return;
148             } else {
149                 if (Objects.nonNull(currentData)) {
150                     currentData.moveOut(point, content);
151                 }
152                 Tip.getInstance().display(content, point,
153                     Arrays.asList(getTimeByX(Utils.getX(point)), "Thread:" + threadName, "Tid:" + getTid()));
154             }
155         }
156         if (nonNull(data2)) {
157             if (data2.stream().filter(it -> contains(it)).anyMatch(it -> it.getRect().contains(point))) {
158                 data2.stream().filter(it -> contains(it) && it.getRect().contains(point)).forEach(it -> {
159                     List<String> stringList = it.getStringList(getTimeByX(Utils.getX(point)));
160                     Tip.getInstance().display(content, point, stringList);
161                     if (Objects.nonNull(currentData2)) {
162                         currentData2.moveOut(point, content);
163                     }
164                     it.moveIn(point, content);
165                     currentData2 = it;
166                 });
167                 return;
168             } else {
169                 if (Objects.nonNull(currentData2)) {
170                     currentData2.moveOut(point, content);
171                 }
172                 Tip.getInstance().display(content, point,
173                     Arrays.asList(getTimeByX(Utils.getX(point)), "Thread:" + threadName, "Tid:" + getTid()));
174             }
175         }
176     }
177 
178     @Override
loadData()179     public void loadData() {
180         if (!isLoading.get()) {
181             isLoading.set(true);
182             CompletableFuture.runAsync(() -> {
183                 if (nonNull(supplier)) {
184                     data = supplier.get();
185                 }
186                 if (nonNull(supplier2)) {
187                     data2 = supplier2.get();
188                 }
189                 SwingUtilities.invokeLater(() -> {
190                     isLoading.set(false);
191                     content.repaint();
192                 });
193             }, Utils.getPool()).whenComplete((unused, throwable) -> {
194                 if (Objects.nonNull(throwable)) {
195                     throwable.printStackTrace();
196                 }
197             });
198         }
199     }
200 
201     /**
202      * setSelect
203      *
204      * @param flag flag
205      * @param x1 x1
206      * @param x2 x2
207      */
setSelect(boolean flag, Integer x1, Integer x2)208     public void setSelect(boolean flag, Integer x1, Integer x2) {
209         this.x1 = x1;
210         this.x2 = x2;
211         if (flag) {
212             if (nonNull(x1) && nonNull(x2)) {
213                 rangeStartNS = x2ns(Math.min(x1, x2));
214                 rangeEndNS = x2ns(Math.max(x1, x2));
215                 TracePanel.rangeStartNS = rangeStartNS;
216                 TracePanel.rangeEndNS = rangeEndNS;
217             }
218             setBorder(new LineBorder(JBUI.CurrentTheme.Link.linkColor(), 1));
219             setBackground(JBUI.CurrentTheme.Link.linkSecondaryColor());
220         } else {
221             rangeStartNS = null;
222             rangeEndNS = null;
223             setBorder(null);
224             setBackground(JBColor.background());
225         }
226     }
227 
228     @Override
refreshNotify()229     public void refreshNotify() {
230         super.refreshNotify();
231         if (nonNull(rangeStartNS) && nonNull(rangeEndNS)) {
232             x1 = (int) Common.ns2x(rangeStartNS, getContentBounds());
233             x2 = (int) Common.ns2x(rangeEndNS, getContentBounds());
234         }
235     }
236 
x2ns(int x1)237     private long x2ns(int x1) {
238         long start = Math.min(startNS, endNS);
239         long end = Math.max(startNS, endNS);
240         long dur = Math.abs(endNS - startNS);
241         if (x1 >= getContentBounds().width) {
242             return end;
243         }
244         if (x1 <= 0) {
245             return start;
246         }
247         double ns = x1 * (dur) * 1.0 / getContentBounds().width;
248         return (long) ns + start;
249     }
250 
251     /**
252      * Gets the value of data .
253      *
254      * @return the value of java.util.List<T>
255      */
getData()256     public List<T> getData() {
257         return data;
258     }
259 
260     /**
261      * Gets the value of data2 .
262      *
263      * @return the value of java.util.List<R>
264      */
getData2()265     public List<R> getData2() {
266         return data2;
267     }
268 
269     /**
270      * interface IRender
271      */
272     public interface IRender<T, R> {
273         /**
274          * paint
275          *
276          * @param g2 Graphics2D
277          * @param data data
278          * @param data2 data2
279          */
paint(Graphics2D g2, List<T> data, List<R> data2)280         void paint(Graphics2D g2, List<T> data, List<R> data2);
281     }
282 }
283