This folder goes deeper into each scaling strategy in AppDimens Dynamic: what it is, the formula, how to import it, and when to pick each mode. Each strategy’s code lives in com.appdimens.kmp.compose.<strategy> and com.appdimens.kmp.code.<strategy> with no cross-imports between strategies.
Modules (1.0.1): principal appdimens-kmp (scaled + core/common/plain); strategy modules appdimens-kmp-<strategy>; BOM appdimens-kmp-bom. See README — Installation · MODULES.md.
- Full Kotlin Multiplatform port: same packages, API and math on Android, JVM, iOS (
iosArm64/iosSimulatorArm64), macOS (macosArm64), Kotlin/JS and wasmJs (browser). - Platform-neutral
AppDimensContext: non-Compose APIs take a window handle instead of an AndroidContext; per-platform adapters (AndroidContext, AWT window,UIScreen,NSScreen, browser viewport). - Event-driven config watcher: Android keeps the
ComponentCallbacks2listener; desktop/web/iOS/macOS rebuild the snapshot on live window configuration (resize-aware on every platform). - Specialized kernels: Zero-branch resolution per family/qualifier (
resolveSdpPx,resolveSdpaPx, etc.). - Non-Compose fast lane:
fastMetricsForCodeskips ThreadLocal probe. - Compose fast lane:
metricsScope ?: LocalDimenMetrics— one CompositionLocal read + one multiply on every platform. - DimenMetrics eager AR:
normalizedAspectRatio/logNormalizedAspectRatiochanged fromlazyto plainval. - R8 pre-shrink for all AARs: all 14 Android modules ship R8-optimized bytecode (
optimization { minify = true }). - BenchLab KMP: competitor benchmark (Dynamic vs SDPS vs Lib #2) that runs on Android, JVM, iOS, macOS and the browser.
fastPartitionrace fixed: the fast partition is now a single atomicFastPartitionSlot(metrics, partition)— before, two independent atomics could pair a snapshot partition with another window's metrics and return a wrong dimension under concurrency.- Android context cache cycle fixed: the
WeakHashMap<Context, …>value no longer holds the key strongly (now aWeakReference), so Activities/Contexts are collectable. - Configuration listeners disposable:
registerConfigurationListenerreturnsConfigurationRegistrationwithdispose(); the Android registry unregistersComponentCallbackswhen the last listener is removed. - Config-watcher lifecycle hardened: the registered listener is now context-free (no value→key cycle), the watcher is reference-counted (
acquireConfigWatcher/releaseConfigWatcher), the AndroidAppDimensProviderpairs them viaDisposableEffect, and the Android registry holds listeners weakly — a destroyed Activity is collectable even without an explicitdispose(). - Weak identity map fixed (JVM/Android):
WeakHashMap<WeakKey<K>, V>made the weak wrapper the map's weak key, so live entries could be dropped while the original key was strongly reachable. Replaced with a strongHashMapofIdentityWeakReferencewrappers +ReferenceQueue. - Native metrics scope is thread-local: the Kotlin/Native
MetricsScopeHolderis@ThreadLocal— each worker gets its own slot (was one shared mutable global). - Native/Web identity maps use
===:SynchronizedIdentityMap/WebIdentityMapcompare window handles by identity instead ofequals(). - Strict race tests:
DimenCacheRaceTestrequires the exact expected value per key/snapshot — no more false negatives. New GC / identity / lifecycle / native-worker tests added. - New targets: classic Kotlin/JS (
js, IR),linuxX64,linuxArm64,mingwX64on every module via the sharedappdimens.kmp-libraryconvention plugin. Linux/Windows expose thecodeAPI only. - Encapsulated diagnostics:
DimenCache.isInitializedis a plainBooleanandcacheStats()returns immutableCacheStats; experimental atomics areinternal. - CI restored:
verify-linux+verify-applegates; wrapperdistributionSha256Sumpinned; Compose dev repository removed from the resolution path.
Product docs: PRD.md · PDR.md · MATHEMATICS-AND-CALCULUS.md.
For cache, bypass, and performance, see also library/PERFORMANCE.md.
Naming parity (compose vs code): In the multi-module tree, each strategy lives under library/ (scaled) or library-<strategy>/, pairing Dimen<Strategy>DpExtensions.kt (layout facilitators → Float px + AppDimensContext) with Dimen<Strategy>SpExtensions.kt where Sp facilitators exist — the same filenames as under compose/<strategy>/, so it is easy to jump between UI toolkits. Scaled uses DimenSdpExtensions.kt and DimenSspExtensions.kt inside the scaled/ subfolder (packages stay top-level compose / code). Plain helpers remain in Dimen<Strategy>PlainPx.kt per strategy plus shared logic in com.appdimens.kmp.code.plain (principal artifact).
Compose API catalog: COMPOSE-API-CONVENTIONS.md (scaled surface + prefix map; §4.5 View/code Plain). Resize: resize.md.
Package index: index.md.
Note: Dokka HTML export can be generated per module (./gradlew :library:dokkaGenerateHtml); the committed docs are the strategy guides and this index.
| Strategy | Maven artifact (1.0.1) | Document |
|---|---|---|
| Unified math (all strategies) | — | MATHEMATICS-AND-CALCULUS.md |
| Module graph / packaging | see MODULES.md | MODULES.md |
| BOM (version alignment only) | appdimens-kmp-bom |
MODULES.md |
| Scaled (default SDP / HDP / WDP) | appdimens-kmp (principal) |
scaled.md |
Percent (linear 1/300 + space*) |
appdimens-kmp-percent |
percent.md |
| Power (sublinear) | appdimens-kmp-power |
power.md |
| Fluid (320–768 dp band) | appdimens-kmp-fluid |
fluid.md |
| Auto (linear + log after 480 dp) | appdimens-kmp-auto |
auto.md |
| Diagonal | appdimens-kmp-diagonal |
diagonal.md |
| Fill (“cover”) | appdimens-kmp-fill |
fill.md |
| Fit (“contain”) | appdimens-kmp-fit |
fit.md |
| Interpolated | appdimens-kmp-interpolated |
interpolated.md |
| Logarithmic | appdimens-kmp-logarithmic |
logarithmic.md |
| Perimeter | appdimens-kmp-perimeter |
perimeter.md |
| Density | appdimens-kmp-density |
density.md |
| Resize (constraint-based auto-fit) | appdimens-kmp-resize |
resize.md |
| Physical units (mm, cm, in) | appdimens-kmp-units |
physical-units.md |
- KDoc API — root index
0a. Modules — Maven/Gradle graph (1.0.1)
0b. Mathematics & calculus — formal reference - Compose API reference — conventions & scaled catalog
- Scaled — recommended starting point
- Percent
- Power
- Fluid
- Auto
- Diagonal
- Fill
- Fit
- Interpolated
- Logarithmic
- Perimeter
- Density
- Resize
- Physical units
- Mathematics & calculus
flowchart LR
start[New_layout]
scaled[scaled_sdp_hdp_wdp]
qa[QA_phone_tablet]
other[Other_strategy]
start --> scaled
scaled --> qa
qa -->|curve_not_right| other
Always start with scaled; switch strategy only where visual QA or requirements (TV, ultrawide, split-screen) need a different growth curve.