Skip to content

Commit

Permalink
support foreach dynamic shapes for shape layer
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhirkevich Alexander Y authored and Zhirkevich Alexander Y committed Jul 8, 2024
1 parent 14cdf0a commit e772421
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ interface DynamicShapeLayer: DynamicLayer {

/**
* Configure generic dynamic shape.
*
* @param path is a path to the shape relative to the shape layer.
* If [path] is not set, the [builder] configuration will be be applied to the all shapes in
* the current layer/[group] recursively
*
* @param builder shape dynamic configuration
* */
fun shape(
vararg path: String,
Expand All @@ -13,6 +19,9 @@ interface DynamicShapeLayer: DynamicLayer {
/**
* Shortcut useful if you want to configure multiple shapes in the same group
*
* @param path is a path to the group shape relative to the shape layer.
* @param builder shape dynamic configuration
*
* Example:
*
* ```
Expand All @@ -31,6 +40,12 @@ interface DynamicShapeLayer: DynamicLayer {

/**
* Configure dynamic stroke.
*
* @param path is a path to the stroke shape relative to the shape layer.
* If [path] is not set, the [builder] configuration will be be applied to the all strokes in
* the current layer/[group] recursively
*
* @param builder shape dynamic configuration
* */
fun stroke(
vararg path: String,
Expand All @@ -39,6 +54,12 @@ interface DynamicShapeLayer: DynamicLayer {

/**
* Configure dynamic fill.
*
* @param path is a path to the fill shape relative to the shape layer.
* If [path] is not set, the [builder] configuration will be be applied to the all fills in
* the current layer/[group] recursively
*
* @param builder shape dynamic configuration
* */
fun fill(
vararg path: String,
Expand All @@ -47,6 +68,12 @@ interface DynamicShapeLayer: DynamicLayer {

/**
* Configure dynamic ellipse.
*
* @param path is a path to the ellipse shape relative to the shape layer.
* If [path] is not set, the [builder] configuration will be be applied to the all ellipses in
* the current layer/[group] recursively
*
* @param builder shape dynamic configuration
* */
fun ellipse(
vararg path: String,
Expand All @@ -55,6 +82,12 @@ interface DynamicShapeLayer: DynamicLayer {

/**
* Configure dynamic rect.
*
* @param path is a path to the rect shape relative to the shape layer.
* If [path] is not set, the [builder] configuration will be be applied to the all rects in
* the current layer/[group] recursively
*
* @param builder shape dynamic configuration
* */
fun rect(
vararg path: String,
Expand All @@ -63,6 +96,12 @@ interface DynamicShapeLayer: DynamicLayer {

/**
* Configure dynamic rect.
*
* @param path is a path to the polystar shape relative to the shape layer.
* If [path] is not set, the [builder] configuration will be be applied to the all polystars in
* the current layer/[group] recursively
*
* @param builder shape dynamic configuration
* */
fun polystar(
vararg path: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package io.github.alexzhirkevich.compottie.dynamic

import androidx.compose.ui.util.fastMaxBy
import kotlin.reflect.KClass

@PublishedApi
internal class DynamicShapeLayerProvider(
private val basePath : String? = null,
Expand All @@ -11,7 +14,9 @@ internal class DynamicShapeLayerProvider(
@PublishedApi
internal val shapes = mutableMapOf<String, DynamicShape>()

override fun group(vararg path : String, builder: DynamicShapeLayer.() -> Unit) {
internal val eachShapes = mutableMapOf<Pair<String?, KClass<out DynamicShape>>, DynamicShape>()

override fun group(vararg path: String, builder: DynamicShapeLayer.() -> Unit) {
DynamicShapeLayerProvider(
basePath = layerPath(basePath, path.joinToString(LayerPathSeparator)),
root = nRoot
Expand Down Expand Up @@ -43,9 +48,23 @@ internal class DynamicShapeLayerProvider(
}

internal inline operator fun <reified S : DynamicShape> get(path: String): S? =
shapes[path] as? S
getInternal(path, S::class) as S?

private inline operator fun <reified T : DynamicShape> set(path: List<String>, instance: T) {
if (path.isNotEmpty()) {
nRoot.shapes[layerPath(basePath, path.joinToString(LayerPathSeparator))] = instance
} else {
nRoot.eachShapes[basePath to T::class] = instance
}
}

private fun <S : DynamicShape> getInternal(path: String, clazz: KClass<S>): DynamicShape? {
(nRoot.shapes[path])?.let { return it }

val key = nRoot.eachShapes.keys
.filter { it.second == clazz }
.fastMaxBy { it.first.orEmpty().commonPrefixWith(path).length }

private operator fun <T : DynamicShape> set(path : List<String>, instance : T){
nRoot.shapes[layerPath(basePath, path.joinToString(LayerPathSeparator))] = instance
return nRoot.eachShapes[key]
}
}

0 comments on commit e772421

Please sign in to comment.