mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-27 16:57:49 +08:00
workspace_model_event_listening.md: remove deprecated WorkspaceModelChangeListener
approach
This commit is contained in:
parent
625ad3bf54
commit
c399689fcd
@ -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
|
# Event Listening
|
||||||
|
|
||||||
@ -6,8 +6,7 @@
|
|||||||
|
|
||||||
<link-summary>Listening to Workspace Model events</link-summary>
|
<link-summary>Listening to Workspace Model events</link-summary>
|
||||||
|
|
||||||
There are two ways to subscribe to events from the Workspace Model:
|
Plugins can subscribe to the [flow](#subscription-via-kotlin-flow) of events from the Workspace Model.
|
||||||
via [listener](#WorkspaceModelChangeListener) or by subscribing to the [flow](#subscription-via-kotlin-flow) of events.
|
|
||||||
|
|
||||||
### `EntityChange` Events
|
### `EntityChange` Events
|
||||||
|
|
||||||
@ -51,80 +50,19 @@ After: `A` `C` → `B`
|
|||||||
|
|
||||||
Move child `B` from `A` to `C`: [**Replaced(A)**, **Replaced(B)**, **Replaced(C)**]
|
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
|
## 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
|
events via [Kotlin Flows](https://kotlinlang.org/docs/flow.html) exposed via the
|
||||||
[`WorkspaceModel.eventLog`](%gh-ic%/platform/backend/workspace/src/WorkspaceModel.kt)
|
[`WorkspaceModel.eventLog`](%gh-ic%/platform/backend/workspace/src/WorkspaceModel.kt)
|
||||||
property.
|
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.
|
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.
|
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
|
If the subscription should be set up after a project is opened, use
|
||||||
[`ProjectActivity`](plugin_components.md#project-open).
|
[`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.
|
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
|
Since this listener is asynchronous, there is no guarantee that indexes built on top of
|
||||||
|
Loading…
x
Reference in New Issue
Block a user