persisting_state_of_components.md: Add information about Kotlin persistent state class implementation

This commit is contained in:
Karol Lewandowski 2023-10-12 10:52:09 +02:00
parent f844160f5d
commit 62af21d9f7

View File

@ -25,14 +25,40 @@ If an extension needs to have a persistent state, define a separate service resp
### Implementing the PersistentStateComponent Interface ### Implementing the PersistentStateComponent Interface
The implementation of `PersistentStateComponent` needs to be parameterized with the type of state class. <tabs group="languages">
<tab title="Kotlin" group-key="kotlin">
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`.
`SimplePersistentStateComponent` is parameterized by a subclass of [`BaseState`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/BaseState.kt).
`BaseState` provides 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 help decrease calling `PersistentStateComponent.getState()` by the platform.
It is recommended to create a separate classes for a component and its state:
```kotlin
@State(...)
class MySettings : SimplePersistentStateComponent<MyState>(MyState())
class MyState : BaseState() {
var value by string()
}
```
</tab>
<tab title="Java" group-key="java">
The implementation of `PersistentStateComponent` must be parameterized with the type of state class.
The state class can either be a separate class, or the class implementing `PersistentStateComponent`. The state class can either be a separate class, or the class implementing `PersistentStateComponent`.
In the former case, the state class instance is typically stored as a field in the `PersistentStateComponent` class: <chapter title="Persistent Component with Separate State Class">
In this case, the state class instance is typically stored as a field in the `PersistentStateComponent` class.
When the state is loaded from the storage, it is assigned to the state field (see `loadState()`):
```java ```java
@State(...) @State(...)
class MyService implements PersistentStateComponent<MyService.State> { class MySettings implements PersistentStateComponent<MySettings.State> {
static class State { static class State {
public String value; public String value;
@ -50,24 +76,35 @@ class MyService implements PersistentStateComponent<MyService.State> {
} }
``` ```
In the latter case, use the following pattern to implement `getState()` and `loadState()` methods: Using a separate state class is the recommended approach.
</chapter>
<chapter title="Persistent Component Being a State Class">
In this case, `getState()` returns the component itself, and `loadState()` copies properties of the state loaded from storage to the component instance:
```java ```java
@State(...) @State(...)
class MyService implements PersistentStateComponent<MyService> { class MySettings implements PersistentStateComponent<MySettings> {
public String stateValue; public String stateValue;
public MyService getState() { public MySettings getState() {
return this; return this;
} }
public void loadState(MyService state) { public void loadState(MySettings state) {
XmlSerializerUtil.copyBean(state, this); XmlSerializerUtil.copyBean(state, this);
} }
} }
``` ```
</chapter>
</tab>
</tabs>
### Implementing the State Class ### Implementing the State Class
The implementation of `PersistentStateComponent` works by serializing public fields, [annotated](%gh-ic%/platform/util/src/com/intellij/util/xmlb/annotations) private fields (see also [Customizing the XML format of persisted values](#customizing-the-xml-format-of-persisted-values)), and bean properties into an XML format. The implementation of `PersistentStateComponent` works by serializing public fields, [annotated](%gh-ic%/platform/util/src/com/intellij/util/xmlb/annotations) private fields (see also [Customizing the XML format of persisted values](#customizing-the-xml-format-of-persisted-values)), and bean properties into an XML format.