Skip to content

Commit

Permalink
Improved documentation
Browse files Browse the repository at this point in the history
Renamed `DownloadManagement` to `StoreDownload` to improve consistency and better reflect scope
  • Loading branch information
JaffaKetchup committed Apr 9, 2024
1 parent 0c270eb commit 8177408
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 85 deletions.
8 changes: 6 additions & 2 deletions lib/custom_backend_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
/// internals necessary to create custom backends or work more directly with
/// them
///
/// Use this import/library with caution! Assistance with non-typical usecases
/// may be limited. Always use the standard import unless necessary.
/// Many of the methods available through this import are exported and visible
/// via the more friendly interface of the main import and function set.
///
/// > [!CAUTION]
/// > Use this import/library with caution! Assistance with non-typical usecases
/// > may be limited. Always use the standard import unless necessary.
///
/// Importing the standard library will also likely be necessary.
library flutter_map_tile_caching.custom_backend_api;
Expand Down
14 changes: 8 additions & 6 deletions lib/src/backend/interfaces/backend/internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ abstract interface class FMTCBackendInternal
/// {@template fmtc.backend.deleteStore}
/// Delete the specified store
///
/// This operation cannot be undone! Ensure you confirm with the user that
/// this action is expected.
/// > [!WARNING]
/// > This operation cannot be undone! Ensure you confirm with the user that
/// > this action is expected.
///
/// Does nothing if the store does not already exist.
/// {@endtemplate}
Expand All @@ -94,8 +95,9 @@ abstract interface class FMTCBackendInternal
/// Also resets the hits & misses stats. Does not reset any associated
/// metadata.
///
/// This operation cannot be undone! Ensure you confirm with the user that
/// this action is expected.
/// > [!WARNING]
/// > This operation cannot be undone! Ensure you confirm with the user that
/// > this action is expected.
///
/// Does nothing if the store does not already exist.
/// {@endtemplate}
Expand Down Expand Up @@ -215,8 +217,8 @@ abstract interface class FMTCBackendInternal
/// {@template fmtc.backend.setMetadata}
/// Set a key-value pair in the metadata for the specified store
///
/// Note that this operation will overwrite any existing value for the
/// specified key.
/// > [!WARNING]
/// > Any existing value for the specified key will be overwritten.
///
/// Prefer using [setBulkMetadata] when setting multiple keys. Only one backend
/// operation is required to set them all at once, and so is more efficient.
Expand Down
9 changes: 1 addition & 8 deletions lib/src/bulk_download/download_progress.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ part of '../../flutter_map_tile_caching.dart';

