Can a `androidx.compose.ui.graphics.Path` , and by...
# compose
q
Can a
androidx.compose.ui.graphics.Path
, and by extension an
android.graphics.Path
, be considered as
@Stable
or
@Immutable
? I know the compose compiler doesn’t think so by default. I’m trying to assess if I could add the
@Stable
or
@Immutable
annotation myself.
z
No, those are mutable classes that aren’t backed by snapshot state, so they are very much not stable.
q
That’s what I figured, so there’s no way to draw on a canvas using a
Path
and having the method / class marked as stable right ?
Schematically:
Copy code
// Can't be stable
class Sprite(val path: Path) {

   fun draw(scope: DrawScope) {
       scope.drawPath(path)
   }
}

// Won't be skippable
@Composable
Sprite.Compose() {
   Canvas {
     draw(this)
   }
}
z
If you have control of where that path is updated, and can ensure that any changes to the path are signaled in some way to the snapshot system (which is how the draw functions are invalidated), then you could make your wrapper type stable. In that code as written though, anyone could create a Path, hang onto it, then pass it to your class, and update it later, so you couldn’t guarantee that.
q
Ok, so no compile time guarantee, but in practice if I know the
Path
will never be updated again once initialised and passed to the
Sprite
class, I can mark the
Sprite
class as
@Stable
or even
@Immutable
and enjoy the optimisation, if I understood you correctly ?
z
Pretty much, yea. Although I would go a little further and say you shouldn’t just make an api like this and hope nobody in the future happens to pass a path that they update later - your Sprite API should be designed to not expose the path directly to consumers, or otherwise make a defensive copy so it doesn’t matter if a consumer decides to change their path instance later.