Skip to content

Commit

Permalink
v10: Improved multi-store usage support (#156)
Browse files Browse the repository at this point in the history
  • Loading branch information
JaffaKetchup authored Jan 11, 2025
1 parent ea6686e commit b9aaf09
Show file tree
Hide file tree
Showing 246 changed files with 14,633 additions and 9,333 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pubspec.lock
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
**/android/app/.cxx

# iOS/XCode related
**/ios/**/*.mode1v3
Expand Down
47 changes: 45 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,49 @@ Many thanks to my sponsors, no matter how much or how little they donated. Spons

# Changelog

## [10.0.0] - "Better Browsing" - 2025/01/11

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`.
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.

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.

* Major changes to browse caching
* Added support for using multiple stores simultaneously in the `FMTCTileProvider` (through the `FMTCTileProvider.allStores` & `FMTCTileProvider.multipleStores` constructors)
* Added `FMTCTileProvider.provideTile` method to expose internal browse caching mechanisms for external use
* Added `BrowseStoreStrategy` for increased control over caching behaviour
* Added 'tile loading interceptor' feature (`FMTCTileProvider.tileLoadingInterceptor`) to track (eg. for debugging and logging) the internal tile loading mechanisms
* Added toggle for hit/miss stat recording, to improve performance where these statistics are never read
* Replaced `FMTCTileProviderSettings.maxStoreLength` with a `maxLength` property on each store individually
* Replaced `CacheBehavior` with `BrowseLoadingStrategy`
* Replaced `FMTCBrowsingErrorHandler` with `BrowsingExceptionHandler`, which may now return bytes to be displayed instead of (re)throwing exception
* 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`
* Removed `FMTCTileProviderSettings` & absorbed properties directly into `FMTCTileProvider`
* Performance of the internal tile image provider has been significantly improved when fetching images from the network URL
> 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!
* Major changes to bulk downloading
* Added support for retrying failed tiles (that failed because the request could not be made) once at the end of the download
* Changed result of `StoreDownload.startForeground` into two seperate streams returned as a record, one for `TileEvent`s, one for `DownloadProgress`s
* Refactored `TileEvent`s into multiple classes and mixins in a sealed inheritance tree to reduce nullability and uncertainty & promote modern Dart features
* Changed `DownloadProgress`' metrics to reflect other changes and renamed methods to improve clarity and consistency with Dart recommended style
* Renamed `StoreDownload.check` to `.countTiles`

* Improvements for bulk downloadable `BaseRegion`s
* Added `MultiRegion`, which contains multiple other `BaseRegion`s
* Improved speed (by massive amounts) and accuracy & reduced memory consumption of `CircleRegion`'s tile generation & counting algorithm
* Fixed multiple bugs with respect to `start` and `end` tiles in downloads
* Deprecated `BaseRegion.(maybe)When` - this is easy to perform using a standard pattern-matched switch

* Exporting stores is now more stable, and has improved documentation
> 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.
* Removed deprecated remnants from v9.*

* Other generic improvements (performance, stability, and documentation)

* Brand new example app to demonstrate the new levels of flexibility and customizability

## [9.1.4] - 2024/12/05

* 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))
Expand All @@ -29,12 +72,12 @@ Many thanks to my sponsors, no matter how much or how little they donated. Spons

## [9.1.2] - 2024/08/07

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

## [9.1.1] - 2024/07/16

* Fixed bug where errors within the import functionality would not be catchable by the original invoker
* Fixed bug where errors within the import functionality would not always be catchable by the original invoker
* Minor other improvements

## [9.1.0] - 2024/05/27
Expand Down
11 changes: 6 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@

## Reporting A Bug

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!
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!

Before reporting a bug, please:

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

## Contributing Code

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.

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.

When submitting code, please:

* Keep code concise and in a similar style to surrounding code
* Document all public APIs in detail and with correct grammar
* Document all new public APIs
* Use the included linting rules
* Update the example application to appropriately consume any public API changes
* Avoid incrementing this package's version number or changelog
10 changes: 5 additions & 5 deletions example/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.

version:
revision: "29babcb32a591b9e5be8c6a6075d4fe605d46ad3"
revision: "3e493a3e4d0a5c99fa7da51faae354e95a9a1abe"
channel: "beta"

project_type: app
Expand All @@ -13,11 +13,11 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
base_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
create_revision: 3e493a3e4d0a5c99fa7da51faae354e95a9a1abe
base_revision: 3e493a3e4d0a5c99fa7da51faae354e95a9a1abe
- platform: android
create_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
base_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
create_revision: 3e493a3e4d0a5c99fa7da51faae354e95a9a1abe
base_revision: 3e493a3e4d0a5c99fa7da51faae354e95a9a1abe

# User provided section

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
plugins {
id "com.android.application"
id "kotlin-android"
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
id("dev.flutter.flutter-gradle-plugin")
}

android {
namespace = "dev.jaffaketchup.fmtc.demo"
compileSdk = flutter.compileSdkVersion
// ndkVersion = flutter.ndkVersion
ndkVersion = "26.1.10909125"
ndkVersion = "27.0.12077973"

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
jvmTarget = JavaVersion.VERSION_1_8.toString()
}

defaultConfig {
Expand All @@ -30,7 +30,9 @@ android {

buildTypes {
release {
signingConfig = signingConfigs.debug
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}
Expand Down
18 changes: 0 additions & 18 deletions example/android/build.gradle

This file was deleted.

21 changes: 21 additions & 0 deletions example/android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
allprojects {
repositories {
google()
mavenCentral()
}
}

val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
rootProject.layout.buildDirectory.value(newBuildDir)

subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}

tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}
2 changes: 1 addition & 1 deletion example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
25 changes: 0 additions & 25 deletions example/android/settings.gradle

This file was deleted.

25 changes: 25 additions & 0 deletions example/android/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pluginManagement {
val flutterSdkPath = run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}

includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.7.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.22" apply false
}

include(":app")
Loading

0 comments on commit b9aaf09

Please sign in to comment.