/// Statistics and information about the current progress of the download
///
/// Note that there a number of things to keep in mind when tracking the progress
/// of a download. See https://fmtc.jaffaketchup.dev/bulk-downloading/foreground
/// for more information.
///
/// See the documentation on each individual property for more information.
@immutable
class DownloadProgress {
Expand Down Expand Up @@ -47,10 +43,7 @@ class DownloadProgress {

/// The result of the latest attempted tile
///
/// Note that there a number of things to keep in mind when tracking the
/// progress of a download. See
/// https://fmtc.jaffaketchup.dev/bulk-downloading/foreground for more
/// information.
/// {@macro fmtc.tileevent.extraConsiderations}
TileEvent get latestTileEvent => _latestTileEvent!;
final TileEvent? _latestTileEvent;

Expand Down
10 changes: 10 additions & 0 deletions lib/src/bulk_download/tile_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ enum TileEventResult {
///
/// Does not contain information about the download as a whole, that is
/// [DownloadProgress]' responsibility.
///
/// {@template fmtc.tileevent.extraConsiderations}
/// > [!TIP]
/// > When tracking [TileEvent]s across multiple [DownloadProgress] events,
/// > extra considerations are necessary. See
/// > [the documentation](https://fmtc.jaffaketchup.dev/bulk-downloading/start#keeping-track-across-events)
/// > for more information.
/// {@endtemplate}
@immutable
class TileEvent {
const TileEvent._(
Expand Down Expand Up @@ -127,6 +135,8 @@ class TileEvent {
/// Events will occasionally be repeated due to the `maxReportInterval`
/// functionality. If using other members, such as [result], to keep count of
/// important events, do not count an event where this is `true`.
///
/// {@macro fmtc.tileevent.extraConsiderations}
final bool isRepeat;

final bool _wasBufferReset;
Expand Down
23 changes: 19 additions & 4 deletions lib/src/root/recovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ part of '../../flutter_map_tile_caching.dart';
///
/// ---
///
/// When a download is started, a recovery region is stored in a database, and
/// the download ID is stored in memory (in a singleton to ensure it is never
/// disposed except when the application is closed).
/// When a download is started, a recovery region is stored in a non-volatile
/// database, and the download ID is stored in volatile memory.
///
/// If the download finishes normally, both entries are removed, otherwise, the
/// memory is cleared when the app is closed, but the database record is not
Expand All @@ -18,8 +17,24 @@ part of '../../flutter_map_tile_caching.dart';
/// {@template fmtc.rootRecovery.failedDefinition}
/// A failed download is one that was found in the recovery database, but not
/// in the application memory. It can therefore be assumed that the download
/// is also no longer in memory, and therefore stopped unexpectedly.
/// is also no longer in memory, and was therefore stopped unexpectedly, for
/// example after a fatal crash.
/// {@endtemplate}
///
/// The recovery system then allows the original [BaseRegion] and
/// [DownloadableRegion] to be recovered (via [RecoveredRegion]) from the failed
/// download, and the download can be restarted as normal.
///
/// > [!NOTE]
/// > Options set at download time, in [StoreDownload.startForeground], are not
/// > included.
///
/// > [!IMPORTANT]
/// > The recovery system does not keep track of the download, therefore it is
/// > unknown where the download failed, and the download must be restarted from
/// > the beginning.
/// >
/// > To workaround this limitation, set `skipExistingTiles` `true`.
class RootRecovery {
RootRecovery._() {
_instance = this;
Expand Down
91 changes: 49 additions & 42 deletions lib/src/store/download.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,39 @@

part of '../../flutter_map_tile_caching.dart';

/// Provides tools to manage bulk downloading to a specific [FMTCStore]
///
/// The 'fmtc_plus_background_downloading' module must be installed to add the
/// background downloading functionality.
/// Provides bulk downloading functionality for a specific [FMTCStore]
///
/// ---
///
/// {@template num_instances}
/// By default, only one download per store at the same time is tolerated.
/// Attempting to start more than one at the same time may cause poor
/// performance or other poor behaviour.
/// By default, only one download is allowed at any one time.
///
/// However, if necessary, multiple can be started by setting methods'
/// `instanceId` argument to a unique value on methods. Whatever object
/// `instanceId` is, it must have a valid and useful equality and `hashCode`
/// implementation, as it is used as the key in a `Map`. Note that this unique
/// value must be known and remembered to control the state of the download.
///
/// > [!WARNING]
/// > Starting multiple simultaneous downloads may lead to a noticeable
/// > performance loss. Ensure you thoroughly test and profile your application.
/// {@endtemplate}
///
/// ---
///
/// Does not keep state. State and download instances are held internally by
/// [DownloadInstance].
class DownloadManagement {
const DownloadManagement._(this._storeDirectory);
final FMTCStore _storeDirectory;
@immutable
class StoreDownload {
const StoreDownload._(this._storeName);
final String _storeName;

/// Download a specified [DownloadableRegion] in the foreground, with a
/// recovery session by default
///
/// To check the number of tiles that need to be downloaded before using this
/// function, use [check].
/// > [!TIP]
/// > To check the number of tiles in a region before starting a download, use
/// > [check].
///
/// Streams a [DownloadProgress] object containing statistics and information
/// about the download's progression status, once per tile and at intervals
Expand All @@ -50,21 +51,24 @@ class DownloadManagement {
/// - [maxBufferLength] (defaults to 200 | 0 to disable): number of tiles to
/// temporarily buffer before writing to the store (split evenly between
/// [parallelThreads])
/// - [skipExistingTiles] (defaults to `true`): whether to skip downloading
/// - [skipExistingTiles] (defaults to `false`): whether to skip downloading
/// tiles that are already cached
/// - [skipSeaTiles] (defaults to `true`): whether to skip caching tiles that
/// are entirely sea (based on a comparison to the tile at x0,y0,z17)
///
/// Using too many parallel threads may place significant strain on the tile
/// server, so check your tile server's ToS for more information.
/// > [!WARNING]
/// > Using too many parallel threads may place significant strain on the tile
/// > server, so check your tile server's ToS for more information.
///
/// Using buffering will mean that an unexpected forceful quit (such as an
/// app closure, [cancel] is safe) will result in losing the tiles that are
/// currently in the buffer. It will also increase the memory (RAM) required.
/// The output stream's statistics do not account for buffering.
/// > [!WARNING]
/// > Using buffering will mean that an unexpected forceful quit (such as an
/// > app closure, [cancel] is safe) will result in losing the tiles that are
/// > currently in the buffer. It will also increase the memory (RAM) required.
///
/// Note that skipping sea tiles will not reduce the number of downloads -
/// tiles must be downloaded to be compared against the sample sea tile.
/// > [!WARNING]
/// > Skipping sea tiles will not reduce the number of downloads - tiles must
/// > be downloaded to be compared against the sample sea tile. It is only
/// > designed to reduce the storage capacity consumed.
///
/// ---
///
Expand All @@ -81,6 +85,24 @@ class DownloadManagement {
///
/// ---
///
/// A fresh [DownloadProgress] event will always be emitted every
/// [maxReportInterval] (if specified), which defaults to every 1 second,
/// regardless of whether any more tiles have been attempted/downloaded/failed.
/// This is to enable the [DownloadProgress.elapsedDuration] to be accurately
/// presented to the end user.
///
/// {@macro fmtc.tileevent.extraConsiderations}
///
/// ---
///
/// When this download is started, assuming [disableRecovery] is `false` (as
/// default), the recovery system will register this download, to allow it to
/// be recovered if it unexpectedly fails.
///
/// For more info, see [RootRecovery].
///
/// ---
///
/// For information about [obscuredQueryParams], see the
/// [online documentation](https://fmtc.jaffaketchup.dev/usage/integration#obscuring-query-parameters).
/// Will default to the value in the default [FMTCTileProviderSettings].
Expand All @@ -96,7 +118,7 @@ class DownloadManagement {
required DownloadableRegion region,
int parallelThreads = 5,
int maxBufferLength = 200,
bool skipExistingTiles = true,
bool skipExistingTiles = false,
bool skipSeaTiles = true,
int? rateLimit,
Duration? maxReportInterval = const Duration(seconds: 1),
Expand All @@ -115,14 +137,6 @@ class DownloadManagement {
);
}

if (region.options.tileProvider.headers['User-Agent'] ==
'flutter_map (unknown)') {
throw ArgumentError(
"`.toDownloadable`'s `TileLayer` argument must specify an appropriate `userAgentPackageName` or other `headers['User-Agent']`",
'region.options.userAgentPackageName',
);
}

if (parallelThreads < 1) {
throw ArgumentError.value(
parallelThreads,
Expand Down Expand Up @@ -151,8 +165,9 @@ class DownloadManagement {
final instance = DownloadInstance.registerIfAvailable(instanceId);
if (instance == null) {
throw StateError(
"Download instance with ID $instanceId already exists\nIf you're sure "
'you want to start multiple downloads, use a unique `instanceId`.',
'A download instance with ID $instanceId already exists\nTo start '
'another download simultaneously, use a unique `instanceId`. Read the '
'documentation for additional considerations that should be taken.',
);
}

Expand All @@ -162,7 +177,7 @@ class DownloadManagement {
if (!disableRecovery) {
await FMTCRoot.recovery._start(
id: recoveryId,
storeName: _storeDirectory.storeName,
storeName: _storeName,
region: region,
);
}
Expand All @@ -174,7 +189,7 @@ class DownloadManagement {
(
sendPort: receivePort.sendPort,
region: region,
storeName: _storeDirectory.storeName,
storeName: _storeName,
parallelThreads: parallelThreads,
maxBufferLength: maxBufferLength,
skipExistingTiles: skipExistingTiles,
Expand Down Expand Up @@ -264,8 +279,6 @@ class DownloadManagement {
/// {@macro num_instances}
///
/// Does nothing (returns immediately) if there is no ongoing download.
///
/// Do not use to interact with background downloads.
Future<void> cancel({Object instanceId = 0}) async =>
await DownloadInstance.get(instanceId)?.requestCancel?.call();

Expand All @@ -282,8 +295,6 @@ class DownloadManagement {
///
/// Does nothing (returns immediately) if there is no ongoing download or the
/// download is already paused.
///
/// Do not use to interact with background downloads.
Future<void> pause({Object instanceId = 0}) async =>
await DownloadInstance.get(instanceId)?.requestPause?.call();

Expand All @@ -293,8 +304,6 @@ class DownloadManagement {
///
/// Does nothing if there is no ongoing download or the download is already
/// running.
///
/// Do not use to interact with background downloads.
void resume({Object instanceId = 0}) =>
DownloadInstance.get(instanceId)?.requestResume?.call();

Expand All @@ -304,8 +313,6 @@ class DownloadManagement {
/// {@macro num_instances}
///
/// Also returns `false` if there is no ongoing download.
///
/// Do not use to interact with background downloads.
bool isPaused({Object instanceId = 0}) =>
DownloadInstance.get(instanceId)?.isPaused ?? false;
}
3 changes: 1 addition & 2 deletions lib/src/store/manage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ part of '../../flutter_map_tile_caching.dart';
/// operation, then an error will be thrown ([StoreNotExists]). It is
/// recommended to check [ready] when necessary.
class StoreManagement {
StoreManagement._(FMTCStore store) : _storeName = store.storeName;

StoreManagement._(this._storeName);
final String _storeName;

/// {@macro fmtc.backend.storeExists}
Expand Down
3 changes: 1 addition & 2 deletions lib/src/store/metadata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ part of '../../flutter_map_tile_caching.dart';
/// advanced requirements should use another package, as this is a basic
/// implementation.
class StoreMetadata {
StoreMetadata._(FMTCStore store) : _storeName = store.storeName;

StoreMetadata._(this._storeName);
final String _storeName;

/// {@macro fmtc.backend.readMetadata}
Expand Down
3 changes: 1 addition & 2 deletions lib/src/store/statistics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ part of '../../flutter_map_tile_caching.dart';
/// operation, then an error will be thrown ([StoreNotExists]). It is
/// recommended to check [StoreManagement.ready] when necessary.
class StoreStats {
StoreStats._(FMTCStore store) : _storeName = store.storeName;

StoreStats._(this._storeName);
final String _storeName;

/// {@macro fmtc.backend.getStoreStats}
Expand Down
Loading

0 comments on commit 8177408

Please sign in to comment.