From 616503dfb135b9db4642c9945b3ce7fbb471dc6d Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Wed, 12 Mar 2025 16:42:21 +0100 Subject: [PATCH] persisting_state_of_components.md: Describe SerializablePersistentStateComponent --- .../basics/persisting_state_of_components.md | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/topics/basics/persisting_state_of_components.md b/topics/basics/persisting_state_of_components.md index bd62ebe92..7fc6bd4ee 100644 --- a/topics/basics/persisting_state_of_components.md +++ b/topics/basics/persisting_state_of_components.md @@ -34,24 +34,61 @@ If an extension needs to have a persistent state, define a separate service resp -The easiest way to implement a persistent state component in Kotlin is extending [`SimplePersistentStateComponent`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/SimplePersistentStateComponent.kt), which implements `PersistentStateComponent`. +The recommended approach to implementing a persistent state component in Kotlin is to extend one of the base classes: +1. [`SimplePersistentStateComponent`](#SimplePersistentStateComponent) +2. [`SerializablePersistentStateComponent`](#SerializablePersistentStateComponent) (available since 2022.2) -`SimplePersistentStateComponent` is parameterized by a subclass of [`BaseState`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/BaseState.kt). + + +[`SimplePersistentStateComponent`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/SimplePersistentStateComponent.kt) is parameterized by a subclass of [`BaseState`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/BaseState.kt). `BaseState` provides a set of handy [property delegates](https://kotlinlang.org/docs/delegated-properties.html), which make it easy to create properties with default values. In addition, delegates track property modifications internally, which helps decrease calling `PersistentStateComponent.getState()` by the platform. -It is recommended to create separate classes for a component and its state: +Example: ```kotlin @Service @State(...) -class MySettings : SimplePersistentStateComponent(MyState()) - -class MyState : BaseState() { - var value by string() +class MySettings : SimplePersistentStateComponent(State()) { + class State : BaseState() { + var value by string("default value") + } } ``` + + + + + +[`SerializablePersistentStateComponent`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/SerializablePersistentStateComponent.kt) is parameterized with a state data class. + +State properties are exposed via persistent state component class' properties. +The state properties are modified by copying the state and overwriting a modified value within `SerializablePersistentStateComponent.updateState()`, which ensures atomic modification. + +Example: + +```kotlin +@Service +@State(...) +class MySettings : SerializablePersistentStateComponent(State()) { + + var stringValue: String + get() = state.stringValue + set(value) { + updateState { + it.copy(stringValue = value) + } + } + + data class State ( + @JvmField val stringValue: String = "default value" + ) +} +``` + + +