Skip to content

Commit 334f2e1

Browse files
committed
Improved demos
1 parent 6ba9ec0 commit 334f2e1

File tree

6 files changed

+338
-149
lines changed

6 files changed

+338
-149
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package software.xdev.vaadin.maps.leaflet.flow;
2+
3+
import java.util.List;
4+
5+
import com.vaadin.flow.component.AttachEvent;
6+
import com.vaadin.flow.component.Composite;
7+
import com.vaadin.flow.component.grid.Grid;
8+
import com.vaadin.flow.component.grid.GridVariant;
9+
import com.vaadin.flow.component.html.Anchor;
10+
import com.vaadin.flow.component.html.Span;
11+
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
12+
import com.vaadin.flow.data.renderer.ComponentRenderer;
13+
import com.vaadin.flow.router.PageTitle;
14+
import com.vaadin.flow.router.Route;
15+
16+
import software.xdev.vaadin.maps.leaflet.flow.demo.ComplexDemo;
17+
import software.xdev.vaadin.maps.leaflet.flow.demo.FreeingUpResourceBenchmarkDemo;
18+
import software.xdev.vaadin.maps.leaflet.flow.demo.MinimalisticDemo;
19+
20+
21+
@PageTitle("Leaflet + Vaadin demos")
22+
@Route("")
23+
public class DemoView extends Composite<VerticalLayout>
24+
{
25+
private final Grid<Example> grExamples = new Grid<>();
26+
27+
public DemoView()
28+
{
29+
this.grExamples
30+
.addColumn(new ComponentRenderer<>(example -> {
31+
final Anchor anchor = new Anchor(example.route(), example.name());
32+
33+
final Span spDesc = new Span(example.desc());
34+
spDesc.getStyle().set("font-size", "90%");
35+
36+
final VerticalLayout vl = new VerticalLayout(anchor, spDesc);
37+
vl.setSpacing(false);
38+
return vl;
39+
}))
40+
.setHeader("Available demos");
41+
42+
this.grExamples.setSizeFull();
43+
this.grExamples.addThemeVariants(GridVariant.LUMO_COMPACT, GridVariant.LUMO_NO_BORDER);
44+
45+
this.getContent().add(this.grExamples);
46+
this.getContent().setHeightFull();
47+
}
48+
49+
@Override
50+
protected void onAttach(final AttachEvent attachEvent)
51+
{
52+
this.grExamples.setItems(List.of(
53+
new Example(
54+
MinimalisticDemo.NAV,
55+
"Minimalistic",
56+
"Showcasing the simplest form of using the API"
57+
),
58+
new Example(
59+
ComplexDemo.NAV,
60+
"Complex",
61+
"A complex example with various leaflet components and methods"
62+
),
63+
new Example(
64+
FreeingUpResourceBenchmarkDemo.NAV,
65+
"Freeing up resources Benchmark",
66+
"Benchmark for showcasing how resources a freed up when handling huge amounts of components"
67+
)
68+
));
69+
}
70+
71+
record Example(String route, String name, String desc)
72+
{
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package software.xdev.vaadin.maps.leaflet.flow.demo;
2+
3+
import java.util.concurrent.atomic.AtomicBoolean;
4+
5+
import com.vaadin.flow.component.button.Button;
6+
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
7+
8+
9+
public abstract class AbstractDemo extends VerticalLayout
10+
{
11+
protected Button createToggleButton(
12+
final String showText,
13+
final String hideText,
14+
final Runnable onShow,
15+
final Runnable onHide)
16+
{
17+
final AtomicBoolean shown = new AtomicBoolean(false);
18+
final Button btn = new Button(
19+
showText,
20+
ev -> {
21+
final boolean isShow = !shown.get();
22+
(isShow ? onShow : onHide).run();
23+
ev.getSource().setText(isShow ? hideText : showText);
24+
25+
shown.set(isShow);
26+
27+
ev.getSource().setEnabled(true);
28+
}
29+
);
30+
btn.setDisableOnClick(true);
31+
return btn;
32+
}
33+
}
Lines changed: 7 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
11
package software.xdev.vaadin.maps.leaflet.flow.demo;
22

3-
import java.util.ArrayList;
43
import java.util.LinkedHashMap;
54
import java.util.List;
6-
import java.util.Random;
7-
import java.util.concurrent.CompletableFuture;
8-
import java.util.concurrent.atomic.AtomicBoolean;
9-
import java.util.concurrent.atomic.AtomicLong;
105

116
import org.slf4j.Logger;
127
import org.slf4j.LoggerFactory;
138

149
import com.vaadin.flow.component.ClientCallable;
15-
import com.vaadin.flow.component.UI;
1610
import com.vaadin.flow.component.button.Button;
1711
import com.vaadin.flow.component.dialog.Dialog;
1812
import com.vaadin.flow.component.icon.Icon;
1913
import com.vaadin.flow.component.icon.VaadinIcon;
2014
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
21-
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
2215
import com.vaadin.flow.router.Route;
2316

2417
import elemental.json.JsonObject;
@@ -52,25 +45,24 @@
5245
import software.xdev.vaadin.maps.leaflet.registry.LDefaultComponentManagementRegistry;
5346

5447

55-
@Route("")
56-
public class LeafletView extends VerticalLayout
48+
@Route(ComplexDemo.NAV)
49+
public class ComplexDemo extends AbstractDemo
5750
{
58-
private static final Logger LOG = LoggerFactory.getLogger(LeafletView.class);
51+
public static final String NAV = "/complex";
52+
53+
private static final Logger LOG = LoggerFactory.getLogger(ComplexDemo.class);
5954
private static final String ID = "leaflet-demo-view";
6055

6156
private final LDefaultComponentManagementRegistry reg;
6257
private final LMap map;
6358
private final HorizontalLayout hlButtons = new HorizontalLayout();
6459

65-
public LeafletView()
60+
public ComplexDemo()
6661
{
67-
// Add an Id to the current view so that we can later find it in JS and do a callback
6862
this.setId(ID);
6963

70-
// Create the registry which allows reusing components and invoking methods
7164
this.reg = new LDefaultComponentManagementRegistry(this);
7265

73-
// Create and add the MapContainer (which will contain the map) to the UI
7466
final MapContainer mapContainer = new MapContainer(this.reg);
7567
mapContainer.setSizeFull();
7668
this.add(mapContainer);
@@ -129,7 +121,7 @@ public LeafletView()
129121
""")
130122
.withIconSize(new LPoint(this.reg, 125, 25)));
131123

132-
final LLatLng locationXDEV = new LLatLng(this.reg, 49.675806, 12.1609901);
124+
final LLatLng locationXDEV = new LLatLng(this.reg, 49.6756, 12.1610);
133125
final LMarker markerXDEV =
134126
new LMarker(this.reg, locationXDEV, new LMarkerOptions().withIcon(iconXDEV))
135127
.bindPopup("<a href='https://xdev.software' target='_blank'>XDEV Software GmbH</a>");
@@ -192,7 +184,6 @@ public LeafletView()
192184
this.addImageOverlayDemo();
193185
this.addVideoOverlayDemo();
194186
this.addComplexPolygonDemo();
195-
this.addMemoryTestDemo();
196187

197188
this.addOpenDialogOverMapDemo();
198189
}
@@ -372,116 +363,6 @@ private void addComplexPolygonDemo()
372363
));
373364
}
374365

375-
/**
376-
* Used for testing if memory on the client side is freed up correctly when handling a lot of components
377-
*/
378-
// S5413 - Yes it's used correctly
379-
// S2245 - This is a reproducible demo
380-
// S1215 - This is a memory test and we don't rely on random GC collects
381-
@SuppressWarnings({"java:S5413", "java:S2245", "java:S1215", "java:S3776"})
382-
private void addMemoryTestDemo()
383-
{
384-
final AtomicBoolean abort = new AtomicBoolean(false);
385-
386-
this.hlButtons.add(this.createToggleButton(
387-
"Start browser memory test",
388-
"Stop browser memory test",
389-
() -> {
390-
this.map.setView(new LLatLng(this.reg, 0, 0), 12);
391-
392-
abort.set(false);
393-
394-
final int bulkSize = 100;
395-
final int sizeWhenStartRemoving = 1_000;
396-
final int endWhen = 100_000;
397-
398-
final AtomicLong totallyAdded = new AtomicLong(0);
399-
final Random random = new Random(1);
400-
final UI ui = UI.getCurrent();
401-
402-
CompletableFuture.runAsync(() -> {
403-
try
404-
{
405-
final List<LMarker> markers = new ArrayList<>();
406-
while(!abort.get() && totallyAdded.get() < endWhen)
407-
{
408-
LOG.info("Totally added markers: {}; Adding bulk", totallyAdded);
409-
410-
for(int i = 0; i < bulkSize; i++)
411-
{
412-
if(markers.size() > sizeWhenStartRemoving)
413-
{
414-
final LMarker removed = markers.remove(0);
415-
416-
ui.accessSynchronously(removed::remove);
417-
}
418-
final double lat = random.nextDouble(-100, 100);
419-
final double lng = random.nextDouble(-100, 100);
420-
final double v = random.nextDouble();
421-
422-
ui.accessSynchronously(() ->
423-
markers.add(
424-
new LMarker(
425-
this.reg,
426-
new LLatLng(
427-
this.reg,
428-
lat,
429-
lng))
430-
.bindPopup("Random double: " + v)
431-
.addTo(this.map)));
432-
}
433-
434-
totallyAdded.set(totallyAdded.get() + bulkSize);
435-
436-
LOG.info("Added {}x markers; Performing GC", bulkSize);
437-
System.gc();
438-
LOG.info("Finished GC; Syncing with client");
439-
ui.accessSynchronously(this.reg::freeUpClient);
440-
441-
if(!abort.get())
442-
{
443-
LOG.info("Waiting a moment");
444-
Thread.sleep(10);
445-
}
446-
}
447-
448-
LOG.info("Ending; Clearing...");
449-
markers.forEach(m -> ui.accessSynchronously(m::remove));
450-
markers.clear();
451-
452-
for(int i = 0; i < 2; i++)
453-
{
454-
System.gc();
455-
456-
Thread.sleep(100);
457-
458-
ui.accessSynchronously(this.reg::freeUpClient);
459-
}
460-
461-
LOG.info("Done - Browser should no longer allocate a lot of RAM now");
462-
463-
ui.accessSynchronously(() -> this.reg.execJs(
464-
"alert('Finished memory test!'"
465-
+ "+'\\nTracked components on client (less is better): ' "
466-
+ "+ document.getElementById('"
467-
+ this.reg.getId().orElseThrow()
468-
+ "').lComponents.size);"));
469-
}
470-
catch(final InterruptedException ex)
471-
{
472-
Thread.currentThread().interrupt();
473-
LOG.warn("Got interrupted", ex);
474-
}
475-
catch(final Exception ex)
476-
{
477-
LOG.error("Unexpected problem while testing", ex);
478-
}
479-
});
480-
},
481-
() -> abort.set(true)
482-
));
483-
}
484-
485366
private void addOpenDialogOverMapDemo()
486367
{
487368
this.hlButtons.add(
@@ -499,27 +380,4 @@ private void addOpenDialogOverMapDemo()
499380
icoClose.addClickListener(iev -> dialog.close());
500381
}));
501382
}
502-
503-
private Button createToggleButton(
504-
final String showText,
505-
final String hideText,
506-
final Runnable onShow,
507-
final Runnable onHide)
508-
{
509-
final AtomicBoolean shown = new AtomicBoolean(false);
510-
final Button btn = new Button(
511-
showText,
512-
ev -> {
513-
final boolean isShow = !shown.get();
514-
(isShow ? onShow : onHide).run();
515-
ev.getSource().setText(isShow ? hideText : showText);
516-
517-
shown.set(isShow);
518-
519-
ev.getSource().setEnabled(true);
520-
}
521-
);
522-
btn.setDisableOnClick(true);
523-
return btn;
524-
}
525383
}

0 commit comments

Comments
 (0)