13
13
*/
14
14
package org.modelix.model.server.mps
15
15
16
- import com.intellij.ide.AppLifecycleListener
17
- import com.intellij.ide.plugins.DynamicPluginListener
18
- import com.intellij.ide.plugins.IdeaPluginDescriptor
19
16
import com.intellij.openapi.Disposable
20
17
import com.intellij.openapi.components.Service
21
18
import com.intellij.openapi.components.service
22
19
import com.intellij.openapi.project.DumbService
23
20
import com.intellij.openapi.project.Project
21
+ import com.intellij.openapi.startup.StartupActivity
24
22
import jetbrains.mps.ide.project.ProjectHelper
25
- import jetbrains.mps.project.ProjectBase
26
- import jetbrains.mps.project.ProjectManager
27
- import jetbrains.mps.smodel.MPSModuleRepository
23
+ import jetbrains.mps.project.MPSProject
28
24
import org.modelix.model.api.INode
29
25
import org.modelix.model.api.runSynchronized
30
26
import org.modelix.model.mpsadapters.MPSRepositoryAsNode
31
27
import org.modelix.model.server.light.LightModelServer
28
+ import java.util.Collections
29
+
30
+ @Service(Service .Level .PROJECT )
31
+ class MPSModelServerForProject (private val project : Project ) : Disposable {
32
32
33
- @Service(Service .Level .APP )
34
- class MPSModelServer : Disposable {
35
33
init {
36
- println ( " modelix server created " )
34
+ service< MPSModelServer >().registerProject(project )
37
35
}
38
36
37
+ override fun dispose () {
38
+ service<MPSModelServer >().unregisterProject(project)
39
+ }
40
+ }
41
+
42
+ @Service(Service .Level .APP )
43
+ class MPSModelServer : Disposable {
44
+
39
45
private var server: LightModelServer ? = null
46
+ private val projects: MutableSet <Project > = Collections .synchronizedSet(HashSet ())
47
+
48
+ fun registerProject (project : Project ) {
49
+ projects.add(project)
50
+ ensureStarted()
51
+ }
52
+
53
+ fun unregisterProject (project : Project ) {
54
+ projects.remove(project)
55
+ }
56
+
57
+ private fun getMPSProjects (): List <MPSProject > {
58
+ return runSynchronized(projects) {
59
+ projects.mapNotNull { it.getComponent(MPSProject ::class .java) }
60
+ }
61
+ }
62
+
63
+ private fun getRootNode (): INode ? {
64
+ return getMPSProjects().asSequence().map {
65
+ MPSRepositoryAsNode (it.repository)
66
+ }.firstOrNull()
67
+ }
40
68
41
69
fun ensureStarted () {
42
70
runSynchronized(this ) {
43
71
if (server != null ) return
44
72
45
73
println (" starting modelix server" )
46
74
47
- val rootNodeProvider: () -> INode ? = { MPSModuleRepository .getInstance()?.let { MPSRepositoryAsNode (it) } }
48
75
server = LightModelServer .builder()
49
76
.port(48305 )
50
- .rootNode(rootNodeProvider )
77
+ .rootNode(::getRootNode )
51
78
.healthCheck(object : LightModelServer .IHealthCheck {
52
79
override val id: String
53
80
get() = " indexer"
@@ -56,13 +83,12 @@ class MPSModelServer : Disposable {
56
83
57
84
override fun run (output : java.lang.StringBuilder ): Boolean {
58
85
var allSmart = true
59
- val projects = ProjectManager .getInstance().openedProjects
60
- for (project in projects) {
86
+ for (project in getMPSProjects()) {
61
87
project.repository.modelAccess.runReadAction {
62
88
val indexerDone =
63
89
! DumbService .getInstance(ProjectHelper .toIdeaProject(project)).isDumb
64
90
if (! indexerDone) {
65
- output.append(" indexer running on project " ).append(project.name )
91
+ output.append(" indexer running on project " ).append(project.toString() )
66
92
allSmart = false
67
93
}
68
94
}
@@ -77,10 +103,10 @@ class MPSModelServer : Disposable {
77
103
get() = false
78
104
79
105
override fun run (output : StringBuilder ): Boolean {
80
- val projects = ProjectManager .getInstance().openedProjects
106
+ val projects = getMPSProjects()
81
107
output.append(" ${projects.size} projects found" )
82
- projects.forEach { output.append(" ${it.name} " ) }
83
- return ProjectManager .getInstance().openedProjects .isNotEmpty()
108
+ projects.forEach { output.append(" $it " ) }
109
+ return projects .isNotEmpty()
84
110
}
85
111
})
86
112
.healthCheck(object : LightModelServer .IHealthCheck {
@@ -90,13 +116,13 @@ class MPSModelServer : Disposable {
90
116
get() = false
91
117
92
118
override fun run (output : StringBuilder ): Boolean {
93
- val projects = ProjectManager .getInstance().openedProjects.filterIsInstance< ProjectBase > ()
119
+ val projects = getMPSProjects ()
94
120
for (project in projects) {
95
121
val modules = project.projectModules
96
122
val virtualFolders = modules
97
123
.mapNotNull { project.getPath(it)?.virtualFolder }
98
124
.filter { it.isNotEmpty() }
99
- output.append(" project ${ project.name} contains ${modules.size} modules with ${virtualFolders.size} virtual folders" )
125
+ output.append(" project $project contains ${modules.size} modules with ${virtualFolders.size} virtual folders" )
100
126
if (virtualFolders.isNotEmpty()) return true
101
127
}
102
128
return false
@@ -121,18 +147,8 @@ class MPSModelServer : Disposable {
121
147
}
122
148
}
123
149
124
- class MPSModelServerDynamicPluginListener : DynamicPluginListener {
125
- override fun pluginLoaded (pluginDescriptor : IdeaPluginDescriptor ) {
126
- service<MPSModelServer >().ensureStarted()
127
- }
128
- }
129
-
130
- class MPSModelServerAppLifecycleListener : AppLifecycleListener {
131
- override fun appStarting (projectFromCommandLine : Project ? ) {
132
- service<MPSModelServer >().ensureStarted()
133
- }
134
-
135
- override fun appStarted () {
136
- service<MPSModelServer >().ensureStarted()
150
+ class MPSModelServerStartupActivity : StartupActivity .Background {
151
+ override fun runActivity (project : Project ) {
152
+ project.service<MPSModelServerForProject >() // just ensure it's initialized
137
153
}
138
154
}
0 commit comments