11package software .xdev .vaadin .maps .leaflet .flow .demo ;
22
3- import java .util .ArrayList ;
43import java .util .LinkedHashMap ;
54import 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
116import org .slf4j .Logger ;
127import org .slf4j .LoggerFactory ;
138
149import com .vaadin .flow .component .ClientCallable ;
15- import com .vaadin .flow .component .UI ;
1610import com .vaadin .flow .component .button .Button ;
1711import com .vaadin .flow .component .dialog .Dialog ;
1812import com .vaadin .flow .component .icon .Icon ;
1913import com .vaadin .flow .component .icon .VaadinIcon ;
2014import com .vaadin .flow .component .orderedlayout .HorizontalLayout ;
21- import com .vaadin .flow .component .orderedlayout .VerticalLayout ;
2215import com .vaadin .flow .router .Route ;
2316
2417import elemental .json .JsonObject ;
5245import 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