Dart Documentationbot_htmlResourceLoader<T>

ResourceLoader<T> abstract class

abstract class ResourceLoader<T> {
  static const String StateUnloaded = 'unloaded';
  static const String StateLoading = 'loading';
  static const String StateLoaded = 'loaded';
  static const String StateError = 'error';

  static const int _defaultSize = 2000;

  final ReadOnlyCollection<_ResourceEntry<T>> _entries;
  final EventHandle<EventArgs> _loadedEvent= new EventHandle<EventArgs>();
  final EventHandle<EventArgs> _progressEvent = new EventHandle<EventArgs>();

  String _state = StateUnloaded;

  // DARTBUG: dart2js
  // Closures inside initializers not implemented
  // http://code.google.com/p/dart/issues/detail?id=3905
  static _buildRORE(Iterable<String> urlList) {
    return $(urlList).map((url) => new _ResourceEntry(url))
        .toReadOnlyCollection();
  }

  ResourceLoader(Iterable<String> urlList) :
    _entries = _buildRORE(urlList);

  int get completedCount => _entries.count((e) => e.completed);

  String get state => _state;

  EventRoot get loaded => _loadedEvent;

  EventRoot get progress => _progressEvent;

  T getResource(String url) => _getByUrl(url).resource;

  int get completedBytes {
    return _entries.selectNumbers((e) => e.completedBytes).sum();
  }

  int get totalBytes {
    return _entries.selectNumbers((e) {
      if(e.totalBytes == null) {
        return _defaultSize;
      } else {
        return e.totalBytes;
      }
    }).sum();
  }

  void load() {
    assert(_state == StateUnloaded);
    _state = StateLoading;
    for(final e in _entries) {
      _httpLoad(e.url);
    }
  }

  // protected
  void _doLoad(String blobUrl);

  // protected
  void _loadResourceFailed(String blobUrl) {
    // TODO: report error some how?
    final e = _getByBlobUrl(blobUrl);
    print(["failled to load resources with blobUrl", e.url]);
    e.revokeBlobUrl();
  }

  // protected
  void _loadResourceSucceed(String blobUrl, T resource) {
    assert(_state == StateLoading);
    assert(resource != null);

    final entry = _getByBlobUrl(blobUrl);
    entry.revokeBlobUrl();

    entry.setResource(resource);

    if(_entries.every((e) => e.completed)) {
      _state = StateLoaded;
      _loadedEvent.fireEvent(EventArgs.empty);
    }
  }

  _ResourceEntry<T> _getByUrl(String url) {
    assert(url != null);
    return _entries.single((e) => e.url == url);
  }

  _ResourceEntry<T> _getByBlobUrl(String blobUrl) {
    assert(blobUrl != null);
    return _entries.single((e) => e.matchesBlobUrl(blobUrl));
  }

  void _httpLoad(String url) {
    final request = new HttpRequest();

    final e = _getByUrl(url);

    request.on.abort.add((args) => _onError(e, args));
    request.on.error.add((args) => _onError(e, args));

    // use loadEnd instead
    //request.on.load.add(_onHttpEvent);
    request.on.loadEnd.add((args) => _onLoadEnd(e, args));

    // loadStart is not that interesting
    //request.on.loadStart.add(_onHttpEvent);
    request.on.progress.add((args) => _onProgress(e, args));

    // doesn't seem to add anything over other methods
    // request.on.readyStateChange.add(_onHttpEvent);
    request.open('GET', url);
    request.responseType = 'blob';
    request.send();
  }

  void _onLoadEnd(_ResourceEntry<T> entry, HttpRequestProgressEvent args) {
    final HttpRequest request = args.currentTarget;
    assert(request.readyState == HttpRequest.DONE);
    if(request.status == 200) {
      final blobUrl = entry.getBlobUrl(request.response);
      _doLoad(blobUrl);
    } else {
      _onError(entry, args);
    }
  }

  void _onError(_ResourceEntry<T> entry, HttpRequestProgressEvent args) {
    // some error thingy here...
    throw 'wtf?';
  }

  void _onProgress(_ResourceEntry<T> entry, HttpRequestProgressEvent args) {
    assert(args.type == 'progress');
    assert(args.lengthComputable);

    // DARTBUG: sanity checks for http://code.google.com/p/dart/issues/detail?id=5373
    assert(args.totalSize == args.total);
    assert(args.position == args.loaded);

    if(entry.updateProgress(args.loaded, args.totalSize)) {
      _progressEvent.fireEvent(EventArgs.empty);
    }
  }
}

Subclasses

AudioLoader, ImageLoader

Constructors

new ResourceLoader(Iterable<String> urlList) #

ResourceLoader(Iterable<String> urlList) :
  _entries = _buildRORE(urlList);

Static Properties

const String StateError #

static const String StateError = 'error';

const String StateLoaded #

static const String StateLoaded = 'loaded';

const String StateLoading #

static const String StateLoading = 'loading';

const String StateUnloaded #

static const String StateUnloaded = 'unloaded';

Properties

final int completedBytes #

int get completedBytes {
  return _entries.selectNumbers((e) => e.completedBytes).sum();
}

final int completedCount #

int get completedCount => _entries.count((e) => e.completed);

final EventRoot loaded #

EventRoot get loaded => _loadedEvent;

final EventRoot progress #

EventRoot get progress => _progressEvent;

final Type runtimeType #

inherited from Object

A representation of the runtime type of the object.

external Type get runtimeType;

final String state #

String get state => _state;

final int totalBytes #

int get totalBytes {
  return _entries.selectNumbers((e) {
    if(e.totalBytes == null) {
      return _defaultSize;
    } else {
      return e.totalBytes;
    }
  }).sum();
}

Operators

bool operator ==(other) #

inherited from Object

The equality operator.

The default behavior for all Objects is to return true if and only if this and other are the same object.

If a subclass overrides the equality operator it should override the hashCode method as well to maintain consistency.

bool operator ==(other) => identical(this, other);

Methods

T getResource(String url) #

T getResource(String url) => _getByUrl(url).resource;

int hashCode() #

inherited from Object

Get a hash code for this object.

All objects have hash codes. Hash codes are guaranteed to be the same for objects that are equal when compared using the equality operator ==. Other than that there are no guarantees about the hash codes. They will not be consistent between runs and there are no distribution guarantees.

If a subclass overrides hashCode it should override the equality operator as well to maintain consistency.

external int hashCode();

void load() #

void load() {
  assert(_state == StateUnloaded);
  _state = StateLoading;
  for(final e in _entries) {
    _httpLoad(e.url);
  }
}

noSuchMethod(String name, List args) #

inherited from Object

noSuchMethod is invoked when users invoke a non-existant method on an object. The name of the method and the arguments of the invocation are passed to noSuchMethod. If noSuchMethod returns a value, that value becomes the result of the original invocation.

The default behavior of noSuchMethod is to throw a noSuchMethodError.

external Dynamic noSuchMethod(String name, List args);

const Object() #

inherited from Object

Creates a new Object instance.

Object instances have no meaningful state, and are only useful through their identity. An Object instance is equal to itself only.

const Object();

new ResourceLoader(Iterable<String> urlList) #

ResourceLoader(Iterable<String> urlList) :
  _entries = _buildRORE(urlList);

String toString() #

inherited from Object

Returns a string representation of this object.

external String toString();