@@ -6,6 +6,101 @@ import 'package:flutter_color_models/flutter_color_models.dart';
66import '../api/model/model.dart' ;
77import 'color.dart' ;
88
9+ /// A caching factory for [StreamColorSwatch] es, from [subscription.color] bases.
10+ ///
11+ /// See subclasses:
12+ /// [StreamColorSwatchesLight]
13+ /// [StreamColorSwatchesDark]
14+ abstract class StreamColorSwatches {
15+ /// Gives the cached [StreamColorSwatch] for a [subscription.color] .
16+ ///
17+ /// For caching details, see subclasses.
18+ StreamColorSwatch forBaseColor (int base );
19+
20+ /// Gives a [StreamColorSwatches] , lerped to [other] at [t] .
21+ ///
22+ /// If [this] and [other] are [identical] , returns [this] .
23+ ///
24+ /// Else returns an instance whose [forBaseColor] will call
25+ /// [this.forBaseColor] and [other.forBaseColor]
26+ /// and return [StreamColorSwatch.lerp] 's result on those.
27+ /// This computation is cached on the instance
28+ /// in order to save work building [t] 's animation frame when there are
29+ /// multiple UI elements using the same [subscription.color] .
30+ StreamColorSwatches lerp (StreamColorSwatches ? other, double t) {
31+ // This short-circuit helps when [a] and [b]
32+ // are both [StreamColorSwatchesLight.instance]
33+ // or both [StreamColorSwatchesDark.instance].
34+ if (identical (this , other)) {
35+ return this ;
36+ }
37+
38+ return _StreamColorSwatchesLerped (this , other, t);
39+ }
40+ }
41+
42+ /// The [StreamColorSwatches] for the light theme.
43+ class StreamColorSwatchesLight extends StreamColorSwatches {
44+ // No public constructor; always use [instance]. Empirically,
45+ // [StreamColorSwatches.lerp] is called even when the theme has not changed,
46+ // and the short-circuit on [identical] cuts redundant work when that happens.
47+ static StreamColorSwatchesLight get instance =>
48+ (_instance ?? = StreamColorSwatchesLight ._());
49+ static StreamColorSwatchesLight ? _instance;
50+
51+ StreamColorSwatchesLight ._();
52+
53+ final Map <int , StreamColorSwatch > _cache = {};
54+
55+ /// Gives the cached [StreamColorSwatch.light] for a [subscription.color] .
56+ ///
57+ /// When this is first called, the result is added to a global cache
58+ /// keyed by [subscription.color] .
59+ /// Subsequent calls return the value from the cache.
60+ @override
61+ StreamColorSwatch forBaseColor (int base ) =>
62+ _cache[base ] ?? = StreamColorSwatch .light (base );
63+ }
64+
65+ /// The [StreamColorSwatches] for the dark theme.
66+ class StreamColorSwatchesDark extends StreamColorSwatches {
67+ // No public constructor, like [StreamColorSwatchesLight].
68+ static StreamColorSwatchesDark get instance =>
69+ (_instance ?? = StreamColorSwatchesDark ._());
70+ static StreamColorSwatchesDark ? _instance;
71+
72+ StreamColorSwatchesDark ._();
73+
74+ final Map <int , StreamColorSwatch > _cache = {};
75+
76+ /// Like [StreamColorSwatchesLight.forBaseColor] ,
77+ /// but using [StreamColorSwatch.dark] .
78+ @override
79+ StreamColorSwatch forBaseColor (int base ) =>
80+ _cache[base ] ?? = StreamColorSwatch .dark (base );
81+ }
82+
83+ class _StreamColorSwatchesLerped extends StreamColorSwatches {
84+ _StreamColorSwatchesLerped (this .a, this .b, this .t);
85+
86+ final StreamColorSwatches a;
87+ final StreamColorSwatches ? b;
88+ final double t;
89+
90+ final Map <int , StreamColorSwatch > _cache = {};
91+
92+ /// Gives the cached [StreamColorSwatch] for a [subscription.color] .
93+ ///
94+ /// Caching is per-instance, not global, in order to save work building
95+ /// [t] 's animation frame when there are multiple UI elements using the same
96+ /// [subscription.color] .
97+ @override
98+ StreamColorSwatch forBaseColor (int base ) =>
99+ _cache[base ]
100+ ?? = StreamColorSwatch .lerp (a.forBaseColor (base ), b? .forBaseColor (base ), t)! ;
101+ }
102+
103+
9104/// A [ColorSwatch] with colors related to a base stream color.
10105///
11106/// Use this in UI code for colors related to [Subscription.color] ,
0 commit comments