Skip to content

Package: EMFFormsSWTLayoutDelayed

EMFFormsSWTLayoutDelayed

nameinstructionbranchcomplexitylinemethod
EMFFormsSWTLayoutDelayed()
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
exchangeRequestedLayouts()
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getReportService()
M: 30 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 11 C: 0
0%
M: 1 C: 0
0%
getRequestedLayouts()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$0(Display)
M: 1 C: 12
92%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
lambda$1(Set)
M: 9 C: 26
74%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 1 C: 8
89%
M: 0 C: 1
100%
layout(Composite)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
layoutDelayed()
M: 0 C: 22
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
setRequestedLayouts(Set)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2017 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Eugen Neufeld - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emfforms.spi.swt.core.layout;
15:
16: import java.util.LinkedHashSet;
17: import java.util.Set;
18:
19: import org.eclipse.emfforms.spi.common.report.AbstractReport;
20: import org.eclipse.emfforms.spi.common.report.ReportService;
21: import org.eclipse.swt.widgets.Composite;
22: import org.eclipse.swt.widgets.Display;
23: import org.osgi.framework.Bundle;
24: import org.osgi.framework.BundleContext;
25: import org.osgi.framework.FrameworkUtil;
26: import org.osgi.framework.ServiceReference;
27:
28: /**
29: * This Layout Optimizer caches the incoming layout request for 200ms before triggering the layout.
30: *
31: * @author Eugen Neufeld
32: * @since 1.12
33: *
34: */
35: public class EMFFormsSWTLayoutDelayed implements EMFFormsSWTLayoutOptimizer {
36:
37:         private Set<Composite> requestedLayouts = new LinkedHashSet<Composite>();
38:         private Thread thread;
39:         private ReportService reportService;
40:
41:         /**
42:          * <p>
43:          * This method will collect layoutrequest that happen in the same 200ms. When there are multiple layoutrequest for
44:          * the same composite in this time frame, the composite will only be layouted once.
45:          * </p>
46:          * <p>
47:          * This will help to improve performance as layout request are usually expensive. Also it might be quite common that
48:          * e.g. multiple hide rules are triggered by the same condition.
49:          * </p>
50:          *
51:          * @param parent the composite to layout
52:          */
53:         @Override
54:         public synchronized void layout(Composite parent) {
55:                 getRequestedLayouts().add(parent);
56:                 layoutDelayed();
57:         }
58:
59:         private synchronized void layoutDelayed() {
60:•                if (thread != null || getRequestedLayouts().isEmpty()) {
61:                         return;
62:                 }
63:                 final Display defaultDisplay = Display.getDefault();
64:                 thread = new Thread(() -> {
65:                         try {
66:                                 Thread.sleep(200);
67:                         } catch (final InterruptedException ex) {
68:                                 /* silent */
69:                         }
70:                         final Set<Composite> toLayout = exchangeRequestedLayouts();
71:
72:                         defaultDisplay.asyncExec(() -> {
73:                                 // BEGIN COMPLEX CODE
74:                                 try {
75:•                                        for (final Composite composite : toLayout) {
76:•                                                if (composite.isDisposed()) {
77:                                                         continue;
78:                                                 }
79:                                                 composite.layout(true, true);
80:                                         }
81:                                 } catch (final Exception ex) {
82:                                         getReportService().report(new AbstractReport(ex, "An exception occurred during re-layouting")); //$NON-NLS-1$
83:                                 } finally {
84:                                         // To avoid memory leaks we need to reset the thread in any case.
85:                                         thread = null;
86:                                         layoutDelayed();
87:                                 }
88:                                 // END COMPLEX CODE
89:                         });
90:
91:                 });
92:                 thread.start();
93:         }
94:
95:         private ReportService getReportService() {
96:•                if (reportService == null) {
97:                         final Bundle bundle = FrameworkUtil.getBundle(EMFFormsSWTLayoutDelayed.class);
98:•                        if (bundle == null) {
99:                                 return null;
100:                         }
101:                         final BundleContext bundleContext = bundle.getBundleContext();
102:•                        if (bundleContext == null) {
103:                                 return null;
104:                         }
105:                         final ServiceReference<ReportService> serviceReference = bundleContext
106:                                 .getServiceReference(ReportService.class);
107:                         reportService = bundleContext.getService(serviceReference);
108:                 }
109:                 return reportService;
110:         }
111:
112:         private synchronized Set<Composite> getRequestedLayouts() {
113:                 return requestedLayouts;
114:         }
115:
116:         private synchronized void setRequestedLayouts(Set<Composite> requestedLayouts) {
117:                 this.requestedLayouts = requestedLayouts;
118:         }
119:
120:         private synchronized Set<Composite> exchangeRequestedLayouts() {
121:                 final Set<Composite> toLayout = new LinkedHashSet<Composite>(getRequestedLayouts());
122:                 setRequestedLayouts(new LinkedHashSet<Composite>());
123:                 return toLayout;
124:         }
125: }