Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor code by adding AssetProvider #213

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions flare_flutter/lib/asset_bundle_cache.dart

This file was deleted.

9 changes: 9 additions & 0 deletions flare_flutter/lib/asset_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'dart:typed_data';

/// Identifies an asset, to obtain asset from an [AssetProvider], call [load].
abstract class AssetProvider {
const AssetProvider();

/// Loads the asset.
Future<ByteData> load();
}
35 changes: 15 additions & 20 deletions flare_flutter/lib/cache.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import 'dart:async';

import 'asset_provider.dart';
import 'cache_asset.dart';

typedef CacheAsset AssetFactoryMethod();

/// A base class for loading cached resources
abstract class Cache<T extends CacheAsset> {
final Map<String, T> _assets = {};
final Map<AssetProvider, T> _assets = {};
final Set<T> _toPrune = Set<T>();
Timer _pruneTimer;

Expand All @@ -16,7 +18,7 @@ abstract class Cache<T extends CacheAsset> {

void _prune() {
for (final T asset in _toPrune) {
_assets.removeWhere((String filename, T cached) {
_assets.removeWhere((AssetProvider assetProvider, T cached) {
return cached == asset;
});
}
Expand All @@ -39,34 +41,27 @@ abstract class Cache<T extends CacheAsset> {
}

/// Get an asset from the cache or load it.
Future<T> getAsset(String filename) async {
T asset = _assets[filename];
Future<T> getAsset(AssetProvider assetProvider) async {
T asset = _assets[assetProvider];
if (asset != null) {
if (asset.isAvailable) {
return asset;
} else {
return await asset.onLoaded() as T;
}
}
int lastDot = filename.lastIndexOf(".");
if (lastDot != -1) {
asset = makeAsset();
if (asset != null) {
_assets[filename] = asset;
asset.load(this, filename);
if (asset.isAvailable) {
return asset;
} else {
return await asset.onLoaded() as T;
}
}
}
return asset;

asset = makeAsset();
assert(asset != null);

_assets[assetProvider] = asset;
asset.load(this, assetProvider);
return asset.isAvailable ? asset : await asset.onLoaded() as T;
}

/// Get an asset from the cache.
T getWarmAsset(String filename) {
T asset = _assets[filename];
T getWarmAsset(AssetProvider assetProvider) {
T asset = _assets[assetProvider];
return (asset?.isAvailable ?? false) ? asset : null;
}
}
6 changes: 3 additions & 3 deletions flare_flutter/lib/cache_asset.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'dart:async';

import 'asset_provider.dart';
import 'cache.dart';

/// A reference counted asset in a cache.
Expand Down Expand Up @@ -32,9 +34,7 @@ abstract class CacheAsset {
return completer.future;
}

void load(Cache cache, String filename) {
_cache = cache;
}
void load(Cache cache, AssetProvider assetProvider) => _cache = cache;

void completeLoad() {
if (_callbacks != null) {
Expand Down
67 changes: 49 additions & 18 deletions flare_flutter/lib/flare_actor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,29 @@ import 'package:flutter/rendering.dart';
import 'package:flare_dart/actor_drawable.dart';
import 'package:flare_dart/math/mat2d.dart';
import 'package:flare_dart/math/aabb.dart';
import 'package:flutter/services.dart';

import 'asset_provider.dart';
import 'flare.dart';
import 'flare_controller.dart';
import 'provider/asset_flare.dart';

typedef void FlareCompletedCallback(String name);

/// A widget that displays a Flare.
///
/// Several constructors are provided for the various ways that a Flare can be
/// specified:
/// * [FlareActor], for obtaining a Flare from an asset [filename].
/// * [FlareActor.asset], for obtaining a Flare from an [AssetBundle]
/// using a key.
class FlareActor extends LeafRenderObjectWidget {
/// Name of the Flare file to be loaded from the AssetBundle.
final String filename;

/// The Flare asset to display.
final AssetProvider flareProvider;

/// The name of the artboard to display.
final String artboard;

Expand Down Expand Up @@ -72,13 +86,30 @@ class FlareActor extends LeafRenderObjectWidget {
this.shouldClip = true,
this.sizeFromArtboard = false,
this.artboard,
});
}) : flareProvider = null;

FlareActor.asset(
String name, {
this.boundsNode,
this.animation,
this.fit = BoxFit.contain,
this.alignment = Alignment.center,
this.isPaused = false,
this.snapToEnd = false,
this.controller,
this.callback,
this.color,
this.shouldClip = true,
this.sizeFromArtboard = false,
this.artboard,
}) : filename = null,
flareProvider = AssetFlare(bundle: rootBundle, name: name);

@override
RenderObject createRenderObject(BuildContext context) {
return FlareActorRenderObject()
..assetBundle = DefaultAssetBundle.of(context)
..filename = filename
..assetProvider =
flareProvider ?? AssetFlare(bundle: rootBundle, name: filename)
..fit = fit
..alignment = alignment
..animationName = animation
Expand All @@ -97,8 +128,8 @@ class FlareActor extends LeafRenderObjectWidget {
void updateRenderObject(
BuildContext context, covariant FlareActorRenderObject renderObject) {
renderObject
..assetBundle = DefaultAssetBundle.of(context)
..filename = filename
..assetProvider =
flareProvider ?? AssetFlare(bundle: rootBundle, name: filename)
..fit = fit
..alignment = alignment
..animationName = animation
Expand Down Expand Up @@ -131,7 +162,7 @@ class FlareAnimationLayer {

class FlareActorRenderObject extends FlareRenderBox {
Mat2D _lastControllerViewTransform;
String _filename;
AssetProvider _assetProvider;
String _artboardName;
String _animationName;
String _boundsNodeName;
Expand Down Expand Up @@ -248,14 +279,14 @@ class FlareActorRenderObject extends FlareRenderBox {
_animationLayers.clear();
}

String get filename => _filename;
set filename(String value) {
if (value == _filename) {
AssetProvider get assetProvider => _assetProvider;
set assetProvider(AssetProvider value) {
if (value == _assetProvider) {
return;
}
_filename = value;
_assetProvider = value;

if (_filename == null) {
if (_assetProvider == null) {
markNeedsPaint();
}
// file will change, let's clear out old animations.
Expand Down Expand Up @@ -298,28 +329,28 @@ class FlareActorRenderObject extends FlareRenderBox {

@override
bool get canLoad {
return super.canLoad && _filename != null;
return super.canLoad && _assetProvider != null;
}

/// Attempt a warm load, thfis is the optimal case when the
/// Attempt a warm load, this is the optimal case when the
/// required asset is already in the cache.
@override
bool warmLoad() {
if (_filename == null) {
if (_assetProvider == null) {
return false;
}
_actor = getWarmFlare(_filename);
_actor = getWarmFlare(_assetProvider);
return _instanceArtboard();
}

/// Load the necessary Flare file specified by _filename.
/// Load the necessary Flare file specified by [AssetProvider].
/// this occurs when the optimal warmLoad fails to find an asset in cache.
@override
Future<void> coldLoad() async {
if (_filename == null) {
if (_assetProvider == null) {
return;
}
_actor = await loadFlare(_filename);
_actor = await loadFlare(_assetProvider);
_instanceArtboard();
}

Expand Down
32 changes: 11 additions & 21 deletions flare_flutter/lib/flare_cache.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import 'dart:async';
import 'package:flutter/services.dart';

import 'asset_bundle_cache.dart';
import 'asset_provider.dart';
import 'cache.dart';
import 'flare_cache_asset.dart';

/// Cache that instances flare assets from ".flr" extension.
class FlareCache extends AssetBundleCache<FlareCacheAsset> {
FlareCache(AssetBundle bundle) : super(bundle);

/// Cache that instances Flare assets from ".flr" extension.
class FlareCache extends Cache<FlareCacheAsset> {
static bool doesPrune = true;
static Duration pruneDelay = const Duration(seconds: 2);

Expand All @@ -18,24 +16,16 @@ class FlareCache extends AssetBundleCache<FlareCacheAsset> {
Duration get pruneAfter => pruneDelay;

@override
FlareCacheAsset makeAsset() {
return FlareCacheAsset();
}
FlareCacheAsset makeAsset() => FlareCacheAsset();
}

/// A mapping of loaded Flare assets.
final Map<AssetBundle, FlareCache> _cache = {};
/// Cache for loaded Flare assets.
final _cache = FlareCache();

/// Get a cached Flare actor, or load it if it's not yet available.
Future<FlareCacheAsset> cachedActor(AssetBundle bundle, String filename) async {
FlareCache cache = _cache[bundle];
if (cache == null) {
_cache[bundle] = cache = FlareCache(bundle);
}
return cache.getAsset(filename);
}
Future<FlareCacheAsset> cachedActor(AssetProvider assetProvider) =>
_cache.getAsset(assetProvider);

/// Get a warm Flare actor that's already in the cache.
FlareCacheAsset getWarmActor(AssetBundle bundle, String filename) {
return _cache[bundle]?.getWarmAsset(filename);
}
FlareCacheAsset getWarmActor(AssetProvider assetProvider) =>
_cache.getWarmAsset(assetProvider);
33 changes: 14 additions & 19 deletions flare_flutter/lib/flare_cache_asset.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:typed_data';
import 'package:flutter/foundation.dart';

import 'asset_bundle_cache.dart';
import 'asset_provider.dart';
import 'cache.dart';
import 'cache_asset.dart';
import 'flare.dart';
Expand All @@ -13,34 +13,29 @@ class FlareCacheAsset extends CacheAsset {

static bool useCompute = true;

void loadedActor(FlutterActor actor, String filename) {
void loadedActor(FlutterActor actor, AssetProvider assetProvider) {
actor.loadImages().then((_) {
if (actor != null) {
_actor = actor;
completeLoad();
} else {
print("Failed to load flare file from $filename.");
print("Failed to load flare file from $assetProvider.");
}
});
}

@override
void load(Cache cache, String filename) {
super.load(cache, filename);
if (cache is AssetBundleCache) {
cache.bundle.load(filename).then((ByteData data) {
if (useCompute) {
compute(FlutterActor.loadFromByteData, data)
.then((FlutterActor actor) {
loadedActor(actor, filename);
});
} else {
FlutterActor.loadFromByteData(data).then((FlutterActor actor) {
loadedActor(actor, filename);
});
}
});
}
void load(Cache cache, AssetProvider assetProvider) {
super.load(cache, assetProvider);
assetProvider.load().then((ByteData data) {
if (useCompute) {
compute(FlutterActor.loadFromByteData, data)
.then((FlutterActor actor) => loadedActor(actor, assetProvider));
} else {
FlutterActor.loadFromByteData(data)
.then((FlutterActor actor) => loadedActor(actor, assetProvider));
}
});
}

@override
Expand Down
Loading