load<T> method

Future<Asset<T>> load<T>(
  1. AssetKey<T> key
)

Reads key's source, decodes it through the key's loader, and completes with the loaded handle. A no-op returning the same handle if it is already loaded.

Throws if key was never declared. That is deliberate rather than a convenience lazy-declare: declaring here would assign an address on this copy alone, and the two copies would silently disagree about every address after it. Declare in a describeAssets pass, which both copies run.

Call this only on the isolate that can decode - GameState.loadScene already does exactly that for a scene's declared set.

Implementation

Future<Asset<T>> load<T>(AssetKey<T> key) {
  final identity = _identityOf(key);
  final asset = _byIdentity[identity] as Asset<T>?;
  if (asset == null) {
    throw StateError(
      '${key.debugLabel} has not been declared, so there is nothing to load '
      'into. Declare it from a describeAssets pass '
      '(`descriptor.has(theKey)`) on a prefab or a SceneStruct: declaring is '
      'what assigns the asset its address, and it has to happen on both '
      'isolate copies in the same order for that address to mean the same '
      'thing on both sides.',
    );
  }
  if (asset.isLoaded) return Future<Asset<T>>.value(asset);
  final inFlight = _loading[identity];
  if (inFlight != null) return inFlight.then((_) => asset);
  final future = _decode(key, asset, identity);
  _loading[identity] = future;
  return future.then((_) => asset);
}