Dart Documentationdartkart.layerTileCache

TileCache class

An instance of this class maintains a cache of ImageElements for already downloaded map tiles.

The size of the cache is bound. The least recently accessed map tile is removed from the cache first, if the upper limit of the maps size is reached.

class TileCache {

 /// default tile cache size
 static const DEFAULT_CAPACITY = 200;

 final Map<String, ImageElement>  _map = new Map();
 final Queue<ImageElement> _access = new Queue();

 final int capacity;

 /**
  * Creates the tile cache with [capacity] as upper
  * capacity limit.
  */
 TileCache({this.capacity: DEFAULT_CAPACITY});

 /**
  *  Lookup (or create) an [ImageElement] for [url].
  *
  *  If the image isn't in the cache then [onLoad] and [onError]
  *  are invoked later when the image is successfully loaded or
  *  when an error occurs respectively.
  */
 ImageElement lookup(String url, {onLoad(event), onError(event)}){
   var img = _map[url];
   if (img != null) {
     _access.remove(img);
     _access.addFirst(img);
     return img;
   }
   img = new Element.tag("img");
   _map[url] = img;
   if (_access.length >= capacity) {
     _access.removeLast();
   }
   _access.addFirst(img);
   var sub1, sub2;
   cancel() => [sub1, sub2].where((s) => s!=null).forEach((s) => s.cancel());
   if (onLoad != null) {
     sub1 = img.onLoad.listen((e) {
       cancel();
       onLoad(e);
     });
   }
   if (onError != null) {
     sub2 = img.onError.listen((e) {
       cancel();
       onError(e);
     });
   }

   //TODO: temporary- replace later
   img.onAbort.listen((e) {
     print("Image loading -> aborted ...");
   });
   img.src = url;
   return img;
 }

 /**
  * Replies the tile image for [url] if it is already in the cache
  * and complete. Otherwise, returns null.
  */
 ImageElement get(String url) {
   var img = _map[url];
   if (img != null && img.complete) {
     _access.remove(img);
     _access.addFirst(img);
     return img;
   } else {
     return null;
   }
 }

 /**
  * Purges [obj] from the cache.
  *
  * ## Possible values for [obj]
  * 
  * * an URL as [String]
  * * an [ImageElement]
  *
  * Otherwise throws an [ArgumentError].
  *
  * Nothing is purged from the cache if [obj] is null.
  */
 void purge(obj) {
   if (obj == null) return;
   if (obj is String) {
     obj = _map[obj];
   } else if (obj is ImageElement) {
     obj = _map.values.firstWhere((img) => img == obj);
   } else {
     throw new ArgumentError("expected a String or an ImageElement, "
         "got $obj"
     );
   }
   if (obj == null) return;
   _access.remove(obj);
   _map.remove(obj.src);
 }
}

Static Properties

const DEFAULT_CAPACITY #

default tile cache size

static const DEFAULT_CAPACITY = 200

Constructors

new TileCache({int capacity: DEFAULT_CAPACITY}) #

Creates the tile cache with capacity as upper capacity limit.

TileCache({this.capacity: DEFAULT_CAPACITY});

Properties

final int capacity #

final int capacity

Methods

ImageElement get(String url) #

Replies the tile image for url if it is already in the cache and complete. Otherwise, returns null.

ImageElement get(String url) {
 var img = _map[url];
 if (img != null && img.complete) {
   _access.remove(img);
   _access.addFirst(img);
   return img;
 } else {
   return null;
 }
}

ImageElement lookup(String url, {onLoad(event), onError(event)}) #

Lookup (or create) an ImageElement for url.

If the image isn't in the cache then onLoad and onError are invoked later when the image is successfully loaded or when an error occurs respectively.

ImageElement lookup(String url, {onLoad(event), onError(event)}){
 var img = _map[url];
 if (img != null) {
   _access.remove(img);
   _access.addFirst(img);
   return img;
 }
 img = new Element.tag("img");
 _map[url] = img;
 if (_access.length >= capacity) {
   _access.removeLast();
 }
 _access.addFirst(img);
 var sub1, sub2;
 cancel() => [sub1, sub2].where((s) => s!=null).forEach((s) => s.cancel());
 if (onLoad != null) {
   sub1 = img.onLoad.listen((e) {
     cancel();
     onLoad(e);
   });
 }
 if (onError != null) {
   sub2 = img.onError.listen((e) {
     cancel();
     onError(e);
   });
 }

 //TODO: temporary- replace later
 img.onAbort.listen((e) {
   print("Image loading -> aborted ...");
 });
 img.src = url;
 return img;
}

void purge(obj) #

Purges obj from the cache.

Possible values for obj

  • an URL as String
  • an ImageElement

Otherwise throws an ArgumentError.

Nothing is purged from the cache if obj is null.

void purge(obj) {
 if (obj == null) return;
 if (obj is String) {
   obj = _map[obj];
 } else if (obj is ImageElement) {
   obj = _map.values.firstWhere((img) => img == obj);
 } else {
   throw new ArgumentError("expected a String or an ImageElement, "
       "got $obj"
   );
 }
 if (obj == null) return;
 _access.remove(obj);
 _map.remove(obj.src);
}