1
1
package software .xdev .vaadin .maps .leaflet .flow .demo ;
2
2
3
- import java .util .ArrayList ;
4
3
import java .util .LinkedHashMap ;
5
4
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 ;
10
5
11
6
import org .slf4j .Logger ;
12
7
import org .slf4j .LoggerFactory ;
13
8
14
9
import com .vaadin .flow .component .ClientCallable ;
15
- import com .vaadin .flow .component .UI ;
16
10
import com .vaadin .flow .component .button .Button ;
17
11
import com .vaadin .flow .component .dialog .Dialog ;
18
12
import com .vaadin .flow .component .icon .Icon ;
19
13
import com .vaadin .flow .component .icon .VaadinIcon ;
20
14
import com .vaadin .flow .component .orderedlayout .HorizontalLayout ;
21
- import com .vaadin .flow .component .orderedlayout .VerticalLayout ;
22
15
import com .vaadin .flow .router .Route ;
23
16
24
17
import elemental .json .JsonObject ;
52
45
import software .xdev .vaadin .maps .leaflet .registry .LDefaultComponentManagementRegistry ;
53
46
54
47
55
- @ Route ("" )
56
- public class LeafletView extends VerticalLayout
48
+ @ Route (ComplexDemo . NAV )
49
+ public class ComplexDemo extends AbstractDemo
57
50
{
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 );
59
54
private static final String ID = "leaflet-demo-view" ;
60
55
61
56
private final LDefaultComponentManagementRegistry reg ;
62
57
private final LMap map ;
63
58
private final HorizontalLayout hlButtons = new HorizontalLayout ();
64
59
65
- public LeafletView ()
60
+ public ComplexDemo ()
66
61
{
67
- // Add an Id to the current view so that we can later find it in JS and do a callback
68
62
this .setId (ID );
69
63
70
- // Create the registry which allows reusing components and invoking methods
71
64
this .reg = new LDefaultComponentManagementRegistry (this );
72
65
73
- // Create and add the MapContainer (which will contain the map) to the UI
74
66
final MapContainer mapContainer = new MapContainer (this .reg );
75
67
mapContainer .setSizeFull ();
76
68
this .add (mapContainer );
@@ -129,7 +121,7 @@ public LeafletView()
129
121
""" )
130
122
.withIconSize (new LPoint (this .reg , 125 , 25 )));
131
123
132
- final LLatLng locationXDEV = new LLatLng (this .reg , 49.675806 , 12.1609901 );
124
+ final LLatLng locationXDEV = new LLatLng (this .reg , 49.6756 , 12.1610 );
133
125
final LMarker markerXDEV =
134
126
new LMarker (this .reg , locationXDEV , new LMarkerOptions ().withIcon (iconXDEV ))
135
127
.bindPopup ("<a href='https://xdev.software' target='_blank'>XDEV Software GmbH</a>" );
@@ -192,7 +184,6 @@ public LeafletView()
192
184
this .addImageOverlayDemo ();
193
185
this .addVideoOverlayDemo ();
194
186
this .addComplexPolygonDemo ();
195
- this .addMemoryTestDemo ();
196
187
197
188
this .addOpenDialogOverMapDemo ();
198
189
}
@@ -372,116 +363,6 @@ private void addComplexPolygonDemo()
372
363
));
373
364
}
374
365
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
-
485
366
private void addOpenDialogOverMapDemo ()
486
367
{
487
368
this .hlButtons .add (
@@ -499,27 +380,4 @@ private void addOpenDialogOverMapDemo()
499
380
icoClose .addClickListener (iev -> dialog .close ());
500
381
}));
501
382
}
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
- }
525
383
}
0 commit comments