Skip to content

Commit b9aaf09

Browse files
authored
v10: Improved multi-store usage support (#156)
1 parent ea6686e commit b9aaf09

File tree

246 files changed

+14633
-9333
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

246 files changed

+14633
-9333
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pubspec.lock
3939
**/android/gradlew.bat
4040
**/android/local.properties
4141
**/android/**/GeneratedPluginRegistrant.java
42+
**/android/app/.cxx
4243

4344
# iOS/XCode related
4445
**/ios/**/*.mode1v3

CHANGELOG.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,49 @@ Many thanks to my sponsors, no matter how much or how little they donated. Spons
1818

1919
# Changelog
2020

21+
## [10.0.0] - "Better Browsing" - 2025/01/11
22+
23+
This update builds on v9 to fully embrace the new many-to-many relationship between tiles and stores, which allows for more flexibility when constructing the `FMTCTileProvider`.
24+
This allows a new paradigm to be used: stores may now be treated as bulk downloaded regions, and all the regions/stores can be used at once - no more switching between them. This allows huge amounts of flexibility and a better UX in a complex application. Additionally, each store may now have its own `BrowseStoreStrategy` when browsing, which allows more flexibility: for example, stores may now contain more than one URL template/source, but control is retained.
25+
26+
Additionally, vector tiles are now supported in theory, as the internal caching/retrieval logic of the specialised `ImageProvider` has been exposed, although it is out of scope to fully implement support for it.
27+
28+
* Major changes to browse caching
29+
* Added support for using multiple stores simultaneously in the `FMTCTileProvider` (through the `FMTCTileProvider.allStores` & `FMTCTileProvider.multipleStores` constructors)
30+
* Added `FMTCTileProvider.provideTile` method to expose internal browse caching mechanisms for external use
31+
* Added `BrowseStoreStrategy` for increased control over caching behaviour
32+
* Added 'tile loading interceptor' feature (`FMTCTileProvider.tileLoadingInterceptor`) to track (eg. for debugging and logging) the internal tile loading mechanisms
33+
* Added toggle for hit/miss stat recording, to improve performance where these statistics are never read
34+
* Replaced `FMTCTileProviderSettings.maxStoreLength` with a `maxLength` property on each store individually
35+
* Replaced `CacheBehavior` with `BrowseLoadingStrategy`
36+
* Replaced `FMTCBrowsingErrorHandler` with `BrowsingExceptionHandler`, which may now return bytes to be displayed instead of (re)throwing exception
37+
* Replaced `obscureQueryParams` with more flexible `urlTransformer` (and static `FMTCTileProvider.urlTransformerOmitKeyValues` utility method to provide old behaviour with more customizability) - also applies to bulk downloading in `StoreDownload.startForeground`
38+
* Removed `FMTCTileProviderSettings` & absorbed properties directly into `FMTCTileProvider`
39+
* Performance of the internal tile image provider has been significantly improved when fetching images from the network URL
40+
> There was a significant time loss due to attempting to handle the network request response as a stream of incoming bytes, which allowed for `chunkEvents` to be reported back to Flutter (allowing it to get progress updates on the state of the tile), but meant the bytes had to be collected and built manually. Removing this functionality allows the network requests to use more streamlined 'package:http' methods, which does not expose a stream of incoming bytes, meaning that bytes no longer have to be treated manually. This can save hundreds of milliseconds on tile loading - a significant time save of potentially up to ~50% in some cases!
41+
42+
* Major changes to bulk downloading
43+
* Added support for retrying failed tiles (that failed because the request could not be made) once at the end of the download
44+
* Changed result of `StoreDownload.startForeground` into two seperate streams returned as a record, one for `TileEvent`s, one for `DownloadProgress`s
45+
* Refactored `TileEvent`s into multiple classes and mixins in a sealed inheritance tree to reduce nullability and uncertainty & promote modern Dart features
46+
* Changed `DownloadProgress`' metrics to reflect other changes and renamed methods to improve clarity and consistency with Dart recommended style
47+
* Renamed `StoreDownload.check` to `.countTiles`
48+
49+
* Improvements for bulk downloadable `BaseRegion`s
50+
* Added `MultiRegion`, which contains multiple other `BaseRegion`s
51+
* Improved speed (by massive amounts) and accuracy & reduced memory consumption of `CircleRegion`'s tile generation & counting algorithm
52+
* Fixed multiple bugs with respect to `start` and `end` tiles in downloads
53+
* Deprecated `BaseRegion.(maybe)When` - this is easy to perform using a standard pattern-matched switch
54+
55+
* Exporting stores is now more stable, and has improved documentation
56+
> The method now works in a dedicated temporary environment and attempts to perform two different strategies to move/copy-and-delete the result to the specified directory at the end before failing. Improved documentation covers the potential pitfalls of permissions and now recommends exporting to an app directory, then using the system share functionality on some devices. It now also returns the number of exported tiles.
57+
58+
* Removed deprecated remnants from v9.*
59+
60+
* Other generic improvements (performance, stability, and documentation)
61+
62+
* Brand new example app to demonstrate the new levels of flexibility and customizability
63+
2164
## [9.1.4] - 2024/12/05
2265

2366
* Fixed bug in `removeTilesOlderThan` where actually tiles newer than the specified expiry were being removed ([#172](https://github.com/JaffaKetchup/flutter_map_tile_caching/issues/172))
@@ -29,12 +72,12 @@ Many thanks to my sponsors, no matter how much or how little they donated. Spons
2972

3073
## [9.1.2] - 2024/08/07
3174

32-
* Fixed compilation on web platforms: FMTC now internally overrides the `FMTCObjectBoxBackend` and becomes a no-op
75+
* Fixed compilation on web platforms: FMTC now internally overrides the `FMTCObjectBoxBackend` and becomes a no-op on non-FFI platforms
3376
* Minor documentation improvements
3477

3578
## [9.1.1] - 2024/07/16
3679

37-
* Fixed bug where errors within the import functionality would not be catchable by the original invoker
80+
* Fixed bug where errors within the import functionality would not always be catchable by the original invoker
3881
* Minor other improvements
3982

4083
## [9.1.0] - 2024/05/27

CONTRIBUTING.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@
22

33
## Reporting A Bug
44

5-
FMTC is a large, platform-dependent package, and there's only one person running manual tests on it before releases, so there's a decent chance that a bug you've found is actually a bug. Reporting it is always appreciated!
5+
I try to test FMTC on as many platforms as I have access to, using a combination of automated tests and manual tests through the example application. However, I only have access to Android and Windows devices. Due to the number of platform-dependent plugins this package uses, bugs are often only present on one platform, which is often iOS. However, they can of course occur on any platform if I've missed one. Reporting any bugs you find is always appreciated!
66

77
Before reporting a bug, please:
88

99
* Check if there is already an open or closed issue that is similar to yours
10-
* Ensure that your Flutter environment is correctly installed & set-up
11-
* Ensure that this package, 'flutter_map', and any modules are correctly installed & set-up
10+
* Ensure that Flutter, this package, 'flutter_map', and any modules are correctly installed & set-up
11+
* Follow the bug reporting issue template
1212

1313
## Contributing Code
1414

1515
Contributors are always welcome, and support is always greatly appreciated! Before opening a Pull Request, however, please open a feature request or bug report to link the PR to.
1616

17+
Please note that all contributions may be dually licensed under an alternative proprietary license on a case-by-case basis, which grants no extra rights to contributors.
18+
1719
When submitting code, please:
1820

19-
* Keep code concise and in a similar style to surrounding code
20-
* Document all public APIs in detail and with correct grammar
21+
* Document all new public APIs
2122
* Use the included linting rules
2223
* Update the example application to appropriately consume any public API changes
2324
* Avoid incrementing this package's version number or changelog

example/.metadata

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# This file should be version controlled and should not be manually edited.
55

66
version:
7-
revision: "29babcb32a591b9e5be8c6a6075d4fe605d46ad3"
7+
revision: "3e493a3e4d0a5c99fa7da51faae354e95a9a1abe"
88
channel: "beta"
99

1010
project_type: app
@@ -13,11 +13,11 @@ project_type: app
1313
migration:
1414
platforms:
1515
- platform: root
16-
create_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
17-
base_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
16+
create_revision: 3e493a3e4d0a5c99fa7da51faae354e95a9a1abe
17+
base_revision: 3e493a3e4d0a5c99fa7da51faae354e95a9a1abe
1818
- platform: android
19-
create_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
20-
base_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
19+
create_revision: 3e493a3e4d0a5c99fa7da51faae354e95a9a1abe
20+
base_revision: 3e493a3e4d0a5c99fa7da51faae354e95a9a1abe
2121

2222
# User provided section
2323

example/android/app/build.gradle renamed to example/android/app/build.gradle.kts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
plugins {
2-
id "com.android.application"
3-
id "kotlin-android"
2+
id("com.android.application")
3+
id("kotlin-android")
44
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
5-
id "dev.flutter.flutter-gradle-plugin"
5+
id("dev.flutter.flutter-gradle-plugin")
66
}
77

88
android {
99
namespace = "dev.jaffaketchup.fmtc.demo"
1010
compileSdk = flutter.compileSdkVersion
1111
// ndkVersion = flutter.ndkVersion
12-
ndkVersion = "26.1.10909125"
12+
ndkVersion = "27.0.12077973"
1313

1414
compileOptions {
1515
sourceCompatibility = JavaVersion.VERSION_1_8
1616
targetCompatibility = JavaVersion.VERSION_1_8
1717
}
1818

1919
kotlinOptions {
20-
jvmTarget = JavaVersion.VERSION_1_8
20+
jvmTarget = JavaVersion.VERSION_1_8.toString()
2121
}
2222

2323
defaultConfig {
@@ -30,7 +30,9 @@ android {
3030

3131
buildTypes {
3232
release {
33-
signingConfig = signingConfigs.debug
33+
// TODO: Add your own signing config for the release build.
34+
// Signing with the debug keys for now, so `flutter run --release` works.
35+
signingConfig = signingConfigs.getByName("debug")
3436
}
3537
}
3638
}

example/android/build.gradle

Lines changed: 0 additions & 18 deletions
This file was deleted.

example/android/build.gradle.kts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
allprojects {
2+
repositories {
3+
google()
4+
mavenCentral()
5+
}
6+
}
7+
8+
val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
9+
rootProject.layout.buildDirectory.value(newBuildDir)
10+
11+
subprojects {
12+
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
13+
project.layout.buildDirectory.value(newSubprojectBuildDir)
14+
}
15+
subprojects {
16+
project.evaluationDependsOn(":app")
17+
}
18+
19+
tasks.register<Delete>("clean") {
20+
delete(rootProject.layout.buildDirectory)
21+
}

example/android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
1+
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
22
android.useAndroidX=true
33
android.enableJetifier=true

example/android/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
33
zipStoreBase=GRADLE_USER_HOME
44
zipStorePath=wrapper/dists
5-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
5+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip

example/android/settings.gradle

Lines changed: 0 additions & 25 deletions
This file was deleted.

example/android/settings.gradle.kts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
pluginManagement {
2+
val flutterSdkPath = run {
3+
val properties = java.util.Properties()
4+
file("local.properties").inputStream().use { properties.load(it) }
5+
val flutterSdkPath = properties.getProperty("flutter.sdk")
6+
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
7+
flutterSdkPath
8+
}
9+
10+
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11+
12+
repositories {
13+
google()
14+
mavenCentral()
15+
gradlePluginPortal()
16+
}
17+
}
18+
19+
plugins {
20+
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
21+
id("com.android.application") version "8.7.0" apply false
22+
id("org.jetbrains.kotlin.android") version "1.8.22" apply false
23+
}
24+
25+
include(":app")

0 commit comments

Comments
 (0)