| // Copyright 2014 The Flutter 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 'framework.dart'; | 
 |  | 
 | /// Provides non-leaking access to a [BuildContext]. | 
 | /// | 
 | /// A [BuildContext] is only valid if it is pointing to an active [Element]. | 
 | /// Once the [Element] is unmounted, the [BuildContext] should not be accessed | 
 | /// further. This class makes it possible for a [StatefulWidget] to share its | 
 | /// build context safely with other objects. | 
 | /// | 
 | /// Creators of this object must guarantee the following: | 
 | /// | 
 | ///   1. They create this object at or after [State.initState] but before | 
 | ///      [State.dispose]. In particular, do not attempt to create this from the | 
 | ///      constructor of a state. | 
 | ///   2. They call [dispose] from [State.dispose]. | 
 | /// | 
 | /// This object will not hold on to the [State] after disposal. | 
 | @optionalTypeArgs | 
 | class DisposableBuildContext<T extends State> { | 
 |   /// Creates an object that provides access to a [BuildContext] without leaking | 
 |   /// a [State]. | 
 |   /// | 
 |   /// Creators must call [dispose] when the [State] is disposed. | 
 |   /// | 
 |   /// The [State] must not be null, and [State.mounted] must be true. | 
 |   DisposableBuildContext(T this._state) | 
 |       : assert(_state != null), | 
 |         assert(_state.mounted, 'A DisposableBuildContext was given a BuildContext for an Element that is not mounted.'); | 
 |  | 
 |   T? _state; | 
 |  | 
 |   /// Provides safe access to the build context. | 
 |   /// | 
 |   /// If [dispose] has been called, will return null. | 
 |   /// | 
 |   /// Otherwise, asserts the [_state] is still mounted and returns its context. | 
 |   BuildContext? get context { | 
 |     assert(_debugValidate()); | 
 |     if (_state == null) { | 
 |       return null; | 
 |     } | 
 |     return _state!.context; | 
 |   } | 
 |  | 
 |   /// Called from asserts or tests to determine whether this object is in a | 
 |   /// valid state. | 
 |   /// | 
 |   /// Always returns true, but will assert if [dispose] has not been called | 
 |   /// but the state this is tracking is unmounted. | 
 |   bool _debugValidate() { | 
 |     assert( | 
 |       _state == null || _state!.mounted, | 
 |       'A DisposableBuildContext tried to access the BuildContext of a disposed ' | 
 |       'State object. This can happen when the creator of this ' | 
 |       'DisposableBuildContext fails to call dispose when it is disposed.', | 
 |     ); | 
 |     return true; | 
 |   } | 
 |  | 
 |  | 
 |   /// Marks the [BuildContext] as disposed. | 
 |   /// | 
 |   /// Creators of this object must call [dispose] when their [Element] is | 
 |   /// unmounted, i.e. when [State.dispose] is called. | 
 |   void dispose() { | 
 |     _state = null; | 
 |   } | 
 | } |