workspace_model_event_listening.md: remove deprecated WorkspaceModelChangeListener approach

This commit is contained in:
Yann Cébron 2025-02-19 14:00:34 +01:00
parent 625ad3bf54
commit c399689fcd

View File

@ -1,4 +1,4 @@
<!-- Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
<!-- Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
# Event Listening
@ -6,8 +6,7 @@
<link-summary>Listening to Workspace Model events</link-summary>
There are two ways to subscribe to events from the Workspace Model:
via [listener](#WorkspaceModelChangeListener) or by subscribing to the [flow](#subscription-via-kotlin-flow) of events.
Plugins can subscribe to the [flow](#subscription-via-kotlin-flow) of events from the Workspace Model.
### `EntityChange` Events
@ -51,80 +50,19 @@ After: `A` `C` &rarr; `B`
Move child `B` from `A` to `C`: [**Replaced(A)**, **Replaced(B)**, **Replaced(C)**]
## Subscription via `WorkspaceModelChangeListener`
{id="WorkspaceModelChangeListener"}
The Workspace Model storage allows us to subscribe to all of its changes using the [](plugin_listeners.md) mechanism via
[`WorkspaceModelChangeListener`](%gh-ic%/platform/backend/workspace/src/WorkspaceModelTopics.kt).
The listener offers both
[`WorkspaceModelChangeListener.beforeChanged()`](%gh-ic%/platform/backend/workspace/src/WorkspaceModelTopics.kt)
and
[`WorkspaceModelChangeListener.changed()`](%gh-ic%/platform/backend/workspace/src/WorkspaceModelTopics.kt)
callbacks.
The object passed to these methods as a parameter
[`VersionedStorageChange`](%gh-ic%/platform/workspace/storage/src/com/intellij/platform/workspace/storage/VersionedEntityStorage.kt)
contains snapshots before and after the modification.
It can be filtered by the concrete type of entity and action (`Added`/`Removed`/`Replaced`).
Examples:
- [`LanguageLevelChangedListener`](%gh-ic%/java/java-impl/src/com/intellij/openapi/roots/impl/LanguageLevelChangedListener.java) to handle Java language level changes
- [`PackagePrefixIndex`](%gh-ic%/java/java-analysis-impl/src/com/intellij/psi/impl/PackagePrefixIndex.java) to update package-prefixes for Java source roots
Registration of listeners can be done in two ways, depending on requirements:
### Programmatic Registration
Listener instance subscription is managed by code, and it starts receiving events only after explicit registration.
```kotlin
val busConnection = project.messageBus.connect(cs)
busConnection.subscribe(WorkspaceModelTopics.CHANGED,
object : WorkspaceModelChangeListener {
override fun changed(event: VersionedStorageChange) {
// Get all changes for ModuleEntity
val moduleChanges = event.getChanges(ModuleEntity::class.java)
// Filtering entities which were removed
moduleChanges.filterIsInstance<EntityChange.Removed<ModuleEntity>>()
.forEach { removedModuleEntity ->
...
}
}
})
```
### Declarative Registration
[Declarative registration](plugin_listeners.md) is available by registering the Project-level listener in <path>plugin.xml</path>.
Listener instances will be automatically instantiated on the first event to the topic.
```xml
<idea-plugin>
<projectListeners>
<listener
class="com.my.plugin.MyCustomWorkspaceModelChangeListener"
topic="com.intellij.platform.backend.workspace.WorkspaceModelChangeListener"/>
</projectListeners>
</idea-plugin>
```
## Subscription via Kotlin Flow
As the IntelliJ Platform started adapting [](kotlin_coroutines.md) in its APIs and internal code, it is also possible to subscribe to the
Using [](kotlin_coroutines.md), it is possible to subscribe to the
events via [Kotlin Flows](https://kotlinlang.org/docs/flow.html) exposed via the
[`WorkspaceModel.eventLog`](%gh-ic%/platform/backend/workspace/src/WorkspaceModel.kt)
property.
In addition to the regular events subscription, flow allows performing incremental computation:
Flows allow performing incremental computation:
calculate information based on the initial storage and modify it according to the updates.
This can be useful for incremental updates of Workspace Model-related caches.
If the subscription should be set up after a project is opened, use
[`ProjectActivity`](plugin_components.md#project-open).
This is also the way to migrate from the existing [`WorkspaceModelChangeListener`](#WorkspaceModelChangeListener)-based approach.
Keep in mind that it might miss the few first updates of the model, which is expected because the initial version of the storage will be provided.
Since this listener is asynchronous, there is no guarantee that indexes built on top of