asset_bundle.dart 3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:sky' as sky;
import 'dart:sky.internals' as internals;
import 'dart:typed_data';

import 'package:mojo/core.dart' as core;
John McCutchan's avatar
John McCutchan committed
11
import 'package:mojo_services/mojo/asset_bundle/asset_bundle.mojom.dart';
12
import 'package:sky/base/image_resource.dart';
13 14 15 16 17 18
import 'package:sky/mojo/net/fetch.dart';
import 'package:sky/mojo/net/image_cache.dart' as image_cache;
import 'package:sky/mojo/shell.dart' as shell;

abstract class AssetBundle {
  void close();
19
  ImageResource loadImage(String key);
20 21 22 23 24 25 26 27 28 29
  Future<String> loadString(String key);
}

class NetworkAssetBundle extends AssetBundle {
  NetworkAssetBundle(Uri baseUrl) : _baseUrl = baseUrl;

  final Uri _baseUrl;

  void close() { }

30
  ImageResource loadImage(String key) {
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    return image_cache.load(_baseUrl.resolve(key).toString());
  }

  Future<String> loadString(String key) {
    return fetchString(_baseUrl.resolve(key).toString());
  }
}

Future _fetchAndUnpackBundle(String relativeUrl, AssetBundleProxy bundle) async {
  core.MojoDataPipeConsumer bundleData = (await fetchUrl(relativeUrl)).body;
  AssetUnpackerProxy unpacker = new AssetUnpackerProxy.unbound();
  shell.requestService("mojo:asset_bundle", unpacker);
  unpacker.ptr.unpackZipStream(bundleData, bundle);
  unpacker.close();
}

class MojoAssetBundle extends AssetBundle {
  MojoAssetBundle(AssetBundleProxy this._bundle);

  factory MojoAssetBundle.fromNetwork(String relativeUrl) {
    AssetBundleProxy bundle = new AssetBundleProxy.unbound();
    _fetchAndUnpackBundle(relativeUrl, bundle);
    return new MojoAssetBundle(bundle);
  }

  AssetBundleProxy _bundle;
57
  Map<String, ImageResource> _imageCache = new Map<String, ImageResource>();
58 59 60 61 62 63 64 65
  Map<String, Future<String>> _stringCache = new Map<String, Future<String>>();

  void close() {
    _bundle.close();
    _bundle = null;
    _imageCache = null;
  }

66
  ImageResource loadImage(String key) {
67 68 69 70 71
    return _imageCache.putIfAbsent(key, () {
      Completer<sky.Image> completer = new Completer<sky.Image>();
      _bundle.ptr.getAsStream(key).then((response) {
        new sky.ImageDecoder(response.assetData.handle.h, completer.complete);
      });
72
      return new ImageResource(completer.future);
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
    });
  }

  Future<String> _fetchString(String key) async {
    core.MojoDataPipeConsumer pipe = (await _bundle.ptr.getAsStream(key)).assetData;
    ByteData data = await core.DataPipeDrainer.drainHandle(pipe);
    return new String.fromCharCodes(new Uint8List.view(data.buffer));
  }

  Future<String> loadString(String key) {
    return _stringCache.putIfAbsent(key, () => _fetchString(key));
  }
}

AssetBundle _initRootBundle() {
  try {
    AssetBundleProxy bundle = new AssetBundleProxy.fromHandle(
        new core.MojoHandle(internals.takeRootBundleHandle()));
    return new MojoAssetBundle(bundle);
  } catch (e) {
    return null;
  }
}

final AssetBundle rootBundle = _initRootBundle();