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

Consider colorMapper for cache key data #902

Merged
merged 2 commits into from
Apr 8, 2023
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
channel: 'stable'
- run: flutter --version
- run: flutter pub get
- run: flutter format --set-exit-if-changed .
- run: dart format --set-exit-if-changed .
- run: flutter analyze .
- run: flutter test --coverage
# - uses: romeovs/[email protected]
Expand Down
24 changes: 20 additions & 4 deletions lib/src/loaders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ class SvgTheme {
}

/// A class that transforms from one color to another during SVG parsing.
///
/// This object must be immutable so that it is suitable for use in the
/// [svg.cache].
@immutable
abstract class ColorMapper {
/// Allows const constructors on subclasses.
const ColorMapper();

/// Returns a new color to use in place of [color] during SVG parsing.
///
/// The SVG parser will call this method every time it parses a color
Expand Down Expand Up @@ -153,7 +160,7 @@ abstract class SvgLoader<T> extends BytesLoader {

@override
SvgCacheKey cacheKey(BuildContext? context) {
return SvgCacheKey(keyData: this, theme: theme);
return SvgCacheKey(keyData: this, theme: theme, colorMapper: colorMapper);
}
}

Expand All @@ -164,7 +171,11 @@ abstract class SvgLoader<T> extends BytesLoader {
@immutable
class SvgCacheKey {
/// See [SvgCacheKey].
const SvgCacheKey({required this.theme, required this.keyData});
const SvgCacheKey({
required this.theme,
required this.keyData,
required this.colorMapper,
});

/// The theme for this cached SVG.
final SvgTheme theme;
Expand All @@ -174,14 +185,18 @@ class SvgCacheKey {
/// For most loaders, using the loader object itself is suitable.
final Object keyData;

/// The color mapper for the SVG, if any.
final ColorMapper? colorMapper;

@override
int get hashCode => Object.hash(theme, keyData);
int get hashCode => Object.hash(theme, keyData, colorMapper);

@override
bool operator ==(Object other) {
return other is SvgCacheKey &&
other.theme == theme &&
other.keyData == keyData;
other.keyData == keyData &&
other.colorMapper == colorMapper;
}
}

Expand Down Expand Up @@ -352,6 +367,7 @@ class SvgAssetLoader extends SvgLoader<ByteData> {
SvgCacheKey cacheKey(BuildContext? context) {
return SvgCacheKey(
theme: theme,
colorMapper: colorMapper,
keyData: _AssetByteLoaderCacheKey(
assetName,
packageName,
Expand Down
30 changes: 29 additions & 1 deletion test/loaders_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_test/flutter_test.dart';

Expand All @@ -8,6 +9,15 @@ void main() {
svg.cache.maximumSize = 100;
});

test('ColorMapper updates the cache', () async {
const TestLoader loaderA = TestLoader();
const TestLoader loaderB = TestLoader(colorMapper: _TestColorMapper());
final ByteData bytesA = await loaderA.loadBytes(null);
final ByteData bytesB = await loaderB.loadBytes(null);
expect(identical(bytesA, bytesB), false);
expect(svg.cache.count, 2);
});

test('SvgTheme updates the cache', () async {
const TestLoader loaderA =
TestLoader(theme: SvgTheme(currentColor: Color(0xFFABCDEF)));
Expand Down Expand Up @@ -61,10 +71,28 @@ class TestBundle extends Fake implements AssetBundle {
}

class TestLoader extends SvgLoader<void> {
const TestLoader({super.theme, super.colorMapper});
const TestLoader({this.keyName = 'A', super.theme, super.colorMapper});

final String keyName;

@override
String provideSvg(void message) {
return '<svg width="10" height="10"></svg>';
}

@override
SvgCacheKey cacheKey(BuildContext? context) {
return SvgCacheKey(
theme: theme, colorMapper: colorMapper, keyData: keyName);
}
}

class _TestColorMapper extends ColorMapper {
const _TestColorMapper();

@override
Color substitute(
String? id, String elementName, String attributeName, Color color) {
return color;
}
}