@@ -11,7 +11,7 @@ import 'package:riverpod/src/framework.dart';
1111/// access to Riverpod [Provider] s.
1212///
1313/// The corresponding [State] object ([RiverpodAwareGameWidgetState] ) assumes
14- /// responsibilities associated with [ ConsumerStatefulElement] in
14+ /// responsibilities associated with ConsumerStatefulElement in
1515/// `flutter_riverpod` .
1616class RiverpodAwareGameWidget <T extends Game > extends GameWidget <T > {
1717 RiverpodAwareGameWidget ({
@@ -36,8 +36,7 @@ class RiverpodAwareGameWidget<T extends Game> extends GameWidget<T> {
3636 GameWidgetState <T > createState () => RiverpodAwareGameWidgetState <T >();
3737}
3838
39- class RiverpodAwareGameWidgetState <T extends Game > extends GameWidgetState <T >
40- implements WidgetRef {
39+ class RiverpodAwareGameWidgetState <T extends Game > extends GameWidgetState <T > {
4140 RiverpodGameMixin get game => widget.game! as RiverpodGameMixin ;
4241
4342 bool _isForceBuilding = false ;
@@ -49,7 +48,7 @@ class RiverpodAwareGameWidgetState<T extends Game> extends GameWidgetState<T>
4948 Map <ProviderListenable <Object ?>, ProviderSubscription <Object ?>>?
5049 _oldDependencies;
5150 final _listeners = < ProviderSubscription <Object ?>> [];
52- List <_ListenManual <Object ?>>? _manualListeners;
51+ List <ProviderSubscription <Object ?>>? _manualListeners;
5352
5453 /// Rebuilds the [RiverpodAwareGameWidget] by calling [setState] .
5554 /// As it is undesirable to call [setState] while the widget may be building,
@@ -146,7 +145,6 @@ class RiverpodAwareGameWidgetState<T extends Game> extends GameWidgetState<T>
146145 }
147146 }
148147
149- @override
150148 Res watch <Res >(ProviderListenable <Res > target) {
151149 _assertNotDisposed ();
152150 return _dependencies.putIfAbsent (target, () {
@@ -167,7 +165,6 @@ class RiverpodAwareGameWidgetState<T extends Game> extends GameWidgetState<T>
167165 as Res ;
168166 }
169167
170- @override
171168 void listen <U >(
172169 ProviderListenable <U > provider,
173170 void Function (U ? previous, U value) listener, {
@@ -186,31 +183,26 @@ class RiverpodAwareGameWidgetState<T extends Game> extends GameWidgetState<T>
186183 _listeners.add (sub);
187184 }
188185
189- @override
190186 bool exists (ProviderBase <Object ?> provider) {
191187 _assertNotDisposed ();
192188 return ProviderScope .containerOf (context, listen: false ).exists (provider);
193189 }
194190
195- @override
196191 Res read <Res >(ProviderListenable <Res > provider) {
197192 _assertNotDisposed ();
198193 return ProviderScope .containerOf (context, listen: false ).read (provider);
199194 }
200195
201- @override
202196 S refresh <S >(Refreshable <S > provider) {
203197 _assertNotDisposed ();
204198 return ProviderScope .containerOf (context, listen: false ).refresh (provider);
205199 }
206200
207- @override
208201 void invalidate (ProviderOrFamily provider) {
209202 _assertNotDisposed ();
210203 _container.invalidate (provider);
211204 }
212205
213- @override
214206 ProviderSubscription <Res > listenManual <Res >(
215207 ProviderListenable <Res > provider,
216208 void Function (Res ? previous, Res next) listener, {
@@ -224,43 +216,25 @@ class RiverpodAwareGameWidgetState<T extends Game> extends GameWidgetState<T>
224216 // be used inside initState.
225217 final container = ProviderScope .containerOf (context, listen: false );
226218
227- final sub = _ListenManual (
228- container,
229- container.listen (
230- provider,
231- listener,
232- onError: onError,
233- fireImmediately: fireImmediately,
234- ),
235- this ,
219+ final sub = container.listen <Res >(
220+ provider,
221+ listener,
222+ onError: onError,
223+ fireImmediately: fireImmediately,
224+ // ignore: invalid_use_of_internal_member, from riverpod
236225 );
237- listeners.add (sub);
238-
239- return sub;
240- }
241- }
242226
243- class _ListenManual <T > extends ProviderSubscription <T > {
244- _ListenManual (super .source, this ._subscription, this ._element);
227+ // Hook-up on onClose to avoid memory leaks.
228+ final previousOnClose = sub.impl.onClose;
229+ sub.impl.onClose = () {
230+ previousOnClose? .call ();
231+ // If the subscription is closed, we remove it from the manual listeners
232+ // so that it doesn't leak.
233+ _manualListeners? .remove (sub);
234+ };
245235
246- final ProviderSubscription <T > _subscription;
247- final RiverpodAwareGameWidgetState _element;
236+ listeners.add (sub);
248237
249- @override
250- void close () {
251- if (! closed) {
252- _subscription.close ();
253- _element._manualListeners? .remove (this );
254- }
255- super .close ();
238+ return sub;
256239 }
257-
258- @override
259- T read () => _subscription.read ();
260-
261- @override
262- bool get closed => _subscription.closed;
263-
264- @override
265- Node get source => _subscription.source;
266240}
0 commit comments